Add support for user-defined I/O conversion casts.
[PostgreSQL.git] / src / backend / nodes / nodeFuncs.c
blob884fe4dca13b15ddcdf732b3539c6d5e4dbddef7
1 /*-------------------------------------------------------------------------
3 * nodeFuncs.c
4 * Various general-purpose manipulations of Node trees
6 * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
10 * IDENTIFICATION
11 * $PostgreSQL$
13 *-------------------------------------------------------------------------
15 #include "postgres.h"
17 #include "catalog/pg_type.h"
18 #include "miscadmin.h"
19 #include "nodes/nodeFuncs.h"
20 #include "nodes/relation.h"
21 #include "utils/builtins.h"
22 #include "utils/lsyscache.h"
25 static bool expression_returns_set_walker(Node *node, void *context);
26 static int leftmostLoc(int loc1, int loc2);
30 * exprType -
31 * returns the Oid of the type of the expression. (Used for typechecking.)
33 Oid
34 exprType(Node *expr)
36 Oid type;
38 if (!expr)
39 return InvalidOid;
41 switch (nodeTag(expr))
43 case T_Var:
44 type = ((Var *) expr)->vartype;
45 break;
46 case T_Const:
47 type = ((Const *) expr)->consttype;
48 break;
49 case T_Param:
50 type = ((Param *) expr)->paramtype;
51 break;
52 case T_Aggref:
53 type = ((Aggref *) expr)->aggtype;
54 break;
55 case T_ArrayRef:
57 ArrayRef *arrayref = (ArrayRef *) expr;
59 /* slice and/or store operations yield the array type */
60 if (arrayref->reflowerindexpr || arrayref->refassgnexpr)
61 type = arrayref->refarraytype;
62 else
63 type = arrayref->refelemtype;
65 break;
66 case T_FuncExpr:
67 type = ((FuncExpr *) expr)->funcresulttype;
68 break;
69 case T_OpExpr:
70 type = ((OpExpr *) expr)->opresulttype;
71 break;
72 case T_DistinctExpr:
73 type = ((DistinctExpr *) expr)->opresulttype;
74 break;
75 case T_ScalarArrayOpExpr:
76 type = BOOLOID;
77 break;
78 case T_BoolExpr:
79 type = BOOLOID;
80 break;
81 case T_SubLink:
83 SubLink *sublink = (SubLink *) expr;
85 if (sublink->subLinkType == EXPR_SUBLINK ||
86 sublink->subLinkType == ARRAY_SUBLINK)
88 /* get the type of the subselect's first target column */
89 Query *qtree = (Query *) sublink->subselect;
90 TargetEntry *tent;
92 if (!qtree || !IsA(qtree, Query))
93 elog(ERROR, "cannot get type for untransformed sublink");
94 tent = (TargetEntry *) linitial(qtree->targetList);
95 Assert(IsA(tent, TargetEntry));
96 Assert(!tent->resjunk);
97 type = exprType((Node *) tent->expr);
98 if (sublink->subLinkType == ARRAY_SUBLINK)
100 type = get_array_type(type);
101 if (!OidIsValid(type))
102 ereport(ERROR,
103 (errcode(ERRCODE_UNDEFINED_OBJECT),
104 errmsg("could not find array type for data type %s",
105 format_type_be(exprType((Node *) tent->expr)))));
108 else
110 /* for all other sublink types, result is boolean */
111 type = BOOLOID;
114 break;
115 case T_SubPlan:
118 * Although the parser does not ever deal with already-planned
119 * expression trees, we support SubPlan nodes in this routine
120 * for the convenience of ruleutils.c.
122 SubPlan *subplan = (SubPlan *) expr;
124 if (subplan->subLinkType == EXPR_SUBLINK ||
125 subplan->subLinkType == ARRAY_SUBLINK)
127 /* get the type of the subselect's first target column */
128 type = subplan->firstColType;
129 if (subplan->subLinkType == ARRAY_SUBLINK)
131 type = get_array_type(type);
132 if (!OidIsValid(type))
133 ereport(ERROR,
134 (errcode(ERRCODE_UNDEFINED_OBJECT),
135 errmsg("could not find array type for data type %s",
136 format_type_be(subplan->firstColType))));
139 else
141 /* for all other subplan types, result is boolean */
142 type = BOOLOID;
145 break;
146 case T_AlternativeSubPlan:
148 /* As above, supported for the convenience of ruleutils.c */
149 AlternativeSubPlan *asplan = (AlternativeSubPlan *) expr;
151 /* subplans should all return the same thing */
152 type = exprType((Node *) linitial(asplan->subplans));
154 break;
155 case T_FieldSelect:
156 type = ((FieldSelect *) expr)->resulttype;
157 break;
158 case T_FieldStore:
159 type = ((FieldStore *) expr)->resulttype;
160 break;
161 case T_RelabelType:
162 type = ((RelabelType *) expr)->resulttype;
163 break;
164 case T_CoerceViaIO:
165 type = ((CoerceViaIO *) expr)->resulttype;
166 break;
167 case T_ArrayCoerceExpr:
168 type = ((ArrayCoerceExpr *) expr)->resulttype;
169 break;
170 case T_ConvertRowtypeExpr:
171 type = ((ConvertRowtypeExpr *) expr)->resulttype;
172 break;
173 case T_CaseExpr:
174 type = ((CaseExpr *) expr)->casetype;
175 break;
176 case T_CaseTestExpr:
177 type = ((CaseTestExpr *) expr)->typeId;
178 break;
179 case T_ArrayExpr:
180 type = ((ArrayExpr *) expr)->array_typeid;
181 break;
182 case T_RowExpr:
183 type = ((RowExpr *) expr)->row_typeid;
184 break;
185 case T_RowCompareExpr:
186 type = BOOLOID;
187 break;
188 case T_CoalesceExpr:
189 type = ((CoalesceExpr *) expr)->coalescetype;
190 break;
191 case T_MinMaxExpr:
192 type = ((MinMaxExpr *) expr)->minmaxtype;
193 break;
194 case T_XmlExpr:
195 if (((XmlExpr *) expr)->op == IS_DOCUMENT)
196 type = BOOLOID;
197 else if (((XmlExpr *) expr)->op == IS_XMLSERIALIZE)
198 type = TEXTOID;
199 else
200 type = XMLOID;
201 break;
202 case T_NullIfExpr:
203 type = exprType((Node *) linitial(((NullIfExpr *) expr)->args));
204 break;
205 case T_NullTest:
206 type = BOOLOID;
207 break;
208 case T_BooleanTest:
209 type = BOOLOID;
210 break;
211 case T_CoerceToDomain:
212 type = ((CoerceToDomain *) expr)->resulttype;
213 break;
214 case T_CoerceToDomainValue:
215 type = ((CoerceToDomainValue *) expr)->typeId;
216 break;
217 case T_SetToDefault:
218 type = ((SetToDefault *) expr)->typeId;
219 break;
220 case T_CurrentOfExpr:
221 type = BOOLOID;
222 break;
223 case T_PlaceHolderVar:
224 type = exprType((Node *) ((PlaceHolderVar *) expr)->phexpr);
225 break;
226 default:
227 elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
228 type = InvalidOid; /* keep compiler quiet */
229 break;
231 return type;
235 * exprTypmod -
236 * returns the type-specific attrmod of the expression, if it can be
237 * determined. In most cases, it can't and we return -1.
239 int32
240 exprTypmod(Node *expr)
242 if (!expr)
243 return -1;
245 switch (nodeTag(expr))
247 case T_Var:
248 return ((Var *) expr)->vartypmod;
249 case T_Const:
250 return ((Const *) expr)->consttypmod;
251 case T_Param:
252 return ((Param *) expr)->paramtypmod;
253 case T_ArrayRef:
254 /* typmod is the same for array or element */
255 return ((ArrayRef *) expr)->reftypmod;
256 case T_FuncExpr:
258 int32 coercedTypmod;
260 /* Be smart about length-coercion functions... */
261 if (exprIsLengthCoercion(expr, &coercedTypmod))
262 return coercedTypmod;
264 break;
265 case T_SubLink:
267 SubLink *sublink = (SubLink *) expr;
269 if (sublink->subLinkType == EXPR_SUBLINK ||
270 sublink->subLinkType == ARRAY_SUBLINK)
272 /* get the typmod of the subselect's first target column */
273 Query *qtree = (Query *) sublink->subselect;
274 TargetEntry *tent;
276 if (!qtree || !IsA(qtree, Query))
277 elog(ERROR, "cannot get type for untransformed sublink");
278 tent = (TargetEntry *) linitial(qtree->targetList);
279 Assert(IsA(tent, TargetEntry));
280 Assert(!tent->resjunk);
281 return exprTypmod((Node *) tent->expr);
282 /* note we don't need to care if it's an array */
285 break;
286 case T_FieldSelect:
287 return ((FieldSelect *) expr)->resulttypmod;
288 case T_RelabelType:
289 return ((RelabelType *) expr)->resulttypmod;
290 case T_ArrayCoerceExpr:
291 return ((ArrayCoerceExpr *) expr)->resulttypmod;
292 case T_CaseExpr:
295 * If all the alternatives agree on type/typmod, return that
296 * typmod, else use -1
298 CaseExpr *cexpr = (CaseExpr *) expr;
299 Oid casetype = cexpr->casetype;
300 int32 typmod;
301 ListCell *arg;
303 if (!cexpr->defresult)
304 return -1;
305 if (exprType((Node *) cexpr->defresult) != casetype)
306 return -1;
307 typmod = exprTypmod((Node *) cexpr->defresult);
308 if (typmod < 0)
309 return -1; /* no point in trying harder */
310 foreach(arg, cexpr->args)
312 CaseWhen *w = (CaseWhen *) lfirst(arg);
314 Assert(IsA(w, CaseWhen));
315 if (exprType((Node *) w->result) != casetype)
316 return -1;
317 if (exprTypmod((Node *) w->result) != typmod)
318 return -1;
320 return typmod;
322 break;
323 case T_CaseTestExpr:
324 return ((CaseTestExpr *) expr)->typeMod;
325 case T_ArrayExpr:
328 * If all the elements agree on type/typmod, return that
329 * typmod, else use -1
331 ArrayExpr *arrayexpr = (ArrayExpr *) expr;
332 Oid commontype;
333 int32 typmod;
334 ListCell *elem;
336 if (arrayexpr->elements == NIL)
337 return -1;
338 typmod = exprTypmod((Node *) linitial(arrayexpr->elements));
339 if (typmod < 0)
340 return -1; /* no point in trying harder */
341 if (arrayexpr->multidims)
342 commontype = arrayexpr->array_typeid;
343 else
344 commontype = arrayexpr->element_typeid;
345 foreach(elem, arrayexpr->elements)
347 Node *e = (Node *) lfirst(elem);
349 if (exprType(e) != commontype)
350 return -1;
351 if (exprTypmod(e) != typmod)
352 return -1;
354 return typmod;
356 break;
357 case T_CoalesceExpr:
360 * If all the alternatives agree on type/typmod, return that
361 * typmod, else use -1
363 CoalesceExpr *cexpr = (CoalesceExpr *) expr;
364 Oid coalescetype = cexpr->coalescetype;
365 int32 typmod;
366 ListCell *arg;
368 if (exprType((Node *) linitial(cexpr->args)) != coalescetype)
369 return -1;
370 typmod = exprTypmod((Node *) linitial(cexpr->args));
371 if (typmod < 0)
372 return -1; /* no point in trying harder */
373 for_each_cell(arg, lnext(list_head(cexpr->args)))
375 Node *e = (Node *) lfirst(arg);
377 if (exprType(e) != coalescetype)
378 return -1;
379 if (exprTypmod(e) != typmod)
380 return -1;
382 return typmod;
384 break;
385 case T_MinMaxExpr:
388 * If all the alternatives agree on type/typmod, return that
389 * typmod, else use -1
391 MinMaxExpr *mexpr = (MinMaxExpr *) expr;
392 Oid minmaxtype = mexpr->minmaxtype;
393 int32 typmod;
394 ListCell *arg;
396 if (exprType((Node *) linitial(mexpr->args)) != minmaxtype)
397 return -1;
398 typmod = exprTypmod((Node *) linitial(mexpr->args));
399 if (typmod < 0)
400 return -1; /* no point in trying harder */
401 for_each_cell(arg, lnext(list_head(mexpr->args)))
403 Node *e = (Node *) lfirst(arg);
405 if (exprType(e) != minmaxtype)
406 return -1;
407 if (exprTypmod(e) != typmod)
408 return -1;
410 return typmod;
412 break;
413 case T_NullIfExpr:
415 NullIfExpr *nexpr = (NullIfExpr *) expr;
417 return exprTypmod((Node *) linitial(nexpr->args));
419 break;
420 case T_CoerceToDomain:
421 return ((CoerceToDomain *) expr)->resulttypmod;
422 case T_CoerceToDomainValue:
423 return ((CoerceToDomainValue *) expr)->typeMod;
424 case T_SetToDefault:
425 return ((SetToDefault *) expr)->typeMod;
426 case T_PlaceHolderVar:
427 return exprTypmod((Node *) ((PlaceHolderVar *) expr)->phexpr);
428 default:
429 break;
431 return -1;
435 * exprIsLengthCoercion
436 * Detect whether an expression tree is an application of a datatype's
437 * typmod-coercion function. Optionally extract the result's typmod.
439 * If coercedTypmod is not NULL, the typmod is stored there if the expression
440 * is a length-coercion function, else -1 is stored there.
442 * Note that a combined type-and-length coercion will be treated as a
443 * length coercion by this routine.
445 bool
446 exprIsLengthCoercion(Node *expr, int32 *coercedTypmod)
448 if (coercedTypmod != NULL)
449 *coercedTypmod = -1; /* default result on failure */
452 * Scalar-type length coercions are FuncExprs, array-type length coercions
453 * are ArrayCoerceExprs
455 if (expr && IsA(expr, FuncExpr))
457 FuncExpr *func = (FuncExpr *) expr;
458 int nargs;
459 Const *second_arg;
462 * If it didn't come from a coercion context, reject.
464 if (func->funcformat != COERCE_EXPLICIT_CAST &&
465 func->funcformat != COERCE_IMPLICIT_CAST)
466 return false;
469 * If it's not a two-argument or three-argument function with the
470 * second argument being an int4 constant, it can't have been created
471 * from a length coercion (it must be a type coercion, instead).
473 nargs = list_length(func->args);
474 if (nargs < 2 || nargs > 3)
475 return false;
477 second_arg = (Const *) lsecond(func->args);
478 if (!IsA(second_arg, Const) ||
479 second_arg->consttype != INT4OID ||
480 second_arg->constisnull)
481 return false;
484 * OK, it is indeed a length-coercion function.
486 if (coercedTypmod != NULL)
487 *coercedTypmod = DatumGetInt32(second_arg->constvalue);
489 return true;
492 if (expr && IsA(expr, ArrayCoerceExpr))
494 ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) expr;
496 /* It's not a length coercion unless there's a nondefault typmod */
497 if (acoerce->resulttypmod < 0)
498 return false;
501 * OK, it is indeed a length-coercion expression.
503 if (coercedTypmod != NULL)
504 *coercedTypmod = acoerce->resulttypmod;
506 return true;
509 return false;
513 * expression_returns_set
514 * Test whether an expression returns a set result.
516 * Because we use expression_tree_walker(), this can also be applied to
517 * whole targetlists; it'll produce TRUE if any one of the tlist items
518 * returns a set.
520 bool
521 expression_returns_set(Node *clause)
523 return expression_returns_set_walker(clause, NULL);
526 static bool
527 expression_returns_set_walker(Node *node, void *context)
529 if (node == NULL)
530 return false;
531 if (IsA(node, FuncExpr))
533 FuncExpr *expr = (FuncExpr *) node;
535 if (expr->funcretset)
536 return true;
537 /* else fall through to check args */
539 if (IsA(node, OpExpr))
541 OpExpr *expr = (OpExpr *) node;
543 if (expr->opretset)
544 return true;
545 /* else fall through to check args */
548 /* Avoid recursion for some cases that can't return a set */
549 if (IsA(node, Aggref))
550 return false;
551 if (IsA(node, DistinctExpr))
552 return false;
553 if (IsA(node, ScalarArrayOpExpr))
554 return false;
555 if (IsA(node, BoolExpr))
556 return false;
557 if (IsA(node, SubLink))
558 return false;
559 if (IsA(node, SubPlan))
560 return false;
561 if (IsA(node, AlternativeSubPlan))
562 return false;
563 if (IsA(node, ArrayExpr))
564 return false;
565 if (IsA(node, RowExpr))
566 return false;
567 if (IsA(node, RowCompareExpr))
568 return false;
569 if (IsA(node, CoalesceExpr))
570 return false;
571 if (IsA(node, MinMaxExpr))
572 return false;
573 if (IsA(node, XmlExpr))
574 return false;
575 if (IsA(node, NullIfExpr))
576 return false;
578 return expression_tree_walker(node, expression_returns_set_walker,
579 context);
584 * exprLocation -
585 * returns the parse location of an expression tree, for error reports
587 * -1 is returned if the location can't be determined.
589 * For expressions larger than a single token, the intent here is to
590 * return the location of the expression's leftmost token, not necessarily
591 * the topmost Node's location field. For example, an OpExpr's location
592 * field will point at the operator name, but if it is not a prefix operator
593 * then we should return the location of the left-hand operand instead.
594 * The reason is that we want to reference the entire expression not just
595 * that operator, and pointing to its start seems to be the most natural way.
597 * The location is not perfect --- for example, since the grammar doesn't
598 * explicitly represent parentheses in the parsetree, given something that
599 * had been written "(a + b) * c" we are going to point at "a" not "(".
600 * But it should be plenty good enough for error reporting purposes.
602 * You might think that this code is overly general, for instance why check
603 * the operands of a FuncExpr node, when the function name can be expected
604 * to be to the left of them? There are a couple of reasons. The grammar
605 * sometimes builds expressions that aren't quite what the user wrote;
606 * for instance x IS NOT BETWEEN ... becomes a NOT-expression whose keyword
607 * pointer is to the right of its leftmost argument. Also, nodes that were
608 * inserted implicitly by parse analysis (such as FuncExprs for implicit
609 * coercions) will have location -1, and so we can have odd combinations of
610 * known and unknown locations in a tree.
613 exprLocation(Node *expr)
615 int loc;
617 if (expr == NULL)
618 return -1;
619 switch (nodeTag(expr))
621 case T_RangeVar:
622 loc = ((RangeVar *) expr)->location;
623 break;
624 case T_Var:
625 loc = ((Var *) expr)->location;
626 break;
627 case T_Const:
628 loc = ((Const *) expr)->location;
629 break;
630 case T_Param:
631 loc = ((Param *) expr)->location;
632 break;
633 case T_Aggref:
634 /* function name should always be the first thing */
635 loc = ((Aggref *) expr)->location;
636 break;
637 case T_ArrayRef:
638 /* just use array argument's location */
639 loc = exprLocation((Node *) ((ArrayRef *) expr)->refexpr);
640 break;
641 case T_FuncExpr:
643 FuncExpr *fexpr = (FuncExpr *) expr;
645 /* consider both function name and leftmost arg */
646 loc = leftmostLoc(fexpr->location,
647 exprLocation((Node *) fexpr->args));
649 break;
650 case T_OpExpr:
651 case T_DistinctExpr: /* struct-equivalent to OpExpr */
652 case T_NullIfExpr: /* struct-equivalent to OpExpr */
654 OpExpr *opexpr = (OpExpr *) expr;
656 /* consider both operator name and leftmost arg */
657 loc = leftmostLoc(opexpr->location,
658 exprLocation((Node *) opexpr->args));
660 break;
661 case T_ScalarArrayOpExpr:
663 ScalarArrayOpExpr *saopexpr = (ScalarArrayOpExpr *) expr;
665 /* consider both operator name and leftmost arg */
666 loc = leftmostLoc(saopexpr->location,
667 exprLocation((Node *) saopexpr->args));
669 break;
670 case T_BoolExpr:
672 BoolExpr *bexpr = (BoolExpr *) expr;
675 * Same as above, to handle either NOT or AND/OR. We can't
676 * special-case NOT because of the way that it's used for
677 * things like IS NOT BETWEEN.
679 loc = leftmostLoc(bexpr->location,
680 exprLocation((Node *) bexpr->args));
682 break;
683 case T_SubLink:
685 SubLink *sublink = (SubLink *) expr;
687 /* check the testexpr, if any, and the operator/keyword */
688 loc = leftmostLoc(exprLocation(sublink->testexpr),
689 sublink->location);
691 break;
692 case T_FieldSelect:
693 /* just use argument's location */
694 loc = exprLocation((Node *) ((FieldSelect *) expr)->arg);
695 break;
696 case T_FieldStore:
697 /* just use argument's location */
698 loc = exprLocation((Node *) ((FieldStore *) expr)->arg);
699 break;
700 case T_RelabelType:
702 RelabelType *rexpr = (RelabelType *) expr;
704 /* Much as above */
705 loc = leftmostLoc(rexpr->location,
706 exprLocation((Node *) rexpr->arg));
708 break;
709 case T_CoerceViaIO:
711 CoerceViaIO *cexpr = (CoerceViaIO *) expr;
713 /* Much as above */
714 loc = leftmostLoc(cexpr->location,
715 exprLocation((Node *) cexpr->arg));
717 break;
718 case T_ArrayCoerceExpr:
720 ArrayCoerceExpr *cexpr = (ArrayCoerceExpr *) expr;
722 /* Much as above */
723 loc = leftmostLoc(cexpr->location,
724 exprLocation((Node *) cexpr->arg));
726 break;
727 case T_ConvertRowtypeExpr:
729 ConvertRowtypeExpr *cexpr = (ConvertRowtypeExpr *) expr;
731 /* Much as above */
732 loc = leftmostLoc(cexpr->location,
733 exprLocation((Node *) cexpr->arg));
735 break;
736 case T_CaseExpr:
737 /* CASE keyword should always be the first thing */
738 loc = ((CaseExpr *) expr)->location;
739 break;
740 case T_CaseWhen:
741 /* WHEN keyword should always be the first thing */
742 loc = ((CaseWhen *) expr)->location;
743 break;
744 case T_ArrayExpr:
745 /* the location points at ARRAY or [, which must be leftmost */
746 loc = ((ArrayExpr *) expr)->location;
747 break;
748 case T_RowExpr:
749 /* the location points at ROW or (, which must be leftmost */
750 loc = ((RowExpr *) expr)->location;
751 break;
752 case T_RowCompareExpr:
753 /* just use leftmost argument's location */
754 loc = exprLocation((Node *) ((RowCompareExpr *) expr)->largs);
755 break;
756 case T_CoalesceExpr:
757 /* COALESCE keyword should always be the first thing */
758 loc = ((CoalesceExpr *) expr)->location;
759 break;
760 case T_MinMaxExpr:
761 /* GREATEST/LEAST keyword should always be the first thing */
762 loc = ((MinMaxExpr *) expr)->location;
763 break;
764 case T_XmlExpr:
766 XmlExpr *xexpr = (XmlExpr *) expr;
768 /* consider both function name and leftmost arg */
769 loc = leftmostLoc(xexpr->location,
770 exprLocation((Node *) xexpr->args));
772 break;
773 case T_NullTest:
774 /* just use argument's location */
775 loc = exprLocation((Node *) ((NullTest *) expr)->arg);
776 break;
777 case T_BooleanTest:
778 /* just use argument's location */
779 loc = exprLocation((Node *) ((BooleanTest *) expr)->arg);
780 break;
781 case T_CoerceToDomain:
783 CoerceToDomain *cexpr = (CoerceToDomain *) expr;
785 /* Much as above */
786 loc = leftmostLoc(cexpr->location,
787 exprLocation((Node *) cexpr->arg));
789 break;
790 case T_CoerceToDomainValue:
791 loc = ((CoerceToDomainValue *) expr)->location;
792 break;
793 case T_SetToDefault:
794 loc = ((SetToDefault *) expr)->location;
795 break;
796 case T_TargetEntry:
797 /* just use argument's location */
798 loc = exprLocation((Node *) ((TargetEntry *) expr)->expr);
799 break;
800 case T_IntoClause:
801 /* use the contained RangeVar's location --- close enough */
802 loc = exprLocation((Node *) ((IntoClause *) expr)->rel);
803 break;
804 case T_List:
806 /* report location of first list member that has a location */
807 ListCell *lc;
809 loc = -1; /* just to suppress compiler warning */
810 foreach(lc, (List *) expr)
812 loc = exprLocation((Node *) lfirst(lc));
813 if (loc >= 0)
814 break;
817 break;
818 case T_A_Expr:
820 A_Expr *aexpr = (A_Expr *) expr;
822 /* use leftmost of operator or left operand (if any) */
823 /* we assume right operand can't be to left of operator */
824 loc = leftmostLoc(aexpr->location,
825 exprLocation(aexpr->lexpr));
827 break;
828 case T_ColumnRef:
829 loc = ((ColumnRef *) expr)->location;
830 break;
831 case T_ParamRef:
832 loc = ((ParamRef *) expr)->location;
833 break;
834 case T_A_Const:
835 loc = ((A_Const *) expr)->location;
836 break;
837 case T_FuncCall:
839 FuncCall *fc = (FuncCall *) expr;
841 /* consider both function name and leftmost arg */
842 loc = leftmostLoc(fc->location,
843 exprLocation((Node *) fc->args));
845 break;
846 case T_A_ArrayExpr:
847 /* the location points at ARRAY or [, which must be leftmost */
848 loc = ((A_ArrayExpr *) expr)->location;
849 break;
850 case T_ResTarget:
851 /* we need not examine the contained expression (if any) */
852 loc = ((ResTarget *) expr)->location;
853 break;
854 case T_TypeCast:
856 TypeCast *tc = (TypeCast *) expr;
859 * This could represent CAST(), ::, or TypeName 'literal',
860 * so any of the components might be leftmost.
862 loc = exprLocation(tc->arg);
863 loc = leftmostLoc(loc, tc->typename->location);
864 loc = leftmostLoc(loc, tc->location);
866 break;
867 case T_SortBy:
868 /* just use argument's location (ignore operator, if any) */
869 loc = exprLocation(((SortBy *) expr)->node);
870 break;
871 case T_TypeName:
872 loc = ((TypeName *) expr)->location;
873 break;
874 case T_XmlSerialize:
875 /* XMLSERIALIZE keyword should always be the first thing */
876 loc = ((XmlSerialize *) expr)->location;
877 break;
878 case T_WithClause:
879 loc = ((WithClause *) expr)->location;
880 break;
881 case T_CommonTableExpr:
882 loc = ((CommonTableExpr *) expr)->location;
883 break;
884 case T_PlaceHolderVar:
885 /* just use argument's location */
886 loc = exprLocation((Node *) ((PlaceHolderVar *) expr)->phexpr);
887 break;
888 default:
889 /* for any other node type it's just unknown... */
890 loc = -1;
891 break;
893 return loc;
897 * leftmostLoc - support for exprLocation
899 * Take the minimum of two parse location values, but ignore unknowns
901 static int
902 leftmostLoc(int loc1, int loc2)
904 if (loc1 < 0)
905 return loc2;
906 else if (loc2 < 0)
907 return loc1;
908 else
909 return Min(loc1, loc2);
914 * Standard expression-tree walking support
916 * We used to have near-duplicate code in many different routines that
917 * understood how to recurse through an expression node tree. That was
918 * a pain to maintain, and we frequently had bugs due to some particular
919 * routine neglecting to support a particular node type. In most cases,
920 * these routines only actually care about certain node types, and don't
921 * care about other types except insofar as they have to recurse through
922 * non-primitive node types. Therefore, we now provide generic tree-walking
923 * logic to consolidate the redundant "boilerplate" code. There are
924 * two versions: expression_tree_walker() and expression_tree_mutator().
928 * expression_tree_walker() is designed to support routines that traverse
929 * a tree in a read-only fashion (although it will also work for routines
930 * that modify nodes in-place but never add/delete/replace nodes).
931 * A walker routine should look like this:
933 * bool my_walker (Node *node, my_struct *context)
935 * if (node == NULL)
936 * return false;
937 * // check for nodes that special work is required for, eg:
938 * if (IsA(node, Var))
940 * ... do special actions for Var nodes
942 * else if (IsA(node, ...))
944 * ... do special actions for other node types
946 * // for any node type not specially processed, do:
947 * return expression_tree_walker(node, my_walker, (void *) context);
950 * The "context" argument points to a struct that holds whatever context
951 * information the walker routine needs --- it can be used to return data
952 * gathered by the walker, too. This argument is not touched by
953 * expression_tree_walker, but it is passed down to recursive sub-invocations
954 * of my_walker. The tree walk is started from a setup routine that
955 * fills in the appropriate context struct, calls my_walker with the top-level
956 * node of the tree, and then examines the results.
958 * The walker routine should return "false" to continue the tree walk, or
959 * "true" to abort the walk and immediately return "true" to the top-level
960 * caller. This can be used to short-circuit the traversal if the walker
961 * has found what it came for. "false" is returned to the top-level caller
962 * iff no invocation of the walker returned "true".
964 * The node types handled by expression_tree_walker include all those
965 * normally found in target lists and qualifier clauses during the planning
966 * stage. In particular, it handles List nodes since a cnf-ified qual clause
967 * will have List structure at the top level, and it handles TargetEntry nodes
968 * so that a scan of a target list can be handled without additional code.
969 * Also, RangeTblRef, FromExpr, JoinExpr, and SetOperationStmt nodes are
970 * handled, so that query jointrees and setOperation trees can be processed
971 * without additional code.
973 * expression_tree_walker will handle SubLink nodes by recursing normally
974 * into the "testexpr" subtree (which is an expression belonging to the outer
975 * plan). It will also call the walker on the sub-Query node; however, when
976 * expression_tree_walker itself is called on a Query node, it does nothing
977 * and returns "false". The net effect is that unless the walker does
978 * something special at a Query node, sub-selects will not be visited during
979 * an expression tree walk. This is exactly the behavior wanted in many cases
980 * --- and for those walkers that do want to recurse into sub-selects, special
981 * behavior is typically needed anyway at the entry to a sub-select (such as
982 * incrementing a depth counter). A walker that wants to examine sub-selects
983 * should include code along the lines of:
985 * if (IsA(node, Query))
987 * adjust context for subquery;
988 * result = query_tree_walker((Query *) node, my_walker, context,
989 * 0); // adjust flags as needed
990 * restore context if needed;
991 * return result;
994 * query_tree_walker is a convenience routine (see below) that calls the
995 * walker on all the expression subtrees of the given Query node.
997 * expression_tree_walker will handle SubPlan nodes by recursing normally
998 * into the "testexpr" and the "args" list (which are expressions belonging to
999 * the outer plan). It will not touch the completed subplan, however. Since
1000 * there is no link to the original Query, it is not possible to recurse into
1001 * subselects of an already-planned expression tree. This is OK for current
1002 * uses, but may need to be revisited in future.
1005 bool
1006 expression_tree_walker(Node *node,
1007 bool (*walker) (),
1008 void *context)
1010 ListCell *temp;
1013 * The walker has already visited the current node, and so we need only
1014 * recurse into any sub-nodes it has.
1016 * We assume that the walker is not interested in List nodes per se, so
1017 * when we expect a List we just recurse directly to self without
1018 * bothering to call the walker.
1020 if (node == NULL)
1021 return false;
1023 /* Guard against stack overflow due to overly complex expressions */
1024 check_stack_depth();
1026 switch (nodeTag(node))
1028 case T_Var:
1029 case T_Const:
1030 case T_Param:
1031 case T_CoerceToDomainValue:
1032 case T_CaseTestExpr:
1033 case T_SetToDefault:
1034 case T_CurrentOfExpr:
1035 case T_RangeTblRef:
1036 /* primitive node types with no expression subnodes */
1037 break;
1038 case T_Aggref:
1040 Aggref *expr = (Aggref *) node;
1042 /* recurse directly on List */
1043 if (expression_tree_walker((Node *) expr->args,
1044 walker, context))
1045 return true;
1047 break;
1048 case T_ArrayRef:
1050 ArrayRef *aref = (ArrayRef *) node;
1052 /* recurse directly for upper/lower array index lists */
1053 if (expression_tree_walker((Node *) aref->refupperindexpr,
1054 walker, context))
1055 return true;
1056 if (expression_tree_walker((Node *) aref->reflowerindexpr,
1057 walker, context))
1058 return true;
1059 /* walker must see the refexpr and refassgnexpr, however */
1060 if (walker(aref->refexpr, context))
1061 return true;
1062 if (walker(aref->refassgnexpr, context))
1063 return true;
1065 break;
1066 case T_FuncExpr:
1068 FuncExpr *expr = (FuncExpr *) node;
1070 if (expression_tree_walker((Node *) expr->args,
1071 walker, context))
1072 return true;
1074 break;
1075 case T_OpExpr:
1077 OpExpr *expr = (OpExpr *) node;
1079 if (expression_tree_walker((Node *) expr->args,
1080 walker, context))
1081 return true;
1083 break;
1084 case T_DistinctExpr:
1086 DistinctExpr *expr = (DistinctExpr *) node;
1088 if (expression_tree_walker((Node *) expr->args,
1089 walker, context))
1090 return true;
1092 break;
1093 case T_ScalarArrayOpExpr:
1095 ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
1097 if (expression_tree_walker((Node *) expr->args,
1098 walker, context))
1099 return true;
1101 break;
1102 case T_BoolExpr:
1104 BoolExpr *expr = (BoolExpr *) node;
1106 if (expression_tree_walker((Node *) expr->args,
1107 walker, context))
1108 return true;
1110 break;
1111 case T_SubLink:
1113 SubLink *sublink = (SubLink *) node;
1115 if (walker(sublink->testexpr, context))
1116 return true;
1119 * Also invoke the walker on the sublink's Query node, so it
1120 * can recurse into the sub-query if it wants to.
1122 return walker(sublink->subselect, context);
1124 break;
1125 case T_SubPlan:
1127 SubPlan *subplan = (SubPlan *) node;
1129 /* recurse into the testexpr, but not into the Plan */
1130 if (walker(subplan->testexpr, context))
1131 return true;
1132 /* also examine args list */
1133 if (expression_tree_walker((Node *) subplan->args,
1134 walker, context))
1135 return true;
1137 break;
1138 case T_AlternativeSubPlan:
1139 return walker(((AlternativeSubPlan *) node)->subplans, context);
1140 case T_FieldSelect:
1141 return walker(((FieldSelect *) node)->arg, context);
1142 case T_FieldStore:
1144 FieldStore *fstore = (FieldStore *) node;
1146 if (walker(fstore->arg, context))
1147 return true;
1148 if (walker(fstore->newvals, context))
1149 return true;
1151 break;
1152 case T_RelabelType:
1153 return walker(((RelabelType *) node)->arg, context);
1154 case T_CoerceViaIO:
1155 return walker(((CoerceViaIO *) node)->arg, context);
1156 case T_ArrayCoerceExpr:
1157 return walker(((ArrayCoerceExpr *) node)->arg, context);
1158 case T_ConvertRowtypeExpr:
1159 return walker(((ConvertRowtypeExpr *) node)->arg, context);
1160 case T_CaseExpr:
1162 CaseExpr *caseexpr = (CaseExpr *) node;
1164 if (walker(caseexpr->arg, context))
1165 return true;
1166 /* we assume walker doesn't care about CaseWhens, either */
1167 foreach(temp, caseexpr->args)
1169 CaseWhen *when = (CaseWhen *) lfirst(temp);
1171 Assert(IsA(when, CaseWhen));
1172 if (walker(when->expr, context))
1173 return true;
1174 if (walker(when->result, context))
1175 return true;
1177 if (walker(caseexpr->defresult, context))
1178 return true;
1180 break;
1181 case T_ArrayExpr:
1182 return walker(((ArrayExpr *) node)->elements, context);
1183 case T_RowExpr:
1184 /* Assume colnames isn't interesting */
1185 return walker(((RowExpr *) node)->args, context);
1186 case T_RowCompareExpr:
1188 RowCompareExpr *rcexpr = (RowCompareExpr *) node;
1190 if (walker(rcexpr->largs, context))
1191 return true;
1192 if (walker(rcexpr->rargs, context))
1193 return true;
1195 break;
1196 case T_CoalesceExpr:
1197 return walker(((CoalesceExpr *) node)->args, context);
1198 case T_MinMaxExpr:
1199 return walker(((MinMaxExpr *) node)->args, context);
1200 case T_XmlExpr:
1202 XmlExpr *xexpr = (XmlExpr *) node;
1204 if (walker(xexpr->named_args, context))
1205 return true;
1206 /* we assume walker doesn't care about arg_names */
1207 if (walker(xexpr->args, context))
1208 return true;
1210 break;
1211 case T_NullIfExpr:
1212 return walker(((NullIfExpr *) node)->args, context);
1213 case T_NullTest:
1214 return walker(((NullTest *) node)->arg, context);
1215 case T_BooleanTest:
1216 return walker(((BooleanTest *) node)->arg, context);
1217 case T_CoerceToDomain:
1218 return walker(((CoerceToDomain *) node)->arg, context);
1219 case T_TargetEntry:
1220 return walker(((TargetEntry *) node)->expr, context);
1221 case T_Query:
1222 /* Do nothing with a sub-Query, per discussion above */
1223 break;
1224 case T_CommonTableExpr:
1226 CommonTableExpr *cte = (CommonTableExpr *) node;
1229 * Invoke the walker on the CTE's Query node, so it
1230 * can recurse into the sub-query if it wants to.
1232 return walker(cte->ctequery, context);
1234 break;
1235 case T_List:
1236 foreach(temp, (List *) node)
1238 if (walker((Node *) lfirst(temp), context))
1239 return true;
1241 break;
1242 case T_FromExpr:
1244 FromExpr *from = (FromExpr *) node;
1246 if (walker(from->fromlist, context))
1247 return true;
1248 if (walker(from->quals, context))
1249 return true;
1251 break;
1252 case T_JoinExpr:
1254 JoinExpr *join = (JoinExpr *) node;
1256 if (walker(join->larg, context))
1257 return true;
1258 if (walker(join->rarg, context))
1259 return true;
1260 if (walker(join->quals, context))
1261 return true;
1264 * alias clause, using list are deemed uninteresting.
1267 break;
1268 case T_SetOperationStmt:
1270 SetOperationStmt *setop = (SetOperationStmt *) node;
1272 if (walker(setop->larg, context))
1273 return true;
1274 if (walker(setop->rarg, context))
1275 return true;
1277 /* groupClauses are deemed uninteresting */
1279 break;
1280 case T_FlattenedSubLink:
1282 FlattenedSubLink *fslink = (FlattenedSubLink *) node;
1284 if (walker(fslink->quals, context))
1285 return true;
1287 break;
1288 case T_PlaceHolderVar:
1289 return walker(((PlaceHolderVar *) node)->phexpr, context);
1290 case T_AppendRelInfo:
1292 AppendRelInfo *appinfo = (AppendRelInfo *) node;
1294 if (expression_tree_walker((Node *) appinfo->translated_vars,
1295 walker, context))
1296 return true;
1298 break;
1299 case T_PlaceHolderInfo:
1300 return walker(((PlaceHolderInfo *) node)->ph_var, context);
1301 default:
1302 elog(ERROR, "unrecognized node type: %d",
1303 (int) nodeTag(node));
1304 break;
1306 return false;
1310 * query_tree_walker --- initiate a walk of a Query's expressions
1312 * This routine exists just to reduce the number of places that need to know
1313 * where all the expression subtrees of a Query are. Note it can be used
1314 * for starting a walk at top level of a Query regardless of whether the
1315 * walker intends to descend into subqueries. It is also useful for
1316 * descending into subqueries within a walker.
1318 * Some callers want to suppress visitation of certain items in the sub-Query,
1319 * typically because they need to process them specially, or don't actually
1320 * want to recurse into subqueries. This is supported by the flags argument,
1321 * which is the bitwise OR of flag values to suppress visitation of
1322 * indicated items. (More flag bits may be added as needed.)
1324 bool
1325 query_tree_walker(Query *query,
1326 bool (*walker) (),
1327 void *context,
1328 int flags)
1330 Assert(query != NULL && IsA(query, Query));
1332 if (walker((Node *) query->targetList, context))
1333 return true;
1334 if (walker((Node *) query->returningList, context))
1335 return true;
1336 if (walker((Node *) query->jointree, context))
1337 return true;
1338 if (walker(query->setOperations, context))
1339 return true;
1340 if (walker(query->havingQual, context))
1341 return true;
1342 if (walker(query->limitOffset, context))
1343 return true;
1344 if (walker(query->limitCount, context))
1345 return true;
1346 if (!(flags & QTW_IGNORE_CTE_SUBQUERIES))
1348 if (walker((Node *) query->cteList, context))
1349 return true;
1351 if (range_table_walker(query->rtable, walker, context, flags))
1352 return true;
1353 return false;
1357 * range_table_walker is just the part of query_tree_walker that scans
1358 * a query's rangetable. This is split out since it can be useful on
1359 * its own.
1361 bool
1362 range_table_walker(List *rtable,
1363 bool (*walker) (),
1364 void *context,
1365 int flags)
1367 ListCell *rt;
1369 foreach(rt, rtable)
1371 RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
1373 /* For historical reasons, visiting RTEs is not the default */
1374 if (flags & QTW_EXAMINE_RTES)
1375 if (walker(rte, context))
1376 return true;
1378 switch (rte->rtekind)
1380 case RTE_RELATION:
1381 case RTE_SPECIAL:
1382 case RTE_CTE:
1383 /* nothing to do */
1384 break;
1385 case RTE_SUBQUERY:
1386 if (!(flags & QTW_IGNORE_RT_SUBQUERIES))
1387 if (walker(rte->subquery, context))
1388 return true;
1389 break;
1390 case RTE_JOIN:
1391 if (!(flags & QTW_IGNORE_JOINALIASES))
1392 if (walker(rte->joinaliasvars, context))
1393 return true;
1394 break;
1395 case RTE_FUNCTION:
1396 if (walker(rte->funcexpr, context))
1397 return true;
1398 break;
1399 case RTE_VALUES:
1400 if (walker(rte->values_lists, context))
1401 return true;
1402 break;
1405 return false;
1410 * expression_tree_mutator() is designed to support routines that make a
1411 * modified copy of an expression tree, with some nodes being added,
1412 * removed, or replaced by new subtrees. The original tree is (normally)
1413 * not changed. Each recursion level is responsible for returning a copy of
1414 * (or appropriately modified substitute for) the subtree it is handed.
1415 * A mutator routine should look like this:
1417 * Node * my_mutator (Node *node, my_struct *context)
1419 * if (node == NULL)
1420 * return NULL;
1421 * // check for nodes that special work is required for, eg:
1422 * if (IsA(node, Var))
1424 * ... create and return modified copy of Var node
1426 * else if (IsA(node, ...))
1428 * ... do special transformations of other node types
1430 * // for any node type not specially processed, do:
1431 * return expression_tree_mutator(node, my_mutator, (void *) context);
1434 * The "context" argument points to a struct that holds whatever context
1435 * information the mutator routine needs --- it can be used to return extra
1436 * data gathered by the mutator, too. This argument is not touched by
1437 * expression_tree_mutator, but it is passed down to recursive sub-invocations
1438 * of my_mutator. The tree walk is started from a setup routine that
1439 * fills in the appropriate context struct, calls my_mutator with the
1440 * top-level node of the tree, and does any required post-processing.
1442 * Each level of recursion must return an appropriately modified Node.
1443 * If expression_tree_mutator() is called, it will make an exact copy
1444 * of the given Node, but invoke my_mutator() to copy the sub-node(s)
1445 * of that Node. In this way, my_mutator() has full control over the
1446 * copying process but need not directly deal with expression trees
1447 * that it has no interest in.
1449 * Just as for expression_tree_walker, the node types handled by
1450 * expression_tree_mutator include all those normally found in target lists
1451 * and qualifier clauses during the planning stage.
1453 * expression_tree_mutator will handle SubLink nodes by recursing normally
1454 * into the "testexpr" subtree (which is an expression belonging to the outer
1455 * plan). It will also call the mutator on the sub-Query node; however, when
1456 * expression_tree_mutator itself is called on a Query node, it does nothing
1457 * and returns the unmodified Query node. The net effect is that unless the
1458 * mutator does something special at a Query node, sub-selects will not be
1459 * visited or modified; the original sub-select will be linked to by the new
1460 * SubLink node. Mutators that want to descend into sub-selects will usually
1461 * do so by recognizing Query nodes and calling query_tree_mutator (below).
1463 * expression_tree_mutator will handle a SubPlan node by recursing into the
1464 * "testexpr" and the "args" list (which belong to the outer plan), but it
1465 * will simply copy the link to the inner plan, since that's typically what
1466 * expression tree mutators want. A mutator that wants to modify the subplan
1467 * can force appropriate behavior by recognizing SubPlan expression nodes
1468 * and doing the right thing.
1471 Node *
1472 expression_tree_mutator(Node *node,
1473 Node *(*mutator) (),
1474 void *context)
1477 * The mutator has already decided not to modify the current node, but we
1478 * must call the mutator for any sub-nodes.
1481 #define FLATCOPY(newnode, node, nodetype) \
1482 ( (newnode) = (nodetype *) palloc(sizeof(nodetype)), \
1483 memcpy((newnode), (node), sizeof(nodetype)) )
1485 #define CHECKFLATCOPY(newnode, node, nodetype) \
1486 ( AssertMacro(IsA((node), nodetype)), \
1487 (newnode) = (nodetype *) palloc(sizeof(nodetype)), \
1488 memcpy((newnode), (node), sizeof(nodetype)) )
1490 #define MUTATE(newfield, oldfield, fieldtype) \
1491 ( (newfield) = (fieldtype) mutator((Node *) (oldfield), context) )
1493 if (node == NULL)
1494 return NULL;
1496 /* Guard against stack overflow due to overly complex expressions */
1497 check_stack_depth();
1499 switch (nodeTag(node))
1502 * Primitive node types with no expression subnodes. Var and
1503 * Const are frequent enough to deserve special cases, the others
1504 * we just use copyObject for.
1506 case T_Var:
1508 Var *var = (Var *) node;
1509 Var *newnode;
1511 FLATCOPY(newnode, var, Var);
1512 return (Node *) newnode;
1514 break;
1515 case T_Const:
1517 Const *oldnode = (Const *) node;
1518 Const *newnode;
1520 FLATCOPY(newnode, oldnode, Const);
1521 /* XXX we don't bother with datumCopy; should we? */
1522 return (Node *) newnode;
1524 break;
1525 case T_Param:
1526 case T_CoerceToDomainValue:
1527 case T_CaseTestExpr:
1528 case T_SetToDefault:
1529 case T_CurrentOfExpr:
1530 case T_RangeTblRef:
1531 return (Node *) copyObject(node);
1532 case T_Aggref:
1534 Aggref *aggref = (Aggref *) node;
1535 Aggref *newnode;
1537 FLATCOPY(newnode, aggref, Aggref);
1538 MUTATE(newnode->args, aggref->args, List *);
1539 return (Node *) newnode;
1541 break;
1542 case T_ArrayRef:
1544 ArrayRef *arrayref = (ArrayRef *) node;
1545 ArrayRef *newnode;
1547 FLATCOPY(newnode, arrayref, ArrayRef);
1548 MUTATE(newnode->refupperindexpr, arrayref->refupperindexpr,
1549 List *);
1550 MUTATE(newnode->reflowerindexpr, arrayref->reflowerindexpr,
1551 List *);
1552 MUTATE(newnode->refexpr, arrayref->refexpr,
1553 Expr *);
1554 MUTATE(newnode->refassgnexpr, arrayref->refassgnexpr,
1555 Expr *);
1556 return (Node *) newnode;
1558 break;
1559 case T_FuncExpr:
1561 FuncExpr *expr = (FuncExpr *) node;
1562 FuncExpr *newnode;
1564 FLATCOPY(newnode, expr, FuncExpr);
1565 MUTATE(newnode->args, expr->args, List *);
1566 return (Node *) newnode;
1568 break;
1569 case T_OpExpr:
1571 OpExpr *expr = (OpExpr *) node;
1572 OpExpr *newnode;
1574 FLATCOPY(newnode, expr, OpExpr);
1575 MUTATE(newnode->args, expr->args, List *);
1576 return (Node *) newnode;
1578 break;
1579 case T_DistinctExpr:
1581 DistinctExpr *expr = (DistinctExpr *) node;
1582 DistinctExpr *newnode;
1584 FLATCOPY(newnode, expr, DistinctExpr);
1585 MUTATE(newnode->args, expr->args, List *);
1586 return (Node *) newnode;
1588 break;
1589 case T_ScalarArrayOpExpr:
1591 ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
1592 ScalarArrayOpExpr *newnode;
1594 FLATCOPY(newnode, expr, ScalarArrayOpExpr);
1595 MUTATE(newnode->args, expr->args, List *);
1596 return (Node *) newnode;
1598 break;
1599 case T_BoolExpr:
1601 BoolExpr *expr = (BoolExpr *) node;
1602 BoolExpr *newnode;
1604 FLATCOPY(newnode, expr, BoolExpr);
1605 MUTATE(newnode->args, expr->args, List *);
1606 return (Node *) newnode;
1608 break;
1609 case T_SubLink:
1611 SubLink *sublink = (SubLink *) node;
1612 SubLink *newnode;
1614 FLATCOPY(newnode, sublink, SubLink);
1615 MUTATE(newnode->testexpr, sublink->testexpr, Node *);
1618 * Also invoke the mutator on the sublink's Query node, so it
1619 * can recurse into the sub-query if it wants to.
1621 MUTATE(newnode->subselect, sublink->subselect, Node *);
1622 return (Node *) newnode;
1624 break;
1625 case T_SubPlan:
1627 SubPlan *subplan = (SubPlan *) node;
1628 SubPlan *newnode;
1630 FLATCOPY(newnode, subplan, SubPlan);
1631 /* transform testexpr */
1632 MUTATE(newnode->testexpr, subplan->testexpr, Node *);
1633 /* transform args list (params to be passed to subplan) */
1634 MUTATE(newnode->args, subplan->args, List *);
1635 /* but not the sub-Plan itself, which is referenced as-is */
1636 return (Node *) newnode;
1638 break;
1639 case T_AlternativeSubPlan:
1641 AlternativeSubPlan *asplan = (AlternativeSubPlan *) node;
1642 AlternativeSubPlan *newnode;
1644 FLATCOPY(newnode, asplan, AlternativeSubPlan);
1645 MUTATE(newnode->subplans, asplan->subplans, List *);
1646 return (Node *) newnode;
1648 break;
1649 case T_FieldSelect:
1651 FieldSelect *fselect = (FieldSelect *) node;
1652 FieldSelect *newnode;
1654 FLATCOPY(newnode, fselect, FieldSelect);
1655 MUTATE(newnode->arg, fselect->arg, Expr *);
1656 return (Node *) newnode;
1658 break;
1659 case T_FieldStore:
1661 FieldStore *fstore = (FieldStore *) node;
1662 FieldStore *newnode;
1664 FLATCOPY(newnode, fstore, FieldStore);
1665 MUTATE(newnode->arg, fstore->arg, Expr *);
1666 MUTATE(newnode->newvals, fstore->newvals, List *);
1667 newnode->fieldnums = list_copy(fstore->fieldnums);
1668 return (Node *) newnode;
1670 break;
1671 case T_RelabelType:
1673 RelabelType *relabel = (RelabelType *) node;
1674 RelabelType *newnode;
1676 FLATCOPY(newnode, relabel, RelabelType);
1677 MUTATE(newnode->arg, relabel->arg, Expr *);
1678 return (Node *) newnode;
1680 break;
1681 case T_CoerceViaIO:
1683 CoerceViaIO *iocoerce = (CoerceViaIO *) node;
1684 CoerceViaIO *newnode;
1686 FLATCOPY(newnode, iocoerce, CoerceViaIO);
1687 MUTATE(newnode->arg, iocoerce->arg, Expr *);
1688 return (Node *) newnode;
1690 break;
1691 case T_ArrayCoerceExpr:
1693 ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node;
1694 ArrayCoerceExpr *newnode;
1696 FLATCOPY(newnode, acoerce, ArrayCoerceExpr);
1697 MUTATE(newnode->arg, acoerce->arg, Expr *);
1698 return (Node *) newnode;
1700 break;
1701 case T_ConvertRowtypeExpr:
1703 ConvertRowtypeExpr *convexpr = (ConvertRowtypeExpr *) node;
1704 ConvertRowtypeExpr *newnode;
1706 FLATCOPY(newnode, convexpr, ConvertRowtypeExpr);
1707 MUTATE(newnode->arg, convexpr->arg, Expr *);
1708 return (Node *) newnode;
1710 break;
1711 case T_CaseExpr:
1713 CaseExpr *caseexpr = (CaseExpr *) node;
1714 CaseExpr *newnode;
1716 FLATCOPY(newnode, caseexpr, CaseExpr);
1717 MUTATE(newnode->arg, caseexpr->arg, Expr *);
1718 MUTATE(newnode->args, caseexpr->args, List *);
1719 MUTATE(newnode->defresult, caseexpr->defresult, Expr *);
1720 return (Node *) newnode;
1722 break;
1723 case T_CaseWhen:
1725 CaseWhen *casewhen = (CaseWhen *) node;
1726 CaseWhen *newnode;
1728 FLATCOPY(newnode, casewhen, CaseWhen);
1729 MUTATE(newnode->expr, casewhen->expr, Expr *);
1730 MUTATE(newnode->result, casewhen->result, Expr *);
1731 return (Node *) newnode;
1733 break;
1734 case T_ArrayExpr:
1736 ArrayExpr *arrayexpr = (ArrayExpr *) node;
1737 ArrayExpr *newnode;
1739 FLATCOPY(newnode, arrayexpr, ArrayExpr);
1740 MUTATE(newnode->elements, arrayexpr->elements, List *);
1741 return (Node *) newnode;
1743 break;
1744 case T_RowExpr:
1746 RowExpr *rowexpr = (RowExpr *) node;
1747 RowExpr *newnode;
1749 FLATCOPY(newnode, rowexpr, RowExpr);
1750 MUTATE(newnode->args, rowexpr->args, List *);
1751 /* Assume colnames needn't be duplicated */
1752 return (Node *) newnode;
1754 break;
1755 case T_RowCompareExpr:
1757 RowCompareExpr *rcexpr = (RowCompareExpr *) node;
1758 RowCompareExpr *newnode;
1760 FLATCOPY(newnode, rcexpr, RowCompareExpr);
1761 MUTATE(newnode->largs, rcexpr->largs, List *);
1762 MUTATE(newnode->rargs, rcexpr->rargs, List *);
1763 return (Node *) newnode;
1765 break;
1766 case T_CoalesceExpr:
1768 CoalesceExpr *coalesceexpr = (CoalesceExpr *) node;
1769 CoalesceExpr *newnode;
1771 FLATCOPY(newnode, coalesceexpr, CoalesceExpr);
1772 MUTATE(newnode->args, coalesceexpr->args, List *);
1773 return (Node *) newnode;
1775 break;
1776 case T_MinMaxExpr:
1778 MinMaxExpr *minmaxexpr = (MinMaxExpr *) node;
1779 MinMaxExpr *newnode;
1781 FLATCOPY(newnode, minmaxexpr, MinMaxExpr);
1782 MUTATE(newnode->args, minmaxexpr->args, List *);
1783 return (Node *) newnode;
1785 break;
1786 case T_XmlExpr:
1788 XmlExpr *xexpr = (XmlExpr *) node;
1789 XmlExpr *newnode;
1791 FLATCOPY(newnode, xexpr, XmlExpr);
1792 MUTATE(newnode->named_args, xexpr->named_args, List *);
1793 /* assume mutator does not care about arg_names */
1794 MUTATE(newnode->args, xexpr->args, List *);
1795 return (Node *) newnode;
1797 break;
1798 case T_NullIfExpr:
1800 NullIfExpr *expr = (NullIfExpr *) node;
1801 NullIfExpr *newnode;
1803 FLATCOPY(newnode, expr, NullIfExpr);
1804 MUTATE(newnode->args, expr->args, List *);
1805 return (Node *) newnode;
1807 break;
1808 case T_NullTest:
1810 NullTest *ntest = (NullTest *) node;
1811 NullTest *newnode;
1813 FLATCOPY(newnode, ntest, NullTest);
1814 MUTATE(newnode->arg, ntest->arg, Expr *);
1815 return (Node *) newnode;
1817 break;
1818 case T_BooleanTest:
1820 BooleanTest *btest = (BooleanTest *) node;
1821 BooleanTest *newnode;
1823 FLATCOPY(newnode, btest, BooleanTest);
1824 MUTATE(newnode->arg, btest->arg, Expr *);
1825 return (Node *) newnode;
1827 break;
1828 case T_CoerceToDomain:
1830 CoerceToDomain *ctest = (CoerceToDomain *) node;
1831 CoerceToDomain *newnode;
1833 FLATCOPY(newnode, ctest, CoerceToDomain);
1834 MUTATE(newnode->arg, ctest->arg, Expr *);
1835 return (Node *) newnode;
1837 break;
1838 case T_TargetEntry:
1840 TargetEntry *targetentry = (TargetEntry *) node;
1841 TargetEntry *newnode;
1843 FLATCOPY(newnode, targetentry, TargetEntry);
1844 MUTATE(newnode->expr, targetentry->expr, Expr *);
1845 return (Node *) newnode;
1847 break;
1848 case T_Query:
1849 /* Do nothing with a sub-Query, per discussion above */
1850 return node;
1851 case T_CommonTableExpr:
1853 CommonTableExpr *cte = (CommonTableExpr *) node;
1854 CommonTableExpr *newnode;
1856 FLATCOPY(newnode, cte, CommonTableExpr);
1859 * Also invoke the mutator on the CTE's Query node, so it
1860 * can recurse into the sub-query if it wants to.
1862 MUTATE(newnode->ctequery, cte->ctequery, Node *);
1863 return (Node *) newnode;
1865 break;
1866 case T_List:
1869 * We assume the mutator isn't interested in the list nodes
1870 * per se, so just invoke it on each list element. NOTE: this
1871 * would fail badly on a list with integer elements!
1873 List *resultlist;
1874 ListCell *temp;
1876 resultlist = NIL;
1877 foreach(temp, (List *) node)
1879 resultlist = lappend(resultlist,
1880 mutator((Node *) lfirst(temp),
1881 context));
1883 return (Node *) resultlist;
1885 break;
1886 case T_FromExpr:
1888 FromExpr *from = (FromExpr *) node;
1889 FromExpr *newnode;
1891 FLATCOPY(newnode, from, FromExpr);
1892 MUTATE(newnode->fromlist, from->fromlist, List *);
1893 MUTATE(newnode->quals, from->quals, Node *);
1894 return (Node *) newnode;
1896 break;
1897 case T_JoinExpr:
1899 JoinExpr *join = (JoinExpr *) node;
1900 JoinExpr *newnode;
1902 FLATCOPY(newnode, join, JoinExpr);
1903 MUTATE(newnode->larg, join->larg, Node *);
1904 MUTATE(newnode->rarg, join->rarg, Node *);
1905 MUTATE(newnode->quals, join->quals, Node *);
1906 /* We do not mutate alias or using by default */
1907 return (Node *) newnode;
1909 break;
1910 case T_SetOperationStmt:
1912 SetOperationStmt *setop = (SetOperationStmt *) node;
1913 SetOperationStmt *newnode;
1915 FLATCOPY(newnode, setop, SetOperationStmt);
1916 MUTATE(newnode->larg, setop->larg, Node *);
1917 MUTATE(newnode->rarg, setop->rarg, Node *);
1918 /* We do not mutate groupClauses by default */
1919 return (Node *) newnode;
1921 break;
1922 case T_FlattenedSubLink:
1924 FlattenedSubLink *fslink = (FlattenedSubLink *) node;
1925 FlattenedSubLink *newnode;
1927 FLATCOPY(newnode, fslink, FlattenedSubLink);
1928 /* Assume we need not copy the relids bitmapsets */
1929 MUTATE(newnode->quals, fslink->quals, Expr *);
1930 return (Node *) newnode;
1932 break;
1933 case T_PlaceHolderVar:
1935 PlaceHolderVar *phv = (PlaceHolderVar *) node;
1936 PlaceHolderVar *newnode;
1938 FLATCOPY(newnode, phv, PlaceHolderVar);
1939 MUTATE(newnode->phexpr, phv->phexpr, Expr *);
1940 /* Assume we need not copy the relids bitmapset */
1941 return (Node *) newnode;
1943 break;
1944 case T_AppendRelInfo:
1946 AppendRelInfo *appinfo = (AppendRelInfo *) node;
1947 AppendRelInfo *newnode;
1949 FLATCOPY(newnode, appinfo, AppendRelInfo);
1950 MUTATE(newnode->translated_vars, appinfo->translated_vars, List *);
1951 return (Node *) newnode;
1953 break;
1954 case T_PlaceHolderInfo:
1956 PlaceHolderInfo *phinfo = (PlaceHolderInfo *) node;
1957 PlaceHolderInfo *newnode;
1959 FLATCOPY(newnode, phinfo, PlaceHolderInfo);
1960 MUTATE(newnode->ph_var, phinfo->ph_var, PlaceHolderVar *);
1961 /* Assume we need not copy the relids bitmapsets */
1962 return (Node *) newnode;
1964 break;
1965 default:
1966 elog(ERROR, "unrecognized node type: %d",
1967 (int) nodeTag(node));
1968 break;
1970 /* can't get here, but keep compiler happy */
1971 return NULL;
1976 * query_tree_mutator --- initiate modification of a Query's expressions
1978 * This routine exists just to reduce the number of places that need to know
1979 * where all the expression subtrees of a Query are. Note it can be used
1980 * for starting a walk at top level of a Query regardless of whether the
1981 * mutator intends to descend into subqueries. It is also useful for
1982 * descending into subqueries within a mutator.
1984 * Some callers want to suppress mutating of certain items in the Query,
1985 * typically because they need to process them specially, or don't actually
1986 * want to recurse into subqueries. This is supported by the flags argument,
1987 * which is the bitwise OR of flag values to suppress mutating of
1988 * indicated items. (More flag bits may be added as needed.)
1990 * Normally the Query node itself is copied, but some callers want it to be
1991 * modified in-place; they must pass QTW_DONT_COPY_QUERY in flags. All
1992 * modified substructure is safely copied in any case.
1994 Query *
1995 query_tree_mutator(Query *query,
1996 Node *(*mutator) (),
1997 void *context,
1998 int flags)
2000 Assert(query != NULL && IsA(query, Query));
2002 if (!(flags & QTW_DONT_COPY_QUERY))
2004 Query *newquery;
2006 FLATCOPY(newquery, query, Query);
2007 query = newquery;
2010 MUTATE(query->targetList, query->targetList, List *);
2011 MUTATE(query->returningList, query->returningList, List *);
2012 MUTATE(query->jointree, query->jointree, FromExpr *);
2013 MUTATE(query->setOperations, query->setOperations, Node *);
2014 MUTATE(query->havingQual, query->havingQual, Node *);
2015 MUTATE(query->limitOffset, query->limitOffset, Node *);
2016 MUTATE(query->limitCount, query->limitCount, Node *);
2017 if (!(flags & QTW_IGNORE_CTE_SUBQUERIES))
2018 MUTATE(query->cteList, query->cteList, List *);
2019 else /* else copy CTE list as-is */
2020 query->cteList = copyObject(query->cteList);
2021 query->rtable = range_table_mutator(query->rtable,
2022 mutator, context, flags);
2023 return query;
2027 * range_table_mutator is just the part of query_tree_mutator that processes
2028 * a query's rangetable. This is split out since it can be useful on
2029 * its own.
2031 List *
2032 range_table_mutator(List *rtable,
2033 Node *(*mutator) (),
2034 void *context,
2035 int flags)
2037 List *newrt = NIL;
2038 ListCell *rt;
2040 foreach(rt, rtable)
2042 RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
2043 RangeTblEntry *newrte;
2045 FLATCOPY(newrte, rte, RangeTblEntry);
2046 switch (rte->rtekind)
2048 case RTE_RELATION:
2049 case RTE_SPECIAL:
2050 case RTE_CTE:
2051 /* we don't bother to copy eref, aliases, etc; OK? */
2052 break;
2053 case RTE_SUBQUERY:
2054 if (!(flags & QTW_IGNORE_RT_SUBQUERIES))
2056 CHECKFLATCOPY(newrte->subquery, rte->subquery, Query);
2057 MUTATE(newrte->subquery, newrte->subquery, Query *);
2059 else
2061 /* else, copy RT subqueries as-is */
2062 newrte->subquery = copyObject(rte->subquery);
2064 break;
2065 case RTE_JOIN:
2066 if (!(flags & QTW_IGNORE_JOINALIASES))
2067 MUTATE(newrte->joinaliasvars, rte->joinaliasvars, List *);
2068 else
2070 /* else, copy join aliases as-is */
2071 newrte->joinaliasvars = copyObject(rte->joinaliasvars);
2073 break;
2074 case RTE_FUNCTION:
2075 MUTATE(newrte->funcexpr, rte->funcexpr, Node *);
2076 break;
2077 case RTE_VALUES:
2078 MUTATE(newrte->values_lists, rte->values_lists, List *);
2079 break;
2081 newrt = lappend(newrt, newrte);
2083 return newrt;
2087 * query_or_expression_tree_walker --- hybrid form
2089 * This routine will invoke query_tree_walker if called on a Query node,
2090 * else will invoke the walker directly. This is a useful way of starting
2091 * the recursion when the walker's normal change of state is not appropriate
2092 * for the outermost Query node.
2094 bool
2095 query_or_expression_tree_walker(Node *node,
2096 bool (*walker) (),
2097 void *context,
2098 int flags)
2100 if (node && IsA(node, Query))
2101 return query_tree_walker((Query *) node,
2102 walker,
2103 context,
2104 flags);
2105 else
2106 return walker(node, context);
2110 * query_or_expression_tree_mutator --- hybrid form
2112 * This routine will invoke query_tree_mutator if called on a Query node,
2113 * else will invoke the mutator directly. This is a useful way of starting
2114 * the recursion when the mutator's normal change of state is not appropriate
2115 * for the outermost Query node.
2117 Node *
2118 query_or_expression_tree_mutator(Node *node,
2119 Node *(*mutator) (),
2120 void *context,
2121 int flags)
2123 if (node && IsA(node, Query))
2124 return (Node *) query_tree_mutator((Query *) node,
2125 mutator,
2126 context,
2127 flags);
2128 else
2129 return mutator(node, context);
2134 * raw_expression_tree_walker --- walk raw parse trees
2136 * This has exactly the same API as expression_tree_walker, but instead of
2137 * walking post-analysis parse trees, it knows how to walk the node types
2138 * found in raw grammar output. (There is not currently any need for a
2139 * combined walker, so we keep them separate in the name of efficiency.)
2140 * Unlike expression_tree_walker, there is no special rule about query
2141 * boundaries: we descend to everything that's possibly interesting.
2143 * Currently, the node type coverage extends to SelectStmt and everything
2144 * that could appear under it, but not other statement types.
2146 bool
2147 raw_expression_tree_walker(Node *node, bool (*walker) (), void *context)
2149 ListCell *temp;
2152 * The walker has already visited the current node, and so we need only
2153 * recurse into any sub-nodes it has.
2155 if (node == NULL)
2156 return false;
2158 /* Guard against stack overflow due to overly complex expressions */
2159 check_stack_depth();
2161 switch (nodeTag(node))
2163 case T_SetToDefault:
2164 case T_CurrentOfExpr:
2165 case T_Integer:
2166 case T_Float:
2167 case T_String:
2168 case T_BitString:
2169 case T_Null:
2170 case T_ParamRef:
2171 case T_A_Const:
2172 case T_A_Star:
2173 /* primitive node types with no subnodes */
2174 break;
2175 case T_Alias:
2176 /* we assume the colnames list isn't interesting */
2177 break;
2178 case T_RangeVar:
2179 return walker(((RangeVar *) node)->alias, context);
2180 case T_SubLink:
2182 SubLink *sublink = (SubLink *) node;
2184 if (walker(sublink->testexpr, context))
2185 return true;
2186 /* we assume the operName is not interesting */
2187 if (walker(sublink->subselect, context))
2188 return true;
2190 break;
2191 case T_CaseExpr:
2193 CaseExpr *caseexpr = (CaseExpr *) node;
2195 if (walker(caseexpr->arg, context))
2196 return true;
2197 /* we assume walker doesn't care about CaseWhens, either */
2198 foreach(temp, caseexpr->args)
2200 CaseWhen *when = (CaseWhen *) lfirst(temp);
2202 Assert(IsA(when, CaseWhen));
2203 if (walker(when->expr, context))
2204 return true;
2205 if (walker(when->result, context))
2206 return true;
2208 if (walker(caseexpr->defresult, context))
2209 return true;
2211 break;
2212 case T_RowExpr:
2213 /* Assume colnames isn't interesting */
2214 return walker(((RowExpr *) node)->args, context);
2215 case T_CoalesceExpr:
2216 return walker(((CoalesceExpr *) node)->args, context);
2217 case T_MinMaxExpr:
2218 return walker(((MinMaxExpr *) node)->args, context);
2219 case T_XmlExpr:
2221 XmlExpr *xexpr = (XmlExpr *) node;
2223 if (walker(xexpr->named_args, context))
2224 return true;
2225 /* we assume walker doesn't care about arg_names */
2226 if (walker(xexpr->args, context))
2227 return true;
2229 break;
2230 case T_NullTest:
2231 return walker(((NullTest *) node)->arg, context);
2232 case T_BooleanTest:
2233 return walker(((BooleanTest *) node)->arg, context);
2234 case T_JoinExpr:
2236 JoinExpr *join = (JoinExpr *) node;
2238 if (walker(join->larg, context))
2239 return true;
2240 if (walker(join->rarg, context))
2241 return true;
2242 if (walker(join->quals, context))
2243 return true;
2244 if (walker(join->alias, context))
2245 return true;
2246 /* using list is deemed uninteresting */
2248 break;
2249 case T_IntoClause:
2251 IntoClause *into = (IntoClause *) node;
2253 if (walker(into->rel, context))
2254 return true;
2255 /* colNames, options are deemed uninteresting */
2257 break;
2258 case T_List:
2259 foreach(temp, (List *) node)
2261 if (walker((Node *) lfirst(temp), context))
2262 return true;
2264 break;
2265 case T_SelectStmt:
2267 SelectStmt *stmt = (SelectStmt *) node;
2269 if (walker(stmt->distinctClause, context))
2270 return true;
2271 if (walker(stmt->intoClause, context))
2272 return true;
2273 if (walker(stmt->targetList, context))
2274 return true;
2275 if (walker(stmt->fromClause, context))
2276 return true;
2277 if (walker(stmt->whereClause, context))
2278 return true;
2279 if (walker(stmt->groupClause, context))
2280 return true;
2281 if (walker(stmt->havingClause, context))
2282 return true;
2283 if (walker(stmt->withClause, context))
2284 return true;
2285 if (walker(stmt->valuesLists, context))
2286 return true;
2287 if (walker(stmt->sortClause, context))
2288 return true;
2289 if (walker(stmt->limitOffset, context))
2290 return true;
2291 if (walker(stmt->limitCount, context))
2292 return true;
2293 if (walker(stmt->lockingClause, context))
2294 return true;
2295 if (walker(stmt->larg, context))
2296 return true;
2297 if (walker(stmt->rarg, context))
2298 return true;
2300 break;
2301 case T_A_Expr:
2303 A_Expr *expr = (A_Expr *) node;
2305 if (walker(expr->lexpr, context))
2306 return true;
2307 if (walker(expr->rexpr, context))
2308 return true;
2309 /* operator name is deemed uninteresting */
2311 break;
2312 case T_ColumnRef:
2313 /* we assume the fields contain nothing interesting */
2314 break;
2315 case T_FuncCall:
2317 FuncCall *fcall = (FuncCall *) node;
2319 if (walker(fcall->args, context))
2320 return true;
2321 /* function name is deemed uninteresting */
2323 break;
2324 case T_A_Indices:
2326 A_Indices *indices = (A_Indices *) node;
2328 if (walker(indices->lidx, context))
2329 return true;
2330 if (walker(indices->uidx, context))
2331 return true;
2333 break;
2334 case T_A_Indirection:
2336 A_Indirection *indir = (A_Indirection *) node;
2338 if (walker(indir->arg, context))
2339 return true;
2340 if (walker(indir->indirection, context))
2341 return true;
2343 break;
2344 case T_A_ArrayExpr:
2345 return walker(((A_ArrayExpr *) node)->elements, context);
2346 case T_ResTarget:
2348 ResTarget *rt = (ResTarget *) node;
2350 if (walker(rt->indirection, context))
2351 return true;
2352 if (walker(rt->val, context))
2353 return true;
2355 break;
2356 case T_TypeCast:
2358 TypeCast *tc = (TypeCast *) node;
2360 if (walker(tc->arg, context))
2361 return true;
2362 if (walker(tc->typename, context))
2363 return true;
2365 break;
2366 case T_SortBy:
2367 return walker(((SortBy *) node)->node, context);
2368 case T_RangeSubselect:
2370 RangeSubselect *rs = (RangeSubselect *) node;
2372 if (walker(rs->subquery, context))
2373 return true;
2374 if (walker(rs->alias, context))
2375 return true;
2377 break;
2378 case T_RangeFunction:
2380 RangeFunction *rf = (RangeFunction *) node;
2382 if (walker(rf->funccallnode, context))
2383 return true;
2384 if (walker(rf->alias, context))
2385 return true;
2387 break;
2388 case T_TypeName:
2390 TypeName *tn = (TypeName *) node;
2392 if (walker(tn->typmods, context))
2393 return true;
2394 if (walker(tn->arrayBounds, context))
2395 return true;
2396 /* type name itself is deemed uninteresting */
2398 break;
2399 case T_ColumnDef:
2401 ColumnDef *coldef = (ColumnDef *) node;
2403 if (walker(coldef->typename, context))
2404 return true;
2405 if (walker(coldef->raw_default, context))
2406 return true;
2407 /* for now, constraints are ignored */
2409 break;
2410 case T_LockingClause:
2411 return walker(((LockingClause *) node)->lockedRels, context);
2412 case T_XmlSerialize:
2414 XmlSerialize *xs = (XmlSerialize *) node;
2416 if (walker(xs->expr, context))
2417 return true;
2418 if (walker(xs->typename, context))
2419 return true;
2421 break;
2422 case T_WithClause:
2423 return walker(((WithClause *) node)->ctes, context);
2424 case T_CommonTableExpr:
2425 return walker(((CommonTableExpr *) node)->ctequery, context);
2426 default:
2427 elog(ERROR, "unrecognized node type: %d",
2428 (int) nodeTag(node));
2429 break;
2431 return false;