Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * nodeFuncs.c
4 : * Various general-purpose manipulations of Node trees
5 : *
6 : * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
7 : * Portions Copyright (c) 1994, Regents of the University of California
8 : *
9 : *
10 : * IDENTIFICATION
11 : * src/backend/nodes/nodeFuncs.c
12 : *
13 : *-------------------------------------------------------------------------
14 : */
15 : #include "postgres.h"
16 :
17 : #include "catalog/pg_collation.h"
18 : #include "catalog/pg_type.h"
19 : #include "miscadmin.h"
20 : #include "nodes/makefuncs.h"
21 : #include "nodes/execnodes.h"
22 : #include "nodes/nodeFuncs.h"
23 : #include "nodes/relation.h"
24 : #include "utils/builtins.h"
25 : #include "utils/lsyscache.h"
26 :
27 :
28 : static bool expression_returns_set_walker(Node *node, void *context);
29 : static int leftmostLoc(int loc1, int loc2);
30 : static bool fix_opfuncids_walker(Node *node, void *context);
31 : static bool planstate_walk_subplans(List *plans, bool (*walker) (),
32 : void *context);
33 : static bool planstate_walk_members(List *plans, PlanState **planstates,
34 : bool (*walker) (), void *context);
35 :
36 :
37 : /*
38 : * exprType -
39 : * returns the Oid of the type of the expression's result.
40 : */
41 : Oid
42 818566 : exprType(const Node *expr)
43 : {
44 : Oid type;
45 :
46 818566 : if (!expr)
47 0 : return InvalidOid;
48 :
49 818566 : switch (nodeTag(expr))
50 : {
51 : case T_Var:
52 382346 : type = ((const Var *) expr)->vartype;
53 382346 : break;
54 : case T_Const:
55 146452 : type = ((const Const *) expr)->consttype;
56 146452 : break;
57 : case T_Param:
58 60504 : type = ((const Param *) expr)->paramtype;
59 60504 : break;
60 : case T_Aggref:
61 14649 : type = ((const Aggref *) expr)->aggtype;
62 14649 : break;
63 : case T_GroupingFunc:
64 253 : type = INT4OID;
65 253 : break;
66 : case T_WindowFunc:
67 951 : type = ((const WindowFunc *) expr)->wintype;
68 951 : break;
69 : case T_ArrayRef:
70 : {
71 2139 : const ArrayRef *arrayref = (const ArrayRef *) expr;
72 :
73 : /* slice and/or store operations yield the array type */
74 2139 : if (arrayref->reflowerindexpr || arrayref->refassgnexpr)
75 613 : type = arrayref->refarraytype;
76 : else
77 1526 : type = arrayref->refelemtype;
78 : }
79 2139 : break;
80 : case T_FuncExpr:
81 100568 : type = ((const FuncExpr *) expr)->funcresulttype;
82 100568 : break;
83 : case T_NamedArgExpr:
84 198 : type = exprType((Node *) ((const NamedArgExpr *) expr)->arg);
85 198 : break;
86 : case T_OpExpr:
87 52002 : type = ((const OpExpr *) expr)->opresulttype;
88 52002 : break;
89 : case T_DistinctExpr:
90 102 : type = ((const DistinctExpr *) expr)->opresulttype;
91 102 : break;
92 : case T_NullIfExpr:
93 57 : type = ((const NullIfExpr *) expr)->opresulttype;
94 57 : break;
95 : case T_ScalarArrayOpExpr:
96 1193 : type = BOOLOID;
97 1193 : break;
98 : case T_BoolExpr:
99 10340 : type = BOOLOID;
100 10340 : break;
101 : case T_SubLink:
102 : {
103 3650 : const SubLink *sublink = (const SubLink *) expr;
104 :
105 5303 : if (sublink->subLinkType == EXPR_SUBLINK ||
106 1653 : sublink->subLinkType == ARRAY_SUBLINK)
107 2886 : {
108 : /* get the type of the subselect's first target column */
109 2886 : Query *qtree = (Query *) sublink->subselect;
110 : TargetEntry *tent;
111 :
112 2886 : if (!qtree || !IsA(qtree, Query))
113 0 : elog(ERROR, "cannot get type for untransformed sublink");
114 2886 : tent = linitial_node(TargetEntry, qtree->targetList);
115 2886 : Assert(!tent->resjunk);
116 2886 : type = exprType((Node *) tent->expr);
117 2886 : if (sublink->subLinkType == ARRAY_SUBLINK)
118 : {
119 889 : type = get_promoted_array_type(type);
120 889 : if (!OidIsValid(type))
121 0 : ereport(ERROR,
122 : (errcode(ERRCODE_UNDEFINED_OBJECT),
123 : errmsg("could not find array type for data type %s",
124 : format_type_be(exprType((Node *) tent->expr)))));
125 : }
126 : }
127 764 : else if (sublink->subLinkType == MULTIEXPR_SUBLINK)
128 : {
129 : /* MULTIEXPR is always considered to return RECORD */
130 9 : type = RECORDOID;
131 : }
132 : else
133 : {
134 : /* for all other sublink types, result is boolean */
135 755 : type = BOOLOID;
136 : }
137 : }
138 3650 : break;
139 : case T_SubPlan:
140 : {
141 2579 : const SubPlan *subplan = (const SubPlan *) expr;
142 :
143 2801 : if (subplan->subLinkType == EXPR_SUBLINK ||
144 222 : subplan->subLinkType == ARRAY_SUBLINK)
145 : {
146 : /* get the type of the subselect's first target column */
147 2407 : type = subplan->firstColType;
148 4814 : if (subplan->subLinkType == ARRAY_SUBLINK)
149 : {
150 50 : type = get_promoted_array_type(type);
151 50 : if (!OidIsValid(type))
152 0 : ereport(ERROR,
153 : (errcode(ERRCODE_UNDEFINED_OBJECT),
154 : errmsg("could not find array type for data type %s",
155 : format_type_be(subplan->firstColType))));
156 : }
157 : }
158 172 : else if (subplan->subLinkType == MULTIEXPR_SUBLINK)
159 : {
160 : /* MULTIEXPR is always considered to return RECORD */
161 11 : type = RECORDOID;
162 : }
163 : else
164 : {
165 : /* for all other subplan types, result is boolean */
166 161 : type = BOOLOID;
167 : }
168 : }
169 2579 : break;
170 : case T_AlternativeSubPlan:
171 : {
172 57 : const AlternativeSubPlan *asplan = (const AlternativeSubPlan *) expr;
173 :
174 : /* subplans should all return the same thing */
175 57 : type = exprType((Node *) linitial(asplan->subplans));
176 : }
177 57 : break;
178 : case T_FieldSelect:
179 1190 : type = ((const FieldSelect *) expr)->resulttype;
180 1190 : break;
181 : case T_FieldStore:
182 126 : type = ((const FieldStore *) expr)->resulttype;
183 126 : break;
184 : case T_RelabelType:
185 13826 : type = ((const RelabelType *) expr)->resulttype;
186 13826 : break;
187 : case T_CoerceViaIO:
188 3838 : type = ((const CoerceViaIO *) expr)->resulttype;
189 3838 : break;
190 : case T_ArrayCoerceExpr:
191 88 : type = ((const ArrayCoerceExpr *) expr)->resulttype;
192 88 : break;
193 : case T_ConvertRowtypeExpr:
194 161 : type = ((const ConvertRowtypeExpr *) expr)->resulttype;
195 161 : break;
196 : case T_CollateExpr:
197 63 : type = exprType((Node *) ((const CollateExpr *) expr)->arg);
198 63 : break;
199 : case T_CaseExpr:
200 5973 : type = ((const CaseExpr *) expr)->casetype;
201 5973 : break;
202 : case T_CaseTestExpr:
203 1222 : type = ((const CaseTestExpr *) expr)->typeId;
204 1222 : break;
205 : case T_ArrayExpr:
206 2101 : type = ((const ArrayExpr *) expr)->array_typeid;
207 2101 : break;
208 : case T_RowExpr:
209 867 : type = ((const RowExpr *) expr)->row_typeid;
210 867 : break;
211 : case T_RowCompareExpr:
212 46 : type = BOOLOID;
213 46 : break;
214 : case T_CoalesceExpr:
215 1081 : type = ((const CoalesceExpr *) expr)->coalescetype;
216 1081 : break;
217 : case T_MinMaxExpr:
218 99 : type = ((const MinMaxExpr *) expr)->minmaxtype;
219 99 : break;
220 : case T_SQLValueFunction:
221 726 : type = ((const SQLValueFunction *) expr)->type;
222 726 : break;
223 : case T_XmlExpr:
224 126 : if (((const XmlExpr *) expr)->op == IS_DOCUMENT)
225 0 : type = BOOLOID;
226 126 : else if (((const XmlExpr *) expr)->op == IS_XMLSERIALIZE)
227 1 : type = TEXTOID;
228 : else
229 125 : type = XMLOID;
230 126 : break;
231 : case T_NullTest:
232 1248 : type = BOOLOID;
233 1248 : break;
234 : case T_BooleanTest:
235 60 : type = BOOLOID;
236 60 : break;
237 : case T_CoerceToDomain:
238 6504 : type = ((const CoerceToDomain *) expr)->resulttype;
239 6504 : break;
240 : case T_CoerceToDomainValue:
241 86 : type = ((const CoerceToDomainValue *) expr)->typeId;
242 86 : break;
243 : case T_SetToDefault:
244 578 : type = ((const SetToDefault *) expr)->typeId;
245 578 : break;
246 : case T_CurrentOfExpr:
247 36 : type = BOOLOID;
248 36 : break;
249 : case T_NextValueExpr:
250 122 : type = ((const NextValueExpr *) expr)->typeId;
251 122 : break;
252 : case T_InferenceElem:
253 : {
254 0 : const InferenceElem *n = (const InferenceElem *) expr;
255 :
256 0 : type = exprType((Node *) n->expr);
257 : }
258 0 : break;
259 : case T_PlaceHolderVar:
260 359 : type = exprType((Node *) ((const PlaceHolderVar *) expr)->phexpr);
261 359 : break;
262 : default:
263 0 : elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
264 : type = InvalidOid; /* keep compiler quiet */
265 : break;
266 : }
267 818566 : return type;
268 : }
269 :
270 : /*
271 : * exprTypmod -
272 : * returns the type-specific modifier of the expression's result type,
273 : * if it can be determined. In many cases, it can't and we return -1.
274 : */
275 : int32
276 265759 : exprTypmod(const Node *expr)
277 : {
278 265759 : if (!expr)
279 0 : return -1;
280 :
281 265759 : switch (nodeTag(expr))
282 : {
283 : case T_Var:
284 139288 : return ((const Var *) expr)->vartypmod;
285 : case T_Const:
286 45023 : return ((const Const *) expr)->consttypmod;
287 : case T_Param:
288 6227 : return ((const Param *) expr)->paramtypmod;
289 : case T_ArrayRef:
290 : /* typmod is the same for array or element */
291 697 : return ((const ArrayRef *) expr)->reftypmod;
292 : case T_FuncExpr:
293 : {
294 : int32 coercedTypmod;
295 :
296 : /* Be smart about length-coercion functions... */
297 42995 : if (exprIsLengthCoercion(expr, &coercedTypmod))
298 2635 : return coercedTypmod;
299 : }
300 40360 : break;
301 : case T_NamedArgExpr:
302 0 : return exprTypmod((Node *) ((const NamedArgExpr *) expr)->arg);
303 : case T_NullIfExpr:
304 : {
305 : /*
306 : * Result is either first argument or NULL, so we can report
307 : * first argument's typmod if known.
308 : */
309 16 : const NullIfExpr *nexpr = (const NullIfExpr *) expr;
310 :
311 16 : return exprTypmod((Node *) linitial(nexpr->args));
312 : }
313 : break;
314 : case T_SubLink:
315 : {
316 96 : const SubLink *sublink = (const SubLink *) expr;
317 :
318 106 : if (sublink->subLinkType == EXPR_SUBLINK ||
319 10 : sublink->subLinkType == ARRAY_SUBLINK)
320 : {
321 : /* get the typmod of the subselect's first target column */
322 91 : Query *qtree = (Query *) sublink->subselect;
323 : TargetEntry *tent;
324 :
325 91 : if (!qtree || !IsA(qtree, Query))
326 0 : elog(ERROR, "cannot get type for untransformed sublink");
327 91 : tent = linitial_node(TargetEntry, qtree->targetList);
328 91 : Assert(!tent->resjunk);
329 91 : return exprTypmod((Node *) tent->expr);
330 : /* note we don't need to care if it's an array */
331 : }
332 : /* otherwise, result is RECORD or BOOLEAN, typmod is -1 */
333 : }
334 5 : break;
335 : case T_SubPlan:
336 : {
337 1734 : const SubPlan *subplan = (const SubPlan *) expr;
338 :
339 1858 : if (subplan->subLinkType == EXPR_SUBLINK ||
340 124 : subplan->subLinkType == ARRAY_SUBLINK)
341 : {
342 : /* get the typmod of the subselect's first target column */
343 : /* note we don't need to care if it's an array */
344 1644 : return subplan->firstColTypmod;
345 : }
346 : /* otherwise, result is RECORD or BOOLEAN, typmod is -1 */
347 : }
348 90 : break;
349 : case T_AlternativeSubPlan:
350 : {
351 29 : const AlternativeSubPlan *asplan = (const AlternativeSubPlan *) expr;
352 :
353 : /* subplans should all return the same thing */
354 29 : return exprTypmod((Node *) linitial(asplan->subplans));
355 : }
356 : break;
357 : case T_FieldSelect:
358 537 : return ((const FieldSelect *) expr)->resulttypmod;
359 : case T_RelabelType:
360 3250 : return ((const RelabelType *) expr)->resulttypmod;
361 : case T_ArrayCoerceExpr:
362 5 : return ((const ArrayCoerceExpr *) expr)->resulttypmod;
363 : case T_CollateExpr:
364 3 : return exprTypmod((Node *) ((const CollateExpr *) expr)->arg);
365 : case T_CaseExpr:
366 : {
367 : /*
368 : * If all the alternatives agree on type/typmod, return that
369 : * typmod, else use -1
370 : */
371 2686 : const CaseExpr *cexpr = (const CaseExpr *) expr;
372 2686 : Oid casetype = cexpr->casetype;
373 : int32 typmod;
374 : ListCell *arg;
375 :
376 2686 : if (!cexpr->defresult)
377 0 : return -1;
378 2686 : if (exprType((Node *) cexpr->defresult) != casetype)
379 0 : return -1;
380 2686 : typmod = exprTypmod((Node *) cexpr->defresult);
381 2686 : if (typmod < 0)
382 2686 : return -1; /* no point in trying harder */
383 0 : foreach(arg, cexpr->args)
384 : {
385 0 : CaseWhen *w = lfirst_node(CaseWhen, arg);
386 :
387 0 : if (exprType((Node *) w->result) != casetype)
388 0 : return -1;
389 0 : if (exprTypmod((Node *) w->result) != typmod)
390 0 : return -1;
391 : }
392 0 : return typmod;
393 : }
394 : break;
395 : case T_CaseTestExpr:
396 183 : return ((const CaseTestExpr *) expr)->typeMod;
397 : case T_ArrayExpr:
398 : {
399 : /*
400 : * If all the elements agree on type/typmod, return that
401 : * typmod, else use -1
402 : */
403 1409 : const ArrayExpr *arrayexpr = (const ArrayExpr *) expr;
404 : Oid commontype;
405 : int32 typmod;
406 : ListCell *elem;
407 :
408 1409 : if (arrayexpr->elements == NIL)
409 14 : return -1;
410 1395 : typmod = exprTypmod((Node *) linitial(arrayexpr->elements));
411 1395 : if (typmod < 0)
412 1327 : return -1; /* no point in trying harder */
413 68 : if (arrayexpr->multidims)
414 0 : commontype = arrayexpr->array_typeid;
415 : else
416 68 : commontype = arrayexpr->element_typeid;
417 136 : foreach(elem, arrayexpr->elements)
418 : {
419 68 : Node *e = (Node *) lfirst(elem);
420 :
421 68 : if (exprType(e) != commontype)
422 0 : return -1;
423 68 : if (exprTypmod(e) != typmod)
424 0 : return -1;
425 : }
426 68 : return typmod;
427 : }
428 : break;
429 : case T_CoalesceExpr:
430 : {
431 : /*
432 : * If all the alternatives agree on type/typmod, return that
433 : * typmod, else use -1
434 : */
435 446 : const CoalesceExpr *cexpr = (const CoalesceExpr *) expr;
436 446 : Oid coalescetype = cexpr->coalescetype;
437 : int32 typmod;
438 : ListCell *arg;
439 :
440 446 : if (exprType((Node *) linitial(cexpr->args)) != coalescetype)
441 0 : return -1;
442 446 : typmod = exprTypmod((Node *) linitial(cexpr->args));
443 446 : if (typmod < 0)
444 446 : return -1; /* no point in trying harder */
445 0 : for_each_cell(arg, lnext(list_head(cexpr->args)))
446 : {
447 0 : Node *e = (Node *) lfirst(arg);
448 :
449 0 : if (exprType(e) != coalescetype)
450 0 : return -1;
451 0 : if (exprTypmod(e) != typmod)
452 0 : return -1;
453 : }
454 0 : return typmod;
455 : }
456 : break;
457 : case T_MinMaxExpr:
458 : {
459 : /*
460 : * If all the alternatives agree on type/typmod, return that
461 : * typmod, else use -1
462 : */
463 40 : const MinMaxExpr *mexpr = (const MinMaxExpr *) expr;
464 40 : Oid minmaxtype = mexpr->minmaxtype;
465 : int32 typmod;
466 : ListCell *arg;
467 :
468 40 : if (exprType((Node *) linitial(mexpr->args)) != minmaxtype)
469 0 : return -1;
470 40 : typmod = exprTypmod((Node *) linitial(mexpr->args));
471 40 : if (typmod < 0)
472 40 : return -1; /* no point in trying harder */
473 0 : for_each_cell(arg, lnext(list_head(mexpr->args)))
474 : {
475 0 : Node *e = (Node *) lfirst(arg);
476 :
477 0 : if (exprType(e) != minmaxtype)
478 0 : return -1;
479 0 : if (exprTypmod(e) != typmod)
480 0 : return -1;
481 : }
482 0 : return typmod;
483 : }
484 : break;
485 : case T_SQLValueFunction:
486 163 : return ((const SQLValueFunction *) expr)->typmod;
487 : case T_CoerceToDomain:
488 3522 : return ((const CoerceToDomain *) expr)->resulttypmod;
489 : case T_CoerceToDomainValue:
490 8 : return ((const CoerceToDomainValue *) expr)->typeMod;
491 : case T_SetToDefault:
492 182 : return ((const SetToDefault *) expr)->typeMod;
493 : case T_PlaceHolderVar:
494 263 : return exprTypmod((Node *) ((const PlaceHolderVar *) expr)->phexpr);
495 : default:
496 16957 : break;
497 : }
498 57412 : return -1;
499 : }
500 :
501 : /*
502 : * exprIsLengthCoercion
503 : * Detect whether an expression tree is an application of a datatype's
504 : * typmod-coercion function. Optionally extract the result's typmod.
505 : *
506 : * If coercedTypmod is not NULL, the typmod is stored there if the expression
507 : * is a length-coercion function, else -1 is stored there.
508 : *
509 : * Note that a combined type-and-length coercion will be treated as a
510 : * length coercion by this routine.
511 : */
512 : bool
513 43405 : exprIsLengthCoercion(const Node *expr, int32 *coercedTypmod)
514 : {
515 43405 : if (coercedTypmod != NULL)
516 43117 : *coercedTypmod = -1; /* default result on failure */
517 :
518 : /*
519 : * Scalar-type length coercions are FuncExprs, array-type length coercions
520 : * are ArrayCoerceExprs
521 : */
522 43405 : if (expr && IsA(expr, FuncExpr))
523 : {
524 43390 : const FuncExpr *func = (const FuncExpr *) expr;
525 : int nargs;
526 : Const *second_arg;
527 :
528 : /*
529 : * If it didn't come from a coercion context, reject.
530 : */
531 84951 : if (func->funcformat != COERCE_EXPLICIT_CAST &&
532 41561 : func->funcformat != COERCE_IMPLICIT_CAST)
533 36257 : return false;
534 :
535 : /*
536 : * If it's not a two-argument or three-argument function with the
537 : * second argument being an int4 constant, it can't have been created
538 : * from a length coercion (it must be a type coercion, instead).
539 : */
540 7133 : nargs = list_length(func->args);
541 7133 : if (nargs < 2 || nargs > 3)
542 4494 : return false;
543 :
544 2639 : second_arg = (Const *) lsecond(func->args);
545 5278 : if (!IsA(second_arg, Const) ||
546 5278 : second_arg->consttype != INT4OID ||
547 2639 : second_arg->constisnull)
548 0 : return false;
549 :
550 : /*
551 : * OK, it is indeed a length-coercion function.
552 : */
553 2639 : if (coercedTypmod != NULL)
554 2639 : *coercedTypmod = DatumGetInt32(second_arg->constvalue);
555 :
556 2639 : return true;
557 : }
558 :
559 15 : if (expr && IsA(expr, ArrayCoerceExpr))
560 : {
561 0 : const ArrayCoerceExpr *acoerce = (const ArrayCoerceExpr *) expr;
562 :
563 : /* It's not a length coercion unless there's a nondefault typmod */
564 0 : if (acoerce->resulttypmod < 0)
565 0 : return false;
566 :
567 : /*
568 : * OK, it is indeed a length-coercion expression.
569 : */
570 0 : if (coercedTypmod != NULL)
571 0 : *coercedTypmod = acoerce->resulttypmod;
572 :
573 0 : return true;
574 : }
575 :
576 15 : return false;
577 : }
578 :
579 : /*
580 : * relabel_to_typmod
581 : * Add a RelabelType node that changes just the typmod of the expression.
582 : *
583 : * This is primarily intended to be used during planning. Therefore, it
584 : * strips any existing RelabelType nodes to maintain the planner's invariant
585 : * that there are not adjacent RelabelTypes.
586 : */
587 : Node *
588 1 : relabel_to_typmod(Node *expr, int32 typmod)
589 : {
590 1 : Oid type = exprType(expr);
591 1 : Oid coll = exprCollation(expr);
592 :
593 : /* Strip any existing RelabelType node(s) */
594 2 : while (expr && IsA(expr, RelabelType))
595 0 : expr = (Node *) ((RelabelType *) expr)->arg;
596 :
597 : /* Apply new typmod, preserving the previous exposed type and collation */
598 1 : return (Node *) makeRelabelType((Expr *) expr, type, typmod, coll,
599 : COERCE_EXPLICIT_CAST);
600 : }
601 :
602 : /*
603 : * strip_implicit_coercions: remove implicit coercions at top level of tree
604 : *
605 : * This doesn't modify or copy the input expression tree, just return a
606 : * pointer to a suitable place within it.
607 : *
608 : * Note: there isn't any useful thing we can do with a RowExpr here, so
609 : * just return it unchanged, even if it's marked as an implicit coercion.
610 : */
611 : Node *
612 38932 : strip_implicit_coercions(Node *node)
613 : {
614 38932 : if (node == NULL)
615 1 : return NULL;
616 38931 : if (IsA(node, FuncExpr))
617 : {
618 549 : FuncExpr *f = (FuncExpr *) node;
619 :
620 549 : if (f->funcformat == COERCE_IMPLICIT_CAST)
621 30 : return strip_implicit_coercions(linitial(f->args));
622 : }
623 38382 : else if (IsA(node, RelabelType))
624 : {
625 372 : RelabelType *r = (RelabelType *) node;
626 :
627 372 : if (r->relabelformat == COERCE_IMPLICIT_CAST)
628 2 : return strip_implicit_coercions((Node *) r->arg);
629 : }
630 38010 : else if (IsA(node, CoerceViaIO))
631 : {
632 43 : CoerceViaIO *c = (CoerceViaIO *) node;
633 :
634 43 : if (c->coerceformat == COERCE_IMPLICIT_CAST)
635 0 : return strip_implicit_coercions((Node *) c->arg);
636 : }
637 37967 : else if (IsA(node, ArrayCoerceExpr))
638 : {
639 0 : ArrayCoerceExpr *c = (ArrayCoerceExpr *) node;
640 :
641 0 : if (c->coerceformat == COERCE_IMPLICIT_CAST)
642 0 : return strip_implicit_coercions((Node *) c->arg);
643 : }
644 37967 : else if (IsA(node, ConvertRowtypeExpr))
645 : {
646 0 : ConvertRowtypeExpr *c = (ConvertRowtypeExpr *) node;
647 :
648 0 : if (c->convertformat == COERCE_IMPLICIT_CAST)
649 0 : return strip_implicit_coercions((Node *) c->arg);
650 : }
651 37967 : else if (IsA(node, CoerceToDomain))
652 : {
653 16 : CoerceToDomain *c = (CoerceToDomain *) node;
654 :
655 16 : if (c->coercionformat == COERCE_IMPLICIT_CAST)
656 0 : return strip_implicit_coercions((Node *) c->arg);
657 : }
658 38899 : return node;
659 : }
660 :
661 : /*
662 : * expression_returns_set
663 : * Test whether an expression returns a set result.
664 : *
665 : * Because we use expression_tree_walker(), this can also be applied to
666 : * whole targetlists; it'll produce TRUE if any one of the tlist items
667 : * returns a set.
668 : */
669 : bool
670 25100 : expression_returns_set(Node *clause)
671 : {
672 25100 : return expression_returns_set_walker(clause, NULL);
673 : }
674 :
675 : static bool
676 101413 : expression_returns_set_walker(Node *node, void *context)
677 : {
678 101413 : if (node == NULL)
679 1309 : return false;
680 100104 : if (IsA(node, FuncExpr))
681 : {
682 3463 : FuncExpr *expr = (FuncExpr *) node;
683 :
684 3463 : if (expr->funcretset)
685 350 : return true;
686 : /* else fall through to check args */
687 : }
688 99754 : if (IsA(node, OpExpr))
689 : {
690 23901 : OpExpr *expr = (OpExpr *) node;
691 :
692 23901 : if (expr->opretset)
693 1 : return true;
694 : /* else fall through to check args */
695 : }
696 :
697 : /* Avoid recursion for some cases that parser checks not to return a set */
698 99753 : if (IsA(node, Aggref))
699 60 : return false;
700 99693 : if (IsA(node, WindowFunc))
701 5 : return false;
702 :
703 99688 : return expression_tree_walker(node, expression_returns_set_walker,
704 : context);
705 : }
706 :
707 :
708 : /*
709 : * exprCollation -
710 : * returns the Oid of the collation of the expression's result.
711 : *
712 : * Note: expression nodes that can invoke functions generally have an
713 : * "inputcollid" field, which is what the function should use as collation.
714 : * That is the resolved common collation of the node's inputs. It is often
715 : * but not always the same as the result collation; in particular, if the
716 : * function produces a non-collatable result type from collatable inputs
717 : * or vice versa, the two are different.
718 : */
719 : Oid
720 369532 : exprCollation(const Node *expr)
721 : {
722 : Oid coll;
723 :
724 369532 : if (!expr)
725 0 : return InvalidOid;
726 :
727 369532 : switch (nodeTag(expr))
728 : {
729 : case T_Var:
730 257434 : coll = ((const Var *) expr)->varcollid;
731 257434 : break;
732 : case T_Const:
733 67310 : coll = ((const Const *) expr)->constcollid;
734 67310 : break;
735 : case T_Param:
736 8427 : coll = ((const Param *) expr)->paramcollid;
737 8427 : break;
738 : case T_Aggref:
739 4276 : coll = ((const Aggref *) expr)->aggcollid;
740 4276 : break;
741 : case T_GroupingFunc:
742 106 : coll = InvalidOid;
743 106 : break;
744 : case T_WindowFunc:
745 276 : coll = ((const WindowFunc *) expr)->wincollid;
746 276 : break;
747 : case T_ArrayRef:
748 456 : coll = ((const ArrayRef *) expr)->refcollid;
749 456 : break;
750 : case T_FuncExpr:
751 15298 : coll = ((const FuncExpr *) expr)->funccollid;
752 15298 : break;
753 : case T_NamedArgExpr:
754 0 : coll = exprCollation((Node *) ((const NamedArgExpr *) expr)->arg);
755 0 : break;
756 : case T_OpExpr:
757 5336 : coll = ((const OpExpr *) expr)->opcollid;
758 5336 : break;
759 : case T_DistinctExpr:
760 20 : coll = ((const DistinctExpr *) expr)->opcollid;
761 20 : break;
762 : case T_NullIfExpr:
763 17 : coll = ((const NullIfExpr *) expr)->opcollid;
764 17 : break;
765 : case T_ScalarArrayOpExpr:
766 57 : coll = InvalidOid; /* result is always boolean */
767 57 : break;
768 : case T_BoolExpr:
769 154 : coll = InvalidOid; /* result is always boolean */
770 154 : break;
771 : case T_SubLink:
772 : {
773 96 : const SubLink *sublink = (const SubLink *) expr;
774 :
775 103 : if (sublink->subLinkType == EXPR_SUBLINK ||
776 7 : sublink->subLinkType == ARRAY_SUBLINK)
777 91 : {
778 : /* get the collation of subselect's first target column */
779 91 : Query *qtree = (Query *) sublink->subselect;
780 : TargetEntry *tent;
781 :
782 91 : if (!qtree || !IsA(qtree, Query))
783 0 : elog(ERROR, "cannot get collation for untransformed sublink");
784 91 : tent = linitial_node(TargetEntry, qtree->targetList);
785 91 : Assert(!tent->resjunk);
786 91 : coll = exprCollation((Node *) tent->expr);
787 : /* collation doesn't change if it's converted to array */
788 : }
789 : else
790 : {
791 : /* otherwise, result is RECORD or BOOLEAN */
792 5 : coll = InvalidOid;
793 : }
794 : }
795 96 : break;
796 : case T_SubPlan:
797 : {
798 923 : const SubPlan *subplan = (const SubPlan *) expr;
799 :
800 951 : if (subplan->subLinkType == EXPR_SUBLINK ||
801 28 : subplan->subLinkType == ARRAY_SUBLINK)
802 : {
803 : /* get the collation of subselect's first target column */
804 908 : coll = subplan->firstColCollation;
805 : /* collation doesn't change if it's converted to array */
806 : }
807 : else
808 : {
809 : /* otherwise, result is RECORD or BOOLEAN */
810 15 : coll = InvalidOid;
811 : }
812 : }
813 923 : break;
814 : case T_AlternativeSubPlan:
815 : {
816 1 : const AlternativeSubPlan *asplan = (const AlternativeSubPlan *) expr;
817 :
818 : /* subplans should all return the same thing */
819 1 : coll = exprCollation((Node *) linitial(asplan->subplans));
820 : }
821 1 : break;
822 : case T_FieldSelect:
823 350 : coll = ((const FieldSelect *) expr)->resultcollid;
824 350 : break;
825 : case T_FieldStore:
826 9 : coll = InvalidOid; /* result is always composite */
827 9 : break;
828 : case T_RelabelType:
829 2144 : coll = ((const RelabelType *) expr)->resultcollid;
830 2144 : break;
831 : case T_CoerceViaIO:
832 976 : coll = ((const CoerceViaIO *) expr)->resultcollid;
833 976 : break;
834 : case T_ArrayCoerceExpr:
835 11 : coll = ((const ArrayCoerceExpr *) expr)->resultcollid;
836 11 : break;
837 : case T_ConvertRowtypeExpr:
838 35 : coll = InvalidOid; /* result is always composite */
839 35 : break;
840 : case T_CollateExpr:
841 2 : coll = ((const CollateExpr *) expr)->collOid;
842 2 : break;
843 : case T_CaseExpr:
844 1650 : coll = ((const CaseExpr *) expr)->casecollid;
845 1650 : break;
846 : case T_CaseTestExpr:
847 857 : coll = ((const CaseTestExpr *) expr)->collation;
848 857 : break;
849 : case T_ArrayExpr:
850 92 : coll = ((const ArrayExpr *) expr)->array_collid;
851 92 : break;
852 : case T_RowExpr:
853 139 : coll = InvalidOid; /* result is always composite */
854 139 : break;
855 : case T_RowCompareExpr:
856 10 : coll = InvalidOid; /* result is always boolean */
857 10 : break;
858 : case T_CoalesceExpr:
859 338 : coll = ((const CoalesceExpr *) expr)->coalescecollid;
860 338 : break;
861 : case T_MinMaxExpr:
862 40 : coll = ((const MinMaxExpr *) expr)->minmaxcollid;
863 40 : break;
864 : case T_SQLValueFunction:
865 114 : coll = InvalidOid; /* all cases return non-collatable types */
866 114 : break;
867 : case T_XmlExpr:
868 :
869 : /*
870 : * XMLSERIALIZE returns text from non-collatable inputs, so its
871 : * collation is always default. The other cases return boolean or
872 : * XML, which are non-collatable.
873 : */
874 25 : if (((const XmlExpr *) expr)->op == IS_XMLSERIALIZE)
875 0 : coll = DEFAULT_COLLATION_OID;
876 : else
877 25 : coll = InvalidOid;
878 25 : break;
879 : case T_NullTest:
880 120 : coll = InvalidOid; /* result is always boolean */
881 120 : break;
882 : case T_BooleanTest:
883 12 : coll = InvalidOid; /* result is always boolean */
884 12 : break;
885 : case T_CoerceToDomain:
886 1943 : coll = ((const CoerceToDomain *) expr)->resultcollid;
887 1943 : break;
888 : case T_CoerceToDomainValue:
889 46 : coll = ((const CoerceToDomainValue *) expr)->collation;
890 46 : break;
891 : case T_SetToDefault:
892 214 : coll = ((const SetToDefault *) expr)->collation;
893 214 : break;
894 : case T_CurrentOfExpr:
895 36 : coll = InvalidOid; /* result is always boolean */
896 36 : break;
897 : case T_NextValueExpr:
898 32 : coll = InvalidOid; /* result is always an integer type */
899 32 : break;
900 : case T_InferenceElem:
901 0 : coll = exprCollation((Node *) ((const InferenceElem *) expr)->expr);
902 0 : break;
903 : case T_PlaceHolderVar:
904 150 : coll = exprCollation((Node *) ((const PlaceHolderVar *) expr)->phexpr);
905 150 : break;
906 : default:
907 0 : elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
908 : coll = InvalidOid; /* keep compiler quiet */
909 : break;
910 : }
911 369532 : return coll;
912 : }
913 :
914 : /*
915 : * exprInputCollation -
916 : * returns the Oid of the collation a function should use, if available.
917 : *
918 : * Result is InvalidOid if the node type doesn't store this information.
919 : */
920 : Oid
921 7 : exprInputCollation(const Node *expr)
922 : {
923 : Oid coll;
924 :
925 7 : if (!expr)
926 0 : return InvalidOid;
927 :
928 7 : switch (nodeTag(expr))
929 : {
930 : case T_Aggref:
931 0 : coll = ((const Aggref *) expr)->inputcollid;
932 0 : break;
933 : case T_WindowFunc:
934 0 : coll = ((const WindowFunc *) expr)->inputcollid;
935 0 : break;
936 : case T_FuncExpr:
937 7 : coll = ((const FuncExpr *) expr)->inputcollid;
938 7 : break;
939 : case T_OpExpr:
940 0 : coll = ((const OpExpr *) expr)->inputcollid;
941 0 : break;
942 : case T_DistinctExpr:
943 0 : coll = ((const DistinctExpr *) expr)->inputcollid;
944 0 : break;
945 : case T_NullIfExpr:
946 0 : coll = ((const NullIfExpr *) expr)->inputcollid;
947 0 : break;
948 : case T_ScalarArrayOpExpr:
949 0 : coll = ((const ScalarArrayOpExpr *) expr)->inputcollid;
950 0 : break;
951 : case T_MinMaxExpr:
952 0 : coll = ((const MinMaxExpr *) expr)->inputcollid;
953 0 : break;
954 : default:
955 0 : coll = InvalidOid;
956 0 : break;
957 : }
958 7 : return coll;
959 : }
960 :
961 : /*
962 : * exprSetCollation -
963 : * Assign collation information to an expression tree node.
964 : *
965 : * Note: since this is only used during parse analysis, we don't need to
966 : * worry about subplans or PlaceHolderVars.
967 : */
968 : void
969 58027 : exprSetCollation(Node *expr, Oid collation)
970 : {
971 58027 : switch (nodeTag(expr))
972 : {
973 : case T_Var:
974 0 : ((Var *) expr)->varcollid = collation;
975 0 : break;
976 : case T_Const:
977 0 : ((Const *) expr)->constcollid = collation;
978 0 : break;
979 : case T_Param:
980 0 : ((Param *) expr)->paramcollid = collation;
981 0 : break;
982 : case T_Aggref:
983 2545 : ((Aggref *) expr)->aggcollid = collation;
984 2545 : break;
985 : case T_GroupingFunc:
986 40 : Assert(!OidIsValid(collation));
987 40 : break;
988 : case T_WindowFunc:
989 168 : ((WindowFunc *) expr)->wincollid = collation;
990 168 : break;
991 : case T_ArrayRef:
992 452 : ((ArrayRef *) expr)->refcollid = collation;
993 452 : break;
994 : case T_FuncExpr:
995 19521 : ((FuncExpr *) expr)->funccollid = collation;
996 19521 : break;
997 : case T_NamedArgExpr:
998 96 : Assert(collation == exprCollation((Node *) ((NamedArgExpr *) expr)->arg));
999 96 : break;
1000 : case T_OpExpr:
1001 19601 : ((OpExpr *) expr)->opcollid = collation;
1002 19601 : break;
1003 : case T_DistinctExpr:
1004 33 : ((DistinctExpr *) expr)->opcollid = collation;
1005 33 : break;
1006 : case T_NullIfExpr:
1007 11 : ((NullIfExpr *) expr)->opcollid = collation;
1008 11 : break;
1009 : case T_ScalarArrayOpExpr:
1010 510 : Assert(!OidIsValid(collation)); /* result is always boolean */
1011 510 : break;
1012 : case T_BoolExpr:
1013 4929 : Assert(!OidIsValid(collation)); /* result is always boolean */
1014 4929 : break;
1015 : case T_SubLink:
1016 : #ifdef USE_ASSERT_CHECKING
1017 : {
1018 1757 : SubLink *sublink = (SubLink *) expr;
1019 :
1020 2579 : if (sublink->subLinkType == EXPR_SUBLINK ||
1021 822 : sublink->subLinkType == ARRAY_SUBLINK)
1022 1373 : {
1023 : /* get the collation of subselect's first target column */
1024 1373 : Query *qtree = (Query *) sublink->subselect;
1025 : TargetEntry *tent;
1026 :
1027 1373 : if (!qtree || !IsA(qtree, Query))
1028 0 : elog(ERROR, "cannot set collation for untransformed sublink");
1029 1373 : tent = linitial_node(TargetEntry, qtree->targetList);
1030 1373 : Assert(!tent->resjunk);
1031 1373 : Assert(collation == exprCollation((Node *) tent->expr));
1032 : }
1033 : else
1034 : {
1035 : /* otherwise, result is RECORD or BOOLEAN */
1036 384 : Assert(!OidIsValid(collation));
1037 : }
1038 : }
1039 : #endif /* USE_ASSERT_CHECKING */
1040 1757 : break;
1041 : case T_FieldSelect:
1042 0 : ((FieldSelect *) expr)->resultcollid = collation;
1043 0 : break;
1044 : case T_FieldStore:
1045 45 : Assert(!OidIsValid(collation)); /* result is always composite */
1046 45 : break;
1047 : case T_RelabelType:
1048 3612 : ((RelabelType *) expr)->resultcollid = collation;
1049 3612 : break;
1050 : case T_CoerceViaIO:
1051 751 : ((CoerceViaIO *) expr)->resultcollid = collation;
1052 751 : break;
1053 : case T_ArrayCoerceExpr:
1054 51 : ((ArrayCoerceExpr *) expr)->resultcollid = collation;
1055 51 : break;
1056 : case T_ConvertRowtypeExpr:
1057 6 : Assert(!OidIsValid(collation)); /* result is always composite */
1058 6 : break;
1059 : case T_CaseExpr:
1060 1046 : ((CaseExpr *) expr)->casecollid = collation;
1061 1046 : break;
1062 : case T_ArrayExpr:
1063 861 : ((ArrayExpr *) expr)->array_collid = collation;
1064 861 : break;
1065 : case T_RowExpr:
1066 0 : Assert(!OidIsValid(collation)); /* result is always composite */
1067 0 : break;
1068 : case T_RowCompareExpr:
1069 0 : Assert(!OidIsValid(collation)); /* result is always boolean */
1070 0 : break;
1071 : case T_CoalesceExpr:
1072 169 : ((CoalesceExpr *) expr)->coalescecollid = collation;
1073 169 : break;
1074 : case T_MinMaxExpr:
1075 15 : ((MinMaxExpr *) expr)->minmaxcollid = collation;
1076 15 : break;
1077 : case T_SQLValueFunction:
1078 125 : Assert(!OidIsValid(collation)); /* no collatable results */
1079 125 : break;
1080 : case T_XmlExpr:
1081 26 : Assert((((XmlExpr *) expr)->op == IS_XMLSERIALIZE) ?
1082 : (collation == DEFAULT_COLLATION_OID) :
1083 : (collation == InvalidOid));
1084 26 : break;
1085 : case T_NullTest:
1086 485 : Assert(!OidIsValid(collation)); /* result is always boolean */
1087 485 : break;
1088 : case T_BooleanTest:
1089 18 : Assert(!OidIsValid(collation)); /* result is always boolean */
1090 18 : break;
1091 : case T_CoerceToDomain:
1092 1154 : ((CoerceToDomain *) expr)->resultcollid = collation;
1093 1154 : break;
1094 : case T_CoerceToDomainValue:
1095 0 : ((CoerceToDomainValue *) expr)->collation = collation;
1096 0 : break;
1097 : case T_SetToDefault:
1098 0 : ((SetToDefault *) expr)->collation = collation;
1099 0 : break;
1100 : case T_CurrentOfExpr:
1101 0 : Assert(!OidIsValid(collation)); /* result is always boolean */
1102 0 : break;
1103 : case T_NextValueExpr:
1104 0 : Assert(!OidIsValid(collation)); /* result is always an integer
1105 : * type */
1106 0 : break;
1107 : default:
1108 0 : elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
1109 : break;
1110 : }
1111 58027 : }
1112 :
1113 : /*
1114 : * exprSetInputCollation -
1115 : * Assign input-collation information to an expression tree node.
1116 : *
1117 : * This is a no-op for node types that don't store their input collation.
1118 : * Note we omit RowCompareExpr, which needs special treatment since it
1119 : * contains multiple input collation OIDs.
1120 : */
1121 : void
1122 56873 : exprSetInputCollation(Node *expr, Oid inputcollation)
1123 : {
1124 56873 : switch (nodeTag(expr))
1125 : {
1126 : case T_Aggref:
1127 2545 : ((Aggref *) expr)->inputcollid = inputcollation;
1128 2545 : break;
1129 : case T_WindowFunc:
1130 168 : ((WindowFunc *) expr)->inputcollid = inputcollation;
1131 168 : break;
1132 : case T_FuncExpr:
1133 19521 : ((FuncExpr *) expr)->inputcollid = inputcollation;
1134 19521 : break;
1135 : case T_OpExpr:
1136 19601 : ((OpExpr *) expr)->inputcollid = inputcollation;
1137 19601 : break;
1138 : case T_DistinctExpr:
1139 33 : ((DistinctExpr *) expr)->inputcollid = inputcollation;
1140 33 : break;
1141 : case T_NullIfExpr:
1142 11 : ((NullIfExpr *) expr)->inputcollid = inputcollation;
1143 11 : break;
1144 : case T_ScalarArrayOpExpr:
1145 510 : ((ScalarArrayOpExpr *) expr)->inputcollid = inputcollation;
1146 510 : break;
1147 : case T_MinMaxExpr:
1148 15 : ((MinMaxExpr *) expr)->inputcollid = inputcollation;
1149 15 : break;
1150 : default:
1151 14469 : break;
1152 : }
1153 56873 : }
1154 :
1155 :
1156 : /*
1157 : * exprLocation -
1158 : * returns the parse location of an expression tree, for error reports
1159 : *
1160 : * -1 is returned if the location can't be determined.
1161 : *
1162 : * For expressions larger than a single token, the intent here is to
1163 : * return the location of the expression's leftmost token, not necessarily
1164 : * the topmost Node's location field. For example, an OpExpr's location
1165 : * field will point at the operator name, but if it is not a prefix operator
1166 : * then we should return the location of the left-hand operand instead.
1167 : * The reason is that we want to reference the entire expression not just
1168 : * that operator, and pointing to its start seems to be the most natural way.
1169 : *
1170 : * The location is not perfect --- for example, since the grammar doesn't
1171 : * explicitly represent parentheses in the parsetree, given something that
1172 : * had been written "(a + b) * c" we are going to point at "a" not "(".
1173 : * But it should be plenty good enough for error reporting purposes.
1174 : *
1175 : * You might think that this code is overly general, for instance why check
1176 : * the operands of a FuncExpr node, when the function name can be expected
1177 : * to be to the left of them? There are a couple of reasons. The grammar
1178 : * sometimes builds expressions that aren't quite what the user wrote;
1179 : * for instance x IS NOT BETWEEN ... becomes a NOT-expression whose keyword
1180 : * pointer is to the right of its leftmost argument. Also, nodes that were
1181 : * inserted implicitly by parse analysis (such as FuncExprs for implicit
1182 : * coercions) will have location -1, and so we can have odd combinations of
1183 : * known and unknown locations in a tree.
1184 : */
1185 : int
1186 131922 : exprLocation(const Node *expr)
1187 : {
1188 : int loc;
1189 :
1190 131922 : if (expr == NULL)
1191 188 : return -1;
1192 131734 : switch (nodeTag(expr))
1193 : {
1194 : case T_RangeVar:
1195 5 : loc = ((const RangeVar *) expr)->location;
1196 5 : break;
1197 : case T_TableFunc:
1198 0 : loc = ((const TableFunc *) expr)->location;
1199 0 : break;
1200 : case T_Var:
1201 66816 : loc = ((const Var *) expr)->location;
1202 66816 : break;
1203 : case T_Const:
1204 45713 : loc = ((const Const *) expr)->location;
1205 45713 : break;
1206 : case T_Param:
1207 4366 : loc = ((const Param *) expr)->location;
1208 4366 : break;
1209 : case T_Aggref:
1210 : /* function name should always be the first thing */
1211 237 : loc = ((const Aggref *) expr)->location;
1212 237 : break;
1213 : case T_GroupingFunc:
1214 5 : loc = ((const GroupingFunc *) expr)->location;
1215 5 : break;
1216 : case T_WindowFunc:
1217 : /* function name should always be the first thing */
1218 2 : loc = ((const WindowFunc *) expr)->location;
1219 2 : break;
1220 : case T_ArrayRef:
1221 : /* just use array argument's location */
1222 30 : loc = exprLocation((Node *) ((const ArrayRef *) expr)->refexpr);
1223 30 : break;
1224 : case T_FuncExpr:
1225 : {
1226 2791 : const FuncExpr *fexpr = (const FuncExpr *) expr;
1227 :
1228 : /* consider both function name and leftmost arg */
1229 2791 : loc = leftmostLoc(fexpr->location,
1230 2791 : exprLocation((Node *) fexpr->args));
1231 : }
1232 2791 : break;
1233 : case T_NamedArgExpr:
1234 : {
1235 1 : const NamedArgExpr *na = (const NamedArgExpr *) expr;
1236 :
1237 : /* consider both argument name and value */
1238 1 : loc = leftmostLoc(na->location,
1239 1 : exprLocation((Node *) na->arg));
1240 : }
1241 1 : break;
1242 : case T_OpExpr:
1243 : case T_DistinctExpr: /* struct-equivalent to OpExpr */
1244 : case T_NullIfExpr: /* struct-equivalent to OpExpr */
1245 : {
1246 629 : const OpExpr *opexpr = (const OpExpr *) expr;
1247 :
1248 : /* consider both operator name and leftmost arg */
1249 629 : loc = leftmostLoc(opexpr->location,
1250 629 : exprLocation((Node *) opexpr->args));
1251 : }
1252 629 : break;
1253 : case T_ScalarArrayOpExpr:
1254 : {
1255 0 : const ScalarArrayOpExpr *saopexpr = (const ScalarArrayOpExpr *) expr;
1256 :
1257 : /* consider both operator name and leftmost arg */
1258 0 : loc = leftmostLoc(saopexpr->location,
1259 0 : exprLocation((Node *) saopexpr->args));
1260 : }
1261 0 : break;
1262 : case T_BoolExpr:
1263 : {
1264 0 : const BoolExpr *bexpr = (const BoolExpr *) expr;
1265 :
1266 : /*
1267 : * Same as above, to handle either NOT or AND/OR. We can't
1268 : * special-case NOT because of the way that it's used for
1269 : * things like IS NOT BETWEEN.
1270 : */
1271 0 : loc = leftmostLoc(bexpr->location,
1272 0 : exprLocation((Node *) bexpr->args));
1273 : }
1274 0 : break;
1275 : case T_SubLink:
1276 : {
1277 26 : const SubLink *sublink = (const SubLink *) expr;
1278 :
1279 : /* check the testexpr, if any, and the operator/keyword */
1280 26 : loc = leftmostLoc(exprLocation(sublink->testexpr),
1281 : sublink->location);
1282 : }
1283 26 : break;
1284 : case T_FieldSelect:
1285 : /* just use argument's location */
1286 138 : loc = exprLocation((Node *) ((const FieldSelect *) expr)->arg);
1287 138 : break;
1288 : case T_FieldStore:
1289 : /* just use argument's location */
1290 0 : loc = exprLocation((Node *) ((const FieldStore *) expr)->arg);
1291 0 : break;
1292 : case T_RelabelType:
1293 : {
1294 507 : const RelabelType *rexpr = (const RelabelType *) expr;
1295 :
1296 : /* Much as above */
1297 507 : loc = leftmostLoc(rexpr->location,
1298 507 : exprLocation((Node *) rexpr->arg));
1299 : }
1300 507 : break;
1301 : case T_CoerceViaIO:
1302 : {
1303 722 : const CoerceViaIO *cexpr = (const CoerceViaIO *) expr;
1304 :
1305 : /* Much as above */
1306 722 : loc = leftmostLoc(cexpr->location,
1307 722 : exprLocation((Node *) cexpr->arg));
1308 : }
1309 722 : break;
1310 : case T_ArrayCoerceExpr:
1311 : {
1312 0 : const ArrayCoerceExpr *cexpr = (const ArrayCoerceExpr *) expr;
1313 :
1314 : /* Much as above */
1315 0 : loc = leftmostLoc(cexpr->location,
1316 0 : exprLocation((Node *) cexpr->arg));
1317 : }
1318 0 : break;
1319 : case T_ConvertRowtypeExpr:
1320 : {
1321 1 : const ConvertRowtypeExpr *cexpr = (const ConvertRowtypeExpr *) expr;
1322 :
1323 : /* Much as above */
1324 1 : loc = leftmostLoc(cexpr->location,
1325 1 : exprLocation((Node *) cexpr->arg));
1326 : }
1327 1 : break;
1328 : case T_CollateExpr:
1329 : /* just use argument's location */
1330 2 : loc = exprLocation((Node *) ((const CollateExpr *) expr)->arg);
1331 2 : break;
1332 : case T_CaseExpr:
1333 : /* CASE keyword should always be the first thing */
1334 29 : loc = ((const CaseExpr *) expr)->location;
1335 29 : break;
1336 : case T_CaseWhen:
1337 : /* WHEN keyword should always be the first thing */
1338 0 : loc = ((const CaseWhen *) expr)->location;
1339 0 : break;
1340 : case T_ArrayExpr:
1341 : /* the location points at ARRAY or [, which must be leftmost */
1342 21 : loc = ((const ArrayExpr *) expr)->location;
1343 21 : break;
1344 : case T_RowExpr:
1345 : /* the location points at ROW or (, which must be leftmost */
1346 8 : loc = ((const RowExpr *) expr)->location;
1347 8 : break;
1348 : case T_RowCompareExpr:
1349 : /* just use leftmost argument's location */
1350 0 : loc = exprLocation((Node *) ((const RowCompareExpr *) expr)->largs);
1351 0 : break;
1352 : case T_CoalesceExpr:
1353 : /* COALESCE keyword should always be the first thing */
1354 29 : loc = ((const CoalesceExpr *) expr)->location;
1355 29 : break;
1356 : case T_MinMaxExpr:
1357 : /* GREATEST/LEAST keyword should always be the first thing */
1358 3 : loc = ((const MinMaxExpr *) expr)->location;
1359 3 : break;
1360 : case T_SQLValueFunction:
1361 : /* function keyword should always be the first thing */
1362 14 : loc = ((const SQLValueFunction *) expr)->location;
1363 14 : break;
1364 : case T_XmlExpr:
1365 : {
1366 1 : const XmlExpr *xexpr = (const XmlExpr *) expr;
1367 :
1368 : /* consider both function name and leftmost arg */
1369 1 : loc = leftmostLoc(xexpr->location,
1370 1 : exprLocation((Node *) xexpr->args));
1371 : }
1372 1 : break;
1373 : case T_NullTest:
1374 : {
1375 12 : const NullTest *nexpr = (const NullTest *) expr;
1376 :
1377 : /* Much as above */
1378 12 : loc = leftmostLoc(nexpr->location,
1379 12 : exprLocation((Node *) nexpr->arg));
1380 : }
1381 12 : break;
1382 : case T_BooleanTest:
1383 : {
1384 0 : const BooleanTest *bexpr = (const BooleanTest *) expr;
1385 :
1386 : /* Much as above */
1387 0 : loc = leftmostLoc(bexpr->location,
1388 0 : exprLocation((Node *) bexpr->arg));
1389 : }
1390 0 : break;
1391 : case T_CoerceToDomain:
1392 : {
1393 83 : const CoerceToDomain *cexpr = (const CoerceToDomain *) expr;
1394 :
1395 : /* Much as above */
1396 83 : loc = leftmostLoc(cexpr->location,
1397 83 : exprLocation((Node *) cexpr->arg));
1398 : }
1399 83 : break;
1400 : case T_CoerceToDomainValue:
1401 54 : loc = ((const CoerceToDomainValue *) expr)->location;
1402 54 : break;
1403 : case T_SetToDefault:
1404 390 : loc = ((const SetToDefault *) expr)->location;
1405 390 : break;
1406 : case T_TargetEntry:
1407 : /* just use argument's location */
1408 0 : loc = exprLocation((Node *) ((const TargetEntry *) expr)->expr);
1409 0 : break;
1410 : case T_IntoClause:
1411 : /* use the contained RangeVar's location --- close enough */
1412 3 : loc = exprLocation((Node *) ((const IntoClause *) expr)->rel);
1413 3 : break;
1414 : case T_List:
1415 : {
1416 : /* report location of first list member that has a location */
1417 : ListCell *lc;
1418 :
1419 3385 : loc = -1; /* just to suppress compiler warning */
1420 3388 : foreach(lc, (const List *) expr)
1421 : {
1422 3385 : loc = exprLocation((Node *) lfirst(lc));
1423 3385 : if (loc >= 0)
1424 3382 : break;
1425 : }
1426 : }
1427 3385 : break;
1428 : case T_A_Expr:
1429 : {
1430 85 : const A_Expr *aexpr = (const A_Expr *) expr;
1431 :
1432 : /* use leftmost of operator or left operand (if any) */
1433 : /* we assume right operand can't be to left of operator */
1434 85 : loc = leftmostLoc(aexpr->location,
1435 85 : exprLocation(aexpr->lexpr));
1436 : }
1437 85 : break;
1438 : case T_ColumnRef:
1439 2405 : loc = ((const ColumnRef *) expr)->location;
1440 2405 : break;
1441 : case T_ParamRef:
1442 0 : loc = ((const ParamRef *) expr)->location;
1443 0 : break;
1444 : case T_A_Const:
1445 1893 : loc = ((const A_Const *) expr)->location;
1446 1893 : break;
1447 : case T_FuncCall:
1448 : {
1449 39 : const FuncCall *fc = (const FuncCall *) expr;
1450 :
1451 : /* consider both function name and leftmost arg */
1452 : /* (we assume any ORDER BY nodes must be to right of name) */
1453 39 : loc = leftmostLoc(fc->location,
1454 39 : exprLocation((Node *) fc->args));
1455 : }
1456 39 : break;
1457 : case T_A_ArrayExpr:
1458 : /* the location points at ARRAY or [, which must be leftmost */
1459 2 : loc = ((const A_ArrayExpr *) expr)->location;
1460 2 : break;
1461 : case T_ResTarget:
1462 : /* we need not examine the contained expression (if any) */
1463 2 : loc = ((const ResTarget *) expr)->location;
1464 2 : break;
1465 : case T_MultiAssignRef:
1466 0 : loc = exprLocation(((const MultiAssignRef *) expr)->source);
1467 0 : break;
1468 : case T_TypeCast:
1469 : {
1470 361 : const TypeCast *tc = (const TypeCast *) expr;
1471 :
1472 : /*
1473 : * This could represent CAST(), ::, or TypeName 'literal', so
1474 : * any of the components might be leftmost.
1475 : */
1476 361 : loc = exprLocation(tc->arg);
1477 361 : loc = leftmostLoc(loc, tc->typeName->location);
1478 361 : loc = leftmostLoc(loc, tc->location);
1479 : }
1480 361 : break;
1481 : case T_CollateClause:
1482 : /* just use argument's location */
1483 9 : loc = exprLocation(((const CollateClause *) expr)->arg);
1484 9 : break;
1485 : case T_SortBy:
1486 : /* just use argument's location (ignore operator, if any) */
1487 1 : loc = exprLocation(((const SortBy *) expr)->node);
1488 1 : break;
1489 : case T_WindowDef:
1490 0 : loc = ((const WindowDef *) expr)->location;
1491 0 : break;
1492 : case T_RangeTableSample:
1493 0 : loc = ((const RangeTableSample *) expr)->location;
1494 0 : break;
1495 : case T_TypeName:
1496 0 : loc = ((const TypeName *) expr)->location;
1497 0 : break;
1498 : case T_ColumnDef:
1499 0 : loc = ((const ColumnDef *) expr)->location;
1500 0 : break;
1501 : case T_Constraint:
1502 0 : loc = ((const Constraint *) expr)->location;
1503 0 : break;
1504 : case T_FunctionParameter:
1505 : /* just use typename's location */
1506 0 : loc = exprLocation((Node *) ((const FunctionParameter *) expr)->argType);
1507 0 : break;
1508 : case T_XmlSerialize:
1509 : /* XMLSERIALIZE keyword should always be the first thing */
1510 0 : loc = ((const XmlSerialize *) expr)->location;
1511 0 : break;
1512 : case T_GroupingSet:
1513 3 : loc = ((const GroupingSet *) expr)->location;
1514 3 : break;
1515 : case T_WithClause:
1516 0 : loc = ((const WithClause *) expr)->location;
1517 0 : break;
1518 : case T_InferClause:
1519 0 : loc = ((const InferClause *) expr)->location;
1520 0 : break;
1521 : case T_OnConflictClause:
1522 1 : loc = ((const OnConflictClause *) expr)->location;
1523 1 : break;
1524 : case T_CommonTableExpr:
1525 0 : loc = ((const CommonTableExpr *) expr)->location;
1526 0 : break;
1527 : case T_PlaceHolderVar:
1528 : /* just use argument's location */
1529 0 : loc = exprLocation((Node *) ((const PlaceHolderVar *) expr)->phexpr);
1530 0 : break;
1531 : case T_InferenceElem:
1532 : /* just use nested expr's location */
1533 0 : loc = exprLocation((Node *) ((const InferenceElem *) expr)->expr);
1534 0 : break;
1535 : case T_PartitionElem:
1536 0 : loc = ((const PartitionElem *) expr)->location;
1537 0 : break;
1538 : case T_PartitionSpec:
1539 0 : loc = ((const PartitionSpec *) expr)->location;
1540 0 : break;
1541 : case T_PartitionBoundSpec:
1542 3 : loc = ((const PartitionBoundSpec *) expr)->location;
1543 3 : break;
1544 : case T_PartitionRangeDatum:
1545 0 : loc = ((const PartitionRangeDatum *) expr)->location;
1546 0 : break;
1547 : default:
1548 : /* for any other node type it's just unknown... */
1549 907 : loc = -1;
1550 907 : break;
1551 : }
1552 131734 : return loc;
1553 : }
1554 :
1555 : /*
1556 : * leftmostLoc - support for exprLocation
1557 : *
1558 : * Take the minimum of two parse location values, but ignore unknowns
1559 : */
1560 : static int
1561 5619 : leftmostLoc(int loc1, int loc2)
1562 : {
1563 5619 : if (loc1 < 0)
1564 478 : return loc2;
1565 5141 : else if (loc2 < 0)
1566 163 : return loc1;
1567 : else
1568 4978 : return Min(loc1, loc2);
1569 : }
1570 :
1571 :
1572 : /*
1573 : * fix_opfuncids
1574 : * Calculate opfuncid field from opno for each OpExpr node in given tree.
1575 : * The given tree can be anything expression_tree_walker handles.
1576 : *
1577 : * The argument is modified in-place. (This is OK since we'd want the
1578 : * same change for any node, even if it gets visited more than once due to
1579 : * shared structure.)
1580 : */
1581 : void
1582 10691 : fix_opfuncids(Node *node)
1583 : {
1584 : /* This tree walk requires no special setup, so away we go... */
1585 10691 : fix_opfuncids_walker(node, NULL);
1586 10691 : }
1587 :
1588 : static bool
1589 31361 : fix_opfuncids_walker(Node *node, void *context)
1590 : {
1591 31361 : if (node == NULL)
1592 1527 : return false;
1593 29834 : if (IsA(node, OpExpr))
1594 1607 : set_opfuncid((OpExpr *) node);
1595 28227 : else if (IsA(node, DistinctExpr))
1596 1 : set_opfuncid((OpExpr *) node); /* rely on struct equivalence */
1597 28226 : else if (IsA(node, NullIfExpr))
1598 0 : set_opfuncid((OpExpr *) node); /* rely on struct equivalence */
1599 28226 : else if (IsA(node, ScalarArrayOpExpr))
1600 99 : set_sa_opfuncid((ScalarArrayOpExpr *) node);
1601 29834 : return expression_tree_walker(node, fix_opfuncids_walker, context);
1602 : }
1603 :
1604 : /*
1605 : * set_opfuncid
1606 : * Set the opfuncid (procedure OID) in an OpExpr node,
1607 : * if it hasn't been set already.
1608 : *
1609 : * Because of struct equivalence, this can also be used for
1610 : * DistinctExpr and NullIfExpr nodes.
1611 : */
1612 : void
1613 137987 : set_opfuncid(OpExpr *opexpr)
1614 : {
1615 137987 : if (opexpr->opfuncid == InvalidOid)
1616 8076 : opexpr->opfuncid = get_opcode(opexpr->opno);
1617 137987 : }
1618 :
1619 : /*
1620 : * set_sa_opfuncid
1621 : * As above, for ScalarArrayOpExpr nodes.
1622 : */
1623 : void
1624 3755 : set_sa_opfuncid(ScalarArrayOpExpr *opexpr)
1625 : {
1626 3755 : if (opexpr->opfuncid == InvalidOid)
1627 6 : opexpr->opfuncid = get_opcode(opexpr->opno);
1628 3755 : }
1629 :
1630 :
1631 : /*
1632 : * check_functions_in_node -
1633 : * apply checker() to each function OID contained in given expression node
1634 : *
1635 : * Returns TRUE if the checker() function does; for nodes representing more
1636 : * than one function call, returns TRUE if the checker() function does so
1637 : * for any of those functions. Returns FALSE if node does not invoke any
1638 : * SQL-visible function. Caller must not pass node == NULL.
1639 : *
1640 : * This function examines only the given node; it does not recurse into any
1641 : * sub-expressions. Callers typically prefer to keep control of the recursion
1642 : * for themselves, in case additional checks should be made, or because they
1643 : * have special rules about which parts of the tree need to be visited.
1644 : *
1645 : * Note: we ignore MinMaxExpr, SQLValueFunction, XmlExpr, CoerceToDomain,
1646 : * and NextValueExpr nodes, because they do not contain SQL function OIDs.
1647 : * However, they can invoke SQL-visible functions, so callers should take
1648 : * thought about how to treat them.
1649 : */
1650 : bool
1651 653592 : check_functions_in_node(Node *node, check_function_callback checker,
1652 : void *context)
1653 : {
1654 653592 : switch (nodeTag(node))
1655 : {
1656 : case T_Aggref:
1657 : {
1658 5668 : Aggref *expr = (Aggref *) node;
1659 :
1660 5668 : if (checker(expr->aggfnoid, context))
1661 65 : return true;
1662 : }
1663 5603 : break;
1664 : case T_WindowFunc:
1665 : {
1666 308 : WindowFunc *expr = (WindowFunc *) node;
1667 :
1668 308 : if (checker(expr->winfnoid, context))
1669 10 : return true;
1670 : }
1671 298 : break;
1672 : case T_FuncExpr:
1673 : {
1674 26745 : FuncExpr *expr = (FuncExpr *) node;
1675 :
1676 26745 : if (checker(expr->funcid, context))
1677 4387 : return true;
1678 : }
1679 22358 : break;
1680 : case T_OpExpr:
1681 : case T_DistinctExpr: /* struct-equivalent to OpExpr */
1682 : case T_NullIfExpr: /* struct-equivalent to OpExpr */
1683 : {
1684 53441 : OpExpr *expr = (OpExpr *) node;
1685 :
1686 : /* Set opfuncid if it wasn't set already */
1687 53441 : set_opfuncid(expr);
1688 53441 : if (checker(expr->opfuncid, context))
1689 40 : return true;
1690 : }
1691 53401 : break;
1692 : case T_ScalarArrayOpExpr:
1693 : {
1694 1580 : ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
1695 :
1696 1580 : set_sa_opfuncid(expr);
1697 1580 : if (checker(expr->opfuncid, context))
1698 0 : return true;
1699 : }
1700 1580 : break;
1701 : case T_CoerceViaIO:
1702 : {
1703 1353 : CoerceViaIO *expr = (CoerceViaIO *) node;
1704 : Oid iofunc;
1705 : Oid typioparam;
1706 : bool typisvarlena;
1707 :
1708 : /* check the result type's input function */
1709 1353 : getTypeInputInfo(expr->resulttype,
1710 : &iofunc, &typioparam);
1711 1353 : if (checker(iofunc, context))
1712 4 : return true;
1713 : /* check the input type's output function */
1714 1351 : getTypeOutputInfo(exprType((Node *) expr->arg),
1715 : &iofunc, &typisvarlena);
1716 1351 : if (checker(iofunc, context))
1717 0 : return true;
1718 : }
1719 1351 : break;
1720 : case T_ArrayCoerceExpr:
1721 : {
1722 42 : ArrayCoerceExpr *expr = (ArrayCoerceExpr *) node;
1723 :
1724 62 : if (OidIsValid(expr->elemfuncid) &&
1725 20 : checker(expr->elemfuncid, context))
1726 0 : return true;
1727 : }
1728 42 : break;
1729 : case T_RowCompareExpr:
1730 : {
1731 21 : RowCompareExpr *rcexpr = (RowCompareExpr *) node;
1732 : ListCell *opid;
1733 :
1734 69 : foreach(opid, rcexpr->opnos)
1735 : {
1736 48 : Oid opfuncid = get_opcode(lfirst_oid(opid));
1737 :
1738 48 : if (checker(opfuncid, context))
1739 0 : return true;
1740 : }
1741 : }
1742 21 : break;
1743 : default:
1744 564434 : break;
1745 : }
1746 649088 : return false;
1747 : }
1748 :
1749 :
1750 : /*
1751 : * Standard expression-tree walking support
1752 : *
1753 : * We used to have near-duplicate code in many different routines that
1754 : * understood how to recurse through an expression node tree. That was
1755 : * a pain to maintain, and we frequently had bugs due to some particular
1756 : * routine neglecting to support a particular node type. In most cases,
1757 : * these routines only actually care about certain node types, and don't
1758 : * care about other types except insofar as they have to recurse through
1759 : * non-primitive node types. Therefore, we now provide generic tree-walking
1760 : * logic to consolidate the redundant "boilerplate" code. There are
1761 : * two versions: expression_tree_walker() and expression_tree_mutator().
1762 : */
1763 :
1764 : /*
1765 : * expression_tree_walker() is designed to support routines that traverse
1766 : * a tree in a read-only fashion (although it will also work for routines
1767 : * that modify nodes in-place but never add/delete/replace nodes).
1768 : * A walker routine should look like this:
1769 : *
1770 : * bool my_walker (Node *node, my_struct *context)
1771 : * {
1772 : * if (node == NULL)
1773 : * return false;
1774 : * // check for nodes that special work is required for, eg:
1775 : * if (IsA(node, Var))
1776 : * {
1777 : * ... do special actions for Var nodes
1778 : * }
1779 : * else if (IsA(node, ...))
1780 : * {
1781 : * ... do special actions for other node types
1782 : * }
1783 : * // for any node type not specially processed, do:
1784 : * return expression_tree_walker(node, my_walker, (void *) context);
1785 : * }
1786 : *
1787 : * The "context" argument points to a struct that holds whatever context
1788 : * information the walker routine needs --- it can be used to return data
1789 : * gathered by the walker, too. This argument is not touched by
1790 : * expression_tree_walker, but it is passed down to recursive sub-invocations
1791 : * of my_walker. The tree walk is started from a setup routine that
1792 : * fills in the appropriate context struct, calls my_walker with the top-level
1793 : * node of the tree, and then examines the results.
1794 : *
1795 : * The walker routine should return "false" to continue the tree walk, or
1796 : * "true" to abort the walk and immediately return "true" to the top-level
1797 : * caller. This can be used to short-circuit the traversal if the walker
1798 : * has found what it came for. "false" is returned to the top-level caller
1799 : * iff no invocation of the walker returned "true".
1800 : *
1801 : * The node types handled by expression_tree_walker include all those
1802 : * normally found in target lists and qualifier clauses during the planning
1803 : * stage. In particular, it handles List nodes since a cnf-ified qual clause
1804 : * will have List structure at the top level, and it handles TargetEntry nodes
1805 : * so that a scan of a target list can be handled without additional code.
1806 : * Also, RangeTblRef, FromExpr, JoinExpr, and SetOperationStmt nodes are
1807 : * handled, so that query jointrees and setOperation trees can be processed
1808 : * without additional code.
1809 : *
1810 : * expression_tree_walker will handle SubLink nodes by recursing normally
1811 : * into the "testexpr" subtree (which is an expression belonging to the outer
1812 : * plan). It will also call the walker on the sub-Query node; however, when
1813 : * expression_tree_walker itself is called on a Query node, it does nothing
1814 : * and returns "false". The net effect is that unless the walker does
1815 : * something special at a Query node, sub-selects will not be visited during
1816 : * an expression tree walk. This is exactly the behavior wanted in many cases
1817 : * --- and for those walkers that do want to recurse into sub-selects, special
1818 : * behavior is typically needed anyway at the entry to a sub-select (such as
1819 : * incrementing a depth counter). A walker that wants to examine sub-selects
1820 : * should include code along the lines of:
1821 : *
1822 : * if (IsA(node, Query))
1823 : * {
1824 : * adjust context for subquery;
1825 : * result = query_tree_walker((Query *) node, my_walker, context,
1826 : * 0); // adjust flags as needed
1827 : * restore context if needed;
1828 : * return result;
1829 : * }
1830 : *
1831 : * query_tree_walker is a convenience routine (see below) that calls the
1832 : * walker on all the expression subtrees of the given Query node.
1833 : *
1834 : * expression_tree_walker will handle SubPlan nodes by recursing normally
1835 : * into the "testexpr" and the "args" list (which are expressions belonging to
1836 : * the outer plan). It will not touch the completed subplan, however. Since
1837 : * there is no link to the original Query, it is not possible to recurse into
1838 : * subselects of an already-planned expression tree. This is OK for current
1839 : * uses, but may need to be revisited in future.
1840 : */
1841 :
1842 : bool
1843 3203444 : expression_tree_walker(Node *node,
1844 : bool (*walker) (),
1845 : void *context)
1846 : {
1847 : ListCell *temp;
1848 :
1849 : /*
1850 : * The walker has already visited the current node, and so we need only
1851 : * recurse into any sub-nodes it has.
1852 : *
1853 : * We assume that the walker is not interested in List nodes per se, so
1854 : * when we expect a List we just recurse directly to self without
1855 : * bothering to call the walker.
1856 : */
1857 3203444 : if (node == NULL)
1858 69573 : return false;
1859 :
1860 : /* Guard against stack overflow due to overly complex expressions */
1861 3133871 : check_stack_depth();
1862 :
1863 3133871 : switch (nodeTag(node))
1864 : {
1865 : case T_Var:
1866 : case T_Const:
1867 : case T_Param:
1868 : case T_CaseTestExpr:
1869 : case T_SQLValueFunction:
1870 : case T_CoerceToDomainValue:
1871 : case T_SetToDefault:
1872 : case T_CurrentOfExpr:
1873 : case T_NextValueExpr:
1874 : case T_RangeTblRef:
1875 : case T_SortGroupClause:
1876 : /* primitive node types with no expression subnodes */
1877 1115807 : break;
1878 : case T_WithCheckOption:
1879 507 : return walker(((WithCheckOption *) node)->qual, context);
1880 : case T_Aggref:
1881 : {
1882 14676 : Aggref *expr = (Aggref *) node;
1883 :
1884 : /* recurse directly on List */
1885 14676 : if (expression_tree_walker((Node *) expr->aggdirectargs,
1886 : walker, context))
1887 0 : return true;
1888 14676 : if (expression_tree_walker((Node *) expr->args,
1889 : walker, context))
1890 1278 : return true;
1891 13398 : if (expression_tree_walker((Node *) expr->aggorder,
1892 : walker, context))
1893 0 : return true;
1894 13398 : if (expression_tree_walker((Node *) expr->aggdistinct,
1895 : walker, context))
1896 0 : return true;
1897 13398 : if (walker((Node *) expr->aggfilter, context))
1898 1 : return true;
1899 : }
1900 13397 : break;
1901 : case T_GroupingFunc:
1902 : {
1903 269 : GroupingFunc *grouping = (GroupingFunc *) node;
1904 :
1905 269 : if (expression_tree_walker((Node *) grouping->args,
1906 : walker, context))
1907 0 : return true;
1908 : }
1909 269 : break;
1910 : case T_WindowFunc:
1911 : {
1912 784 : WindowFunc *expr = (WindowFunc *) node;
1913 :
1914 : /* recurse directly on List */
1915 784 : if (expression_tree_walker((Node *) expr->args,
1916 : walker, context))
1917 29 : return true;
1918 755 : if (walker((Node *) expr->aggfilter, context))
1919 2 : return true;
1920 : }
1921 753 : break;
1922 : case T_ArrayRef:
1923 : {
1924 4328 : ArrayRef *aref = (ArrayRef *) node;
1925 :
1926 : /* recurse directly for upper/lower array index lists */
1927 4328 : if (expression_tree_walker((Node *) aref->refupperindexpr,
1928 : walker, context))
1929 3 : return true;
1930 4325 : if (expression_tree_walker((Node *) aref->reflowerindexpr,
1931 : walker, context))
1932 0 : return true;
1933 : /* walker must see the refexpr and refassgnexpr, however */
1934 4325 : if (walker(aref->refexpr, context))
1935 80 : return true;
1936 4245 : if (walker(aref->refassgnexpr, context))
1937 3 : return true;
1938 : }
1939 4242 : break;
1940 : case T_FuncExpr:
1941 : {
1942 148995 : FuncExpr *expr = (FuncExpr *) node;
1943 :
1944 148995 : if (expression_tree_walker((Node *) expr->args,
1945 : walker, context))
1946 3719 : return true;
1947 : }
1948 145276 : break;
1949 : case T_NamedArgExpr:
1950 180 : return walker(((NamedArgExpr *) node)->arg, context);
1951 : case T_OpExpr:
1952 : case T_DistinctExpr: /* struct-equivalent to OpExpr */
1953 : case T_NullIfExpr: /* struct-equivalent to OpExpr */
1954 : {
1955 274846 : OpExpr *expr = (OpExpr *) node;
1956 :
1957 274846 : if (expression_tree_walker((Node *) expr->args,
1958 : walker, context))
1959 3676 : return true;
1960 : }
1961 271160 : break;
1962 : case T_ScalarArrayOpExpr:
1963 : {
1964 10165 : ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
1965 :
1966 10165 : if (expression_tree_walker((Node *) expr->args,
1967 : walker, context))
1968 247 : return true;
1969 : }
1970 9918 : break;
1971 : case T_BoolExpr:
1972 : {
1973 37984 : BoolExpr *expr = (BoolExpr *) node;
1974 :
1975 37984 : if (expression_tree_walker((Node *) expr->args,
1976 : walker, context))
1977 432 : return true;
1978 : }
1979 37551 : break;
1980 : case T_SubLink:
1981 : {
1982 9298 : SubLink *sublink = (SubLink *) node;
1983 :
1984 9298 : if (walker(sublink->testexpr, context))
1985 0 : return true;
1986 :
1987 : /*
1988 : * Also invoke the walker on the sublink's Query node, so it
1989 : * can recurse into the sub-query if it wants to.
1990 : */
1991 9298 : return walker(sublink->subselect, context);
1992 : }
1993 : break;
1994 : case T_SubPlan:
1995 : {
1996 5231 : SubPlan *subplan = (SubPlan *) node;
1997 :
1998 : /* recurse into the testexpr, but not into the Plan */
1999 5231 : if (walker(subplan->testexpr, context))
2000 10 : return true;
2001 : /* also examine args list */
2002 5221 : if (expression_tree_walker((Node *) subplan->args,
2003 : walker, context))
2004 3 : return true;
2005 : }
2006 5218 : break;
2007 : case T_AlternativeSubPlan:
2008 480 : return walker(((AlternativeSubPlan *) node)->subplans, context);
2009 : case T_FieldSelect:
2010 3134 : return walker(((FieldSelect *) node)->arg, context);
2011 : case T_FieldStore:
2012 : {
2013 196 : FieldStore *fstore = (FieldStore *) node;
2014 :
2015 196 : if (walker(fstore->arg, context))
2016 0 : return true;
2017 196 : if (walker(fstore->newvals, context))
2018 1 : return true;
2019 : }
2020 195 : break;
2021 : case T_RelabelType:
2022 33624 : return walker(((RelabelType *) node)->arg, context);
2023 : case T_CoerceViaIO:
2024 6719 : return walker(((CoerceViaIO *) node)->arg, context);
2025 : case T_ArrayCoerceExpr:
2026 449 : return walker(((ArrayCoerceExpr *) node)->arg, context);
2027 : case T_ConvertRowtypeExpr:
2028 182 : return walker(((ConvertRowtypeExpr *) node)->arg, context);
2029 : case T_CollateExpr:
2030 106 : return walker(((CollateExpr *) node)->arg, context);
2031 : case T_CaseExpr:
2032 : {
2033 15607 : CaseExpr *caseexpr = (CaseExpr *) node;
2034 :
2035 15607 : if (walker(caseexpr->arg, context))
2036 11 : return true;
2037 : /* we assume walker doesn't care about CaseWhens, either */
2038 40231 : foreach(temp, caseexpr->args)
2039 : {
2040 24874 : CaseWhen *when = lfirst_node(CaseWhen, temp);
2041 :
2042 24874 : if (walker(when->expr, context))
2043 200 : return true;
2044 24674 : if (walker(when->result, context))
2045 39 : return true;
2046 : }
2047 15357 : if (walker(caseexpr->defresult, context))
2048 606 : return true;
2049 : }
2050 14751 : break;
2051 : case T_ArrayExpr:
2052 6676 : return walker(((ArrayExpr *) node)->elements, context);
2053 : case T_RowExpr:
2054 : /* Assume colnames isn't interesting */
2055 1516 : return walker(((RowExpr *) node)->args, context);
2056 : case T_RowCompareExpr:
2057 : {
2058 117 : RowCompareExpr *rcexpr = (RowCompareExpr *) node;
2059 :
2060 117 : if (walker(rcexpr->largs, context))
2061 0 : return true;
2062 117 : if (walker(rcexpr->rargs, context))
2063 0 : return true;
2064 : }
2065 117 : break;
2066 : case T_CoalesceExpr:
2067 3387 : return walker(((CoalesceExpr *) node)->args, context);
2068 : case T_MinMaxExpr:
2069 170 : return walker(((MinMaxExpr *) node)->args, context);
2070 : case T_XmlExpr:
2071 : {
2072 131 : XmlExpr *xexpr = (XmlExpr *) node;
2073 :
2074 131 : if (walker(xexpr->named_args, context))
2075 0 : return true;
2076 : /* we assume walker doesn't care about arg_names */
2077 131 : if (walker(xexpr->args, context))
2078 1 : return true;
2079 : }
2080 130 : break;
2081 : case T_NullTest:
2082 8454 : return walker(((NullTest *) node)->arg, context);
2083 : case T_BooleanTest:
2084 423 : return walker(((BooleanTest *) node)->arg, context);
2085 : case T_CoerceToDomain:
2086 26050 : return walker(((CoerceToDomain *) node)->arg, context);
2087 : case T_TargetEntry:
2088 492266 : return walker(((TargetEntry *) node)->expr, context);
2089 : case T_Query:
2090 : /* Do nothing with a sub-Query, per discussion above */
2091 3716 : break;
2092 : case T_WindowClause:
2093 : {
2094 4 : WindowClause *wc = (WindowClause *) node;
2095 :
2096 4 : if (walker(wc->partitionClause, context))
2097 0 : return true;
2098 4 : if (walker(wc->orderClause, context))
2099 0 : return true;
2100 4 : if (walker(wc->startOffset, context))
2101 1 : return true;
2102 3 : if (walker(wc->endOffset, context))
2103 0 : return true;
2104 : }
2105 3 : break;
2106 : case T_CommonTableExpr:
2107 : {
2108 141 : CommonTableExpr *cte = (CommonTableExpr *) node;
2109 :
2110 : /*
2111 : * Invoke the walker on the CTE's Query node, so it can
2112 : * recurse into the sub-query if it wants to.
2113 : */
2114 141 : return walker(cte->ctequery, context);
2115 : }
2116 : break;
2117 : case T_List:
2118 2582918 : foreach(temp, (List *) node)
2119 : {
2120 1800609 : if (walker((Node *) lfirst(temp), context))
2121 35541 : return true;
2122 : }
2123 782309 : break;
2124 : case T_FromExpr:
2125 : {
2126 70815 : FromExpr *from = (FromExpr *) node;
2127 :
2128 70815 : if (walker(from->fromlist, context))
2129 3345 : return true;
2130 67470 : if (walker(from->quals, context))
2131 246 : return true;
2132 : }
2133 67223 : break;
2134 : case T_OnConflictExpr:
2135 : {
2136 380 : OnConflictExpr *onconflict = (OnConflictExpr *) node;
2137 :
2138 380 : if (walker((Node *) onconflict->arbiterElems, context))
2139 0 : return true;
2140 380 : if (walker(onconflict->arbiterWhere, context))
2141 0 : return true;
2142 380 : if (walker(onconflict->onConflictSet, context))
2143 95 : return true;
2144 285 : if (walker(onconflict->onConflictWhere, context))
2145 0 : return true;
2146 285 : if (walker(onconflict->exclRelTlist, context))
2147 39 : return true;
2148 : }
2149 246 : break;
2150 : case T_JoinExpr:
2151 : {
2152 10404 : JoinExpr *join = (JoinExpr *) node;
2153 :
2154 10404 : if (walker(join->larg, context))
2155 602 : return true;
2156 9802 : if (walker(join->rarg, context))
2157 1287 : return true;
2158 8515 : if (walker(join->quals, context))
2159 3 : return true;
2160 :
2161 : /*
2162 : * alias clause, using list are deemed uninteresting.
2163 : */
2164 : }
2165 8512 : break;
2166 : case T_SetOperationStmt:
2167 : {
2168 952 : SetOperationStmt *setop = (SetOperationStmt *) node;
2169 :
2170 952 : if (walker(setop->larg, context))
2171 0 : return true;
2172 952 : if (walker(setop->rarg, context))
2173 0 : return true;
2174 :
2175 : /* groupClauses are deemed uninteresting */
2176 : }
2177 952 : break;
2178 : case T_PlaceHolderVar:
2179 667 : return walker(((PlaceHolderVar *) node)->phexpr, context);
2180 : case T_InferenceElem:
2181 436 : return walker(((InferenceElem *) node)->expr, context);
2182 : case T_AppendRelInfo:
2183 : {
2184 156 : AppendRelInfo *appinfo = (AppendRelInfo *) node;
2185 :
2186 156 : if (expression_tree_walker((Node *) appinfo->translated_vars,
2187 : walker, context))
2188 0 : return true;
2189 : }
2190 156 : break;
2191 : case T_PlaceHolderInfo:
2192 0 : return walker(((PlaceHolderInfo *) node)->ph_var, context);
2193 : case T_RangeTblFunction:
2194 5340 : return walker(((RangeTblFunction *) node)->funcexpr, context);
2195 : case T_TableSampleClause:
2196 : {
2197 88 : TableSampleClause *tsc = (TableSampleClause *) node;
2198 :
2199 88 : if (expression_tree_walker((Node *) tsc->args,
2200 : walker, context))
2201 0 : return true;
2202 88 : if (walker((Node *) tsc->repeatable, context))
2203 0 : return true;
2204 : }
2205 88 : break;
2206 : case T_TableFunc:
2207 : {
2208 126 : TableFunc *tf = (TableFunc *) node;
2209 :
2210 126 : if (walker(tf->ns_uris, context))
2211 0 : return true;
2212 126 : if (walker(tf->docexpr, context))
2213 0 : return true;
2214 126 : if (walker(tf->rowexpr, context))
2215 0 : return true;
2216 126 : if (walker(tf->colexprs, context))
2217 0 : return true;
2218 126 : if (walker(tf->coldefexprs, context))
2219 0 : return true;
2220 : }
2221 126 : break;
2222 : default:
2223 0 : elog(ERROR, "unrecognized node type: %d",
2224 : (int) nodeTag(node));
2225 : break;
2226 : }
2227 2482115 : return false;
2228 : }
2229 :
2230 : /*
2231 : * query_tree_walker --- initiate a walk of a Query's expressions
2232 : *
2233 : * This routine exists just to reduce the number of places that need to know
2234 : * where all the expression subtrees of a Query are. Note it can be used
2235 : * for starting a walk at top level of a Query regardless of whether the
2236 : * walker intends to descend into subqueries. It is also useful for
2237 : * descending into subqueries within a walker.
2238 : *
2239 : * Some callers want to suppress visitation of certain items in the sub-Query,
2240 : * typically because they need to process them specially, or don't actually
2241 : * want to recurse into subqueries. This is supported by the flags argument,
2242 : * which is the bitwise OR of flag values to suppress visitation of
2243 : * indicated items. (More flag bits may be added as needed.)
2244 : */
2245 : bool
2246 84955 : query_tree_walker(Query *query,
2247 : bool (*walker) (),
2248 : void *context,
2249 : int flags)
2250 : {
2251 84955 : Assert(query != NULL && IsA(query, Query));
2252 :
2253 84955 : if (walker((Node *) query->targetList, context))
2254 14503 : return true;
2255 70448 : if (walker((Node *) query->withCheckOptions, context))
2256 0 : return true;
2257 70448 : if (walker((Node *) query->onConflict, context))
2258 134 : return true;
2259 70314 : if (walker((Node *) query->returningList, context))
2260 10 : return true;
2261 70304 : if (walker((Node *) query->jointree, context))
2262 3528 : return true;
2263 66775 : if (walker(query->setOperations, context))
2264 0 : return true;
2265 66775 : if (walker(query->havingQual, context))
2266 0 : return true;
2267 66775 : if (walker(query->limitOffset, context))
2268 1 : return true;
2269 66774 : if (walker(query->limitCount, context))
2270 0 : return true;
2271 66774 : if (!(flags & QTW_IGNORE_CTE_SUBQUERIES))
2272 : {
2273 35427 : if (walker((Node *) query->cteList, context))
2274 9 : return true;
2275 : }
2276 66765 : if (!(flags & QTW_IGNORE_RANGE_TABLE))
2277 : {
2278 37638 : if (range_table_walker(query->rtable, walker, context, flags))
2279 484 : return true;
2280 : }
2281 66281 : return false;
2282 : }
2283 :
2284 : /*
2285 : * range_table_walker is just the part of query_tree_walker that scans
2286 : * a query's rangetable. This is split out since it can be useful on
2287 : * its own.
2288 : */
2289 : bool
2290 37707 : range_table_walker(List *rtable,
2291 : bool (*walker) (),
2292 : void *context,
2293 : int flags)
2294 : {
2295 : ListCell *rt;
2296 :
2297 100975 : foreach(rt, rtable)
2298 : {
2299 63752 : RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
2300 :
2301 : /* For historical reasons, visiting RTEs is not the default */
2302 63752 : if (flags & QTW_EXAMINE_RTES)
2303 6780 : if (walker(rte, context))
2304 0 : return true;
2305 :
2306 63752 : switch (rte->rtekind)
2307 : {
2308 : case RTE_RELATION:
2309 47576 : if (walker(rte->tablesample, context))
2310 0 : return true;
2311 47576 : break;
2312 : case RTE_CTE:
2313 : case RTE_NAMEDTUPLESTORE:
2314 : /* nothing to do */
2315 408 : break;
2316 : case RTE_SUBQUERY:
2317 5629 : if (!(flags & QTW_IGNORE_RT_SUBQUERIES))
2318 5556 : if (walker(rte->subquery, context))
2319 83 : return true;
2320 5546 : break;
2321 : case RTE_JOIN:
2322 6304 : if (!(flags & QTW_IGNORE_JOINALIASES))
2323 5969 : if (walker(rte->joinaliasvars, context))
2324 0 : return true;
2325 6304 : break;
2326 : case RTE_FUNCTION:
2327 2425 : if (walker(rte->functions, context))
2328 392 : return true;
2329 2033 : break;
2330 : case RTE_TABLEFUNC:
2331 38 : if (walker(rte->tablefunc, context))
2332 0 : return true;
2333 38 : break;
2334 : case RTE_VALUES:
2335 1372 : if (walker(rte->values_lists, context))
2336 9 : return true;
2337 1363 : break;
2338 : }
2339 :
2340 63268 : if (walker(rte->securityQuals, context))
2341 0 : return true;
2342 : }
2343 37223 : return false;
2344 : }
2345 :
2346 :
2347 : /*
2348 : * expression_tree_mutator() is designed to support routines that make a
2349 : * modified copy of an expression tree, with some nodes being added,
2350 : * removed, or replaced by new subtrees. The original tree is (normally)
2351 : * not changed. Each recursion level is responsible for returning a copy of
2352 : * (or appropriately modified substitute for) the subtree it is handed.
2353 : * A mutator routine should look like this:
2354 : *
2355 : * Node * my_mutator (Node *node, my_struct *context)
2356 : * {
2357 : * if (node == NULL)
2358 : * return NULL;
2359 : * // check for nodes that special work is required for, eg:
2360 : * if (IsA(node, Var))
2361 : * {
2362 : * ... create and return modified copy of Var node
2363 : * }
2364 : * else if (IsA(node, ...))
2365 : * {
2366 : * ... do special transformations of other node types
2367 : * }
2368 : * // for any node type not specially processed, do:
2369 : * return expression_tree_mutator(node, my_mutator, (void *) context);
2370 : * }
2371 : *
2372 : * The "context" argument points to a struct that holds whatever context
2373 : * information the mutator routine needs --- it can be used to return extra
2374 : * data gathered by the mutator, too. This argument is not touched by
2375 : * expression_tree_mutator, but it is passed down to recursive sub-invocations
2376 : * of my_mutator. The tree walk is started from a setup routine that
2377 : * fills in the appropriate context struct, calls my_mutator with the
2378 : * top-level node of the tree, and does any required post-processing.
2379 : *
2380 : * Each level of recursion must return an appropriately modified Node.
2381 : * If expression_tree_mutator() is called, it will make an exact copy
2382 : * of the given Node, but invoke my_mutator() to copy the sub-node(s)
2383 : * of that Node. In this way, my_mutator() has full control over the
2384 : * copying process but need not directly deal with expression trees
2385 : * that it has no interest in.
2386 : *
2387 : * Just as for expression_tree_walker, the node types handled by
2388 : * expression_tree_mutator include all those normally found in target lists
2389 : * and qualifier clauses during the planning stage.
2390 : *
2391 : * expression_tree_mutator will handle SubLink nodes by recursing normally
2392 : * into the "testexpr" subtree (which is an expression belonging to the outer
2393 : * plan). It will also call the mutator on the sub-Query node; however, when
2394 : * expression_tree_mutator itself is called on a Query node, it does nothing
2395 : * and returns the unmodified Query node. The net effect is that unless the
2396 : * mutator does something special at a Query node, sub-selects will not be
2397 : * visited or modified; the original sub-select will be linked to by the new
2398 : * SubLink node. Mutators that want to descend into sub-selects will usually
2399 : * do so by recognizing Query nodes and calling query_tree_mutator (below).
2400 : *
2401 : * expression_tree_mutator will handle a SubPlan node by recursing into the
2402 : * "testexpr" and the "args" list (which belong to the outer plan), but it
2403 : * will simply copy the link to the inner plan, since that's typically what
2404 : * expression tree mutators want. A mutator that wants to modify the subplan
2405 : * can force appropriate behavior by recognizing SubPlan expression nodes
2406 : * and doing the right thing.
2407 : */
2408 :
2409 : Node *
2410 620544 : expression_tree_mutator(Node *node,
2411 : Node *(*mutator) (),
2412 : void *context)
2413 : {
2414 : /*
2415 : * The mutator has already decided not to modify the current node, but we
2416 : * must call the mutator for any sub-nodes.
2417 : */
2418 :
2419 : #define FLATCOPY(newnode, node, nodetype) \
2420 : ( (newnode) = (nodetype *) palloc(sizeof(nodetype)), \
2421 : memcpy((newnode), (node), sizeof(nodetype)) )
2422 :
2423 : #define CHECKFLATCOPY(newnode, node, nodetype) \
2424 : ( AssertMacro(IsA((node), nodetype)), \
2425 : (newnode) = (nodetype *) palloc(sizeof(nodetype)), \
2426 : memcpy((newnode), (node), sizeof(nodetype)) )
2427 :
2428 : #define MUTATE(newfield, oldfield, fieldtype) \
2429 : ( (newfield) = (fieldtype) mutator((Node *) (oldfield), context) )
2430 :
2431 620544 : if (node == NULL)
2432 5138 : return NULL;
2433 :
2434 : /* Guard against stack overflow due to overly complex expressions */
2435 615406 : check_stack_depth();
2436 :
2437 615406 : switch (nodeTag(node))
2438 : {
2439 : /*
2440 : * Primitive node types with no expression subnodes. Var and
2441 : * Const are frequent enough to deserve special cases, the others
2442 : * we just use copyObject for.
2443 : */
2444 : case T_Var:
2445 : {
2446 106041 : Var *var = (Var *) node;
2447 : Var *newnode;
2448 :
2449 106041 : FLATCOPY(newnode, var, Var);
2450 106041 : return (Node *) newnode;
2451 : }
2452 : break;
2453 : case T_Const:
2454 : {
2455 99157 : Const *oldnode = (Const *) node;
2456 : Const *newnode;
2457 :
2458 99157 : FLATCOPY(newnode, oldnode, Const);
2459 : /* XXX we don't bother with datumCopy; should we? */
2460 99157 : return (Node *) newnode;
2461 : }
2462 : break;
2463 : case T_Param:
2464 : case T_CaseTestExpr:
2465 : case T_SQLValueFunction:
2466 : case T_CoerceToDomainValue:
2467 : case T_SetToDefault:
2468 : case T_CurrentOfExpr:
2469 : case T_NextValueExpr:
2470 : case T_RangeTblRef:
2471 : case T_SortGroupClause:
2472 4593 : return (Node *) copyObject(node);
2473 : case T_WithCheckOption:
2474 : {
2475 77 : WithCheckOption *wco = (WithCheckOption *) node;
2476 : WithCheckOption *newnode;
2477 :
2478 77 : FLATCOPY(newnode, wco, WithCheckOption);
2479 77 : MUTATE(newnode->qual, wco->qual, Node *);
2480 77 : return (Node *) newnode;
2481 : }
2482 : case T_Aggref:
2483 : {
2484 6095 : Aggref *aggref = (Aggref *) node;
2485 : Aggref *newnode;
2486 :
2487 6095 : FLATCOPY(newnode, aggref, Aggref);
2488 : /* assume mutation doesn't change types of arguments */
2489 6095 : newnode->aggargtypes = list_copy(aggref->aggargtypes);
2490 6095 : MUTATE(newnode->aggdirectargs, aggref->aggdirectargs, List *);
2491 6095 : MUTATE(newnode->args, aggref->args, List *);
2492 6095 : MUTATE(newnode->aggorder, aggref->aggorder, List *);
2493 6095 : MUTATE(newnode->aggdistinct, aggref->aggdistinct, List *);
2494 6095 : MUTATE(newnode->aggfilter, aggref->aggfilter, Expr *);
2495 6095 : return (Node *) newnode;
2496 : }
2497 : break;
2498 : case T_GroupingFunc:
2499 : {
2500 118 : GroupingFunc *grouping = (GroupingFunc *) node;
2501 : GroupingFunc *newnode;
2502 :
2503 118 : FLATCOPY(newnode, grouping, GroupingFunc);
2504 118 : MUTATE(newnode->args, grouping->args, List *);
2505 :
2506 : /*
2507 : * We assume here that mutating the arguments does not change
2508 : * the semantics, i.e. that the arguments are not mutated in a
2509 : * way that makes them semantically different from their
2510 : * previously matching expressions in the GROUP BY clause.
2511 : *
2512 : * If a mutator somehow wanted to do this, it would have to
2513 : * handle the refs and cols lists itself as appropriate.
2514 : */
2515 118 : newnode->refs = list_copy(grouping->refs);
2516 118 : newnode->cols = list_copy(grouping->cols);
2517 :
2518 118 : return (Node *) newnode;
2519 : }
2520 : break;
2521 : case T_WindowFunc:
2522 : {
2523 257 : WindowFunc *wfunc = (WindowFunc *) node;
2524 : WindowFunc *newnode;
2525 :
2526 257 : FLATCOPY(newnode, wfunc, WindowFunc);
2527 257 : MUTATE(newnode->args, wfunc->args, List *);
2528 257 : MUTATE(newnode->aggfilter, wfunc->aggfilter, Expr *);
2529 257 : return (Node *) newnode;
2530 : }
2531 : break;
2532 : case T_ArrayRef:
2533 : {
2534 651 : ArrayRef *arrayref = (ArrayRef *) node;
2535 : ArrayRef *newnode;
2536 :
2537 651 : FLATCOPY(newnode, arrayref, ArrayRef);
2538 651 : MUTATE(newnode->refupperindexpr, arrayref->refupperindexpr,
2539 : List *);
2540 651 : MUTATE(newnode->reflowerindexpr, arrayref->reflowerindexpr,
2541 : List *);
2542 651 : MUTATE(newnode->refexpr, arrayref->refexpr,
2543 : Expr *);
2544 651 : MUTATE(newnode->refassgnexpr, arrayref->refassgnexpr,
2545 : Expr *);
2546 651 : return (Node *) newnode;
2547 : }
2548 : break;
2549 : case T_FuncExpr:
2550 : {
2551 17124 : FuncExpr *expr = (FuncExpr *) node;
2552 : FuncExpr *newnode;
2553 :
2554 17124 : FLATCOPY(newnode, expr, FuncExpr);
2555 17124 : MUTATE(newnode->args, expr->args, List *);
2556 17124 : return (Node *) newnode;
2557 : }
2558 : break;
2559 : case T_NamedArgExpr:
2560 : {
2561 0 : NamedArgExpr *nexpr = (NamedArgExpr *) node;
2562 : NamedArgExpr *newnode;
2563 :
2564 0 : FLATCOPY(newnode, nexpr, NamedArgExpr);
2565 0 : MUTATE(newnode->arg, nexpr->arg, Expr *);
2566 0 : return (Node *) newnode;
2567 : }
2568 : break;
2569 : case T_OpExpr:
2570 : {
2571 35658 : OpExpr *expr = (OpExpr *) node;
2572 : OpExpr *newnode;
2573 :
2574 35658 : FLATCOPY(newnode, expr, OpExpr);
2575 35658 : MUTATE(newnode->args, expr->args, List *);
2576 35658 : return (Node *) newnode;
2577 : }
2578 : break;
2579 : case T_DistinctExpr:
2580 : {
2581 10 : DistinctExpr *expr = (DistinctExpr *) node;
2582 : DistinctExpr *newnode;
2583 :
2584 10 : FLATCOPY(newnode, expr, DistinctExpr);
2585 10 : MUTATE(newnode->args, expr->args, List *);
2586 10 : return (Node *) newnode;
2587 : }
2588 : break;
2589 : case T_NullIfExpr:
2590 : {
2591 20 : NullIfExpr *expr = (NullIfExpr *) node;
2592 : NullIfExpr *newnode;
2593 :
2594 20 : FLATCOPY(newnode, expr, NullIfExpr);
2595 20 : MUTATE(newnode->args, expr->args, List *);
2596 20 : return (Node *) newnode;
2597 : }
2598 : break;
2599 : case T_ScalarArrayOpExpr:
2600 : {
2601 2821 : ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
2602 : ScalarArrayOpExpr *newnode;
2603 :
2604 2821 : FLATCOPY(newnode, expr, ScalarArrayOpExpr);
2605 2821 : MUTATE(newnode->args, expr->args, List *);
2606 2821 : return (Node *) newnode;
2607 : }
2608 : break;
2609 : case T_BoolExpr:
2610 : {
2611 5241 : BoolExpr *expr = (BoolExpr *) node;
2612 : BoolExpr *newnode;
2613 :
2614 5241 : FLATCOPY(newnode, expr, BoolExpr);
2615 5241 : MUTATE(newnode->args, expr->args, List *);
2616 5240 : return (Node *) newnode;
2617 : }
2618 : break;
2619 : case T_SubLink:
2620 : {
2621 2108 : SubLink *sublink = (SubLink *) node;
2622 : SubLink *newnode;
2623 :
2624 2108 : FLATCOPY(newnode, sublink, SubLink);
2625 2108 : MUTATE(newnode->testexpr, sublink->testexpr, Node *);
2626 :
2627 : /*
2628 : * Also invoke the mutator on the sublink's Query node, so it
2629 : * can recurse into the sub-query if it wants to.
2630 : */
2631 2108 : MUTATE(newnode->subselect, sublink->subselect, Node *);
2632 2108 : return (Node *) newnode;
2633 : }
2634 : break;
2635 : case T_SubPlan:
2636 : {
2637 485 : SubPlan *subplan = (SubPlan *) node;
2638 : SubPlan *newnode;
2639 :
2640 485 : FLATCOPY(newnode, subplan, SubPlan);
2641 : /* transform testexpr */
2642 485 : MUTATE(newnode->testexpr, subplan->testexpr, Node *);
2643 : /* transform args list (params to be passed to subplan) */
2644 485 : MUTATE(newnode->args, subplan->args, List *);
2645 : /* but not the sub-Plan itself, which is referenced as-is */
2646 485 : return (Node *) newnode;
2647 : }
2648 : break;
2649 : case T_AlternativeSubPlan:
2650 : {
2651 82 : AlternativeSubPlan *asplan = (AlternativeSubPlan *) node;
2652 : AlternativeSubPlan *newnode;
2653 :
2654 82 : FLATCOPY(newnode, asplan, AlternativeSubPlan);
2655 82 : MUTATE(newnode->subplans, asplan->subplans, List *);
2656 82 : return (Node *) newnode;
2657 : }
2658 : break;
2659 : case T_FieldSelect:
2660 : {
2661 252 : FieldSelect *fselect = (FieldSelect *) node;
2662 : FieldSelect *newnode;
2663 :
2664 252 : FLATCOPY(newnode, fselect, FieldSelect);
2665 252 : MUTATE(newnode->arg, fselect->arg, Expr *);
2666 252 : return (Node *) newnode;
2667 : }
2668 : break;
2669 : case T_FieldStore:
2670 : {
2671 34 : FieldStore *fstore = (FieldStore *) node;
2672 : FieldStore *newnode;
2673 :
2674 34 : FLATCOPY(newnode, fstore, FieldStore);
2675 34 : MUTATE(newnode->arg, fstore->arg, Expr *);
2676 34 : MUTATE(newnode->newvals, fstore->newvals, List *);
2677 34 : newnode->fieldnums = list_copy(fstore->fieldnums);
2678 34 : return (Node *) newnode;
2679 : }
2680 : break;
2681 : case T_RelabelType:
2682 : {
2683 4143 : RelabelType *relabel = (RelabelType *) node;
2684 : RelabelType *newnode;
2685 :
2686 4143 : FLATCOPY(newnode, relabel, RelabelType);
2687 4143 : MUTATE(newnode->arg, relabel->arg, Expr *);
2688 4143 : return (Node *) newnode;
2689 : }
2690 : break;
2691 : case T_CoerceViaIO:
2692 : {
2693 1174 : CoerceViaIO *iocoerce = (CoerceViaIO *) node;
2694 : CoerceViaIO *newnode;
2695 :
2696 1174 : FLATCOPY(newnode, iocoerce, CoerceViaIO);
2697 1174 : MUTATE(newnode->arg, iocoerce->arg, Expr *);
2698 1174 : return (Node *) newnode;
2699 : }
2700 : break;
2701 : case T_ArrayCoerceExpr:
2702 : {
2703 10 : ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node;
2704 : ArrayCoerceExpr *newnode;
2705 :
2706 10 : FLATCOPY(newnode, acoerce, ArrayCoerceExpr);
2707 10 : MUTATE(newnode->arg, acoerce->arg, Expr *);
2708 10 : return (Node *) newnode;
2709 : }
2710 : break;
2711 : case T_ConvertRowtypeExpr:
2712 : {
2713 16 : ConvertRowtypeExpr *convexpr = (ConvertRowtypeExpr *) node;
2714 : ConvertRowtypeExpr *newnode;
2715 :
2716 16 : FLATCOPY(newnode, convexpr, ConvertRowtypeExpr);
2717 16 : MUTATE(newnode->arg, convexpr->arg, Expr *);
2718 16 : return (Node *) newnode;
2719 : }
2720 : break;
2721 : case T_CollateExpr:
2722 : {
2723 5 : CollateExpr *collate = (CollateExpr *) node;
2724 : CollateExpr *newnode;
2725 :
2726 5 : FLATCOPY(newnode, collate, CollateExpr);
2727 5 : MUTATE(newnode->arg, collate->arg, Expr *);
2728 5 : return (Node *) newnode;
2729 : }
2730 : break;
2731 : case T_CaseExpr:
2732 : {
2733 2422 : CaseExpr *caseexpr = (CaseExpr *) node;
2734 : CaseExpr *newnode;
2735 :
2736 2422 : FLATCOPY(newnode, caseexpr, CaseExpr);
2737 2422 : MUTATE(newnode->arg, caseexpr->arg, Expr *);
2738 2422 : MUTATE(newnode->args, caseexpr->args, List *);
2739 2422 : MUTATE(newnode->defresult, caseexpr->defresult, Expr *);
2740 2422 : return (Node *) newnode;
2741 : }
2742 : break;
2743 : case T_CaseWhen:
2744 : {
2745 3370 : CaseWhen *casewhen = (CaseWhen *) node;
2746 : CaseWhen *newnode;
2747 :
2748 3370 : FLATCOPY(newnode, casewhen, CaseWhen);
2749 3370 : MUTATE(newnode->expr, casewhen->expr, Expr *);
2750 3370 : MUTATE(newnode->result, casewhen->result, Expr *);
2751 3370 : return (Node *) newnode;
2752 : }
2753 : break;
2754 : case T_ArrayExpr:
2755 : {
2756 460 : ArrayExpr *arrayexpr = (ArrayExpr *) node;
2757 : ArrayExpr *newnode;
2758 :
2759 460 : FLATCOPY(newnode, arrayexpr, ArrayExpr);
2760 460 : MUTATE(newnode->elements, arrayexpr->elements, List *);
2761 460 : return (Node *) newnode;
2762 : }
2763 : break;
2764 : case T_RowExpr:
2765 : {
2766 434 : RowExpr *rowexpr = (RowExpr *) node;
2767 : RowExpr *newnode;
2768 :
2769 434 : FLATCOPY(newnode, rowexpr, RowExpr);
2770 434 : MUTATE(newnode->args, rowexpr->args, List *);
2771 : /* Assume colnames needn't be duplicated */
2772 434 : return (Node *) newnode;
2773 : }
2774 : break;
2775 : case T_RowCompareExpr:
2776 : {
2777 25 : RowCompareExpr *rcexpr = (RowCompareExpr *) node;
2778 : RowCompareExpr *newnode;
2779 :
2780 25 : FLATCOPY(newnode, rcexpr, RowCompareExpr);
2781 25 : MUTATE(newnode->largs, rcexpr->largs, List *);
2782 25 : MUTATE(newnode->rargs, rcexpr->rargs, List *);
2783 25 : return (Node *) newnode;
2784 : }
2785 : break;
2786 : case T_CoalesceExpr:
2787 : {
2788 549 : CoalesceExpr *coalesceexpr = (CoalesceExpr *) node;
2789 : CoalesceExpr *newnode;
2790 :
2791 549 : FLATCOPY(newnode, coalesceexpr, CoalesceExpr);
2792 549 : MUTATE(newnode->args, coalesceexpr->args, List *);
2793 549 : return (Node *) newnode;
2794 : }
2795 : break;
2796 : case T_MinMaxExpr:
2797 : {
2798 36 : MinMaxExpr *minmaxexpr = (MinMaxExpr *) node;
2799 : MinMaxExpr *newnode;
2800 :
2801 36 : FLATCOPY(newnode, minmaxexpr, MinMaxExpr);
2802 36 : MUTATE(newnode->args, minmaxexpr->args, List *);
2803 36 : return (Node *) newnode;
2804 : }
2805 : break;
2806 : case T_XmlExpr:
2807 : {
2808 25 : XmlExpr *xexpr = (XmlExpr *) node;
2809 : XmlExpr *newnode;
2810 :
2811 25 : FLATCOPY(newnode, xexpr, XmlExpr);
2812 25 : MUTATE(newnode->named_args, xexpr->named_args, List *);
2813 : /* assume mutator does not care about arg_names */
2814 25 : MUTATE(newnode->args, xexpr->args, List *);
2815 25 : return (Node *) newnode;
2816 : }
2817 : break;
2818 : case T_NullTest:
2819 : {
2820 1181 : NullTest *ntest = (NullTest *) node;
2821 : NullTest *newnode;
2822 :
2823 1181 : FLATCOPY(newnode, ntest, NullTest);
2824 1181 : MUTATE(newnode->arg, ntest->arg, Expr *);
2825 1181 : return (Node *) newnode;
2826 : }
2827 : break;
2828 : case T_BooleanTest:
2829 : {
2830 25 : BooleanTest *btest = (BooleanTest *) node;
2831 : BooleanTest *newnode;
2832 :
2833 25 : FLATCOPY(newnode, btest, BooleanTest);
2834 25 : MUTATE(newnode->arg, btest->arg, Expr *);
2835 25 : return (Node *) newnode;
2836 : }
2837 : break;
2838 : case T_CoerceToDomain:
2839 : {
2840 4019 : CoerceToDomain *ctest = (CoerceToDomain *) node;
2841 : CoerceToDomain *newnode;
2842 :
2843 4019 : FLATCOPY(newnode, ctest, CoerceToDomain);
2844 4019 : MUTATE(newnode->arg, ctest->arg, Expr *);
2845 4015 : return (Node *) newnode;
2846 : }
2847 : break;
2848 : case T_TargetEntry:
2849 : {
2850 132449 : TargetEntry *targetentry = (TargetEntry *) node;
2851 : TargetEntry *newnode;
2852 :
2853 132449 : FLATCOPY(newnode, targetentry, TargetEntry);
2854 132449 : MUTATE(newnode->expr, targetentry->expr, Expr *);
2855 132201 : return (Node *) newnode;
2856 : }
2857 : break;
2858 : case T_Query:
2859 : /* Do nothing with a sub-Query, per discussion above */
2860 1623 : return node;
2861 : case T_WindowClause:
2862 : {
2863 0 : WindowClause *wc = (WindowClause *) node;
2864 : WindowClause *newnode;
2865 :
2866 0 : FLATCOPY(newnode, wc, WindowClause);
2867 0 : MUTATE(newnode->partitionClause, wc->partitionClause, List *);
2868 0 : MUTATE(newnode->orderClause, wc->orderClause, List *);
2869 0 : MUTATE(newnode->startOffset, wc->startOffset, Node *);
2870 0 : MUTATE(newnode->endOffset, wc->endOffset, Node *);
2871 0 : return (Node *) newnode;
2872 : }
2873 : break;
2874 : case T_CommonTableExpr:
2875 : {
2876 3 : CommonTableExpr *cte = (CommonTableExpr *) node;
2877 : CommonTableExpr *newnode;
2878 :
2879 3 : FLATCOPY(newnode, cte, CommonTableExpr);
2880 :
2881 : /*
2882 : * Also invoke the mutator on the CTE's Query node, so it can
2883 : * recurse into the sub-query if it wants to.
2884 : */
2885 3 : MUTATE(newnode->ctequery, cte->ctequery, Node *);
2886 3 : return (Node *) newnode;
2887 : }
2888 : break;
2889 : case T_List:
2890 : {
2891 : /*
2892 : * We assume the mutator isn't interested in the list nodes
2893 : * per se, so just invoke it on each list element. NOTE: this
2894 : * would fail badly on a list with integer elements!
2895 : */
2896 : List *resultlist;
2897 : ListCell *temp;
2898 :
2899 176102 : resultlist = NIL;
2900 542829 : foreach(temp, (List *) node)
2901 : {
2902 366727 : resultlist = lappend(resultlist,
2903 366979 : mutator((Node *) lfirst(temp),
2904 : context));
2905 : }
2906 175850 : return (Node *) resultlist;
2907 : }
2908 : break;
2909 : case T_FromExpr:
2910 : {
2911 1290 : FromExpr *from = (FromExpr *) node;
2912 : FromExpr *newnode;
2913 :
2914 1290 : FLATCOPY(newnode, from, FromExpr);
2915 1290 : MUTATE(newnode->fromlist, from->fromlist, List *);
2916 1290 : MUTATE(newnode->quals, from->quals, Node *);
2917 1290 : return (Node *) newnode;
2918 : }
2919 : break;
2920 : case T_OnConflictExpr:
2921 : {
2922 13 : OnConflictExpr *oc = (OnConflictExpr *) node;
2923 : OnConflictExpr *newnode;
2924 :
2925 13 : FLATCOPY(newnode, oc, OnConflictExpr);
2926 13 : MUTATE(newnode->arbiterElems, oc->arbiterElems, List *);
2927 13 : MUTATE(newnode->arbiterWhere, oc->arbiterWhere, Node *);
2928 13 : MUTATE(newnode->onConflictSet, oc->onConflictSet, List *);
2929 13 : MUTATE(newnode->onConflictWhere, oc->onConflictWhere, Node *);
2930 13 : MUTATE(newnode->exclRelTlist, oc->exclRelTlist, List *);
2931 :
2932 13 : return (Node *) newnode;
2933 : }
2934 : break;
2935 : case T_JoinExpr:
2936 : {
2937 15 : JoinExpr *join = (JoinExpr *) node;
2938 : JoinExpr *newnode;
2939 :
2940 15 : FLATCOPY(newnode, join, JoinExpr);
2941 15 : MUTATE(newnode->larg, join->larg, Node *);
2942 15 : MUTATE(newnode->rarg, join->rarg, Node *);
2943 15 : MUTATE(newnode->quals, join->quals, Node *);
2944 : /* We do not mutate alias or using by default */
2945 15 : return (Node *) newnode;
2946 : }
2947 : break;
2948 : case T_SetOperationStmt:
2949 : {
2950 8 : SetOperationStmt *setop = (SetOperationStmt *) node;
2951 : SetOperationStmt *newnode;
2952 :
2953 8 : FLATCOPY(newnode, setop, SetOperationStmt);
2954 8 : MUTATE(newnode->larg, setop->larg, Node *);
2955 8 : MUTATE(newnode->rarg, setop->rarg, Node *);
2956 : /* We do not mutate groupClauses by default */
2957 8 : return (Node *) newnode;
2958 : }
2959 : break;
2960 : case T_PlaceHolderVar:
2961 : {
2962 222 : PlaceHolderVar *phv = (PlaceHolderVar *) node;
2963 : PlaceHolderVar *newnode;
2964 :
2965 222 : FLATCOPY(newnode, phv, PlaceHolderVar);
2966 222 : MUTATE(newnode->phexpr, phv->phexpr, Expr *);
2967 : /* Assume we need not copy the relids bitmapset */
2968 222 : return (Node *) newnode;
2969 : }
2970 : break;
2971 : case T_InferenceElem:
2972 : {
2973 243 : InferenceElem *inferenceelemdexpr = (InferenceElem *) node;
2974 : InferenceElem *newnode;
2975 :
2976 243 : FLATCOPY(newnode, inferenceelemdexpr, InferenceElem);
2977 243 : MUTATE(newnode->expr, newnode->expr, Node *);
2978 243 : return (Node *) newnode;
2979 : }
2980 : break;
2981 : case T_AppendRelInfo:
2982 : {
2983 1945 : AppendRelInfo *appinfo = (AppendRelInfo *) node;
2984 : AppendRelInfo *newnode;
2985 :
2986 1945 : FLATCOPY(newnode, appinfo, AppendRelInfo);
2987 1945 : MUTATE(newnode->translated_vars, appinfo->translated_vars, List *);
2988 1945 : return (Node *) newnode;
2989 : }
2990 : break;
2991 : case T_PlaceHolderInfo:
2992 : {
2993 0 : PlaceHolderInfo *phinfo = (PlaceHolderInfo *) node;
2994 : PlaceHolderInfo *newnode;
2995 :
2996 0 : FLATCOPY(newnode, phinfo, PlaceHolderInfo);
2997 0 : MUTATE(newnode->ph_var, phinfo->ph_var, PlaceHolderVar *);
2998 : /* Assume we need not copy the relids bitmapsets */
2999 0 : return (Node *) newnode;
3000 : }
3001 : break;
3002 : case T_RangeTblFunction:
3003 : {
3004 2667 : RangeTblFunction *rtfunc = (RangeTblFunction *) node;
3005 : RangeTblFunction *newnode;
3006 :
3007 2667 : FLATCOPY(newnode, rtfunc, RangeTblFunction);
3008 2667 : MUTATE(newnode->funcexpr, rtfunc->funcexpr, Node *);
3009 : /* Assume we need not copy the coldef info lists */
3010 2667 : return (Node *) newnode;
3011 : }
3012 : break;
3013 : case T_TableSampleClause:
3014 : {
3015 54 : TableSampleClause *tsc = (TableSampleClause *) node;
3016 : TableSampleClause *newnode;
3017 :
3018 54 : FLATCOPY(newnode, tsc, TableSampleClause);
3019 54 : MUTATE(newnode->args, tsc->args, List *);
3020 54 : MUTATE(newnode->repeatable, tsc->repeatable, Expr *);
3021 54 : return (Node *) newnode;
3022 : }
3023 : break;
3024 : case T_TableFunc:
3025 : {
3026 54 : TableFunc *tf = (TableFunc *) node;
3027 : TableFunc *newnode;
3028 :
3029 54 : FLATCOPY(newnode, tf, TableFunc);
3030 54 : MUTATE(newnode->ns_uris, tf->ns_uris, List *);
3031 54 : MUTATE(newnode->docexpr, tf->docexpr, Node *);
3032 54 : MUTATE(newnode->rowexpr, tf->rowexpr, Node *);
3033 54 : MUTATE(newnode->colexprs, tf->colexprs, List *);
3034 54 : MUTATE(newnode->coldefexprs, tf->coldefexprs, List *);
3035 54 : return (Node *) newnode;
3036 : }
3037 : break;
3038 : default:
3039 0 : elog(ERROR, "unrecognized node type: %d",
3040 : (int) nodeTag(node));
3041 : break;
3042 : }
3043 : /* can't get here, but keep compiler happy */
3044 : return NULL;
3045 : }
3046 :
3047 :
3048 : /*
3049 : * query_tree_mutator --- initiate modification of a Query's expressions
3050 : *
3051 : * This routine exists just to reduce the number of places that need to know
3052 : * where all the expression subtrees of a Query are. Note it can be used
3053 : * for starting a walk at top level of a Query regardless of whether the
3054 : * mutator intends to descend into subqueries. It is also useful for
3055 : * descending into subqueries within a mutator.
3056 : *
3057 : * Some callers want to suppress mutating of certain items in the Query,
3058 : * typically because they need to process them specially, or don't actually
3059 : * want to recurse into subqueries. This is supported by the flags argument,
3060 : * which is the bitwise OR of flag values to suppress mutating of
3061 : * indicated items. (More flag bits may be added as needed.)
3062 : *
3063 : * Normally the Query node itself is copied, but some callers want it to be
3064 : * modified in-place; they must pass QTW_DONT_COPY_QUERY in flags. All
3065 : * modified substructure is safely copied in any case.
3066 : */
3067 : Query *
3068 1286 : query_tree_mutator(Query *query,
3069 : Node *(*mutator) (),
3070 : void *context,
3071 : int flags)
3072 : {
3073 1286 : Assert(query != NULL && IsA(query, Query));
3074 :
3075 1286 : if (!(flags & QTW_DONT_COPY_QUERY))
3076 : {
3077 : Query *newquery;
3078 :
3079 1286 : FLATCOPY(newquery, query, Query);
3080 1286 : query = newquery;
3081 : }
3082 :
3083 1286 : MUTATE(query->targetList, query->targetList, List *);
3084 1286 : MUTATE(query->withCheckOptions, query->withCheckOptions, List *);
3085 1286 : MUTATE(query->onConflict, query->onConflict, OnConflictExpr *);
3086 1286 : MUTATE(query->returningList, query->returningList, List *);
3087 1286 : MUTATE(query->jointree, query->jointree, FromExpr *);
3088 1286 : MUTATE(query->setOperations, query->setOperations, Node *);
3089 1286 : MUTATE(query->havingQual, query->havingQual, Node *);
3090 1286 : MUTATE(query->limitOffset, query->limitOffset, Node *);
3091 1286 : MUTATE(query->limitCount, query->limitCount, Node *);
3092 1286 : if (!(flags & QTW_IGNORE_CTE_SUBQUERIES))
3093 1097 : MUTATE(query->cteList, query->cteList, List *);
3094 : else /* else copy CTE list as-is */
3095 189 : query->cteList = copyObject(query->cteList);
3096 1286 : query->rtable = range_table_mutator(query->rtable,
3097 : mutator, context, flags);
3098 1286 : return query;
3099 : }
3100 :
3101 : /*
3102 : * range_table_mutator is just the part of query_tree_mutator that processes
3103 : * a query's rangetable. This is split out since it can be useful on
3104 : * its own.
3105 : */
3106 : List *
3107 1286 : range_table_mutator(List *rtable,
3108 : Node *(*mutator) (),
3109 : void *context,
3110 : int flags)
3111 : {
3112 1286 : List *newrt = NIL;
3113 : ListCell *rt;
3114 :
3115 4340 : foreach(rt, rtable)
3116 : {
3117 3054 : RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
3118 : RangeTblEntry *newrte;
3119 :
3120 3054 : FLATCOPY(newrte, rte, RangeTblEntry);
3121 3054 : switch (rte->rtekind)
3122 : {
3123 : case RTE_RELATION:
3124 2602 : MUTATE(newrte->tablesample, rte->tablesample,
3125 : TableSampleClause *);
3126 : /* we don't bother to copy eref, aliases, etc; OK? */
3127 2602 : break;
3128 : case RTE_CTE:
3129 : case RTE_NAMEDTUPLESTORE:
3130 : /* nothing to do */
3131 19 : break;
3132 : case RTE_SUBQUERY:
3133 154 : if (!(flags & QTW_IGNORE_RT_SUBQUERIES))
3134 : {
3135 116 : CHECKFLATCOPY(newrte->subquery, rte->subquery, Query);
3136 116 : MUTATE(newrte->subquery, newrte->subquery, Query *);
3137 : }
3138 : else
3139 : {
3140 : /* else, copy RT subqueries as-is */
3141 38 : newrte->subquery = copyObject(rte->subquery);
3142 : }
3143 154 : break;
3144 : case RTE_JOIN:
3145 13 : if (!(flags & QTW_IGNORE_JOINALIASES))
3146 5 : MUTATE(newrte->joinaliasvars, rte->joinaliasvars, List *);
3147 : else
3148 : {
3149 : /* else, copy join aliases as-is */
3150 8 : newrte->joinaliasvars = copyObject(rte->joinaliasvars);
3151 : }
3152 13 : break;
3153 : case RTE_FUNCTION:
3154 225 : MUTATE(newrte->functions, rte->functions, List *);
3155 225 : break;
3156 : case RTE_TABLEFUNC:
3157 0 : MUTATE(newrte->tablefunc, rte->tablefunc, TableFunc *);
3158 0 : break;
3159 : case RTE_VALUES:
3160 41 : MUTATE(newrte->values_lists, rte->values_lists, List *);
3161 41 : break;
3162 : }
3163 3054 : MUTATE(newrte->securityQuals, rte->securityQuals, List *);
3164 3054 : newrt = lappend(newrt, newrte);
3165 : }
3166 1286 : return newrt;
3167 : }
3168 :
3169 : /*
3170 : * query_or_expression_tree_walker --- hybrid form
3171 : *
3172 : * This routine will invoke query_tree_walker if called on a Query node,
3173 : * else will invoke the walker directly. This is a useful way of starting
3174 : * the recursion when the walker's normal change of state is not appropriate
3175 : * for the outermost Query node.
3176 : */
3177 : bool
3178 182149 : query_or_expression_tree_walker(Node *node,
3179 : bool (*walker) (),
3180 : void *context,
3181 : int flags)
3182 : {
3183 182149 : if (node && IsA(node, Query))
3184 20497 : return query_tree_walker((Query *) node,
3185 : walker,
3186 : context,
3187 : flags);
3188 : else
3189 161652 : return walker(node, context);
3190 : }
3191 :
3192 : /*
3193 : * query_or_expression_tree_mutator --- hybrid form
3194 : *
3195 : * This routine will invoke query_tree_mutator if called on a Query node,
3196 : * else will invoke the mutator directly. This is a useful way of starting
3197 : * the recursion when the mutator's normal change of state is not appropriate
3198 : * for the outermost Query node.
3199 : */
3200 : Node *
3201 9446 : query_or_expression_tree_mutator(Node *node,
3202 : Node *(*mutator) (),
3203 : void *context,
3204 : int flags)
3205 : {
3206 9446 : if (node && IsA(node, Query))
3207 429 : return (Node *) query_tree_mutator((Query *) node,
3208 : mutator,
3209 : context,
3210 : flags);
3211 : else
3212 9017 : return mutator(node, context);
3213 : }
3214 :
3215 :
3216 : /*
3217 : * raw_expression_tree_walker --- walk raw parse trees
3218 : *
3219 : * This has exactly the same API as expression_tree_walker, but instead of
3220 : * walking post-analysis parse trees, it knows how to walk the node types
3221 : * found in raw grammar output. (There is not currently any need for a
3222 : * combined walker, so we keep them separate in the name of efficiency.)
3223 : * Unlike expression_tree_walker, there is no special rule about query
3224 : * boundaries: we descend to everything that's possibly interesting.
3225 : *
3226 : * Currently, the node type coverage here extends only to DML statements
3227 : * (SELECT/INSERT/UPDATE/DELETE) and nodes that can appear in them, because
3228 : * this is used mainly during analysis of CTEs, and only DML statements can
3229 : * appear in CTEs.
3230 : */
3231 : bool
3232 2734 : raw_expression_tree_walker(Node *node,
3233 : bool (*walker) (),
3234 : void *context)
3235 : {
3236 : ListCell *temp;
3237 :
3238 : /*
3239 : * The walker has already visited the current node, and so we need only
3240 : * recurse into any sub-nodes it has.
3241 : */
3242 2734 : if (node == NULL)
3243 0 : return false;
3244 :
3245 : /* Guard against stack overflow due to overly complex expressions */
3246 2734 : check_stack_depth();
3247 :
3248 2734 : switch (nodeTag(node))
3249 : {
3250 : case T_SetToDefault:
3251 : case T_CurrentOfExpr:
3252 : case T_SQLValueFunction:
3253 : case T_Integer:
3254 : case T_Float:
3255 : case T_String:
3256 : case T_BitString:
3257 : case T_Null:
3258 : case T_ParamRef:
3259 : case T_A_Const:
3260 : case T_A_Star:
3261 : /* primitive node types with no subnodes */
3262 379 : break;
3263 : case T_Alias:
3264 : /* we assume the colnames list isn't interesting */
3265 9 : break;
3266 : case T_RangeVar:
3267 0 : return walker(((RangeVar *) node)->alias, context);
3268 : case T_GroupingFunc:
3269 0 : return walker(((GroupingFunc *) node)->args, context);
3270 : case T_SubLink:
3271 : {
3272 3 : SubLink *sublink = (SubLink *) node;
3273 :
3274 3 : if (walker(sublink->testexpr, context))
3275 0 : return true;
3276 : /* we assume the operName is not interesting */
3277 3 : if (walker(sublink->subselect, context))
3278 0 : return true;
3279 : }
3280 3 : break;
3281 : case T_CaseExpr:
3282 : {
3283 0 : CaseExpr *caseexpr = (CaseExpr *) node;
3284 :
3285 0 : if (walker(caseexpr->arg, context))
3286 0 : return true;
3287 : /* we assume walker doesn't care about CaseWhens, either */
3288 0 : foreach(temp, caseexpr->args)
3289 : {
3290 0 : CaseWhen *when = lfirst_node(CaseWhen, temp);
3291 :
3292 0 : if (walker(when->expr, context))
3293 0 : return true;
3294 0 : if (walker(when->result, context))
3295 0 : return true;
3296 : }
3297 0 : if (walker(caseexpr->defresult, context))
3298 0 : return true;
3299 : }
3300 0 : break;
3301 : case T_RowExpr:
3302 : /* Assume colnames isn't interesting */
3303 12 : return walker(((RowExpr *) node)->args, context);
3304 : case T_CoalesceExpr:
3305 0 : return walker(((CoalesceExpr *) node)->args, context);
3306 : case T_MinMaxExpr:
3307 0 : return walker(((MinMaxExpr *) node)->args, context);
3308 : case T_XmlExpr:
3309 : {
3310 0 : XmlExpr *xexpr = (XmlExpr *) node;
3311 :
3312 0 : if (walker(xexpr->named_args, context))
3313 0 : return true;
3314 : /* we assume walker doesn't care about arg_names */
3315 0 : if (walker(xexpr->args, context))
3316 0 : return true;
3317 : }
3318 0 : break;
3319 : case T_NullTest:
3320 0 : return walker(((NullTest *) node)->arg, context);
3321 : case T_BooleanTest:
3322 0 : return walker(((BooleanTest *) node)->arg, context);
3323 : case T_JoinExpr:
3324 : {
3325 11 : JoinExpr *join = (JoinExpr *) node;
3326 :
3327 11 : if (walker(join->larg, context))
3328 0 : return true;
3329 11 : if (walker(join->rarg, context))
3330 0 : return true;
3331 11 : if (walker(join->quals, context))
3332 0 : return true;
3333 11 : if (walker(join->alias, context))
3334 0 : return true;
3335 : /* using list is deemed uninteresting */
3336 : }
3337 11 : break;
3338 : case T_IntoClause:
3339 : {
3340 0 : IntoClause *into = (IntoClause *) node;
3341 :
3342 0 : if (walker(into->rel, context))
3343 0 : return true;
3344 : /* colNames, options are deemed uninteresting */
3345 : /* viewQuery should be null in raw parsetree, but check it */
3346 0 : if (walker(into->viewQuery, context))
3347 0 : return true;
3348 : }
3349 0 : break;
3350 : case T_List:
3351 1510 : foreach(temp, (List *) node)
3352 : {
3353 834 : if (walker((Node *) lfirst(temp), context))
3354 0 : return true;
3355 : }
3356 676 : break;
3357 : case T_InsertStmt:
3358 : {
3359 7 : InsertStmt *stmt = (InsertStmt *) node;
3360 :
3361 7 : if (walker(stmt->relation, context))
3362 0 : return true;
3363 7 : if (walker(stmt->cols, context))
3364 0 : return true;
3365 7 : if (walker(stmt->selectStmt, context))
3366 0 : return true;
3367 7 : if (walker(stmt->onConflictClause, context))
3368 0 : return true;
3369 7 : if (walker(stmt->returningList, context))
3370 0 : return true;
3371 7 : if (walker(stmt->withClause, context))
3372 0 : return true;
3373 : }
3374 7 : break;
3375 : case T_DeleteStmt:
3376 : {
3377 0 : DeleteStmt *stmt = (DeleteStmt *) node;
3378 :
3379 0 : if (walker(stmt->relation, context))
3380 0 : return true;
3381 0 : if (walker(stmt->usingClause, context))
3382 0 : return true;
3383 0 : if (walker(stmt->whereClause, context))
3384 0 : return true;
3385 0 : if (walker(stmt->returningList, context))
3386 0 : return true;
3387 0 : if (walker(stmt->withClause, context))
3388 0 : return true;
3389 : }
3390 0 : break;
3391 : case T_UpdateStmt:
3392 : {
3393 1 : UpdateStmt *stmt = (UpdateStmt *) node;
3394 :
3395 1 : if (walker(stmt->relation, context))
3396 0 : return true;
3397 1 : if (walker(stmt->targetList, context))
3398 0 : return true;
3399 1 : if (walker(stmt->whereClause, context))
3400 0 : return true;
3401 1 : if (walker(stmt->fromClause, context))
3402 0 : return true;
3403 1 : if (walker(stmt->returningList, context))
3404 0 : return true;
3405 1 : if (walker(stmt->withClause, context))
3406 0 : return true;
3407 : }
3408 1 : break;
3409 : case T_SelectStmt:
3410 : {
3411 428 : SelectStmt *stmt = (SelectStmt *) node;
3412 :
3413 428 : if (walker(stmt->distinctClause, context))
3414 0 : return true;
3415 428 : if (walker(stmt->intoClause, context))
3416 0 : return true;
3417 428 : if (walker(stmt->targetList, context))
3418 0 : return true;
3419 427 : if (walker(stmt->fromClause, context))
3420 0 : return true;
3421 415 : if (walker(stmt->whereClause, context))
3422 0 : return true;
3423 414 : if (walker(stmt->groupClause, context))
3424 0 : return true;
3425 414 : if (walker(stmt->havingClause, context))
3426 0 : return true;
3427 414 : if (walker(stmt->windowClause, context))
3428 0 : return true;
3429 414 : if (walker(stmt->valuesLists, context))
3430 0 : return true;
3431 414 : if (walker(stmt->sortClause, context))
3432 0 : return true;
3433 414 : if (walker(stmt->limitOffset, context))
3434 0 : return true;
3435 414 : if (walker(stmt->limitCount, context))
3436 0 : return true;
3437 414 : if (walker(stmt->lockingClause, context))
3438 0 : return true;
3439 414 : if (walker(stmt->withClause, context))
3440 0 : return true;
3441 414 : if (walker(stmt->larg, context))
3442 0 : return true;
3443 414 : if (walker(stmt->rarg, context))
3444 0 : return true;
3445 : }
3446 412 : break;
3447 : case T_A_Expr:
3448 : {
3449 249 : A_Expr *expr = (A_Expr *) node;
3450 :
3451 249 : if (walker(expr->lexpr, context))
3452 0 : return true;
3453 249 : if (walker(expr->rexpr, context))
3454 0 : return true;
3455 : /* operator name is deemed uninteresting */
3456 : }
3457 249 : break;
3458 : case T_BoolExpr:
3459 : {
3460 8 : BoolExpr *expr = (BoolExpr *) node;
3461 :
3462 8 : if (walker(expr->args, context))
3463 0 : return true;
3464 : }
3465 8 : break;
3466 : case T_ColumnRef:
3467 : /* we assume the fields contain nothing interesting */
3468 476 : break;
3469 : case T_FuncCall:
3470 : {
3471 12 : FuncCall *fcall = (FuncCall *) node;
3472 :
3473 12 : if (walker(fcall->args, context))
3474 0 : return true;
3475 12 : if (walker(fcall->agg_order, context))
3476 0 : return true;
3477 12 : if (walker(fcall->agg_filter, context))
3478 0 : return true;
3479 12 : if (walker(fcall->over, context))
3480 0 : return true;
3481 : /* function name is deemed uninteresting */
3482 : }
3483 12 : break;
3484 : case T_NamedArgExpr:
3485 0 : return walker(((NamedArgExpr *) node)->arg, context);
3486 : case T_A_Indices:
3487 : {
3488 0 : A_Indices *indices = (A_Indices *) node;
3489 :
3490 0 : if (walker(indices->lidx, context))
3491 0 : return true;
3492 0 : if (walker(indices->uidx, context))
3493 0 : return true;
3494 : }
3495 0 : break;
3496 : case T_A_Indirection:
3497 : {
3498 0 : A_Indirection *indir = (A_Indirection *) node;
3499 :
3500 0 : if (walker(indir->arg, context))
3501 0 : return true;
3502 0 : if (walker(indir->indirection, context))
3503 0 : return true;
3504 : }
3505 0 : break;
3506 : case T_A_ArrayExpr:
3507 10 : return walker(((A_ArrayExpr *) node)->elements, context);
3508 : case T_ResTarget:
3509 : {
3510 365 : ResTarget *rt = (ResTarget *) node;
3511 :
3512 365 : if (walker(rt->indirection, context))
3513 0 : return true;
3514 365 : if (walker(rt->val, context))
3515 0 : return true;
3516 : }
3517 364 : break;
3518 : case T_MultiAssignRef:
3519 0 : return walker(((MultiAssignRef *) node)->source, context);
3520 : case T_TypeCast:
3521 : {
3522 26 : TypeCast *tc = (TypeCast *) node;
3523 :
3524 26 : if (walker(tc->arg, context))
3525 0 : return true;
3526 26 : if (walker(tc->typeName, context))
3527 0 : return true;
3528 : }
3529 26 : break;
3530 : case T_CollateClause:
3531 4 : return walker(((CollateClause *) node)->arg, context);
3532 : case T_SortBy:
3533 1 : return walker(((SortBy *) node)->node, context);
3534 : case T_WindowDef:
3535 : {
3536 4 : WindowDef *wd = (WindowDef *) node;
3537 :
3538 4 : if (walker(wd->partitionClause, context))
3539 0 : return true;
3540 4 : if (walker(wd->orderClause, context))
3541 0 : return true;
3542 4 : if (walker(wd->startOffset, context))
3543 0 : return true;
3544 4 : if (walker(wd->endOffset, context))
3545 0 : return true;
3546 : }
3547 4 : break;
3548 : case T_RangeSubselect:
3549 : {
3550 10 : RangeSubselect *rs = (RangeSubselect *) node;
3551 :
3552 10 : if (walker(rs->subquery, context))
3553 0 : return true;
3554 9 : if (walker(rs->alias, context))
3555 0 : return true;
3556 : }
3557 9 : break;
3558 : case T_RangeFunction:
3559 : {
3560 0 : RangeFunction *rf = (RangeFunction *) node;
3561 :
3562 0 : if (walker(rf->functions, context))
3563 0 : return true;
3564 0 : if (walker(rf->alias, context))
3565 0 : return true;
3566 0 : if (walker(rf->coldeflist, context))
3567 0 : return true;
3568 : }
3569 0 : break;
3570 : case T_RangeTableSample:
3571 : {
3572 0 : RangeTableSample *rts = (RangeTableSample *) node;
3573 :
3574 0 : if (walker(rts->relation, context))
3575 0 : return true;
3576 : /* method name is deemed uninteresting */
3577 0 : if (walker(rts->args, context))
3578 0 : return true;
3579 0 : if (walker(rts->repeatable, context))
3580 0 : return true;
3581 : }
3582 0 : break;
3583 : case T_RangeTableFunc:
3584 : {
3585 0 : RangeTableFunc *rtf = (RangeTableFunc *) node;
3586 :
3587 0 : if (walker(rtf->docexpr, context))
3588 0 : return true;
3589 0 : if (walker(rtf->rowexpr, context))
3590 0 : return true;
3591 0 : if (walker(rtf->namespaces, context))
3592 0 : return true;
3593 0 : if (walker(rtf->columns, context))
3594 0 : return true;
3595 0 : if (walker(rtf->alias, context))
3596 0 : return true;
3597 : }
3598 0 : break;
3599 : case T_RangeTableFuncCol:
3600 : {
3601 0 : RangeTableFuncCol *rtfc = (RangeTableFuncCol *) node;
3602 :
3603 0 : if (walker(rtfc->colexpr, context))
3604 0 : return true;
3605 0 : if (walker(rtfc->coldefexpr, context))
3606 0 : return true;
3607 : }
3608 0 : break;
3609 : case T_TypeName:
3610 : {
3611 26 : TypeName *tn = (TypeName *) node;
3612 :
3613 26 : if (walker(tn->typmods, context))
3614 0 : return true;
3615 26 : if (walker(tn->arrayBounds, context))
3616 0 : return true;
3617 : /* type name itself is deemed uninteresting */
3618 : }
3619 26 : break;
3620 : case T_ColumnDef:
3621 : {
3622 0 : ColumnDef *coldef = (ColumnDef *) node;
3623 :
3624 0 : if (walker(coldef->typeName, context))
3625 0 : return true;
3626 0 : if (walker(coldef->raw_default, context))
3627 0 : return true;
3628 0 : if (walker(coldef->collClause, context))
3629 0 : return true;
3630 : /* for now, constraints are ignored */
3631 : }
3632 0 : break;
3633 : case T_IndexElem:
3634 : {
3635 0 : IndexElem *indelem = (IndexElem *) node;
3636 :
3637 0 : if (walker(indelem->expr, context))
3638 0 : return true;
3639 : /* collation and opclass names are deemed uninteresting */
3640 : }
3641 0 : break;
3642 : case T_GroupingSet:
3643 0 : return walker(((GroupingSet *) node)->content, context);
3644 : case T_LockingClause:
3645 1 : return walker(((LockingClause *) node)->lockedRels, context);
3646 : case T_XmlSerialize:
3647 : {
3648 0 : XmlSerialize *xs = (XmlSerialize *) node;
3649 :
3650 0 : if (walker(xs->expr, context))
3651 0 : return true;
3652 0 : if (walker(xs->typeName, context))
3653 0 : return true;
3654 : }
3655 0 : break;
3656 : case T_WithClause:
3657 0 : return walker(((WithClause *) node)->ctes, context);
3658 : case T_InferClause:
3659 : {
3660 0 : InferClause *stmt = (InferClause *) node;
3661 :
3662 0 : if (walker(stmt->indexElems, context))
3663 0 : return true;
3664 0 : if (walker(stmt->whereClause, context))
3665 0 : return true;
3666 : }
3667 0 : break;
3668 : case T_OnConflictClause:
3669 : {
3670 0 : OnConflictClause *stmt = (OnConflictClause *) node;
3671 :
3672 0 : if (walker(stmt->infer, context))
3673 0 : return true;
3674 0 : if (walker(stmt->targetList, context))
3675 0 : return true;
3676 0 : if (walker(stmt->whereClause, context))
3677 0 : return true;
3678 : }
3679 0 : break;
3680 : case T_CommonTableExpr:
3681 2 : return walker(((CommonTableExpr *) node)->ctequery, context);
3682 : default:
3683 0 : elog(ERROR, "unrecognized node type: %d",
3684 : (int) nodeTag(node));
3685 : break;
3686 : }
3687 2672 : return false;
3688 : }
3689 :
3690 : /*
3691 : * planstate_tree_walker --- walk plan state trees
3692 : *
3693 : * The walker has already visited the current node, and so we need only
3694 : * recurse into any sub-nodes it has.
3695 : */
3696 : bool
3697 49799 : planstate_tree_walker(PlanState *planstate,
3698 : bool (*walker) (),
3699 : void *context)
3700 : {
3701 49799 : Plan *plan = planstate->plan;
3702 : ListCell *lc;
3703 :
3704 : /* initPlan-s */
3705 49799 : if (planstate_walk_subplans(planstate->initPlan, walker, context))
3706 0 : return true;
3707 :
3708 : /* lefttree */
3709 49799 : if (outerPlanState(planstate))
3710 : {
3711 14570 : if (walker(outerPlanState(planstate), context))
3712 0 : return true;
3713 : }
3714 :
3715 : /* righttree */
3716 49799 : if (innerPlanState(planstate))
3717 : {
3718 3778 : if (walker(innerPlanState(planstate), context))
3719 0 : return true;
3720 : }
3721 :
3722 : /* special child plans */
3723 49799 : switch (nodeTag(plan))
3724 : {
3725 : case T_ModifyTable:
3726 4230 : if (planstate_walk_members(((ModifyTable *) plan)->plans,
3727 : ((ModifyTableState *) planstate)->mt_plans,
3728 : walker, context))
3729 0 : return true;
3730 4230 : break;
3731 : case T_Append:
3732 635 : if (planstate_walk_members(((Append *) plan)->appendplans,
3733 : ((AppendState *) planstate)->appendplans,
3734 : walker, context))
3735 0 : return true;
3736 635 : break;
3737 : case T_MergeAppend:
3738 34 : if (planstate_walk_members(((MergeAppend *) plan)->mergeplans,
3739 : ((MergeAppendState *) planstate)->mergeplans,
3740 : walker, context))
3741 0 : return true;
3742 34 : break;
3743 : case T_BitmapAnd:
3744 3 : if (planstate_walk_members(((BitmapAnd *) plan)->bitmapplans,
3745 : ((BitmapAndState *) planstate)->bitmapplans,
3746 : walker, context))
3747 0 : return true;
3748 3 : break;
3749 : case T_BitmapOr:
3750 17 : if (planstate_walk_members(((BitmapOr *) plan)->bitmapplans,
3751 : ((BitmapOrState *) planstate)->bitmapplans,
3752 : walker, context))
3753 0 : return true;
3754 17 : break;
3755 : case T_SubqueryScan:
3756 286 : if (walker(((SubqueryScanState *) planstate)->subplan, context))
3757 0 : return true;
3758 286 : break;
3759 : case T_CustomScan:
3760 0 : foreach(lc, ((CustomScanState *) planstate)->custom_ps)
3761 : {
3762 0 : if (walker((PlanState *) lfirst(lc), context))
3763 0 : return true;
3764 : }
3765 0 : break;
3766 : default:
3767 44594 : break;
3768 : }
3769 :
3770 : /* subPlan-s */
3771 49799 : if (planstate_walk_subplans(planstate->subPlan, walker, context))
3772 0 : return true;
3773 :
3774 49799 : return false;
3775 : }
3776 :
3777 : /*
3778 : * Walk a list of SubPlans (or initPlans, which also use SubPlan nodes).
3779 : */
3780 : static bool
3781 99598 : planstate_walk_subplans(List *plans,
3782 : bool (*walker) (),
3783 : void *context)
3784 : {
3785 : ListCell *lc;
3786 :
3787 102818 : foreach(lc, plans)
3788 : {
3789 3220 : SubPlanState *sps = lfirst_node(SubPlanState, lc);
3790 :
3791 3220 : if (walker(sps->planstate, context))
3792 0 : return true;
3793 : }
3794 :
3795 99598 : return false;
3796 : }
3797 :
3798 : /*
3799 : * Walk the constituent plans of a ModifyTable, Append, MergeAppend,
3800 : * BitmapAnd, or BitmapOr node.
3801 : *
3802 : * Note: we don't actually need to examine the Plan list members, but
3803 : * we need the list in order to determine the length of the PlanState array.
3804 : */
3805 : static bool
3806 4919 : planstate_walk_members(List *plans, PlanState **planstates,
3807 : bool (*walker) (), void *context)
3808 : {
3809 4919 : int nplans = list_length(plans);
3810 : int j;
3811 :
3812 10980 : for (j = 0; j < nplans; j++)
3813 : {
3814 6061 : if (walker(planstates[j], context))
3815 0 : return true;
3816 : }
3817 :
3818 4919 : return false;
3819 : }
|