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