LCOV - code coverage report
Current view: top level - src/backend/parser - parse_agg.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 84.5 % 973 822
Test Date: 2026-01-26 10:56:24 Functions: 100.0 % 24 24
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 70.2 % 812 570

             Branch data     Line data    Source code
       1                 :             : /*-------------------------------------------------------------------------
       2                 :             :  *
       3                 :             :  * parse_agg.c
       4                 :             :  *        handle aggregates and window functions in parser
       5                 :             :  *
       6                 :             :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
       7                 :             :  * Portions Copyright (c) 1994, Regents of the University of California
       8                 :             :  *
       9                 :             :  *
      10                 :             :  * IDENTIFICATION
      11                 :             :  *        src/backend/parser/parse_agg.c
      12                 :             :  *
      13                 :             :  *-------------------------------------------------------------------------
      14                 :             :  */
      15                 :             : #include "postgres.h"
      16                 :             : 
      17                 :             : #include "access/htup_details.h"
      18                 :             : #include "catalog/pg_aggregate.h"
      19                 :             : #include "catalog/pg_constraint.h"
      20                 :             : #include "catalog/pg_type.h"
      21                 :             : #include "common/int.h"
      22                 :             : #include "nodes/makefuncs.h"
      23                 :             : #include "nodes/nodeFuncs.h"
      24                 :             : #include "optimizer/optimizer.h"
      25                 :             : #include "parser/parse_agg.h"
      26                 :             : #include "parser/parse_clause.h"
      27                 :             : #include "parser/parse_coerce.h"
      28                 :             : #include "parser/parse_expr.h"
      29                 :             : #include "parser/parse_relation.h"
      30                 :             : #include "parser/parsetree.h"
      31                 :             : #include "rewrite/rewriteManip.h"
      32                 :             : #include "utils/builtins.h"
      33                 :             : #include "utils/lsyscache.h"
      34                 :             : #include "utils/syscache.h"
      35                 :             : 
      36                 :             : typedef struct
      37                 :             : {
      38                 :             :         ParseState *pstate;
      39                 :             :         int                     min_varlevel;
      40                 :             :         int                     min_agglevel;
      41                 :             :         int                     min_ctelevel;
      42                 :             :         RangeTblEntry *min_cte;
      43                 :             :         int                     sublevels_up;
      44                 :             : } check_agg_arguments_context;
      45                 :             : 
      46                 :             : typedef struct
      47                 :             : {
      48                 :             :         ParseState *pstate;
      49                 :             :         Query      *qry;
      50                 :             :         bool            hasJoinRTEs;
      51                 :             :         List       *groupClauses;
      52                 :             :         List       *groupClauseCommonVars;
      53                 :             :         List       *gset_common;
      54                 :             :         bool            have_non_var_grouping;
      55                 :             :         List      **func_grouped_rels;
      56                 :             :         int                     sublevels_up;
      57                 :             :         bool            in_agg_direct_args;
      58                 :             : } substitute_grouped_columns_context;
      59                 :             : 
      60                 :             : static int      check_agg_arguments(ParseState *pstate,
      61                 :             :                                                                 List *directargs,
      62                 :             :                                                                 List *args,
      63                 :             :                                                                 Expr *filter,
      64                 :             :                                                                 int agglocation);
      65                 :             : static bool check_agg_arguments_walker(Node *node,
      66                 :             :                                                                            check_agg_arguments_context *context);
      67                 :             : static Node *substitute_grouped_columns(Node *node, ParseState *pstate, Query *qry,
      68                 :             :                                                                                 List *groupClauses, List *groupClauseCommonVars,
      69                 :             :                                                                                 List *gset_common,
      70                 :             :                                                                                 bool have_non_var_grouping,
      71                 :             :                                                                                 List **func_grouped_rels);
      72                 :             : static Node *substitute_grouped_columns_mutator(Node *node,
      73                 :             :                                                                                                 substitute_grouped_columns_context *context);
      74                 :             : static void finalize_grouping_exprs(Node *node, ParseState *pstate, Query *qry,
      75                 :             :                                                                         List *groupClauses, bool hasJoinRTEs,
      76                 :             :                                                                         bool have_non_var_grouping);
      77                 :             : static bool finalize_grouping_exprs_walker(Node *node,
      78                 :             :                                                                                    substitute_grouped_columns_context *context);
      79                 :             : static Var *buildGroupedVar(int attnum, Index ressortgroupref,
      80                 :             :                                                         substitute_grouped_columns_context *context);
      81                 :             : static void check_agglevels_and_constraints(ParseState *pstate, Node *expr);
      82                 :             : static List *expand_groupingset_node(GroupingSet *gs);
      83                 :             : static Node *make_agg_arg(Oid argtype, Oid argcollation);
      84                 :             : 
      85                 :             : 
      86                 :             : /*
      87                 :             :  * transformAggregateCall -
      88                 :             :  *              Finish initial transformation of an aggregate call
      89                 :             :  *
      90                 :             :  * parse_func.c has recognized the function as an aggregate, and has set up
      91                 :             :  * all the fields of the Aggref except aggargtypes, aggdirectargs, args,
      92                 :             :  * aggorder, aggdistinct and agglevelsup.  The passed-in args list has been
      93                 :             :  * through standard expression transformation and type coercion to match the
      94                 :             :  * agg's declared arg types, while the passed-in aggorder list hasn't been
      95                 :             :  * transformed at all.
      96                 :             :  *
      97                 :             :  * Here we separate the args list into direct and aggregated args, storing the
      98                 :             :  * former in agg->aggdirectargs and the latter in agg->args.  The regular
      99                 :             :  * args, but not the direct args, are converted into a targetlist by inserting
     100                 :             :  * TargetEntry nodes.  We then transform the aggorder and agg_distinct
     101                 :             :  * specifications to produce lists of SortGroupClause nodes for agg->aggorder
     102                 :             :  * and agg->aggdistinct.  (For a regular aggregate, this might result in
     103                 :             :  * adding resjunk expressions to the targetlist; but for ordered-set
     104                 :             :  * aggregates the aggorder list will always be one-to-one with the aggregated
     105                 :             :  * args.)
     106                 :             :  *
     107                 :             :  * We must also determine which query level the aggregate actually belongs to,
     108                 :             :  * set agglevelsup accordingly, and mark p_hasAggs true in the corresponding
     109                 :             :  * pstate level.
     110                 :             :  */
     111                 :             : void
     112                 :        5520 : transformAggregateCall(ParseState *pstate, Aggref *agg,
     113                 :             :                                            List *args, List *aggorder, bool agg_distinct)
     114                 :             : {
     115                 :        5520 :         List       *argtypes = NIL;
     116                 :        5520 :         List       *tlist = NIL;
     117                 :        5520 :         List       *torder = NIL;
     118                 :        5520 :         List       *tdistinct = NIL;
     119                 :        5520 :         AttrNumber      attno = 1;
     120                 :        5520 :         int                     save_next_resno;
     121                 :        5520 :         ListCell   *lc;
     122                 :             : 
     123         [ +  + ]:        5520 :         if (AGGKIND_IS_ORDERED_SET(agg->aggkind))
     124                 :             :         {
     125                 :             :                 /*
     126                 :             :                  * For an ordered-set agg, the args list includes direct args and
     127                 :             :                  * aggregated args; we must split them apart.
     128                 :             :                  */
     129                 :          49 :                 int                     numDirectArgs = list_length(args) - list_length(aggorder);
     130                 :          49 :                 List       *aargs;
     131                 :          49 :                 ListCell   *lc2;
     132                 :             : 
     133         [ +  - ]:          49 :                 Assert(numDirectArgs >= 0);
     134                 :             : 
     135                 :          49 :                 aargs = list_copy_tail(args, numDirectArgs);
     136                 :          49 :                 agg->aggdirectargs = list_truncate(args, numDirectArgs);
     137                 :             : 
     138                 :             :                 /*
     139                 :             :                  * Build a tlist from the aggregated args, and make a sortlist entry
     140                 :             :                  * for each one.  Note that the expressions in the SortBy nodes are
     141                 :             :                  * ignored (they are the raw versions of the transformed args); we are
     142                 :             :                  * just looking at the sort information in the SortBy nodes.
     143                 :             :                  */
     144   [ +  -  +  +  :         106 :                 forboth(lc, aargs, lc2, aggorder)
          +  -  +  +  +  
                +  +  + ]
     145                 :             :                 {
     146                 :          57 :                         Expr       *arg = (Expr *) lfirst(lc);
     147                 :          57 :                         SortBy     *sortby = (SortBy *) lfirst(lc2);
     148                 :          57 :                         TargetEntry *tle;
     149                 :             : 
     150                 :             :                         /* We don't bother to assign column names to the entries */
     151                 :          57 :                         tle = makeTargetEntry(arg, attno++, NULL, false);
     152                 :          57 :                         tlist = lappend(tlist, tle);
     153                 :             : 
     154                 :         114 :                         torder = addTargetToSortList(pstate, tle,
     155                 :          57 :                                                                                  torder, tlist, sortby);
     156                 :          57 :                 }
     157                 :             : 
     158                 :             :                 /* Never any DISTINCT in an ordered-set agg */
     159         [ +  - ]:          49 :                 Assert(!agg_distinct);
     160                 :          49 :         }
     161                 :             :         else
     162                 :             :         {
     163                 :             :                 /* Regular aggregate, so it has no direct args */
     164                 :        5471 :                 agg->aggdirectargs = NIL;
     165                 :             : 
     166                 :             :                 /*
     167                 :             :                  * Transform the plain list of Exprs into a targetlist.
     168                 :             :                  */
     169   [ +  +  +  +  :       10099 :                 foreach(lc, args)
                   +  + ]
     170                 :             :                 {
     171                 :        4628 :                         Expr       *arg = (Expr *) lfirst(lc);
     172                 :        4628 :                         TargetEntry *tle;
     173                 :             : 
     174                 :             :                         /* We don't bother to assign column names to the entries */
     175                 :        4628 :                         tle = makeTargetEntry(arg, attno++, NULL, false);
     176                 :        4628 :                         tlist = lappend(tlist, tle);
     177                 :        4628 :                 }
     178                 :             : 
     179                 :             :                 /*
     180                 :             :                  * If we have an ORDER BY, transform it.  This will add columns to the
     181                 :             :                  * tlist if they appear in ORDER BY but weren't already in the arg
     182                 :             :                  * list.  They will be marked resjunk = true so we can tell them apart
     183                 :             :                  * from regular aggregate arguments later.
     184                 :             :                  *
     185                 :             :                  * We need to mess with p_next_resno since it will be used to number
     186                 :             :                  * any new targetlist entries.
     187                 :             :                  */
     188                 :        5471 :                 save_next_resno = pstate->p_next_resno;
     189                 :        5471 :                 pstate->p_next_resno = attno;
     190                 :             : 
     191                 :       10942 :                 torder = transformSortClause(pstate,
     192                 :        5471 :                                                                          aggorder,
     193                 :             :                                                                          &tlist,
     194                 :             :                                                                          EXPR_KIND_ORDER_BY,
     195                 :             :                                                                          true /* force SQL99 rules */ );
     196                 :             : 
     197                 :             :                 /*
     198                 :             :                  * If we have DISTINCT, transform that to produce a distinctList.
     199                 :             :                  */
     200         [ +  + ]:        5471 :                 if (agg_distinct)
     201                 :             :                 {
     202                 :          80 :                         tdistinct = transformDistinctClause(pstate, &tlist, torder, true);
     203                 :             : 
     204                 :             :                         /*
     205                 :             :                          * Remove this check if executor support for hashed distinct for
     206                 :             :                          * aggregates is ever added.
     207                 :             :                          */
     208   [ +  -  +  +  :         190 :                         foreach(lc, tdistinct)
                   +  + ]
     209                 :             :                         {
     210                 :         110 :                                 SortGroupClause *sortcl = (SortGroupClause *) lfirst(lc);
     211                 :             : 
     212         [ +  - ]:         110 :                                 if (!OidIsValid(sortcl->sortop))
     213                 :             :                                 {
     214                 :           0 :                                         Node       *expr = get_sortgroupclause_expr(sortcl, tlist);
     215                 :             : 
     216   [ #  #  #  # ]:           0 :                                         ereport(ERROR,
     217                 :             :                                                         (errcode(ERRCODE_UNDEFINED_FUNCTION),
     218                 :             :                                                          errmsg("could not identify an ordering operator for type %s",
     219                 :             :                                                                         format_type_be(exprType(expr))),
     220                 :             :                                                          errdetail("Aggregates with DISTINCT must be able to sort their inputs."),
     221                 :             :                                                          parser_errposition(pstate, exprLocation(expr))));
     222                 :           0 :                                 }
     223                 :         110 :                         }
     224                 :          80 :                 }
     225                 :             : 
     226                 :        5471 :                 pstate->p_next_resno = save_next_resno;
     227                 :             :         }
     228                 :             : 
     229                 :             :         /* Update the Aggref with the transformation results */
     230                 :        5520 :         agg->args = tlist;
     231                 :        5520 :         agg->aggorder = torder;
     232                 :        5520 :         agg->aggdistinct = tdistinct;
     233                 :             : 
     234                 :             :         /*
     235                 :             :          * Now build the aggargtypes list with the type OIDs of the direct and
     236                 :             :          * aggregated args, ignoring any resjunk entries that might have been
     237                 :             :          * added by ORDER BY/DISTINCT processing.  We can't do this earlier
     238                 :             :          * because said processing can modify some args' data types, in particular
     239                 :             :          * by resolving previously-unresolved "unknown" literals.
     240                 :             :          */
     241   [ +  +  +  +  :        5576 :         foreach(lc, agg->aggdirectargs)
                   +  + ]
     242                 :             :         {
     243                 :          56 :                 Expr       *arg = (Expr *) lfirst(lc);
     244                 :             : 
     245                 :          56 :                 argtypes = lappend_oid(argtypes, exprType((Node *) arg));
     246                 :          56 :         }
     247   [ +  +  +  +  :       10291 :         foreach(lc, tlist)
                   +  + ]
     248                 :             :         {
     249                 :        4771 :                 TargetEntry *tle = (TargetEntry *) lfirst(lc);
     250                 :             : 
     251         [ +  + ]:        4771 :                 if (tle->resjunk)
     252                 :         108 :                         continue;                       /* ignore junk */
     253                 :        4663 :                 argtypes = lappend_oid(argtypes, exprType((Node *) tle->expr));
     254      [ -  +  + ]:        4771 :         }
     255                 :        5520 :         agg->aggargtypes = argtypes;
     256                 :             : 
     257                 :        5520 :         check_agglevels_and_constraints(pstate, (Node *) agg);
     258                 :        5520 : }
     259                 :             : 
     260                 :             : /*
     261                 :             :  * transformGroupingFunc
     262                 :             :  *              Transform a GROUPING expression
     263                 :             :  *
     264                 :             :  * GROUPING() behaves very like an aggregate.  Processing of levels and nesting
     265                 :             :  * is done as for aggregates.  We set p_hasAggs for these expressions too.
     266                 :             :  */
     267                 :             : Node *
     268                 :          59 : transformGroupingFunc(ParseState *pstate, GroupingFunc *p)
     269                 :             : {
     270                 :          59 :         ListCell   *lc;
     271                 :          59 :         List       *args = p->args;
     272                 :          59 :         List       *result_list = NIL;
     273                 :          59 :         GroupingFunc *result = makeNode(GroupingFunc);
     274                 :             : 
     275         [ +  - ]:          59 :         if (list_length(args) > 31)
     276   [ #  #  #  # ]:           0 :                 ereport(ERROR,
     277                 :             :                                 (errcode(ERRCODE_TOO_MANY_ARGUMENTS),
     278                 :             :                                  errmsg("GROUPING must have fewer than 32 arguments"),
     279                 :             :                                  parser_errposition(pstate, p->location)));
     280                 :             : 
     281   [ +  -  +  +  :         150 :         foreach(lc, args)
                   +  + ]
     282                 :             :         {
     283                 :          91 :                 Node       *current_result;
     284                 :             : 
     285                 :          91 :                 current_result = transformExpr(pstate, (Node *) lfirst(lc), pstate->p_expr_kind);
     286                 :             : 
     287                 :             :                 /* acceptability of expressions is checked later */
     288                 :             : 
     289                 :          91 :                 result_list = lappend(result_list, current_result);
     290                 :          91 :         }
     291                 :             : 
     292                 :          59 :         result->args = result_list;
     293                 :          59 :         result->location = p->location;
     294                 :             : 
     295                 :          59 :         check_agglevels_and_constraints(pstate, (Node *) result);
     296                 :             : 
     297                 :         118 :         return (Node *) result;
     298                 :          59 : }
     299                 :             : 
     300                 :             : /*
     301                 :             :  * Aggregate functions and grouping operations (which are combined in the spec
     302                 :             :  * as <set function specification>) are very similar with regard to level and
     303                 :             :  * nesting restrictions (though we allow a lot more things than the spec does).
     304                 :             :  * Centralise those restrictions here.
     305                 :             :  */
     306                 :             : static void
     307                 :        5579 : check_agglevels_and_constraints(ParseState *pstate, Node *expr)
     308                 :             : {
     309                 :        5579 :         List       *directargs = NIL;
     310                 :        5579 :         List       *args = NIL;
     311                 :        5579 :         Expr       *filter = NULL;
     312                 :        5579 :         int                     min_varlevel;
     313                 :        5579 :         int                     location = -1;
     314                 :        5579 :         Index      *p_levelsup;
     315                 :        5579 :         const char *err;
     316                 :        5579 :         bool            errkind;
     317                 :        5579 :         bool            isAgg = IsA(expr, Aggref);
     318                 :             : 
     319         [ +  + ]:        5579 :         if (isAgg)
     320                 :             :         {
     321                 :        5520 :                 Aggref     *agg = (Aggref *) expr;
     322                 :             : 
     323                 :        5520 :                 directargs = agg->aggdirectargs;
     324                 :        5520 :                 args = agg->args;
     325                 :        5520 :                 filter = agg->aggfilter;
     326                 :        5520 :                 location = agg->location;
     327                 :        5520 :                 p_levelsup = &agg->agglevelsup;
     328                 :        5520 :         }
     329                 :             :         else
     330                 :             :         {
     331                 :          59 :                 GroupingFunc *grp = (GroupingFunc *) expr;
     332                 :             : 
     333                 :          59 :                 args = grp->args;
     334                 :          59 :                 location = grp->location;
     335                 :          59 :                 p_levelsup = &grp->agglevelsup;
     336                 :          59 :         }
     337                 :             : 
     338                 :             :         /*
     339                 :             :          * Check the arguments to compute the aggregate's level and detect
     340                 :             :          * improper nesting.
     341                 :             :          */
     342                 :       11158 :         min_varlevel = check_agg_arguments(pstate,
     343                 :        5579 :                                                                            directargs,
     344                 :        5579 :                                                                            args,
     345                 :        5579 :                                                                            filter,
     346                 :        5579 :                                                                            location);
     347                 :             : 
     348                 :        5579 :         *p_levelsup = min_varlevel;
     349                 :             : 
     350                 :             :         /* Mark the correct pstate level as having aggregates */
     351         [ +  + ]:        5608 :         while (min_varlevel-- > 0)
     352                 :          29 :                 pstate = pstate->parentParseState;
     353                 :        5579 :         pstate->p_hasAggs = true;
     354                 :             : 
     355                 :             :         /*
     356                 :             :          * Check to see if the aggregate function is in an invalid place within
     357                 :             :          * its aggregation query.
     358                 :             :          *
     359                 :             :          * For brevity we support two schemes for reporting an error here: set
     360                 :             :          * "err" to a custom message, or set "errkind" true if the error context
     361                 :             :          * is sufficiently identified by what ParseExprKindName will return, *and*
     362                 :             :          * what it will return is just a SQL keyword.  (Otherwise, use a custom
     363                 :             :          * message to avoid creating translation problems.)
     364                 :             :          */
     365                 :        5579 :         err = NULL;
     366                 :        5579 :         errkind = false;
     367   [ -  +  -  -  :        5579 :         switch (pstate->p_expr_kind)
          -  -  -  -  +  
          +  -  +  +  +  
          -  -  -  -  -  
          -  -  -  -  -  
          -  +  +  +  -  
                   +  - ]
     368                 :             :         {
     369                 :             :                 case EXPR_KIND_NONE:
     370                 :           0 :                         Assert(false);          /* can't happen */
     371                 :           0 :                         break;
     372                 :             :                 case EXPR_KIND_OTHER:
     373                 :             : 
     374                 :             :                         /*
     375                 :             :                          * Accept aggregate/grouping here; caller must throw error if
     376                 :             :                          * wanted
     377                 :             :                          */
     378                 :             :                         break;
     379                 :             :                 case EXPR_KIND_JOIN_ON:
     380                 :             :                 case EXPR_KIND_JOIN_USING:
     381         [ #  # ]:           0 :                         if (isAgg)
     382                 :           0 :                                 err = _("aggregate functions are not allowed in JOIN conditions");
     383                 :             :                         else
     384                 :           0 :                                 err = _("grouping operations are not allowed in JOIN conditions");
     385                 :             : 
     386                 :           0 :                         break;
     387                 :             :                 case EXPR_KIND_FROM_SUBSELECT:
     388                 :             : 
     389                 :             :                         /*
     390                 :             :                          * Aggregate/grouping scope rules make it worth being explicit
     391                 :             :                          * here
     392                 :             :                          */
     393         [ +  - ]:           4 :                         if (isAgg)
     394                 :           4 :                                 err = _("aggregate functions are not allowed in FROM clause of their own query level");
     395                 :             :                         else
     396                 :           0 :                                 err = _("grouping operations are not allowed in FROM clause of their own query level");
     397                 :             : 
     398                 :           4 :                         break;
     399                 :             :                 case EXPR_KIND_FROM_FUNCTION:
     400         [ #  # ]:           0 :                         if (isAgg)
     401                 :           0 :                                 err = _("aggregate functions are not allowed in functions in FROM");
     402                 :             :                         else
     403                 :           0 :                                 err = _("grouping operations are not allowed in functions in FROM");
     404                 :             : 
     405                 :           0 :                         break;
     406                 :             :                 case EXPR_KIND_WHERE:
     407                 :           2 :                         errkind = true;
     408                 :           2 :                         break;
     409                 :             :                 case EXPR_KIND_POLICY:
     410         [ +  - ]:           1 :                         if (isAgg)
     411                 :           1 :                                 err = _("aggregate functions are not allowed in policy expressions");
     412                 :             :                         else
     413                 :           0 :                                 err = _("grouping operations are not allowed in policy expressions");
     414                 :             : 
     415                 :           1 :                         break;
     416                 :             :                 case EXPR_KIND_HAVING:
     417                 :             :                         /* okay */
     418                 :             :                         break;
     419                 :             :                 case EXPR_KIND_FILTER:
     420                 :           2 :                         errkind = true;
     421                 :           2 :                         break;
     422                 :             :                 case EXPR_KIND_WINDOW_PARTITION:
     423                 :             :                         /* okay */
     424                 :             :                         break;
     425                 :             :                 case EXPR_KIND_WINDOW_ORDER:
     426                 :             :                         /* okay */
     427                 :             :                         break;
     428                 :             :                 case EXPR_KIND_WINDOW_FRAME_RANGE:
     429         [ #  # ]:           0 :                         if (isAgg)
     430                 :           0 :                                 err = _("aggregate functions are not allowed in window RANGE");
     431                 :             :                         else
     432                 :           0 :                                 err = _("grouping operations are not allowed in window RANGE");
     433                 :             : 
     434                 :           0 :                         break;
     435                 :             :                 case EXPR_KIND_WINDOW_FRAME_ROWS:
     436         [ #  # ]:           0 :                         if (isAgg)
     437                 :           0 :                                 err = _("aggregate functions are not allowed in window ROWS");
     438                 :             :                         else
     439                 :           0 :                                 err = _("grouping operations are not allowed in window ROWS");
     440                 :             : 
     441                 :           0 :                         break;
     442                 :             :                 case EXPR_KIND_WINDOW_FRAME_GROUPS:
     443         [ #  # ]:           0 :                         if (isAgg)
     444                 :           0 :                                 err = _("aggregate functions are not allowed in window GROUPS");
     445                 :             :                         else
     446                 :           0 :                                 err = _("grouping operations are not allowed in window GROUPS");
     447                 :             : 
     448                 :           0 :                         break;
     449                 :             :                 case EXPR_KIND_SELECT_TARGET:
     450                 :             :                         /* okay */
     451                 :             :                         break;
     452                 :             :                 case EXPR_KIND_INSERT_TARGET:
     453                 :             :                 case EXPR_KIND_UPDATE_SOURCE:
     454                 :             :                 case EXPR_KIND_UPDATE_TARGET:
     455                 :           0 :                         errkind = true;
     456                 :           0 :                         break;
     457                 :             :                 case EXPR_KIND_MERGE_WHEN:
     458         [ #  # ]:           0 :                         if (isAgg)
     459                 :           0 :                                 err = _("aggregate functions are not allowed in MERGE WHEN conditions");
     460                 :             :                         else
     461                 :           0 :                                 err = _("grouping operations are not allowed in MERGE WHEN conditions");
     462                 :             : 
     463                 :           0 :                         break;
     464                 :             :                 case EXPR_KIND_GROUP_BY:
     465                 :           0 :                         errkind = true;
     466                 :           0 :                         break;
     467                 :             :                 case EXPR_KIND_ORDER_BY:
     468                 :             :                         /* okay */
     469                 :             :                         break;
     470                 :             :                 case EXPR_KIND_DISTINCT_ON:
     471                 :             :                         /* okay */
     472                 :             :                         break;
     473                 :             :                 case EXPR_KIND_LIMIT:
     474                 :             :                 case EXPR_KIND_OFFSET:
     475                 :           0 :                         errkind = true;
     476                 :           0 :                         break;
     477                 :             :                 case EXPR_KIND_RETURNING:
     478                 :             :                 case EXPR_KIND_MERGE_RETURNING:
     479                 :           0 :                         errkind = true;
     480                 :           0 :                         break;
     481                 :             :                 case EXPR_KIND_VALUES:
     482                 :             :                 case EXPR_KIND_VALUES_SINGLE:
     483                 :           0 :                         errkind = true;
     484                 :           0 :                         break;
     485                 :             :                 case EXPR_KIND_CHECK_CONSTRAINT:
     486                 :             :                 case EXPR_KIND_DOMAIN_CHECK:
     487         [ #  # ]:           0 :                         if (isAgg)
     488                 :           0 :                                 err = _("aggregate functions are not allowed in check constraints");
     489                 :             :                         else
     490                 :           0 :                                 err = _("grouping operations are not allowed in check constraints");
     491                 :             : 
     492                 :           0 :                         break;
     493                 :             :                 case EXPR_KIND_COLUMN_DEFAULT:
     494                 :             :                 case EXPR_KIND_FUNCTION_DEFAULT:
     495                 :             : 
     496         [ +  - ]:           1 :                         if (isAgg)
     497                 :           1 :                                 err = _("aggregate functions are not allowed in DEFAULT expressions");
     498                 :             :                         else
     499                 :           0 :                                 err = _("grouping operations are not allowed in DEFAULT expressions");
     500                 :             : 
     501                 :           1 :                         break;
     502                 :             :                 case EXPR_KIND_INDEX_EXPRESSION:
     503         [ #  # ]:           0 :                         if (isAgg)
     504                 :           0 :                                 err = _("aggregate functions are not allowed in index expressions");
     505                 :             :                         else
     506                 :           0 :                                 err = _("grouping operations are not allowed in index expressions");
     507                 :             : 
     508                 :           0 :                         break;
     509                 :             :                 case EXPR_KIND_INDEX_PREDICATE:
     510         [ #  # ]:           0 :                         if (isAgg)
     511                 :           0 :                                 err = _("aggregate functions are not allowed in index predicates");
     512                 :             :                         else
     513                 :           0 :                                 err = _("grouping operations are not allowed in index predicates");
     514                 :             : 
     515                 :           0 :                         break;
     516                 :             :                 case EXPR_KIND_STATS_EXPRESSION:
     517         [ #  # ]:           0 :                         if (isAgg)
     518                 :           0 :                                 err = _("aggregate functions are not allowed in statistics expressions");
     519                 :             :                         else
     520                 :           0 :                                 err = _("grouping operations are not allowed in statistics expressions");
     521                 :             : 
     522                 :           0 :                         break;
     523                 :             :                 case EXPR_KIND_ALTER_COL_TRANSFORM:
     524         [ #  # ]:           0 :                         if (isAgg)
     525                 :           0 :                                 err = _("aggregate functions are not allowed in transform expressions");
     526                 :             :                         else
     527                 :           0 :                                 err = _("grouping operations are not allowed in transform expressions");
     528                 :             : 
     529                 :           0 :                         break;
     530                 :             :                 case EXPR_KIND_EXECUTE_PARAMETER:
     531         [ #  # ]:           0 :                         if (isAgg)
     532                 :           0 :                                 err = _("aggregate functions are not allowed in EXECUTE parameters");
     533                 :             :                         else
     534                 :           0 :                                 err = _("grouping operations are not allowed in EXECUTE parameters");
     535                 :             : 
     536                 :           0 :                         break;
     537                 :             :                 case EXPR_KIND_TRIGGER_WHEN:
     538         [ #  # ]:           0 :                         if (isAgg)
     539                 :           0 :                                 err = _("aggregate functions are not allowed in trigger WHEN conditions");
     540                 :             :                         else
     541                 :           0 :                                 err = _("grouping operations are not allowed in trigger WHEN conditions");
     542                 :             : 
     543                 :           0 :                         break;
     544                 :             :                 case EXPR_KIND_PARTITION_BOUND:
     545         [ +  - ]:           2 :                         if (isAgg)
     546                 :           2 :                                 err = _("aggregate functions are not allowed in partition bound");
     547                 :             :                         else
     548                 :           0 :                                 err = _("grouping operations are not allowed in partition bound");
     549                 :             : 
     550                 :           2 :                         break;
     551                 :             :                 case EXPR_KIND_PARTITION_EXPRESSION:
     552         [ +  - ]:           1 :                         if (isAgg)
     553                 :           1 :                                 err = _("aggregate functions are not allowed in partition key expressions");
     554                 :             :                         else
     555                 :           0 :                                 err = _("grouping operations are not allowed in partition key expressions");
     556                 :             : 
     557                 :           1 :                         break;
     558                 :             :                 case EXPR_KIND_GENERATED_COLUMN:
     559                 :             : 
     560         [ +  - ]:           2 :                         if (isAgg)
     561                 :           2 :                                 err = _("aggregate functions are not allowed in column generation expressions");
     562                 :             :                         else
     563                 :           0 :                                 err = _("grouping operations are not allowed in column generation expressions");
     564                 :             : 
     565                 :           2 :                         break;
     566                 :             : 
     567                 :             :                 case EXPR_KIND_CALL_ARGUMENT:
     568         [ #  # ]:           0 :                         if (isAgg)
     569                 :           0 :                                 err = _("aggregate functions are not allowed in CALL arguments");
     570                 :             :                         else
     571                 :           0 :                                 err = _("grouping operations are not allowed in CALL arguments");
     572                 :             : 
     573                 :           0 :                         break;
     574                 :             : 
     575                 :             :                 case EXPR_KIND_COPY_WHERE:
     576         [ +  - ]:           1 :                         if (isAgg)
     577                 :           1 :                                 err = _("aggregate functions are not allowed in COPY FROM WHERE conditions");
     578                 :             :                         else
     579                 :           0 :                                 err = _("grouping operations are not allowed in COPY FROM WHERE conditions");
     580                 :             : 
     581                 :           1 :                         break;
     582                 :             : 
     583                 :             :                 case EXPR_KIND_CYCLE_MARK:
     584                 :           0 :                         errkind = true;
     585                 :           0 :                         break;
     586                 :             : 
     587                 :             :                         /*
     588                 :             :                          * There is intentionally no default: case here, so that the
     589                 :             :                          * compiler will warn if we add a new ParseExprKind without
     590                 :             :                          * extending this switch.  If we do see an unrecognized value at
     591                 :             :                          * runtime, the behavior will be the same as for EXPR_KIND_OTHER,
     592                 :             :                          * which is sane anyway.
     593                 :             :                          */
     594                 :             :         }
     595                 :             : 
     596         [ +  + ]:        5579 :         if (err)
     597   [ +  -  +  - ]:          12 :                 ereport(ERROR,
     598                 :             :                                 (errcode(ERRCODE_GROUPING_ERROR),
     599                 :             :                                  errmsg_internal("%s", err),
     600                 :             :                                  parser_errposition(pstate, location)));
     601                 :             : 
     602         [ +  + ]:        5567 :         if (errkind)
     603                 :             :         {
     604         [ +  - ]:           4 :                 if (isAgg)
     605                 :             :                         /* translator: %s is name of a SQL construct, eg GROUP BY */
     606                 :           4 :                         err = _("aggregate functions are not allowed in %s");
     607                 :             :                 else
     608                 :             :                         /* translator: %s is name of a SQL construct, eg GROUP BY */
     609                 :           0 :                         err = _("grouping operations are not allowed in %s");
     610                 :             : 
     611   [ -  +  +  - ]:           4 :                 ereport(ERROR,
     612                 :             :                                 (errcode(ERRCODE_GROUPING_ERROR),
     613                 :             :                                  errmsg_internal(err,
     614                 :             :                                                                  ParseExprKindName(pstate->p_expr_kind)),
     615                 :             :                                  parser_errposition(pstate, location)));
     616                 :           0 :         }
     617                 :        5563 : }
     618                 :             : 
     619                 :             : /*
     620                 :             :  * check_agg_arguments
     621                 :             :  *        Scan the arguments of an aggregate function to determine the
     622                 :             :  *        aggregate's semantic level (zero is the current select's level,
     623                 :             :  *        one is its parent, etc).
     624                 :             :  *
     625                 :             :  * The aggregate's level is the same as the level of the lowest-level variable
     626                 :             :  * or aggregate in its aggregated arguments (including any ORDER BY columns)
     627                 :             :  * or filter expression; or if it contains no variables at all, we presume it
     628                 :             :  * to be local.
     629                 :             :  *
     630                 :             :  * Vars/Aggs in direct arguments are *not* counted towards determining the
     631                 :             :  * agg's level, as those arguments aren't evaluated per-row but only
     632                 :             :  * per-group, and so in some sense aren't really agg arguments.  However,
     633                 :             :  * this can mean that we decide an agg is upper-level even when its direct
     634                 :             :  * args contain lower-level Vars/Aggs, and that case has to be disallowed.
     635                 :             :  * (This is a little strange, but the SQL standard seems pretty definite that
     636                 :             :  * direct args are not to be considered when setting the agg's level.)
     637                 :             :  *
     638                 :             :  * We also take this opportunity to detect any aggregates or window functions
     639                 :             :  * nested within the arguments.  We can throw error immediately if we find
     640                 :             :  * a window function.  Aggregates are a bit trickier because it's only an
     641                 :             :  * error if the inner aggregate is of the same semantic level as the outer,
     642                 :             :  * which we can't know until we finish scanning the arguments.
     643                 :             :  */
     644                 :             : static int
     645                 :        5578 : check_agg_arguments(ParseState *pstate,
     646                 :             :                                         List *directargs,
     647                 :             :                                         List *args,
     648                 :             :                                         Expr *filter,
     649                 :             :                                         int agglocation)
     650                 :             : {
     651                 :        5578 :         int                     agglevel;
     652                 :        5578 :         check_agg_arguments_context context;
     653                 :             : 
     654                 :        5578 :         context.pstate = pstate;
     655                 :        5578 :         context.min_varlevel = -1;      /* signifies nothing found yet */
     656                 :        5578 :         context.min_agglevel = -1;
     657                 :        5578 :         context.min_ctelevel = -1;
     658                 :        5578 :         context.min_cte = NULL;
     659                 :        5578 :         context.sublevels_up = 0;
     660                 :             : 
     661                 :        5578 :         (void) check_agg_arguments_walker((Node *) args, &context);
     662                 :        5578 :         (void) check_agg_arguments_walker((Node *) filter, &context);
     663                 :             : 
     664                 :             :         /*
     665                 :             :          * If we found no vars nor aggs at all, it's a level-zero aggregate;
     666                 :             :          * otherwise, its level is the minimum of vars or aggs.
     667                 :             :          */
     668         [ +  + ]:        5578 :         if (context.min_varlevel < 0)
     669                 :             :         {
     670         [ -  + ]:        1694 :                 if (context.min_agglevel < 0)
     671                 :        1694 :                         agglevel = 0;
     672                 :             :                 else
     673                 :           0 :                         agglevel = context.min_agglevel;
     674                 :        1694 :         }
     675         [ +  + ]:        3884 :         else if (context.min_agglevel < 0)
     676                 :        3878 :                 agglevel = context.min_varlevel;
     677                 :             :         else
     678         [ +  + ]:           6 :                 agglevel = Min(context.min_varlevel, context.min_agglevel);
     679                 :             : 
     680                 :             :         /*
     681                 :             :          * If there's a nested aggregate of the same semantic level, complain.
     682                 :             :          */
     683         [ +  + ]:        5578 :         if (agglevel == context.min_agglevel)
     684                 :             :         {
     685                 :           5 :                 int                     aggloc;
     686                 :             : 
     687                 :           5 :                 aggloc = locate_agg_of_level((Node *) args, agglevel);
     688         [ +  + ]:           5 :                 if (aggloc < 0)
     689                 :           2 :                         aggloc = locate_agg_of_level((Node *) filter, agglevel);
     690   [ +  -  +  - ]:           5 :                 ereport(ERROR,
     691                 :             :                                 (errcode(ERRCODE_GROUPING_ERROR),
     692                 :             :                                  errmsg("aggregate function calls cannot be nested"),
     693                 :             :                                  parser_errposition(pstate, aggloc)));
     694                 :           0 :         }
     695                 :             : 
     696                 :             :         /*
     697                 :             :          * If there's a non-local CTE that's below the aggregate's semantic level,
     698                 :             :          * complain.  It's not quite clear what we should do to fix up such a case
     699                 :             :          * (treating the CTE reference like a Var seems wrong), and it's also
     700                 :             :          * unclear whether there is a real-world use for such cases.
     701                 :             :          */
     702   [ +  +  +  + ]:        5573 :         if (context.min_ctelevel >= 0 && context.min_ctelevel < agglevel)
     703   [ +  -  +  - ]:           1 :                 ereport(ERROR,
     704                 :             :                                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     705                 :             :                                  errmsg("outer-level aggregate cannot use a nested CTE"),
     706                 :             :                                  errdetail("CTE \"%s\" is below the aggregate's semantic level.",
     707                 :             :                                                    context.min_cte->eref->aliasname),
     708                 :             :                                  parser_errposition(pstate, agglocation)));
     709                 :             : 
     710                 :             :         /*
     711                 :             :          * Now check for vars/aggs in the direct arguments, and throw error if
     712                 :             :          * needed.  Note that we allow a Var of the agg's semantic level, but not
     713                 :             :          * an Agg of that level.  In principle such Aggs could probably be
     714                 :             :          * supported, but it would create an ordering dependency among the
     715                 :             :          * aggregates at execution time.  Since the case appears neither to be
     716                 :             :          * required by spec nor particularly useful, we just treat it as a
     717                 :             :          * nested-aggregate situation.
     718                 :             :          */
     719         [ +  + ]:        5572 :         if (directargs)
     720                 :             :         {
     721                 :          48 :                 context.min_varlevel = -1;
     722                 :          48 :                 context.min_agglevel = -1;
     723                 :          48 :                 context.min_ctelevel = -1;
     724                 :          48 :                 (void) check_agg_arguments_walker((Node *) directargs, &context);
     725   [ +  +  +  + ]:          48 :                 if (context.min_varlevel >= 0 && context.min_varlevel < agglevel)
     726   [ +  -  +  - ]:           1 :                         ereport(ERROR,
     727                 :             :                                         (errcode(ERRCODE_GROUPING_ERROR),
     728                 :             :                                          errmsg("outer-level aggregate cannot contain a lower-level variable in its direct arguments"),
     729                 :             :                                          parser_errposition(pstate,
     730                 :             :                                                                                 locate_var_of_level((Node *) directargs,
     731                 :             :                                                                                                                         context.min_varlevel))));
     732   [ +  +  -  + ]:          47 :                 if (context.min_agglevel >= 0 && context.min_agglevel <= agglevel)
     733   [ +  -  +  - ]:           1 :                         ereport(ERROR,
     734                 :             :                                         (errcode(ERRCODE_GROUPING_ERROR),
     735                 :             :                                          errmsg("aggregate function calls cannot be nested"),
     736                 :             :                                          parser_errposition(pstate,
     737                 :             :                                                                                 locate_agg_of_level((Node *) directargs,
     738                 :             :                                                                                                                         context.min_agglevel))));
     739   [ -  +  #  # ]:          46 :                 if (context.min_ctelevel >= 0 && context.min_ctelevel < agglevel)
     740   [ #  #  #  # ]:           0 :                         ereport(ERROR,
     741                 :             :                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     742                 :             :                                          errmsg("outer-level aggregate cannot use a nested CTE"),
     743                 :             :                                          errdetail("CTE \"%s\" is below the aggregate's semantic level.",
     744                 :             :                                                            context.min_cte->eref->aliasname),
     745                 :             :                                          parser_errposition(pstate, agglocation)));
     746                 :          46 :         }
     747                 :       11140 :         return agglevel;
     748                 :        5570 : }
     749                 :             : 
     750                 :             : static bool
     751                 :       23019 : check_agg_arguments_walker(Node *node,
     752                 :             :                                                    check_agg_arguments_context *context)
     753                 :             : {
     754         [ +  + ]:       23019 :         if (node == NULL)
     755                 :        7460 :                 return false;
     756         [ +  + ]:       15559 :         if (IsA(node, Var))
     757                 :             :         {
     758                 :        4304 :                 int                     varlevelsup = ((Var *) node)->varlevelsup;
     759                 :             : 
     760                 :             :                 /* convert levelsup to frame of reference of original query */
     761                 :        4304 :                 varlevelsup -= context->sublevels_up;
     762                 :             :                 /* ignore local vars of subqueries */
     763         [ +  + ]:        4304 :                 if (varlevelsup >= 0)
     764                 :             :                 {
     765   [ +  +  +  + ]:        4281 :                         if (context->min_varlevel < 0 ||
     766                 :         390 :                                 context->min_varlevel > varlevelsup)
     767                 :        3908 :                                 context->min_varlevel = varlevelsup;
     768                 :        4281 :                 }
     769                 :        4304 :                 return false;
     770                 :        4304 :         }
     771         [ +  + ]:       11255 :         if (IsA(node, Aggref))
     772                 :             :         {
     773                 :          11 :                 int                     agglevelsup = ((Aggref *) node)->agglevelsup;
     774                 :             : 
     775                 :             :                 /* convert levelsup to frame of reference of original query */
     776                 :          11 :                 agglevelsup -= context->sublevels_up;
     777                 :             :                 /* ignore local aggs of subqueries */
     778         [ +  + ]:          11 :                 if (agglevelsup >= 0)
     779                 :             :                 {
     780   [ -  +  #  # ]:           7 :                         if (context->min_agglevel < 0 ||
     781                 :           0 :                                 context->min_agglevel > agglevelsup)
     782                 :           7 :                                 context->min_agglevel = agglevelsup;
     783                 :           7 :                 }
     784                 :             :                 /* Continue and descend into subtree */
     785                 :          11 :         }
     786         [ +  - ]:       11255 :         if (IsA(node, GroupingFunc))
     787                 :             :         {
     788                 :           0 :                 int                     agglevelsup = ((GroupingFunc *) node)->agglevelsup;
     789                 :             : 
     790                 :             :                 /* convert levelsup to frame of reference of original query */
     791                 :           0 :                 agglevelsup -= context->sublevels_up;
     792                 :             :                 /* ignore local aggs of subqueries */
     793         [ #  # ]:           0 :                 if (agglevelsup >= 0)
     794                 :             :                 {
     795   [ #  #  #  # ]:           0 :                         if (context->min_agglevel < 0 ||
     796                 :           0 :                                 context->min_agglevel > agglevelsup)
     797                 :           0 :                                 context->min_agglevel = agglevelsup;
     798                 :           0 :                 }
     799                 :             :                 /* Continue and descend into subtree */
     800                 :           0 :         }
     801                 :             : 
     802                 :             :         /*
     803                 :             :          * SRFs and window functions can be rejected immediately, unless we are
     804                 :             :          * within a sub-select within the aggregate's arguments; in that case
     805                 :             :          * they're OK.
     806                 :             :          */
     807         [ +  + ]:       11255 :         if (context->sublevels_up == 0)
     808                 :             :         {
     809   [ +  +  +  + ]:       11296 :                 if ((IsA(node, FuncExpr) && ((FuncExpr *) node)->funcretset) ||
     810         [ +  + ]:       11101 :                         (IsA(node, OpExpr) && ((OpExpr *) node)->opretset))
     811   [ +  -  +  - ]:           1 :                         ereport(ERROR,
     812                 :             :                                         (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
     813                 :             :                                          errmsg("aggregate function calls cannot contain set-returning function calls"),
     814                 :             :                                          errhint("You might be able to move the set-returning function into a LATERAL FROM item."),
     815                 :             :                                          parser_errposition(context->pstate, exprLocation(node))));
     816         [ +  - ]:       11101 :                 if (IsA(node, WindowFunc))
     817   [ #  #  #  # ]:           0 :                         ereport(ERROR,
     818                 :             :                                         (errcode(ERRCODE_GROUPING_ERROR),
     819                 :             :                                          errmsg("aggregate function calls cannot contain window function calls"),
     820                 :             :                                          parser_errposition(context->pstate,
     821                 :             :                                                                                 ((WindowFunc *) node)->location)));
     822                 :       11101 :         }
     823                 :             : 
     824         [ +  + ]:       11254 :         if (IsA(node, RangeTblEntry))
     825                 :             :         {
     826                 :          21 :                 RangeTblEntry *rte = (RangeTblEntry *) node;
     827                 :             : 
     828         [ +  + ]:          21 :                 if (rte->rtekind == RTE_CTE)
     829                 :             :                 {
     830                 :           3 :                         int                     ctelevelsup = rte->ctelevelsup;
     831                 :             : 
     832                 :             :                         /* convert levelsup to frame of reference of original query */
     833                 :           3 :                         ctelevelsup -= context->sublevels_up;
     834                 :             :                         /* ignore local CTEs of subqueries */
     835         [ -  + ]:           3 :                         if (ctelevelsup >= 0)
     836                 :             :                         {
     837   [ -  +  #  # ]:           3 :                                 if (context->min_ctelevel < 0 ||
     838                 :           0 :                                         context->min_ctelevel > ctelevelsup)
     839                 :             :                                 {
     840                 :           3 :                                         context->min_ctelevel = ctelevelsup;
     841                 :           3 :                                         context->min_cte = rte;
     842                 :           3 :                                 }
     843                 :           3 :                         }
     844                 :           3 :                 }
     845                 :          21 :                 return false;                   /* allow range_table_walker to continue */
     846                 :          21 :         }
     847         [ +  + ]:       11233 :         if (IsA(node, Query))
     848                 :             :         {
     849                 :             :                 /* Recurse into subselects */
     850                 :          22 :                 bool            result;
     851                 :             : 
     852                 :          22 :                 context->sublevels_up++;
     853                 :          22 :                 result = query_tree_walker((Query *) node,
     854                 :             :                                                                    check_agg_arguments_walker,
     855                 :             :                                                                    context,
     856                 :             :                                                                    QTW_EXAMINE_RTES_BEFORE);
     857                 :          22 :                 context->sublevels_up--;
     858                 :          22 :                 return result;
     859                 :          22 :         }
     860                 :             : 
     861                 :       11211 :         return expression_tree_walker(node,
     862                 :             :                                                                   check_agg_arguments_walker,
     863                 :             :                                                                   context);
     864                 :       23018 : }
     865                 :             : 
     866                 :             : /*
     867                 :             :  * transformWindowFuncCall -
     868                 :             :  *              Finish initial transformation of a window function call
     869                 :             :  *
     870                 :             :  * parse_func.c has recognized the function as a window function, and has set
     871                 :             :  * up all the fields of the WindowFunc except winref.  Here we must (1) add
     872                 :             :  * the WindowDef to the pstate (if not a duplicate of one already present) and
     873                 :             :  * set winref to link to it; and (2) mark p_hasWindowFuncs true in the pstate.
     874                 :             :  * Unlike aggregates, only the most closely nested pstate level need be
     875                 :             :  * considered --- there are no "outer window functions" per SQL spec.
     876                 :             :  */
     877                 :             : void
     878                 :         630 : transformWindowFuncCall(ParseState *pstate, WindowFunc *wfunc,
     879                 :             :                                                 WindowDef *windef)
     880                 :             : {
     881                 :         630 :         const char *err;
     882                 :         630 :         bool            errkind;
     883                 :             : 
     884                 :             :         /*
     885                 :             :          * A window function call can't contain another one (but aggs are OK). XXX
     886                 :             :          * is this required by spec, or just an unimplemented feature?
     887                 :             :          *
     888                 :             :          * Note: we don't need to check the filter expression here, because the
     889                 :             :          * context checks done below and in transformAggregateCall would have
     890                 :             :          * already rejected any window funcs or aggs within the filter.
     891                 :             :          */
     892   [ +  +  +  - ]:         630 :         if (pstate->p_hasWindowFuncs &&
     893                 :         177 :                 contain_windowfuncs((Node *) wfunc->args))
     894   [ #  #  #  # ]:           0 :                 ereport(ERROR,
     895                 :             :                                 (errcode(ERRCODE_WINDOWING_ERROR),
     896                 :             :                                  errmsg("window function calls cannot be nested"),
     897                 :             :                                  parser_errposition(pstate,
     898                 :             :                                                                         locate_windowfunc((Node *) wfunc->args))));
     899                 :             : 
     900                 :             :         /*
     901                 :             :          * Check to see if the window function is in an invalid place within the
     902                 :             :          * query.
     903                 :             :          *
     904                 :             :          * For brevity we support two schemes for reporting an error here: set
     905                 :             :          * "err" to a custom message, or set "errkind" true if the error context
     906                 :             :          * is sufficiently identified by what ParseExprKindName will return, *and*
     907                 :             :          * what it will return is just a SQL keyword.  (Otherwise, use a custom
     908                 :             :          * message to avoid creating translation problems.)
     909                 :             :          */
     910                 :         630 :         err = NULL;
     911                 :         630 :         errkind = false;
     912   [ -  +  +  +  :         630 :         switch (pstate->p_expr_kind)
          -  +  -  +  -  
          -  -  -  -  +  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  +  +  
                      - ]
     913                 :             :         {
     914                 :             :                 case EXPR_KIND_NONE:
     915                 :           0 :                         Assert(false);          /* can't happen */
     916                 :           0 :                         break;
     917                 :             :                 case EXPR_KIND_OTHER:
     918                 :             :                         /* Accept window func here; caller must throw error if wanted */
     919                 :             :                         break;
     920                 :             :                 case EXPR_KIND_JOIN_ON:
     921                 :             :                 case EXPR_KIND_JOIN_USING:
     922                 :           1 :                         err = _("window functions are not allowed in JOIN conditions");
     923                 :           1 :                         break;
     924                 :             :                 case EXPR_KIND_FROM_SUBSELECT:
     925                 :             :                         /* can't get here, but just in case, throw an error */
     926                 :           0 :                         errkind = true;
     927                 :           0 :                         break;
     928                 :             :                 case EXPR_KIND_FROM_FUNCTION:
     929                 :           0 :                         err = _("window functions are not allowed in functions in FROM");
     930                 :           0 :                         break;
     931                 :             :                 case EXPR_KIND_WHERE:
     932                 :           2 :                         errkind = true;
     933                 :           2 :                         break;
     934                 :             :                 case EXPR_KIND_POLICY:
     935                 :           0 :                         err = _("window functions are not allowed in policy expressions");
     936                 :           0 :                         break;
     937                 :             :                 case EXPR_KIND_HAVING:
     938                 :           0 :                         errkind = true;
     939                 :           0 :                         break;
     940                 :             :                 case EXPR_KIND_FILTER:
     941                 :           0 :                         errkind = true;
     942                 :           0 :                         break;
     943                 :             :                 case EXPR_KIND_WINDOW_PARTITION:
     944                 :             :                 case EXPR_KIND_WINDOW_ORDER:
     945                 :             :                 case EXPR_KIND_WINDOW_FRAME_RANGE:
     946                 :             :                 case EXPR_KIND_WINDOW_FRAME_ROWS:
     947                 :             :                 case EXPR_KIND_WINDOW_FRAME_GROUPS:
     948                 :           1 :                         err = _("window functions are not allowed in window definitions");
     949                 :           1 :                         break;
     950                 :             :                 case EXPR_KIND_SELECT_TARGET:
     951                 :             :                         /* okay */
     952                 :             :                         break;
     953                 :             :                 case EXPR_KIND_INSERT_TARGET:
     954                 :             :                 case EXPR_KIND_UPDATE_SOURCE:
     955                 :             :                 case EXPR_KIND_UPDATE_TARGET:
     956                 :           0 :                         errkind = true;
     957                 :           0 :                         break;
     958                 :             :                 case EXPR_KIND_MERGE_WHEN:
     959                 :           0 :                         err = _("window functions are not allowed in MERGE WHEN conditions");
     960                 :           0 :                         break;
     961                 :             :                 case EXPR_KIND_GROUP_BY:
     962                 :           0 :                         errkind = true;
     963                 :           0 :                         break;
     964                 :             :                 case EXPR_KIND_ORDER_BY:
     965                 :             :                         /* okay */
     966                 :             :                         break;
     967                 :             :                 case EXPR_KIND_DISTINCT_ON:
     968                 :             :                         /* okay */
     969                 :             :                         break;
     970                 :             :                 case EXPR_KIND_LIMIT:
     971                 :             :                 case EXPR_KIND_OFFSET:
     972                 :           0 :                         errkind = true;
     973                 :           0 :                         break;
     974                 :             :                 case EXPR_KIND_RETURNING:
     975                 :             :                 case EXPR_KIND_MERGE_RETURNING:
     976                 :           1 :                         errkind = true;
     977                 :           1 :                         break;
     978                 :             :                 case EXPR_KIND_VALUES:
     979                 :             :                 case EXPR_KIND_VALUES_SINGLE:
     980                 :           0 :                         errkind = true;
     981                 :           0 :                         break;
     982                 :             :                 case EXPR_KIND_CHECK_CONSTRAINT:
     983                 :             :                 case EXPR_KIND_DOMAIN_CHECK:
     984                 :           0 :                         err = _("window functions are not allowed in check constraints");
     985                 :           0 :                         break;
     986                 :             :                 case EXPR_KIND_COLUMN_DEFAULT:
     987                 :             :                 case EXPR_KIND_FUNCTION_DEFAULT:
     988                 :           0 :                         err = _("window functions are not allowed in DEFAULT expressions");
     989                 :           0 :                         break;
     990                 :             :                 case EXPR_KIND_INDEX_EXPRESSION:
     991                 :           0 :                         err = _("window functions are not allowed in index expressions");
     992                 :           0 :                         break;
     993                 :             :                 case EXPR_KIND_STATS_EXPRESSION:
     994                 :           0 :                         err = _("window functions are not allowed in statistics expressions");
     995                 :           0 :                         break;
     996                 :             :                 case EXPR_KIND_INDEX_PREDICATE:
     997                 :           0 :                         err = _("window functions are not allowed in index predicates");
     998                 :           0 :                         break;
     999                 :             :                 case EXPR_KIND_ALTER_COL_TRANSFORM:
    1000                 :           0 :                         err = _("window functions are not allowed in transform expressions");
    1001                 :           0 :                         break;
    1002                 :             :                 case EXPR_KIND_EXECUTE_PARAMETER:
    1003                 :           0 :                         err = _("window functions are not allowed in EXECUTE parameters");
    1004                 :           0 :                         break;
    1005                 :             :                 case EXPR_KIND_TRIGGER_WHEN:
    1006                 :           0 :                         err = _("window functions are not allowed in trigger WHEN conditions");
    1007                 :           0 :                         break;
    1008                 :             :                 case EXPR_KIND_PARTITION_BOUND:
    1009                 :           0 :                         err = _("window functions are not allowed in partition bound");
    1010                 :           0 :                         break;
    1011                 :             :                 case EXPR_KIND_PARTITION_EXPRESSION:
    1012                 :           1 :                         err = _("window functions are not allowed in partition key expressions");
    1013                 :           1 :                         break;
    1014                 :             :                 case EXPR_KIND_CALL_ARGUMENT:
    1015                 :           0 :                         err = _("window functions are not allowed in CALL arguments");
    1016                 :           0 :                         break;
    1017                 :             :                 case EXPR_KIND_COPY_WHERE:
    1018                 :           1 :                         err = _("window functions are not allowed in COPY FROM WHERE conditions");
    1019                 :           1 :                         break;
    1020                 :             :                 case EXPR_KIND_GENERATED_COLUMN:
    1021                 :           2 :                         err = _("window functions are not allowed in column generation expressions");
    1022                 :           2 :                         break;
    1023                 :             :                 case EXPR_KIND_CYCLE_MARK:
    1024                 :           0 :                         errkind = true;
    1025                 :           0 :                         break;
    1026                 :             : 
    1027                 :             :                         /*
    1028                 :             :                          * There is intentionally no default: case here, so that the
    1029                 :             :                          * compiler will warn if we add a new ParseExprKind without
    1030                 :             :                          * extending this switch.  If we do see an unrecognized value at
    1031                 :             :                          * runtime, the behavior will be the same as for EXPR_KIND_OTHER,
    1032                 :             :                          * which is sane anyway.
    1033                 :             :                          */
    1034                 :             :         }
    1035         [ +  + ]:         630 :         if (err)
    1036   [ +  -  +  - ]:           6 :                 ereport(ERROR,
    1037                 :             :                                 (errcode(ERRCODE_WINDOWING_ERROR),
    1038                 :             :                                  errmsg_internal("%s", err),
    1039                 :             :                                  parser_errposition(pstate, wfunc->location)));
    1040         [ +  + ]:         624 :         if (errkind)
    1041   [ +  -  +  - ]:           3 :                 ereport(ERROR,
    1042                 :             :                                 (errcode(ERRCODE_WINDOWING_ERROR),
    1043                 :             :                 /* translator: %s is name of a SQL construct, eg GROUP BY */
    1044                 :             :                                  errmsg("window functions are not allowed in %s",
    1045                 :             :                                                 ParseExprKindName(pstate->p_expr_kind)),
    1046                 :             :                                  parser_errposition(pstate, wfunc->location)));
    1047                 :             : 
    1048                 :             :         /*
    1049                 :             :          * If the OVER clause just specifies a window name, find that WINDOW
    1050                 :             :          * clause (which had better be present).  Otherwise, try to match all the
    1051                 :             :          * properties of the OVER clause, and make a new entry in the p_windowdefs
    1052                 :             :          * list if no luck.
    1053                 :             :          */
    1054         [ +  + ]:         621 :         if (windef->name)
    1055                 :             :         {
    1056                 :         197 :                 Index           winref = 0;
    1057                 :         197 :                 ListCell   *lc;
    1058                 :             : 
    1059         [ +  - ]:         197 :                 Assert(windef->refname == NULL &&
    1060                 :             :                            windef->partitionClause == NIL &&
    1061                 :             :                            windef->orderClause == NIL &&
    1062                 :             :                            windef->frameOptions == FRAMEOPTION_DEFAULTS);
    1063                 :             : 
    1064   [ +  -  -  +  :         401 :                 foreach(lc, pstate->p_windowdefs)
                   +  - ]
    1065                 :             :                 {
    1066                 :         204 :                         WindowDef  *refwin = (WindowDef *) lfirst(lc);
    1067                 :             : 
    1068                 :         204 :                         winref++;
    1069   [ +  -  +  + ]:         204 :                         if (refwin->name && strcmp(refwin->name, windef->name) == 0)
    1070                 :             :                         {
    1071                 :         197 :                                 wfunc->winref = winref;
    1072                 :         197 :                                 break;
    1073                 :             :                         }
    1074         [ +  + ]:         204 :                 }
    1075         [ +  - ]:         197 :                 if (lc == NULL)                 /* didn't find it? */
    1076   [ #  #  #  # ]:           0 :                         ereport(ERROR,
    1077                 :             :                                         (errcode(ERRCODE_UNDEFINED_OBJECT),
    1078                 :             :                                          errmsg("window \"%s\" does not exist", windef->name),
    1079                 :             :                                          parser_errposition(pstate, windef->location)));
    1080                 :         197 :         }
    1081                 :             :         else
    1082                 :             :         {
    1083                 :         424 :                 Index           winref = 0;
    1084                 :         424 :                 ListCell   *lc;
    1085                 :             : 
    1086   [ +  +  +  +  :         526 :                 foreach(lc, pstate->p_windowdefs)
                   +  + ]
    1087                 :             :                 {
    1088                 :         102 :                         WindowDef  *refwin = (WindowDef *) lfirst(lc);
    1089                 :             : 
    1090                 :         102 :                         winref++;
    1091   [ +  +  +  -  :         102 :                         if (refwin->refname && windef->refname &&
                   -  + ]
    1092                 :           2 :                                 strcmp(refwin->refname, windef->refname) == 0)
    1093                 :             :                                  /* matched on refname */ ;
    1094   [ +  -  +  + ]:         100 :                         else if (!refwin->refname && !windef->refname)
    1095                 :             :                                  /* matched, no refname */ ;
    1096                 :             :                         else
    1097                 :           8 :                                 continue;
    1098                 :             : 
    1099                 :             :                         /*
    1100                 :             :                          * Also see similar de-duplication code in optimize_window_clauses
    1101                 :             :                          */
    1102         [ +  + ]:          94 :                         if (equal(refwin->partitionClause, windef->partitionClause) &&
    1103         [ +  + ]:          79 :                                 equal(refwin->orderClause, windef->orderClause) &&
    1104         [ +  + ]:          69 :                                 refwin->frameOptions == windef->frameOptions &&
    1105   [ +  -  -  + ]:          42 :                                 equal(refwin->startOffset, windef->startOffset) &&
    1106                 :          42 :                                 equal(refwin->endOffset, windef->endOffset))
    1107                 :             :                         {
    1108                 :             :                                 /* found a duplicate window specification */
    1109                 :          42 :                                 wfunc->winref = winref;
    1110                 :          42 :                                 break;
    1111                 :             :                         }
    1112      [ +  +  + ]:         102 :                 }
    1113         [ +  + ]:         424 :                 if (lc == NULL)                 /* didn't find it? */
    1114                 :             :                 {
    1115                 :         382 :                         pstate->p_windowdefs = lappend(pstate->p_windowdefs, windef);
    1116                 :         382 :                         wfunc->winref = list_length(pstate->p_windowdefs);
    1117                 :         382 :                 }
    1118                 :         424 :         }
    1119                 :             : 
    1120                 :         621 :         pstate->p_hasWindowFuncs = true;
    1121                 :         621 : }
    1122                 :             : 
    1123                 :             : /*
    1124                 :             :  * parseCheckAggregates
    1125                 :             :  *      Check for aggregates where they shouldn't be and improper grouping, and
    1126                 :             :  *      replace grouped variables in the targetlist and HAVING clause with Vars
    1127                 :             :  *      that reference the RTE_GROUP RTE.
    1128                 :             :  *      This function should be called after the target list and qualifications
    1129                 :             :  *      are finalized.
    1130                 :             :  *
    1131                 :             :  *      Misplaced aggregates are now mostly detected in transformAggregateCall,
    1132                 :             :  *      but it seems more robust to check for aggregates in recursive queries
    1133                 :             :  *      only after everything is finalized.  In any case it's hard to detect
    1134                 :             :  *      improper grouping on-the-fly, so we have to make another pass over the
    1135                 :             :  *      query for that.
    1136                 :             :  */
    1137                 :             : void
    1138                 :        4938 : parseCheckAggregates(ParseState *pstate, Query *qry)
    1139                 :             : {
    1140                 :        4938 :         List       *gset_common = NIL;
    1141                 :        4938 :         List       *groupClauses = NIL;
    1142                 :        4938 :         List       *groupClauseCommonVars = NIL;
    1143                 :        4938 :         bool            have_non_var_grouping;
    1144                 :        4938 :         List       *func_grouped_rels = NIL;
    1145                 :        4938 :         ListCell   *l;
    1146                 :        4938 :         bool            hasJoinRTEs;
    1147                 :        4938 :         bool            hasSelfRefRTEs;
    1148                 :        4938 :         Node       *clause;
    1149                 :             : 
    1150                 :             :         /* This should only be called if we found aggregates or grouping */
    1151   [ +  +  +  +  :        4938 :         Assert(pstate->p_hasAggs || qry->groupClause || qry->havingQual || qry->groupingSets);
             +  +  +  - ]
    1152                 :             : 
    1153                 :             :         /*
    1154                 :             :          * If we have grouping sets, expand them and find the intersection of all
    1155                 :             :          * sets.
    1156                 :             :          */
    1157         [ +  + ]:        4938 :         if (qry->groupingSets)
    1158                 :             :         {
    1159                 :             :                 /*
    1160                 :             :                  * The limit of 4096 is arbitrary and exists simply to avoid resource
    1161                 :             :                  * issues from pathological constructs.
    1162                 :             :                  */
    1163                 :         175 :                 List       *gsets = expand_grouping_sets(qry->groupingSets, qry->groupDistinct, 4096);
    1164                 :             : 
    1165         [ +  - ]:         175 :                 if (!gsets)
    1166   [ #  #  #  #  :           0 :                         ereport(ERROR,
                   #  # ]
    1167                 :             :                                         (errcode(ERRCODE_STATEMENT_TOO_COMPLEX),
    1168                 :             :                                          errmsg("too many grouping sets present (maximum 4096)"),
    1169                 :             :                                          parser_errposition(pstate,
    1170                 :             :                                                                                 qry->groupClause
    1171                 :             :                                                                                 ? exprLocation((Node *) qry->groupClause)
    1172                 :             :                                                                                 : exprLocation((Node *) qry->groupingSets))));
    1173                 :             : 
    1174                 :             :                 /*
    1175                 :             :                  * The intersection will often be empty, so help things along by
    1176                 :             :                  * seeding the intersect with the smallest set.
    1177                 :             :                  */
    1178                 :         175 :                 gset_common = linitial(gsets);
    1179                 :             : 
    1180         [ +  + ]:         175 :                 if (gset_common)
    1181                 :             :                 {
    1182   [ +  -  +  +  :         150 :                         for_each_from(l, gsets, 1)
                   +  + ]
    1183                 :             :                         {
    1184                 :          77 :                                 gset_common = list_intersection_int(gset_common, lfirst(l));
    1185         [ +  + ]:          77 :                                 if (!gset_common)
    1186                 :          38 :                                         break;
    1187                 :          39 :                         }
    1188                 :          73 :                 }
    1189                 :             : 
    1190                 :             :                 /*
    1191                 :             :                  * If there was only one grouping set in the expansion, AND if the
    1192                 :             :                  * groupClause is non-empty (meaning that the grouping set is not
    1193                 :             :                  * empty either), then we can ditch the grouping set and pretend we
    1194                 :             :                  * just had a normal GROUP BY.
    1195                 :             :                  */
    1196   [ +  +  +  + ]:         175 :                 if (list_length(gsets) == 1 && qry->groupClause)
    1197                 :           4 :                         qry->groupingSets = NIL;
    1198                 :         175 :         }
    1199                 :             : 
    1200                 :             :         /*
    1201                 :             :          * Scan the range table to see if there are JOIN or self-reference CTE
    1202                 :             :          * entries.  We'll need this info below.
    1203                 :             :          */
    1204                 :        4938 :         hasJoinRTEs = hasSelfRefRTEs = false;
    1205   [ +  +  +  +  :       10969 :         foreach(l, pstate->p_rtable)
                   +  + ]
    1206                 :             :         {
    1207                 :        6031 :                 RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
    1208                 :             : 
    1209         [ +  + ]:        6031 :                 if (rte->rtekind == RTE_JOIN)
    1210                 :         273 :                         hasJoinRTEs = true;
    1211   [ +  +  +  + ]:        5758 :                 else if (rte->rtekind == RTE_CTE && rte->self_reference)
    1212                 :           2 :                         hasSelfRefRTEs = true;
    1213                 :        6031 :         }
    1214                 :             : 
    1215                 :             :         /*
    1216                 :             :          * Build a list of the acceptable GROUP BY expressions for use by
    1217                 :             :          * substitute_grouped_columns().
    1218                 :             :          *
    1219                 :             :          * We get the TLE, not just the expr, because GROUPING wants to know the
    1220                 :             :          * sortgroupref.
    1221                 :             :          */
    1222   [ +  +  +  +  :        6127 :         foreach(l, qry->groupClause)
                   +  + ]
    1223                 :             :         {
    1224                 :        1189 :                 SortGroupClause *grpcl = (SortGroupClause *) lfirst(l);
    1225                 :        1189 :                 TargetEntry *expr;
    1226                 :             : 
    1227                 :        1189 :                 expr = get_sortgroupclause_tle(grpcl, qry->targetList);
    1228         [ +  - ]:        1189 :                 if (expr == NULL)
    1229                 :           0 :                         continue;                       /* probably cannot happen */
    1230                 :             : 
    1231                 :        1189 :                 groupClauses = lappend(groupClauses, expr);
    1232      [ -  -  + ]:        1189 :         }
    1233                 :             : 
    1234                 :             :         /*
    1235                 :             :          * If there are join alias vars involved, we have to flatten them to the
    1236                 :             :          * underlying vars, so that aliased and unaliased vars will be correctly
    1237                 :             :          * taken as equal.  We can skip the expense of doing this if no rangetable
    1238                 :             :          * entries are RTE_JOIN kind.
    1239                 :             :          */
    1240         [ +  + ]:        4938 :         if (hasJoinRTEs)
    1241                 :         488 :                 groupClauses = (List *) flatten_join_alias_vars(NULL, qry,
    1242                 :         244 :                                                                                                                 (Node *) groupClauses);
    1243                 :             : 
    1244                 :             :         /*
    1245                 :             :          * Detect whether any of the grouping expressions aren't simple Vars; if
    1246                 :             :          * they're all Vars then we don't have to work so hard in the recursive
    1247                 :             :          * scans.  (Note we have to flatten aliases before this.)
    1248                 :             :          *
    1249                 :             :          * Track Vars that are included in all grouping sets separately in
    1250                 :             :          * groupClauseCommonVars, since these are the only ones we can use to
    1251                 :             :          * check for functional dependencies.
    1252                 :             :          */
    1253                 :        4938 :         have_non_var_grouping = false;
    1254   [ +  +  +  +  :        6127 :         foreach(l, groupClauses)
                   +  + ]
    1255                 :             :         {
    1256                 :        1189 :                 TargetEntry *tle = lfirst(l);
    1257                 :             : 
    1258         [ +  + ]:        1189 :                 if (!IsA(tle->expr, Var))
    1259                 :             :                 {
    1260                 :         227 :                         have_non_var_grouping = true;
    1261                 :         227 :                 }
    1262   [ +  +  +  + ]:         962 :                 else if (!qry->groupingSets ||
    1263                 :         294 :                                  list_member_int(gset_common, tle->ressortgroupref))
    1264                 :             :                 {
    1265                 :         699 :                         groupClauseCommonVars = lappend(groupClauseCommonVars, tle->expr);
    1266                 :         699 :                 }
    1267                 :        1189 :         }
    1268                 :             : 
    1269                 :             :         /*
    1270                 :             :          * If there are any acceptable GROUP BY expressions, build an RTE and
    1271                 :             :          * nsitem for the result of the grouping step.
    1272                 :             :          */
    1273         [ +  + ]:        4938 :         if (groupClauses)
    1274                 :             :         {
    1275                 :         700 :                 pstate->p_grouping_nsitem =
    1276                 :         700 :                         addRangeTableEntryForGroup(pstate, groupClauses);
    1277                 :             : 
    1278                 :             :                 /* Set qry->rtable again in case it was previously NIL */
    1279                 :         700 :                 qry->rtable = pstate->p_rtable;
    1280                 :             :                 /* Mark the Query as having RTE_GROUP RTE */
    1281                 :         700 :                 qry->hasGroupRTE = true;
    1282                 :         700 :         }
    1283                 :             : 
    1284                 :             :         /*
    1285                 :             :          * Replace grouped variables in the targetlist and HAVING clause with Vars
    1286                 :             :          * that reference the RTE_GROUP RTE.  Emit an error message if we find any
    1287                 :             :          * ungrouped variables.
    1288                 :             :          *
    1289                 :             :          * Note: because we check resjunk tlist elements as well as regular ones,
    1290                 :             :          * this will also find ungrouped variables that came from ORDER BY and
    1291                 :             :          * WINDOW clauses.  For that matter, it's also going to examine the
    1292                 :             :          * grouping expressions themselves --- but they'll all pass the test ...
    1293                 :             :          *
    1294                 :             :          * We also finalize GROUPING expressions, but for that we need to traverse
    1295                 :             :          * the original (unflattened) clause in order to modify nodes.
    1296                 :             :          */
    1297                 :        4938 :         clause = (Node *) qry->targetList;
    1298                 :        9876 :         finalize_grouping_exprs(clause, pstate, qry,
    1299                 :        4938 :                                                         groupClauses, hasJoinRTEs,
    1300                 :        4938 :                                                         have_non_var_grouping);
    1301         [ +  + ]:        4938 :         if (hasJoinRTEs)
    1302                 :         244 :                 clause = flatten_join_alias_vars(NULL, qry, clause);
    1303                 :        4938 :         qry->targetList = (List *)
    1304                 :        9876 :                 substitute_grouped_columns(clause, pstate, qry,
    1305                 :        4938 :                                                                    groupClauses, groupClauseCommonVars,
    1306                 :        4938 :                                                                    gset_common,
    1307                 :        4938 :                                                                    have_non_var_grouping,
    1308                 :             :                                                                    &func_grouped_rels);
    1309                 :             : 
    1310                 :        4938 :         clause = (Node *) qry->havingQual;
    1311                 :        9876 :         finalize_grouping_exprs(clause, pstate, qry,
    1312                 :        4938 :                                                         groupClauses, hasJoinRTEs,
    1313                 :        4938 :                                                         have_non_var_grouping);
    1314         [ +  + ]:        4938 :         if (hasJoinRTEs)
    1315                 :         240 :                 clause = flatten_join_alias_vars(NULL, qry, clause);
    1316                 :        4938 :         qry->havingQual =
    1317                 :        9876 :                 substitute_grouped_columns(clause, pstate, qry,
    1318                 :        4938 :                                                                    groupClauses, groupClauseCommonVars,
    1319                 :        4938 :                                                                    gset_common,
    1320                 :        4938 :                                                                    have_non_var_grouping,
    1321                 :             :                                                                    &func_grouped_rels);
    1322                 :             : 
    1323                 :             :         /*
    1324                 :             :          * Per spec, aggregates can't appear in a recursive term.
    1325                 :             :          */
    1326   [ +  +  +  + ]:        4938 :         if (pstate->p_hasAggs && hasSelfRefRTEs)
    1327   [ +  -  +  - ]:           2 :                 ereport(ERROR,
    1328                 :             :                                 (errcode(ERRCODE_INVALID_RECURSION),
    1329                 :             :                                  errmsg("aggregate functions are not allowed in a recursive query's recursive term"),
    1330                 :             :                                  parser_errposition(pstate,
    1331                 :             :                                                                         locate_agg_of_level((Node *) qry, 0))));
    1332                 :        4936 : }
    1333                 :             : 
    1334                 :             : /*
    1335                 :             :  * substitute_grouped_columns -
    1336                 :             :  *        Scan the given expression tree for grouped variables (variables that
    1337                 :             :  *        are listed in the groupClauses list) and replace them with Vars that
    1338                 :             :  *        reference the RTE_GROUP RTE.  Emit a suitable error message if any
    1339                 :             :  *        ungrouped variables (variables that are not listed in the groupClauses
    1340                 :             :  *        list and are not within the arguments of aggregate functions) are
    1341                 :             :  *        found.
    1342                 :             :  *
    1343                 :             :  * NOTE: we assume that the given clause has been transformed suitably for
    1344                 :             :  * parser output.  This means we can use expression_tree_mutator.
    1345                 :             :  *
    1346                 :             :  * NOTE: we recognize grouping expressions in the main query, but only
    1347                 :             :  * grouping Vars in subqueries.  For example, this will be rejected,
    1348                 :             :  * although it could be allowed:
    1349                 :             :  *              SELECT
    1350                 :             :  *                      (SELECT x FROM bar where y = (foo.a + foo.b))
    1351                 :             :  *              FROM foo
    1352                 :             :  *              GROUP BY a + b;
    1353                 :             :  * The difficulty is the need to account for different sublevels_up.
    1354                 :             :  * This appears to require a whole custom version of equal(), which is
    1355                 :             :  * way more pain than the feature seems worth.
    1356                 :             :  */
    1357                 :             : static Node *
    1358                 :        9859 : substitute_grouped_columns(Node *node, ParseState *pstate, Query *qry,
    1359                 :             :                                                    List *groupClauses, List *groupClauseCommonVars,
    1360                 :             :                                                    List *gset_common,
    1361                 :             :                                                    bool have_non_var_grouping,
    1362                 :             :                                                    List **func_grouped_rels)
    1363                 :             : {
    1364                 :        9859 :         substitute_grouped_columns_context context;
    1365                 :             : 
    1366                 :        9859 :         context.pstate = pstate;
    1367                 :        9859 :         context.qry = qry;
    1368                 :        9859 :         context.hasJoinRTEs = false;    /* assume caller flattened join Vars */
    1369                 :        9859 :         context.groupClauses = groupClauses;
    1370                 :        9859 :         context.groupClauseCommonVars = groupClauseCommonVars;
    1371                 :        9859 :         context.gset_common = gset_common;
    1372                 :        9859 :         context.have_non_var_grouping = have_non_var_grouping;
    1373                 :        9859 :         context.func_grouped_rels = func_grouped_rels;
    1374                 :        9859 :         context.sublevels_up = 0;
    1375                 :        9859 :         context.in_agg_direct_args = false;
    1376                 :       19718 :         return substitute_grouped_columns_mutator(node, &context);
    1377                 :        9859 : }
    1378                 :             : 
    1379                 :             : static Node *
    1380                 :       31966 : substitute_grouped_columns_mutator(Node *node,
    1381                 :             :                                                                    substitute_grouped_columns_context *context)
    1382                 :             : {
    1383                 :       31966 :         ListCell   *gl;
    1384                 :             : 
    1385         [ +  + ]:       31966 :         if (node == NULL)
    1386                 :       11045 :                 return NULL;
    1387                 :             : 
    1388         [ +  + ]:       20921 :         if (IsA(node, Aggref))
    1389                 :             :         {
    1390                 :        5478 :                 Aggref     *agg = (Aggref *) node;
    1391                 :             : 
    1392         [ +  + ]:        5478 :                 if ((int) agg->agglevelsup == context->sublevels_up)
    1393                 :             :                 {
    1394                 :             :                         /*
    1395                 :             :                          * If we find an aggregate call of the original level, do not
    1396                 :             :                          * recurse into its normal arguments, ORDER BY arguments, or
    1397                 :             :                          * filter; grouped vars there do not need to be replaced and
    1398                 :             :                          * ungrouped vars there are not an error.  But we should check
    1399                 :             :                          * direct arguments as though they weren't in an aggregate.  We
    1400                 :             :                          * set a special flag in the context to help produce a useful
    1401                 :             :                          * error message for ungrouped vars in direct arguments.
    1402                 :             :                          */
    1403                 :        5477 :                         agg = copyObject(agg);
    1404                 :             : 
    1405         [ +  - ]:        5477 :                         Assert(!context->in_agg_direct_args);
    1406                 :        5477 :                         context->in_agg_direct_args = true;
    1407                 :        5477 :                         agg->aggdirectargs = (List *)
    1408                 :       10954 :                                 substitute_grouped_columns_mutator((Node *) agg->aggdirectargs,
    1409                 :        5477 :                                                                                                    context);
    1410                 :        5477 :                         context->in_agg_direct_args = false;
    1411                 :        5477 :                         return (Node *) agg;
    1412                 :             :                 }
    1413                 :             : 
    1414                 :             :                 /*
    1415                 :             :                  * We can skip recursing into aggregates of higher levels altogether,
    1416                 :             :                  * since they could not possibly contain Vars of concern to us (see
    1417                 :             :                  * transformAggregateCall).  We do need to look at aggregates of lower
    1418                 :             :                  * levels, however.
    1419                 :             :                  */
    1420         [ -  + ]:           1 :                 if ((int) agg->agglevelsup > context->sublevels_up)
    1421                 :           0 :                         return node;
    1422         [ +  + ]:        5478 :         }
    1423                 :             : 
    1424         [ +  + ]:       15444 :         if (IsA(node, GroupingFunc))
    1425                 :             :         {
    1426                 :          64 :                 GroupingFunc *grp = (GroupingFunc *) node;
    1427                 :             : 
    1428                 :             :                 /* handled GroupingFunc separately, no need to recheck at this level */
    1429                 :             : 
    1430         [ +  + ]:          64 :                 if ((int) grp->agglevelsup >= context->sublevels_up)
    1431                 :          59 :                         return node;
    1432         [ +  + ]:          64 :         }
    1433                 :             : 
    1434                 :             :         /*
    1435                 :             :          * If we have any GROUP BY items that are not simple Vars, check to see if
    1436                 :             :          * subexpression as a whole matches any GROUP BY item. We need to do this
    1437                 :             :          * at every recursion level so that we recognize GROUPed-BY expressions
    1438                 :             :          * before reaching variables within them. But this only works at the outer
    1439                 :             :          * query level, as noted above.
    1440                 :             :          */
    1441   [ +  +  +  + ]:       15385 :         if (context->have_non_var_grouping && context->sublevels_up == 0)
    1442                 :             :         {
    1443                 :        1200 :                 int                     attnum = 0;
    1444                 :             : 
    1445   [ +  -  +  +  :        3662 :                 foreach(gl, context->groupClauses)
             +  +  +  + ]
    1446                 :             :                 {
    1447                 :        2462 :                         TargetEntry *tle = (TargetEntry *) lfirst(gl);
    1448                 :             : 
    1449                 :        2462 :                         attnum++;
    1450         [ +  + ]:        2462 :                         if (equal(node, tle->expr))
    1451                 :             :                         {
    1452                 :             :                                 /* acceptable, replace it with a GROUP Var */
    1453                 :         712 :                                 return (Node *) buildGroupedVar(attnum,
    1454                 :         356 :                                                                                                 tle->ressortgroupref,
    1455                 :         356 :                                                                                                 context);
    1456                 :             :                         }
    1457         [ +  + ]:        2462 :                 }
    1458         [ +  + ]:        1200 :         }
    1459                 :             : 
    1460                 :             :         /*
    1461                 :             :          * Constants are always acceptable.  We have to do this after we checked
    1462                 :             :          * the subexpression as a whole for a match, because it is possible that
    1463                 :             :          * we have GROUP BY items that are constants, and the constants would
    1464                 :             :          * become not so constant after the grouping step.
    1465                 :             :          */
    1466   [ +  +  +  + ]:       15029 :         if (IsA(node, Const) ||
    1467                 :       14624 :                 IsA(node, Param))
    1468                 :         437 :                 return node;
    1469                 :             : 
    1470                 :             :         /*
    1471                 :             :          * If we have an ungrouped Var of the original query level, we have a
    1472                 :             :          * failure.  Vars below the original query level are not a problem, and
    1473                 :             :          * neither are Vars from above it.  (If such Vars are ungrouped as far as
    1474                 :             :          * their own query level is concerned, that's someone else's problem...)
    1475                 :             :          */
    1476         [ +  + ]:       14592 :         if (IsA(node, Var))
    1477                 :             :         {
    1478                 :        1054 :                 Var                *var = (Var *) node;
    1479                 :        1054 :                 RangeTblEntry *rte;
    1480                 :        1054 :                 char       *attname;
    1481                 :             : 
    1482         [ +  + ]:        1054 :                 if (var->varlevelsup != context->sublevels_up)
    1483                 :          63 :                         return node;            /* it's not local to my query, ignore */
    1484                 :             : 
    1485                 :             :                 /*
    1486                 :             :                  * Check for a match, if we didn't do it above.
    1487                 :             :                  */
    1488   [ +  +  -  + ]:         991 :                 if (!context->have_non_var_grouping || context->sublevels_up != 0)
    1489                 :             :                 {
    1490                 :         990 :                         int                     attnum = 0;
    1491                 :             : 
    1492   [ +  +  +  +  :        2497 :                         foreach(gl, context->groupClauses)
             +  +  +  + ]
    1493                 :             :                         {
    1494                 :        1507 :                                 TargetEntry *tle = (TargetEntry *) lfirst(gl);
    1495                 :        1507 :                                 Var                *gvar = (Var *) tle->expr;
    1496                 :             : 
    1497                 :        1507 :                                 attnum++;
    1498         [ +  - ]:        1507 :                                 if (IsA(gvar, Var) &&
    1499         [ +  + ]:        1507 :                                         gvar->varno == var->varno &&
    1500   [ +  +  +  - ]:        1448 :                                         gvar->varattno == var->varattno &&
    1501                 :         933 :                                         gvar->varlevelsup == 0)
    1502                 :             :                                 {
    1503                 :             :                                         /* acceptable, replace it with a GROUP Var */
    1504                 :        1866 :                                         return (Node *) buildGroupedVar(attnum,
    1505                 :         933 :                                                                                                         tle->ressortgroupref,
    1506                 :         933 :                                                                                                         context);
    1507                 :             :                                 }
    1508         [ +  + ]:        1507 :                         }
    1509         [ +  + ]:         990 :                 }
    1510                 :             : 
    1511                 :             :                 /*
    1512                 :             :                  * Check whether the Var is known functionally dependent on the GROUP
    1513                 :             :                  * BY columns.  If so, we can allow the Var to be used, because the
    1514                 :             :                  * grouping is really a no-op for this table.  However, this deduction
    1515                 :             :                  * depends on one or more constraints of the table, so we have to add
    1516                 :             :                  * those constraints to the query's constraintDeps list, because it's
    1517                 :             :                  * not semantically valid anymore if the constraint(s) get dropped.
    1518                 :             :                  * (Therefore, this check must be the last-ditch effort before raising
    1519                 :             :                  * error: we don't want to add dependencies unnecessarily.)
    1520                 :             :                  *
    1521                 :             :                  * Because this is a pretty expensive check, and will have the same
    1522                 :             :                  * outcome for all columns of a table, we remember which RTEs we've
    1523                 :             :                  * already proven functional dependency for in the func_grouped_rels
    1524                 :             :                  * list.  This test also prevents us from adding duplicate entries to
    1525                 :             :                  * the constraintDeps list.
    1526                 :             :                  */
    1527         [ +  + ]:          58 :                 if (list_member_int(*context->func_grouped_rels, var->varno))
    1528                 :          23 :                         return node;            /* previously proven acceptable */
    1529                 :             : 
    1530         [ +  - ]:          35 :                 Assert(var->varno > 0 &&
    1531                 :             :                            (int) var->varno <= list_length(context->pstate->p_rtable));
    1532                 :          35 :                 rte = rt_fetch(var->varno, context->pstate->p_rtable);
    1533         [ +  + ]:          35 :                 if (rte->rtekind == RTE_RELATION)
    1534                 :             :                 {
    1535   [ +  +  +  + ]:          68 :                         if (check_functional_grouping(rte->relid,
    1536                 :          34 :                                                                                   var->varno,
    1537                 :             :                                                                                   0,
    1538                 :          34 :                                                                                   context->groupClauseCommonVars,
    1539                 :          34 :                                                                                   &context->qry->constraintDeps))
    1540                 :             :                         {
    1541                 :          19 :                                 *context->func_grouped_rels =
    1542                 :          19 :                                         lappend_int(*context->func_grouped_rels, var->varno);
    1543                 :          19 :                                 return node;    /* acceptable */
    1544                 :             :                         }
    1545                 :          15 :                 }
    1546                 :             : 
    1547                 :             :                 /* Found an ungrouped local variable; generate error message */
    1548                 :          16 :                 attname = get_rte_attribute_name(rte, var->varattno);
    1549         [ +  - ]:          16 :                 if (context->sublevels_up == 0)
    1550   [ +  -  +  -  :          16 :                         ereport(ERROR,
                   +  + ]
    1551                 :             :                                         (errcode(ERRCODE_GROUPING_ERROR),
    1552                 :             :                                          errmsg("column \"%s.%s\" must appear in the GROUP BY clause or be used in an aggregate function",
    1553                 :             :                                                         rte->eref->aliasname, attname),
    1554                 :             :                                          context->in_agg_direct_args ?
    1555                 :             :                                          errdetail("Direct arguments of an ordered-set aggregate must use only grouped columns.") : 0,
    1556                 :             :                                          parser_errposition(context->pstate, var->location)));
    1557                 :             :                 else
    1558   [ #  #  #  # ]:           0 :                         ereport(ERROR,
    1559                 :             :                                         (errcode(ERRCODE_GROUPING_ERROR),
    1560                 :             :                                          errmsg("subquery uses ungrouped column \"%s.%s\" from outer query",
    1561                 :             :                                                         rte->eref->aliasname, attname),
    1562                 :             :                                          parser_errposition(context->pstate, var->location)));
    1563         [ +  - ]:        1038 :         }
    1564                 :             : 
    1565         [ +  + ]:       13538 :         if (IsA(node, Query))
    1566                 :             :         {
    1567                 :             :                 /* Recurse into subselects */
    1568                 :          49 :                 Query      *newnode;
    1569                 :             : 
    1570                 :          49 :                 context->sublevels_up++;
    1571                 :          49 :                 newnode = query_tree_mutator((Query *) node,
    1572                 :             :                                                                          substitute_grouped_columns_mutator,
    1573                 :             :                                                                          context,
    1574                 :             :                                                                          0);
    1575                 :          49 :                 context->sublevels_up--;
    1576                 :          49 :                 return (Node *) newnode;
    1577                 :          49 :         }
    1578                 :       13489 :         return expression_tree_mutator(node, substitute_grouped_columns_mutator,
    1579                 :             :                                                                    context);
    1580                 :       31950 : }
    1581                 :             : 
    1582                 :             : /*
    1583                 :             :  * finalize_grouping_exprs -
    1584                 :             :  *        Scan the given expression tree for GROUPING() and related calls,
    1585                 :             :  *        and validate and process their arguments.
    1586                 :             :  *
    1587                 :             :  * This is split out from substitute_grouped_columns above because it needs
    1588                 :             :  * to modify the nodes (which it does in-place, not via a mutator) while
    1589                 :             :  * substitute_grouped_columns may see only a copy of the original thanks to
    1590                 :             :  * flattening of join alias vars. So here, we flatten each individual
    1591                 :             :  * GROUPING argument as we see it before comparing it.
    1592                 :             :  */
    1593                 :             : static void
    1594                 :        9860 : finalize_grouping_exprs(Node *node, ParseState *pstate, Query *qry,
    1595                 :             :                                                 List *groupClauses, bool hasJoinRTEs,
    1596                 :             :                                                 bool have_non_var_grouping)
    1597                 :             : {
    1598                 :        9860 :         substitute_grouped_columns_context context;
    1599                 :             : 
    1600                 :        9860 :         context.pstate = pstate;
    1601                 :        9860 :         context.qry = qry;
    1602                 :        9860 :         context.hasJoinRTEs = hasJoinRTEs;
    1603                 :        9860 :         context.groupClauses = groupClauses;
    1604                 :        9860 :         context.groupClauseCommonVars = NIL;
    1605                 :        9860 :         context.gset_common = NIL;
    1606                 :        9860 :         context.have_non_var_grouping = have_non_var_grouping;
    1607                 :        9860 :         context.func_grouped_rels = NULL;
    1608                 :        9860 :         context.sublevels_up = 0;
    1609                 :        9860 :         context.in_agg_direct_args = false;
    1610                 :        9860 :         finalize_grouping_exprs_walker(node, &context);
    1611                 :        9860 : }
    1612                 :             : 
    1613                 :             : static bool
    1614                 :       32221 : finalize_grouping_exprs_walker(Node *node,
    1615                 :             :                                                            substitute_grouped_columns_context *context)
    1616                 :             : {
    1617                 :       32221 :         ListCell   *gl;
    1618                 :             : 
    1619         [ +  + ]:       32221 :         if (node == NULL)
    1620                 :       11249 :                 return false;
    1621   [ +  +  +  + ]:       20972 :         if (IsA(node, Const) ||
    1622                 :       20367 :                 IsA(node, Param))
    1623                 :         639 :                 return false;                   /* constants are always acceptable */
    1624                 :             : 
    1625         [ +  + ]:       20333 :         if (IsA(node, Aggref))
    1626                 :             :         {
    1627                 :        5479 :                 Aggref     *agg = (Aggref *) node;
    1628                 :             : 
    1629         [ +  + ]:        5479 :                 if ((int) agg->agglevelsup == context->sublevels_up)
    1630                 :             :                 {
    1631                 :             :                         /*
    1632                 :             :                          * If we find an aggregate call of the original level, do not
    1633                 :             :                          * recurse into its normal arguments, ORDER BY arguments, or
    1634                 :             :                          * filter; GROUPING exprs of this level are not allowed there. But
    1635                 :             :                          * check direct arguments as though they weren't in an aggregate.
    1636                 :             :                          */
    1637                 :        5478 :                         bool            result;
    1638                 :             : 
    1639         [ +  - ]:        5478 :                         Assert(!context->in_agg_direct_args);
    1640                 :        5478 :                         context->in_agg_direct_args = true;
    1641                 :       10956 :                         result = finalize_grouping_exprs_walker((Node *) agg->aggdirectargs,
    1642                 :        5478 :                                                                                                         context);
    1643                 :        5478 :                         context->in_agg_direct_args = false;
    1644                 :        5478 :                         return result;
    1645                 :        5478 :                 }
    1646                 :             : 
    1647                 :             :                 /*
    1648                 :             :                  * We can skip recursing into aggregates of higher levels altogether,
    1649                 :             :                  * since they could not possibly contain exprs of concern to us (see
    1650                 :             :                  * transformAggregateCall).  We do need to look at aggregates of lower
    1651                 :             :                  * levels, however.
    1652                 :             :                  */
    1653         [ -  + ]:           1 :                 if ((int) agg->agglevelsup > context->sublevels_up)
    1654                 :           0 :                         return false;
    1655         [ +  + ]:        5479 :         }
    1656                 :             : 
    1657         [ +  + ]:       14855 :         if (IsA(node, GroupingFunc))
    1658                 :             :         {
    1659                 :          65 :                 GroupingFunc *grp = (GroupingFunc *) node;
    1660                 :             : 
    1661                 :             :                 /*
    1662                 :             :                  * We only need to check GroupingFunc nodes at the exact level to
    1663                 :             :                  * which they belong, since they cannot mix levels in arguments.
    1664                 :             :                  */
    1665                 :             : 
    1666         [ +  + ]:          65 :                 if ((int) grp->agglevelsup == context->sublevels_up)
    1667                 :             :                 {
    1668                 :          59 :                         ListCell   *lc;
    1669                 :          59 :                         List       *ref_list = NIL;
    1670                 :             : 
    1671   [ +  -  +  +  :         148 :                         foreach(lc, grp->args)
                   +  + ]
    1672                 :             :                         {
    1673                 :          90 :                                 Node       *expr = lfirst(lc);
    1674                 :          90 :                                 Index           ref = 0;
    1675                 :             : 
    1676         [ +  + ]:          90 :                                 if (context->hasJoinRTEs)
    1677                 :           8 :                                         expr = flatten_join_alias_vars(NULL, context->qry, expr);
    1678                 :             : 
    1679                 :             :                                 /*
    1680                 :             :                                  * Each expression must match a grouping entry at the current
    1681                 :             :                                  * query level. Unlike the general expression case, we don't
    1682                 :             :                                  * allow functional dependencies or outer references.
    1683                 :             :                                  */
    1684                 :             : 
    1685         [ +  + ]:          90 :                                 if (IsA(expr, Var))
    1686                 :             :                                 {
    1687                 :          80 :                                         Var                *var = (Var *) expr;
    1688                 :             : 
    1689         [ +  - ]:          80 :                                         if (var->varlevelsup == context->sublevels_up)
    1690                 :             :                                         {
    1691   [ +  +  -  +  :         197 :                                                 foreach(gl, context->groupClauses)
                   +  + ]
    1692                 :             :                                                 {
    1693                 :         117 :                                                         TargetEntry *tle = lfirst(gl);
    1694                 :         117 :                                                         Var                *gvar = (Var *) tle->expr;
    1695                 :             : 
    1696         [ +  - ]:         117 :                                                         if (IsA(gvar, Var) &&
    1697         [ +  + ]:         117 :                                                                 gvar->varno == var->varno &&
    1698   [ +  +  -  + ]:         115 :                                                                 gvar->varattno == var->varattno &&
    1699                 :          79 :                                                                 gvar->varlevelsup == 0)
    1700                 :             :                                                         {
    1701                 :          79 :                                                                 ref = tle->ressortgroupref;
    1702                 :          79 :                                                                 break;
    1703                 :             :                                                         }
    1704         [ +  + ]:         117 :                                                 }
    1705                 :          80 :                                         }
    1706                 :          80 :                                 }
    1707   [ +  -  -  + ]:          10 :                                 else if (context->have_non_var_grouping &&
    1708                 :          10 :                                                  context->sublevels_up == 0)
    1709                 :             :                                 {
    1710   [ +  -  -  +  :          30 :                                         foreach(gl, context->groupClauses)
                   +  - ]
    1711                 :             :                                         {
    1712                 :          20 :                                                 TargetEntry *tle = lfirst(gl);
    1713                 :             : 
    1714         [ +  + ]:          20 :                                                 if (equal(expr, tle->expr))
    1715                 :             :                                                 {
    1716                 :          10 :                                                         ref = tle->ressortgroupref;
    1717                 :          10 :                                                         break;
    1718                 :             :                                                 }
    1719         [ +  + ]:          20 :                                         }
    1720                 :          10 :                                 }
    1721                 :             : 
    1722         [ +  + ]:          90 :                                 if (ref == 0)
    1723   [ +  -  +  - ]:           1 :                                         ereport(ERROR,
    1724                 :             :                                                         (errcode(ERRCODE_GROUPING_ERROR),
    1725                 :             :                                                          errmsg("arguments to GROUPING must be grouping expressions of the associated query level"),
    1726                 :             :                                                          parser_errposition(context->pstate,
    1727                 :             :                                                                                                 exprLocation(expr))));
    1728                 :             : 
    1729                 :          89 :                                 ref_list = lappend_int(ref_list, ref);
    1730                 :          89 :                         }
    1731                 :             : 
    1732                 :          58 :                         grp->refs = ref_list;
    1733                 :          58 :                 }
    1734                 :             : 
    1735         [ +  + ]:          64 :                 if ((int) grp->agglevelsup > context->sublevels_up)
    1736                 :           1 :                         return false;
    1737         [ +  + ]:          64 :         }
    1738                 :             : 
    1739         [ +  + ]:       14853 :         if (IsA(node, Query))
    1740                 :             :         {
    1741                 :             :                 /* Recurse into subselects */
    1742                 :          65 :                 bool            result;
    1743                 :             : 
    1744                 :          65 :                 context->sublevels_up++;
    1745                 :          65 :                 result = query_tree_walker((Query *) node,
    1746                 :             :                                                                    finalize_grouping_exprs_walker,
    1747                 :             :                                                                    context,
    1748                 :             :                                                                    0);
    1749                 :          65 :                 context->sublevels_up--;
    1750                 :          65 :                 return result;
    1751                 :          65 :         }
    1752                 :       14788 :         return expression_tree_walker(node, finalize_grouping_exprs_walker,
    1753                 :             :                                                                   context);
    1754                 :       32220 : }
    1755                 :             : 
    1756                 :             : /*
    1757                 :             :  * buildGroupedVar -
    1758                 :             :  *        build a Var node that references the RTE_GROUP RTE
    1759                 :             :  */
    1760                 :             : static Var *
    1761                 :        1289 : buildGroupedVar(int attnum, Index ressortgroupref,
    1762                 :             :                                 substitute_grouped_columns_context *context)
    1763                 :             : {
    1764                 :        1289 :         Var                *var;
    1765                 :        1289 :         ParseNamespaceItem *grouping_nsitem = context->pstate->p_grouping_nsitem;
    1766                 :        1289 :         ParseNamespaceColumn *nscol = grouping_nsitem->p_nscolumns + attnum - 1;
    1767                 :             : 
    1768         [ +  - ]:        1289 :         Assert(nscol->p_varno == grouping_nsitem->p_rtindex);
    1769         [ +  - ]:        1289 :         Assert(nscol->p_varattno == attnum);
    1770                 :        2578 :         var = makeVar(nscol->p_varno,
    1771                 :        1289 :                                   nscol->p_varattno,
    1772                 :        1289 :                                   nscol->p_vartype,
    1773                 :        1289 :                                   nscol->p_vartypmod,
    1774                 :        1289 :                                   nscol->p_varcollid,
    1775                 :        1289 :                                   context->sublevels_up);
    1776                 :             :         /* makeVar doesn't offer parameters for these, so set by hand: */
    1777                 :        1289 :         var->varnosyn = nscol->p_varnosyn;
    1778                 :        1289 :         var->varattnosyn = nscol->p_varattnosyn;
    1779                 :             : 
    1780   [ +  +  +  + ]:        1289 :         if (context->qry->groupingSets &&
    1781                 :         368 :                 !list_member_int(context->gset_common, ressortgroupref))
    1782                 :         330 :                 var->varnullingrels =
    1783                 :         330 :                         bms_add_member(var->varnullingrels, grouping_nsitem->p_rtindex);
    1784                 :             : 
    1785                 :        2578 :         return var;
    1786                 :        1289 : }
    1787                 :             : 
    1788                 :             : 
    1789                 :             : /*
    1790                 :             :  * Given a GroupingSet node, expand it and return a list of lists.
    1791                 :             :  *
    1792                 :             :  * For EMPTY nodes, return a list of one empty list.
    1793                 :             :  *
    1794                 :             :  * For SIMPLE nodes, return a list of one list, which is the node content.
    1795                 :             :  *
    1796                 :             :  * For CUBE and ROLLUP nodes, return a list of the expansions.
    1797                 :             :  *
    1798                 :             :  * For SET nodes, recursively expand contained CUBE and ROLLUP.
    1799                 :             :  */
    1800                 :             : static List *
    1801                 :         846 : expand_groupingset_node(GroupingSet *gs)
    1802                 :             : {
    1803                 :         846 :         List       *result = NIL;
    1804                 :             : 
    1805   [ +  +  -  +  :         846 :         switch (gs->kind)
                   +  + ]
    1806                 :             :         {
    1807                 :             :                 case GROUPING_SET_EMPTY:
    1808                 :         110 :                         result = list_make1(NIL);
    1809                 :         110 :                         break;
    1810                 :             : 
    1811                 :             :                 case GROUPING_SET_SIMPLE:
    1812                 :         380 :                         result = list_make1(gs->content);
    1813                 :         380 :                         break;
    1814                 :             : 
    1815                 :             :                 case GROUPING_SET_ROLLUP:
    1816                 :             :                         {
    1817                 :         101 :                                 List       *rollup_val = gs->content;
    1818                 :         101 :                                 ListCell   *lc;
    1819                 :         101 :                                 int                     curgroup_size = list_length(gs->content);
    1820                 :             : 
    1821         [ +  + ]:         257 :                                 while (curgroup_size > 0)
    1822                 :             :                                 {
    1823                 :         156 :                                         List       *current_result = NIL;
    1824                 :         156 :                                         int                     i = curgroup_size;
    1825                 :             : 
    1826   [ +  -  -  +  :         367 :                                         foreach(lc, rollup_val)
                   +  - ]
    1827                 :             :                                         {
    1828                 :         211 :                                                 GroupingSet *gs_current = (GroupingSet *) lfirst(lc);
    1829                 :             : 
    1830         [ +  - ]:         211 :                                                 Assert(gs_current->kind == GROUPING_SET_SIMPLE);
    1831                 :             : 
    1832                 :         422 :                                                 current_result = list_concat(current_result,
    1833                 :         211 :                                                                                                          gs_current->content);
    1834                 :             : 
    1835                 :             :                                                 /* If we are done with making the current group, break */
    1836         [ +  + ]:         211 :                                                 if (--i == 0)
    1837                 :         156 :                                                         break;
    1838         [ +  + ]:         211 :                                         }
    1839                 :             : 
    1840                 :         156 :                                         result = lappend(result, current_result);
    1841                 :         156 :                                         --curgroup_size;
    1842                 :         156 :                                 }
    1843                 :             : 
    1844                 :         101 :                                 result = lappend(result, NIL);
    1845                 :         101 :                         }
    1846                 :         101 :                         break;
    1847                 :             : 
    1848                 :             :                 case GROUPING_SET_CUBE:
    1849                 :             :                         {
    1850                 :          60 :                                 List       *cube_list = gs->content;
    1851                 :          60 :                                 int                     number_bits = list_length(cube_list);
    1852                 :          60 :                                 uint32          num_sets;
    1853                 :          60 :                                 uint32          i;
    1854                 :             : 
    1855                 :             :                                 /* parser should cap this much lower */
    1856         [ +  - ]:          60 :                                 Assert(number_bits < 31);
    1857                 :             : 
    1858                 :          60 :                                 num_sets = (1U << number_bits);
    1859                 :             : 
    1860         [ +  + ]:         336 :                                 for (i = 0; i < num_sets; i++)
    1861                 :             :                                 {
    1862                 :         276 :                                         List       *current_result = NIL;
    1863                 :         276 :                                         ListCell   *lc;
    1864                 :         276 :                                         uint32          mask = 1U;
    1865                 :             : 
    1866   [ +  -  +  +  :         920 :                                         foreach(lc, cube_list)
                   +  + ]
    1867                 :             :                                         {
    1868                 :         644 :                                                 GroupingSet *gs_current = (GroupingSet *) lfirst(lc);
    1869                 :             : 
    1870         [ +  - ]:         644 :                                                 Assert(gs_current->kind == GROUPING_SET_SIMPLE);
    1871                 :             : 
    1872         [ +  + ]:         644 :                                                 if (mask & i)
    1873                 :         644 :                                                         current_result = list_concat(current_result,
    1874                 :         322 :                                                                                                                  gs_current->content);
    1875                 :             : 
    1876                 :         644 :                                                 mask <<= 1;
    1877                 :         644 :                                         }
    1878                 :             : 
    1879                 :         276 :                                         result = lappend(result, current_result);
    1880                 :         276 :                                 }
    1881                 :          60 :                         }
    1882                 :          60 :                         break;
    1883                 :             : 
    1884                 :             :                 case GROUPING_SET_SETS:
    1885                 :             :                         {
    1886                 :         195 :                                 ListCell   *lc;
    1887                 :             : 
    1888   [ +  -  +  +  :         667 :                                 foreach(lc, gs->content)
                   +  + ]
    1889                 :             :                                 {
    1890                 :         472 :                                         List       *current_result = expand_groupingset_node(lfirst(lc));
    1891                 :             : 
    1892                 :         472 :                                         result = list_concat(result, current_result);
    1893                 :         472 :                                 }
    1894                 :         195 :                         }
    1895                 :         195 :                         break;
    1896                 :             :         }
    1897                 :             : 
    1898                 :        1692 :         return result;
    1899                 :         846 : }
    1900                 :             : 
    1901                 :             : /* list_sort comparator to sort sub-lists by length */
    1902                 :             : static int
    1903                 :         986 : cmp_list_len_asc(const ListCell *a, const ListCell *b)
    1904                 :             : {
    1905                 :         986 :         int                     la = list_length((const List *) lfirst(a));
    1906                 :         986 :         int                     lb = list_length((const List *) lfirst(b));
    1907                 :             : 
    1908                 :        1972 :         return pg_cmp_s32(la, lb);
    1909                 :         986 : }
    1910                 :             : 
    1911                 :             : /* list_sort comparator to sort sub-lists by length and contents */
    1912                 :             : static int
    1913                 :          41 : cmp_list_len_contents_asc(const ListCell *a, const ListCell *b)
    1914                 :             : {
    1915                 :          41 :         int                     res = cmp_list_len_asc(a, b);
    1916                 :             : 
    1917         [ +  + ]:          41 :         if (res == 0)
    1918                 :             :         {
    1919                 :          13 :                 List       *la = (List *) lfirst(a);
    1920                 :          13 :                 List       *lb = (List *) lfirst(b);
    1921                 :          13 :                 ListCell   *lca;
    1922                 :          13 :                 ListCell   *lcb;
    1923                 :             : 
    1924   [ +  +  +  +  :          33 :                 forboth(lca, la, lcb, lb)
          +  +  +  +  +  
             +  +  +  +  
                      + ]
    1925                 :             :                 {
    1926                 :          20 :                         int                     va = lfirst_int(lca);
    1927                 :          20 :                         int                     vb = lfirst_int(lcb);
    1928                 :             : 
    1929         [ +  + ]:          20 :                         if (va > vb)
    1930                 :           2 :                                 return 1;
    1931         [ +  + ]:          18 :                         if (va < vb)
    1932                 :           2 :                                 return -1;
    1933         [ +  + ]:          20 :                 }
    1934         [ +  + ]:          13 :         }
    1935                 :             : 
    1936                 :          37 :         return res;
    1937                 :          41 : }
    1938                 :             : 
    1939                 :             : /*
    1940                 :             :  * Expand a groupingSets clause to a flat list of grouping sets.
    1941                 :             :  * The returned list is sorted by length, shortest sets first.
    1942                 :             :  *
    1943                 :             :  * This is mainly for the planner, but we use it here too to do
    1944                 :             :  * some consistency checks.
    1945                 :             :  */
    1946                 :             : List *
    1947                 :         348 : expand_grouping_sets(List *groupingSets, bool groupDistinct, int limit)
    1948                 :             : {
    1949                 :         348 :         List       *expanded_groups = NIL;
    1950                 :         348 :         List       *result = NIL;
    1951                 :         348 :         double          numsets = 1;
    1952                 :         348 :         ListCell   *lc;
    1953                 :             : 
    1954         [ -  + ]:         348 :         if (groupingSets == NIL)
    1955                 :           0 :                 return NIL;
    1956                 :             : 
    1957   [ +  -  +  +  :         722 :         foreach(lc, groupingSets)
             +  +  -  + ]
    1958                 :             :         {
    1959                 :         374 :                 List       *current_result = NIL;
    1960                 :         374 :                 GroupingSet *gs = lfirst(lc);
    1961                 :             : 
    1962                 :         374 :                 current_result = expand_groupingset_node(gs);
    1963                 :             : 
    1964         [ +  - ]:         374 :                 Assert(current_result != NIL);
    1965                 :             : 
    1966                 :         374 :                 numsets *= list_length(current_result);
    1967                 :             : 
    1968   [ +  +  +  - ]:         374 :                 if (limit >= 0 && numsets > limit)
    1969                 :           0 :                         return NIL;
    1970                 :             : 
    1971                 :         374 :                 expanded_groups = lappend(expanded_groups, current_result);
    1972         [ -  + ]:         374 :         }
    1973                 :             : 
    1974                 :             :         /*
    1975                 :             :          * Do cartesian product between sublists of expanded_groups. While at it,
    1976                 :             :          * remove any duplicate elements from individual grouping sets (we must
    1977                 :             :          * NOT change the number of sets though)
    1978                 :             :          */
    1979                 :             : 
    1980   [ +  -  +  +  :        1321 :         foreach(lc, (List *) linitial(expanded_groups))
                   +  + ]
    1981                 :             :         {
    1982                 :         973 :                 result = lappend(result, list_union_int(NIL, (List *) lfirst(lc)));
    1983                 :         973 :         }
    1984                 :             : 
    1985   [ +  -  +  +  :         374 :         for_each_from(lc, expanded_groups, 1)
                   +  + ]
    1986                 :             :         {
    1987                 :          26 :                 List       *p = lfirst(lc);
    1988                 :          26 :                 List       *new_result = NIL;
    1989                 :          26 :                 ListCell   *lc2;
    1990                 :             : 
    1991   [ +  -  +  +  :          78 :                 foreach(lc2, result)
                   +  + ]
    1992                 :             :                 {
    1993                 :          52 :                         List       *q = lfirst(lc2);
    1994                 :          52 :                         ListCell   *lc3;
    1995                 :             : 
    1996   [ +  -  +  +  :         164 :                         foreach(lc3, p)
                   +  + ]
    1997                 :             :                         {
    1998                 :         224 :                                 new_result = lappend(new_result,
    1999                 :         112 :                                                                          list_union_int(q, (List *) lfirst(lc3)));
    2000                 :         112 :                         }
    2001                 :          52 :                 }
    2002                 :          26 :                 result = new_result;
    2003                 :          26 :         }
    2004                 :             : 
    2005                 :             :         /* Now sort the lists by length and deduplicate if necessary */
    2006   [ +  +  -  + ]:         348 :         if (!groupDistinct || list_length(result) < 2)
    2007                 :         345 :                 list_sort(result, cmp_list_len_asc);
    2008                 :             :         else
    2009                 :             :         {
    2010                 :           3 :                 ListCell   *cell;
    2011                 :           3 :                 List       *prev;
    2012                 :             : 
    2013                 :             :                 /* Sort each groupset individually */
    2014   [ +  -  +  +  :          23 :                 foreach(cell, result)
                   +  + ]
    2015                 :          20 :                         list_sort(lfirst(cell), list_int_cmp);
    2016                 :             : 
    2017                 :             :                 /* Now sort the list of groupsets by length and contents */
    2018                 :           3 :                 list_sort(result, cmp_list_len_contents_asc);
    2019                 :             : 
    2020                 :             :                 /* Finally, remove duplicates */
    2021                 :           3 :                 prev = linitial(result);
    2022   [ +  -  +  +  :          20 :                 for_each_from(cell, result, 1)
                   +  + ]
    2023                 :             :                 {
    2024         [ +  + ]:          17 :                         if (equal(lfirst(cell), prev))
    2025                 :           9 :                                 result = foreach_delete_current(result, cell);
    2026                 :             :                         else
    2027                 :           8 :                                 prev = lfirst(cell);
    2028                 :          17 :                 }
    2029                 :           3 :         }
    2030                 :             : 
    2031                 :         348 :         return result;
    2032                 :         348 : }
    2033                 :             : 
    2034                 :             : /*
    2035                 :             :  * get_aggregate_argtypes
    2036                 :             :  *      Identify the specific datatypes passed to an aggregate call.
    2037                 :             :  *
    2038                 :             :  * Given an Aggref, extract the actual datatypes of the input arguments.
    2039                 :             :  * The input datatypes are reported in a way that matches up with the
    2040                 :             :  * aggregate's declaration, ie, any ORDER BY columns attached to a plain
    2041                 :             :  * aggregate are ignored, but we report both direct and aggregated args of
    2042                 :             :  * an ordered-set aggregate.
    2043                 :             :  *
    2044                 :             :  * Datatypes are returned into inputTypes[], which must reference an array
    2045                 :             :  * of length FUNC_MAX_ARGS.
    2046                 :             :  *
    2047                 :             :  * The function result is the number of actual arguments.
    2048                 :             :  */
    2049                 :             : int
    2050                 :       13196 : get_aggregate_argtypes(Aggref *aggref, Oid *inputTypes)
    2051                 :             : {
    2052                 :       13196 :         int                     numArguments = 0;
    2053                 :       13196 :         ListCell   *lc;
    2054                 :             : 
    2055         [ +  - ]:       13196 :         Assert(list_length(aggref->aggargtypes) <= FUNC_MAX_ARGS);
    2056                 :             : 
    2057   [ +  +  +  +  :       24154 :         foreach(lc, aggref->aggargtypes)
                   +  + ]
    2058                 :             :         {
    2059                 :       10958 :                 inputTypes[numArguments++] = lfirst_oid(lc);
    2060                 :       10958 :         }
    2061                 :             : 
    2062                 :       26392 :         return numArguments;
    2063                 :       13196 : }
    2064                 :             : 
    2065                 :             : /*
    2066                 :             :  * resolve_aggregate_transtype
    2067                 :             :  *      Identify the transition state value's datatype for an aggregate call.
    2068                 :             :  *
    2069                 :             :  * This function resolves a polymorphic aggregate's state datatype.
    2070                 :             :  * It must be passed the aggtranstype from the aggregate's catalog entry,
    2071                 :             :  * as well as the actual argument types extracted by get_aggregate_argtypes.
    2072                 :             :  * (We could fetch pg_aggregate.aggtranstype internally, but all existing
    2073                 :             :  * callers already have the value at hand, so we make them pass it.)
    2074                 :             :  */
    2075                 :             : Oid
    2076                 :       11645 : resolve_aggregate_transtype(Oid aggfuncid,
    2077                 :             :                                                         Oid aggtranstype,
    2078                 :             :                                                         Oid *inputTypes,
    2079                 :             :                                                         int numArguments)
    2080                 :             : {
    2081                 :             :         /* resolve actual type of transition state, if polymorphic */
    2082   [ +  +  +  +  :       11645 :         if (IsPolymorphicType(aggtranstype))
          +  -  +  +  +  
          +  +  +  +  +  
          +  -  +  -  +  
                      - ]
    2083                 :             :         {
    2084                 :             :                 /* have to fetch the agg's declared input types... */
    2085                 :       11645 :                 Oid                *declaredArgTypes;
    2086                 :       11645 :                 int                     agg_nargs;
    2087                 :             : 
    2088                 :       11645 :                 (void) get_func_signature(aggfuncid, &declaredArgTypes, &agg_nargs);
    2089                 :             : 
    2090                 :             :                 /*
    2091                 :             :                  * VARIADIC ANY aggs could have more actual than declared args, but
    2092                 :             :                  * such extra args can't affect polymorphic type resolution.
    2093                 :             :                  */
    2094         [ +  - ]:       11645 :                 Assert(agg_nargs <= numArguments);
    2095                 :             : 
    2096                 :         178 :                 aggtranstype = enforce_generic_type_consistency(inputTypes,
    2097                 :          89 :                                                                                                                 declaredArgTypes,
    2098                 :          89 :                                                                                                                 agg_nargs,
    2099                 :          89 :                                                                                                                 aggtranstype,
    2100                 :             :                                                                                                                 false);
    2101                 :          89 :                 pfree(declaredArgTypes);
    2102                 :          89 :         }
    2103                 :          89 :         return aggtranstype;
    2104                 :             : }
    2105                 :             : 
    2106                 :             : /*
    2107                 :             :  * agg_args_support_sendreceive
    2108                 :             :  *              Returns true if all non-byval types of aggref's args have send and
    2109                 :             :  *              receive functions.
    2110                 :             :  */
    2111                 :             : bool
    2112                 :        1750 : agg_args_support_sendreceive(Aggref *aggref)
    2113                 :             : {
    2114                 :        1750 :         ListCell   *lc;
    2115                 :             : 
    2116   [ +  -  +  +  :        3500 :         foreach(lc, aggref->args)
             +  +  +  + ]
    2117                 :             :         {
    2118                 :        1750 :                 HeapTuple       typeTuple;
    2119                 :        1750 :                 Form_pg_type pt;
    2120                 :        1750 :                 TargetEntry *tle = (TargetEntry *) lfirst(lc);
    2121                 :        1750 :                 Oid                     type = exprType((Node *) tle->expr);
    2122                 :             : 
    2123                 :             :                 /*
    2124                 :             :                  * RECORD is a special case: it has typsend/typreceive functions, but
    2125                 :             :                  * record_recv only works if passed the correct typmod to identify the
    2126                 :             :                  * specific anonymous record type.  array_agg_deserialize cannot do
    2127                 :             :                  * that, so we have to disclaim support for the case.
    2128                 :             :                  */
    2129         [ +  + ]:        1750 :                 if (type == RECORDOID)
    2130                 :           7 :                         return false;
    2131                 :             : 
    2132                 :        1743 :                 typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type));
    2133         [ +  - ]:        1743 :                 if (!HeapTupleIsValid(typeTuple))
    2134   [ #  #  #  # ]:           0 :                         elog(ERROR, "cache lookup failed for type %u", type);
    2135                 :             : 
    2136                 :        1743 :                 pt = (Form_pg_type) GETSTRUCT(typeTuple);
    2137                 :             : 
    2138   [ +  +  +  - ]:        3464 :                 if (!pt->typbyval &&
    2139         [ +  + ]:        1722 :                         (!OidIsValid(pt->typsend) || !OidIsValid(pt->typreceive)))
    2140                 :             :                 {
    2141                 :           1 :                         ReleaseSysCache(typeTuple);
    2142                 :           1 :                         return false;
    2143                 :             :                 }
    2144                 :        1742 :                 ReleaseSysCache(typeTuple);
    2145         [ +  + ]:        1750 :         }
    2146                 :        1742 :         return true;
    2147                 :        1750 : }
    2148                 :             : 
    2149                 :             : /*
    2150                 :             :  * Create an expression tree for the transition function of an aggregate.
    2151                 :             :  * This is needed so that polymorphic functions can be used within an
    2152                 :             :  * aggregate --- without the expression tree, such functions would not know
    2153                 :             :  * the datatypes they are supposed to use.  (The trees will never actually
    2154                 :             :  * be executed, however, so we can skimp a bit on correctness.)
    2155                 :             :  *
    2156                 :             :  * agg_input_types and agg_state_type identifies the input types of the
    2157                 :             :  * aggregate.  These should be resolved to actual types (ie, none should
    2158                 :             :  * ever be ANYELEMENT etc).
    2159                 :             :  * agg_input_collation is the aggregate function's input collation.
    2160                 :             :  *
    2161                 :             :  * For an ordered-set aggregate, remember that agg_input_types describes
    2162                 :             :  * the direct arguments followed by the aggregated arguments.
    2163                 :             :  *
    2164                 :             :  * transfn_oid and invtransfn_oid identify the funcs to be called; the
    2165                 :             :  * latter may be InvalidOid, however if invtransfn_oid is set then
    2166                 :             :  * transfn_oid must also be set.
    2167                 :             :  *
    2168                 :             :  * transfn_oid may also be passed as the aggcombinefn when the *transfnexpr is
    2169                 :             :  * to be used for a combine aggregate phase.  We expect invtransfn_oid to be
    2170                 :             :  * InvalidOid in this case since there is no such thing as an inverse
    2171                 :             :  * combinefn.
    2172                 :             :  *
    2173                 :             :  * Pointers to the constructed trees are returned into *transfnexpr,
    2174                 :             :  * *invtransfnexpr. If there is no invtransfn, the respective pointer is set
    2175                 :             :  * to NULL.  Since use of the invtransfn is optional, NULL may be passed for
    2176                 :             :  * invtransfnexpr.
    2177                 :             :  */
    2178                 :             : void
    2179                 :        7203 : build_aggregate_transfn_expr(Oid *agg_input_types,
    2180                 :             :                                                          int agg_num_inputs,
    2181                 :             :                                                          int agg_num_direct_inputs,
    2182                 :             :                                                          bool agg_variadic,
    2183                 :             :                                                          Oid agg_state_type,
    2184                 :             :                                                          Oid agg_input_collation,
    2185                 :             :                                                          Oid transfn_oid,
    2186                 :             :                                                          Oid invtransfn_oid,
    2187                 :             :                                                          Expr **transfnexpr,
    2188                 :             :                                                          Expr **invtransfnexpr)
    2189                 :             : {
    2190                 :        7203 :         List       *args;
    2191                 :        7203 :         FuncExpr   *fexpr;
    2192                 :        7203 :         int                     i;
    2193                 :             : 
    2194                 :             :         /*
    2195                 :             :          * Build arg list to use in the transfn FuncExpr node.
    2196                 :             :          */
    2197                 :        7203 :         args = list_make1(make_agg_arg(agg_state_type, agg_input_collation));
    2198                 :             : 
    2199         [ +  + ]:       13528 :         for (i = agg_num_direct_inputs; i < agg_num_inputs; i++)
    2200                 :             :         {
    2201                 :       12650 :                 args = lappend(args,
    2202                 :        6325 :                                            make_agg_arg(agg_input_types[i], agg_input_collation));
    2203                 :        6325 :         }
    2204                 :             : 
    2205                 :       14406 :         fexpr = makeFuncExpr(transfn_oid,
    2206                 :        7203 :                                                  agg_state_type,
    2207                 :        7203 :                                                  args,
    2208                 :             :                                                  InvalidOid,
    2209                 :        7203 :                                                  agg_input_collation,
    2210                 :             :                                                  COERCE_EXPLICIT_CALL);
    2211                 :        7203 :         fexpr->funcvariadic = agg_variadic;
    2212                 :        7203 :         *transfnexpr = (Expr *) fexpr;
    2213                 :             : 
    2214                 :             :         /*
    2215                 :             :          * Build invtransfn expression if requested, with same args as transfn
    2216                 :             :          */
    2217         [ +  + ]:        7203 :         if (invtransfnexpr != NULL)
    2218                 :             :         {
    2219         [ +  + ]:         257 :                 if (OidIsValid(invtransfn_oid))
    2220                 :             :                 {
    2221                 :         266 :                         fexpr = makeFuncExpr(invtransfn_oid,
    2222                 :         133 :                                                                  agg_state_type,
    2223                 :         133 :                                                                  args,
    2224                 :             :                                                                  InvalidOid,
    2225                 :         133 :                                                                  agg_input_collation,
    2226                 :             :                                                                  COERCE_EXPLICIT_CALL);
    2227                 :         133 :                         fexpr->funcvariadic = agg_variadic;
    2228                 :         133 :                         *invtransfnexpr = (Expr *) fexpr;
    2229                 :         133 :                 }
    2230                 :             :                 else
    2231                 :         124 :                         *invtransfnexpr = NULL;
    2232                 :         257 :         }
    2233                 :        7203 : }
    2234                 :             : 
    2235                 :             : /*
    2236                 :             :  * Like build_aggregate_transfn_expr, but creates an expression tree for the
    2237                 :             :  * serialization function of an aggregate.
    2238                 :             :  */
    2239                 :             : void
    2240                 :          56 : build_aggregate_serialfn_expr(Oid serialfn_oid,
    2241                 :             :                                                           Expr **serialfnexpr)
    2242                 :             : {
    2243                 :          56 :         List       *args;
    2244                 :          56 :         FuncExpr   *fexpr;
    2245                 :             : 
    2246                 :             :         /* serialfn always takes INTERNAL and returns BYTEA */
    2247                 :          56 :         args = list_make1(make_agg_arg(INTERNALOID, InvalidOid));
    2248                 :             : 
    2249                 :         112 :         fexpr = makeFuncExpr(serialfn_oid,
    2250                 :             :                                                  BYTEAOID,
    2251                 :          56 :                                                  args,
    2252                 :             :                                                  InvalidOid,
    2253                 :             :                                                  InvalidOid,
    2254                 :             :                                                  COERCE_EXPLICIT_CALL);
    2255                 :          56 :         *serialfnexpr = (Expr *) fexpr;
    2256                 :          56 : }
    2257                 :             : 
    2258                 :             : /*
    2259                 :             :  * Like build_aggregate_transfn_expr, but creates an expression tree for the
    2260                 :             :  * deserialization function of an aggregate.
    2261                 :             :  */
    2262                 :             : void
    2263                 :          20 : build_aggregate_deserialfn_expr(Oid deserialfn_oid,
    2264                 :             :                                                                 Expr **deserialfnexpr)
    2265                 :             : {
    2266                 :          20 :         List       *args;
    2267                 :          20 :         FuncExpr   *fexpr;
    2268                 :             : 
    2269                 :             :         /* deserialfn always takes BYTEA, INTERNAL and returns INTERNAL */
    2270                 :          20 :         args = list_make2(make_agg_arg(BYTEAOID, InvalidOid),
    2271                 :             :                                           make_agg_arg(INTERNALOID, InvalidOid));
    2272                 :             : 
    2273                 :          40 :         fexpr = makeFuncExpr(deserialfn_oid,
    2274                 :             :                                                  INTERNALOID,
    2275                 :          20 :                                                  args,
    2276                 :             :                                                  InvalidOid,
    2277                 :             :                                                  InvalidOid,
    2278                 :             :                                                  COERCE_EXPLICIT_CALL);
    2279                 :          20 :         *deserialfnexpr = (Expr *) fexpr;
    2280                 :          20 : }
    2281                 :             : 
    2282                 :             : /*
    2283                 :             :  * Like build_aggregate_transfn_expr, but creates an expression tree for the
    2284                 :             :  * final function of an aggregate, rather than the transition function.
    2285                 :             :  */
    2286                 :             : void
    2287                 :        3438 : build_aggregate_finalfn_expr(Oid *agg_input_types,
    2288                 :             :                                                          int num_finalfn_inputs,
    2289                 :             :                                                          Oid agg_state_type,
    2290                 :             :                                                          Oid agg_result_type,
    2291                 :             :                                                          Oid agg_input_collation,
    2292                 :             :                                                          Oid finalfn_oid,
    2293                 :             :                                                          Expr **finalfnexpr)
    2294                 :             : {
    2295                 :        3438 :         List       *args;
    2296                 :        3438 :         int                     i;
    2297                 :             : 
    2298                 :             :         /*
    2299                 :             :          * Build expr tree for final function
    2300                 :             :          */
    2301                 :        3438 :         args = list_make1(make_agg_arg(agg_state_type, agg_input_collation));
    2302                 :             : 
    2303                 :             :         /* finalfn may take additional args, which match agg's input types */
    2304         [ +  + ]:        5549 :         for (i = 0; i < num_finalfn_inputs - 1; i++)
    2305                 :             :         {
    2306                 :        4222 :                 args = lappend(args,
    2307                 :        2111 :                                            make_agg_arg(agg_input_types[i], agg_input_collation));
    2308                 :        2111 :         }
    2309                 :             : 
    2310                 :        6876 :         *finalfnexpr = (Expr *) makeFuncExpr(finalfn_oid,
    2311                 :        3438 :                                                                                  agg_result_type,
    2312                 :        3438 :                                                                                  args,
    2313                 :             :                                                                                  InvalidOid,
    2314                 :        3438 :                                                                                  agg_input_collation,
    2315                 :             :                                                                                  COERCE_EXPLICIT_CALL);
    2316                 :             :         /* finalfn is currently never treated as variadic */
    2317                 :        3438 : }
    2318                 :             : 
    2319                 :             : /*
    2320                 :             :  * Convenience function to build dummy argument expressions for aggregates.
    2321                 :             :  *
    2322                 :             :  * We really only care that an aggregate support function can discover its
    2323                 :             :  * actual argument types at runtime using get_fn_expr_argtype(), so it's okay
    2324                 :             :  * to use Param nodes that don't correspond to any real Param.
    2325                 :             :  */
    2326                 :             : static Node *
    2327                 :       19173 : make_agg_arg(Oid argtype, Oid argcollation)
    2328                 :             : {
    2329                 :       19173 :         Param      *argp = makeNode(Param);
    2330                 :             : 
    2331                 :       19173 :         argp->paramkind = PARAM_EXEC;
    2332                 :       19173 :         argp->paramid = -1;
    2333                 :       19173 :         argp->paramtype = argtype;
    2334                 :       19173 :         argp->paramtypmod = -1;
    2335                 :       19173 :         argp->paramcollid = argcollation;
    2336                 :       19173 :         argp->location = -1;
    2337                 :       38346 :         return (Node *) argp;
    2338                 :       19173 : }
        

Generated by: LCOV version 2.3.2-1