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