LCOV - differential code coverage report
Current view: top level - src/backend/parser - parse_agg.c (source / functions) Coverage Total Hit UBC GBC CBC
Current: 7a15cff1f11193467898da1c1fabf06fd2caee04 vs 84a3778c79c2d28b4dc281d03ef2ab019b16483b Lines: 76.9 % 853 656 197 656
Current Date: 2025-12-15 18:36:29 -0500 Functions: 100.0 % 24 24 24
Baseline: lcov-20251216-010103-baseline Branches: 70.1 % 740 519 221 4 515
Baseline Date: 2025-12-15 13:30:48 -0800 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(7,30] days: 81.8 % 11 9 2 9
(30,360] days: 100.0 % 9 9 9
(360..) days: 76.6 % 833 638 195 638
Function coverage date bins:
(360..) days: 100.0 % 24 24 24
Branch coverage date bins:
(7,30] days: 43.8 % 16 7 9 7
(30,360] days: 87.5 % 8 7 1 7
(360..) days: 70.5 % 716 505 211 4 501

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * parse_agg.c
                                  4                 :                :  *    handle aggregates and window functions in parser
                                  5                 :                :  *
                                  6                 :                :  * Portions Copyright (c) 1996-2025, 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
 5753 tgl@sss.pgh.pa.us         112                 :CBC       24280 : transformAggregateCall(ParseState *pstate, Aggref *agg,
                                113                 :                :                        List *args, List *aggorder, bool agg_distinct)
                                114                 :                : {
 3469                           115                 :          24280 :     List       *argtypes = NIL;
 4376                           116                 :          24280 :     List       *tlist = NIL;
                                117                 :          24280 :     List       *torder = NIL;
 5772 bruce@momjian.us          118                 :          24280 :     List       *tdistinct = NIL;
 4376 tgl@sss.pgh.pa.us         119                 :          24280 :     AttrNumber  attno = 1;
                                120                 :                :     int         save_next_resno;
                                121                 :                :     ListCell   *lc;
                                122                 :                : 
                                123         [ +  + ]:          24280 :     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                 :            159 :         int         numDirectArgs = list_length(args) - list_length(aggorder);
                                130                 :                :         List       *aargs;
                                131                 :                :         ListCell   *lc2;
                                132                 :                : 
                                133         [ -  + ]:            159 :         Assert(numDirectArgs >= 0);
                                134                 :                : 
                                135                 :            159 :         aargs = list_copy_tail(args, numDirectArgs);
                                136                 :            159 :         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   [ +  -  +  +  :            345 :         forboth(lc, aargs, lc2, aggorder)
                                     +  -  +  +  +  
                                        +  +  -  +  
                                                 + ]
                                145                 :                :         {
                                146                 :            186 :             Expr       *arg = (Expr *) lfirst(lc);
                                147                 :            186 :             SortBy     *sortby = (SortBy *) lfirst(lc2);
                                148                 :                :             TargetEntry *tle;
                                149                 :                : 
                                150                 :                :             /* We don't bother to assign column names to the entries */
                                151                 :            186 :             tle = makeTargetEntry(arg, attno++, NULL, false);
                                152                 :            186 :             tlist = lappend(tlist, tle);
                                153                 :                : 
                                154                 :            186 :             torder = addTargetToSortList(pstate, tle,
                                155                 :                :                                          torder, tlist, sortby);
                                156                 :                :         }
                                157                 :                : 
                                158                 :                :         /* Never any DISTINCT in an ordered-set agg */
                                159         [ -  + ]:            159 :         Assert(!agg_distinct);
                                160                 :                :     }
                                161                 :                :     else
                                162                 :                :     {
                                163                 :                :         /* Regular aggregate, so it has no direct args */
                                164                 :          24121 :         agg->aggdirectargs = NIL;
                                165                 :                : 
                                166                 :                :         /*
                                167                 :                :          * Transform the plain list of Exprs into a targetlist.
                                168                 :                :          */
                                169   [ +  +  +  +  :          41430 :         foreach(lc, args)
                                              +  + ]
                                170                 :                :         {
                                171                 :          17309 :             Expr       *arg = (Expr *) lfirst(lc);
                                172                 :                :             TargetEntry *tle;
                                173                 :                : 
                                174                 :                :             /* We don't bother to assign column names to the entries */
                                175                 :          17309 :             tle = makeTargetEntry(arg, attno++, NULL, false);
                                176                 :          17309 :             tlist = lappend(tlist, tle);
                                177                 :                :         }
                                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                 :          24121 :         save_next_resno = pstate->p_next_resno;
                                189                 :          24121 :         pstate->p_next_resno = attno;
                                190                 :                : 
                                191                 :          24121 :         torder = transformSortClause(pstate,
                                192                 :                :                                      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         [ +  + ]:          24121 :         if (agg_distinct)
                                201                 :                :         {
                                202                 :            278 :             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   [ +  -  +  +  :            610 :             foreach(lc, tdistinct)
                                              +  + ]
                                209                 :                :             {
                                210                 :            350 :                 SortGroupClause *sortcl = (SortGroupClause *) lfirst(lc);
                                211                 :                : 
                                212         [ -  + ]:            350 :                 if (!OidIsValid(sortcl->sortop))
                                213                 :                :                 {
 4376 tgl@sss.pgh.pa.us         214                 :UBC           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                 :                :                 }
                                223                 :                :             }
                                224                 :                :         }
                                225                 :                : 
 4376 tgl@sss.pgh.pa.us         226                 :CBC       24103 :         pstate->p_next_resno = save_next_resno;
                                227                 :                :     }
                                228                 :                : 
                                229                 :                :     /* Update the Aggref with the transformation results */
 5845                           230                 :          24262 :     agg->args = tlist;
                                231                 :          24262 :     agg->aggorder = torder;
                                232                 :          24262 :     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                 :                :      */
  771                           241   [ +  +  +  +  :          24445 :     foreach(lc, agg->aggdirectargs)
                                              +  + ]
                                242                 :                :     {
                                243                 :            183 :         Expr       *arg = (Expr *) lfirst(lc);
                                244                 :                : 
                                245                 :            183 :         argtypes = lappend_oid(argtypes, exprType((Node *) arg));
                                246                 :                :     }
                                247   [ +  +  +  +  :          42514 :     foreach(lc, tlist)
                                              +  + ]
                                248                 :                :     {
                                249                 :          18252 :         TargetEntry *tle = (TargetEntry *) lfirst(lc);
                                250                 :                : 
                                251         [ +  + ]:          18252 :         if (tle->resjunk)
                                252                 :            805 :             continue;           /* ignore junk */
                                253                 :          17447 :         argtypes = lappend_oid(argtypes, exprType((Node *) tle->expr));
                                254                 :                :     }
                                255                 :          24262 :     agg->aggargtypes = argtypes;
                                256                 :                : 
 3867 andres@anarazel.de        257                 :          24262 :     check_agglevels_and_constraints(pstate, (Node *) agg);
                                258                 :          24187 : }
                                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                 :            181 : transformGroupingFunc(ParseState *pstate, GroupingFunc *p)
                                269                 :                : {
                                270                 :                :     ListCell   *lc;
                                271                 :            181 :     List       *args = p->args;
                                272                 :            181 :     List       *result_list = NIL;
                                273                 :            181 :     GroupingFunc *result = makeNode(GroupingFunc);
                                274                 :                : 
                                275         [ -  + ]:            181 :     if (list_length(args) > 31)
 3867 andres@anarazel.de        276         [ #  # ]:UBC           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                 :                : 
 3867 andres@anarazel.de        281   [ +  -  +  +  :CBC         460 :     foreach(lc, args)
                                              +  + ]
                                282                 :                :     {
                                283                 :                :         Node       *current_result;
                                284                 :                : 
 3860 bruce@momjian.us          285                 :            279 :         current_result = transformExpr(pstate, (Node *) lfirst(lc), pstate->p_expr_kind);
                                286                 :                : 
                                287                 :                :         /* acceptability of expressions is checked later */
                                288                 :                : 
 3867 andres@anarazel.de        289                 :            279 :         result_list = lappend(result_list, current_result);
                                290                 :                :     }
                                291                 :                : 
                                292                 :            181 :     result->args = result_list;
                                293                 :            181 :     result->location = p->location;
                                294                 :                : 
                                295                 :            181 :     check_agglevels_and_constraints(pstate, (Node *) result);
                                296                 :                : 
                                297                 :            181 :     return (Node *) result;
                                298                 :                : }
                                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                 :          24443 : check_agglevels_and_constraints(ParseState *pstate, Node *expr)
                                308                 :                : {
                                309                 :          24443 :     List       *directargs = NIL;
                                310                 :          24443 :     List       *args = NIL;
                                311                 :          24443 :     Expr       *filter = NULL;
                                312                 :                :     int         min_varlevel;
                                313                 :          24443 :     int         location = -1;
                                314                 :                :     Index      *p_levelsup;
                                315                 :                :     const char *err;
                                316                 :                :     bool        errkind;
                                317                 :          24443 :     bool        isAgg = IsA(expr, Aggref);
                                318                 :                : 
                                319         [ +  + ]:          24443 :     if (isAgg)
                                320                 :                :     {
 3860 bruce@momjian.us          321                 :          24262 :         Aggref     *agg = (Aggref *) expr;
                                322                 :                : 
 3867 andres@anarazel.de        323                 :          24262 :         directargs = agg->aggdirectargs;
                                324                 :          24262 :         args = agg->args;
                                325                 :          24262 :         filter = agg->aggfilter;
                                326                 :          24262 :         location = agg->location;
                                327                 :          24262 :         p_levelsup = &agg->agglevelsup;
                                328                 :                :     }
                                329                 :                :     else
                                330                 :                :     {
                                331                 :            181 :         GroupingFunc *grp = (GroupingFunc *) expr;
                                332                 :                : 
                                333                 :            181 :         args = grp->args;
                                334                 :            181 :         location = grp->location;
                                335                 :            181 :         p_levelsup = &grp->agglevelsup;
                                336                 :                :     }
                                337                 :                : 
                                338                 :                :     /*
                                339                 :                :      * Check the arguments to compute the aggregate's level and detect
                                340                 :                :      * improper nesting.
                                341                 :                :      */
 4376 tgl@sss.pgh.pa.us         342                 :          24443 :     min_varlevel = check_agg_arguments(pstate,
                                343                 :                :                                        directargs,
                                344                 :                :                                        args,
                                345                 :                :                                        filter,
                                346                 :                :                                        location);
                                347                 :                : 
 3867 andres@anarazel.de        348                 :          24416 :     *p_levelsup = min_varlevel;
                                349                 :                : 
                                350                 :                :     /* Mark the correct pstate level as having aggregates */
 4876 tgl@sss.pgh.pa.us         351         [ +  + ]:          24508 :     while (min_varlevel-- > 0)
                                352                 :             92 :         pstate = pstate->parentParseState;
                                353                 :          24416 :     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                 :          24416 :     err = NULL;
                                366                 :          24416 :     errkind = false;
                                367   [ -  -  -  +  :          24416 :     switch (pstate->p_expr_kind)
                                     -  +  +  +  +  
                                     -  +  -  -  -  
                                     +  -  -  -  +  
                                     -  -  -  -  -  
                                     +  -  -  -  -  
                                     -  -  +  +  +  
                                        -  +  -  - ]
                                368                 :                :     {
 4876 tgl@sss.pgh.pa.us         369                 :UBC           0 :         case EXPR_KIND_NONE:
                                370                 :              0 :             Assert(false);      /* can't happen */
                                371                 :                :             break;
                                372                 :              0 :         case EXPR_KIND_OTHER:
                                373                 :                : 
                                374                 :                :             /*
                                375                 :                :              * Accept aggregate/grouping here; caller must throw error if
                                376                 :                :              * wanted
                                377                 :                :              */
                                378                 :              0 :             break;
                                379                 :              0 :         case EXPR_KIND_JOIN_ON:
                                380                 :                :         case EXPR_KIND_JOIN_USING:
 3867 andres@anarazel.de        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                 :                : 
 4876 tgl@sss.pgh.pa.us         386                 :              0 :             break;
 4876 tgl@sss.pgh.pa.us         387                 :CBC          12 :         case EXPR_KIND_FROM_SUBSELECT:
                                388                 :                : 
                                389                 :                :             /*
                                390                 :                :              * Aggregate/grouping scope rules make it worth being explicit
                                391                 :                :              * here
                                392                 :                :              */
 3867 andres@anarazel.de        393         [ +  - ]:             12 :             if (isAgg)
                                394                 :             12 :                 err = _("aggregate functions are not allowed in FROM clause of their own query level");
                                395                 :                :             else
 3867 andres@anarazel.de        396                 :UBC           0 :                 err = _("grouping operations are not allowed in FROM clause of their own query level");
                                397                 :                : 
 4876 tgl@sss.pgh.pa.us         398                 :CBC          12 :             break;
 4876 tgl@sss.pgh.pa.us         399                 :UBC           0 :         case EXPR_KIND_FROM_FUNCTION:
 3867 andres@anarazel.de        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                 :                : 
 4876 tgl@sss.pgh.pa.us         405                 :              0 :             break;
 4876 tgl@sss.pgh.pa.us         406                 :CBC           6 :         case EXPR_KIND_WHERE:
                                407                 :              6 :             errkind = true;
 3793 mail@joeconway.com        408                 :              6 :             break;
                                409                 :              3 :         case EXPR_KIND_POLICY:
                                410         [ +  - ]:              3 :             if (isAgg)
                                411                 :              3 :                 err = _("aggregate functions are not allowed in policy expressions");
                                412                 :                :             else
 3793 mail@joeconway.com        413                 :UBC           0 :                 err = _("grouping operations are not allowed in policy expressions");
                                414                 :                : 
 4876 tgl@sss.pgh.pa.us         415                 :CBC           3 :             break;
                                416                 :            341 :         case EXPR_KIND_HAVING:
                                417                 :                :             /* okay */
                                418                 :            341 :             break;
 4536 noah@leadboat.com         419                 :              6 :         case EXPR_KIND_FILTER:
                                420                 :              6 :             errkind = true;
                                421                 :              6 :             break;
 4876 tgl@sss.pgh.pa.us         422                 :UBC           0 :         case EXPR_KIND_WINDOW_PARTITION:
                                423                 :                :             /* okay */
                                424                 :              0 :             break;
 4876 tgl@sss.pgh.pa.us         425                 :CBC           6 :         case EXPR_KIND_WINDOW_ORDER:
                                426                 :                :             /* okay */
                                427                 :              6 :             break;
 4876 tgl@sss.pgh.pa.us         428                 :UBC           0 :         case EXPR_KIND_WINDOW_FRAME_RANGE:
 3867 andres@anarazel.de        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                 :                : 
 4876 tgl@sss.pgh.pa.us         434                 :              0 :             break;
                                435                 :              0 :         case EXPR_KIND_WINDOW_FRAME_ROWS:
 3867 andres@anarazel.de        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                 :                : 
 2869 tgl@sss.pgh.pa.us         441                 :              0 :             break;
                                442                 :              0 :         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                 :                : 
 4876                           448                 :              0 :             break;
 4876 tgl@sss.pgh.pa.us         449                 :CBC       23981 :         case EXPR_KIND_SELECT_TARGET:
                                450                 :                :             /* okay */
                                451                 :          23981 :             break;
 4876 tgl@sss.pgh.pa.us         452                 :UBC           0 :         case EXPR_KIND_INSERT_TARGET:
                                453                 :                :         case EXPR_KIND_UPDATE_SOURCE:
                                454                 :                :         case EXPR_KIND_UPDATE_TARGET:
                                455                 :              0 :             errkind = true;
 1359 alvherre@alvh.no-ip.      456                 :              0 :             break;
                                457                 :              0 :         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                 :                : 
 4876 tgl@sss.pgh.pa.us         463                 :              0 :             break;
                                464                 :              0 :         case EXPR_KIND_GROUP_BY:
                                465                 :              0 :             errkind = true;
                                466                 :              0 :             break;
 4876 tgl@sss.pgh.pa.us         467                 :CBC          40 :         case EXPR_KIND_ORDER_BY:
                                468                 :                :             /* okay */
                                469                 :             40 :             break;
 4876 tgl@sss.pgh.pa.us         470                 :UBC           0 :         case EXPR_KIND_DISTINCT_ON:
                                471                 :                :             /* okay */
                                472                 :              0 :             break;
                                473                 :              0 :         case EXPR_KIND_LIMIT:
                                474                 :                :         case EXPR_KIND_OFFSET:
                                475                 :              0 :             errkind = true;
                                476                 :              0 :             break;
                                477                 :              0 :         case EXPR_KIND_RETURNING:
                                478                 :                :         case EXPR_KIND_MERGE_RETURNING:
                                479                 :              0 :             errkind = true;
                                480                 :              0 :             break;
                                481                 :              0 :         case EXPR_KIND_VALUES:
                                482                 :                :         case EXPR_KIND_VALUES_SINGLE:
                                483                 :              0 :             errkind = true;
                                484                 :              0 :             break;
                                485                 :              0 :         case EXPR_KIND_CHECK_CONSTRAINT:
                                486                 :                :         case EXPR_KIND_DOMAIN_CHECK:
 3867 andres@anarazel.de        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                 :                : 
 4876 tgl@sss.pgh.pa.us         492                 :              0 :             break;
 4876 tgl@sss.pgh.pa.us         493                 :CBC           3 :         case EXPR_KIND_COLUMN_DEFAULT:
                                494                 :                :         case EXPR_KIND_FUNCTION_DEFAULT:
                                495                 :                : 
 3867 andres@anarazel.de        496         [ +  - ]:              3 :             if (isAgg)
                                497                 :              3 :                 err = _("aggregate functions are not allowed in DEFAULT expressions");
                                498                 :                :             else
 3867 andres@anarazel.de        499                 :UBC           0 :                 err = _("grouping operations are not allowed in DEFAULT expressions");
                                500                 :                : 
 4876 tgl@sss.pgh.pa.us         501                 :CBC           3 :             break;
 4876 tgl@sss.pgh.pa.us         502                 :UBC           0 :         case EXPR_KIND_INDEX_EXPRESSION:
 3867 andres@anarazel.de        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                 :                : 
 4876 tgl@sss.pgh.pa.us         508                 :              0 :             break;
                                509                 :              0 :         case EXPR_KIND_INDEX_PREDICATE:
 3867 andres@anarazel.de        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                 :                : 
 1726 tomas.vondra@postgre      515                 :              0 :             break;
                                516                 :              0 :         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                 :                : 
 4876 tgl@sss.pgh.pa.us         522                 :              0 :             break;
                                523                 :              0 :         case EXPR_KIND_ALTER_COL_TRANSFORM:
 3867 andres@anarazel.de        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                 :                : 
 4876 tgl@sss.pgh.pa.us         529                 :              0 :             break;
                                530                 :              0 :         case EXPR_KIND_EXECUTE_PARAMETER:
 3867 andres@anarazel.de        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                 :                : 
 4876 tgl@sss.pgh.pa.us         536                 :              0 :             break;
                                537                 :              0 :         case EXPR_KIND_TRIGGER_WHEN:
 3867 andres@anarazel.de        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                 :                : 
 2517 peter@eisentraut.org      543                 :              0 :             break;
 2517 peter@eisentraut.org      544                 :CBC           6 :         case EXPR_KIND_PARTITION_BOUND:
                                545         [ +  - ]:              6 :             if (isAgg)
                                546                 :              6 :                 err = _("aggregate functions are not allowed in partition bound");
                                547                 :                :             else
 2517 peter@eisentraut.org      548                 :UBC           0 :                 err = _("grouping operations are not allowed in partition bound");
                                549                 :                : 
 4876 tgl@sss.pgh.pa.us         550                 :CBC           6 :             break;
 3296 rhaas@postgresql.org      551                 :              3 :         case EXPR_KIND_PARTITION_EXPRESSION:
                                552         [ +  - ]:              3 :             if (isAgg)
 2866 tgl@sss.pgh.pa.us         553                 :              3 :                 err = _("aggregate functions are not allowed in partition key expressions");
                                554                 :                :             else
 2866 tgl@sss.pgh.pa.us         555                 :UBC           0 :                 err = _("grouping operations are not allowed in partition key expressions");
                                556                 :                : 
 3296 rhaas@postgresql.org      557                 :CBC           3 :             break;
 2453 peter@eisentraut.org      558                 :              6 :         case EXPR_KIND_GENERATED_COLUMN:
                                559                 :                : 
                                560         [ +  - ]:              6 :             if (isAgg)
                                561                 :              6 :                 err = _("aggregate functions are not allowed in column generation expressions");
                                562                 :                :             else
 2453 peter@eisentraut.org      563                 :UBC           0 :                 err = _("grouping operations are not allowed in column generation expressions");
                                564                 :                : 
 2453 peter@eisentraut.org      565                 :CBC           6 :             break;
                                566                 :                : 
 2866 tgl@sss.pgh.pa.us         567                 :UBC           0 :         case EXPR_KIND_CALL_ARGUMENT:
 2938 peter_e@gmx.net           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                 :                : 
 2523 tomas.vondra@postgre      575                 :CBC           3 :         case EXPR_KIND_COPY_WHERE:
                                576         [ +  - ]:              3 :             if (isAgg)
                                577                 :              3 :                 err = _("aggregate functions are not allowed in COPY FROM WHERE conditions");
                                578                 :                :             else
 2523 tomas.vondra@postgre      579                 :UBC           0 :                 err = _("grouping operations are not allowed in COPY FROM WHERE conditions");
                                580                 :                : 
 2523 tomas.vondra@postgre      581                 :CBC           3 :             break;
                                582                 :                : 
 1779 peter@eisentraut.org      583                 :UBC           0 :         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                 :                : 
 4876 tgl@sss.pgh.pa.us         596         [ +  + ]:CBC       24416 :     if (err)
 6197                           597         [ +  - ]:             36 :         ereport(ERROR,
                                598                 :                :                 (errcode(ERRCODE_GROUPING_ERROR),
                                599                 :                :                  errmsg_internal("%s", err),
                                600                 :                :                  parser_errposition(pstate, location)));
                                601                 :                : 
 4876                           602         [ +  + ]:          24380 :     if (errkind)
                                603                 :                :     {
 3867 andres@anarazel.de        604         [ +  - ]:             12 :         if (isAgg)
                                605                 :                :             /* translator: %s is name of a SQL construct, eg GROUP BY */
                                606                 :             12 :             err = _("aggregate functions are not allowed in %s");
                                607                 :                :         else
                                608                 :                :             /* translator: %s is name of a SQL construct, eg GROUP BY */
 3867 andres@anarazel.de        609                 :UBC           0 :             err = _("grouping operations are not allowed in %s");
                                610                 :                : 
 4876 tgl@sss.pgh.pa.us         611         [ +  - ]:CBC          12 :         ereport(ERROR,
                                612                 :                :                 (errcode(ERRCODE_GROUPING_ERROR),
                                613                 :                :                  errmsg_internal(err,
                                614                 :                :                                  ParseExprKindName(pstate->p_expr_kind)),
                                615                 :                :                  parser_errposition(pstate, location)));
                                616                 :                :     }
                                617                 :          24368 : }
                                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
 4376                           645                 :          24443 : check_agg_arguments(ParseState *pstate,
                                646                 :                :                     List *directargs,
                                647                 :                :                     List *args,
                                648                 :                :                     Expr *filter,
                                649                 :                :                     int agglocation)
                                650                 :                : {
                                651                 :                :     int         agglevel;
                                652                 :                :     check_agg_arguments_context context;
                                653                 :                : 
 4876                           654                 :          24443 :     context.pstate = pstate;
                                655                 :          24443 :     context.min_varlevel = -1;  /* signifies nothing found yet */
                                656                 :          24443 :     context.min_agglevel = -1;
   28                           657                 :          24443 :     context.min_ctelevel = -1;
                                658                 :          24443 :     context.min_cte = NULL;
 4876                           659                 :          24443 :     context.sublevels_up = 0;
                                660                 :                : 
 1581                           661                 :          24443 :     (void) check_agg_arguments_walker((Node *) args, &context);
                                662                 :          24440 :     (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                 :                :      */
 4876                           668         [ +  + ]:          24440 :     if (context.min_varlevel < 0)
                                669                 :                :     {
                                670         [ +  - ]:           9865 :         if (context.min_agglevel < 0)
 4376                           671                 :           9865 :             agglevel = 0;
                                672                 :                :         else
 4376 tgl@sss.pgh.pa.us         673                 :UBC           0 :             agglevel = context.min_agglevel;
                                674                 :                :     }
 4876 tgl@sss.pgh.pa.us         675         [ +  + ]:CBC       14575 :     else if (context.min_agglevel < 0)
                                676                 :          14557 :         agglevel = context.min_varlevel;
                                677                 :                :     else
                                678                 :             18 :         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         [ +  + ]:          24440 :     if (agglevel == context.min_agglevel)
                                684                 :                :     {
                                685                 :                :         int         aggloc;
                                686                 :                : 
 4376                           687                 :             15 :         aggloc = locate_agg_of_level((Node *) args, agglevel);
                                688         [ +  + ]:             15 :         if (aggloc < 0)
                                689                 :              6 :             aggloc = locate_agg_of_level((Node *) filter, agglevel);
 4879                           690         [ +  - ]:             15 :         ereport(ERROR,
                                691                 :                :                 (errcode(ERRCODE_GROUPING_ERROR),
                                692                 :                :                  errmsg("aggregate function calls cannot be nested"),
                                693                 :                :                  parser_errposition(pstate, aggloc)));
                                694                 :                :     }
                                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                 :                :      */
   28                           702   [ +  +  +  + ]:          24425 :     if (context.min_ctelevel >= 0 && context.min_ctelevel < agglevel)
                                703         [ +  - ]:              3 :         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                 :                :      */
 4376                           719         [ +  + ]:          24422 :     if (directargs)
                                720                 :                :     {
                                721                 :            156 :         context.min_varlevel = -1;
                                722                 :            156 :         context.min_agglevel = -1;
   28                           723                 :            156 :         context.min_ctelevel = -1;
 1581                           724                 :            156 :         (void) check_agg_arguments_walker((Node *) directargs, &context);
 4376                           725   [ +  +  +  + ]:            156 :         if (context.min_varlevel >= 0 && context.min_varlevel < agglevel)
                                726         [ +  - ]:              3 :             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   [ +  +  +  - ]:            153 :         if (context.min_agglevel >= 0 && context.min_agglevel <= agglevel)
                                733         [ +  - ]:              3 :             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))));
   28                           739   [ -  +  -  - ]:            150 :         if (context.min_ctelevel >= 0 && context.min_ctelevel < agglevel)
   28 tgl@sss.pgh.pa.us         740         [ #  # ]:UBC           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                 :                :     }
 4876 tgl@sss.pgh.pa.us         747                 :CBC       24416 :     return agglevel;
                                748                 :                : }
                                749                 :                : 
                                750                 :                : static bool
                                751                 :          96237 : check_agg_arguments_walker(Node *node,
                                752                 :                :                            check_agg_arguments_context *context)
                                753                 :                : {
                                754         [ +  + ]:          96237 :     if (node == NULL)
                                755                 :          34447 :         return false;
                                756         [ +  + ]:          61790 :     if (IsA(node, Var))
                                757                 :                :     {
                                758                 :          16467 :         int         varlevelsup = ((Var *) node)->varlevelsup;
                                759                 :                : 
                                760                 :                :         /* convert levelsup to frame of reference of original query */
                                761                 :          16467 :         varlevelsup -= context->sublevels_up;
                                762                 :                :         /* ignore local vars of subqueries */
                                763         [ +  + ]:          16467 :         if (varlevelsup >= 0)
                                764                 :                :         {
                                765         [ +  + ]:          16396 :             if (context->min_varlevel < 0 ||
                                766         [ +  + ]:           1791 :                 context->min_varlevel > varlevelsup)
                                767                 :          14656 :                 context->min_varlevel = varlevelsup;
                                768                 :                :         }
                                769                 :          16467 :         return false;
                                770                 :                :     }
                                771         [ +  + ]:          45323 :     if (IsA(node, Aggref))
                                772                 :                :     {
                                773                 :             33 :         int         agglevelsup = ((Aggref *) node)->agglevelsup;
                                774                 :                : 
                                775                 :                :         /* convert levelsup to frame of reference of original query */
                                776                 :             33 :         agglevelsup -= context->sublevels_up;
                                777                 :                :         /* ignore local aggs of subqueries */
                                778         [ +  + ]:             33 :         if (agglevelsup >= 0)
                                779                 :                :         {
                                780         [ -  + ]:             21 :             if (context->min_agglevel < 0 ||
 4876 tgl@sss.pgh.pa.us         781         [ #  # ]:UBC           0 :                 context->min_agglevel > agglevelsup)
 4876 tgl@sss.pgh.pa.us         782                 :CBC          21 :                 context->min_agglevel = agglevelsup;
                                783                 :                :         }
                                784                 :                :         /* Continue and descend into subtree */
                                785                 :                :     }
 3867 andres@anarazel.de        786         [ -  + ]:          45323 :     if (IsA(node, GroupingFunc))
                                787                 :                :     {
 3867 andres@anarazel.de        788                 :UBC           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                 :                :         }
                                799                 :                :         /* Continue and descend into subtree */
                                800                 :                :     }
                                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                 :                :      */
 3094 tgl@sss.pgh.pa.us         807         [ +  + ]:CBC       45323 :     if (context->sublevels_up == 0)
                                808                 :                :     {
 2040                           809   [ +  +  +  + ]:          44849 :         if ((IsA(node, FuncExpr) && ((FuncExpr *) node)->funcretset) ||
                                810   [ +  +  -  + ]:          44846 :             (IsA(node, OpExpr) && ((OpExpr *) node)->opretset))
 3094                           811         [ +  - ]:              3 :             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         [ -  + ]:          44846 :         if (IsA(node, WindowFunc))
 3094 tgl@sss.pgh.pa.us         817         [ #  # ]:UBC           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                 :                :     }
                                823                 :                : 
   90 tgl@sss.pgh.pa.us         824         [ +  + ]:CBC       45320 :     if (IsA(node, RangeTblEntry))
                                825                 :                :     {
                                826                 :             64 :         RangeTblEntry *rte = (RangeTblEntry *) node;
                                827                 :                : 
                                828         [ +  + ]:             64 :         if (rte->rtekind == RTE_CTE)
                                829                 :                :         {
                                830                 :              9 :             int         ctelevelsup = rte->ctelevelsup;
                                831                 :                : 
                                832                 :                :             /* convert levelsup to frame of reference of original query */
                                833                 :              9 :             ctelevelsup -= context->sublevels_up;
                                834                 :                :             /* ignore local CTEs of subqueries */
                                835         [ +  - ]:              9 :             if (ctelevelsup >= 0)
                                836                 :                :             {
   28                           837         [ -  + ]:              9 :                 if (context->min_ctelevel < 0 ||
   28 tgl@sss.pgh.pa.us         838         [ #  # ]:UBC           0 :                     context->min_ctelevel > ctelevelsup)
                                839                 :                :                 {
   28 tgl@sss.pgh.pa.us         840                 :CBC           9 :                     context->min_ctelevel = ctelevelsup;
                                841                 :              9 :                     context->min_cte = rte;
                                842                 :                :                 }
                                843                 :                :             }
                                844                 :                :         }
   90                           845                 :             64 :         return false;           /* allow range_table_walker to continue */
                                846                 :                :     }
 4876                           847         [ +  + ]:          45256 :     if (IsA(node, Query))
                                848                 :                :     {
                                849                 :                :         /* Recurse into subselects */
                                850                 :                :         bool        result;
                                851                 :                : 
                                852                 :             69 :         context->sublevels_up++;
                                853                 :             69 :         result = query_tree_walker((Query *) node,
                                854                 :                :                                    check_agg_arguments_walker,
                                855                 :                :                                    context,
                                856                 :                :                                    QTW_EXAMINE_RTES_BEFORE);
                                857                 :             69 :         context->sublevels_up--;
                                858                 :             69 :         return result;
                                859                 :                :     }
                                860                 :                : 
                                861                 :          45187 :     return expression_tree_walker(node,
                                862                 :                :                                   check_agg_arguments_walker,
                                863                 :                :                                   context);
                                864                 :                : }
                                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
 6197                           878                 :           1945 : transformWindowFuncCall(ParseState *pstate, WindowFunc *wfunc,
                                879                 :                :                         WindowDef *windef)
                                880                 :                : {
                                881                 :                :     const char *err;
                                882                 :                :     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   [ +  +  -  + ]:           2476 :     if (pstate->p_hasWindowFuncs &&
 4876                           893                 :            531 :         contain_windowfuncs((Node *) wfunc->args))
 6197 tgl@sss.pgh.pa.us         894         [ #  # ]:UBC           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                 :                :      */
 4876 tgl@sss.pgh.pa.us         910                 :CBC        1945 :     err = NULL;
                                911                 :           1945 :     errkind = false;
                                912   [ -  -  +  -  :           1945 :     switch (pstate->p_expr_kind)
                                     -  +  -  -  -  
                                     +  +  -  -  -  
                                     +  -  -  +  -  
                                     -  -  -  -  -  
                                     -  -  -  -  +  
                                        -  +  +  -  
                                                 - ]
                                913                 :                :     {
 4876 tgl@sss.pgh.pa.us         914                 :UBC           0 :         case EXPR_KIND_NONE:
                                915                 :              0 :             Assert(false);      /* can't happen */
                                916                 :                :             break;
                                917                 :              0 :         case EXPR_KIND_OTHER:
                                918                 :                :             /* Accept window func here; caller must throw error if wanted */
                                919                 :              0 :             break;
 4876 tgl@sss.pgh.pa.us         920                 :CBC           3 :         case EXPR_KIND_JOIN_ON:
                                921                 :                :         case EXPR_KIND_JOIN_USING:
                                922                 :              3 :             err = _("window functions are not allowed in JOIN conditions");
                                923                 :              3 :             break;
 4876 tgl@sss.pgh.pa.us         924                 :UBC           0 :         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                 :              0 :         case EXPR_KIND_FROM_FUNCTION:
                                929                 :              0 :             err = _("window functions are not allowed in functions in FROM");
                                930                 :              0 :             break;
 4876 tgl@sss.pgh.pa.us         931                 :CBC           6 :         case EXPR_KIND_WHERE:
                                932                 :              6 :             errkind = true;
                                933                 :              6 :             break;
 3793 mail@joeconway.com        934                 :UBC           0 :         case EXPR_KIND_POLICY:
                                935                 :              0 :             err = _("window functions are not allowed in policy expressions");
                                936                 :              0 :             break;
 4876 tgl@sss.pgh.pa.us         937                 :              0 :         case EXPR_KIND_HAVING:
                                938                 :              0 :             errkind = true;
                                939                 :              0 :             break;
 4536 noah@leadboat.com         940                 :              0 :         case EXPR_KIND_FILTER:
                                941                 :              0 :             errkind = true;
                                942                 :              0 :             break;
 4876 tgl@sss.pgh.pa.us         943                 :CBC           3 :         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                 :              3 :             err = _("window functions are not allowed in window definitions");
                                949                 :              3 :             break;
                                950                 :           1914 :         case EXPR_KIND_SELECT_TARGET:
                                951                 :                :             /* okay */
                                952                 :           1914 :             break;
 4876 tgl@sss.pgh.pa.us         953                 :UBC           0 :         case EXPR_KIND_INSERT_TARGET:
                                954                 :                :         case EXPR_KIND_UPDATE_SOURCE:
                                955                 :                :         case EXPR_KIND_UPDATE_TARGET:
                                956                 :              0 :             errkind = true;
                                957                 :              0 :             break;
 1359 alvherre@alvh.no-ip.      958                 :              0 :         case EXPR_KIND_MERGE_WHEN:
                                959                 :              0 :             err = _("window functions are not allowed in MERGE WHEN conditions");
                                960                 :              0 :             break;
 4876 tgl@sss.pgh.pa.us         961                 :              0 :         case EXPR_KIND_GROUP_BY:
                                962                 :              0 :             errkind = true;
                                963                 :              0 :             break;
 4876 tgl@sss.pgh.pa.us         964                 :CBC           4 :         case EXPR_KIND_ORDER_BY:
                                965                 :                :             /* okay */
                                966                 :              4 :             break;
 4876 tgl@sss.pgh.pa.us         967                 :UBC           0 :         case EXPR_KIND_DISTINCT_ON:
                                968                 :                :             /* okay */
                                969                 :              0 :             break;
                                970                 :              0 :         case EXPR_KIND_LIMIT:
                                971                 :                :         case EXPR_KIND_OFFSET:
                                972                 :              0 :             errkind = true;
                                973                 :              0 :             break;
 4876 tgl@sss.pgh.pa.us         974                 :CBC           3 :         case EXPR_KIND_RETURNING:
                                975                 :                :         case EXPR_KIND_MERGE_RETURNING:
                                976                 :              3 :             errkind = true;
                                977                 :              3 :             break;
 4876 tgl@sss.pgh.pa.us         978                 :UBC           0 :         case EXPR_KIND_VALUES:
                                979                 :                :         case EXPR_KIND_VALUES_SINGLE:
                                980                 :              0 :             errkind = true;
                                981                 :              0 :             break;
                                982                 :              0 :         case EXPR_KIND_CHECK_CONSTRAINT:
                                983                 :                :         case EXPR_KIND_DOMAIN_CHECK:
 4728 peter_e@gmx.net           984                 :              0 :             err = _("window functions are not allowed in check constraints");
 4876 tgl@sss.pgh.pa.us         985                 :              0 :             break;
                                986                 :              0 :         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                 :              0 :         case EXPR_KIND_INDEX_EXPRESSION:
                                991                 :              0 :             err = _("window functions are not allowed in index expressions");
                                992                 :              0 :             break;
 1726 tomas.vondra@postgre      993                 :              0 :         case EXPR_KIND_STATS_EXPRESSION:
                                994                 :              0 :             err = _("window functions are not allowed in statistics expressions");
                                995                 :              0 :             break;
 4876 tgl@sss.pgh.pa.us         996                 :              0 :         case EXPR_KIND_INDEX_PREDICATE:
                                997                 :              0 :             err = _("window functions are not allowed in index predicates");
                                998                 :              0 :             break;
                                999                 :              0 :         case EXPR_KIND_ALTER_COL_TRANSFORM:
                               1000                 :              0 :             err = _("window functions are not allowed in transform expressions");
                               1001                 :              0 :             break;
                               1002                 :              0 :         case EXPR_KIND_EXECUTE_PARAMETER:
                               1003                 :              0 :             err = _("window functions are not allowed in EXECUTE parameters");
                               1004                 :              0 :             break;
                               1005                 :              0 :         case EXPR_KIND_TRIGGER_WHEN:
                               1006                 :              0 :             err = _("window functions are not allowed in trigger WHEN conditions");
                               1007                 :              0 :             break;
 2517 peter@eisentraut.org     1008                 :              0 :         case EXPR_KIND_PARTITION_BOUND:
                               1009                 :              0 :             err = _("window functions are not allowed in partition bound");
                               1010                 :              0 :             break;
 3296 rhaas@postgresql.org     1011                 :CBC           3 :         case EXPR_KIND_PARTITION_EXPRESSION:
 2866 tgl@sss.pgh.pa.us        1012                 :              3 :             err = _("window functions are not allowed in partition key expressions");
 3296 rhaas@postgresql.org     1013                 :              3 :             break;
 2866 tgl@sss.pgh.pa.us        1014                 :UBC           0 :         case EXPR_KIND_CALL_ARGUMENT:
 2938 peter_e@gmx.net          1015                 :              0 :             err = _("window functions are not allowed in CALL arguments");
                               1016                 :              0 :             break;
 2523 tomas.vondra@postgre     1017                 :CBC           3 :         case EXPR_KIND_COPY_WHERE:
                               1018                 :              3 :             err = _("window functions are not allowed in COPY FROM WHERE conditions");
                               1019                 :              3 :             break;
 2453 peter@eisentraut.org     1020                 :              6 :         case EXPR_KIND_GENERATED_COLUMN:
                               1021                 :              6 :             err = _("window functions are not allowed in column generation expressions");
                               1022                 :              6 :             break;
 1779 peter@eisentraut.org     1023                 :UBC           0 :         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                 :                :     }
 4876 tgl@sss.pgh.pa.us        1035         [ +  + ]:CBC        1945 :     if (err)
                               1036         [ +  - ]:             18 :         ereport(ERROR,
                               1037                 :                :                 (errcode(ERRCODE_WINDOWING_ERROR),
                               1038                 :                :                  errmsg_internal("%s", err),
                               1039                 :                :                  parser_errposition(pstate, wfunc->location)));
                               1040         [ +  + ]:           1927 :     if (errkind)
                               1041         [ +  - ]:              9 :         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                 :                :      */
 6194                          1054         [ +  + ]:           1918 :     if (windef->name)
                               1055                 :                :     {
 6197                          1056                 :            591 :         Index       winref = 0;
                               1057                 :                :         ListCell   *lc;
                               1058                 :                : 
 6194                          1059   [ +  -  +  -  :            591 :         Assert(windef->refname == NULL &&
                                        +  -  -  + ]
                               1060                 :                :                windef->partitionClause == NIL &&
                               1061                 :                :                windef->orderClause == NIL &&
                               1062                 :                :                windef->frameOptions == FRAMEOPTION_DEFAULTS);
                               1063                 :                : 
 6197                          1064   [ +  -  +  -  :            612 :         foreach(lc, pstate->p_windowdefs)
                                              +  - ]
                               1065                 :                :         {
 6032 bruce@momjian.us         1066                 :            612 :             WindowDef  *refwin = (WindowDef *) lfirst(lc);
                               1067                 :                : 
 6197 tgl@sss.pgh.pa.us        1068                 :            612 :             winref++;
 6194                          1069   [ +  -  +  + ]:            612 :             if (refwin->name && strcmp(refwin->name, windef->name) == 0)
                               1070                 :                :             {
 6197                          1071                 :            591 :                 wfunc->winref = winref;
                               1072                 :            591 :                 break;
                               1073                 :                :             }
                               1074                 :                :         }
                               1075         [ -  + ]:            591 :         if (lc == NULL)         /* didn't find it? */
 6197 tgl@sss.pgh.pa.us        1076         [ #  # ]:UBC           0 :             ereport(ERROR,
                               1077                 :                :                     (errcode(ERRCODE_UNDEFINED_OBJECT),
                               1078                 :                :                      errmsg("window \"%s\" does not exist", windef->name),
                               1079                 :                :                      parser_errposition(pstate, windef->location)));
                               1080                 :                :     }
                               1081                 :                :     else
                               1082                 :                :     {
 6197 tgl@sss.pgh.pa.us        1083                 :CBC        1327 :         Index       winref = 0;
                               1084                 :                :         ListCell   *lc;
                               1085                 :                : 
                               1086   [ +  +  +  +  :           1507 :         foreach(lc, pstate->p_windowdefs)
                                              +  + ]
                               1087                 :                :         {
 6032 bruce@momjian.us         1088                 :            306 :             WindowDef  *refwin = (WindowDef *) lfirst(lc);
                               1089                 :                : 
 6197 tgl@sss.pgh.pa.us        1090                 :            306 :             winref++;
                               1091   [ +  +  +  - ]:            312 :             if (refwin->refname && windef->refname &&
 6194                          1092         [ +  - ]:              6 :                 strcmp(refwin->refname, windef->refname) == 0)
                               1093                 :                :                  /* matched on refname */ ;
 6197                          1094   [ +  -  +  + ]:            300 :             else if (!refwin->refname && !windef->refname)
                               1095                 :                :                  /* matched, no refname */ ;
                               1096                 :                :             else
                               1097                 :             24 :                 continue;
                               1098                 :                : 
                               1099                 :                :             /*
                               1100                 :                :              * Also see similar de-duplication code in optimize_window_clauses
                               1101                 :                :              */
                               1102   [ +  +  +  + ]:            519 :             if (equal(refwin->partitionClause, windef->partitionClause) &&
 6194                          1103                 :            237 :                 equal(refwin->orderClause, windef->orderClause) &&
 5786                          1104   [ +  +  +  - ]:            333 :                 refwin->frameOptions == windef->frameOptions &&
                               1105         [ +  - ]:            252 :                 equal(refwin->startOffset, windef->startOffset) &&
                               1106                 :            126 :                 equal(refwin->endOffset, windef->endOffset))
                               1107                 :                :             {
                               1108                 :                :                 /* found a duplicate window specification */
 6197                          1109                 :            126 :                 wfunc->winref = winref;
                               1110                 :            126 :                 break;
                               1111                 :                :             }
                               1112                 :                :         }
                               1113         [ +  + ]:           1327 :         if (lc == NULL)         /* didn't find it? */
                               1114                 :                :         {
                               1115                 :           1201 :             pstate->p_windowdefs = lappend(pstate->p_windowdefs, windef);
                               1116                 :           1201 :             wfunc->winref = list_length(pstate->p_windowdefs);
                               1117                 :                :         }
                               1118                 :                :     }
                               1119                 :                : 
                               1120                 :           1918 :     pstate->p_hasWindowFuncs = true;
                               1121                 :           1918 : }
                               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
 8229                          1138                 :          21711 : parseCheckAggregates(ParseState *pstate, Query *qry)
                               1139                 :                : {
 3860 bruce@momjian.us         1140                 :          21711 :     List       *gset_common = NIL;
 8229 tgl@sss.pgh.pa.us        1141                 :          21711 :     List       *groupClauses = NIL;
 3867 andres@anarazel.de       1142                 :          21711 :     List       *groupClauseCommonVars = NIL;
                               1143                 :                :     bool        have_non_var_grouping;
 5610 tgl@sss.pgh.pa.us        1144                 :          21711 :     List       *func_grouped_rels = NIL;
                               1145                 :                :     ListCell   *l;
                               1146                 :                :     bool        hasJoinRTEs;
                               1147                 :                :     bool        hasSelfRefRTEs;
                               1148                 :                :     Node       *clause;
                               1149                 :                : 
                               1150                 :                :     /* This should only be called if we found aggregates or grouping */
 3867 andres@anarazel.de       1151   [ +  +  +  +  :          21711 :     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         [ +  + ]:          21711 :     if (qry->groupingSets)
                               1158                 :                :     {
                               1159                 :                :         /*
                               1160                 :                :          * The limit of 4096 is arbitrary and exists simply to avoid resource
                               1161                 :                :          * issues from pathological constructs.
                               1162                 :                :          */
 1734 tomas.vondra@postgre     1163                 :            505 :         List       *gsets = expand_grouping_sets(qry->groupingSets, qry->groupDistinct, 4096);
                               1164                 :                : 
 3867 andres@anarazel.de       1165         [ -  + ]:            505 :         if (!gsets)
 3867 andres@anarazel.de       1166   [ #  #  #  # ]:UBC           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                 :                :          */
 3867 andres@anarazel.de       1178                 :CBC         505 :         gset_common = linitial(gsets);
                               1179                 :                : 
                               1180         [ +  + ]:            505 :         if (gset_common)
                               1181                 :                :         {
 1905 tgl@sss.pgh.pa.us        1182   [ +  -  +  +  :            320 :             for_each_from(l, gsets, 1)
                                              +  + ]
                               1183                 :                :             {
 3867 andres@anarazel.de       1184                 :            215 :                 gset_common = list_intersection_int(gset_common, lfirst(l));
                               1185         [ +  + ]:            215 :                 if (!gset_common)
                               1186                 :             98 :                     break;
                               1187                 :                :             }
                               1188                 :                :         }
                               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   [ +  +  +  + ]:            505 :         if (list_length(gsets) == 1 && qry->groupClause)
                               1197                 :             12 :             qry->groupingSets = NIL;
                               1198                 :                :     }
                               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                 :                :      */
 6282 tgl@sss.pgh.pa.us        1204                 :          21711 :     hasJoinRTEs = hasSelfRefRTEs = false;
                               1205   [ +  +  +  +  :          47555 :     foreach(l, pstate->p_rtable)
                                              +  + ]
                               1206                 :                :     {
                               1207                 :          25844 :         RangeTblEntry *rte = (RangeTblEntry *) lfirst(l);
                               1208                 :                : 
                               1209         [ +  + ]:          25844 :         if (rte->rtekind == RTE_JOIN)
                               1210                 :           1131 :             hasJoinRTEs = true;
                               1211   [ +  +  +  + ]:          24713 :         else if (rte->rtekind == RTE_CTE && rte->self_reference)
                               1212                 :              6 :             hasSelfRefRTEs = true;
                               1213                 :                :     }
                               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                 :                :      */
 7874 neilc@samurai.com        1222   [ +  +  +  +  :          25793 :     foreach(l, qry->groupClause)
                                              +  + ]
                               1223                 :                :     {
 6345 tgl@sss.pgh.pa.us        1224                 :           4082 :         SortGroupClause *grpcl = (SortGroupClause *) lfirst(l);
                               1225                 :                :         TargetEntry *expr;
                               1226                 :                : 
 3867 andres@anarazel.de       1227                 :           4082 :         expr = get_sortgroupclause_tle(grpcl, qry->targetList);
 8229 tgl@sss.pgh.pa.us        1228         [ -  + ]:           4082 :         if (expr == NULL)
 8229 tgl@sss.pgh.pa.us        1229                 :UBC           0 :             continue;           /* probably cannot happen */
                               1230                 :                : 
 2344 tgl@sss.pgh.pa.us        1231                 :CBC        4082 :         groupClauses = lappend(groupClauses, expr);
                               1232                 :                :     }
                               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                 :                :      */
 8229                          1240         [ +  + ]:          21711 :     if (hasJoinRTEs)
 1051                          1241                 :            928 :         groupClauses = (List *) flatten_join_alias_vars(NULL, qry,
                               1242                 :                :                                                         (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                 :                :      */
 7993                          1253                 :          21711 :     have_non_var_grouping = false;
 7874 neilc@samurai.com        1254   [ +  +  +  +  :          25793 :     foreach(l, groupClauses)
                                              +  + ]
                               1255                 :                :     {
 3867 andres@anarazel.de       1256                 :           4082 :         TargetEntry *tle = lfirst(l);
                               1257                 :                : 
                               1258         [ +  + ]:           4082 :         if (!IsA(tle->expr, Var))
                               1259                 :                :         {
 7993 tgl@sss.pgh.pa.us        1260                 :            703 :             have_non_var_grouping = true;
                               1261                 :                :         }
 3867 andres@anarazel.de       1262   [ +  +  +  + ]:           4231 :         else if (!qry->groupingSets ||
                               1263                 :            852 :                  list_member_int(gset_common, tle->ressortgroupref))
                               1264                 :                :         {
                               1265                 :           2620 :             groupClauseCommonVars = lappend(groupClauseCommonVars, tle->expr);
                               1266                 :                :         }
                               1267                 :                :     }
                               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                 :                :      */
  462 rguo@postgresql.org      1273         [ +  + ]:          21711 :     if (groupClauses)
                               1274                 :                :     {
                               1275                 :           2415 :         pstate->p_grouping_nsitem =
                               1276                 :           2415 :             addRangeTableEntryForGroup(pstate, groupClauses);
                               1277                 :                : 
                               1278                 :                :         /* Set qry->rtable again in case it was previously NIL */
                               1279                 :           2415 :         qry->rtable = pstate->p_rtable;
                               1280                 :                :         /* Mark the Query as having RTE_GROUP RTE */
                               1281                 :           2415 :         qry->hasGroupRTE = true;
                               1282                 :                :     }
                               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                 :                :      */
 8229 tgl@sss.pgh.pa.us        1297                 :          21711 :     clause = (Node *) qry->targetList;
 3867 andres@anarazel.de       1298                 :          21711 :     finalize_grouping_exprs(clause, pstate, qry,
                               1299                 :                :                             groupClauses, hasJoinRTEs,
                               1300                 :                :                             have_non_var_grouping);
 8229 tgl@sss.pgh.pa.us        1301         [ +  + ]:          21708 :     if (hasJoinRTEs)
 1051                          1302                 :            928 :         clause = flatten_join_alias_vars(NULL, qry, clause);
  462 rguo@postgresql.org      1303                 :          21663 :     qry->targetList = (List *)
                               1304                 :          21708 :         substitute_grouped_columns(clause, pstate, qry,
                               1305                 :                :                                    groupClauses, groupClauseCommonVars,
                               1306                 :                :                                    gset_common,
                               1307                 :                :                                    have_non_var_grouping,
                               1308                 :                :                                    &func_grouped_rels);
                               1309                 :                : 
 8229 tgl@sss.pgh.pa.us        1310                 :          21663 :     clause = (Node *) qry->havingQual;
 3867 andres@anarazel.de       1311                 :          21663 :     finalize_grouping_exprs(clause, pstate, qry,
                               1312                 :                :                             groupClauses, hasJoinRTEs,
                               1313                 :                :                             have_non_var_grouping);
 8229 tgl@sss.pgh.pa.us        1314         [ +  + ]:          21663 :     if (hasJoinRTEs)
 1051                          1315                 :            916 :         clause = flatten_join_alias_vars(NULL, qry, clause);
  462 rguo@postgresql.org      1316                 :          21660 :     qry->havingQual =
                               1317                 :          21663 :         substitute_grouped_columns(clause, pstate, qry,
                               1318                 :                :                                    groupClauses, groupClauseCommonVars,
                               1319                 :                :                                    gset_common,
                               1320                 :                :                                    have_non_var_grouping,
                               1321                 :                :                                    &func_grouped_rels);
                               1322                 :                : 
                               1323                 :                :     /*
                               1324                 :                :      * Per spec, aggregates can't appear in a recursive term.
                               1325                 :                :      */
 6282 tgl@sss.pgh.pa.us        1326   [ +  +  +  + ]:          21660 :     if (pstate->p_hasAggs && hasSelfRefRTEs)
                               1327         [ +  - ]:              6 :         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))));
 8229                          1332                 :          21654 : }
                               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 *
  462 rguo@postgresql.org      1358                 :          43371 : 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                 :                :     substitute_grouped_columns_context context;
                               1365                 :                : 
 9504 tgl@sss.pgh.pa.us        1366                 :          43371 :     context.pstate = pstate;
 5610                          1367                 :          43371 :     context.qry = qry;
 2513                          1368                 :          43371 :     context.hasJoinRTEs = false;    /* assume caller flattened join Vars */
 9504                          1369                 :          43371 :     context.groupClauses = groupClauses;
 3867 andres@anarazel.de       1370                 :          43371 :     context.groupClauseCommonVars = groupClauseCommonVars;
  462 rguo@postgresql.org      1371                 :          43371 :     context.gset_common = gset_common;
 8369 tgl@sss.pgh.pa.us        1372                 :          43371 :     context.have_non_var_grouping = have_non_var_grouping;
 5610                          1373                 :          43371 :     context.func_grouped_rels = func_grouped_rels;
 8369                          1374                 :          43371 :     context.sublevels_up = 0;
 4376                          1375                 :          43371 :     context.in_agg_direct_args = false;
  462 rguo@postgresql.org      1376                 :          43371 :     return substitute_grouped_columns_mutator(node, &context);
                               1377                 :                : }
                               1378                 :                : 
                               1379                 :                : static Node *
                               1380                 :         148100 : substitute_grouped_columns_mutator(Node *node,
                               1381                 :                :                                    substitute_grouped_columns_context *context)
                               1382                 :                : {
                               1383                 :                :     ListCell   *gl;
                               1384                 :                : 
 9677 tgl@sss.pgh.pa.us        1385         [ +  + ]:         148100 :     if (node == NULL)
  462 rguo@postgresql.org      1386                 :          48523 :         return NULL;
                               1387                 :                : 
 4376 tgl@sss.pgh.pa.us        1388         [ +  + ]:          99577 :     if (IsA(node, Aggref))
                               1389                 :                :     {
                               1390                 :          24591 :         Aggref     *agg = (Aggref *) node;
                               1391                 :                : 
                               1392         [ +  + ]:          24591 :         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                 :                :              */
  462 rguo@postgresql.org      1403                 :          24588 :             agg = copyObject(agg);
                               1404                 :                : 
 4376 tgl@sss.pgh.pa.us        1405         [ -  + ]:          24588 :             Assert(!context->in_agg_direct_args);
                               1406                 :          24588 :             context->in_agg_direct_args = true;
  462 rguo@postgresql.org      1407                 :          24585 :             agg->aggdirectargs = (List *)
                               1408                 :          24588 :                 substitute_grouped_columns_mutator((Node *) agg->aggdirectargs,
                               1409                 :                :                                                    context);
 4376 tgl@sss.pgh.pa.us        1410                 :          24585 :             context->in_agg_direct_args = false;
  462 rguo@postgresql.org      1411                 :          24585 :             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                 :                :          */
 4376 tgl@sss.pgh.pa.us        1420         [ -  + ]:              3 :         if ((int) agg->agglevelsup > context->sublevels_up)
  462 rguo@postgresql.org      1421                 :UBC           0 :             return node;
                               1422                 :                :     }
                               1423                 :                : 
 3867 andres@anarazel.de       1424         [ +  + ]:CBC       74989 :     if (IsA(node, GroupingFunc))
                               1425                 :                :     {
                               1426                 :            198 :         GroupingFunc *grp = (GroupingFunc *) node;
                               1427                 :                : 
                               1428                 :                :         /* handled GroupingFunc separately, no need to recheck at this level */
                               1429                 :                : 
                               1430         [ +  + ]:            198 :         if ((int) grp->agglevelsup >= context->sublevels_up)
  462 rguo@postgresql.org      1431                 :            182 :             return node;
                               1432                 :                :     }
                               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                 :                :      */
 8369 tgl@sss.pgh.pa.us        1441   [ +  +  +  + ]:          74807 :     if (context->have_non_var_grouping && context->sublevels_up == 0)
                               1442                 :                :     {
  462 rguo@postgresql.org      1443                 :           3856 :         int         attnum = 0;
                               1444                 :                : 
 8369 tgl@sss.pgh.pa.us        1445   [ +  -  +  +  :          10486 :         foreach(gl, context->groupClauses)
                                              +  + ]
                               1446                 :                :         {
  462 rguo@postgresql.org      1447                 :           7720 :             TargetEntry *tle = (TargetEntry *) lfirst(gl);
                               1448                 :                : 
                               1449                 :           7720 :             attnum++;
 3867 andres@anarazel.de       1450         [ +  + ]:           7720 :             if (equal(node, tle->expr))
                               1451                 :                :             {
                               1452                 :                :                 /* acceptable, replace it with a GROUP Var */
  462 rguo@postgresql.org      1453                 :           1090 :                 return (Node *) buildGroupedVar(attnum,
                               1454                 :                :                                                 tle->ressortgroupref,
                               1455                 :                :                                                 context);
                               1456                 :                :             }
                               1457                 :                :         }
                               1458                 :                :     }
                               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         [ +  + ]:          73717 :     if (IsA(node, Const) ||
                               1467         [ +  + ]:          71462 :         IsA(node, Param))
                               1468                 :           2377 :         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                 :                :      */
 9677 tgl@sss.pgh.pa.us        1476         [ +  + ]:          71340 :     if (IsA(node, Var))
                               1477                 :                :     {
 9379 bruce@momjian.us         1478                 :           5298 :         Var        *var = (Var *) node;
                               1479                 :                :         RangeTblEntry *rte;
                               1480                 :                :         char       *attname;
                               1481                 :                : 
 8369 tgl@sss.pgh.pa.us        1482         [ +  + ]:           5298 :         if (var->varlevelsup != context->sublevels_up)
  462 rguo@postgresql.org      1483                 :            221 :             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                 :                :          */
 8369 tgl@sss.pgh.pa.us        1488   [ +  +  -  + ]:           5077 :         if (!context->have_non_var_grouping || context->sublevels_up != 0)
                               1489                 :                :         {
  462 rguo@postgresql.org      1490                 :           5074 :             int         attnum = 0;
                               1491                 :                : 
 8369 tgl@sss.pgh.pa.us        1492   [ +  +  +  +  :           7073 :             foreach(gl, context->groupClauses)
                                              +  + ]
                               1493                 :                :             {
  462 rguo@postgresql.org      1494                 :           6890 :                 TargetEntry *tle = (TargetEntry *) lfirst(gl);
                               1495                 :           6890 :                 Var        *gvar = (Var *) tle->expr;
                               1496                 :                : 
                               1497                 :           6890 :                 attnum++;
 8369 tgl@sss.pgh.pa.us        1498         [ +  - ]:           6890 :                 if (IsA(gvar, Var) &&
                               1499         [ +  + ]:           6890 :                     gvar->varno == var->varno &&
                               1500         [ +  + ]:           6523 :                     gvar->varattno == var->varattno &&
                               1501         [ +  - ]:           4891 :                     gvar->varlevelsup == 0)
                               1502                 :                :                 {
                               1503                 :                :                     /* acceptable, replace it with a GROUP Var */
  462 rguo@postgresql.org      1504                 :           4891 :                     return (Node *) buildGroupedVar(attnum,
                               1505                 :                :                                                     tle->ressortgroupref,
                               1506                 :                :                                                     context);
                               1507                 :                :                 }
                               1508                 :                :             }
                               1509                 :                :         }
                               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                 :                :          */
 5610 tgl@sss.pgh.pa.us        1527         [ +  + ]:            186 :         if (list_member_int(*context->func_grouped_rels, var->varno))
  462 rguo@postgresql.org      1528                 :             75 :             return node;        /* previously proven acceptable */
                               1529                 :                : 
 9504 tgl@sss.pgh.pa.us        1530   [ +  -  -  + ]:            111 :         Assert(var->varno > 0 &&
                               1531                 :                :                (int) var->varno <= list_length(context->pstate->p_rtable));
                               1532                 :            111 :         rte = rt_fetch(var->varno, context->pstate->p_rtable);
 5610                          1533         [ +  + ]:            111 :         if (rte->rtekind == RTE_RELATION)
                               1534                 :                :         {
                               1535         [ +  + ]:            108 :             if (check_functional_grouping(rte->relid,
                               1536                 :            108 :                                           var->varno,
                               1537                 :                :                                           0,
                               1538                 :                :                                           context->groupClauseCommonVars,
                               1539                 :            108 :                                           &context->qry->constraintDeps))
                               1540                 :                :             {
                               1541                 :            126 :                 *context->func_grouped_rels =
                               1542                 :             63 :                     lappend_int(*context->func_grouped_rels, var->varno);
  462 rguo@postgresql.org      1543                 :             63 :                 return node;    /* acceptable */
                               1544                 :                :             }
                               1545                 :                :         }
                               1546                 :                : 
                               1547                 :                :         /* Found an ungrouped local variable; generate error message */
 9213 tgl@sss.pgh.pa.us        1548                 :             48 :         attname = get_rte_attribute_name(rte, var->varattno);
 8369                          1549         [ +  - ]:             48 :         if (context->sublevels_up == 0)
 8186                          1550   [ +  -  +  + ]:             48 :             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
 8186 tgl@sss.pgh.pa.us        1558         [ #  # ]:UBC           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                 :                :     }
                               1564                 :                : 
 8369 tgl@sss.pgh.pa.us        1565         [ +  + ]:CBC       66042 :     if (IsA(node, Query))
                               1566                 :                :     {
                               1567                 :                :         /* Recurse into subselects */
                               1568                 :                :         Query      *newnode;
                               1569                 :                : 
                               1570                 :            171 :         context->sublevels_up++;
  462 rguo@postgresql.org      1571                 :            171 :         newnode = query_tree_mutator((Query *) node,
                               1572                 :                :                                      substitute_grouped_columns_mutator,
                               1573                 :                :                                      context,
                               1574                 :                :                                      0);
 8369 tgl@sss.pgh.pa.us        1575                 :            171 :         context->sublevels_up--;
  462 rguo@postgresql.org      1576                 :            171 :         return (Node *) newnode;
                               1577                 :                :     }
                               1578                 :          65871 :     return expression_tree_mutator(node, substitute_grouped_columns_mutator,
                               1579                 :                :                                    context);
                               1580                 :                : }
                               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
 3867 andres@anarazel.de       1594                 :          43374 : finalize_grouping_exprs(Node *node, ParseState *pstate, Query *qry,
                               1595                 :                :                         List *groupClauses, bool hasJoinRTEs,
                               1596                 :                :                         bool have_non_var_grouping)
                               1597                 :                : {
                               1598                 :                :     substitute_grouped_columns_context context;
                               1599                 :                : 
                               1600                 :          43374 :     context.pstate = pstate;
                               1601                 :          43374 :     context.qry = qry;
 2513 tgl@sss.pgh.pa.us        1602                 :          43374 :     context.hasJoinRTEs = hasJoinRTEs;
 3867 andres@anarazel.de       1603                 :          43374 :     context.groupClauses = groupClauses;
                               1604                 :          43374 :     context.groupClauseCommonVars = NIL;
  462 rguo@postgresql.org      1605                 :          43374 :     context.gset_common = NIL;
 3867 andres@anarazel.de       1606                 :          43374 :     context.have_non_var_grouping = have_non_var_grouping;
                               1607                 :          43374 :     context.func_grouped_rels = NULL;
                               1608                 :          43374 :     context.sublevels_up = 0;
                               1609                 :          43374 :     context.in_agg_direct_args = false;
                               1610                 :          43374 :     finalize_grouping_exprs_walker(node, &context);
                               1611                 :          43371 : }
                               1612                 :                : 
                               1613                 :                : static bool
                               1614                 :         145258 : finalize_grouping_exprs_walker(Node *node,
                               1615                 :                :                                substitute_grouped_columns_context *context)
                               1616                 :                : {
                               1617                 :                :     ListCell   *gl;
                               1618                 :                : 
                               1619         [ +  + ]:         145258 :     if (node == NULL)
                               1620                 :          49133 :         return false;
                               1621         [ +  + ]:          96125 :     if (IsA(node, Const) ||
                               1622         [ +  + ]:          93229 :         IsA(node, Param))
                               1623                 :           3024 :         return false;           /* constants are always acceptable */
                               1624                 :                : 
                               1625         [ +  + ]:          93101 :     if (IsA(node, Aggref))
                               1626                 :                :     {
                               1627                 :          24594 :         Aggref     *agg = (Aggref *) node;
                               1628                 :                : 
                               1629         [ +  + ]:          24594 :         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                 :                :             bool        result;
                               1638                 :                : 
                               1639         [ -  + ]:          24591 :             Assert(!context->in_agg_direct_args);
                               1640                 :          24591 :             context->in_agg_direct_args = true;
                               1641                 :          24591 :             result = finalize_grouping_exprs_walker((Node *) agg->aggdirectargs,
                               1642                 :                :                                                     context);
                               1643                 :          24591 :             context->in_agg_direct_args = false;
                               1644                 :          24591 :             return result;
                               1645                 :                :         }
                               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         [ -  + ]:              3 :         if ((int) agg->agglevelsup > context->sublevels_up)
 3867 andres@anarazel.de       1654                 :UBC           0 :             return false;
                               1655                 :                :     }
                               1656                 :                : 
 3867 andres@anarazel.de       1657         [ +  + ]:CBC       68510 :     if (IsA(node, GroupingFunc))
                               1658                 :                :     {
                               1659                 :            201 :         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         [ +  + ]:            201 :         if ((int) grp->agglevelsup == context->sublevels_up)
                               1667                 :                :         {
                               1668                 :                :             ListCell   *lc;
 3860 bruce@momjian.us         1669                 :            181 :             List       *ref_list = NIL;
                               1670                 :                : 
 3867 andres@anarazel.de       1671   [ +  -  +  +  :            454 :             foreach(lc, grp->args)
                                              +  + ]
                               1672                 :                :             {
 3860 bruce@momjian.us         1673                 :            276 :                 Node       *expr = lfirst(lc);
                               1674                 :            276 :                 Index       ref = 0;
                               1675                 :                : 
 2513 tgl@sss.pgh.pa.us        1676         [ +  + ]:            276 :                 if (context->hasJoinRTEs)
 1051                          1677                 :             24 :                     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                 :                : 
 3867 andres@anarazel.de       1685         [ +  + ]:            276 :                 if (IsA(expr, Var))
                               1686                 :                :                 {
 3860 bruce@momjian.us         1687                 :            246 :                     Var        *var = (Var *) expr;
                               1688                 :                : 
 3867 andres@anarazel.de       1689         [ +  - ]:            246 :                     if (var->varlevelsup == context->sublevels_up)
                               1690                 :                :                     {
                               1691   [ +  +  +  -  :            362 :                         foreach(gl, context->groupClauses)
                                              +  + ]
                               1692                 :                :                         {
                               1693                 :            359 :                             TargetEntry *tle = lfirst(gl);
                               1694                 :            359 :                             Var        *gvar = (Var *) tle->expr;
                               1695                 :                : 
                               1696         [ +  - ]:            359 :                             if (IsA(gvar, Var) &&
                               1697         [ +  + ]:            359 :                                 gvar->varno == var->varno &&
                               1698         [ +  + ]:            353 :                                 gvar->varattno == var->varattno &&
                               1699         [ +  - ]:            243 :                                 gvar->varlevelsup == 0)
                               1700                 :                :                             {
                               1701                 :            243 :                                 ref = tle->ressortgroupref;
                               1702                 :            243 :                                 break;
                               1703                 :                :                             }
                               1704                 :                :                         }
                               1705                 :                :                     }
                               1706                 :                :                 }
                               1707         [ +  - ]:             30 :                 else if (context->have_non_var_grouping &&
                               1708         [ +  - ]:             30 :                          context->sublevels_up == 0)
                               1709                 :                :                 {
                               1710   [ +  -  +  -  :             60 :                     foreach(gl, context->groupClauses)
                                              +  - ]
                               1711                 :                :                     {
                               1712                 :             60 :                         TargetEntry *tle = lfirst(gl);
                               1713                 :                : 
                               1714         [ +  + ]:             60 :                         if (equal(expr, tle->expr))
                               1715                 :                :                         {
                               1716                 :             30 :                             ref = tle->ressortgroupref;
                               1717                 :             30 :                             break;
                               1718                 :                :                         }
                               1719                 :                :                     }
                               1720                 :                :                 }
                               1721                 :                : 
                               1722         [ +  + ]:            276 :                 if (ref == 0)
                               1723         [ +  - ]:              3 :                     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                 :            273 :                 ref_list = lappend_int(ref_list, ref);
                               1730                 :                :             }
                               1731                 :                : 
                               1732                 :            178 :             grp->refs = ref_list;
                               1733                 :                :         }
                               1734                 :                : 
                               1735         [ +  + ]:            198 :         if ((int) grp->agglevelsup > context->sublevels_up)
                               1736                 :              4 :             return false;
                               1737                 :                :     }
                               1738                 :                : 
                               1739         [ +  + ]:          68503 :     if (IsA(node, Query))
                               1740                 :                :     {
                               1741                 :                :         /* Recurse into subselects */
                               1742                 :                :         bool        result;
                               1743                 :                : 
                               1744                 :            221 :         context->sublevels_up++;
                               1745                 :            221 :         result = query_tree_walker((Query *) node,
                               1746                 :                :                                    finalize_grouping_exprs_walker,
                               1747                 :                :                                    context,
                               1748                 :                :                                    0);
                               1749                 :            221 :         context->sublevels_up--;
                               1750                 :            221 :         return result;
                               1751                 :                :     }
                               1752                 :          68282 :     return expression_tree_walker(node, finalize_grouping_exprs_walker,
                               1753                 :                :                                   context);
                               1754                 :                : }
                               1755                 :                : 
                               1756                 :                : /*
                               1757                 :                :  * buildGroupedVar -
                               1758                 :                :  *    build a Var node that references the RTE_GROUP RTE
                               1759                 :                :  */
                               1760                 :                : static Var *
  462 rguo@postgresql.org      1761                 :           5981 : buildGroupedVar(int attnum, Index ressortgroupref,
                               1762                 :                :                 substitute_grouped_columns_context *context)
                               1763                 :                : {
                               1764                 :                :     Var        *var;
                               1765                 :           5981 :     ParseNamespaceItem *grouping_nsitem = context->pstate->p_grouping_nsitem;
                               1766                 :           5981 :     ParseNamespaceColumn *nscol = grouping_nsitem->p_nscolumns + attnum - 1;
                               1767                 :                : 
                               1768         [ -  + ]:           5981 :     Assert(nscol->p_varno == grouping_nsitem->p_rtindex);
                               1769         [ -  + ]:           5981 :     Assert(nscol->p_varattno == attnum);
                               1770                 :           5981 :     var = makeVar(nscol->p_varno,
                               1771                 :           5981 :                   nscol->p_varattno,
                               1772                 :                :                   nscol->p_vartype,
                               1773                 :                :                   nscol->p_vartypmod,
                               1774                 :                :                   nscol->p_varcollid,
                               1775                 :           5981 :                   context->sublevels_up);
                               1776                 :                :     /* makeVar doesn't offer parameters for these, so set by hand: */
                               1777                 :           5981 :     var->varnosyn = nscol->p_varnosyn;
                               1778                 :           5981 :     var->varattnosyn = nscol->p_varattnosyn;
                               1779                 :                : 
                               1780         [ +  + ]:           5981 :     if (context->qry->groupingSets &&
                               1781         [ +  + ]:           1056 :         !list_member_int(context->gset_common, ressortgroupref))
                               1782                 :            942 :         var->varnullingrels =
                               1783                 :            942 :             bms_add_member(var->varnullingrels, grouping_nsitem->p_rtindex);
                               1784                 :                : 
                               1785                 :           5981 :     return var;
                               1786                 :                : }
                               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 *
 3867 andres@anarazel.de       1801                 :           2426 : expand_groupingset_node(GroupingSet *gs)
                               1802                 :                : {
 3860 bruce@momjian.us         1803                 :           2426 :     List       *result = NIL;
                               1804                 :                : 
 3867 andres@anarazel.de       1805   [ +  +  +  +  :           2426 :     switch (gs->kind)
                                              +  - ]
                               1806                 :                :     {
                               1807                 :            330 :         case GROUPING_SET_EMPTY:
                               1808                 :            330 :             result = list_make1(NIL);
                               1809                 :            330 :             break;
                               1810                 :                : 
                               1811                 :           1064 :         case GROUPING_SET_SIMPLE:
                               1812                 :           1064 :             result = list_make1(gs->content);
                               1813                 :           1064 :             break;
                               1814                 :                : 
                               1815                 :            295 :         case GROUPING_SET_ROLLUP:
                               1816                 :                :             {
                               1817                 :            295 :                 List       *rollup_val = gs->content;
                               1818                 :                :                 ListCell   *lc;
                               1819                 :            295 :                 int         curgroup_size = list_length(gs->content);
                               1820                 :                : 
                               1821         [ +  + ]:            755 :                 while (curgroup_size > 0)
                               1822                 :                :                 {
 3860 bruce@momjian.us         1823                 :            460 :                     List       *current_result = NIL;
                               1824                 :            460 :                     int         i = curgroup_size;
                               1825                 :                : 
 3867 andres@anarazel.de       1826   [ +  -  +  -  :            625 :                     foreach(lc, rollup_val)
                                              +  - ]
                               1827                 :                :                     {
                               1828                 :            625 :                         GroupingSet *gs_current = (GroupingSet *) lfirst(lc);
                               1829                 :                : 
                               1830         [ -  + ]:            625 :                         Assert(gs_current->kind == GROUPING_SET_SIMPLE);
                               1831                 :                : 
 2318 tgl@sss.pgh.pa.us        1832                 :            625 :                         current_result = list_concat(current_result,
                               1833                 :            625 :                                                      gs_current->content);
                               1834                 :                : 
                               1835                 :                :                         /* If we are done with making the current group, break */
 3867 andres@anarazel.de       1836         [ +  + ]:            625 :                         if (--i == 0)
                               1837                 :            460 :                             break;
                               1838                 :                :                     }
                               1839                 :                : 
                               1840                 :            460 :                     result = lappend(result, current_result);
                               1841                 :            460 :                     --curgroup_size;
                               1842                 :                :                 }
                               1843                 :                : 
                               1844                 :            295 :                 result = lappend(result, NIL);
                               1845                 :                :             }
                               1846                 :            295 :             break;
                               1847                 :                : 
                               1848                 :            184 :         case GROUPING_SET_CUBE:
                               1849                 :                :             {
 3860 bruce@momjian.us         1850                 :            184 :                 List       *cube_list = gs->content;
                               1851                 :            184 :                 int         number_bits = list_length(cube_list);
                               1852                 :                :                 uint32      num_sets;
                               1853                 :                :                 uint32      i;
                               1854                 :                : 
                               1855                 :                :                 /* parser should cap this much lower */
 3867 andres@anarazel.de       1856         [ -  + ]:            184 :                 Assert(number_bits < 31);
                               1857                 :                : 
                               1858                 :            184 :                 num_sets = (1U << number_bits);
                               1859                 :                : 
                               1860         [ +  + ]:           1020 :                 for (i = 0; i < num_sets; i++)
                               1861                 :                :                 {
 3860 bruce@momjian.us         1862                 :            836 :                     List       *current_result = NIL;
                               1863                 :                :                     ListCell   *lc;
                               1864                 :            836 :                     uint32      mask = 1U;
                               1865                 :                : 
 3867 andres@anarazel.de       1866   [ +  -  +  +  :           2776 :                     foreach(lc, cube_list)
                                              +  + ]
                               1867                 :                :                     {
                               1868                 :           1940 :                         GroupingSet *gs_current = (GroupingSet *) lfirst(lc);
                               1869                 :                : 
                               1870         [ -  + ]:           1940 :                         Assert(gs_current->kind == GROUPING_SET_SIMPLE);
                               1871                 :                : 
                               1872         [ +  + ]:           1940 :                         if (mask & i)
 2318 tgl@sss.pgh.pa.us        1873                 :            970 :                             current_result = list_concat(current_result,
                               1874                 :            970 :                                                          gs_current->content);
                               1875                 :                : 
 3867 andres@anarazel.de       1876                 :           1940 :                         mask <<= 1;
                               1877                 :                :                     }
                               1878                 :                : 
                               1879                 :            836 :                     result = lappend(result, current_result);
                               1880                 :                :                 }
                               1881                 :                :             }
                               1882                 :            184 :             break;
                               1883                 :                : 
                               1884                 :            553 :         case GROUPING_SET_SETS:
                               1885                 :                :             {
                               1886                 :                :                 ListCell   *lc;
                               1887                 :                : 
                               1888   [ +  -  +  +  :           1893 :                 foreach(lc, gs->content)
                                              +  + ]
                               1889                 :                :                 {
 3860 bruce@momjian.us         1890                 :           1340 :                     List       *current_result = expand_groupingset_node(lfirst(lc));
                               1891                 :                : 
 3867 andres@anarazel.de       1892                 :           1340 :                     result = list_concat(result, current_result);
                               1893                 :                :                 }
                               1894                 :                :             }
                               1895                 :            553 :             break;
                               1896                 :                :     }
                               1897                 :                : 
                               1898                 :           2426 :     return result;
                               1899                 :                : }
                               1900                 :                : 
                               1901                 :                : /* list_sort comparator to sort sub-lists by length */
                               1902                 :                : static int
 2345 tgl@sss.pgh.pa.us        1903                 :           2964 : cmp_list_len_asc(const ListCell *a, const ListCell *b)
                               1904                 :                : {
                               1905                 :           2964 :     int         la = list_length((const List *) lfirst(a));
                               1906                 :           2964 :     int         lb = list_length((const List *) lfirst(b));
                               1907                 :                : 
  669 nathan@postgresql.or     1908                 :           2964 :     return pg_cmp_s32(la, lb);
                               1909                 :                : }
                               1910                 :                : 
                               1911                 :                : /* list_sort comparator to sort sub-lists by length and contents */
                               1912                 :                : static int
 1734 tomas.vondra@postgre     1913                 :            163 : cmp_list_len_contents_asc(const ListCell *a, const ListCell *b)
                               1914                 :                : {
 1679 tgl@sss.pgh.pa.us        1915                 :            163 :     int         res = cmp_list_len_asc(a, b);
                               1916                 :                : 
 1734 tomas.vondra@postgre     1917         [ +  + ]:            163 :     if (res == 0)
                               1918                 :                :     {
 1679 tgl@sss.pgh.pa.us        1919                 :             51 :         List       *la = (List *) lfirst(a);
                               1920                 :             51 :         List       *lb = (List *) lfirst(b);
                               1921                 :                :         ListCell   *lca;
                               1922                 :                :         ListCell   *lcb;
                               1923                 :                : 
 1734 tomas.vondra@postgre     1924   [ +  +  +  +  :            115 :         forboth(lca, la, lcb, lb)
                                     +  +  +  +  +  
                                        +  +  -  +  
                                                 + ]
                               1925                 :                :         {
 1679 tgl@sss.pgh.pa.us        1926                 :             80 :             int         va = lfirst_int(lca);
                               1927                 :             80 :             int         vb = lfirst_int(lcb);
                               1928                 :                : 
 1734 tomas.vondra@postgre     1929         [ +  + ]:             80 :             if (va > vb)
                               1930                 :             16 :                 return 1;
                               1931         [ +  + ]:             72 :             if (va < vb)
                               1932                 :              8 :                 return -1;
                               1933                 :                :         }
                               1934                 :                :     }
                               1935                 :                : 
                               1936                 :            147 :     return res;
                               1937                 :                : }
                               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                 :           1004 : expand_grouping_sets(List *groupingSets, bool groupDistinct, int limit)
                               1948                 :                : {
 3867 andres@anarazel.de       1949                 :           1004 :     List       *expanded_groups = NIL;
 3860 bruce@momjian.us         1950                 :           1004 :     List       *result = NIL;
 3867 andres@anarazel.de       1951                 :           1004 :     double      numsets = 1;
                               1952                 :                :     ListCell   *lc;
                               1953                 :                : 
                               1954         [ -  + ]:           1004 :     if (groupingSets == NIL)
 3867 andres@anarazel.de       1955                 :UBC           0 :         return NIL;
                               1956                 :                : 
 3867 andres@anarazel.de       1957   [ +  -  +  +  :CBC        2090 :     foreach(lc, groupingSets)
                                              +  + ]
                               1958                 :                :     {
 3860 bruce@momjian.us         1959                 :           1086 :         List       *current_result = NIL;
 3867 andres@anarazel.de       1960                 :           1086 :         GroupingSet *gs = lfirst(lc);
                               1961                 :                : 
                               1962                 :           1086 :         current_result = expand_groupingset_node(gs);
                               1963                 :                : 
                               1964         [ -  + ]:           1086 :         Assert(current_result != NIL);
                               1965                 :                : 
                               1966                 :           1086 :         numsets *= list_length(current_result);
                               1967                 :                : 
                               1968   [ +  +  -  + ]:           1086 :         if (limit >= 0 && numsets > limit)
 3867 andres@anarazel.de       1969                 :UBC           0 :             return NIL;
                               1970                 :                : 
 3867 andres@anarazel.de       1971                 :CBC        1086 :         expanded_groups = lappend(expanded_groups, current_result);
                               1972                 :                :     }
                               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   [ +  -  +  +  :           3827 :     foreach(lc, (List *) linitial(expanded_groups))
                                              +  + ]
                               1981                 :                :     {
                               1982                 :           2823 :         result = lappend(result, list_union_int(NIL, (List *) lfirst(lc)));
                               1983                 :                :     }
                               1984                 :                : 
 1905 tgl@sss.pgh.pa.us        1985   [ +  -  +  +  :           1086 :     for_each_from(lc, expanded_groups, 1)
                                              +  + ]
                               1986                 :                :     {
 3867 andres@anarazel.de       1987                 :             82 :         List       *p = lfirst(lc);
                               1988                 :             82 :         List       *new_result = NIL;
                               1989                 :                :         ListCell   *lc2;
                               1990                 :                : 
                               1991   [ +  -  +  +  :            250 :         foreach(lc2, result)
                                              +  + ]
                               1992                 :                :         {
                               1993                 :            168 :             List       *q = lfirst(lc2);
                               1994                 :                :             ListCell   *lc3;
                               1995                 :                : 
                               1996   [ +  -  +  +  :            540 :             foreach(lc3, p)
                                              +  + ]
                               1997                 :                :             {
                               1998                 :            372 :                 new_result = lappend(new_result,
                               1999                 :            372 :                                      list_union_int(q, (List *) lfirst(lc3)));
                               2000                 :                :             }
                               2001                 :                :         }
                               2002                 :             82 :         result = new_result;
                               2003                 :                :     }
                               2004                 :                : 
                               2005                 :                :     /* Now sort the lists by length and deduplicate if necessary */
 1734 tomas.vondra@postgre     2006   [ +  +  -  + ]:           1004 :     if (!groupDistinct || list_length(result) < 2)
                               2007                 :            993 :         list_sort(result, cmp_list_len_asc);
                               2008                 :                :     else
                               2009                 :                :     {
                               2010                 :                :         ListCell   *cell;
                               2011                 :                :         List       *prev;
                               2012                 :                : 
                               2013                 :                :         /* Sort each groupset individually */
                               2014   [ +  -  +  +  :             89 :         foreach(cell, result)
                                              +  + ]
                               2015                 :             78 :             list_sort(lfirst(cell), list_int_cmp);
                               2016                 :                : 
                               2017                 :                :         /* Now sort the list of groupsets by length and contents */
                               2018                 :             11 :         list_sort(result, cmp_list_len_contents_asc);
                               2019                 :                : 
                               2020                 :                :         /* Finally, remove duplicates */
 1639 drowley@postgresql.o     2021                 :             11 :         prev = linitial(result);
 1734 tomas.vondra@postgre     2022   [ +  -  +  +  :             78 :         for_each_from(cell, result, 1)
                                              +  + ]
                               2023                 :                :         {
                               2024         [ +  + ]:             67 :             if (equal(lfirst(cell), prev))
      tgl@sss.pgh.pa.us        2025                 :             35 :                 result = foreach_delete_current(result, cell);
                               2026                 :                :             else
      tomas.vondra@postgre     2027                 :             32 :                 prev = lfirst(cell);
                               2028                 :                :         }
                               2029                 :                :     }
                               2030                 :                : 
 3867 andres@anarazel.de       2031                 :           1004 :     return result;
                               2032                 :                : }
                               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
 4376 tgl@sss.pgh.pa.us        2050                 :          55106 : get_aggregate_argtypes(Aggref *aggref, Oid *inputTypes)
                               2051                 :                : {
                               2052                 :          55106 :     int         numArguments = 0;
                               2053                 :                :     ListCell   *lc;
                               2054                 :                : 
 3469                          2055         [ -  + ]:          55106 :     Assert(list_length(aggref->aggargtypes) <= FUNC_MAX_ARGS);
                               2056                 :                : 
                               2057   [ +  +  +  +  :          94327 :     foreach(lc, aggref->aggargtypes)
                                              +  + ]
                               2058                 :                :     {
                               2059                 :          39221 :         inputTypes[numArguments++] = lfirst_oid(lc);
                               2060                 :                :     }
                               2061                 :                : 
 4376                          2062                 :          55106 :     return numArguments;
                               2063                 :                : }
                               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                 :          25086 : 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   [ +  +  +  +  :          25086 :     if (IsPolymorphicType(aggtranstype))
                                     +  -  +  +  +  
                                     +  +  +  +  +  
                                     +  -  +  -  +  
                                           -  -  + ]
                               2083                 :                :     {
                               2084                 :                :         /* have to fetch the agg's declared input types... */
                               2085                 :                :         Oid        *declaredArgTypes;
                               2086                 :                :         int         agg_nargs;
                               2087                 :                : 
                               2088                 :            272 :         (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         [ -  + ]:            272 :         Assert(agg_nargs <= numArguments);
                               2095                 :                : 
                               2096                 :            272 :         aggtranstype = enforce_generic_type_consistency(inputTypes,
                               2097                 :                :                                                         declaredArgTypes,
                               2098                 :                :                                                         agg_nargs,
                               2099                 :                :                                                         aggtranstype,
                               2100                 :                :                                                         false);
                               2101                 :            272 :         pfree(declaredArgTypes);
                               2102                 :                :     }
                               2103                 :          25086 :     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
 1058 drowley@postgresql.o     2112                 :           5669 : agg_args_support_sendreceive(Aggref *aggref)
                               2113                 :                : {
                               2114                 :                :     ListCell   *lc;
                               2115                 :                : 
                               2116   [ +  -  +  +  :          11268 :     foreach(lc, aggref->args)
                                              +  + ]
                               2117                 :                :     {
                               2118                 :                :         HeapTuple   typeTuple;
                               2119                 :                :         Form_pg_type pt;
                               2120                 :           5669 :         TargetEntry *tle = (TargetEntry *) lfirst(lc);
                               2121                 :           5669 :         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                 :                :          */
  282 tgl@sss.pgh.pa.us        2129         [ +  + ]:           5669 :         if (type == RECORDOID)
                               2130                 :             70 :             return false;
                               2131                 :                : 
 1058 drowley@postgresql.o     2132                 :           5648 :         typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(type));
                               2133         [ -  + ]:           5648 :         if (!HeapTupleIsValid(typeTuple))
 1058 drowley@postgresql.o     2134         [ #  # ]:UBC           0 :             elog(ERROR, "cache lookup failed for type %u", type);
                               2135                 :                : 
 1058 drowley@postgresql.o     2136                 :CBC        5648 :         pt = (Form_pg_type) GETSTRUCT(typeTuple);
                               2137                 :                : 
                               2138         [ +  + ]:           5648 :         if (!pt->typbyval &&
                               2139   [ +  +  -  + ]:           5574 :             (!OidIsValid(pt->typsend) || !OidIsValid(pt->typreceive)))
                               2140                 :                :         {
                               2141                 :             49 :             ReleaseSysCache(typeTuple);
                               2142                 :             49 :             return false;
                               2143                 :                :         }
                               2144                 :           5599 :         ReleaseSysCache(typeTuple);
                               2145                 :                :     }
                               2146                 :           5599 :     return true;
                               2147                 :                : }
                               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
 3787 heikki.linnakangas@i     2179                 :          29423 : 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                 :                :     List       *args;
                               2191                 :                :     FuncExpr   *fexpr;
                               2192                 :                :     int         i;
                               2193                 :                : 
                               2194                 :                :     /*
                               2195                 :                :      * Build arg list to use in the transfn FuncExpr node.
                               2196                 :                :      */
 3464 tgl@sss.pgh.pa.us        2197                 :          29423 :     args = list_make1(make_agg_arg(agg_state_type, agg_input_collation));
                               2198                 :                : 
 4376                          2199         [ +  + ]:          51669 :     for (i = agg_num_direct_inputs; i < agg_num_inputs; i++)
                               2200                 :                :     {
 3464                          2201                 :          22246 :         args = lappend(args,
                               2202                 :          22246 :                        make_agg_arg(agg_input_types[i], agg_input_collation));
                               2203                 :                :     }
                               2204                 :                : 
 4487                          2205                 :          29423 :     fexpr = makeFuncExpr(transfn_oid,
                               2206                 :                :                          agg_state_type,
                               2207                 :                :                          args,
                               2208                 :                :                          InvalidOid,
                               2209                 :                :                          agg_input_collation,
                               2210                 :                :                          COERCE_EXPLICIT_CALL);
                               2211                 :          29423 :     fexpr->funcvariadic = agg_variadic;
                               2212                 :          29423 :     *transfnexpr = (Expr *) fexpr;
                               2213                 :                : 
                               2214                 :                :     /*
                               2215                 :                :      * Build invtransfn expression if requested, with same args as transfn
                               2216                 :                :      */
 4266                          2217         [ +  + ]:          29423 :     if (invtransfnexpr != NULL)
                               2218                 :                :     {
                               2219         [ +  + ]:            778 :         if (OidIsValid(invtransfn_oid))
                               2220                 :                :         {
                               2221                 :            399 :             fexpr = makeFuncExpr(invtransfn_oid,
                               2222                 :                :                                  agg_state_type,
                               2223                 :                :                                  args,
                               2224                 :                :                                  InvalidOid,
                               2225                 :                :                                  agg_input_collation,
                               2226                 :                :                                  COERCE_EXPLICIT_CALL);
                               2227                 :            399 :             fexpr->funcvariadic = agg_variadic;
                               2228                 :            399 :             *invtransfnexpr = (Expr *) fexpr;
                               2229                 :                :         }
                               2230                 :                :         else
                               2231                 :            379 :             *invtransfnexpr = NULL;
                               2232                 :                :     }
 3787 heikki.linnakangas@i     2233                 :          29423 : }
                               2234                 :                : 
                               2235                 :                : /*
                               2236                 :                :  * Like build_aggregate_transfn_expr, but creates an expression tree for the
                               2237                 :                :  * serialization function of an aggregate.
                               2238                 :                :  */
                               2239                 :                : void
 3464 tgl@sss.pgh.pa.us        2240                 :            168 : build_aggregate_serialfn_expr(Oid serialfn_oid,
                               2241                 :                :                               Expr **serialfnexpr)
                               2242                 :                : {
                               2243                 :                :     List       *args;
                               2244                 :                :     FuncExpr   *fexpr;
                               2245                 :                : 
                               2246                 :                :     /* serialfn always takes INTERNAL and returns BYTEA */
                               2247                 :            168 :     args = list_make1(make_agg_arg(INTERNALOID, InvalidOid));
                               2248                 :                : 
 3549 rhaas@postgresql.org     2249                 :            168 :     fexpr = makeFuncExpr(serialfn_oid,
                               2250                 :                :                          BYTEAOID,
                               2251                 :                :                          args,
                               2252                 :                :                          InvalidOid,
                               2253                 :                :                          InvalidOid,
                               2254                 :                :                          COERCE_EXPLICIT_CALL);
                               2255                 :            168 :     *serialfnexpr = (Expr *) fexpr;
                               2256                 :            168 : }
                               2257                 :                : 
                               2258                 :                : /*
                               2259                 :                :  * Like build_aggregate_transfn_expr, but creates an expression tree for the
                               2260                 :                :  * deserialization function of an aggregate.
                               2261                 :                :  */
                               2262                 :                : void
 3464 tgl@sss.pgh.pa.us        2263                 :             60 : build_aggregate_deserialfn_expr(Oid deserialfn_oid,
                               2264                 :                :                                 Expr **deserialfnexpr)
                               2265                 :                : {
                               2266                 :                :     List       *args;
                               2267                 :                :     FuncExpr   *fexpr;
                               2268                 :                : 
                               2269                 :                :     /* deserialfn always takes BYTEA, INTERNAL and returns INTERNAL */
                               2270                 :             60 :     args = list_make2(make_agg_arg(BYTEAOID, InvalidOid),
                               2271                 :                :                       make_agg_arg(INTERNALOID, InvalidOid));
                               2272                 :                : 
                               2273                 :             60 :     fexpr = makeFuncExpr(deserialfn_oid,
                               2274                 :                :                          INTERNALOID,
                               2275                 :                :                          args,
                               2276                 :                :                          InvalidOid,
                               2277                 :                :                          InvalidOid,
                               2278                 :                :                          COERCE_EXPLICIT_CALL);
                               2279                 :             60 :     *deserialfnexpr = (Expr *) fexpr;
                               2280                 :             60 : }
                               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
 3787 heikki.linnakangas@i     2287                 :          11689 : 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                 :                :     List       *args;
                               2296                 :                :     int         i;
                               2297                 :                : 
                               2298                 :                :     /*
                               2299                 :                :      * Build expr tree for final function
                               2300                 :                :      */
 3464 tgl@sss.pgh.pa.us        2301                 :          11689 :     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 */
 4255                          2304         [ +  + ]:          19080 :     for (i = 0; i < num_finalfn_inputs - 1; i++)
                               2305                 :                :     {
 3464                          2306                 :           7391 :         args = lappend(args,
                               2307                 :           7391 :                        make_agg_arg(agg_input_types[i], agg_input_collation));
                               2308                 :                :     }
                               2309                 :                : 
 8170 bruce@momjian.us         2310                 :          11689 :     *finalfnexpr = (Expr *) makeFuncExpr(finalfn_oid,
                               2311                 :                :                                          agg_result_type,
                               2312                 :                :                                          args,
                               2313                 :                :                                          InvalidOid,
                               2314                 :                :                                          agg_input_collation,
                               2315                 :                :                                          COERCE_EXPLICIT_CALL);
                               2316                 :                :     /* finalfn is currently never treated as variadic */
 8204 tgl@sss.pgh.pa.us        2317                 :          11689 : }
                               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 *
 3464                          2327                 :          71037 : make_agg_arg(Oid argtype, Oid argcollation)
                               2328                 :                : {
                               2329                 :          71037 :     Param      *argp = makeNode(Param);
                               2330                 :                : 
                               2331                 :          71037 :     argp->paramkind = PARAM_EXEC;
                               2332                 :          71037 :     argp->paramid = -1;
                               2333                 :          71037 :     argp->paramtype = argtype;
                               2334                 :          71037 :     argp->paramtypmod = -1;
                               2335                 :          71037 :     argp->paramcollid = argcollation;
                               2336                 :          71037 :     argp->location = -1;
                               2337                 :          71037 :     return (Node *) argp;
                               2338                 :                : }
        

Generated by: LCOV version 2.4-beta