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