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

Generated by: LCOV version 2.4-beta