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