LCOV - differential code coverage report
Current view: top level - src/backend/parser - parse_agg.c (source / functions) Coverage Total Hit UBC GNC CBC DCB
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 75.6 % 804 608 196 1 607 1
Current Date: 2024-04-14 14:21:10 Functions: 100.0 % 23 23 3 20
Baseline: 16@8cea358b128 Branches: 69.4 % 708 491 217 491
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed [..60] days: 100.0 % 1 1 1
(120,180] days: 100.0 % 9 9 9
(240..) days: 75.3 % 794 598 196 598
Function coverage date bins:
(240..) days: 100.0 % 23 23 3 20
Branch coverage date bins:
(120,180] days: 100.0 % 14 14 14
(240..) days: 68.7 % 694 477 217 477

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

Generated by: LCOV version 2.1-beta2-3-g6141622