LCOV - differential code coverage report
Current view: top level - src/backend/parser - parse_agg.c (source / functions) Coverage Total Hit UNC UBC GBC GNC CBC DUB DCB
Current: 0e5ff9b9b45a657aea12440478dc002e9b01f138 vs 0123ce131fca454009439dfa3b2266d1d40737d7 Lines: 77.5 % 876 679 197 33 646 10
Current Date: 2026-03-14 14:10:32 -0400 Functions: 100.0 % 24 24 5 19
Baseline: lcov-20260315-024220-baseline Branches: 70.5 % 750 529 7 214 4 27 498 7 17
Baseline Date: 2026-03-14 15:27:56 +0100 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(7,30] days: 100.0 % 38 38 33 5
(30,360] days: 88.9 % 18 16 2 16
(360..) days: 76.2 % 820 625 195 625
Function coverage date bins:
(360..) days: 100.0 % 24 24 5 19
Branch coverage date bins:
(7,30] days: 80.6 % 36 29 7 27 2
(30,360] days: 54.5 % 22 12 10 12
(360..) days: 70.5 % 692 488 204 4 484

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

Generated by: LCOV version 2.4-beta