Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * nodeFuncs.c
4 : * Various general-purpose manipulations of Node trees
5 : *
6 : * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
7 : * Portions Copyright (c) 1994, Regents of the University of California
8 : *
9 : *
10 : * IDENTIFICATION
11 : * src/backend/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/execnodes.h"
21 : #include "nodes/nodeFuncs.h"
22 : #include "nodes/pathnodes.h"
23 : #include "utils/builtins.h"
24 : #include "utils/lsyscache.h"
25 :
26 : static bool expression_returns_set_walker(Node *node, void *context);
27 : static int leftmostLoc(int loc1, int loc2);
28 : static bool fix_opfuncids_walker(Node *node, void *context);
29 : static bool planstate_walk_subplans(List *plans,
30 : planstate_tree_walker_callback walker,
31 : void *context);
32 : static bool planstate_walk_members(PlanState **planstates, int nplans,
33 : planstate_tree_walker_callback walker,
34 : void *context);
35 :
36 :
37 : /*
38 : * exprType -
39 : * returns the Oid of the type of the expression's result.
40 : */
41 : Oid
42 22208444 : exprType(const Node *expr)
43 : {
44 : Oid type;
45 :
46 22208444 : if (!expr)
47 308 : return InvalidOid;
48 :
49 22208136 : switch (nodeTag(expr))
50 : {
51 12604437 : case T_Var:
52 12604437 : type = ((const Var *) expr)->vartype;
53 12604437 : break;
54 3147530 : case T_Const:
55 3147530 : type = ((const Const *) expr)->consttype;
56 3147530 : break;
57 1840155 : case T_Param:
58 1840155 : type = ((const Param *) expr)->paramtype;
59 1840155 : break;
60 222657 : case T_Aggref:
61 222657 : type = ((const Aggref *) expr)->aggtype;
62 222657 : break;
63 1759 : case T_GroupingFunc:
64 1759 : type = INT4OID;
65 1759 : break;
66 15153 : case T_WindowFunc:
67 15153 : type = ((const WindowFunc *) expr)->wintype;
68 15153 : break;
69 696 : case T_MergeSupportFunc:
70 696 : type = ((const MergeSupportFunc *) expr)->msftype;
71 696 : break;
72 104688 : case T_SubscriptingRef:
73 104688 : type = ((const SubscriptingRef *) expr)->refrestype;
74 104688 : break;
75 1382217 : case T_FuncExpr:
76 1382217 : type = ((const FuncExpr *) expr)->funcresulttype;
77 1382217 : break;
78 53300 : case T_NamedArgExpr:
79 53300 : type = exprType((Node *) ((const NamedArgExpr *) expr)->arg);
80 53300 : break;
81 1014882 : case T_OpExpr:
82 1014882 : type = ((const OpExpr *) expr)->opresulttype;
83 1014882 : break;
84 1714 : case T_DistinctExpr:
85 1714 : type = ((const DistinctExpr *) expr)->opresulttype;
86 1714 : break;
87 1787 : case T_NullIfExpr:
88 1787 : type = ((const NullIfExpr *) expr)->opresulttype;
89 1787 : break;
90 75990 : case T_ScalarArrayOpExpr:
91 75990 : type = BOOLOID;
92 75990 : break;
93 242300 : case T_BoolExpr:
94 242300 : type = BOOLOID;
95 242300 : break;
96 76608 : case T_SubLink:
97 : {
98 76608 : const SubLink *sublink = (const SubLink *) expr;
99 :
100 76608 : if (sublink->subLinkType == EXPR_SUBLINK ||
101 32327 : sublink->subLinkType == ARRAY_SUBLINK)
102 56266 : {
103 : /* get the type of the subselect's first target column */
104 56266 : Query *qtree = (Query *) sublink->subselect;
105 : TargetEntry *tent;
106 :
107 56266 : if (!qtree || !IsA(qtree, Query))
108 0 : elog(ERROR, "cannot get type for untransformed sublink");
109 56266 : tent = linitial_node(TargetEntry, qtree->targetList);
110 : Assert(!tent->resjunk);
111 56266 : type = exprType((Node *) tent->expr);
112 56266 : if (sublink->subLinkType == ARRAY_SUBLINK)
113 : {
114 11985 : type = get_promoted_array_type(type);
115 11985 : if (!OidIsValid(type))
116 0 : ereport(ERROR,
117 : (errcode(ERRCODE_UNDEFINED_OBJECT),
118 : errmsg("could not find array type for data type %s",
119 : format_type_be(exprType((Node *) tent->expr)))));
120 : }
121 : }
122 20342 : else if (sublink->subLinkType == MULTIEXPR_SUBLINK)
123 : {
124 : /* MULTIEXPR is always considered to return RECORD */
125 91 : type = RECORDOID;
126 : }
127 : else
128 : {
129 : /* for all other sublink types, result is boolean */
130 20251 : type = BOOLOID;
131 : }
132 : }
133 76608 : break;
134 37396 : case T_SubPlan:
135 : {
136 37396 : const SubPlan *subplan = (const SubPlan *) expr;
137 :
138 37396 : if (subplan->subLinkType == EXPR_SUBLINK ||
139 3185 : subplan->subLinkType == ARRAY_SUBLINK)
140 : {
141 : /* get the type of the subselect's first target column */
142 34459 : type = subplan->firstColType;
143 34459 : if (subplan->subLinkType == ARRAY_SUBLINK)
144 : {
145 248 : type = get_promoted_array_type(type);
146 248 : if (!OidIsValid(type))
147 0 : ereport(ERROR,
148 : (errcode(ERRCODE_UNDEFINED_OBJECT),
149 : errmsg("could not find array type for data type %s",
150 : format_type_be(subplan->firstColType))));
151 : }
152 : }
153 2937 : else if (subplan->subLinkType == MULTIEXPR_SUBLINK)
154 : {
155 : /* MULTIEXPR is always considered to return RECORD */
156 126 : type = RECORDOID;
157 : }
158 : else
159 : {
160 : /* for all other subplan types, result is boolean */
161 2811 : type = BOOLOID;
162 : }
163 : }
164 37396 : break;
165 1088 : case T_AlternativeSubPlan:
166 : {
167 1088 : const AlternativeSubPlan *asplan = (const AlternativeSubPlan *) expr;
168 :
169 : /* subplans should all return the same thing */
170 1088 : type = exprType((Node *) linitial(asplan->subplans));
171 : }
172 1088 : break;
173 33189 : case T_FieldSelect:
174 33189 : type = ((const FieldSelect *) expr)->resulttype;
175 33189 : break;
176 760 : case T_FieldStore:
177 760 : type = ((const FieldStore *) expr)->resulttype;
178 760 : break;
179 456608 : case T_RelabelType:
180 456608 : type = ((const RelabelType *) expr)->resulttype;
181 456608 : break;
182 103086 : case T_CoerceViaIO:
183 103086 : type = ((const CoerceViaIO *) expr)->resulttype;
184 103086 : break;
185 11743 : case T_ArrayCoerceExpr:
186 11743 : type = ((const ArrayCoerceExpr *) expr)->resulttype;
187 11743 : break;
188 1703 : case T_ConvertRowtypeExpr:
189 1703 : type = ((const ConvertRowtypeExpr *) expr)->resulttype;
190 1703 : break;
191 7603 : case T_CollateExpr:
192 7603 : type = exprType((Node *) ((const CollateExpr *) expr)->arg);
193 7603 : break;
194 266674 : case T_CaseExpr:
195 266674 : type = ((const CaseExpr *) expr)->casetype;
196 266674 : break;
197 29678 : case T_CaseTestExpr:
198 29678 : type = ((const CaseTestExpr *) expr)->typeId;
199 29678 : break;
200 71925 : case T_ArrayExpr:
201 71925 : type = ((const ArrayExpr *) expr)->array_typeid;
202 71925 : break;
203 11321 : case T_RowExpr:
204 11321 : type = ((const RowExpr *) expr)->row_typeid;
205 11321 : break;
206 306 : case T_RowCompareExpr:
207 306 : type = BOOLOID;
208 306 : break;
209 18809 : case T_CoalesceExpr:
210 18809 : type = ((const CoalesceExpr *) expr)->coalescetype;
211 18809 : break;
212 3676 : case T_MinMaxExpr:
213 3676 : type = ((const MinMaxExpr *) expr)->minmaxtype;
214 3676 : break;
215 7849 : case T_SQLValueFunction:
216 7849 : type = ((const SQLValueFunction *) expr)->type;
217 7849 : break;
218 17548 : case T_XmlExpr:
219 17548 : if (((const XmlExpr *) expr)->op == IS_DOCUMENT)
220 70 : type = BOOLOID;
221 17478 : else if (((const XmlExpr *) expr)->op == IS_XMLSERIALIZE)
222 635 : type = TEXTOID;
223 : else
224 16843 : type = XMLOID;
225 17548 : break;
226 681 : case T_JsonValueExpr:
227 : {
228 681 : const JsonValueExpr *jve = (const JsonValueExpr *) expr;
229 :
230 681 : type = exprType((Node *) jve->formatted_expr);
231 : }
232 681 : break;
233 4992 : case T_JsonConstructorExpr:
234 4992 : type = ((const JsonConstructorExpr *) expr)->returning->typid;
235 4992 : break;
236 1262 : case T_JsonIsPredicate:
237 1262 : type = BOOLOID;
238 1262 : break;
239 6960 : case T_JsonExpr:
240 : {
241 6960 : const JsonExpr *jexpr = (const JsonExpr *) expr;
242 :
243 6960 : type = jexpr->returning->typid;
244 6960 : break;
245 : }
246 3204 : case T_JsonBehavior:
247 : {
248 3204 : const JsonBehavior *behavior = (const JsonBehavior *) expr;
249 :
250 3204 : type = exprType(behavior->expr);
251 3204 : break;
252 : }
253 30268 : case T_NullTest:
254 30268 : type = BOOLOID;
255 30268 : break;
256 2392 : case T_BooleanTest:
257 2392 : type = BOOLOID;
258 2392 : break;
259 188101 : case T_CoerceToDomain:
260 188101 : type = ((const CoerceToDomain *) expr)->resulttype;
261 188101 : break;
262 1532 : case T_CoerceToDomainValue:
263 1532 : type = ((const CoerceToDomainValue *) expr)->typeId;
264 1532 : break;
265 81206 : case T_SetToDefault:
266 81206 : type = ((const SetToDefault *) expr)->typeId;
267 81206 : break;
268 168 : case T_CurrentOfExpr:
269 168 : type = BOOLOID;
270 168 : break;
271 1445 : case T_NextValueExpr:
272 1445 : type = ((const NextValueExpr *) expr)->typeId;
273 1445 : break;
274 0 : case T_InferenceElem:
275 : {
276 0 : const InferenceElem *n = (const InferenceElem *) expr;
277 :
278 0 : type = exprType((Node *) n->expr);
279 : }
280 0 : break;
281 640 : case T_ReturningExpr:
282 640 : type = exprType((Node *) ((const ReturningExpr *) expr)->retexpr);
283 640 : break;
284 16831 : case T_PlaceHolderVar:
285 16831 : type = exprType((Node *) ((const PlaceHolderVar *) expr)->phexpr);
286 16831 : break;
287 1619 : case T_GraphPropertyRef:
288 1619 : type = ((const GraphPropertyRef *) expr)->typeId;
289 1619 : break;
290 0 : default:
291 0 : elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
292 : type = InvalidOid; /* keep compiler quiet */
293 : break;
294 : }
295 22208136 : return type;
296 : }
297 :
298 : /*
299 : * exprTypmod -
300 : * returns the type-specific modifier of the expression's result type,
301 : * if it can be determined. In many cases, it can't and we return -1.
302 : */
303 : int32
304 7667029 : exprTypmod(const Node *expr)
305 : {
306 7667029 : if (!expr)
307 0 : return -1;
308 :
309 7667029 : switch (nodeTag(expr))
310 : {
311 4598528 : case T_Var:
312 4598528 : return ((const Var *) expr)->vartypmod;
313 1168933 : case T_Const:
314 1168933 : return ((const Const *) expr)->consttypmod;
315 104748 : case T_Param:
316 104748 : return ((const Param *) expr)->paramtypmod;
317 31835 : case T_SubscriptingRef:
318 31835 : return ((const SubscriptingRef *) expr)->reftypmod;
319 873282 : case T_FuncExpr:
320 : {
321 : int32 coercedTypmod;
322 :
323 : /* Be smart about length-coercion functions... */
324 873282 : if (exprIsLengthCoercion(expr, &coercedTypmod))
325 19688 : return coercedTypmod;
326 : }
327 853594 : break;
328 0 : case T_NamedArgExpr:
329 0 : return exprTypmod((Node *) ((const NamedArgExpr *) expr)->arg);
330 321 : case T_NullIfExpr:
331 : {
332 : /*
333 : * Result is either first argument or NULL, so we can report
334 : * first argument's typmod if known.
335 : */
336 321 : const NullIfExpr *nexpr = (const NullIfExpr *) expr;
337 :
338 321 : return exprTypmod((Node *) linitial(nexpr->args));
339 : }
340 : break;
341 4396 : case T_SubLink:
342 : {
343 4396 : const SubLink *sublink = (const SubLink *) expr;
344 :
345 4396 : if (sublink->subLinkType == EXPR_SUBLINK ||
346 421 : sublink->subLinkType == ARRAY_SUBLINK)
347 : {
348 : /* get the typmod of the subselect's first target column */
349 4339 : Query *qtree = (Query *) sublink->subselect;
350 : TargetEntry *tent;
351 :
352 4339 : if (!qtree || !IsA(qtree, Query))
353 0 : elog(ERROR, "cannot get type for untransformed sublink");
354 4339 : tent = linitial_node(TargetEntry, qtree->targetList);
355 : Assert(!tent->resjunk);
356 4339 : return exprTypmod((Node *) tent->expr);
357 : /* note we don't need to care if it's an array */
358 : }
359 : /* otherwise, result is RECORD or BOOLEAN, typmod is -1 */
360 : }
361 57 : break;
362 26475 : case T_SubPlan:
363 : {
364 26475 : const SubPlan *subplan = (const SubPlan *) expr;
365 :
366 26475 : if (subplan->subLinkType == EXPR_SUBLINK ||
367 1719 : subplan->subLinkType == ARRAY_SUBLINK)
368 : {
369 : /* get the typmod of the subselect's first target column */
370 : /* note we don't need to care if it's an array */
371 24933 : return subplan->firstColTypmod;
372 : }
373 : /* otherwise, result is RECORD or BOOLEAN, typmod is -1 */
374 : }
375 1542 : break;
376 549 : case T_AlternativeSubPlan:
377 : {
378 549 : const AlternativeSubPlan *asplan = (const AlternativeSubPlan *) expr;
379 :
380 : /* subplans should all return the same thing */
381 549 : return exprTypmod((Node *) linitial(asplan->subplans));
382 : }
383 : break;
384 14581 : case T_FieldSelect:
385 14581 : return ((const FieldSelect *) expr)->resulttypmod;
386 154393 : case T_RelabelType:
387 154393 : return ((const RelabelType *) expr)->resulttypmod;
388 5585 : case T_ArrayCoerceExpr:
389 5585 : return ((const ArrayCoerceExpr *) expr)->resulttypmod;
390 151 : case T_CollateExpr:
391 151 : return exprTypmod((Node *) ((const CollateExpr *) expr)->arg);
392 125850 : case T_CaseExpr:
393 : {
394 : /*
395 : * If all the alternatives agree on type/typmod, return that
396 : * typmod, else use -1
397 : */
398 125850 : const CaseExpr *cexpr = (const CaseExpr *) expr;
399 125850 : Oid casetype = cexpr->casetype;
400 : int32 typmod;
401 : ListCell *arg;
402 :
403 125850 : if (!cexpr->defresult)
404 0 : return -1;
405 125850 : if (exprType((Node *) cexpr->defresult) != casetype)
406 0 : return -1;
407 125850 : typmod = exprTypmod((Node *) cexpr->defresult);
408 125850 : if (typmod < 0)
409 125850 : return -1; /* no point in trying harder */
410 0 : foreach(arg, cexpr->args)
411 : {
412 0 : CaseWhen *w = lfirst_node(CaseWhen, arg);
413 :
414 0 : if (exprType((Node *) w->result) != casetype)
415 0 : return -1;
416 0 : if (exprTypmod((Node *) w->result) != typmod)
417 0 : return -1;
418 : }
419 0 : return typmod;
420 : }
421 : break;
422 9767 : case T_CaseTestExpr:
423 9767 : return ((const CaseTestExpr *) expr)->typeMod;
424 29075 : case T_ArrayExpr:
425 : {
426 : /*
427 : * If all the elements agree on type/typmod, return that
428 : * typmod, else use -1
429 : */
430 29075 : const ArrayExpr *arrayexpr = (const ArrayExpr *) expr;
431 : Oid commontype;
432 : int32 typmod;
433 : ListCell *elem;
434 :
435 29075 : if (arrayexpr->elements == NIL)
436 164 : return -1;
437 28911 : typmod = exprTypmod((Node *) linitial(arrayexpr->elements));
438 28911 : if (typmod < 0)
439 28887 : return -1; /* no point in trying harder */
440 24 : if (arrayexpr->multidims)
441 0 : commontype = arrayexpr->array_typeid;
442 : else
443 24 : commontype = arrayexpr->element_typeid;
444 84 : foreach(elem, arrayexpr->elements)
445 : {
446 60 : Node *e = (Node *) lfirst(elem);
447 :
448 60 : if (exprType(e) != commontype)
449 0 : return -1;
450 60 : if (exprTypmod(e) != typmod)
451 0 : return -1;
452 : }
453 24 : return typmod;
454 : }
455 : break;
456 5689 : case T_CoalesceExpr:
457 : {
458 : /*
459 : * If all the alternatives agree on type/typmod, return that
460 : * typmod, else use -1
461 : */
462 5689 : const CoalesceExpr *cexpr = (const CoalesceExpr *) expr;
463 5689 : Oid coalescetype = cexpr->coalescetype;
464 : int32 typmod;
465 : ListCell *arg;
466 :
467 5689 : if (exprType((Node *) linitial(cexpr->args)) != coalescetype)
468 0 : return -1;
469 5689 : typmod = exprTypmod((Node *) linitial(cexpr->args));
470 5689 : if (typmod < 0)
471 5689 : return -1; /* no point in trying harder */
472 0 : for_each_from(arg, cexpr->args, 1)
473 : {
474 0 : Node *e = (Node *) lfirst(arg);
475 :
476 0 : if (exprType(e) != coalescetype)
477 0 : return -1;
478 0 : if (exprTypmod(e) != typmod)
479 0 : return -1;
480 : }
481 0 : return typmod;
482 : }
483 : break;
484 1898 : case T_MinMaxExpr:
485 : {
486 : /*
487 : * If all the alternatives agree on type/typmod, return that
488 : * typmod, else use -1
489 : */
490 1898 : const MinMaxExpr *mexpr = (const MinMaxExpr *) expr;
491 1898 : Oid minmaxtype = mexpr->minmaxtype;
492 : int32 typmod;
493 : ListCell *arg;
494 :
495 1898 : if (exprType((Node *) linitial(mexpr->args)) != minmaxtype)
496 0 : return -1;
497 1898 : typmod = exprTypmod((Node *) linitial(mexpr->args));
498 1898 : if (typmod < 0)
499 1898 : return -1; /* no point in trying harder */
500 0 : for_each_from(arg, mexpr->args, 1)
501 : {
502 0 : Node *e = (Node *) lfirst(arg);
503 :
504 0 : if (exprType(e) != minmaxtype)
505 0 : return -1;
506 0 : if (exprTypmod(e) != typmod)
507 0 : return -1;
508 : }
509 0 : return typmod;
510 : }
511 : break;
512 1676 : case T_SQLValueFunction:
513 1676 : return ((const SQLValueFunction *) expr)->typmod;
514 44 : case T_JsonValueExpr:
515 44 : return exprTypmod((Node *) ((const JsonValueExpr *) expr)->formatted_expr);
516 1862 : case T_JsonConstructorExpr:
517 1862 : return ((const JsonConstructorExpr *) expr)->returning->typmod;
518 2683 : case T_JsonExpr:
519 : {
520 2683 : const JsonExpr *jexpr = (const JsonExpr *) expr;
521 :
522 2683 : return jexpr->returning->typmod;
523 : }
524 : break;
525 0 : case T_JsonBehavior:
526 : {
527 0 : const JsonBehavior *behavior = (const JsonBehavior *) expr;
528 :
529 0 : return exprTypmod(behavior->expr);
530 : }
531 : break;
532 143099 : case T_CoerceToDomain:
533 143099 : return ((const CoerceToDomain *) expr)->resulttypmod;
534 52 : case T_CoerceToDomainValue:
535 52 : return ((const CoerceToDomainValue *) expr)->typeMod;
536 21241 : case T_SetToDefault:
537 21241 : return ((const SetToDefault *) expr)->typeMod;
538 352 : case T_ReturningExpr:
539 352 : return exprTypmod((Node *) ((const ReturningExpr *) expr)->retexpr);
540 9543 : case T_PlaceHolderVar:
541 9543 : return exprTypmod((Node *) ((const PlaceHolderVar *) expr)->phexpr);
542 1265 : case T_GraphPropertyRef:
543 1265 : return ((const GraphPropertyRef *) expr)->typmod;
544 329156 : default:
545 329156 : break;
546 : }
547 1184349 : return -1;
548 : }
549 :
550 : /*
551 : * exprIsLengthCoercion
552 : * Detect whether an expression tree is an application of a datatype's
553 : * typmod-coercion function. Optionally extract the result's typmod.
554 : *
555 : * If coercedTypmod is not NULL, the typmod is stored there if the expression
556 : * is a length-coercion function, else -1 is stored there.
557 : *
558 : * Note that a combined type-and-length coercion will be treated as a
559 : * length coercion by this routine.
560 : */
561 : bool
562 874422 : exprIsLengthCoercion(const Node *expr, int32 *coercedTypmod)
563 : {
564 874422 : if (coercedTypmod != NULL)
565 874422 : *coercedTypmod = -1; /* default result on failure */
566 :
567 : /*
568 : * Scalar-type length coercions are FuncExprs, array-type length coercions
569 : * are ArrayCoerceExprs
570 : */
571 874422 : if (expr && IsA(expr, FuncExpr))
572 : {
573 874422 : const FuncExpr *func = (const FuncExpr *) expr;
574 : int nargs;
575 : Const *second_arg;
576 :
577 : /*
578 : * If it didn't come from a coercion context, reject.
579 : */
580 874422 : if (func->funcformat != COERCE_EXPLICIT_CAST &&
581 849637 : func->funcformat != COERCE_IMPLICIT_CAST)
582 703601 : return false;
583 :
584 : /*
585 : * If it's not a two-argument or three-argument function with the
586 : * second argument being an int4 constant, it can't have been created
587 : * from a length coercion (it must be a type coercion, instead).
588 : */
589 170821 : nargs = list_length(func->args);
590 170821 : if (nargs < 2 || nargs > 3)
591 151046 : return false;
592 :
593 19775 : second_arg = (Const *) lsecond(func->args);
594 19775 : if (!IsA(second_arg, Const) ||
595 19775 : second_arg->consttype != INT4OID ||
596 19775 : second_arg->constisnull)
597 0 : return false;
598 :
599 : /*
600 : * OK, it is indeed a length-coercion function.
601 : */
602 19775 : if (coercedTypmod != NULL)
603 19775 : *coercedTypmod = DatumGetInt32(second_arg->constvalue);
604 :
605 19775 : return true;
606 : }
607 :
608 0 : if (expr && IsA(expr, ArrayCoerceExpr))
609 : {
610 0 : const ArrayCoerceExpr *acoerce = (const ArrayCoerceExpr *) expr;
611 :
612 : /* It's not a length coercion unless there's a nondefault typmod */
613 0 : if (acoerce->resulttypmod < 0)
614 0 : return false;
615 :
616 : /*
617 : * OK, it is indeed a length-coercion expression.
618 : */
619 0 : if (coercedTypmod != NULL)
620 0 : *coercedTypmod = acoerce->resulttypmod;
621 :
622 0 : return true;
623 : }
624 :
625 0 : return false;
626 : }
627 :
628 : /*
629 : * applyRelabelType
630 : * Add a RelabelType node if needed to make the expression expose
631 : * the specified type, typmod, and collation.
632 : *
633 : * This is primarily intended to be used during planning. Therefore, it must
634 : * maintain the post-eval_const_expressions invariants that there are not
635 : * adjacent RelabelTypes, and that the tree is fully const-folded (hence,
636 : * we mustn't return a RelabelType atop a Const). If we do find a Const,
637 : * we'll modify it in-place if "overwrite_ok" is true; that should only be
638 : * passed as true if caller knows the Const is newly generated.
639 : */
640 : Node *
641 224653 : applyRelabelType(Node *arg, Oid rtype, int32 rtypmod, Oid rcollid,
642 : CoercionForm rformat, int rlocation, bool overwrite_ok)
643 : {
644 : /*
645 : * If we find stacked RelabelTypes (eg, from foo::int::oid) we can discard
646 : * all but the top one, and must do so to ensure that semantically
647 : * equivalent expressions are equal().
648 : */
649 227571 : while (arg && IsA(arg, RelabelType))
650 2918 : arg = (Node *) ((RelabelType *) arg)->arg;
651 :
652 224653 : if (arg && IsA(arg, Const))
653 : {
654 : /* Modify the Const directly to preserve const-flatness. */
655 87457 : Const *con = (Const *) arg;
656 :
657 87457 : if (!overwrite_ok)
658 11557 : con = copyObject(con);
659 87457 : con->consttype = rtype;
660 87457 : con->consttypmod = rtypmod;
661 87457 : con->constcollid = rcollid;
662 : /* We keep the Const's original location. */
663 87457 : return (Node *) con;
664 : }
665 142905 : else if (exprType(arg) == rtype &&
666 11312 : exprTypmod(arg) == rtypmod &&
667 5603 : exprCollation(arg) == rcollid)
668 : {
669 : /* Sometimes we find a nest of relabels that net out to nothing. */
670 2762 : return arg;
671 : }
672 : else
673 : {
674 : /* Nope, gotta have a RelabelType. */
675 134434 : RelabelType *newrelabel = makeNode(RelabelType);
676 :
677 134434 : newrelabel->arg = (Expr *) arg;
678 134434 : newrelabel->resulttype = rtype;
679 134434 : newrelabel->resulttypmod = rtypmod;
680 134434 : newrelabel->resultcollid = rcollid;
681 134434 : newrelabel->relabelformat = rformat;
682 134434 : newrelabel->location = rlocation;
683 134434 : return (Node *) newrelabel;
684 : }
685 : }
686 :
687 : /*
688 : * relabel_to_typmod
689 : * Add a RelabelType node that changes just the typmod of the expression.
690 : *
691 : * Convenience function for a common usage of applyRelabelType.
692 : */
693 : Node *
694 24 : relabel_to_typmod(Node *expr, int32 typmod)
695 : {
696 24 : return applyRelabelType(expr, exprType(expr), typmod, exprCollation(expr),
697 : COERCE_EXPLICIT_CAST, -1, false);
698 : }
699 :
700 : /*
701 : * strip_implicit_coercions: remove implicit coercions at top level of tree
702 : *
703 : * This doesn't modify or copy the input expression tree, just return a
704 : * pointer to a suitable place within it.
705 : *
706 : * Note: there isn't any useful thing we can do with a RowExpr here, so
707 : * just return it unchanged, even if it's marked as an implicit coercion.
708 : */
709 : Node *
710 708698 : strip_implicit_coercions(Node *node)
711 : {
712 708698 : if (node == NULL)
713 0 : return NULL;
714 708698 : if (IsA(node, FuncExpr))
715 : {
716 9730 : FuncExpr *f = (FuncExpr *) node;
717 :
718 9730 : if (f->funcformat == COERCE_IMPLICIT_CAST)
719 36 : return strip_implicit_coercions(linitial(f->args));
720 : }
721 698968 : else if (IsA(node, RelabelType))
722 : {
723 8049 : RelabelType *r = (RelabelType *) node;
724 :
725 8049 : if (r->relabelformat == COERCE_IMPLICIT_CAST)
726 9 : return strip_implicit_coercions((Node *) r->arg);
727 : }
728 690919 : else if (IsA(node, CoerceViaIO))
729 : {
730 409 : CoerceViaIO *c = (CoerceViaIO *) node;
731 :
732 409 : if (c->coerceformat == COERCE_IMPLICIT_CAST)
733 0 : return strip_implicit_coercions((Node *) c->arg);
734 : }
735 690510 : else if (IsA(node, ArrayCoerceExpr))
736 : {
737 0 : ArrayCoerceExpr *c = (ArrayCoerceExpr *) node;
738 :
739 0 : if (c->coerceformat == COERCE_IMPLICIT_CAST)
740 0 : return strip_implicit_coercions((Node *) c->arg);
741 : }
742 690510 : else if (IsA(node, ConvertRowtypeExpr))
743 : {
744 0 : ConvertRowtypeExpr *c = (ConvertRowtypeExpr *) node;
745 :
746 0 : if (c->convertformat == COERCE_IMPLICIT_CAST)
747 0 : return strip_implicit_coercions((Node *) c->arg);
748 : }
749 690510 : else if (IsA(node, CoerceToDomain))
750 : {
751 5115 : CoerceToDomain *c = (CoerceToDomain *) node;
752 :
753 5115 : if (c->coercionformat == COERCE_IMPLICIT_CAST)
754 0 : return strip_implicit_coercions((Node *) c->arg);
755 : }
756 708653 : return node;
757 : }
758 :
759 : /*
760 : * expression_returns_set
761 : * Test whether an expression returns a set result.
762 : *
763 : * Because we use expression_tree_walker(), this can also be applied to
764 : * whole targetlists; it'll produce true if any one of the tlist items
765 : * returns a set.
766 : */
767 : bool
768 598444 : expression_returns_set(Node *clause)
769 : {
770 598444 : return expression_returns_set_walker(clause, NULL);
771 : }
772 :
773 : static bool
774 2586465 : expression_returns_set_walker(Node *node, void *context)
775 : {
776 2586465 : if (node == NULL)
777 31066 : return false;
778 2555399 : if (IsA(node, FuncExpr))
779 : {
780 84099 : FuncExpr *expr = (FuncExpr *) node;
781 :
782 84099 : if (expr->funcretset)
783 12016 : return true;
784 : /* else fall through to check args */
785 : }
786 2543383 : if (IsA(node, OpExpr))
787 : {
788 574156 : OpExpr *expr = (OpExpr *) node;
789 :
790 574156 : if (expr->opretset)
791 5 : return true;
792 : /* else fall through to check args */
793 : }
794 :
795 : /*
796 : * If you add any more cases that return sets, also fix
797 : * expression_returns_set_rows() in clauses.c and IS_SRF_CALL() in
798 : * tlist.c.
799 : */
800 :
801 : /* Avoid recursion for some cases that parser checks not to return a set */
802 2543378 : if (IsA(node, Aggref))
803 795 : return false;
804 2542583 : if (IsA(node, GroupingFunc))
805 40 : return false;
806 2542543 : if (IsA(node, WindowFunc))
807 24 : return false;
808 :
809 2542519 : return expression_tree_walker(node, expression_returns_set_walker,
810 : context);
811 : }
812 :
813 :
814 : /*
815 : * exprCollation -
816 : * returns the Oid of the collation of the expression's result.
817 : *
818 : * Note: expression nodes that can invoke functions generally have an
819 : * "inputcollid" field, which is what the function should use as collation.
820 : * That is the resolved common collation of the node's inputs. It is often
821 : * but not always the same as the result collation; in particular, if the
822 : * function produces a non-collatable result type from collatable inputs
823 : * or vice versa, the two are different.
824 : */
825 : Oid
826 10017630 : exprCollation(const Node *expr)
827 : {
828 : Oid coll;
829 :
830 10017630 : if (!expr)
831 0 : return InvalidOid;
832 :
833 10017630 : switch (nodeTag(expr))
834 : {
835 7771737 : case T_Var:
836 7771737 : coll = ((const Var *) expr)->varcollid;
837 7771737 : break;
838 1288085 : case T_Const:
839 1288085 : coll = ((const Const *) expr)->constcollid;
840 1288085 : break;
841 122654 : case T_Param:
842 122654 : coll = ((const Param *) expr)->paramcollid;
843 122654 : break;
844 65489 : case T_Aggref:
845 65489 : coll = ((const Aggref *) expr)->aggcollid;
846 65489 : break;
847 555 : case T_GroupingFunc:
848 555 : coll = InvalidOid;
849 555 : break;
850 3960 : case T_WindowFunc:
851 3960 : coll = ((const WindowFunc *) expr)->wincollid;
852 3960 : break;
853 241 : case T_MergeSupportFunc:
854 241 : coll = ((const MergeSupportFunc *) expr)->msfcollid;
855 241 : break;
856 6857 : case T_SubscriptingRef:
857 6857 : coll = ((const SubscriptingRef *) expr)->refcollid;
858 6857 : break;
859 277245 : case T_FuncExpr:
860 277245 : coll = ((const FuncExpr *) expr)->funccollid;
861 277245 : break;
862 0 : case T_NamedArgExpr:
863 0 : coll = exprCollation((Node *) ((const NamedArgExpr *) expr)->arg);
864 0 : break;
865 79612 : case T_OpExpr:
866 79612 : coll = ((const OpExpr *) expr)->opcollid;
867 79612 : break;
868 52 : case T_DistinctExpr:
869 52 : coll = ((const DistinctExpr *) expr)->opcollid;
870 52 : break;
871 173 : case T_NullIfExpr:
872 173 : coll = ((const NullIfExpr *) expr)->opcollid;
873 173 : break;
874 14996 : case T_ScalarArrayOpExpr:
875 : /* ScalarArrayOpExpr's result is boolean ... */
876 14996 : coll = InvalidOid; /* ... so it has no collation */
877 14996 : break;
878 2823 : case T_BoolExpr:
879 : /* BoolExpr's result is boolean ... */
880 2823 : coll = InvalidOid; /* ... so it has no collation */
881 2823 : break;
882 2400 : case T_SubLink:
883 : {
884 2400 : const SubLink *sublink = (const SubLink *) expr;
885 :
886 2400 : if (sublink->subLinkType == EXPR_SUBLINK ||
887 178 : sublink->subLinkType == ARRAY_SUBLINK)
888 2351 : {
889 : /* get the collation of subselect's first target column */
890 2351 : Query *qtree = (Query *) sublink->subselect;
891 : TargetEntry *tent;
892 :
893 2351 : if (!qtree || !IsA(qtree, Query))
894 0 : elog(ERROR, "cannot get collation for untransformed sublink");
895 2351 : tent = linitial_node(TargetEntry, qtree->targetList);
896 : Assert(!tent->resjunk);
897 2351 : coll = exprCollation((Node *) tent->expr);
898 : /* collation doesn't change if it's converted to array */
899 : }
900 : else
901 : {
902 : /* otherwise, SubLink's result is RECORD or BOOLEAN */
903 49 : coll = InvalidOid; /* ... so it has no collation */
904 : }
905 : }
906 2400 : break;
907 14767 : case T_SubPlan:
908 : {
909 14767 : const SubPlan *subplan = (const SubPlan *) expr;
910 :
911 14767 : if (subplan->subLinkType == EXPR_SUBLINK ||
912 207 : subplan->subLinkType == ARRAY_SUBLINK)
913 : {
914 : /* get the collation of subselect's first target column */
915 14624 : coll = subplan->firstColCollation;
916 : /* collation doesn't change if it's converted to array */
917 : }
918 : else
919 : {
920 : /* otherwise, SubPlan's result is RECORD or BOOLEAN */
921 143 : coll = InvalidOid; /* ... so it has no collation */
922 : }
923 : }
924 14767 : break;
925 0 : case T_AlternativeSubPlan:
926 : {
927 0 : const AlternativeSubPlan *asplan = (const AlternativeSubPlan *) expr;
928 :
929 : /* subplans should all return the same thing */
930 0 : coll = exprCollation((Node *) linitial(asplan->subplans));
931 : }
932 0 : break;
933 8611 : case T_FieldSelect:
934 8611 : coll = ((const FieldSelect *) expr)->resultcollid;
935 8611 : break;
936 42 : case T_FieldStore:
937 : /* FieldStore's result is composite ... */
938 42 : coll = InvalidOid; /* ... so it has no collation */
939 42 : break;
940 87926 : case T_RelabelType:
941 87926 : coll = ((const RelabelType *) expr)->resultcollid;
942 87926 : break;
943 31240 : case T_CoerceViaIO:
944 31240 : coll = ((const CoerceViaIO *) expr)->resultcollid;
945 31240 : break;
946 1245 : case T_ArrayCoerceExpr:
947 1245 : coll = ((const ArrayCoerceExpr *) expr)->resultcollid;
948 1245 : break;
949 348 : case T_ConvertRowtypeExpr:
950 : /* ConvertRowtypeExpr's result is composite ... */
951 348 : coll = InvalidOid; /* ... so it has no collation */
952 348 : break;
953 161 : case T_CollateExpr:
954 161 : coll = ((const CollateExpr *) expr)->collOid;
955 161 : break;
956 97808 : case T_CaseExpr:
957 97808 : coll = ((const CaseExpr *) expr)->casecollid;
958 97808 : break;
959 24300 : case T_CaseTestExpr:
960 24300 : coll = ((const CaseTestExpr *) expr)->collation;
961 24300 : break;
962 21839 : case T_ArrayExpr:
963 21839 : coll = ((const ArrayExpr *) expr)->array_collid;
964 21839 : break;
965 3798 : case T_RowExpr:
966 : /* RowExpr's result is composite ... */
967 3798 : coll = InvalidOid; /* ... so it has no collation */
968 3798 : break;
969 44 : case T_RowCompareExpr:
970 : /* RowCompareExpr's result is boolean ... */
971 44 : coll = InvalidOid; /* ... so it has no collation */
972 44 : break;
973 2678 : case T_CoalesceExpr:
974 2678 : coll = ((const CoalesceExpr *) expr)->coalescecollid;
975 2678 : break;
976 1708 : case T_MinMaxExpr:
977 1708 : coll = ((const MinMaxExpr *) expr)->minmaxcollid;
978 1708 : break;
979 1118 : case T_SQLValueFunction:
980 : /* Returns either NAME or a non-collatable type */
981 1118 : if (((const SQLValueFunction *) expr)->type == NAMEOID)
982 1015 : coll = C_COLLATION_OID;
983 : else
984 103 : coll = InvalidOid;
985 1118 : break;
986 449 : case T_XmlExpr:
987 :
988 : /*
989 : * XMLSERIALIZE returns text from non-collatable inputs, so its
990 : * collation is always default. The other cases return boolean or
991 : * XML, which are non-collatable.
992 : */
993 449 : if (((const XmlExpr *) expr)->op == IS_XMLSERIALIZE)
994 110 : coll = DEFAULT_COLLATION_OID;
995 : else
996 339 : coll = InvalidOid;
997 449 : break;
998 8 : case T_JsonValueExpr:
999 8 : coll = exprCollation((Node *) ((const JsonValueExpr *) expr)->formatted_expr);
1000 8 : break;
1001 998 : case T_JsonConstructorExpr:
1002 : {
1003 998 : const JsonConstructorExpr *ctor = (const JsonConstructorExpr *) expr;
1004 :
1005 998 : if (ctor->coercion)
1006 152 : coll = exprCollation((Node *) ctor->coercion);
1007 : else
1008 846 : coll = InvalidOid;
1009 : }
1010 998 : break;
1011 222 : case T_JsonIsPredicate:
1012 : /* IS JSON's result is boolean ... */
1013 222 : coll = InvalidOid; /* ... so it has no collation */
1014 222 : break;
1015 1652 : case T_JsonExpr:
1016 : {
1017 1652 : const JsonExpr *jsexpr = (const JsonExpr *) expr;
1018 :
1019 1652 : coll = jsexpr->collation;
1020 : }
1021 1652 : break;
1022 0 : case T_JsonBehavior:
1023 : {
1024 0 : const JsonBehavior *behavior = (const JsonBehavior *) expr;
1025 :
1026 0 : if (behavior->expr)
1027 0 : coll = exprCollation(behavior->expr);
1028 : else
1029 0 : coll = InvalidOid;
1030 : }
1031 0 : break;
1032 1416 : case T_NullTest:
1033 : /* NullTest's result is boolean ... */
1034 1416 : coll = InvalidOid; /* ... so it has no collation */
1035 1416 : break;
1036 338 : case T_BooleanTest:
1037 : /* BooleanTest's result is boolean ... */
1038 338 : coll = InvalidOid; /* ... so it has no collation */
1039 338 : break;
1040 45805 : case T_CoerceToDomain:
1041 45805 : coll = ((const CoerceToDomain *) expr)->resultcollid;
1042 45805 : break;
1043 557 : case T_CoerceToDomainValue:
1044 557 : coll = ((const CoerceToDomainValue *) expr)->collation;
1045 557 : break;
1046 20999 : case T_SetToDefault:
1047 20999 : coll = ((const SetToDefault *) expr)->collation;
1048 20999 : break;
1049 168 : case T_CurrentOfExpr:
1050 : /* CurrentOfExpr's result is boolean ... */
1051 168 : coll = InvalidOid; /* ... so it has no collation */
1052 168 : break;
1053 374 : case T_NextValueExpr:
1054 : /* NextValueExpr's result is an integer type ... */
1055 374 : coll = InvalidOid; /* ... so it has no collation */
1056 374 : break;
1057 0 : case T_InferenceElem:
1058 0 : coll = exprCollation((Node *) ((const InferenceElem *) expr)->expr);
1059 0 : break;
1060 352 : case T_ReturningExpr:
1061 352 : coll = exprCollation((Node *) ((const ReturningExpr *) expr)->retexpr);
1062 352 : break;
1063 8165 : case T_PlaceHolderVar:
1064 8165 : coll = exprCollation((Node *) ((const PlaceHolderVar *) expr)->phexpr);
1065 8165 : break;
1066 1615 : case T_GraphPropertyRef:
1067 1615 : coll = ((const GraphPropertyRef *) expr)->collation;
1068 1615 : break;
1069 0 : default:
1070 0 : elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
1071 : coll = InvalidOid; /* keep compiler quiet */
1072 : break;
1073 : }
1074 10017630 : return coll;
1075 : }
1076 :
1077 : /*
1078 : * exprInputCollation -
1079 : * returns the Oid of the collation a function should use, if available.
1080 : *
1081 : * Result is InvalidOid if the node type doesn't store this information.
1082 : */
1083 : Oid
1084 935 : exprInputCollation(const Node *expr)
1085 : {
1086 : Oid coll;
1087 :
1088 935 : if (!expr)
1089 0 : return InvalidOid;
1090 :
1091 935 : switch (nodeTag(expr))
1092 : {
1093 0 : case T_Aggref:
1094 0 : coll = ((const Aggref *) expr)->inputcollid;
1095 0 : break;
1096 0 : case T_WindowFunc:
1097 0 : coll = ((const WindowFunc *) expr)->inputcollid;
1098 0 : break;
1099 65 : case T_FuncExpr:
1100 65 : coll = ((const FuncExpr *) expr)->inputcollid;
1101 65 : break;
1102 241 : case T_OpExpr:
1103 241 : coll = ((const OpExpr *) expr)->inputcollid;
1104 241 : break;
1105 4 : case T_DistinctExpr:
1106 4 : coll = ((const DistinctExpr *) expr)->inputcollid;
1107 4 : break;
1108 8 : case T_NullIfExpr:
1109 8 : coll = ((const NullIfExpr *) expr)->inputcollid;
1110 8 : break;
1111 4 : case T_ScalarArrayOpExpr:
1112 4 : coll = ((const ScalarArrayOpExpr *) expr)->inputcollid;
1113 4 : break;
1114 4 : case T_MinMaxExpr:
1115 4 : coll = ((const MinMaxExpr *) expr)->inputcollid;
1116 4 : break;
1117 609 : default:
1118 609 : coll = InvalidOid;
1119 609 : break;
1120 : }
1121 935 : return coll;
1122 : }
1123 :
1124 : /*
1125 : * exprSetCollation -
1126 : * Assign collation information to an expression tree node.
1127 : *
1128 : * Note: since this is only used during parse analysis, we don't need to
1129 : * worry about subplans, PlaceHolderVars, or ReturningExprs.
1130 : */
1131 : void
1132 1211733 : exprSetCollation(Node *expr, Oid collation)
1133 : {
1134 1211733 : switch (nodeTag(expr))
1135 : {
1136 0 : case T_Var:
1137 0 : ((Var *) expr)->varcollid = collation;
1138 0 : break;
1139 0 : case T_Const:
1140 0 : ((Const *) expr)->constcollid = collation;
1141 0 : break;
1142 0 : case T_Param:
1143 0 : ((Param *) expr)->paramcollid = collation;
1144 0 : break;
1145 31026 : case T_Aggref:
1146 31026 : ((Aggref *) expr)->aggcollid = collation;
1147 31026 : break;
1148 252 : case T_GroupingFunc:
1149 : Assert(!OidIsValid(collation));
1150 252 : break;
1151 2592 : case T_WindowFunc:
1152 2592 : ((WindowFunc *) expr)->wincollid = collation;
1153 2592 : break;
1154 146 : case T_MergeSupportFunc:
1155 146 : ((MergeSupportFunc *) expr)->msfcollid = collation;
1156 146 : break;
1157 8909 : case T_SubscriptingRef:
1158 8909 : ((SubscriptingRef *) expr)->refcollid = collation;
1159 8909 : break;
1160 287288 : case T_FuncExpr:
1161 287288 : ((FuncExpr *) expr)->funccollid = collation;
1162 287288 : break;
1163 26608 : case T_NamedArgExpr:
1164 : Assert(collation == exprCollation((Node *) ((NamedArgExpr *) expr)->arg));
1165 26608 : break;
1166 414962 : case T_OpExpr:
1167 414962 : ((OpExpr *) expr)->opcollid = collation;
1168 414962 : break;
1169 857 : case T_DistinctExpr:
1170 857 : ((DistinctExpr *) expr)->opcollid = collation;
1171 857 : break;
1172 467 : case T_NullIfExpr:
1173 467 : ((NullIfExpr *) expr)->opcollid = collation;
1174 467 : break;
1175 23075 : case T_ScalarArrayOpExpr:
1176 : /* ScalarArrayOpExpr's result is boolean ... */
1177 : Assert(!OidIsValid(collation)); /* ... so never set a collation */
1178 23075 : break;
1179 117202 : case T_BoolExpr:
1180 : /* BoolExpr's result is boolean ... */
1181 : Assert(!OidIsValid(collation)); /* ... so never set a collation */
1182 117202 : break;
1183 35817 : case T_SubLink:
1184 : #ifdef USE_ASSERT_CHECKING
1185 : {
1186 : SubLink *sublink = (SubLink *) expr;
1187 :
1188 : if (sublink->subLinkType == EXPR_SUBLINK ||
1189 : sublink->subLinkType == ARRAY_SUBLINK)
1190 : {
1191 : /* get the collation of subselect's first target column */
1192 : Query *qtree = (Query *) sublink->subselect;
1193 : TargetEntry *tent;
1194 :
1195 : if (!qtree || !IsA(qtree, Query))
1196 : elog(ERROR, "cannot set collation for untransformed sublink");
1197 : tent = linitial_node(TargetEntry, qtree->targetList);
1198 : Assert(!tent->resjunk);
1199 : Assert(collation == exprCollation((Node *) tent->expr));
1200 : }
1201 : else
1202 : {
1203 : /* otherwise, result is RECORD or BOOLEAN */
1204 : Assert(!OidIsValid(collation));
1205 : }
1206 : }
1207 : #endif /* USE_ASSERT_CHECKING */
1208 35817 : break;
1209 0 : case T_FieldSelect:
1210 0 : ((FieldSelect *) expr)->resultcollid = collation;
1211 0 : break;
1212 401 : case T_FieldStore:
1213 : /* FieldStore's result is composite ... */
1214 : Assert(!OidIsValid(collation)); /* ... so never set a collation */
1215 401 : break;
1216 106959 : case T_RelabelType:
1217 106959 : ((RelabelType *) expr)->resultcollid = collation;
1218 106959 : break;
1219 17789 : case T_CoerceViaIO:
1220 17789 : ((CoerceViaIO *) expr)->resultcollid = collation;
1221 17789 : break;
1222 3761 : case T_ArrayCoerceExpr:
1223 3761 : ((ArrayCoerceExpr *) expr)->resultcollid = collation;
1224 3761 : break;
1225 40 : case T_ConvertRowtypeExpr:
1226 : /* ConvertRowtypeExpr's result is composite ... */
1227 : Assert(!OidIsValid(collation)); /* ... so never set a collation */
1228 40 : break;
1229 30440 : case T_CaseExpr:
1230 30440 : ((CaseExpr *) expr)->casecollid = collation;
1231 30440 : break;
1232 18490 : case T_ArrayExpr:
1233 18490 : ((ArrayExpr *) expr)->array_collid = collation;
1234 18490 : break;
1235 0 : case T_RowExpr:
1236 : /* RowExpr's result is composite ... */
1237 : Assert(!OidIsValid(collation)); /* ... so never set a collation */
1238 0 : break;
1239 0 : case T_RowCompareExpr:
1240 : /* RowCompareExpr's result is boolean ... */
1241 : Assert(!OidIsValid(collation)); /* ... so never set a collation */
1242 0 : break;
1243 4199 : case T_CoalesceExpr:
1244 4199 : ((CoalesceExpr *) expr)->coalescecollid = collation;
1245 4199 : break;
1246 227 : case T_MinMaxExpr:
1247 227 : ((MinMaxExpr *) expr)->minmaxcollid = collation;
1248 227 : break;
1249 1806 : case T_SQLValueFunction:
1250 : Assert((((SQLValueFunction *) expr)->type == NAMEOID) ?
1251 : (collation == C_COLLATION_OID) :
1252 : (collation == InvalidOid));
1253 1806 : break;
1254 519 : case T_XmlExpr:
1255 : Assert((((XmlExpr *) expr)->op == IS_XMLSERIALIZE) ?
1256 : (collation == DEFAULT_COLLATION_OID) :
1257 : (collation == InvalidOid));
1258 519 : break;
1259 466 : case T_JsonValueExpr:
1260 466 : exprSetCollation((Node *) ((JsonValueExpr *) expr)->formatted_expr,
1261 : collation);
1262 466 : break;
1263 1018 : case T_JsonConstructorExpr:
1264 : {
1265 1018 : JsonConstructorExpr *ctor = (JsonConstructorExpr *) expr;
1266 :
1267 1018 : if (ctor->coercion)
1268 252 : exprSetCollation((Node *) ctor->coercion, collation);
1269 : else
1270 : Assert(!OidIsValid(collation)); /* result is always a
1271 : * json[b] type */
1272 : }
1273 1018 : break;
1274 260 : case T_JsonIsPredicate:
1275 : Assert(!OidIsValid(collation)); /* result is always boolean */
1276 260 : break;
1277 1700 : case T_JsonExpr:
1278 : {
1279 1700 : JsonExpr *jexpr = (JsonExpr *) expr;
1280 :
1281 1700 : jexpr->collation = collation;
1282 : }
1283 1700 : break;
1284 3204 : case T_JsonBehavior:
1285 : Assert(((JsonBehavior *) expr)->expr == NULL ||
1286 : exprCollation(((JsonBehavior *) expr)->expr) == collation);
1287 3204 : break;
1288 14333 : case T_NullTest:
1289 : /* NullTest's result is boolean ... */
1290 : Assert(!OidIsValid(collation)); /* ... so never set a collation */
1291 14333 : break;
1292 733 : case T_BooleanTest:
1293 : /* BooleanTest's result is boolean ... */
1294 : Assert(!OidIsValid(collation)); /* ... so never set a collation */
1295 733 : break;
1296 56187 : case T_CoerceToDomain:
1297 56187 : ((CoerceToDomain *) expr)->resultcollid = collation;
1298 56187 : break;
1299 0 : case T_CoerceToDomainValue:
1300 0 : ((CoerceToDomainValue *) expr)->collation = collation;
1301 0 : break;
1302 0 : case T_SetToDefault:
1303 0 : ((SetToDefault *) expr)->collation = collation;
1304 0 : break;
1305 0 : case T_CurrentOfExpr:
1306 : /* CurrentOfExpr's result is boolean ... */
1307 : Assert(!OidIsValid(collation)); /* ... so never set a collation */
1308 0 : break;
1309 0 : case T_NextValueExpr:
1310 : /* NextValueExpr's result is an integer type ... */
1311 : Assert(!OidIsValid(collation)); /* ... so never set a collation */
1312 0 : break;
1313 0 : default:
1314 0 : elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
1315 : break;
1316 : }
1317 1211733 : }
1318 :
1319 : /*
1320 : * exprSetInputCollation -
1321 : * Assign input-collation information to an expression tree node.
1322 : *
1323 : * This is a no-op for node types that don't store their input collation.
1324 : * Note we omit RowCompareExpr, which needs special treatment since it
1325 : * contains multiple input collation OIDs.
1326 : */
1327 : void
1328 1154836 : exprSetInputCollation(Node *expr, Oid inputcollation)
1329 : {
1330 1154836 : switch (nodeTag(expr))
1331 : {
1332 31026 : case T_Aggref:
1333 31026 : ((Aggref *) expr)->inputcollid = inputcollation;
1334 31026 : break;
1335 2592 : case T_WindowFunc:
1336 2592 : ((WindowFunc *) expr)->inputcollid = inputcollation;
1337 2592 : break;
1338 287160 : case T_FuncExpr:
1339 287160 : ((FuncExpr *) expr)->inputcollid = inputcollation;
1340 287160 : break;
1341 414962 : case T_OpExpr:
1342 414962 : ((OpExpr *) expr)->inputcollid = inputcollation;
1343 414962 : break;
1344 857 : case T_DistinctExpr:
1345 857 : ((DistinctExpr *) expr)->inputcollid = inputcollation;
1346 857 : break;
1347 467 : case T_NullIfExpr:
1348 467 : ((NullIfExpr *) expr)->inputcollid = inputcollation;
1349 467 : break;
1350 23075 : case T_ScalarArrayOpExpr:
1351 23075 : ((ScalarArrayOpExpr *) expr)->inputcollid = inputcollation;
1352 23075 : break;
1353 227 : case T_MinMaxExpr:
1354 227 : ((MinMaxExpr *) expr)->inputcollid = inputcollation;
1355 227 : break;
1356 394470 : default:
1357 394470 : break;
1358 : }
1359 1154836 : }
1360 :
1361 :
1362 : /*
1363 : * exprLocation -
1364 : * returns the parse location of an expression tree, for error reports
1365 : *
1366 : * -1 is returned if the location can't be determined.
1367 : *
1368 : * For expressions larger than a single token, the intent here is to
1369 : * return the location of the expression's leftmost token, not necessarily
1370 : * the topmost Node's location field. For example, an OpExpr's location
1371 : * field will point at the operator name, but if it is not a prefix operator
1372 : * then we should return the location of the left-hand operand instead.
1373 : * The reason is that we want to reference the entire expression not just
1374 : * that operator, and pointing to its start seems to be the most natural way.
1375 : *
1376 : * The location is not perfect --- for example, since the grammar doesn't
1377 : * explicitly represent parentheses in the parsetree, given something that
1378 : * had been written "(a + b) * c" we are going to point at "a" not "(".
1379 : * But it should be plenty good enough for error reporting purposes.
1380 : *
1381 : * You might think that this code is overly general, for instance why check
1382 : * the operands of a FuncExpr node, when the function name can be expected
1383 : * to be to the left of them? There are a couple of reasons. The grammar
1384 : * sometimes builds expressions that aren't quite what the user wrote;
1385 : * for instance x IS NOT BETWEEN ... becomes a NOT-expression whose keyword
1386 : * pointer is to the right of its leftmost argument. Also, nodes that were
1387 : * inserted implicitly by parse analysis (such as FuncExprs for implicit
1388 : * coercions) will have location -1, and so we can have odd combinations of
1389 : * known and unknown locations in a tree.
1390 : */
1391 : int
1392 2956736 : exprLocation(const Node *expr)
1393 : {
1394 : int loc;
1395 :
1396 2956736 : if (expr == NULL)
1397 17936 : return -1;
1398 2938800 : switch (nodeTag(expr))
1399 : {
1400 20 : case T_RangeVar:
1401 20 : loc = ((const RangeVar *) expr)->location;
1402 20 : break;
1403 0 : case T_TableFunc:
1404 0 : loc = ((const TableFunc *) expr)->location;
1405 0 : break;
1406 1542381 : case T_Var:
1407 1542381 : loc = ((const Var *) expr)->location;
1408 1542381 : break;
1409 898812 : case T_Const:
1410 898812 : loc = ((const Const *) expr)->location;
1411 898812 : break;
1412 68172 : case T_Param:
1413 68172 : loc = ((const Param *) expr)->location;
1414 68172 : break;
1415 6730 : case T_Aggref:
1416 : /* function name should always be the first thing */
1417 6730 : loc = ((const Aggref *) expr)->location;
1418 6730 : break;
1419 50 : case T_GroupingFunc:
1420 50 : loc = ((const GroupingFunc *) expr)->location;
1421 50 : break;
1422 36 : case T_WindowFunc:
1423 : /* function name should always be the first thing */
1424 36 : loc = ((const WindowFunc *) expr)->location;
1425 36 : break;
1426 146 : case T_MergeSupportFunc:
1427 146 : loc = ((const MergeSupportFunc *) expr)->location;
1428 146 : break;
1429 196 : case T_SubscriptingRef:
1430 : /* just use container argument's location */
1431 196 : loc = exprLocation((Node *) ((const SubscriptingRef *) expr)->refexpr);
1432 196 : break;
1433 68510 : case T_FuncExpr:
1434 : {
1435 68510 : const FuncExpr *fexpr = (const FuncExpr *) expr;
1436 :
1437 : /* consider both function name and leftmost arg */
1438 68510 : loc = leftmostLoc(fexpr->location,
1439 68510 : exprLocation((Node *) fexpr->args));
1440 : }
1441 68510 : break;
1442 4 : case T_NamedArgExpr:
1443 : {
1444 4 : const NamedArgExpr *na = (const NamedArgExpr *) expr;
1445 :
1446 : /* consider both argument name and value */
1447 4 : loc = leftmostLoc(na->location,
1448 4 : exprLocation((Node *) na->arg));
1449 : }
1450 4 : break;
1451 8703 : case T_OpExpr:
1452 : case T_DistinctExpr: /* struct-equivalent to OpExpr */
1453 : case T_NullIfExpr: /* struct-equivalent to OpExpr */
1454 : {
1455 8703 : const OpExpr *opexpr = (const OpExpr *) expr;
1456 :
1457 : /* consider both operator name and leftmost arg */
1458 8703 : loc = leftmostLoc(opexpr->location,
1459 8703 : exprLocation((Node *) opexpr->args));
1460 : }
1461 8703 : break;
1462 0 : case T_ScalarArrayOpExpr:
1463 : {
1464 0 : const ScalarArrayOpExpr *saopexpr = (const ScalarArrayOpExpr *) expr;
1465 :
1466 : /* consider both operator name and leftmost arg */
1467 0 : loc = leftmostLoc(saopexpr->location,
1468 0 : exprLocation((Node *) saopexpr->args));
1469 : }
1470 0 : break;
1471 89 : case T_BoolExpr:
1472 : {
1473 89 : const BoolExpr *bexpr = (const BoolExpr *) expr;
1474 :
1475 : /*
1476 : * Same as above, to handle either NOT or AND/OR. We can't
1477 : * special-case NOT because of the way that it's used for
1478 : * things like IS NOT BETWEEN.
1479 : */
1480 89 : loc = leftmostLoc(bexpr->location,
1481 89 : exprLocation((Node *) bexpr->args));
1482 : }
1483 89 : break;
1484 756 : case T_SubLink:
1485 : {
1486 756 : const SubLink *sublink = (const SubLink *) expr;
1487 :
1488 : /* check the testexpr, if any, and the operator/keyword */
1489 756 : loc = leftmostLoc(exprLocation(sublink->testexpr),
1490 756 : sublink->location);
1491 : }
1492 756 : break;
1493 2684 : case T_FieldSelect:
1494 : /* just use argument's location */
1495 2684 : loc = exprLocation((Node *) ((const FieldSelect *) expr)->arg);
1496 2684 : break;
1497 0 : case T_FieldStore:
1498 : /* just use argument's location */
1499 0 : loc = exprLocation((Node *) ((const FieldStore *) expr)->arg);
1500 0 : break;
1501 9647 : case T_RelabelType:
1502 : {
1503 9647 : const RelabelType *rexpr = (const RelabelType *) expr;
1504 :
1505 : /* Much as above */
1506 9647 : loc = leftmostLoc(rexpr->location,
1507 9647 : exprLocation((Node *) rexpr->arg));
1508 : }
1509 9647 : break;
1510 16302 : case T_CoerceViaIO:
1511 : {
1512 16302 : const CoerceViaIO *cexpr = (const CoerceViaIO *) expr;
1513 :
1514 : /* Much as above */
1515 16302 : loc = leftmostLoc(cexpr->location,
1516 16302 : exprLocation((Node *) cexpr->arg));
1517 : }
1518 16302 : break;
1519 6 : case T_ArrayCoerceExpr:
1520 : {
1521 6 : const ArrayCoerceExpr *cexpr = (const ArrayCoerceExpr *) expr;
1522 :
1523 : /* Much as above */
1524 6 : loc = leftmostLoc(cexpr->location,
1525 6 : exprLocation((Node *) cexpr->arg));
1526 : }
1527 6 : break;
1528 8 : case T_ConvertRowtypeExpr:
1529 : {
1530 8 : const ConvertRowtypeExpr *cexpr = (const ConvertRowtypeExpr *) expr;
1531 :
1532 : /* Much as above */
1533 8 : loc = leftmostLoc(cexpr->location,
1534 8 : exprLocation((Node *) cexpr->arg));
1535 : }
1536 8 : break;
1537 80 : case T_CollateExpr:
1538 : /* just use argument's location */
1539 80 : loc = exprLocation((Node *) ((const CollateExpr *) expr)->arg);
1540 80 : break;
1541 7179 : case T_CaseExpr:
1542 : /* CASE keyword should always be the first thing */
1543 7179 : loc = ((const CaseExpr *) expr)->location;
1544 7179 : break;
1545 0 : case T_CaseWhen:
1546 : /* WHEN keyword should always be the first thing */
1547 0 : loc = ((const CaseWhen *) expr)->location;
1548 0 : break;
1549 278 : case T_ArrayExpr:
1550 : /* the location points at ARRAY or [, which must be leftmost */
1551 278 : loc = ((const ArrayExpr *) expr)->location;
1552 278 : break;
1553 233 : case T_RowExpr:
1554 : /* the location points at ROW or (, which must be leftmost */
1555 233 : loc = ((const RowExpr *) expr)->location;
1556 233 : break;
1557 0 : case T_RowCompareExpr:
1558 : /* just use leftmost argument's location */
1559 0 : loc = exprLocation((Node *) ((const RowCompareExpr *) expr)->largs);
1560 0 : break;
1561 1505 : case T_CoalesceExpr:
1562 : /* COALESCE keyword should always be the first thing */
1563 1505 : loc = ((const CoalesceExpr *) expr)->location;
1564 1505 : break;
1565 19 : case T_MinMaxExpr:
1566 : /* GREATEST/LEAST keyword should always be the first thing */
1567 19 : loc = ((const MinMaxExpr *) expr)->location;
1568 19 : break;
1569 1137 : case T_SQLValueFunction:
1570 : /* function keyword should always be the first thing */
1571 1137 : loc = ((const SQLValueFunction *) expr)->location;
1572 1137 : break;
1573 144 : case T_XmlExpr:
1574 : {
1575 144 : const XmlExpr *xexpr = (const XmlExpr *) expr;
1576 :
1577 : /* consider both function name and leftmost arg */
1578 144 : loc = leftmostLoc(xexpr->location,
1579 144 : exprLocation((Node *) xexpr->args));
1580 : }
1581 144 : break;
1582 0 : case T_JsonFormat:
1583 0 : loc = ((const JsonFormat *) expr)->location;
1584 0 : break;
1585 0 : case T_JsonValueExpr:
1586 0 : loc = exprLocation((Node *) ((const JsonValueExpr *) expr)->raw_expr);
1587 0 : break;
1588 114 : case T_JsonConstructorExpr:
1589 114 : loc = ((const JsonConstructorExpr *) expr)->location;
1590 114 : break;
1591 0 : case T_JsonIsPredicate:
1592 0 : loc = ((const JsonIsPredicate *) expr)->location;
1593 0 : break;
1594 340 : case T_JsonExpr:
1595 : {
1596 340 : const JsonExpr *jsexpr = (const JsonExpr *) expr;
1597 :
1598 : /* consider both function name and leftmost arg */
1599 340 : loc = leftmostLoc(jsexpr->location,
1600 340 : exprLocation(jsexpr->formatted_expr));
1601 : }
1602 340 : break;
1603 140 : case T_JsonBehavior:
1604 140 : loc = exprLocation(((const JsonBehavior *) expr)->expr);
1605 140 : break;
1606 110 : case T_NullTest:
1607 : {
1608 110 : const NullTest *nexpr = (const NullTest *) expr;
1609 :
1610 : /* Much as above */
1611 110 : loc = leftmostLoc(nexpr->location,
1612 110 : exprLocation((Node *) nexpr->arg));
1613 : }
1614 110 : break;
1615 0 : case T_BooleanTest:
1616 : {
1617 0 : const BooleanTest *bexpr = (const BooleanTest *) expr;
1618 :
1619 : /* Much as above */
1620 0 : loc = leftmostLoc(bexpr->location,
1621 0 : exprLocation((Node *) bexpr->arg));
1622 : }
1623 0 : break;
1624 53018 : case T_CoerceToDomain:
1625 : {
1626 53018 : const CoerceToDomain *cexpr = (const CoerceToDomain *) expr;
1627 :
1628 : /* Much as above */
1629 53018 : loc = leftmostLoc(cexpr->location,
1630 53018 : exprLocation((Node *) cexpr->arg));
1631 : }
1632 53018 : break;
1633 698 : case T_CoerceToDomainValue:
1634 698 : loc = ((const CoerceToDomainValue *) expr)->location;
1635 698 : break;
1636 40190 : case T_SetToDefault:
1637 40190 : loc = ((const SetToDefault *) expr)->location;
1638 40190 : break;
1639 0 : case T_ReturningExpr:
1640 0 : loc = exprLocation((Node *) ((const ReturningExpr *) expr)->retexpr);
1641 0 : break;
1642 0 : case T_TargetEntry:
1643 : /* just use argument's location */
1644 0 : loc = exprLocation((Node *) ((const TargetEntry *) expr)->expr);
1645 0 : break;
1646 12 : case T_IntoClause:
1647 : /* use the contained RangeVar's location --- close enough */
1648 12 : loc = exprLocation((Node *) ((const IntoClause *) expr)->rel);
1649 12 : break;
1650 64618 : case T_List:
1651 : {
1652 : /* report location of first list member that has a location */
1653 : ListCell *lc;
1654 :
1655 64618 : loc = -1; /* just to suppress compiler warning */
1656 65298 : foreach(lc, (const List *) expr)
1657 : {
1658 64960 : loc = exprLocation((Node *) lfirst(lc));
1659 64960 : if (loc >= 0)
1660 64280 : break;
1661 : }
1662 : }
1663 64618 : break;
1664 3561 : case T_A_Expr:
1665 : {
1666 3561 : const A_Expr *aexpr = (const A_Expr *) expr;
1667 :
1668 : /* use leftmost of operator or left operand (if any) */
1669 : /* we assume right operand can't be to left of operator */
1670 3561 : loc = leftmostLoc(aexpr->location,
1671 3561 : exprLocation(aexpr->lexpr));
1672 : }
1673 3561 : break;
1674 55674 : case T_ColumnRef:
1675 55674 : loc = ((const ColumnRef *) expr)->location;
1676 55674 : break;
1677 0 : case T_ParamRef:
1678 0 : loc = ((const ParamRef *) expr)->location;
1679 0 : break;
1680 51072 : case T_A_Const:
1681 51072 : loc = ((const A_Const *) expr)->location;
1682 51072 : break;
1683 2675 : case T_FuncCall:
1684 : {
1685 2675 : const FuncCall *fc = (const FuncCall *) expr;
1686 :
1687 : /* consider both function name and leftmost arg */
1688 : /* (we assume any ORDER BY nodes must be to right of name) */
1689 2675 : loc = leftmostLoc(fc->location,
1690 2675 : exprLocation((Node *) fc->args));
1691 : }
1692 2675 : break;
1693 0 : case T_A_ArrayExpr:
1694 : /* the location points at ARRAY or [, which must be leftmost */
1695 0 : loc = ((const A_ArrayExpr *) expr)->location;
1696 0 : break;
1697 12 : case T_ResTarget:
1698 : /* we need not examine the contained expression (if any) */
1699 12 : loc = ((const ResTarget *) expr)->location;
1700 12 : break;
1701 0 : case T_MultiAssignRef:
1702 0 : loc = exprLocation(((const MultiAssignRef *) expr)->source);
1703 0 : break;
1704 5613 : case T_TypeCast:
1705 : {
1706 5613 : const TypeCast *tc = (const TypeCast *) expr;
1707 :
1708 : /*
1709 : * This could represent CAST(), ::, or TypeName 'literal', so
1710 : * any of the components might be leftmost.
1711 : */
1712 5613 : loc = exprLocation(tc->arg);
1713 5613 : loc = leftmostLoc(loc, tc->typeName->location);
1714 5613 : loc = leftmostLoc(loc, tc->location);
1715 : }
1716 5613 : break;
1717 675 : case T_CollateClause:
1718 : /* just use argument's location */
1719 675 : loc = exprLocation(((const CollateClause *) expr)->arg);
1720 675 : break;
1721 8 : case T_SortBy:
1722 : /* just use argument's location (ignore operator, if any) */
1723 8 : loc = exprLocation(((const SortBy *) expr)->node);
1724 8 : break;
1725 0 : case T_WindowDef:
1726 0 : loc = ((const WindowDef *) expr)->location;
1727 0 : break;
1728 0 : case T_RangeTableSample:
1729 0 : loc = ((const RangeTableSample *) expr)->location;
1730 0 : break;
1731 0 : case T_TypeName:
1732 0 : loc = ((const TypeName *) expr)->location;
1733 0 : break;
1734 12 : case T_ColumnDef:
1735 12 : loc = ((const ColumnDef *) expr)->location;
1736 12 : break;
1737 0 : case T_IndexElem:
1738 0 : loc = ((const IndexElem *) expr)->location;
1739 0 : break;
1740 0 : case T_Constraint:
1741 0 : loc = ((const Constraint *) expr)->location;
1742 0 : break;
1743 0 : case T_FunctionParameter:
1744 0 : loc = ((const FunctionParameter *) expr)->location;
1745 0 : break;
1746 0 : case T_XmlSerialize:
1747 : /* XMLSERIALIZE keyword should always be the first thing */
1748 0 : loc = ((const XmlSerialize *) expr)->location;
1749 0 : break;
1750 24 : case T_GroupingSet:
1751 24 : loc = ((const GroupingSet *) expr)->location;
1752 24 : break;
1753 0 : case T_WithClause:
1754 0 : loc = ((const WithClause *) expr)->location;
1755 0 : break;
1756 0 : case T_InferClause:
1757 0 : loc = ((const InferClause *) expr)->location;
1758 0 : break;
1759 4 : case T_OnConflictClause:
1760 4 : loc = ((const OnConflictClause *) expr)->location;
1761 4 : break;
1762 0 : case T_CTESearchClause:
1763 0 : loc = ((const CTESearchClause *) expr)->location;
1764 0 : break;
1765 0 : case T_CTECycleClause:
1766 0 : loc = ((const CTECycleClause *) expr)->location;
1767 0 : break;
1768 0 : case T_CommonTableExpr:
1769 0 : loc = ((const CommonTableExpr *) expr)->location;
1770 0 : break;
1771 0 : case T_JsonKeyValue:
1772 : /* just use the key's location */
1773 0 : loc = exprLocation((Node *) ((const JsonKeyValue *) expr)->key);
1774 0 : break;
1775 0 : case T_JsonObjectConstructor:
1776 0 : loc = ((const JsonObjectConstructor *) expr)->location;
1777 0 : break;
1778 0 : case T_JsonArrayConstructor:
1779 0 : loc = ((const JsonArrayConstructor *) expr)->location;
1780 0 : break;
1781 0 : case T_JsonArrayQueryConstructor:
1782 0 : loc = ((const JsonArrayQueryConstructor *) expr)->location;
1783 0 : break;
1784 0 : case T_JsonAggConstructor:
1785 0 : loc = ((const JsonAggConstructor *) expr)->location;
1786 0 : break;
1787 0 : case T_JsonObjectAgg:
1788 0 : loc = exprLocation((Node *) ((const JsonObjectAgg *) expr)->constructor);
1789 0 : break;
1790 0 : case T_JsonArrayAgg:
1791 0 : loc = exprLocation((Node *) ((const JsonArrayAgg *) expr)->constructor);
1792 0 : break;
1793 0 : case T_PlaceHolderVar:
1794 : /* just use argument's location */
1795 0 : loc = exprLocation((Node *) ((const PlaceHolderVar *) expr)->phexpr);
1796 0 : break;
1797 0 : case T_InferenceElem:
1798 : /* just use nested expr's location */
1799 0 : loc = exprLocation((Node *) ((const InferenceElem *) expr)->expr);
1800 0 : break;
1801 0 : case T_PartitionElem:
1802 0 : loc = ((const PartitionElem *) expr)->location;
1803 0 : break;
1804 0 : case T_PartitionSpec:
1805 0 : loc = ((const PartitionSpec *) expr)->location;
1806 0 : break;
1807 36 : case T_PartitionBoundSpec:
1808 36 : loc = ((const PartitionBoundSpec *) expr)->location;
1809 36 : break;
1810 32 : case T_PartitionRangeDatum:
1811 32 : loc = ((const PartitionRangeDatum *) expr)->location;
1812 32 : break;
1813 26335 : default:
1814 : /* for any other node type it's just unknown... */
1815 26335 : loc = -1;
1816 26335 : break;
1817 : }
1818 2938800 : return loc;
1819 : }
1820 :
1821 : /*
1822 : * leftmostLoc - support for exprLocation
1823 : *
1824 : * Take the minimum of two parse location values, but ignore unknowns
1825 : */
1826 : static int
1827 175099 : leftmostLoc(int loc1, int loc2)
1828 : {
1829 175099 : if (loc1 < 0)
1830 13515 : return loc2;
1831 161584 : else if (loc2 < 0)
1832 16927 : return loc1;
1833 : else
1834 144657 : return Min(loc1, loc2);
1835 : }
1836 :
1837 :
1838 : /*
1839 : * fix_opfuncids
1840 : * Calculate opfuncid field from opno for each OpExpr node in given tree.
1841 : * The given tree can be anything expression_tree_walker handles.
1842 : *
1843 : * The argument is modified in-place. (This is OK since we'd want the
1844 : * same change for any node, even if it gets visited more than once due to
1845 : * shared structure.)
1846 : */
1847 : void
1848 317301 : fix_opfuncids(Node *node)
1849 : {
1850 : /* This tree walk requires no special setup, so away we go... */
1851 317301 : fix_opfuncids_walker(node, NULL);
1852 317301 : }
1853 :
1854 : static bool
1855 761822 : fix_opfuncids_walker(Node *node, void *context)
1856 : {
1857 761822 : if (node == NULL)
1858 38236 : return false;
1859 723586 : if (IsA(node, OpExpr))
1860 46844 : set_opfuncid((OpExpr *) node);
1861 676742 : else if (IsA(node, DistinctExpr))
1862 4 : set_opfuncid((OpExpr *) node); /* rely on struct equivalence */
1863 676738 : else if (IsA(node, NullIfExpr))
1864 671 : set_opfuncid((OpExpr *) node); /* rely on struct equivalence */
1865 676067 : else if (IsA(node, ScalarArrayOpExpr))
1866 1760 : set_sa_opfuncid((ScalarArrayOpExpr *) node);
1867 723586 : return expression_tree_walker(node, fix_opfuncids_walker, context);
1868 : }
1869 :
1870 : /*
1871 : * set_opfuncid
1872 : * Set the opfuncid (procedure OID) in an OpExpr node,
1873 : * if it hasn't been set already.
1874 : *
1875 : * Because of struct equivalence, this can also be used for
1876 : * DistinctExpr and NullIfExpr nodes.
1877 : */
1878 : void
1879 3157298 : set_opfuncid(OpExpr *opexpr)
1880 : {
1881 3157298 : if (opexpr->opfuncid == InvalidOid)
1882 190523 : opexpr->opfuncid = get_opcode(opexpr->opno);
1883 3157298 : }
1884 :
1885 : /*
1886 : * set_sa_opfuncid
1887 : * As above, for ScalarArrayOpExpr nodes.
1888 : */
1889 : void
1890 153869 : set_sa_opfuncid(ScalarArrayOpExpr *opexpr)
1891 : {
1892 153869 : if (opexpr->opfuncid == InvalidOid)
1893 410 : opexpr->opfuncid = get_opcode(opexpr->opno);
1894 153869 : }
1895 :
1896 :
1897 : /*
1898 : * check_functions_in_node -
1899 : * apply checker() to each function OID contained in given expression node
1900 : *
1901 : * Returns true if the checker() function does; for nodes representing more
1902 : * than one function call, returns true if the checker() function does so
1903 : * for any of those functions. Returns false if node does not invoke any
1904 : * SQL-visible function. Caller must not pass node == NULL.
1905 : *
1906 : * This function examines only the given node; it does not recurse into any
1907 : * sub-expressions. Callers typically prefer to keep control of the recursion
1908 : * for themselves, in case additional checks should be made, or because they
1909 : * have special rules about which parts of the tree need to be visited.
1910 : *
1911 : * Note: we ignore MinMaxExpr, SQLValueFunction, XmlExpr, CoerceToDomain,
1912 : * and NextValueExpr nodes, because they do not contain SQL function OIDs.
1913 : * However, they can invoke SQL-visible functions, so callers should take
1914 : * thought about how to treat them.
1915 : */
1916 : bool
1917 18410343 : check_functions_in_node(Node *node, check_function_callback checker,
1918 : void *context)
1919 : {
1920 18410343 : switch (nodeTag(node))
1921 : {
1922 94176 : case T_Aggref:
1923 : {
1924 94176 : Aggref *expr = (Aggref *) node;
1925 :
1926 94176 : if (checker(expr->aggfnoid, context))
1927 860 : return true;
1928 : }
1929 93316 : break;
1930 6442 : case T_WindowFunc:
1931 : {
1932 6442 : WindowFunc *expr = (WindowFunc *) node;
1933 :
1934 6442 : if (checker(expr->winfnoid, context))
1935 125 : return true;
1936 : }
1937 6317 : break;
1938 549923 : case T_FuncExpr:
1939 : {
1940 549923 : FuncExpr *expr = (FuncExpr *) node;
1941 :
1942 549923 : if (checker(expr->funcid, context))
1943 74113 : return true;
1944 : }
1945 475810 : break;
1946 1243782 : case T_OpExpr:
1947 : case T_DistinctExpr: /* struct-equivalent to OpExpr */
1948 : case T_NullIfExpr: /* struct-equivalent to OpExpr */
1949 : {
1950 1243782 : OpExpr *expr = (OpExpr *) node;
1951 :
1952 : /* Set opfuncid if it wasn't set already */
1953 1243782 : set_opfuncid(expr);
1954 1243782 : if (checker(expr->opfuncid, context))
1955 1388 : return true;
1956 : }
1957 1242394 : break;
1958 52755 : case T_ScalarArrayOpExpr:
1959 : {
1960 52755 : ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
1961 :
1962 52755 : set_sa_opfuncid(expr);
1963 52755 : if (checker(expr->opfuncid, context))
1964 77 : return true;
1965 : }
1966 52678 : break;
1967 39813 : case T_CoerceViaIO:
1968 : {
1969 39813 : CoerceViaIO *expr = (CoerceViaIO *) node;
1970 : Oid iofunc;
1971 : Oid typioparam;
1972 : bool typisvarlena;
1973 :
1974 : /* check the result type's input function */
1975 39813 : getTypeInputInfo(expr->resulttype,
1976 : &iofunc, &typioparam);
1977 39813 : if (checker(iofunc, context))
1978 364 : return true;
1979 : /* check the input type's output function */
1980 39782 : getTypeOutputInfo(exprType((Node *) expr->arg),
1981 : &iofunc, &typisvarlena);
1982 39782 : if (checker(iofunc, context))
1983 333 : return true;
1984 : }
1985 39449 : break;
1986 284 : case T_RowCompareExpr:
1987 : {
1988 284 : RowCompareExpr *rcexpr = (RowCompareExpr *) node;
1989 : ListCell *opid;
1990 :
1991 937 : foreach(opid, rcexpr->opnos)
1992 : {
1993 653 : Oid opfuncid = get_opcode(lfirst_oid(opid));
1994 :
1995 653 : if (checker(opfuncid, context))
1996 0 : return true;
1997 : }
1998 : }
1999 284 : break;
2000 16423168 : default:
2001 16423168 : break;
2002 : }
2003 18333416 : return false;
2004 : }
2005 :
2006 :
2007 : /*
2008 : * Standard expression-tree walking support
2009 : *
2010 : * We used to have near-duplicate code in many different routines that
2011 : * understood how to recurse through an expression node tree. That was
2012 : * a pain to maintain, and we frequently had bugs due to some particular
2013 : * routine neglecting to support a particular node type. In most cases,
2014 : * these routines only actually care about certain node types, and don't
2015 : * care about other types except insofar as they have to recurse through
2016 : * non-primitive node types. Therefore, we now provide generic tree-walking
2017 : * logic to consolidate the redundant "boilerplate" code. There are
2018 : * two versions: expression_tree_walker() and expression_tree_mutator().
2019 : */
2020 :
2021 : /*
2022 : * expression_tree_walker() is designed to support routines that traverse
2023 : * a tree in a read-only fashion (although it will also work for routines
2024 : * that modify nodes in-place but never add/delete/replace nodes).
2025 : * A walker routine should look like this:
2026 : *
2027 : * bool my_walker (Node *node, my_struct *context)
2028 : * {
2029 : * if (node == NULL)
2030 : * return false;
2031 : * // check for nodes that special work is required for, eg:
2032 : * if (IsA(node, Var))
2033 : * {
2034 : * ... do special actions for Var nodes
2035 : * }
2036 : * else if (IsA(node, ...))
2037 : * {
2038 : * ... do special actions for other node types
2039 : * }
2040 : * // for any node type not specially processed, do:
2041 : * return expression_tree_walker(node, my_walker, context);
2042 : * }
2043 : *
2044 : * The "context" argument points to a struct that holds whatever context
2045 : * information the walker routine needs --- it can be used to return data
2046 : * gathered by the walker, too. This argument is not touched by
2047 : * expression_tree_walker, but it is passed down to recursive sub-invocations
2048 : * of my_walker. The tree walk is started from a setup routine that
2049 : * fills in the appropriate context struct, calls my_walker with the top-level
2050 : * node of the tree, and then examines the results.
2051 : *
2052 : * The walker routine should return "false" to continue the tree walk, or
2053 : * "true" to abort the walk and immediately return "true" to the top-level
2054 : * caller. This can be used to short-circuit the traversal if the walker
2055 : * has found what it came for. "false" is returned to the top-level caller
2056 : * iff no invocation of the walker returned "true".
2057 : *
2058 : * The node types handled by expression_tree_walker include all those
2059 : * normally found in target lists and qualifier clauses during the planning
2060 : * stage. In particular, it handles List nodes since a cnf-ified qual clause
2061 : * will have List structure at the top level, and it handles TargetEntry nodes
2062 : * so that a scan of a target list can be handled without additional code.
2063 : * Also, RangeTblRef, FromExpr, JoinExpr, and SetOperationStmt nodes are
2064 : * handled, so that query jointrees and setOperation trees can be processed
2065 : * without additional code.
2066 : *
2067 : * expression_tree_walker will handle SubLink nodes by recursing normally
2068 : * into the "testexpr" subtree (which is an expression belonging to the outer
2069 : * plan). It will also call the walker on the sub-Query node; however, when
2070 : * expression_tree_walker itself is called on a Query node, it does nothing
2071 : * and returns "false". The net effect is that unless the walker does
2072 : * something special at a Query node, sub-selects will not be visited during
2073 : * an expression tree walk. This is exactly the behavior wanted in many cases
2074 : * --- and for those walkers that do want to recurse into sub-selects, special
2075 : * behavior is typically needed anyway at the entry to a sub-select (such as
2076 : * incrementing a depth counter). A walker that wants to examine sub-selects
2077 : * should include code along the lines of:
2078 : *
2079 : * if (IsA(node, Query))
2080 : * {
2081 : * adjust context for subquery;
2082 : * result = query_tree_walker((Query *) node, my_walker, context,
2083 : * 0); // adjust flags as needed
2084 : * restore context if needed;
2085 : * return result;
2086 : * }
2087 : *
2088 : * query_tree_walker is a convenience routine (see below) that calls the
2089 : * walker on all the expression subtrees of the given Query node.
2090 : *
2091 : * expression_tree_walker will handle SubPlan nodes by recursing normally
2092 : * into the "testexpr" and the "args" list (which are expressions belonging to
2093 : * the outer plan). It will not touch the completed subplan, however. Since
2094 : * there is no link to the original Query, it is not possible to recurse into
2095 : * subselects of an already-planned expression tree. This is OK for current
2096 : * uses, but may need to be revisited in future.
2097 : */
2098 :
2099 : bool
2100 82300039 : expression_tree_walker_impl(Node *node,
2101 : tree_walker_callback walker,
2102 : void *context)
2103 : {
2104 : ListCell *temp;
2105 :
2106 : /*
2107 : * The walker has already visited the current node, and so we need only
2108 : * recurse into any sub-nodes it has.
2109 : *
2110 : * We assume that the walker is not interested in List nodes per se, so
2111 : * when we expect a List we just recurse directly to self without
2112 : * bothering to call the walker.
2113 : */
2114 : #define WALK(n) walker((Node *) (n), context)
2115 :
2116 : #define LIST_WALK(l) expression_tree_walker_impl((Node *) (l), walker, context)
2117 :
2118 82300039 : if (node == NULL)
2119 1582762 : return false;
2120 :
2121 : /* Guard against stack overflow due to overly complex expressions */
2122 80717277 : check_stack_depth();
2123 :
2124 80717273 : switch (nodeTag(node))
2125 : {
2126 34570550 : case T_Var:
2127 : case T_Const:
2128 : case T_Param:
2129 : case T_CaseTestExpr:
2130 : case T_SQLValueFunction:
2131 : case T_CoerceToDomainValue:
2132 : case T_SetToDefault:
2133 : case T_CurrentOfExpr:
2134 : case T_NextValueExpr:
2135 : case T_RangeTblRef:
2136 : case T_SortGroupClause:
2137 : case T_CTESearchClause:
2138 : case T_GraphPropertyRef:
2139 : case T_MergeSupportFunc:
2140 : /* primitive node types with no expression subnodes */
2141 34570550 : break;
2142 6691 : case T_WithCheckOption:
2143 6691 : return WALK(((WithCheckOption *) node)->qual);
2144 275785 : case T_Aggref:
2145 : {
2146 275785 : Aggref *expr = (Aggref *) node;
2147 :
2148 : /* recurse directly on Lists */
2149 275785 : if (LIST_WALK(expr->aggdirectargs))
2150 0 : return true;
2151 275785 : if (LIST_WALK(expr->args))
2152 14716 : return true;
2153 261069 : if (LIST_WALK(expr->aggorder))
2154 0 : return true;
2155 261069 : if (LIST_WALK(expr->aggdistinct))
2156 0 : return true;
2157 261069 : if (WALK(expr->aggfilter))
2158 70 : return true;
2159 : }
2160 260999 : break;
2161 3111 : case T_GroupingFunc:
2162 : {
2163 3111 : GroupingFunc *grouping = (GroupingFunc *) node;
2164 :
2165 3111 : if (LIST_WALK(grouping->args))
2166 190 : return true;
2167 : }
2168 2921 : break;
2169 15966 : case T_WindowFunc:
2170 : {
2171 15966 : WindowFunc *expr = (WindowFunc *) node;
2172 :
2173 : /* recurse directly on List */
2174 15966 : if (LIST_WALK(expr->args))
2175 451 : return true;
2176 15515 : if (WALK(expr->aggfilter))
2177 9 : return true;
2178 15506 : if (WALK(expr->runCondition))
2179 0 : return true;
2180 : }
2181 15506 : break;
2182 458 : case T_WindowFuncRunCondition:
2183 : {
2184 458 : WindowFuncRunCondition *expr = (WindowFuncRunCondition *) node;
2185 :
2186 458 : if (WALK(expr->arg))
2187 0 : return true;
2188 : }
2189 458 : break;
2190 206613 : case T_SubscriptingRef:
2191 : {
2192 206613 : SubscriptingRef *sbsref = (SubscriptingRef *) node;
2193 :
2194 : /* recurse directly for upper/lower container index lists */
2195 206613 : if (LIST_WALK(sbsref->refupperindexpr))
2196 9926 : return true;
2197 196687 : if (LIST_WALK(sbsref->reflowerindexpr))
2198 0 : return true;
2199 : /* walker must see the refexpr and refassgnexpr, however */
2200 196687 : if (WALK(sbsref->refexpr))
2201 11544 : return true;
2202 :
2203 185143 : if (WALK(sbsref->refassgnexpr))
2204 126 : return true;
2205 : }
2206 185017 : break;
2207 2713374 : case T_FuncExpr:
2208 : {
2209 2713374 : FuncExpr *expr = (FuncExpr *) node;
2210 :
2211 2713374 : if (LIST_WALK(expr->args))
2212 61515 : return true;
2213 : }
2214 2651851 : break;
2215 56057 : case T_NamedArgExpr:
2216 56057 : return WALK(((NamedArgExpr *) node)->arg);
2217 6449249 : case T_OpExpr:
2218 : case T_DistinctExpr: /* struct-equivalent to OpExpr */
2219 : case T_NullIfExpr: /* struct-equivalent to OpExpr */
2220 : {
2221 6449249 : OpExpr *expr = (OpExpr *) node;
2222 :
2223 6449249 : if (LIST_WALK(expr->args))
2224 63647 : return true;
2225 : }
2226 6385518 : break;
2227 345846 : case T_ScalarArrayOpExpr:
2228 : {
2229 345846 : ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
2230 :
2231 345846 : if (LIST_WALK(expr->args))
2232 33442 : return true;
2233 : }
2234 312404 : break;
2235 948330 : case T_BoolExpr:
2236 : {
2237 948330 : BoolExpr *expr = (BoolExpr *) node;
2238 :
2239 948330 : if (LIST_WALK(expr->args))
2240 10376 : return true;
2241 : }
2242 937946 : break;
2243 199643 : case T_SubLink:
2244 : {
2245 199643 : SubLink *sublink = (SubLink *) node;
2246 :
2247 199643 : if (WALK(sublink->testexpr))
2248 56 : return true;
2249 :
2250 : /*
2251 : * Also invoke the walker on the sublink's Query node, so it
2252 : * can recurse into the sub-query if it wants to.
2253 : */
2254 199587 : return WALK(sublink->subselect);
2255 : }
2256 : break;
2257 86266 : case T_SubPlan:
2258 : {
2259 86266 : SubPlan *subplan = (SubPlan *) node;
2260 :
2261 : /* recurse into the testexpr, but not into the Plan */
2262 86266 : if (WALK(subplan->testexpr))
2263 58 : return true;
2264 : /* also examine args list */
2265 86208 : if (LIST_WALK(subplan->args))
2266 350 : return true;
2267 : }
2268 85858 : break;
2269 6198 : case T_AlternativeSubPlan:
2270 6198 : return LIST_WALK(((AlternativeSubPlan *) node)->subplans);
2271 247874 : case T_FieldSelect:
2272 247874 : return WALK(((FieldSelect *) node)->arg);
2273 2347 : case T_FieldStore:
2274 : {
2275 2347 : FieldStore *fstore = (FieldStore *) node;
2276 :
2277 2347 : if (WALK(fstore->arg))
2278 0 : return true;
2279 2347 : if (WALK(fstore->newvals))
2280 8 : return true;
2281 : }
2282 2339 : break;
2283 1001300 : case T_RelabelType:
2284 1001300 : return WALK(((RelabelType *) node)->arg);
2285 205345 : case T_CoerceViaIO:
2286 205345 : return WALK(((CoerceViaIO *) node)->arg);
2287 40022 : case T_ArrayCoerceExpr:
2288 : {
2289 40022 : ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node;
2290 :
2291 40022 : if (WALK(acoerce->arg))
2292 3383 : return true;
2293 36639 : if (WALK(acoerce->elemexpr))
2294 20 : return true;
2295 : }
2296 36619 : break;
2297 2309 : case T_ConvertRowtypeExpr:
2298 2309 : return WALK(((ConvertRowtypeExpr *) node)->arg);
2299 25657 : case T_CollateExpr:
2300 25657 : return WALK(((CollateExpr *) node)->arg);
2301 350539 : case T_CaseExpr:
2302 : {
2303 350539 : CaseExpr *caseexpr = (CaseExpr *) node;
2304 :
2305 350539 : if (WALK(caseexpr->arg))
2306 319 : return true;
2307 : /* we assume walker doesn't care about CaseWhens, either */
2308 1025776 : foreach(temp, caseexpr->args)
2309 : {
2310 683278 : CaseWhen *when = lfirst_node(CaseWhen, temp);
2311 :
2312 683278 : if (WALK(when->expr))
2313 7722 : return true;
2314 681205 : if (WALK(when->result))
2315 5649 : return true;
2316 : }
2317 342498 : if (WALK(caseexpr->defresult))
2318 7318 : return true;
2319 : }
2320 335180 : break;
2321 164319 : case T_ArrayExpr:
2322 164319 : return WALK(((ArrayExpr *) node)->elements);
2323 26972 : case T_RowExpr:
2324 : /* Assume colnames isn't interesting */
2325 26972 : return WALK(((RowExpr *) node)->args);
2326 2151 : case T_RowCompareExpr:
2327 : {
2328 2151 : RowCompareExpr *rcexpr = (RowCompareExpr *) node;
2329 :
2330 2151 : if (WALK(rcexpr->largs))
2331 0 : return true;
2332 2151 : if (WALK(rcexpr->rargs))
2333 0 : return true;
2334 : }
2335 2151 : break;
2336 42218 : case T_CoalesceExpr:
2337 42218 : return WALK(((CoalesceExpr *) node)->args);
2338 4469 : case T_MinMaxExpr:
2339 4469 : return WALK(((MinMaxExpr *) node)->args);
2340 3953 : case T_XmlExpr:
2341 : {
2342 3953 : XmlExpr *xexpr = (XmlExpr *) node;
2343 :
2344 3953 : if (WALK(xexpr->named_args))
2345 8 : return true;
2346 : /* we assume walker doesn't care about arg_names */
2347 3945 : if (WALK(xexpr->args))
2348 16 : return true;
2349 : }
2350 3929 : break;
2351 2977 : case T_JsonValueExpr:
2352 : {
2353 2977 : JsonValueExpr *jve = (JsonValueExpr *) node;
2354 :
2355 2977 : if (WALK(jve->raw_expr))
2356 40 : return true;
2357 2937 : if (WALK(jve->formatted_expr))
2358 0 : return true;
2359 : }
2360 2937 : break;
2361 8010 : case T_JsonConstructorExpr:
2362 : {
2363 8010 : JsonConstructorExpr *ctor = (JsonConstructorExpr *) node;
2364 :
2365 8010 : if (WALK(ctor->args))
2366 58 : return true;
2367 7952 : if (WALK(ctor->func))
2368 80 : return true;
2369 7872 : if (WALK(ctor->coercion))
2370 10 : return true;
2371 : }
2372 7862 : break;
2373 2141 : case T_JsonIsPredicate:
2374 2141 : return WALK(((JsonIsPredicate *) node)->expr);
2375 14049 : case T_JsonExpr:
2376 : {
2377 14049 : JsonExpr *jexpr = (JsonExpr *) node;
2378 :
2379 14049 : if (WALK(jexpr->formatted_expr))
2380 56 : return true;
2381 13993 : if (WALK(jexpr->path_spec))
2382 4 : return true;
2383 13989 : if (WALK(jexpr->passing_values))
2384 4 : return true;
2385 : /* we assume walker doesn't care about passing_names */
2386 13985 : if (WALK(jexpr->on_empty))
2387 30 : return true;
2388 13955 : if (WALK(jexpr->on_error))
2389 24 : return true;
2390 : }
2391 13931 : break;
2392 24688 : case T_JsonBehavior:
2393 : {
2394 24688 : JsonBehavior *behavior = (JsonBehavior *) node;
2395 :
2396 24688 : if (WALK(behavior->expr))
2397 54 : return true;
2398 : }
2399 24634 : break;
2400 193254 : case T_NullTest:
2401 193254 : return WALK(((NullTest *) node)->arg);
2402 10851 : case T_BooleanTest:
2403 10851 : return WALK(((BooleanTest *) node)->arg);
2404 263243 : case T_CoerceToDomain:
2405 263243 : return WALK(((CoerceToDomain *) node)->arg);
2406 12780382 : case T_TargetEntry:
2407 12780382 : return WALK(((TargetEntry *) node)->expr);
2408 100350 : case T_Query:
2409 : /* Do nothing with a sub-Query, per discussion above */
2410 100350 : break;
2411 162 : case T_WindowClause:
2412 : {
2413 162 : WindowClause *wc = (WindowClause *) node;
2414 :
2415 162 : if (WALK(wc->partitionClause))
2416 0 : return true;
2417 162 : if (WALK(wc->orderClause))
2418 0 : return true;
2419 162 : if (WALK(wc->startOffset))
2420 0 : return true;
2421 162 : if (WALK(wc->endOffset))
2422 0 : return true;
2423 : }
2424 162 : break;
2425 68 : case T_CTECycleClause:
2426 : {
2427 68 : CTECycleClause *cc = (CTECycleClause *) node;
2428 :
2429 68 : if (WALK(cc->cycle_mark_value))
2430 0 : return true;
2431 68 : if (WALK(cc->cycle_mark_default))
2432 0 : return true;
2433 : }
2434 68 : break;
2435 5999 : case T_CommonTableExpr:
2436 : {
2437 5999 : CommonTableExpr *cte = (CommonTableExpr *) node;
2438 :
2439 : /*
2440 : * Invoke the walker on the CTE's Query node, so it can
2441 : * recurse into the sub-query if it wants to.
2442 : */
2443 5999 : if (WALK(cte->ctequery))
2444 154 : return true;
2445 :
2446 5845 : if (WALK(cte->search_clause))
2447 0 : return true;
2448 5845 : if (WALK(cte->cycle_clause))
2449 0 : return true;
2450 : }
2451 5845 : break;
2452 0 : case T_JsonKeyValue:
2453 : {
2454 0 : JsonKeyValue *kv = (JsonKeyValue *) node;
2455 :
2456 0 : if (WALK(kv->key))
2457 0 : return true;
2458 0 : if (WALK(kv->value))
2459 0 : return true;
2460 : }
2461 0 : break;
2462 0 : case T_JsonObjectConstructor:
2463 : {
2464 0 : JsonObjectConstructor *ctor = (JsonObjectConstructor *) node;
2465 :
2466 0 : if (LIST_WALK(ctor->exprs))
2467 0 : return true;
2468 : }
2469 0 : break;
2470 0 : case T_JsonArrayConstructor:
2471 : {
2472 0 : JsonArrayConstructor *ctor = (JsonArrayConstructor *) node;
2473 :
2474 0 : if (LIST_WALK(ctor->exprs))
2475 0 : return true;
2476 : }
2477 0 : break;
2478 0 : case T_JsonArrayQueryConstructor:
2479 : {
2480 0 : JsonArrayQueryConstructor *ctor = (JsonArrayQueryConstructor *) node;
2481 :
2482 0 : if (WALK(ctor->query))
2483 0 : return true;
2484 : }
2485 0 : break;
2486 0 : case T_JsonAggConstructor:
2487 : {
2488 0 : JsonAggConstructor *ctor = (JsonAggConstructor *) node;
2489 :
2490 0 : if (WALK(ctor->agg_filter))
2491 0 : return true;
2492 0 : if (WALK(ctor->agg_order))
2493 0 : return true;
2494 0 : if (WALK(ctor->over))
2495 0 : return true;
2496 : }
2497 0 : break;
2498 0 : case T_JsonObjectAgg:
2499 : {
2500 0 : JsonObjectAgg *ctor = (JsonObjectAgg *) node;
2501 :
2502 0 : if (WALK(ctor->constructor))
2503 0 : return true;
2504 0 : if (WALK(ctor->arg))
2505 0 : return true;
2506 : }
2507 0 : break;
2508 0 : case T_JsonArrayAgg:
2509 : {
2510 0 : JsonArrayAgg *ctor = (JsonArrayAgg *) node;
2511 :
2512 0 : if (WALK(ctor->constructor))
2513 0 : return true;
2514 0 : if (WALK(ctor->arg))
2515 0 : return true;
2516 : }
2517 0 : break;
2518 :
2519 2746 : case T_PartitionBoundSpec:
2520 : {
2521 2746 : PartitionBoundSpec *pbs = (PartitionBoundSpec *) node;
2522 :
2523 2746 : if (WALK(pbs->listdatums))
2524 0 : return true;
2525 2746 : if (WALK(pbs->lowerdatums))
2526 0 : return true;
2527 2746 : if (WALK(pbs->upperdatums))
2528 0 : return true;
2529 : }
2530 2746 : break;
2531 3596 : case T_PartitionRangeDatum:
2532 : {
2533 3596 : PartitionRangeDatum *prd = (PartitionRangeDatum *) node;
2534 :
2535 3596 : if (WALK(prd->value))
2536 0 : return true;
2537 : }
2538 3596 : break;
2539 17829274 : case T_List:
2540 61501198 : foreach(temp, (List *) node)
2541 : {
2542 44278435 : if (WALK(lfirst(temp)))
2543 606347 : return true;
2544 : }
2545 17222763 : break;
2546 1025605 : case T_FromExpr:
2547 : {
2548 1025605 : FromExpr *from = (FromExpr *) node;
2549 :
2550 1025605 : if (LIST_WALK(from->fromlist))
2551 47360 : return true;
2552 978245 : if (WALK(from->quals))
2553 2462 : return true;
2554 : }
2555 975775 : break;
2556 2448 : case T_OnConflictExpr:
2557 : {
2558 2448 : OnConflictExpr *onconflict = (OnConflictExpr *) node;
2559 :
2560 2448 : if (WALK(onconflict->arbiterElems))
2561 0 : return true;
2562 2448 : if (WALK(onconflict->arbiterWhere))
2563 0 : return true;
2564 2448 : if (WALK(onconflict->onConflictSet))
2565 0 : return true;
2566 2448 : if (WALK(onconflict->onConflictWhere))
2567 0 : return true;
2568 2448 : if (WALK(onconflict->exclRelTlist))
2569 0 : return true;
2570 : }
2571 2448 : break;
2572 4542 : case T_MergeAction:
2573 : {
2574 4542 : MergeAction *action = (MergeAction *) node;
2575 :
2576 4542 : if (WALK(action->qual))
2577 93 : return true;
2578 4449 : if (WALK(action->targetList))
2579 233 : return true;
2580 : }
2581 4216 : break;
2582 879 : case T_ForPortionOfExpr:
2583 : {
2584 879 : ForPortionOfExpr *forPortionOf = (ForPortionOfExpr *) node;
2585 :
2586 879 : if (WALK(forPortionOf->targetFrom))
2587 0 : return true;
2588 879 : if (WALK(forPortionOf->targetTo))
2589 0 : return true;
2590 879 : if (WALK(forPortionOf->targetRange))
2591 0 : return true;
2592 879 : if (WALK(forPortionOf->overlapsExpr))
2593 0 : return true;
2594 : }
2595 879 : break;
2596 636 : case T_PartitionPruneStepOp:
2597 : {
2598 636 : PartitionPruneStepOp *opstep = (PartitionPruneStepOp *) node;
2599 :
2600 636 : if (WALK(opstep->exprs))
2601 0 : return true;
2602 : }
2603 636 : break;
2604 119 : case T_PartitionPruneStepCombine:
2605 : /* no expression subnodes */
2606 119 : break;
2607 234651 : case T_JoinExpr:
2608 : {
2609 234651 : JoinExpr *join = (JoinExpr *) node;
2610 :
2611 234651 : if (WALK(join->larg))
2612 11910 : return true;
2613 222741 : if (WALK(join->rarg))
2614 15931 : return true;
2615 206810 : if (WALK(join->quals))
2616 48 : return true;
2617 :
2618 : /*
2619 : * alias clause, using list are deemed uninteresting.
2620 : */
2621 : }
2622 206762 : break;
2623 28356 : case T_SetOperationStmt:
2624 : {
2625 28356 : SetOperationStmt *setop = (SetOperationStmt *) node;
2626 :
2627 28356 : if (WALK(setop->larg))
2628 0 : return true;
2629 28356 : if (WALK(setop->rarg))
2630 0 : return true;
2631 :
2632 : /* groupClauses are deemed uninteresting */
2633 : }
2634 28356 : break;
2635 0 : case T_IndexClause:
2636 : {
2637 0 : IndexClause *iclause = (IndexClause *) node;
2638 :
2639 0 : if (WALK(iclause->rinfo))
2640 0 : return true;
2641 0 : if (LIST_WALK(iclause->indexquals))
2642 0 : return true;
2643 : }
2644 0 : break;
2645 25342 : case T_PlaceHolderVar:
2646 25342 : return WALK(((PlaceHolderVar *) node)->phexpr);
2647 2470 : case T_InferenceElem:
2648 2470 : return WALK(((InferenceElem *) node)->expr);
2649 2836 : case T_ReturningExpr:
2650 2836 : return WALK(((ReturningExpr *) node)->retexpr);
2651 1482 : case T_AppendRelInfo:
2652 : {
2653 1482 : AppendRelInfo *appinfo = (AppendRelInfo *) node;
2654 :
2655 1482 : if (LIST_WALK(appinfo->translated_vars))
2656 0 : return true;
2657 : }
2658 1482 : break;
2659 0 : case T_PlaceHolderInfo:
2660 0 : return WALK(((PlaceHolderInfo *) node)->ph_var);
2661 139120 : case T_RangeTblFunction:
2662 139120 : return WALK(((RangeTblFunction *) node)->funcexpr);
2663 615 : case T_TableSampleClause:
2664 : {
2665 615 : TableSampleClause *tsc = (TableSampleClause *) node;
2666 :
2667 615 : if (LIST_WALK(tsc->args))
2668 0 : return true;
2669 615 : if (WALK(tsc->repeatable))
2670 0 : return true;
2671 : }
2672 615 : break;
2673 2558 : case T_TableFunc:
2674 : {
2675 2558 : TableFunc *tf = (TableFunc *) node;
2676 :
2677 2558 : if (WALK(tf->ns_uris))
2678 0 : return true;
2679 2558 : if (WALK(tf->docexpr))
2680 60 : return true;
2681 2498 : if (WALK(tf->rowexpr))
2682 0 : return true;
2683 2498 : if (WALK(tf->colexprs))
2684 0 : return true;
2685 2498 : if (WALK(tf->coldefexprs))
2686 0 : return true;
2687 2498 : if (WALK(tf->colvalexprs))
2688 0 : return true;
2689 2498 : if (WALK(tf->passingvalexprs))
2690 0 : return true;
2691 : }
2692 2498 : break;
2693 152 : case T_GraphElementPattern:
2694 : {
2695 152 : GraphElementPattern *gep = (GraphElementPattern *) node;
2696 :
2697 152 : if (WALK(gep->subexpr))
2698 0 : return true;
2699 152 : if (WALK(gep->whereClause))
2700 0 : return true;
2701 : }
2702 152 : break;
2703 60 : case T_GraphPattern:
2704 : {
2705 60 : GraphPattern *gp = (GraphPattern *) node;
2706 :
2707 60 : if (LIST_WALK(gp->path_pattern_list))
2708 0 : return true;
2709 60 : if (WALK(gp->whereClause))
2710 0 : return true;
2711 : }
2712 60 : break;
2713 0 : default:
2714 0 : elog(ERROR, "unrecognized node type: %d",
2715 : (int) nodeTag(node));
2716 : break;
2717 : }
2718 64398138 : return false;
2719 :
2720 : /* The WALK() macro can be re-used below, but LIST_WALK() not so much */
2721 : #undef LIST_WALK
2722 : }
2723 :
2724 : /*
2725 : * query_tree_walker --- initiate a walk of a Query's expressions
2726 : *
2727 : * This routine exists just to reduce the number of places that need to know
2728 : * where all the expression subtrees of a Query are. Note it can be used
2729 : * for starting a walk at top level of a Query regardless of whether the
2730 : * walker intends to descend into subqueries. It is also useful for
2731 : * descending into subqueries within a walker.
2732 : *
2733 : * Some callers want to suppress visitation of certain items in the sub-Query,
2734 : * typically because they need to process them specially, or don't actually
2735 : * want to recurse into subqueries. This is supported by the flags argument,
2736 : * which is the bitwise OR of flag values to add or suppress visitation of
2737 : * indicated items. (More flag bits may be added as needed.)
2738 : */
2739 : bool
2740 1256676 : query_tree_walker_impl(Query *query,
2741 : tree_walker_callback walker,
2742 : void *context,
2743 : int flags)
2744 : {
2745 : Assert(query != NULL && IsA(query, Query));
2746 :
2747 : /*
2748 : * We don't walk any utilityStmt here. However, we can't easily assert
2749 : * that it is absent, since there are at least two code paths by which
2750 : * action statements from CREATE RULE end up here, and NOTIFY is allowed
2751 : * in a rule action.
2752 : */
2753 :
2754 1256676 : if (WALK(query->targetList))
2755 232738 : return true;
2756 1023918 : if (WALK(query->withCheckOptions))
2757 0 : return true;
2758 1023918 : if (WALK(query->onConflict))
2759 0 : return true;
2760 1023918 : if (WALK(query->mergeActionList))
2761 326 : return true;
2762 1023592 : if (WALK(query->mergeJoinCondition))
2763 227 : return true;
2764 1023365 : if (WALK(query->forPortionOf))
2765 0 : return true;
2766 1023365 : if (WALK(query->returningList))
2767 57 : return true;
2768 1023308 : if (WALK(query->jointree))
2769 49522 : return true;
2770 973778 : if (WALK(query->setOperations))
2771 0 : return true;
2772 973778 : if (WALK(query->havingQual))
2773 0 : return true;
2774 973778 : if (WALK(query->limitOffset))
2775 4 : return true;
2776 973774 : if (WALK(query->limitCount))
2777 0 : return true;
2778 :
2779 : /*
2780 : * Most callers aren't interested in SortGroupClause nodes since those
2781 : * don't contain actual expressions. However they do contain OIDs which
2782 : * may be needed by dependency walkers etc.
2783 : */
2784 973774 : if ((flags & QTW_EXAMINE_SORTGROUP))
2785 : {
2786 42608 : if (WALK(query->groupClause))
2787 0 : return true;
2788 42608 : if (WALK(query->windowClause))
2789 0 : return true;
2790 42608 : if (WALK(query->sortClause))
2791 0 : return true;
2792 42608 : if (WALK(query->distinctClause))
2793 0 : return true;
2794 : }
2795 : else
2796 : {
2797 : /*
2798 : * But we need to walk the expressions under WindowClause nodes even
2799 : * if we're not interested in SortGroupClause nodes.
2800 : */
2801 : ListCell *lc;
2802 :
2803 935854 : foreach(lc, query->windowClause)
2804 : {
2805 4693 : WindowClause *wc = lfirst_node(WindowClause, lc);
2806 :
2807 4693 : if (WALK(wc->startOffset))
2808 5 : return true;
2809 4688 : if (WALK(wc->endOffset))
2810 0 : return true;
2811 : }
2812 : }
2813 :
2814 : /*
2815 : * groupingSets and rowMarks are not walked:
2816 : *
2817 : * groupingSets contain only ressortgrouprefs (integers) which are
2818 : * meaningless without the corresponding groupClause or tlist.
2819 : * Accordingly, any walker that needs to care about them needs to handle
2820 : * them itself in its Query processing.
2821 : *
2822 : * rowMarks is not walked because it contains only rangetable indexes (and
2823 : * flags etc.) and therefore should be handled at Query level similarly.
2824 : */
2825 :
2826 973769 : if (!(flags & QTW_IGNORE_CTE_SUBQUERIES))
2827 : {
2828 563493 : if (WALK(query->cteList))
2829 150 : return true;
2830 : }
2831 973619 : if (!(flags & QTW_IGNORE_RANGE_TABLE))
2832 : {
2833 598115 : if (range_table_walker(query->rtable, walker, context, flags))
2834 16532 : return true;
2835 : }
2836 957087 : return false;
2837 : }
2838 :
2839 : /*
2840 : * range_table_walker is just the part of query_tree_walker that scans
2841 : * a query's rangetable. This is split out since it can be useful on
2842 : * its own.
2843 : */
2844 : bool
2845 602165 : range_table_walker_impl(List *rtable,
2846 : tree_walker_callback walker,
2847 : void *context,
2848 : int flags)
2849 : {
2850 : ListCell *rt;
2851 :
2852 1503559 : foreach(rt, rtable)
2853 : {
2854 917926 : RangeTblEntry *rte = lfirst_node(RangeTblEntry, rt);
2855 :
2856 917926 : if (range_table_entry_walker(rte, walker, context, flags))
2857 16532 : return true;
2858 : }
2859 585633 : return false;
2860 : }
2861 :
2862 : /*
2863 : * Some callers even want to scan the expressions in individual RTEs.
2864 : */
2865 : bool
2866 917946 : range_table_entry_walker_impl(RangeTblEntry *rte,
2867 : tree_walker_callback walker,
2868 : void *context,
2869 : int flags)
2870 : {
2871 : /*
2872 : * Walkers might need to examine the RTE node itself either before or
2873 : * after visiting its contents (or, conceivably, both). Note that if you
2874 : * specify neither flag, the walker won't be called on the RTE at all.
2875 : */
2876 917946 : if (flags & QTW_EXAMINE_RTES_BEFORE)
2877 102170 : if (WALK(rte))
2878 10 : return true;
2879 :
2880 917936 : switch (rte->rtekind)
2881 : {
2882 553432 : case RTE_RELATION:
2883 553432 : if (WALK(rte->tablesample))
2884 0 : return true;
2885 553432 : break;
2886 103424 : case RTE_SUBQUERY:
2887 103424 : if (!(flags & QTW_IGNORE_RT_SUBQUERIES))
2888 101707 : if (WALK(rte->subquery))
2889 3615 : return true;
2890 99809 : break;
2891 143520 : case RTE_JOIN:
2892 143520 : if (!(flags & QTW_IGNORE_JOINALIASES))
2893 124580 : if (WALK(rte->joinaliasvars))
2894 0 : return true;
2895 143520 : break;
2896 59989 : case RTE_FUNCTION:
2897 59989 : if (WALK(rte->functions))
2898 12850 : return true;
2899 47139 : break;
2900 791 : case RTE_TABLEFUNC:
2901 791 : if (WALK(rte->tablefunc))
2902 0 : return true;
2903 791 : break;
2904 21134 : case RTE_VALUES:
2905 21134 : if (WALK(rte->values_lists))
2906 41 : return true;
2907 21093 : break;
2908 60 : case RTE_GRAPH_TABLE:
2909 60 : if (WALK(rte->graph_pattern))
2910 0 : return true;
2911 60 : if (WALK(rte->graph_table_columns))
2912 0 : return true;
2913 60 : break;
2914 30109 : case RTE_CTE:
2915 : case RTE_NAMEDTUPLESTORE:
2916 : case RTE_RESULT:
2917 : /* nothing to do */
2918 30109 : break;
2919 5477 : case RTE_GROUP:
2920 5477 : if (!(flags & QTW_IGNORE_GROUPEXPRS))
2921 5477 : if (WALK(rte->groupexprs))
2922 21 : return true;
2923 5456 : break;
2924 : }
2925 :
2926 901409 : if (WALK(rte->securityQuals))
2927 15 : return true;
2928 :
2929 901394 : if (flags & QTW_EXAMINE_RTES_AFTER)
2930 12196 : if (WALK(rte))
2931 0 : return true;
2932 :
2933 901394 : return false;
2934 : }
2935 :
2936 :
2937 : /*
2938 : * expression_tree_mutator() is designed to support routines that make a
2939 : * modified copy of an expression tree, with some nodes being added,
2940 : * removed, or replaced by new subtrees. The original tree is (normally)
2941 : * not changed. Each recursion level is responsible for returning a copy of
2942 : * (or appropriately modified substitute for) the subtree it is handed.
2943 : * A mutator routine should look like this:
2944 : *
2945 : * Node * my_mutator (Node *node, my_struct *context)
2946 : * {
2947 : * if (node == NULL)
2948 : * return NULL;
2949 : * // check for nodes that special work is required for, eg:
2950 : * if (IsA(node, Var))
2951 : * {
2952 : * ... create and return modified copy of Var node
2953 : * }
2954 : * else if (IsA(node, ...))
2955 : * {
2956 : * ... do special transformations of other node types
2957 : * }
2958 : * // for any node type not specially processed, do:
2959 : * return expression_tree_mutator(node, my_mutator, context);
2960 : * }
2961 : *
2962 : * The "context" argument points to a struct that holds whatever context
2963 : * information the mutator routine needs --- it can be used to return extra
2964 : * data gathered by the mutator, too. This argument is not touched by
2965 : * expression_tree_mutator, but it is passed down to recursive sub-invocations
2966 : * of my_mutator. The tree walk is started from a setup routine that
2967 : * fills in the appropriate context struct, calls my_mutator with the
2968 : * top-level node of the tree, and does any required post-processing.
2969 : *
2970 : * Each level of recursion must return an appropriately modified Node.
2971 : * If expression_tree_mutator() is called, it will make an exact copy
2972 : * of the given Node, but invoke my_mutator() to copy the sub-node(s)
2973 : * of that Node. In this way, my_mutator() has full control over the
2974 : * copying process but need not directly deal with expression trees
2975 : * that it has no interest in.
2976 : *
2977 : * Just as for expression_tree_walker, the node types handled by
2978 : * expression_tree_mutator include all those normally found in target lists
2979 : * and qualifier clauses during the planning stage.
2980 : *
2981 : * expression_tree_mutator will handle SubLink nodes by recursing normally
2982 : * into the "testexpr" subtree (which is an expression belonging to the outer
2983 : * plan). It will also call the mutator on the sub-Query node; however, when
2984 : * expression_tree_mutator itself is called on a Query node, it does nothing
2985 : * and returns the unmodified Query node. The net effect is that unless the
2986 : * mutator does something special at a Query node, sub-selects will not be
2987 : * visited or modified; the original sub-select will be linked to by the new
2988 : * SubLink node. Mutators that want to descend into sub-selects will usually
2989 : * do so by recognizing Query nodes and calling query_tree_mutator (below).
2990 : *
2991 : * expression_tree_mutator will handle a SubPlan node by recursing into the
2992 : * "testexpr" and the "args" list (which belong to the outer plan), but it
2993 : * will simply copy the link to the inner plan, since that's typically what
2994 : * expression tree mutators want. A mutator that wants to modify the subplan
2995 : * can force appropriate behavior by recognizing SubPlan expression nodes
2996 : * and doing the right thing.
2997 : */
2998 :
2999 : Node *
3000 16081088 : expression_tree_mutator_impl(Node *node,
3001 : tree_mutator_callback mutator,
3002 : void *context)
3003 : {
3004 : /*
3005 : * The mutator has already decided not to modify the current node, but we
3006 : * must call the mutator for any sub-nodes.
3007 : */
3008 :
3009 : #define FLATCOPY(newnode, node, nodetype) \
3010 : ( (newnode) = palloc_object(nodetype), \
3011 : memcpy((newnode), (node), sizeof(nodetype)) )
3012 :
3013 : #define MUTATE(newfield, oldfield, fieldtype) \
3014 : ( (newfield) = (fieldtype) mutator((Node *) (oldfield), context) )
3015 :
3016 16081088 : if (node == NULL)
3017 52232 : return NULL;
3018 :
3019 : /* Guard against stack overflow due to overly complex expressions */
3020 16028856 : check_stack_depth();
3021 :
3022 16028856 : switch (nodeTag(node))
3023 : {
3024 : /*
3025 : * Primitive node types with no expression subnodes. Var and
3026 : * Const are frequent enough to deserve special cases, the others
3027 : * we just use copyObject for.
3028 : */
3029 3064612 : case T_Var:
3030 : {
3031 3064612 : Var *var = (Var *) node;
3032 : Var *newnode;
3033 :
3034 3064612 : FLATCOPY(newnode, var, Var);
3035 : /* Assume we need not copy the varnullingrels bitmapset */
3036 3064612 : return (Node *) newnode;
3037 : }
3038 : break;
3039 2532466 : case T_Const:
3040 : {
3041 2532466 : Const *oldnode = (Const *) node;
3042 : Const *newnode;
3043 :
3044 2532466 : FLATCOPY(newnode, oldnode, Const);
3045 : /* XXX we don't bother with datumCopy; should we? */
3046 2532466 : return (Node *) newnode;
3047 : }
3048 : break;
3049 108366 : case T_Param:
3050 : case T_CaseTestExpr:
3051 : case T_SQLValueFunction:
3052 : case T_JsonFormat:
3053 : case T_CoerceToDomainValue:
3054 : case T_SetToDefault:
3055 : case T_CurrentOfExpr:
3056 : case T_NextValueExpr:
3057 : case T_RangeTblRef:
3058 : case T_SortGroupClause:
3059 : case T_CTESearchClause:
3060 : case T_MergeSupportFunc:
3061 108366 : return copyObject(node);
3062 1105 : case T_WithCheckOption:
3063 : {
3064 1105 : WithCheckOption *wco = (WithCheckOption *) node;
3065 : WithCheckOption *newnode;
3066 :
3067 1105 : FLATCOPY(newnode, wco, WithCheckOption);
3068 1105 : MUTATE(newnode->qual, wco->qual, Node *);
3069 1105 : return (Node *) newnode;
3070 : }
3071 141015 : case T_Aggref:
3072 : {
3073 141015 : Aggref *aggref = (Aggref *) node;
3074 : Aggref *newnode;
3075 :
3076 141015 : FLATCOPY(newnode, aggref, Aggref);
3077 : /* assume mutation doesn't change types of arguments */
3078 141015 : newnode->aggargtypes = list_copy(aggref->aggargtypes);
3079 141015 : MUTATE(newnode->aggdirectargs, aggref->aggdirectargs, List *);
3080 141015 : MUTATE(newnode->args, aggref->args, List *);
3081 141015 : MUTATE(newnode->aggorder, aggref->aggorder, List *);
3082 141015 : MUTATE(newnode->aggdistinct, aggref->aggdistinct, List *);
3083 141015 : MUTATE(newnode->aggfilter, aggref->aggfilter, Expr *);
3084 141015 : return (Node *) newnode;
3085 : }
3086 : break;
3087 1273 : case T_GroupingFunc:
3088 : {
3089 1273 : GroupingFunc *grouping = (GroupingFunc *) node;
3090 : GroupingFunc *newnode;
3091 :
3092 1273 : FLATCOPY(newnode, grouping, GroupingFunc);
3093 1273 : MUTATE(newnode->args, grouping->args, List *);
3094 :
3095 : /*
3096 : * We assume here that mutating the arguments does not change
3097 : * the semantics, i.e. that the arguments are not mutated in a
3098 : * way that makes them semantically different from their
3099 : * previously matching expressions in the GROUP BY clause.
3100 : *
3101 : * If a mutator somehow wanted to do this, it would have to
3102 : * handle the refs and cols lists itself as appropriate.
3103 : */
3104 1273 : newnode->refs = list_copy(grouping->refs);
3105 1273 : newnode->cols = list_copy(grouping->cols);
3106 :
3107 1273 : return (Node *) newnode;
3108 : }
3109 : break;
3110 4701 : case T_WindowFunc:
3111 : {
3112 4701 : WindowFunc *wfunc = (WindowFunc *) node;
3113 : WindowFunc *newnode;
3114 :
3115 4701 : FLATCOPY(newnode, wfunc, WindowFunc);
3116 4701 : MUTATE(newnode->args, wfunc->args, List *);
3117 4701 : MUTATE(newnode->aggfilter, wfunc->aggfilter, Expr *);
3118 4701 : return (Node *) newnode;
3119 : }
3120 : break;
3121 0 : case T_WindowFuncRunCondition:
3122 : {
3123 0 : WindowFuncRunCondition *wfuncrc = (WindowFuncRunCondition *) node;
3124 : WindowFuncRunCondition *newnode;
3125 :
3126 0 : FLATCOPY(newnode, wfuncrc, WindowFuncRunCondition);
3127 0 : MUTATE(newnode->arg, wfuncrc->arg, Expr *);
3128 0 : return (Node *) newnode;
3129 : }
3130 : break;
3131 55424 : case T_SubscriptingRef:
3132 : {
3133 55424 : SubscriptingRef *sbsref = (SubscriptingRef *) node;
3134 : SubscriptingRef *newnode;
3135 :
3136 55424 : FLATCOPY(newnode, sbsref, SubscriptingRef);
3137 55424 : MUTATE(newnode->refupperindexpr, sbsref->refupperindexpr,
3138 : List *);
3139 55424 : MUTATE(newnode->reflowerindexpr, sbsref->reflowerindexpr,
3140 : List *);
3141 55424 : MUTATE(newnode->refexpr, sbsref->refexpr,
3142 : Expr *);
3143 55424 : MUTATE(newnode->refassgnexpr, sbsref->refassgnexpr,
3144 : Expr *);
3145 :
3146 55424 : return (Node *) newnode;
3147 : }
3148 : break;
3149 272460 : case T_FuncExpr:
3150 : {
3151 272460 : FuncExpr *expr = (FuncExpr *) node;
3152 : FuncExpr *newnode;
3153 :
3154 272460 : FLATCOPY(newnode, expr, FuncExpr);
3155 272460 : MUTATE(newnode->args, expr->args, List *);
3156 272460 : return (Node *) newnode;
3157 : }
3158 : break;
3159 0 : case T_NamedArgExpr:
3160 : {
3161 0 : NamedArgExpr *nexpr = (NamedArgExpr *) node;
3162 : NamedArgExpr *newnode;
3163 :
3164 0 : FLATCOPY(newnode, nexpr, NamedArgExpr);
3165 0 : MUTATE(newnode->arg, nexpr->arg, Expr *);
3166 0 : return (Node *) newnode;
3167 : }
3168 : break;
3169 1069346 : case T_OpExpr:
3170 : {
3171 1069346 : OpExpr *expr = (OpExpr *) node;
3172 : OpExpr *newnode;
3173 :
3174 1069346 : FLATCOPY(newnode, expr, OpExpr);
3175 1069346 : MUTATE(newnode->args, expr->args, List *);
3176 1069338 : return (Node *) newnode;
3177 : }
3178 : break;
3179 2191 : case T_DistinctExpr:
3180 : {
3181 2191 : DistinctExpr *expr = (DistinctExpr *) node;
3182 : DistinctExpr *newnode;
3183 :
3184 2191 : FLATCOPY(newnode, expr, DistinctExpr);
3185 2191 : MUTATE(newnode->args, expr->args, List *);
3186 2191 : return (Node *) newnode;
3187 : }
3188 : break;
3189 1459 : case T_NullIfExpr:
3190 : {
3191 1459 : NullIfExpr *expr = (NullIfExpr *) node;
3192 : NullIfExpr *newnode;
3193 :
3194 1459 : FLATCOPY(newnode, expr, NullIfExpr);
3195 1459 : MUTATE(newnode->args, expr->args, List *);
3196 1459 : return (Node *) newnode;
3197 : }
3198 : break;
3199 68925 : case T_ScalarArrayOpExpr:
3200 : {
3201 68925 : ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
3202 : ScalarArrayOpExpr *newnode;
3203 :
3204 68925 : FLATCOPY(newnode, expr, ScalarArrayOpExpr);
3205 68925 : MUTATE(newnode->args, expr->args, List *);
3206 68925 : return (Node *) newnode;
3207 : }
3208 : break;
3209 155551 : case T_BoolExpr:
3210 : {
3211 155551 : BoolExpr *expr = (BoolExpr *) node;
3212 : BoolExpr *newnode;
3213 :
3214 155551 : FLATCOPY(newnode, expr, BoolExpr);
3215 155551 : MUTATE(newnode->args, expr->args, List *);
3216 155547 : return (Node *) newnode;
3217 : }
3218 : break;
3219 42936 : case T_SubLink:
3220 : {
3221 42936 : SubLink *sublink = (SubLink *) node;
3222 : SubLink *newnode;
3223 :
3224 42936 : FLATCOPY(newnode, sublink, SubLink);
3225 42936 : MUTATE(newnode->testexpr, sublink->testexpr, Node *);
3226 :
3227 : /*
3228 : * Also invoke the mutator on the sublink's Query node, so it
3229 : * can recurse into the sub-query if it wants to.
3230 : */
3231 42936 : MUTATE(newnode->subselect, sublink->subselect, Node *);
3232 42936 : return (Node *) newnode;
3233 : }
3234 : break;
3235 14732 : case T_SubPlan:
3236 : {
3237 14732 : SubPlan *subplan = (SubPlan *) node;
3238 : SubPlan *newnode;
3239 :
3240 14732 : FLATCOPY(newnode, subplan, SubPlan);
3241 : /* transform testexpr */
3242 14732 : MUTATE(newnode->testexpr, subplan->testexpr, Node *);
3243 : /* transform args list (params to be passed to subplan) */
3244 14732 : MUTATE(newnode->args, subplan->args, List *);
3245 : /* but not the sub-Plan itself, which is referenced as-is */
3246 14732 : return (Node *) newnode;
3247 : }
3248 : break;
3249 180 : case T_AlternativeSubPlan:
3250 : {
3251 180 : AlternativeSubPlan *asplan = (AlternativeSubPlan *) node;
3252 : AlternativeSubPlan *newnode;
3253 :
3254 180 : FLATCOPY(newnode, asplan, AlternativeSubPlan);
3255 180 : MUTATE(newnode->subplans, asplan->subplans, List *);
3256 180 : return (Node *) newnode;
3257 : }
3258 : break;
3259 86733 : case T_FieldSelect:
3260 : {
3261 86733 : FieldSelect *fselect = (FieldSelect *) node;
3262 : FieldSelect *newnode;
3263 :
3264 86733 : FLATCOPY(newnode, fselect, FieldSelect);
3265 86733 : MUTATE(newnode->arg, fselect->arg, Expr *);
3266 86733 : return (Node *) newnode;
3267 : }
3268 : break;
3269 360 : case T_FieldStore:
3270 : {
3271 360 : FieldStore *fstore = (FieldStore *) node;
3272 : FieldStore *newnode;
3273 :
3274 360 : FLATCOPY(newnode, fstore, FieldStore);
3275 360 : MUTATE(newnode->arg, fstore->arg, Expr *);
3276 360 : MUTATE(newnode->newvals, fstore->newvals, List *);
3277 360 : newnode->fieldnums = list_copy(fstore->fieldnums);
3278 360 : return (Node *) newnode;
3279 : }
3280 : break;
3281 125090 : case T_RelabelType:
3282 : {
3283 125090 : RelabelType *relabel = (RelabelType *) node;
3284 : RelabelType *newnode;
3285 :
3286 125090 : FLATCOPY(newnode, relabel, RelabelType);
3287 125090 : MUTATE(newnode->arg, relabel->arg, Expr *);
3288 125090 : return (Node *) newnode;
3289 : }
3290 : break;
3291 31793 : case T_CoerceViaIO:
3292 : {
3293 31793 : CoerceViaIO *iocoerce = (CoerceViaIO *) node;
3294 : CoerceViaIO *newnode;
3295 :
3296 31793 : FLATCOPY(newnode, iocoerce, CoerceViaIO);
3297 31793 : MUTATE(newnode->arg, iocoerce->arg, Expr *);
3298 31793 : return (Node *) newnode;
3299 : }
3300 : break;
3301 10580 : case T_ArrayCoerceExpr:
3302 : {
3303 10580 : ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node;
3304 : ArrayCoerceExpr *newnode;
3305 :
3306 10580 : FLATCOPY(newnode, acoerce, ArrayCoerceExpr);
3307 10580 : MUTATE(newnode->arg, acoerce->arg, Expr *);
3308 10580 : MUTATE(newnode->elemexpr, acoerce->elemexpr, Expr *);
3309 10580 : return (Node *) newnode;
3310 : }
3311 : break;
3312 278 : case T_ConvertRowtypeExpr:
3313 : {
3314 278 : ConvertRowtypeExpr *convexpr = (ConvertRowtypeExpr *) node;
3315 : ConvertRowtypeExpr *newnode;
3316 :
3317 278 : FLATCOPY(newnode, convexpr, ConvertRowtypeExpr);
3318 278 : MUTATE(newnode->arg, convexpr->arg, Expr *);
3319 278 : return (Node *) newnode;
3320 : }
3321 : break;
3322 6064 : case T_CollateExpr:
3323 : {
3324 6064 : CollateExpr *collate = (CollateExpr *) node;
3325 : CollateExpr *newnode;
3326 :
3327 6064 : FLATCOPY(newnode, collate, CollateExpr);
3328 6064 : MUTATE(newnode->arg, collate->arg, Expr *);
3329 6064 : return (Node *) newnode;
3330 : }
3331 : break;
3332 66089 : case T_CaseExpr:
3333 : {
3334 66089 : CaseExpr *caseexpr = (CaseExpr *) node;
3335 : CaseExpr *newnode;
3336 :
3337 66089 : FLATCOPY(newnode, caseexpr, CaseExpr);
3338 66089 : MUTATE(newnode->arg, caseexpr->arg, Expr *);
3339 66089 : MUTATE(newnode->args, caseexpr->args, List *);
3340 66089 : MUTATE(newnode->defresult, caseexpr->defresult, Expr *);
3341 66089 : return (Node *) newnode;
3342 : }
3343 : break;
3344 148966 : case T_CaseWhen:
3345 : {
3346 148966 : CaseWhen *casewhen = (CaseWhen *) node;
3347 : CaseWhen *newnode;
3348 :
3349 148966 : FLATCOPY(newnode, casewhen, CaseWhen);
3350 148966 : MUTATE(newnode->expr, casewhen->expr, Expr *);
3351 148966 : MUTATE(newnode->result, casewhen->result, Expr *);
3352 148966 : return (Node *) newnode;
3353 : }
3354 : break;
3355 32492 : case T_ArrayExpr:
3356 : {
3357 32492 : ArrayExpr *arrayexpr = (ArrayExpr *) node;
3358 : ArrayExpr *newnode;
3359 :
3360 32492 : FLATCOPY(newnode, arrayexpr, ArrayExpr);
3361 32492 : MUTATE(newnode->elements, arrayexpr->elements, List *);
3362 32492 : return (Node *) newnode;
3363 : }
3364 : break;
3365 7218 : case T_RowExpr:
3366 : {
3367 7218 : RowExpr *rowexpr = (RowExpr *) node;
3368 : RowExpr *newnode;
3369 :
3370 7218 : FLATCOPY(newnode, rowexpr, RowExpr);
3371 7218 : MUTATE(newnode->args, rowexpr->args, List *);
3372 : /* Assume colnames needn't be duplicated */
3373 7218 : return (Node *) newnode;
3374 : }
3375 : break;
3376 515 : case T_RowCompareExpr:
3377 : {
3378 515 : RowCompareExpr *rcexpr = (RowCompareExpr *) node;
3379 : RowCompareExpr *newnode;
3380 :
3381 515 : FLATCOPY(newnode, rcexpr, RowCompareExpr);
3382 515 : MUTATE(newnode->largs, rcexpr->largs, List *);
3383 515 : MUTATE(newnode->rargs, rcexpr->rargs, List *);
3384 515 : return (Node *) newnode;
3385 : }
3386 : break;
3387 9460 : case T_CoalesceExpr:
3388 : {
3389 9460 : CoalesceExpr *coalesceexpr = (CoalesceExpr *) node;
3390 : CoalesceExpr *newnode;
3391 :
3392 9460 : FLATCOPY(newnode, coalesceexpr, CoalesceExpr);
3393 9460 : MUTATE(newnode->args, coalesceexpr->args, List *);
3394 9460 : return (Node *) newnode;
3395 : }
3396 : break;
3397 1131 : case T_MinMaxExpr:
3398 : {
3399 1131 : MinMaxExpr *minmaxexpr = (MinMaxExpr *) node;
3400 : MinMaxExpr *newnode;
3401 :
3402 1131 : FLATCOPY(newnode, minmaxexpr, MinMaxExpr);
3403 1131 : MUTATE(newnode->args, minmaxexpr->args, List *);
3404 1131 : return (Node *) newnode;
3405 : }
3406 : break;
3407 683 : case T_XmlExpr:
3408 : {
3409 683 : XmlExpr *xexpr = (XmlExpr *) node;
3410 : XmlExpr *newnode;
3411 :
3412 683 : FLATCOPY(newnode, xexpr, XmlExpr);
3413 683 : MUTATE(newnode->named_args, xexpr->named_args, List *);
3414 : /* assume mutator does not care about arg_names */
3415 683 : MUTATE(newnode->args, xexpr->args, List *);
3416 683 : return (Node *) newnode;
3417 : }
3418 : break;
3419 2207 : case T_JsonReturning:
3420 : {
3421 2207 : JsonReturning *jr = (JsonReturning *) node;
3422 : JsonReturning *newnode;
3423 :
3424 2207 : FLATCOPY(newnode, jr, JsonReturning);
3425 2207 : MUTATE(newnode->format, jr->format, JsonFormat *);
3426 :
3427 2207 : return (Node *) newnode;
3428 : }
3429 149 : case T_JsonValueExpr:
3430 : {
3431 149 : JsonValueExpr *jve = (JsonValueExpr *) node;
3432 : JsonValueExpr *newnode;
3433 :
3434 149 : FLATCOPY(newnode, jve, JsonValueExpr);
3435 149 : MUTATE(newnode->raw_expr, jve->raw_expr, Expr *);
3436 149 : MUTATE(newnode->formatted_expr, jve->formatted_expr, Expr *);
3437 149 : MUTATE(newnode->format, jve->format, JsonFormat *);
3438 :
3439 149 : return (Node *) newnode;
3440 : }
3441 2207 : case T_JsonConstructorExpr:
3442 : {
3443 2207 : JsonConstructorExpr *jce = (JsonConstructorExpr *) node;
3444 : JsonConstructorExpr *newnode;
3445 :
3446 2207 : FLATCOPY(newnode, jce, JsonConstructorExpr);
3447 2207 : MUTATE(newnode->args, jce->args, List *);
3448 2207 : MUTATE(newnode->func, jce->func, Expr *);
3449 2207 : MUTATE(newnode->coercion, jce->coercion, Expr *);
3450 2207 : MUTATE(newnode->returning, jce->returning, JsonReturning *);
3451 :
3452 2207 : return (Node *) newnode;
3453 : }
3454 506 : case T_JsonIsPredicate:
3455 : {
3456 506 : JsonIsPredicate *pred = (JsonIsPredicate *) node;
3457 : JsonIsPredicate *newnode;
3458 :
3459 506 : FLATCOPY(newnode, pred, JsonIsPredicate);
3460 506 : MUTATE(newnode->expr, pred->expr, Node *);
3461 506 : MUTATE(newnode->format, pred->format, JsonFormat *);
3462 :
3463 506 : return (Node *) newnode;
3464 : }
3465 3220 : case T_JsonExpr:
3466 : {
3467 3220 : JsonExpr *jexpr = (JsonExpr *) node;
3468 : JsonExpr *newnode;
3469 :
3470 3220 : FLATCOPY(newnode, jexpr, JsonExpr);
3471 3220 : MUTATE(newnode->formatted_expr, jexpr->formatted_expr, Node *);
3472 3220 : MUTATE(newnode->path_spec, jexpr->path_spec, Node *);
3473 3216 : MUTATE(newnode->passing_values, jexpr->passing_values, List *);
3474 : /* assume mutator does not care about passing_names */
3475 3216 : MUTATE(newnode->on_empty, jexpr->on_empty, JsonBehavior *);
3476 3212 : MUTATE(newnode->on_error, jexpr->on_error, JsonBehavior *);
3477 3208 : return (Node *) newnode;
3478 : }
3479 : break;
3480 5655 : case T_JsonBehavior:
3481 : {
3482 5655 : JsonBehavior *behavior = (JsonBehavior *) node;
3483 : JsonBehavior *newnode;
3484 :
3485 5655 : FLATCOPY(newnode, behavior, JsonBehavior);
3486 5655 : MUTATE(newnode->expr, behavior->expr, Node *);
3487 5647 : return (Node *) newnode;
3488 : }
3489 : break;
3490 36108 : case T_NullTest:
3491 : {
3492 36108 : NullTest *ntest = (NullTest *) node;
3493 : NullTest *newnode;
3494 :
3495 36108 : FLATCOPY(newnode, ntest, NullTest);
3496 36108 : MUTATE(newnode->arg, ntest->arg, Expr *);
3497 36108 : return (Node *) newnode;
3498 : }
3499 : break;
3500 1922 : case T_BooleanTest:
3501 : {
3502 1922 : BooleanTest *btest = (BooleanTest *) node;
3503 : BooleanTest *newnode;
3504 :
3505 1922 : FLATCOPY(newnode, btest, BooleanTest);
3506 1922 : MUTATE(newnode->arg, btest->arg, Expr *);
3507 1922 : return (Node *) newnode;
3508 : }
3509 : break;
3510 14779 : case T_CoerceToDomain:
3511 : {
3512 14779 : CoerceToDomain *ctest = (CoerceToDomain *) node;
3513 : CoerceToDomain *newnode;
3514 :
3515 14779 : FLATCOPY(newnode, ctest, CoerceToDomain);
3516 14779 : MUTATE(newnode->arg, ctest->arg, Expr *);
3517 14779 : return (Node *) newnode;
3518 : }
3519 : break;
3520 1633 : case T_ReturningExpr:
3521 : {
3522 1633 : ReturningExpr *rexpr = (ReturningExpr *) node;
3523 : ReturningExpr *newnode;
3524 :
3525 1633 : FLATCOPY(newnode, rexpr, ReturningExpr);
3526 1633 : MUTATE(newnode->retexpr, rexpr->retexpr, Expr *);
3527 1633 : return (Node *) newnode;
3528 : }
3529 : break;
3530 3388311 : case T_TargetEntry:
3531 : {
3532 3388311 : TargetEntry *targetentry = (TargetEntry *) node;
3533 : TargetEntry *newnode;
3534 :
3535 3388311 : FLATCOPY(newnode, targetentry, TargetEntry);
3536 3388311 : MUTATE(newnode->expr, targetentry->expr, Expr *);
3537 3385598 : return (Node *) newnode;
3538 : }
3539 : break;
3540 30469 : case T_Query:
3541 : /* Do nothing with a sub-Query, per discussion above */
3542 30469 : return node;
3543 0 : case T_WindowClause:
3544 : {
3545 0 : WindowClause *wc = (WindowClause *) node;
3546 : WindowClause *newnode;
3547 :
3548 0 : FLATCOPY(newnode, wc, WindowClause);
3549 0 : MUTATE(newnode->partitionClause, wc->partitionClause, List *);
3550 0 : MUTATE(newnode->orderClause, wc->orderClause, List *);
3551 0 : MUTATE(newnode->startOffset, wc->startOffset, Node *);
3552 0 : MUTATE(newnode->endOffset, wc->endOffset, Node *);
3553 0 : return (Node *) newnode;
3554 : }
3555 : break;
3556 0 : case T_CTECycleClause:
3557 : {
3558 0 : CTECycleClause *cc = (CTECycleClause *) node;
3559 : CTECycleClause *newnode;
3560 :
3561 0 : FLATCOPY(newnode, cc, CTECycleClause);
3562 0 : MUTATE(newnode->cycle_mark_value, cc->cycle_mark_value, Node *);
3563 0 : MUTATE(newnode->cycle_mark_default, cc->cycle_mark_default, Node *);
3564 0 : return (Node *) newnode;
3565 : }
3566 : break;
3567 164 : case T_CommonTableExpr:
3568 : {
3569 164 : CommonTableExpr *cte = (CommonTableExpr *) node;
3570 : CommonTableExpr *newnode;
3571 :
3572 164 : FLATCOPY(newnode, cte, CommonTableExpr);
3573 :
3574 : /*
3575 : * Also invoke the mutator on the CTE's Query node, so it can
3576 : * recurse into the sub-query if it wants to.
3577 : */
3578 164 : MUTATE(newnode->ctequery, cte->ctequery, Node *);
3579 :
3580 164 : MUTATE(newnode->search_clause, cte->search_clause, CTESearchClause *);
3581 164 : MUTATE(newnode->cycle_clause, cte->cycle_clause, CTECycleClause *);
3582 :
3583 164 : return (Node *) newnode;
3584 : }
3585 : break;
3586 0 : case T_PartitionBoundSpec:
3587 : {
3588 0 : PartitionBoundSpec *pbs = (PartitionBoundSpec *) node;
3589 : PartitionBoundSpec *newnode;
3590 :
3591 0 : FLATCOPY(newnode, pbs, PartitionBoundSpec);
3592 0 : MUTATE(newnode->listdatums, pbs->listdatums, List *);
3593 0 : MUTATE(newnode->lowerdatums, pbs->lowerdatums, List *);
3594 0 : MUTATE(newnode->upperdatums, pbs->upperdatums, List *);
3595 0 : return (Node *) newnode;
3596 : }
3597 : break;
3598 0 : case T_PartitionRangeDatum:
3599 : {
3600 0 : PartitionRangeDatum *prd = (PartitionRangeDatum *) node;
3601 : PartitionRangeDatum *newnode;
3602 :
3603 0 : FLATCOPY(newnode, prd, PartitionRangeDatum);
3604 0 : MUTATE(newnode->value, prd->value, Node *);
3605 0 : return (Node *) newnode;
3606 : }
3607 : break;
3608 4340179 : case T_List:
3609 : {
3610 : /*
3611 : * We assume the mutator isn't interested in the list nodes
3612 : * per se, so just invoke it on each list element. NOTE: this
3613 : * would fail badly on a list with integer elements!
3614 : */
3615 : List *resultlist;
3616 : ListCell *temp;
3617 :
3618 4340179 : resultlist = NIL;
3619 14042126 : foreach(temp, (List *) node)
3620 : {
3621 9701947 : resultlist = lappend(resultlist,
3622 9704753 : mutator((Node *) lfirst(temp),
3623 : context));
3624 : }
3625 4337373 : return (Node *) resultlist;
3626 : }
3627 : break;
3628 22994 : case T_FromExpr:
3629 : {
3630 22994 : FromExpr *from = (FromExpr *) node;
3631 : FromExpr *newnode;
3632 :
3633 22994 : FLATCOPY(newnode, from, FromExpr);
3634 22994 : MUTATE(newnode->fromlist, from->fromlist, List *);
3635 22994 : MUTATE(newnode->quals, from->quals, Node *);
3636 22994 : return (Node *) newnode;
3637 : }
3638 : break;
3639 364 : case T_OnConflictExpr:
3640 : {
3641 364 : OnConflictExpr *oc = (OnConflictExpr *) node;
3642 : OnConflictExpr *newnode;
3643 :
3644 364 : FLATCOPY(newnode, oc, OnConflictExpr);
3645 364 : MUTATE(newnode->arbiterElems, oc->arbiterElems, List *);
3646 364 : MUTATE(newnode->arbiterWhere, oc->arbiterWhere, Node *);
3647 364 : MUTATE(newnode->onConflictSet, oc->onConflictSet, List *);
3648 364 : MUTATE(newnode->onConflictWhere, oc->onConflictWhere, Node *);
3649 364 : MUTATE(newnode->exclRelTlist, oc->exclRelTlist, List *);
3650 :
3651 364 : return (Node *) newnode;
3652 : }
3653 : break;
3654 712 : case T_MergeAction:
3655 : {
3656 712 : MergeAction *action = (MergeAction *) node;
3657 : MergeAction *newnode;
3658 :
3659 712 : FLATCOPY(newnode, action, MergeAction);
3660 712 : MUTATE(newnode->qual, action->qual, Node *);
3661 712 : MUTATE(newnode->targetList, action->targetList, List *);
3662 :
3663 712 : return (Node *) newnode;
3664 : }
3665 : break;
3666 8 : case T_ForPortionOfExpr:
3667 : {
3668 8 : ForPortionOfExpr *fpo = (ForPortionOfExpr *) node;
3669 : ForPortionOfExpr *newnode;
3670 :
3671 8 : FLATCOPY(newnode, fpo, ForPortionOfExpr);
3672 8 : MUTATE(newnode->rangeVar, fpo->rangeVar, Var *);
3673 8 : MUTATE(newnode->targetFrom, fpo->targetFrom, Node *);
3674 8 : MUTATE(newnode->targetTo, fpo->targetTo, Node *);
3675 8 : MUTATE(newnode->targetRange, fpo->targetRange, Node *);
3676 8 : MUTATE(newnode->overlapsExpr, fpo->overlapsExpr, Node *);
3677 8 : MUTATE(newnode->rangeTargetList, fpo->rangeTargetList, List *);
3678 :
3679 8 : return (Node *) newnode;
3680 : }
3681 : break;
3682 130 : case T_PartitionPruneStepOp:
3683 : {
3684 130 : PartitionPruneStepOp *opstep = (PartitionPruneStepOp *) node;
3685 : PartitionPruneStepOp *newnode;
3686 :
3687 130 : FLATCOPY(newnode, opstep, PartitionPruneStepOp);
3688 130 : MUTATE(newnode->exprs, opstep->exprs, List *);
3689 :
3690 130 : return (Node *) newnode;
3691 : }
3692 : break;
3693 10 : case T_PartitionPruneStepCombine:
3694 : /* no expression sub-nodes */
3695 10 : return copyObject(node);
3696 6082 : case T_JoinExpr:
3697 : {
3698 6082 : JoinExpr *join = (JoinExpr *) node;
3699 : JoinExpr *newnode;
3700 :
3701 6082 : FLATCOPY(newnode, join, JoinExpr);
3702 6082 : MUTATE(newnode->larg, join->larg, Node *);
3703 6082 : MUTATE(newnode->rarg, join->rarg, Node *);
3704 6082 : MUTATE(newnode->quals, join->quals, Node *);
3705 : /* We do not mutate alias or using by default */
3706 6082 : return (Node *) newnode;
3707 : }
3708 : break;
3709 169 : case T_SetOperationStmt:
3710 : {
3711 169 : SetOperationStmt *setop = (SetOperationStmt *) node;
3712 : SetOperationStmt *newnode;
3713 :
3714 169 : FLATCOPY(newnode, setop, SetOperationStmt);
3715 169 : MUTATE(newnode->larg, setop->larg, Node *);
3716 169 : MUTATE(newnode->rarg, setop->rarg, Node *);
3717 : /* We do not mutate groupClauses by default */
3718 169 : return (Node *) newnode;
3719 : }
3720 : break;
3721 447 : case T_IndexClause:
3722 : {
3723 447 : IndexClause *iclause = (IndexClause *) node;
3724 : IndexClause *newnode;
3725 :
3726 447 : FLATCOPY(newnode, iclause, IndexClause);
3727 447 : MUTATE(newnode->rinfo, iclause->rinfo, RestrictInfo *);
3728 447 : MUTATE(newnode->indexquals, iclause->indexquals, List *);
3729 447 : return (Node *) newnode;
3730 : }
3731 : break;
3732 11919 : case T_PlaceHolderVar:
3733 : {
3734 11919 : PlaceHolderVar *phv = (PlaceHolderVar *) node;
3735 : PlaceHolderVar *newnode;
3736 :
3737 11919 : FLATCOPY(newnode, phv, PlaceHolderVar);
3738 11919 : MUTATE(newnode->phexpr, phv->phexpr, Expr *);
3739 : /* Assume we need not copy the relids bitmapsets */
3740 11919 : return (Node *) newnode;
3741 : }
3742 : break;
3743 2355 : case T_InferenceElem:
3744 : {
3745 2355 : InferenceElem *inferenceelemdexpr = (InferenceElem *) node;
3746 : InferenceElem *newnode;
3747 :
3748 2355 : FLATCOPY(newnode, inferenceelemdexpr, InferenceElem);
3749 2355 : MUTATE(newnode->expr, newnode->expr, Node *);
3750 2355 : return (Node *) newnode;
3751 : }
3752 : break;
3753 20043 : case T_AppendRelInfo:
3754 : {
3755 20043 : AppendRelInfo *appinfo = (AppendRelInfo *) node;
3756 : AppendRelInfo *newnode;
3757 :
3758 20043 : FLATCOPY(newnode, appinfo, AppendRelInfo);
3759 20043 : MUTATE(newnode->translated_vars, appinfo->translated_vars, List *);
3760 : /* Assume nothing need be done with parent_colnos[] */
3761 20043 : return (Node *) newnode;
3762 : }
3763 : break;
3764 0 : case T_PlaceHolderInfo:
3765 : {
3766 0 : PlaceHolderInfo *phinfo = (PlaceHolderInfo *) node;
3767 : PlaceHolderInfo *newnode;
3768 :
3769 0 : FLATCOPY(newnode, phinfo, PlaceHolderInfo);
3770 0 : MUTATE(newnode->ph_var, phinfo->ph_var, PlaceHolderVar *);
3771 : /* Assume we need not copy the relids bitmapsets */
3772 0 : return (Node *) newnode;
3773 : }
3774 : break;
3775 70693 : case T_RangeTblFunction:
3776 : {
3777 70693 : RangeTblFunction *rtfunc = (RangeTblFunction *) node;
3778 : RangeTblFunction *newnode;
3779 :
3780 70693 : FLATCOPY(newnode, rtfunc, RangeTblFunction);
3781 70693 : MUTATE(newnode->funcexpr, rtfunc->funcexpr, Node *);
3782 : /* Assume we need not copy the coldef info lists */
3783 70693 : return (Node *) newnode;
3784 : }
3785 : break;
3786 373 : case T_TableSampleClause:
3787 : {
3788 373 : TableSampleClause *tsc = (TableSampleClause *) node;
3789 : TableSampleClause *newnode;
3790 :
3791 373 : FLATCOPY(newnode, tsc, TableSampleClause);
3792 373 : MUTATE(newnode->args, tsc->args, List *);
3793 373 : MUTATE(newnode->repeatable, tsc->repeatable, Expr *);
3794 373 : return (Node *) newnode;
3795 : }
3796 : break;
3797 854 : case T_TableFunc:
3798 : {
3799 854 : TableFunc *tf = (TableFunc *) node;
3800 : TableFunc *newnode;
3801 :
3802 854 : FLATCOPY(newnode, tf, TableFunc);
3803 854 : MUTATE(newnode->ns_uris, tf->ns_uris, List *);
3804 854 : MUTATE(newnode->docexpr, tf->docexpr, Node *);
3805 854 : MUTATE(newnode->rowexpr, tf->rowexpr, Node *);
3806 854 : MUTATE(newnode->colexprs, tf->colexprs, List *);
3807 854 : MUTATE(newnode->coldefexprs, tf->coldefexprs, List *);
3808 854 : MUTATE(newnode->colvalexprs, tf->colvalexprs, List *);
3809 854 : MUTATE(newnode->passingvalexprs, tf->passingvalexprs, List *);
3810 854 : return (Node *) newnode;
3811 : }
3812 : break;
3813 0 : default:
3814 0 : elog(ERROR, "unrecognized node type: %d",
3815 : (int) nodeTag(node));
3816 : break;
3817 : }
3818 : /* can't get here, but keep compiler happy */
3819 : return NULL;
3820 : }
3821 :
3822 :
3823 : /*
3824 : * query_tree_mutator --- initiate modification of a Query's expressions
3825 : *
3826 : * This routine exists just to reduce the number of places that need to know
3827 : * where all the expression subtrees of a Query are. Note it can be used
3828 : * for starting a walk at top level of a Query regardless of whether the
3829 : * mutator intends to descend into subqueries. It is also useful for
3830 : * descending into subqueries within a mutator.
3831 : *
3832 : * Some callers want to suppress mutating of certain items in the Query,
3833 : * typically because they need to process them specially, or don't actually
3834 : * want to recurse into subqueries. This is supported by the flags argument,
3835 : * which is the bitwise OR of flag values to suppress mutating of
3836 : * indicated items. (More flag bits may be added as needed.)
3837 : *
3838 : * Normally the top-level Query node itself is copied, but some callers want
3839 : * it to be modified in-place; they must pass QTW_DONT_COPY_QUERY in flags.
3840 : * All modified substructure is safely copied in any case.
3841 : */
3842 : Query *
3843 22752 : query_tree_mutator_impl(Query *query,
3844 : tree_mutator_callback mutator,
3845 : void *context,
3846 : int flags)
3847 : {
3848 : Assert(query != NULL && IsA(query, Query));
3849 :
3850 22752 : if (!(flags & QTW_DONT_COPY_QUERY))
3851 : {
3852 : Query *newquery;
3853 :
3854 22752 : FLATCOPY(newquery, query, Query);
3855 22752 : query = newquery;
3856 : }
3857 :
3858 22752 : MUTATE(query->targetList, query->targetList, List *);
3859 22752 : MUTATE(query->withCheckOptions, query->withCheckOptions, List *);
3860 22752 : MUTATE(query->onConflict, query->onConflict, OnConflictExpr *);
3861 22752 : MUTATE(query->mergeActionList, query->mergeActionList, List *);
3862 22752 : MUTATE(query->mergeJoinCondition, query->mergeJoinCondition, Node *);
3863 22752 : MUTATE(query->forPortionOf, query->forPortionOf, ForPortionOfExpr *);
3864 22752 : MUTATE(query->returningList, query->returningList, List *);
3865 22752 : MUTATE(query->jointree, query->jointree, FromExpr *);
3866 22752 : MUTATE(query->setOperations, query->setOperations, Node *);
3867 22752 : MUTATE(query->havingQual, query->havingQual, Node *);
3868 22752 : MUTATE(query->limitOffset, query->limitOffset, Node *);
3869 22752 : MUTATE(query->limitCount, query->limitCount, Node *);
3870 :
3871 : /*
3872 : * Most callers aren't interested in SortGroupClause nodes since those
3873 : * don't contain actual expressions. However they do contain OIDs, which
3874 : * may be of interest to some mutators.
3875 : */
3876 :
3877 22752 : if ((flags & QTW_EXAMINE_SORTGROUP))
3878 : {
3879 0 : MUTATE(query->groupClause, query->groupClause, List *);
3880 0 : MUTATE(query->windowClause, query->windowClause, List *);
3881 0 : MUTATE(query->sortClause, query->sortClause, List *);
3882 0 : MUTATE(query->distinctClause, query->distinctClause, List *);
3883 : }
3884 : else
3885 : {
3886 : /*
3887 : * But we need to mutate the expressions under WindowClause nodes even
3888 : * if we're not interested in SortGroupClause nodes.
3889 : */
3890 : List *resultlist;
3891 : ListCell *temp;
3892 :
3893 22752 : resultlist = NIL;
3894 22896 : foreach(temp, query->windowClause)
3895 : {
3896 144 : WindowClause *wc = lfirst_node(WindowClause, temp);
3897 : WindowClause *newnode;
3898 :
3899 144 : FLATCOPY(newnode, wc, WindowClause);
3900 144 : MUTATE(newnode->startOffset, wc->startOffset, Node *);
3901 144 : MUTATE(newnode->endOffset, wc->endOffset, Node *);
3902 :
3903 144 : resultlist = lappend(resultlist, (Node *) newnode);
3904 : }
3905 22752 : query->windowClause = resultlist;
3906 : }
3907 :
3908 : /*
3909 : * groupingSets and rowMarks are not mutated:
3910 : *
3911 : * groupingSets contain only ressortgroup refs (integers) which are
3912 : * meaningless without the groupClause or tlist. Accordingly, any mutator
3913 : * that needs to care about them needs to handle them itself in its Query
3914 : * processing.
3915 : *
3916 : * rowMarks contains only rangetable indexes (and flags etc.) and
3917 : * therefore should be handled at Query level similarly.
3918 : */
3919 :
3920 22752 : if (!(flags & QTW_IGNORE_CTE_SUBQUERIES))
3921 22752 : MUTATE(query->cteList, query->cteList, List *);
3922 : else /* else copy CTE list as-is */
3923 0 : query->cteList = copyObject(query->cteList);
3924 22752 : query->rtable = range_table_mutator(query->rtable,
3925 : mutator, context, flags);
3926 22752 : return query;
3927 : }
3928 :
3929 : /*
3930 : * range_table_mutator is just the part of query_tree_mutator that processes
3931 : * a query's rangetable. This is split out since it can be useful on
3932 : * its own.
3933 : */
3934 : List *
3935 22752 : range_table_mutator_impl(List *rtable,
3936 : tree_mutator_callback mutator,
3937 : void *context,
3938 : int flags)
3939 : {
3940 22752 : List *newrt = NIL;
3941 : ListCell *rt;
3942 :
3943 66860 : foreach(rt, rtable)
3944 : {
3945 44108 : RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
3946 : RangeTblEntry *newrte;
3947 :
3948 44108 : FLATCOPY(newrte, rte, RangeTblEntry);
3949 44108 : switch (rte->rtekind)
3950 : {
3951 27181 : case RTE_RELATION:
3952 27181 : MUTATE(newrte->tablesample, rte->tablesample,
3953 : TableSampleClause *);
3954 : /* we don't bother to copy eref, aliases, etc; OK? */
3955 27181 : break;
3956 3469 : case RTE_SUBQUERY:
3957 3469 : if (!(flags & QTW_IGNORE_RT_SUBQUERIES))
3958 3469 : MUTATE(newrte->subquery, rte->subquery, Query *);
3959 : else
3960 : {
3961 : /* else, copy RT subqueries as-is */
3962 0 : newrte->subquery = copyObject(rte->subquery);
3963 : }
3964 3469 : break;
3965 6085 : case RTE_JOIN:
3966 6085 : if (!(flags & QTW_IGNORE_JOINALIASES))
3967 5691 : MUTATE(newrte->joinaliasvars, rte->joinaliasvars, List *);
3968 : else
3969 : {
3970 : /* else, copy join aliases as-is */
3971 394 : newrte->joinaliasvars = copyObject(rte->joinaliasvars);
3972 : }
3973 6085 : break;
3974 5719 : case RTE_FUNCTION:
3975 5719 : MUTATE(newrte->functions, rte->functions, List *);
3976 5719 : break;
3977 0 : case RTE_TABLEFUNC:
3978 0 : MUTATE(newrte->tablefunc, rte->tablefunc, TableFunc *);
3979 0 : break;
3980 1018 : case RTE_VALUES:
3981 1018 : MUTATE(newrte->values_lists, rte->values_lists, List *);
3982 1018 : break;
3983 0 : case RTE_GRAPH_TABLE:
3984 0 : MUTATE(newrte->graph_pattern, rte->graph_pattern, GraphPattern *);
3985 0 : MUTATE(newrte->graph_table_columns, rte->graph_table_columns, List *);
3986 0 : break;
3987 427 : case RTE_CTE:
3988 : case RTE_NAMEDTUPLESTORE:
3989 : case RTE_RESULT:
3990 : /* nothing to do */
3991 427 : break;
3992 209 : case RTE_GROUP:
3993 209 : if (!(flags & QTW_IGNORE_GROUPEXPRS))
3994 209 : MUTATE(newrte->groupexprs, rte->groupexprs, List *);
3995 : else
3996 : {
3997 : /* else, copy grouping exprs as-is */
3998 0 : newrte->groupexprs = copyObject(rte->groupexprs);
3999 : }
4000 209 : break;
4001 : }
4002 44108 : MUTATE(newrte->securityQuals, rte->securityQuals, List *);
4003 44108 : newrt = lappend(newrt, newrte);
4004 : }
4005 22752 : return newrt;
4006 : }
4007 :
4008 : /*
4009 : * query_or_expression_tree_walker --- hybrid form
4010 : *
4011 : * This routine will invoke query_tree_walker if called on a Query node,
4012 : * else will invoke the walker directly. This is a useful way of starting
4013 : * the recursion when the walker's normal change of state is not appropriate
4014 : * for the outermost Query node.
4015 : */
4016 : bool
4017 3240264 : query_or_expression_tree_walker_impl(Node *node,
4018 : tree_walker_callback walker,
4019 : void *context,
4020 : int flags)
4021 : {
4022 3240264 : if (node && IsA(node, Query))
4023 317689 : return query_tree_walker((Query *) node,
4024 : walker,
4025 : context,
4026 : flags);
4027 : else
4028 2922575 : return WALK(node);
4029 : }
4030 :
4031 : /*
4032 : * query_or_expression_tree_mutator --- hybrid form
4033 : *
4034 : * This routine will invoke query_tree_mutator if called on a Query node,
4035 : * else will invoke the mutator directly. This is a useful way of starting
4036 : * the recursion when the mutator's normal change of state is not appropriate
4037 : * for the outermost Query node.
4038 : */
4039 : Node *
4040 479082 : query_or_expression_tree_mutator_impl(Node *node,
4041 : tree_mutator_callback mutator,
4042 : void *context,
4043 : int flags)
4044 : {
4045 479082 : if (node && IsA(node, Query))
4046 6498 : return (Node *) query_tree_mutator((Query *) node,
4047 : mutator,
4048 : context,
4049 : flags);
4050 : else
4051 472584 : return mutator(node, context);
4052 : }
4053 :
4054 :
4055 : /*
4056 : * raw_expression_tree_walker --- walk raw parse trees
4057 : *
4058 : * This has exactly the same API as expression_tree_walker, but instead of
4059 : * walking post-analysis parse trees, it knows how to walk the node types
4060 : * found in raw grammar output. (There is not currently any need for a
4061 : * combined walker, so we keep them separate in the name of efficiency.)
4062 : * Unlike expression_tree_walker, there is no special rule about query
4063 : * boundaries: we descend to everything that's possibly interesting.
4064 : *
4065 : * Currently, the node type coverage here extends only to DML statements
4066 : * (SELECT/INSERT/UPDATE/DELETE/MERGE) and nodes that can appear in them,
4067 : * because this is used mainly during analysis of CTEs, and only DML
4068 : * statements can appear in CTEs.
4069 : */
4070 : bool
4071 8084884 : raw_expression_tree_walker_impl(Node *node,
4072 : tree_walker_callback walker,
4073 : void *context)
4074 : {
4075 : ListCell *temp;
4076 :
4077 : /*
4078 : * The walker has already visited the current node, and so we need only
4079 : * recurse into any sub-nodes it has.
4080 : */
4081 8084884 : if (node == NULL)
4082 0 : return false;
4083 :
4084 : /* Guard against stack overflow due to overly complex expressions */
4085 8084884 : check_stack_depth();
4086 :
4087 8084884 : switch (nodeTag(node))
4088 : {
4089 1000183 : case T_JsonFormat:
4090 : case T_SetToDefault:
4091 : case T_CurrentOfExpr:
4092 : case T_SQLValueFunction:
4093 : case T_Integer:
4094 : case T_Float:
4095 : case T_Boolean:
4096 : case T_String:
4097 : case T_BitString:
4098 : case T_ParamRef:
4099 : case T_A_Const:
4100 : case T_A_Star:
4101 : case T_MergeSupportFunc:
4102 : case T_ReturningOption:
4103 : /* primitive node types with no subnodes */
4104 1000183 : break;
4105 259735 : case T_Alias:
4106 : /* we assume the colnames list isn't interesting */
4107 259735 : break;
4108 413328 : case T_RangeVar:
4109 413328 : return WALK(((RangeVar *) node)->alias);
4110 328 : case T_GroupingFunc:
4111 328 : return WALK(((GroupingFunc *) node)->args);
4112 39229 : case T_SubLink:
4113 : {
4114 39229 : SubLink *sublink = (SubLink *) node;
4115 :
4116 39229 : if (WALK(sublink->testexpr))
4117 0 : return true;
4118 : /* we assume the operName is not interesting */
4119 39229 : if (WALK(sublink->subselect))
4120 0 : return true;
4121 : }
4122 39229 : break;
4123 29172 : case T_CaseExpr:
4124 : {
4125 29172 : CaseExpr *caseexpr = (CaseExpr *) node;
4126 :
4127 29172 : if (WALK(caseexpr->arg))
4128 0 : return true;
4129 : /* we assume walker doesn't care about CaseWhens, either */
4130 78465 : foreach(temp, caseexpr->args)
4131 : {
4132 49293 : CaseWhen *when = lfirst_node(CaseWhen, temp);
4133 :
4134 49293 : if (WALK(when->expr))
4135 0 : return true;
4136 49293 : if (WALK(when->result))
4137 0 : return true;
4138 : }
4139 29172 : if (WALK(caseexpr->defresult))
4140 0 : return true;
4141 : }
4142 29172 : break;
4143 5072 : case T_RowExpr:
4144 : /* Assume colnames isn't interesting */
4145 5072 : return WALK(((RowExpr *) node)->args);
4146 3777 : case T_CoalesceExpr:
4147 3777 : return WALK(((CoalesceExpr *) node)->args);
4148 263 : case T_MinMaxExpr:
4149 263 : return WALK(((MinMaxExpr *) node)->args);
4150 411 : case T_XmlExpr:
4151 : {
4152 411 : XmlExpr *xexpr = (XmlExpr *) node;
4153 :
4154 411 : if (WALK(xexpr->named_args))
4155 0 : return true;
4156 : /* we assume walker doesn't care about arg_names */
4157 411 : if (WALK(xexpr->args))
4158 0 : return true;
4159 : }
4160 411 : break;
4161 998 : case T_JsonReturning:
4162 998 : return WALK(((JsonReturning *) node)->format);
4163 2642 : case T_JsonValueExpr:
4164 : {
4165 2642 : JsonValueExpr *jve = (JsonValueExpr *) node;
4166 :
4167 2642 : if (WALK(jve->raw_expr))
4168 0 : return true;
4169 2642 : if (WALK(jve->formatted_expr))
4170 0 : return true;
4171 2642 : if (WALK(jve->format))
4172 0 : return true;
4173 : }
4174 2642 : break;
4175 104 : case T_JsonParseExpr:
4176 : {
4177 104 : JsonParseExpr *jpe = (JsonParseExpr *) node;
4178 :
4179 104 : if (WALK(jpe->expr))
4180 0 : return true;
4181 104 : if (WALK(jpe->output))
4182 0 : return true;
4183 : }
4184 104 : break;
4185 70 : case T_JsonScalarExpr:
4186 : {
4187 70 : JsonScalarExpr *jse = (JsonScalarExpr *) node;
4188 :
4189 70 : if (WALK(jse->expr))
4190 0 : return true;
4191 70 : if (WALK(jse->output))
4192 0 : return true;
4193 : }
4194 70 : break;
4195 68 : case T_JsonSerializeExpr:
4196 : {
4197 68 : JsonSerializeExpr *jse = (JsonSerializeExpr *) node;
4198 :
4199 68 : if (WALK(jse->expr))
4200 0 : return true;
4201 68 : if (WALK(jse->output))
4202 0 : return true;
4203 : }
4204 68 : break;
4205 0 : case T_JsonConstructorExpr:
4206 : {
4207 0 : JsonConstructorExpr *ctor = (JsonConstructorExpr *) node;
4208 :
4209 0 : if (WALK(ctor->args))
4210 0 : return true;
4211 0 : if (WALK(ctor->func))
4212 0 : return true;
4213 0 : if (WALK(ctor->coercion))
4214 0 : return true;
4215 0 : if (WALK(ctor->returning))
4216 0 : return true;
4217 : }
4218 0 : break;
4219 280 : case T_JsonIsPredicate:
4220 280 : return WALK(((JsonIsPredicate *) node)->expr);
4221 252 : case T_JsonArgument:
4222 252 : return WALK(((JsonArgument *) node)->val);
4223 1016 : case T_JsonFuncExpr:
4224 : {
4225 1016 : JsonFuncExpr *jfe = (JsonFuncExpr *) node;
4226 :
4227 1016 : if (WALK(jfe->context_item))
4228 0 : return true;
4229 1016 : if (WALK(jfe->pathspec))
4230 0 : return true;
4231 1016 : if (WALK(jfe->passing))
4232 0 : return true;
4233 1016 : if (WALK(jfe->output))
4234 0 : return true;
4235 1016 : if (WALK(jfe->on_empty))
4236 0 : return true;
4237 1016 : if (WALK(jfe->on_error))
4238 0 : return true;
4239 : }
4240 1016 : break;
4241 732 : case T_JsonBehavior:
4242 : {
4243 732 : JsonBehavior *jb = (JsonBehavior *) node;
4244 :
4245 732 : if (WALK(jb->expr))
4246 0 : return true;
4247 : }
4248 732 : break;
4249 348 : case T_JsonTable:
4250 : {
4251 348 : JsonTable *jt = (JsonTable *) node;
4252 :
4253 348 : if (WALK(jt->context_item))
4254 0 : return true;
4255 348 : if (WALK(jt->pathspec))
4256 0 : return true;
4257 348 : if (WALK(jt->passing))
4258 0 : return true;
4259 348 : if (WALK(jt->columns))
4260 0 : return true;
4261 348 : if (WALK(jt->on_error))
4262 0 : return true;
4263 : }
4264 348 : break;
4265 892 : case T_JsonTableColumn:
4266 : {
4267 892 : JsonTableColumn *jtc = (JsonTableColumn *) node;
4268 :
4269 892 : if (WALK(jtc->typeName))
4270 0 : return true;
4271 892 : if (WALK(jtc->on_empty))
4272 0 : return true;
4273 892 : if (WALK(jtc->on_error))
4274 0 : return true;
4275 892 : if (WALK(jtc->columns))
4276 0 : return true;
4277 : }
4278 892 : break;
4279 348 : case T_JsonTablePathSpec:
4280 348 : return WALK(((JsonTablePathSpec *) node)->string);
4281 15573 : case T_NullTest:
4282 15573 : return WALK(((NullTest *) node)->arg);
4283 771 : case T_BooleanTest:
4284 771 : return WALK(((BooleanTest *) node)->arg);
4285 74633 : case T_JoinExpr:
4286 : {
4287 74633 : JoinExpr *join = (JoinExpr *) node;
4288 :
4289 74633 : if (WALK(join->larg))
4290 0 : return true;
4291 74633 : if (WALK(join->rarg))
4292 0 : return true;
4293 74633 : if (WALK(join->quals))
4294 0 : return true;
4295 74633 : if (WALK(join->alias))
4296 0 : return true;
4297 : /* using list is deemed uninteresting */
4298 : }
4299 74633 : break;
4300 20 : case T_IntoClause:
4301 : {
4302 20 : IntoClause *into = (IntoClause *) node;
4303 :
4304 20 : if (WALK(into->rel))
4305 0 : return true;
4306 : /* colNames, options are deemed uninteresting */
4307 : /* viewQuery should be null in raw parsetree, but check it */
4308 20 : if (WALK(into->viewQuery))
4309 0 : return true;
4310 : }
4311 20 : break;
4312 1503766 : case T_List:
4313 4245635 : foreach(temp, (List *) node)
4314 : {
4315 2741937 : if (WALK((Node *) lfirst(temp)))
4316 0 : return true;
4317 : }
4318 1503698 : break;
4319 43164 : case T_InsertStmt:
4320 : {
4321 43164 : InsertStmt *stmt = (InsertStmt *) node;
4322 :
4323 43164 : if (WALK(stmt->relation))
4324 0 : return true;
4325 43164 : if (WALK(stmt->cols))
4326 0 : return true;
4327 43164 : if (WALK(stmt->selectStmt))
4328 0 : return true;
4329 43164 : if (WALK(stmt->onConflictClause))
4330 0 : return true;
4331 43164 : if (WALK(stmt->returningClause))
4332 0 : return true;
4333 43164 : if (WALK(stmt->withClause))
4334 0 : return true;
4335 : }
4336 43164 : break;
4337 3355 : case T_DeleteStmt:
4338 : {
4339 3355 : DeleteStmt *stmt = (DeleteStmt *) node;
4340 :
4341 3355 : if (WALK(stmt->relation))
4342 0 : return true;
4343 3355 : if (WALK(stmt->usingClause))
4344 0 : return true;
4345 3355 : if (WALK(stmt->whereClause))
4346 0 : return true;
4347 3355 : if (WALK(stmt->returningClause))
4348 0 : return true;
4349 3355 : if (WALK(stmt->withClause))
4350 0 : return true;
4351 : }
4352 3355 : break;
4353 9280 : case T_UpdateStmt:
4354 : {
4355 9280 : UpdateStmt *stmt = (UpdateStmt *) node;
4356 :
4357 9280 : if (WALK(stmt->relation))
4358 0 : return true;
4359 9280 : if (WALK(stmt->targetList))
4360 0 : return true;
4361 9280 : if (WALK(stmt->whereClause))
4362 0 : return true;
4363 9280 : if (WALK(stmt->fromClause))
4364 0 : return true;
4365 9280 : if (WALK(stmt->returningClause))
4366 0 : return true;
4367 9280 : if (WALK(stmt->withClause))
4368 0 : return true;
4369 : }
4370 9280 : break;
4371 1408 : case T_MergeStmt:
4372 : {
4373 1408 : MergeStmt *stmt = (MergeStmt *) node;
4374 :
4375 1408 : if (WALK(stmt->relation))
4376 0 : return true;
4377 1408 : if (WALK(stmt->sourceRelation))
4378 0 : return true;
4379 1408 : if (WALK(stmt->joinCondition))
4380 0 : return true;
4381 1408 : if (WALK(stmt->mergeWhenClauses))
4382 0 : return true;
4383 1408 : if (WALK(stmt->returningClause))
4384 0 : return true;
4385 1408 : if (WALK(stmt->withClause))
4386 0 : return true;
4387 : }
4388 1408 : break;
4389 2145 : case T_MergeWhenClause:
4390 : {
4391 2145 : MergeWhenClause *mergeWhenClause = (MergeWhenClause *) node;
4392 :
4393 2145 : if (WALK(mergeWhenClause->condition))
4394 0 : return true;
4395 2145 : if (WALK(mergeWhenClause->targetList))
4396 0 : return true;
4397 2145 : if (WALK(mergeWhenClause->values))
4398 0 : return true;
4399 : }
4400 2145 : break;
4401 2571 : case T_ReturningClause:
4402 : {
4403 2571 : ReturningClause *returning = (ReturningClause *) node;
4404 :
4405 2571 : if (WALK(returning->options))
4406 0 : return true;
4407 2571 : if (WALK(returning->exprs))
4408 0 : return true;
4409 : }
4410 2571 : break;
4411 461602 : case T_SelectStmt:
4412 : {
4413 461602 : SelectStmt *stmt = (SelectStmt *) node;
4414 :
4415 461602 : if (WALK(stmt->distinctClause))
4416 0 : return true;
4417 461602 : if (WALK(stmt->intoClause))
4418 0 : return true;
4419 461602 : if (WALK(stmt->targetList))
4420 0 : return true;
4421 461598 : if (WALK(stmt->fromClause))
4422 0 : return true;
4423 461542 : if (WALK(stmt->whereClause))
4424 0 : return true;
4425 461538 : if (WALK(stmt->groupClause))
4426 0 : return true;
4427 461538 : if (WALK(stmt->havingClause))
4428 0 : return true;
4429 461538 : if (WALK(stmt->windowClause))
4430 0 : return true;
4431 461538 : if (WALK(stmt->valuesLists))
4432 0 : return true;
4433 461538 : if (WALK(stmt->sortClause))
4434 0 : return true;
4435 461538 : if (WALK(stmt->limitOffset))
4436 0 : return true;
4437 461538 : if (WALK(stmt->limitCount))
4438 0 : return true;
4439 461538 : if (WALK(stmt->lockingClause))
4440 0 : return true;
4441 461538 : if (WALK(stmt->withClause))
4442 0 : return true;
4443 461538 : if (WALK(stmt->larg))
4444 0 : return true;
4445 461538 : if (WALK(stmt->rarg))
4446 0 : return true;
4447 : }
4448 461530 : break;
4449 0 : case T_PLAssignStmt:
4450 : {
4451 0 : PLAssignStmt *stmt = (PLAssignStmt *) node;
4452 :
4453 0 : if (WALK(stmt->indirection))
4454 0 : return true;
4455 0 : if (WALK(stmt->val))
4456 0 : return true;
4457 : }
4458 0 : break;
4459 522158 : case T_A_Expr:
4460 : {
4461 522158 : A_Expr *expr = (A_Expr *) node;
4462 :
4463 522158 : if (WALK(expr->lexpr))
4464 0 : return true;
4465 522158 : if (WALK(expr->rexpr))
4466 0 : return true;
4467 : /* operator name is deemed uninteresting */
4468 : }
4469 522158 : break;
4470 164246 : case T_BoolExpr:
4471 : {
4472 164246 : BoolExpr *expr = (BoolExpr *) node;
4473 :
4474 164246 : if (WALK(expr->args))
4475 0 : return true;
4476 : }
4477 164246 : break;
4478 1570630 : case T_ColumnRef:
4479 : /* we assume the fields contain nothing interesting */
4480 1570630 : break;
4481 299126 : case T_FuncCall:
4482 : {
4483 299126 : FuncCall *fcall = (FuncCall *) node;
4484 :
4485 299126 : if (WALK(fcall->args))
4486 0 : return true;
4487 299126 : if (WALK(fcall->agg_order))
4488 0 : return true;
4489 299126 : if (WALK(fcall->agg_filter))
4490 0 : return true;
4491 299126 : if (WALK(fcall->over))
4492 0 : return true;
4493 : /* function name is deemed uninteresting */
4494 : }
4495 299126 : break;
4496 26555 : case T_NamedArgExpr:
4497 26555 : return WALK(((NamedArgExpr *) node)->arg);
4498 13739 : case T_A_Indices:
4499 : {
4500 13739 : A_Indices *indices = (A_Indices *) node;
4501 :
4502 13739 : if (WALK(indices->lidx))
4503 0 : return true;
4504 13739 : if (WALK(indices->uidx))
4505 0 : return true;
4506 : }
4507 13739 : break;
4508 22492 : case T_A_Indirection:
4509 : {
4510 22492 : A_Indirection *indir = (A_Indirection *) node;
4511 :
4512 22492 : if (WALK(indir->arg))
4513 0 : return true;
4514 22492 : if (WALK(indir->indirection))
4515 0 : return true;
4516 : }
4517 22492 : break;
4518 6609 : case T_A_ArrayExpr:
4519 6609 : return WALK(((A_ArrayExpr *) node)->elements);
4520 936999 : case T_ResTarget:
4521 : {
4522 936999 : ResTarget *rt = (ResTarget *) node;
4523 :
4524 936999 : if (WALK(rt->indirection))
4525 0 : return true;
4526 936999 : if (WALK(rt->val))
4527 0 : return true;
4528 : }
4529 936995 : break;
4530 261 : case T_MultiAssignRef:
4531 261 : return WALK(((MultiAssignRef *) node)->source);
4532 231155 : case T_TypeCast:
4533 : {
4534 231155 : TypeCast *tc = (TypeCast *) node;
4535 :
4536 231155 : if (WALK(tc->arg))
4537 0 : return true;
4538 231155 : if (WALK(tc->typeName))
4539 0 : return true;
4540 : }
4541 231155 : break;
4542 6823 : case T_CollateClause:
4543 6823 : return WALK(((CollateClause *) node)->arg);
4544 81997 : case T_SortBy:
4545 81997 : return WALK(((SortBy *) node)->node);
4546 3460 : case T_WindowDef:
4547 : {
4548 3460 : WindowDef *wd = (WindowDef *) node;
4549 :
4550 3460 : if (WALK(wd->partitionClause))
4551 0 : return true;
4552 3460 : if (WALK(wd->orderClause))
4553 0 : return true;
4554 3460 : if (WALK(wd->startOffset))
4555 0 : return true;
4556 3460 : if (WALK(wd->endOffset))
4557 0 : return true;
4558 : }
4559 3460 : break;
4560 16490 : case T_RangeSubselect:
4561 : {
4562 16490 : RangeSubselect *rs = (RangeSubselect *) node;
4563 :
4564 16490 : if (WALK(rs->subquery))
4565 0 : return true;
4566 16486 : if (WALK(rs->alias))
4567 0 : return true;
4568 : }
4569 16486 : break;
4570 42229 : case T_RangeFunction:
4571 : {
4572 42229 : RangeFunction *rf = (RangeFunction *) node;
4573 :
4574 42229 : if (WALK(rf->functions))
4575 0 : return true;
4576 42229 : if (WALK(rf->alias))
4577 0 : return true;
4578 42229 : if (WALK(rf->coldeflist))
4579 0 : return true;
4580 : }
4581 42229 : break;
4582 204 : case T_RangeTableSample:
4583 : {
4584 204 : RangeTableSample *rts = (RangeTableSample *) node;
4585 :
4586 204 : if (WALK(rts->relation))
4587 0 : return true;
4588 : /* method name is deemed uninteresting */
4589 204 : if (WALK(rts->args))
4590 0 : return true;
4591 204 : if (WALK(rts->repeatable))
4592 0 : return true;
4593 : }
4594 204 : break;
4595 154 : case T_RangeTableFunc:
4596 : {
4597 154 : RangeTableFunc *rtf = (RangeTableFunc *) node;
4598 :
4599 154 : if (WALK(rtf->docexpr))
4600 0 : return true;
4601 154 : if (WALK(rtf->rowexpr))
4602 0 : return true;
4603 154 : if (WALK(rtf->namespaces))
4604 0 : return true;
4605 154 : if (WALK(rtf->columns))
4606 0 : return true;
4607 154 : if (WALK(rtf->alias))
4608 0 : return true;
4609 : }
4610 154 : break;
4611 545 : case T_RangeTableFuncCol:
4612 : {
4613 545 : RangeTableFuncCol *rtfc = (RangeTableFuncCol *) node;
4614 :
4615 545 : if (WALK(rtfc->colexpr))
4616 0 : return true;
4617 545 : if (WALK(rtfc->coldefexpr))
4618 0 : return true;
4619 : }
4620 545 : break;
4621 589 : case T_RangeGraphTable:
4622 : {
4623 589 : RangeGraphTable *rgt = (RangeGraphTable *) node;
4624 :
4625 589 : if (WALK(rgt->graph_pattern))
4626 0 : return true;
4627 589 : if (WALK(rgt->columns))
4628 0 : return true;
4629 589 : if (WALK(rgt->alias))
4630 0 : return true;
4631 : }
4632 589 : break;
4633 234120 : case T_TypeName:
4634 : {
4635 234120 : TypeName *tn = (TypeName *) node;
4636 :
4637 234120 : if (WALK(tn->typmods))
4638 0 : return true;
4639 234120 : if (WALK(tn->arrayBounds))
4640 0 : return true;
4641 : /* type name itself is deemed uninteresting */
4642 : }
4643 234120 : break;
4644 1179 : case T_ColumnDef:
4645 : {
4646 1179 : ColumnDef *coldef = (ColumnDef *) node;
4647 :
4648 1179 : if (WALK(coldef->typeName))
4649 0 : return true;
4650 1179 : if (WALK(coldef->raw_default))
4651 0 : return true;
4652 1179 : if (WALK(coldef->collClause))
4653 0 : return true;
4654 : /* for now, constraints are ignored */
4655 : }
4656 1179 : break;
4657 1569 : case T_IndexElem:
4658 : {
4659 1569 : IndexElem *indelem = (IndexElem *) node;
4660 :
4661 1569 : if (WALK(indelem->expr))
4662 0 : return true;
4663 : /* collation and opclass names are deemed uninteresting */
4664 : }
4665 1569 : break;
4666 1184 : case T_GroupingSet:
4667 1184 : return WALK(((GroupingSet *) node)->content);
4668 8061 : case T_LockingClause:
4669 8061 : return WALK(((LockingClause *) node)->lockedRels);
4670 144 : case T_XmlSerialize:
4671 : {
4672 144 : XmlSerialize *xs = (XmlSerialize *) node;
4673 :
4674 144 : if (WALK(xs->expr))
4675 0 : return true;
4676 144 : if (WALK(xs->typeName))
4677 0 : return true;
4678 : }
4679 144 : break;
4680 2988 : case T_WithClause:
4681 2988 : return WALK(((WithClause *) node)->ctes);
4682 1401 : case T_InferClause:
4683 : {
4684 1401 : InferClause *stmt = (InferClause *) node;
4685 :
4686 1401 : if (WALK(stmt->indexElems))
4687 0 : return true;
4688 1401 : if (WALK(stmt->whereClause))
4689 0 : return true;
4690 : }
4691 1401 : break;
4692 1553 : case T_OnConflictClause:
4693 : {
4694 1553 : OnConflictClause *stmt = (OnConflictClause *) node;
4695 :
4696 1553 : if (WALK(stmt->infer))
4697 0 : return true;
4698 1553 : if (WALK(stmt->targetList))
4699 0 : return true;
4700 1553 : if (WALK(stmt->whereClause))
4701 0 : return true;
4702 : }
4703 1553 : break;
4704 3752 : case T_CommonTableExpr:
4705 : /* search_clause and cycle_clause are not interesting here */
4706 3752 : return WALK(((CommonTableExpr *) node)->ctequery);
4707 998 : case T_JsonOutput:
4708 : {
4709 998 : JsonOutput *out = (JsonOutput *) node;
4710 :
4711 998 : if (WALK(out->typeName))
4712 0 : return true;
4713 998 : if (WALK(out->returning))
4714 0 : return true;
4715 : }
4716 998 : break;
4717 534 : case T_JsonKeyValue:
4718 : {
4719 534 : JsonKeyValue *jkv = (JsonKeyValue *) node;
4720 :
4721 534 : if (WALK(jkv->key))
4722 0 : return true;
4723 534 : if (WALK(jkv->value))
4724 0 : return true;
4725 : }
4726 534 : break;
4727 290 : case T_JsonObjectConstructor:
4728 : {
4729 290 : JsonObjectConstructor *joc = (JsonObjectConstructor *) node;
4730 :
4731 290 : if (WALK(joc->output))
4732 0 : return true;
4733 290 : if (WALK(joc->exprs))
4734 0 : return true;
4735 : }
4736 290 : break;
4737 144 : case T_JsonArrayConstructor:
4738 : {
4739 144 : JsonArrayConstructor *jac = (JsonArrayConstructor *) node;
4740 :
4741 144 : if (WALK(jac->output))
4742 0 : return true;
4743 144 : if (WALK(jac->exprs))
4744 0 : return true;
4745 : }
4746 144 : break;
4747 268 : case T_JsonAggConstructor:
4748 : {
4749 268 : JsonAggConstructor *ctor = (JsonAggConstructor *) node;
4750 :
4751 268 : if (WALK(ctor->output))
4752 0 : return true;
4753 268 : if (WALK(ctor->agg_order))
4754 0 : return true;
4755 268 : if (WALK(ctor->agg_filter))
4756 0 : return true;
4757 268 : if (WALK(ctor->over))
4758 0 : return true;
4759 : }
4760 268 : break;
4761 136 : case T_JsonObjectAgg:
4762 : {
4763 136 : JsonObjectAgg *joa = (JsonObjectAgg *) node;
4764 :
4765 136 : if (WALK(joa->constructor))
4766 0 : return true;
4767 136 : if (WALK(joa->arg))
4768 0 : return true;
4769 : }
4770 136 : break;
4771 132 : case T_JsonArrayAgg:
4772 : {
4773 132 : JsonArrayAgg *jaa = (JsonArrayAgg *) node;
4774 :
4775 132 : if (WALK(jaa->constructor))
4776 0 : return true;
4777 132 : if (WALK(jaa->arg))
4778 0 : return true;
4779 : }
4780 132 : break;
4781 40 : case T_JsonArrayQueryConstructor:
4782 : {
4783 40 : JsonArrayQueryConstructor *jaqc = (JsonArrayQueryConstructor *) node;
4784 :
4785 40 : if (WALK(jaqc->output))
4786 0 : return true;
4787 40 : if (WALK(jaqc->query))
4788 0 : return true;
4789 : }
4790 40 : break;
4791 1805 : case T_GraphElementPattern:
4792 : {
4793 1805 : GraphElementPattern *gep = (GraphElementPattern *) node;
4794 :
4795 1805 : if (WALK(gep->subexpr))
4796 0 : return true;
4797 1805 : if (WALK(gep->whereClause))
4798 0 : return true;
4799 : }
4800 1805 : break;
4801 589 : case T_GraphPattern:
4802 : {
4803 589 : GraphPattern *gp = (GraphPattern *) node;
4804 :
4805 589 : if (WALK(gp->path_pattern_list))
4806 0 : return true;
4807 589 : if (WALK(gp->whereClause))
4808 0 : return true;
4809 : }
4810 589 : break;
4811 0 : default:
4812 0 : elog(ERROR, "unrecognized node type: %d",
4813 : (int) nodeTag(node));
4814 : break;
4815 : }
4816 7505516 : return false;
4817 : }
4818 :
4819 : /*
4820 : * planstate_tree_walker --- walk plan state trees
4821 : *
4822 : * The walker has already visited the current node, and so we need only
4823 : * recurse into any sub-nodes it has.
4824 : */
4825 : bool
4826 907249 : planstate_tree_walker_impl(PlanState *planstate,
4827 : planstate_tree_walker_callback walker,
4828 : void *context)
4829 : {
4830 907249 : Plan *plan = planstate->plan;
4831 : ListCell *lc;
4832 :
4833 : /* We don't need implicit coercions to Node here */
4834 : #define PSWALK(n) walker(n, context)
4835 :
4836 : /* Guard against stack overflow due to overly complex plan trees */
4837 907249 : check_stack_depth();
4838 :
4839 : /* initPlan-s */
4840 907249 : if (planstate_walk_subplans(planstate->initPlan, walker, context))
4841 0 : return true;
4842 :
4843 : /* lefttree */
4844 907249 : if (outerPlanState(planstate))
4845 : {
4846 356071 : if (PSWALK(outerPlanState(planstate)))
4847 0 : return true;
4848 : }
4849 :
4850 : /* righttree */
4851 907249 : if (innerPlanState(planstate))
4852 : {
4853 106305 : if (PSWALK(innerPlanState(planstate)))
4854 0 : return true;
4855 : }
4856 :
4857 : /* special child plans */
4858 907249 : switch (nodeTag(plan))
4859 : {
4860 13429 : case T_Append:
4861 13429 : if (planstate_walk_members(((AppendState *) planstate)->appendplans,
4862 : ((AppendState *) planstate)->as_nplans,
4863 : walker, context))
4864 0 : return true;
4865 13429 : break;
4866 430 : case T_MergeAppend:
4867 430 : if (planstate_walk_members(((MergeAppendState *) planstate)->mergeplans,
4868 : ((MergeAppendState *) planstate)->ms_nplans,
4869 : walker, context))
4870 0 : return true;
4871 430 : break;
4872 148 : case T_BitmapAnd:
4873 148 : if (planstate_walk_members(((BitmapAndState *) planstate)->bitmapplans,
4874 : ((BitmapAndState *) planstate)->nplans,
4875 : walker, context))
4876 0 : return true;
4877 148 : break;
4878 261 : case T_BitmapOr:
4879 261 : if (planstate_walk_members(((BitmapOrState *) planstate)->bitmapplans,
4880 : ((BitmapOrState *) planstate)->nplans,
4881 : walker, context))
4882 0 : return true;
4883 261 : break;
4884 14741 : case T_SubqueryScan:
4885 14741 : if (PSWALK(((SubqueryScanState *) planstate)->subplan))
4886 0 : return true;
4887 14741 : break;
4888 0 : case T_CustomScan:
4889 0 : foreach(lc, ((CustomScanState *) planstate)->custom_ps)
4890 : {
4891 0 : if (PSWALK(lfirst(lc)))
4892 0 : return true;
4893 : }
4894 0 : break;
4895 878240 : default:
4896 878240 : break;
4897 : }
4898 :
4899 : /* subPlan-s */
4900 907249 : if (planstate_walk_subplans(planstate->subPlan, walker, context))
4901 0 : return true;
4902 :
4903 907249 : return false;
4904 : }
4905 :
4906 : /*
4907 : * Walk a list of SubPlans (or initPlans, which also use SubPlan nodes).
4908 : */
4909 : static bool
4910 1814498 : planstate_walk_subplans(List *plans,
4911 : planstate_tree_walker_callback walker,
4912 : void *context)
4913 : {
4914 : ListCell *lc;
4915 :
4916 1843940 : foreach(lc, plans)
4917 : {
4918 29442 : SubPlanState *sps = lfirst_node(SubPlanState, lc);
4919 :
4920 29442 : if (PSWALK(sps->planstate))
4921 0 : return true;
4922 : }
4923 :
4924 1814498 : return false;
4925 : }
4926 :
4927 : /*
4928 : * Walk the constituent plans of a ModifyTable, Append, MergeAppend,
4929 : * BitmapAnd, or BitmapOr node.
4930 : */
4931 : static bool
4932 14268 : planstate_walk_members(PlanState **planstates, int nplans,
4933 : planstate_tree_walker_callback walker,
4934 : void *context)
4935 : {
4936 61705 : for (int j = 0; j < nplans; j++)
4937 : {
4938 47437 : if (PSWALK(planstates[j]))
4939 0 : return true;
4940 : }
4941 :
4942 14268 : return false;
4943 : }
|