1 /*-------------------------------------------------------------------------
4 * Various general-purpose manipulations of Node trees
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * src/backend/nodes/nodeFuncs.c
13 *-------------------------------------------------------------------------
17 #include "catalog/pg_collation.h"
18 #include "catalog/pg_type.h"
19 #include "miscadmin.h"
20 #include "nodes/execnodes.h"
21 #include "nodes/nodeFuncs.h"
22 #include "nodes/pathnodes.h"
23 #include "utils/builtins.h"
24 #include "utils/lsyscache.h"
26 static bool expression_returns_set_walker(Node
*node
, void *context
);
27 static int leftmostLoc(int loc1
, int loc2
);
28 static bool fix_opfuncids_walker(Node
*node
, void *context
);
29 static bool planstate_walk_subplans(List
*plans
,
30 planstate_tree_walker_callback walker
,
32 static bool planstate_walk_members(PlanState
**planstates
, int nplans
,
33 planstate_tree_walker_callback walker
,
39 * returns the Oid of the type of the expression's result.
42 exprType(const Node
*expr
)
49 switch (nodeTag(expr
))
52 type
= ((const Var
*) expr
)->vartype
;
55 type
= ((const Const
*) expr
)->consttype
;
58 type
= ((const Param
*) expr
)->paramtype
;
61 type
= ((const Aggref
*) expr
)->aggtype
;
67 type
= ((const WindowFunc
*) expr
)->wintype
;
69 case T_MergeSupportFunc
:
70 type
= ((const MergeSupportFunc
*) expr
)->msftype
;
72 case T_SubscriptingRef
:
73 type
= ((const SubscriptingRef
*) expr
)->refrestype
;
76 type
= ((const FuncExpr
*) expr
)->funcresulttype
;
79 type
= exprType((Node
*) ((const NamedArgExpr
*) expr
)->arg
);
82 type
= ((const OpExpr
*) expr
)->opresulttype
;
85 type
= ((const DistinctExpr
*) expr
)->opresulttype
;
88 type
= ((const NullIfExpr
*) expr
)->opresulttype
;
90 case T_ScalarArrayOpExpr
:
98 const SubLink
*sublink
= (const SubLink
*) expr
;
100 if (sublink
->subLinkType
== EXPR_SUBLINK
||
101 sublink
->subLinkType
== ARRAY_SUBLINK
)
103 /* get the type of the subselect's first target column */
104 Query
*qtree
= (Query
*) sublink
->subselect
;
107 if (!qtree
|| !IsA(qtree
, Query
))
108 elog(ERROR
, "cannot get type for untransformed sublink");
109 tent
= linitial_node(TargetEntry
, qtree
->targetList
);
110 Assert(!tent
->resjunk
);
111 type
= exprType((Node
*) tent
->expr
);
112 if (sublink
->subLinkType
== ARRAY_SUBLINK
)
114 type
= get_promoted_array_type(type
);
115 if (!OidIsValid(type
))
117 (errcode(ERRCODE_UNDEFINED_OBJECT
),
118 errmsg("could not find array type for data type %s",
119 format_type_be(exprType((Node
*) tent
->expr
)))));
122 else if (sublink
->subLinkType
== MULTIEXPR_SUBLINK
)
124 /* MULTIEXPR is always considered to return RECORD */
129 /* for all other sublink types, result is boolean */
136 const SubPlan
*subplan
= (const SubPlan
*) expr
;
138 if (subplan
->subLinkType
== EXPR_SUBLINK
||
139 subplan
->subLinkType
== ARRAY_SUBLINK
)
141 /* get the type of the subselect's first target column */
142 type
= subplan
->firstColType
;
143 if (subplan
->subLinkType
== ARRAY_SUBLINK
)
145 type
= get_promoted_array_type(type
);
146 if (!OidIsValid(type
))
148 (errcode(ERRCODE_UNDEFINED_OBJECT
),
149 errmsg("could not find array type for data type %s",
150 format_type_be(subplan
->firstColType
))));
153 else if (subplan
->subLinkType
== MULTIEXPR_SUBLINK
)
155 /* MULTIEXPR is always considered to return RECORD */
160 /* for all other subplan types, result is boolean */
165 case T_AlternativeSubPlan
:
167 const AlternativeSubPlan
*asplan
= (const AlternativeSubPlan
*) expr
;
169 /* subplans should all return the same thing */
170 type
= exprType((Node
*) linitial(asplan
->subplans
));
174 type
= ((const FieldSelect
*) expr
)->resulttype
;
177 type
= ((const FieldStore
*) expr
)->resulttype
;
180 type
= ((const RelabelType
*) expr
)->resulttype
;
183 type
= ((const CoerceViaIO
*) expr
)->resulttype
;
185 case T_ArrayCoerceExpr
:
186 type
= ((const ArrayCoerceExpr
*) expr
)->resulttype
;
188 case T_ConvertRowtypeExpr
:
189 type
= ((const ConvertRowtypeExpr
*) expr
)->resulttype
;
192 type
= exprType((Node
*) ((const CollateExpr
*) expr
)->arg
);
195 type
= ((const CaseExpr
*) expr
)->casetype
;
198 type
= ((const CaseTestExpr
*) expr
)->typeId
;
201 type
= ((const ArrayExpr
*) expr
)->array_typeid
;
204 type
= ((const RowExpr
*) expr
)->row_typeid
;
206 case T_RowCompareExpr
:
210 type
= ((const CoalesceExpr
*) expr
)->coalescetype
;
213 type
= ((const MinMaxExpr
*) expr
)->minmaxtype
;
215 case T_SQLValueFunction
:
216 type
= ((const SQLValueFunction
*) expr
)->type
;
219 if (((const XmlExpr
*) expr
)->op
== IS_DOCUMENT
)
221 else if (((const XmlExpr
*) expr
)->op
== IS_XMLSERIALIZE
)
226 case T_JsonValueExpr
:
228 const JsonValueExpr
*jve
= (const JsonValueExpr
*) expr
;
230 type
= exprType((Node
*) jve
->formatted_expr
);
233 case T_JsonConstructorExpr
:
234 type
= ((const JsonConstructorExpr
*) expr
)->returning
->typid
;
236 case T_JsonIsPredicate
:
241 const JsonExpr
*jexpr
= (const JsonExpr
*) expr
;
243 type
= jexpr
->returning
->typid
;
248 const JsonBehavior
*behavior
= (const JsonBehavior
*) expr
;
250 type
= exprType(behavior
->expr
);
259 case T_CoerceToDomain
:
260 type
= ((const CoerceToDomain
*) expr
)->resulttype
;
262 case T_CoerceToDomainValue
:
263 type
= ((const CoerceToDomainValue
*) expr
)->typeId
;
266 type
= ((const SetToDefault
*) expr
)->typeId
;
268 case T_CurrentOfExpr
:
271 case T_NextValueExpr
:
272 type
= ((const NextValueExpr
*) expr
)->typeId
;
274 case T_InferenceElem
:
276 const InferenceElem
*n
= (const InferenceElem
*) expr
;
278 type
= exprType((Node
*) n
->expr
);
281 case T_PlaceHolderVar
:
282 type
= exprType((Node
*) ((const PlaceHolderVar
*) expr
)->phexpr
);
285 elog(ERROR
, "unrecognized node type: %d", (int) nodeTag(expr
));
286 type
= InvalidOid
; /* keep compiler quiet */
294 * returns the type-specific modifier of the expression's result type,
295 * if it can be determined. In many cases, it can't and we return -1.
298 exprTypmod(const Node
*expr
)
303 switch (nodeTag(expr
))
306 return ((const Var
*) expr
)->vartypmod
;
308 return ((const Const
*) expr
)->consttypmod
;
310 return ((const Param
*) expr
)->paramtypmod
;
311 case T_SubscriptingRef
:
312 return ((const SubscriptingRef
*) expr
)->reftypmod
;
317 /* Be smart about length-coercion functions... */
318 if (exprIsLengthCoercion(expr
, &coercedTypmod
))
319 return coercedTypmod
;
323 return exprTypmod((Node
*) ((const NamedArgExpr
*) expr
)->arg
);
327 * Result is either first argument or NULL, so we can report
328 * first argument's typmod if known.
330 const NullIfExpr
*nexpr
= (const NullIfExpr
*) expr
;
332 return exprTypmod((Node
*) linitial(nexpr
->args
));
337 const SubLink
*sublink
= (const SubLink
*) expr
;
339 if (sublink
->subLinkType
== EXPR_SUBLINK
||
340 sublink
->subLinkType
== ARRAY_SUBLINK
)
342 /* get the typmod of the subselect's first target column */
343 Query
*qtree
= (Query
*) sublink
->subselect
;
346 if (!qtree
|| !IsA(qtree
, Query
))
347 elog(ERROR
, "cannot get type for untransformed sublink");
348 tent
= linitial_node(TargetEntry
, qtree
->targetList
);
349 Assert(!tent
->resjunk
);
350 return exprTypmod((Node
*) tent
->expr
);
351 /* note we don't need to care if it's an array */
353 /* otherwise, result is RECORD or BOOLEAN, typmod is -1 */
358 const SubPlan
*subplan
= (const SubPlan
*) expr
;
360 if (subplan
->subLinkType
== EXPR_SUBLINK
||
361 subplan
->subLinkType
== ARRAY_SUBLINK
)
363 /* get the typmod of the subselect's first target column */
364 /* note we don't need to care if it's an array */
365 return subplan
->firstColTypmod
;
367 /* otherwise, result is RECORD or BOOLEAN, typmod is -1 */
370 case T_AlternativeSubPlan
:
372 const AlternativeSubPlan
*asplan
= (const AlternativeSubPlan
*) expr
;
374 /* subplans should all return the same thing */
375 return exprTypmod((Node
*) linitial(asplan
->subplans
));
379 return ((const FieldSelect
*) expr
)->resulttypmod
;
381 return ((const RelabelType
*) expr
)->resulttypmod
;
382 case T_ArrayCoerceExpr
:
383 return ((const ArrayCoerceExpr
*) expr
)->resulttypmod
;
385 return exprTypmod((Node
*) ((const CollateExpr
*) expr
)->arg
);
389 * If all the alternatives agree on type/typmod, return that
390 * typmod, else use -1
392 const CaseExpr
*cexpr
= (const CaseExpr
*) expr
;
393 Oid casetype
= cexpr
->casetype
;
397 if (!cexpr
->defresult
)
399 if (exprType((Node
*) cexpr
->defresult
) != casetype
)
401 typmod
= exprTypmod((Node
*) cexpr
->defresult
);
403 return -1; /* no point in trying harder */
404 foreach(arg
, cexpr
->args
)
406 CaseWhen
*w
= lfirst_node(CaseWhen
, arg
);
408 if (exprType((Node
*) w
->result
) != casetype
)
410 if (exprTypmod((Node
*) w
->result
) != typmod
)
417 return ((const CaseTestExpr
*) expr
)->typeMod
;
421 * If all the elements agree on type/typmod, return that
422 * typmod, else use -1
424 const ArrayExpr
*arrayexpr
= (const ArrayExpr
*) expr
;
429 if (arrayexpr
->elements
== NIL
)
431 typmod
= exprTypmod((Node
*) linitial(arrayexpr
->elements
));
433 return -1; /* no point in trying harder */
434 if (arrayexpr
->multidims
)
435 commontype
= arrayexpr
->array_typeid
;
437 commontype
= arrayexpr
->element_typeid
;
438 foreach(elem
, arrayexpr
->elements
)
440 Node
*e
= (Node
*) lfirst(elem
);
442 if (exprType(e
) != commontype
)
444 if (exprTypmod(e
) != typmod
)
453 * If all the alternatives agree on type/typmod, return that
454 * typmod, else use -1
456 const CoalesceExpr
*cexpr
= (const CoalesceExpr
*) expr
;
457 Oid coalescetype
= cexpr
->coalescetype
;
461 if (exprType((Node
*) linitial(cexpr
->args
)) != coalescetype
)
463 typmod
= exprTypmod((Node
*) linitial(cexpr
->args
));
465 return -1; /* no point in trying harder */
466 for_each_from(arg
, cexpr
->args
, 1)
468 Node
*e
= (Node
*) lfirst(arg
);
470 if (exprType(e
) != coalescetype
)
472 if (exprTypmod(e
) != typmod
)
481 * If all the alternatives agree on type/typmod, return that
482 * typmod, else use -1
484 const MinMaxExpr
*mexpr
= (const MinMaxExpr
*) expr
;
485 Oid minmaxtype
= mexpr
->minmaxtype
;
489 if (exprType((Node
*) linitial(mexpr
->args
)) != minmaxtype
)
491 typmod
= exprTypmod((Node
*) linitial(mexpr
->args
));
493 return -1; /* no point in trying harder */
494 for_each_from(arg
, mexpr
->args
, 1)
496 Node
*e
= (Node
*) lfirst(arg
);
498 if (exprType(e
) != minmaxtype
)
500 if (exprTypmod(e
) != typmod
)
506 case T_SQLValueFunction
:
507 return ((const SQLValueFunction
*) expr
)->typmod
;
508 case T_JsonValueExpr
:
509 return exprTypmod((Node
*) ((const JsonValueExpr
*) expr
)->formatted_expr
);
510 case T_JsonConstructorExpr
:
511 return ((const JsonConstructorExpr
*) expr
)->returning
->typmod
;
514 const JsonExpr
*jexpr
= (const JsonExpr
*) expr
;
516 return jexpr
->returning
->typmod
;
521 const JsonBehavior
*behavior
= (const JsonBehavior
*) expr
;
523 return exprTypmod(behavior
->expr
);
526 case T_CoerceToDomain
:
527 return ((const CoerceToDomain
*) expr
)->resulttypmod
;
528 case T_CoerceToDomainValue
:
529 return ((const CoerceToDomainValue
*) expr
)->typeMod
;
531 return ((const SetToDefault
*) expr
)->typeMod
;
532 case T_PlaceHolderVar
:
533 return exprTypmod((Node
*) ((const PlaceHolderVar
*) expr
)->phexpr
);
541 * exprIsLengthCoercion
542 * Detect whether an expression tree is an application of a datatype's
543 * typmod-coercion function. Optionally extract the result's typmod.
545 * If coercedTypmod is not NULL, the typmod is stored there if the expression
546 * is a length-coercion function, else -1 is stored there.
548 * Note that a combined type-and-length coercion will be treated as a
549 * length coercion by this routine.
552 exprIsLengthCoercion(const Node
*expr
, int32
*coercedTypmod
)
554 if (coercedTypmod
!= NULL
)
555 *coercedTypmod
= -1; /* default result on failure */
558 * Scalar-type length coercions are FuncExprs, array-type length coercions
559 * are ArrayCoerceExprs
561 if (expr
&& IsA(expr
, FuncExpr
))
563 const FuncExpr
*func
= (const FuncExpr
*) expr
;
568 * If it didn't come from a coercion context, reject.
570 if (func
->funcformat
!= COERCE_EXPLICIT_CAST
&&
571 func
->funcformat
!= COERCE_IMPLICIT_CAST
)
575 * If it's not a two-argument or three-argument function with the
576 * second argument being an int4 constant, it can't have been created
577 * from a length coercion (it must be a type coercion, instead).
579 nargs
= list_length(func
->args
);
580 if (nargs
< 2 || nargs
> 3)
583 second_arg
= (Const
*) lsecond(func
->args
);
584 if (!IsA(second_arg
, Const
) ||
585 second_arg
->consttype
!= INT4OID
||
586 second_arg
->constisnull
)
590 * OK, it is indeed a length-coercion function.
592 if (coercedTypmod
!= NULL
)
593 *coercedTypmod
= DatumGetInt32(second_arg
->constvalue
);
598 if (expr
&& IsA(expr
, ArrayCoerceExpr
))
600 const ArrayCoerceExpr
*acoerce
= (const ArrayCoerceExpr
*) expr
;
602 /* It's not a length coercion unless there's a nondefault typmod */
603 if (acoerce
->resulttypmod
< 0)
607 * OK, it is indeed a length-coercion expression.
609 if (coercedTypmod
!= NULL
)
610 *coercedTypmod
= acoerce
->resulttypmod
;
620 * Add a RelabelType node if needed to make the expression expose
621 * the specified type, typmod, and collation.
623 * This is primarily intended to be used during planning. Therefore, it must
624 * maintain the post-eval_const_expressions invariants that there are not
625 * adjacent RelabelTypes, and that the tree is fully const-folded (hence,
626 * we mustn't return a RelabelType atop a Const). If we do find a Const,
627 * we'll modify it in-place if "overwrite_ok" is true; that should only be
628 * passed as true if caller knows the Const is newly generated.
631 applyRelabelType(Node
*arg
, Oid rtype
, int32 rtypmod
, Oid rcollid
,
632 CoercionForm rformat
, int rlocation
, bool overwrite_ok
)
635 * If we find stacked RelabelTypes (eg, from foo::int::oid) we can discard
636 * all but the top one, and must do so to ensure that semantically
637 * equivalent expressions are equal().
639 while (arg
&& IsA(arg
, RelabelType
))
640 arg
= (Node
*) ((RelabelType
*) arg
)->arg
;
642 if (arg
&& IsA(arg
, Const
))
644 /* Modify the Const directly to preserve const-flatness. */
645 Const
*con
= (Const
*) arg
;
648 con
= copyObject(con
);
649 con
->consttype
= rtype
;
650 con
->consttypmod
= rtypmod
;
651 con
->constcollid
= rcollid
;
652 /* We keep the Const's original location. */
655 else if (exprType(arg
) == rtype
&&
656 exprTypmod(arg
) == rtypmod
&&
657 exprCollation(arg
) == rcollid
)
659 /* Sometimes we find a nest of relabels that net out to nothing. */
664 /* Nope, gotta have a RelabelType. */
665 RelabelType
*newrelabel
= makeNode(RelabelType
);
667 newrelabel
->arg
= (Expr
*) arg
;
668 newrelabel
->resulttype
= rtype
;
669 newrelabel
->resulttypmod
= rtypmod
;
670 newrelabel
->resultcollid
= rcollid
;
671 newrelabel
->relabelformat
= rformat
;
672 newrelabel
->location
= rlocation
;
673 return (Node
*) newrelabel
;
679 * Add a RelabelType node that changes just the typmod of the expression.
681 * Convenience function for a common usage of applyRelabelType.
684 relabel_to_typmod(Node
*expr
, int32 typmod
)
686 return applyRelabelType(expr
, exprType(expr
), typmod
, exprCollation(expr
),
687 COERCE_EXPLICIT_CAST
, -1, false);
691 * strip_implicit_coercions: remove implicit coercions at top level of tree
693 * This doesn't modify or copy the input expression tree, just return a
694 * pointer to a suitable place within it.
696 * Note: there isn't any useful thing we can do with a RowExpr here, so
697 * just return it unchanged, even if it's marked as an implicit coercion.
700 strip_implicit_coercions(Node
*node
)
704 if (IsA(node
, FuncExpr
))
706 FuncExpr
*f
= (FuncExpr
*) node
;
708 if (f
->funcformat
== COERCE_IMPLICIT_CAST
)
709 return strip_implicit_coercions(linitial(f
->args
));
711 else if (IsA(node
, RelabelType
))
713 RelabelType
*r
= (RelabelType
*) node
;
715 if (r
->relabelformat
== COERCE_IMPLICIT_CAST
)
716 return strip_implicit_coercions((Node
*) r
->arg
);
718 else if (IsA(node
, CoerceViaIO
))
720 CoerceViaIO
*c
= (CoerceViaIO
*) node
;
722 if (c
->coerceformat
== COERCE_IMPLICIT_CAST
)
723 return strip_implicit_coercions((Node
*) c
->arg
);
725 else if (IsA(node
, ArrayCoerceExpr
))
727 ArrayCoerceExpr
*c
= (ArrayCoerceExpr
*) node
;
729 if (c
->coerceformat
== COERCE_IMPLICIT_CAST
)
730 return strip_implicit_coercions((Node
*) c
->arg
);
732 else if (IsA(node
, ConvertRowtypeExpr
))
734 ConvertRowtypeExpr
*c
= (ConvertRowtypeExpr
*) node
;
736 if (c
->convertformat
== COERCE_IMPLICIT_CAST
)
737 return strip_implicit_coercions((Node
*) c
->arg
);
739 else if (IsA(node
, CoerceToDomain
))
741 CoerceToDomain
*c
= (CoerceToDomain
*) node
;
743 if (c
->coercionformat
== COERCE_IMPLICIT_CAST
)
744 return strip_implicit_coercions((Node
*) c
->arg
);
750 * expression_returns_set
751 * Test whether an expression returns a set result.
753 * Because we use expression_tree_walker(), this can also be applied to
754 * whole targetlists; it'll produce true if any one of the tlist items
758 expression_returns_set(Node
*clause
)
760 return expression_returns_set_walker(clause
, NULL
);
764 expression_returns_set_walker(Node
*node
, void *context
)
768 if (IsA(node
, FuncExpr
))
770 FuncExpr
*expr
= (FuncExpr
*) node
;
772 if (expr
->funcretset
)
774 /* else fall through to check args */
776 if (IsA(node
, OpExpr
))
778 OpExpr
*expr
= (OpExpr
*) node
;
782 /* else fall through to check args */
786 * If you add any more cases that return sets, also fix
787 * expression_returns_set_rows() in clauses.c and IS_SRF_CALL() in
791 /* Avoid recursion for some cases that parser checks not to return a set */
792 if (IsA(node
, Aggref
))
794 if (IsA(node
, GroupingFunc
))
796 if (IsA(node
, WindowFunc
))
799 return expression_tree_walker(node
, expression_returns_set_walker
,
806 * returns the Oid of the collation of the expression's result.
808 * Note: expression nodes that can invoke functions generally have an
809 * "inputcollid" field, which is what the function should use as collation.
810 * That is the resolved common collation of the node's inputs. It is often
811 * but not always the same as the result collation; in particular, if the
812 * function produces a non-collatable result type from collatable inputs
813 * or vice versa, the two are different.
816 exprCollation(const Node
*expr
)
823 switch (nodeTag(expr
))
826 coll
= ((const Var
*) expr
)->varcollid
;
829 coll
= ((const Const
*) expr
)->constcollid
;
832 coll
= ((const Param
*) expr
)->paramcollid
;
835 coll
= ((const Aggref
*) expr
)->aggcollid
;
841 coll
= ((const WindowFunc
*) expr
)->wincollid
;
843 case T_MergeSupportFunc
:
844 coll
= ((const MergeSupportFunc
*) expr
)->msfcollid
;
846 case T_SubscriptingRef
:
847 coll
= ((const SubscriptingRef
*) expr
)->refcollid
;
850 coll
= ((const FuncExpr
*) expr
)->funccollid
;
853 coll
= exprCollation((Node
*) ((const NamedArgExpr
*) expr
)->arg
);
856 coll
= ((const OpExpr
*) expr
)->opcollid
;
859 coll
= ((const DistinctExpr
*) expr
)->opcollid
;
862 coll
= ((const NullIfExpr
*) expr
)->opcollid
;
864 case T_ScalarArrayOpExpr
:
865 /* ScalarArrayOpExpr's result is boolean ... */
866 coll
= InvalidOid
; /* ... so it has no collation */
869 /* BoolExpr's result is boolean ... */
870 coll
= InvalidOid
; /* ... so it has no collation */
874 const SubLink
*sublink
= (const SubLink
*) expr
;
876 if (sublink
->subLinkType
== EXPR_SUBLINK
||
877 sublink
->subLinkType
== ARRAY_SUBLINK
)
879 /* get the collation of subselect's first target column */
880 Query
*qtree
= (Query
*) sublink
->subselect
;
883 if (!qtree
|| !IsA(qtree
, Query
))
884 elog(ERROR
, "cannot get collation for untransformed sublink");
885 tent
= linitial_node(TargetEntry
, qtree
->targetList
);
886 Assert(!tent
->resjunk
);
887 coll
= exprCollation((Node
*) tent
->expr
);
888 /* collation doesn't change if it's converted to array */
892 /* otherwise, SubLink's result is RECORD or BOOLEAN */
893 coll
= InvalidOid
; /* ... so it has no collation */
899 const SubPlan
*subplan
= (const SubPlan
*) expr
;
901 if (subplan
->subLinkType
== EXPR_SUBLINK
||
902 subplan
->subLinkType
== ARRAY_SUBLINK
)
904 /* get the collation of subselect's first target column */
905 coll
= subplan
->firstColCollation
;
906 /* collation doesn't change if it's converted to array */
910 /* otherwise, SubPlan's result is RECORD or BOOLEAN */
911 coll
= InvalidOid
; /* ... so it has no collation */
915 case T_AlternativeSubPlan
:
917 const AlternativeSubPlan
*asplan
= (const AlternativeSubPlan
*) expr
;
919 /* subplans should all return the same thing */
920 coll
= exprCollation((Node
*) linitial(asplan
->subplans
));
924 coll
= ((const FieldSelect
*) expr
)->resultcollid
;
927 /* FieldStore's result is composite ... */
928 coll
= InvalidOid
; /* ... so it has no collation */
931 coll
= ((const RelabelType
*) expr
)->resultcollid
;
934 coll
= ((const CoerceViaIO
*) expr
)->resultcollid
;
936 case T_ArrayCoerceExpr
:
937 coll
= ((const ArrayCoerceExpr
*) expr
)->resultcollid
;
939 case T_ConvertRowtypeExpr
:
940 /* ConvertRowtypeExpr's result is composite ... */
941 coll
= InvalidOid
; /* ... so it has no collation */
944 coll
= ((const CollateExpr
*) expr
)->collOid
;
947 coll
= ((const CaseExpr
*) expr
)->casecollid
;
950 coll
= ((const CaseTestExpr
*) expr
)->collation
;
953 coll
= ((const ArrayExpr
*) expr
)->array_collid
;
956 /* RowExpr's result is composite ... */
957 coll
= InvalidOid
; /* ... so it has no collation */
959 case T_RowCompareExpr
:
960 /* RowCompareExpr's result is boolean ... */
961 coll
= InvalidOid
; /* ... so it has no collation */
964 coll
= ((const CoalesceExpr
*) expr
)->coalescecollid
;
967 coll
= ((const MinMaxExpr
*) expr
)->minmaxcollid
;
969 case T_SQLValueFunction
:
970 /* Returns either NAME or a non-collatable type */
971 if (((const SQLValueFunction
*) expr
)->type
== NAMEOID
)
972 coll
= C_COLLATION_OID
;
979 * XMLSERIALIZE returns text from non-collatable inputs, so its
980 * collation is always default. The other cases return boolean or
981 * XML, which are non-collatable.
983 if (((const XmlExpr
*) expr
)->op
== IS_XMLSERIALIZE
)
984 coll
= DEFAULT_COLLATION_OID
;
988 case T_JsonValueExpr
:
989 coll
= exprCollation((Node
*) ((const JsonValueExpr
*) expr
)->formatted_expr
);
991 case T_JsonConstructorExpr
:
993 const JsonConstructorExpr
*ctor
= (const JsonConstructorExpr
*) expr
;
996 coll
= exprCollation((Node
*) ctor
->coercion
);
1001 case T_JsonIsPredicate
:
1002 /* IS JSON's result is boolean ... */
1003 coll
= InvalidOid
; /* ... so it has no collation */
1007 const JsonExpr
*jsexpr
= (JsonExpr
*) expr
;
1009 coll
= jsexpr
->collation
;
1012 case T_JsonBehavior
:
1014 const JsonBehavior
*behavior
= (JsonBehavior
*) expr
;
1017 coll
= exprCollation(behavior
->expr
);
1023 /* NullTest's result is boolean ... */
1024 coll
= InvalidOid
; /* ... so it has no collation */
1027 /* BooleanTest's result is boolean ... */
1028 coll
= InvalidOid
; /* ... so it has no collation */
1030 case T_CoerceToDomain
:
1031 coll
= ((const CoerceToDomain
*) expr
)->resultcollid
;
1033 case T_CoerceToDomainValue
:
1034 coll
= ((const CoerceToDomainValue
*) expr
)->collation
;
1036 case T_SetToDefault
:
1037 coll
= ((const SetToDefault
*) expr
)->collation
;
1039 case T_CurrentOfExpr
:
1040 /* CurrentOfExpr's result is boolean ... */
1041 coll
= InvalidOid
; /* ... so it has no collation */
1043 case T_NextValueExpr
:
1044 /* NextValueExpr's result is an integer type ... */
1045 coll
= InvalidOid
; /* ... so it has no collation */
1047 case T_InferenceElem
:
1048 coll
= exprCollation((Node
*) ((const InferenceElem
*) expr
)->expr
);
1050 case T_PlaceHolderVar
:
1051 coll
= exprCollation((Node
*) ((const PlaceHolderVar
*) expr
)->phexpr
);
1054 elog(ERROR
, "unrecognized node type: %d", (int) nodeTag(expr
));
1055 coll
= InvalidOid
; /* keep compiler quiet */
1062 * exprInputCollation -
1063 * returns the Oid of the collation a function should use, if available.
1065 * Result is InvalidOid if the node type doesn't store this information.
1068 exprInputCollation(const Node
*expr
)
1075 switch (nodeTag(expr
))
1078 coll
= ((const Aggref
*) expr
)->inputcollid
;
1081 coll
= ((const WindowFunc
*) expr
)->inputcollid
;
1084 coll
= ((const FuncExpr
*) expr
)->inputcollid
;
1087 coll
= ((const OpExpr
*) expr
)->inputcollid
;
1089 case T_DistinctExpr
:
1090 coll
= ((const DistinctExpr
*) expr
)->inputcollid
;
1093 coll
= ((const NullIfExpr
*) expr
)->inputcollid
;
1095 case T_ScalarArrayOpExpr
:
1096 coll
= ((const ScalarArrayOpExpr
*) expr
)->inputcollid
;
1099 coll
= ((const MinMaxExpr
*) expr
)->inputcollid
;
1109 * exprSetCollation -
1110 * Assign collation information to an expression tree node.
1112 * Note: since this is only used during parse analysis, we don't need to
1113 * worry about subplans or PlaceHolderVars.
1116 exprSetCollation(Node
*expr
, Oid collation
)
1118 switch (nodeTag(expr
))
1121 ((Var
*) expr
)->varcollid
= collation
;
1124 ((Const
*) expr
)->constcollid
= collation
;
1127 ((Param
*) expr
)->paramcollid
= collation
;
1130 ((Aggref
*) expr
)->aggcollid
= collation
;
1132 case T_GroupingFunc
:
1133 Assert(!OidIsValid(collation
));
1136 ((WindowFunc
*) expr
)->wincollid
= collation
;
1138 case T_MergeSupportFunc
:
1139 ((MergeSupportFunc
*) expr
)->msfcollid
= collation
;
1141 case T_SubscriptingRef
:
1142 ((SubscriptingRef
*) expr
)->refcollid
= collation
;
1145 ((FuncExpr
*) expr
)->funccollid
= collation
;
1147 case T_NamedArgExpr
:
1148 Assert(collation
== exprCollation((Node
*) ((NamedArgExpr
*) expr
)->arg
));
1151 ((OpExpr
*) expr
)->opcollid
= collation
;
1153 case T_DistinctExpr
:
1154 ((DistinctExpr
*) expr
)->opcollid
= collation
;
1157 ((NullIfExpr
*) expr
)->opcollid
= collation
;
1159 case T_ScalarArrayOpExpr
:
1160 /* ScalarArrayOpExpr's result is boolean ... */
1161 Assert(!OidIsValid(collation
)); /* ... so never set a collation */
1164 /* BoolExpr's result is boolean ... */
1165 Assert(!OidIsValid(collation
)); /* ... so never set a collation */
1168 #ifdef USE_ASSERT_CHECKING
1170 SubLink
*sublink
= (SubLink
*) expr
;
1172 if (sublink
->subLinkType
== EXPR_SUBLINK
||
1173 sublink
->subLinkType
== ARRAY_SUBLINK
)
1175 /* get the collation of subselect's first target column */
1176 Query
*qtree
= (Query
*) sublink
->subselect
;
1179 if (!qtree
|| !IsA(qtree
, Query
))
1180 elog(ERROR
, "cannot set collation for untransformed sublink");
1181 tent
= linitial_node(TargetEntry
, qtree
->targetList
);
1182 Assert(!tent
->resjunk
);
1183 Assert(collation
== exprCollation((Node
*) tent
->expr
));
1187 /* otherwise, result is RECORD or BOOLEAN */
1188 Assert(!OidIsValid(collation
));
1191 #endif /* USE_ASSERT_CHECKING */
1194 ((FieldSelect
*) expr
)->resultcollid
= collation
;
1197 /* FieldStore's result is composite ... */
1198 Assert(!OidIsValid(collation
)); /* ... so never set a collation */
1201 ((RelabelType
*) expr
)->resultcollid
= collation
;
1204 ((CoerceViaIO
*) expr
)->resultcollid
= collation
;
1206 case T_ArrayCoerceExpr
:
1207 ((ArrayCoerceExpr
*) expr
)->resultcollid
= collation
;
1209 case T_ConvertRowtypeExpr
:
1210 /* ConvertRowtypeExpr's result is composite ... */
1211 Assert(!OidIsValid(collation
)); /* ... so never set a collation */
1214 ((CaseExpr
*) expr
)->casecollid
= collation
;
1217 ((ArrayExpr
*) expr
)->array_collid
= collation
;
1220 /* RowExpr's result is composite ... */
1221 Assert(!OidIsValid(collation
)); /* ... so never set a collation */
1223 case T_RowCompareExpr
:
1224 /* RowCompareExpr's result is boolean ... */
1225 Assert(!OidIsValid(collation
)); /* ... so never set a collation */
1227 case T_CoalesceExpr
:
1228 ((CoalesceExpr
*) expr
)->coalescecollid
= collation
;
1231 ((MinMaxExpr
*) expr
)->minmaxcollid
= collation
;
1233 case T_SQLValueFunction
:
1234 Assert((((SQLValueFunction
*) expr
)->type
== NAMEOID
) ?
1235 (collation
== C_COLLATION_OID
) :
1236 (collation
== InvalidOid
));
1239 Assert((((XmlExpr
*) expr
)->op
== IS_XMLSERIALIZE
) ?
1240 (collation
== DEFAULT_COLLATION_OID
) :
1241 (collation
== InvalidOid
));
1243 case T_JsonValueExpr
:
1244 exprSetCollation((Node
*) ((JsonValueExpr
*) expr
)->formatted_expr
,
1247 case T_JsonConstructorExpr
:
1249 JsonConstructorExpr
*ctor
= (JsonConstructorExpr
*) expr
;
1252 exprSetCollation((Node
*) ctor
->coercion
, collation
);
1254 Assert(!OidIsValid(collation
)); /* result is always a
1258 case T_JsonIsPredicate
:
1259 Assert(!OidIsValid(collation
)); /* result is always boolean */
1263 JsonExpr
*jexpr
= (JsonExpr
*) expr
;
1265 jexpr
->collation
= collation
;
1268 case T_JsonBehavior
:
1270 JsonBehavior
*behavior
= (JsonBehavior
*) expr
;
1273 exprSetCollation(behavior
->expr
, collation
);
1277 /* NullTest's result is boolean ... */
1278 Assert(!OidIsValid(collation
)); /* ... so never set a collation */
1281 /* BooleanTest's result is boolean ... */
1282 Assert(!OidIsValid(collation
)); /* ... so never set a collation */
1284 case T_CoerceToDomain
:
1285 ((CoerceToDomain
*) expr
)->resultcollid
= collation
;
1287 case T_CoerceToDomainValue
:
1288 ((CoerceToDomainValue
*) expr
)->collation
= collation
;
1290 case T_SetToDefault
:
1291 ((SetToDefault
*) expr
)->collation
= collation
;
1293 case T_CurrentOfExpr
:
1294 /* CurrentOfExpr's result is boolean ... */
1295 Assert(!OidIsValid(collation
)); /* ... so never set a collation */
1297 case T_NextValueExpr
:
1298 /* NextValueExpr's result is an integer type ... */
1299 Assert(!OidIsValid(collation
)); /* ... so never set a collation */
1302 elog(ERROR
, "unrecognized node type: %d", (int) nodeTag(expr
));
1308 * exprSetInputCollation -
1309 * Assign input-collation information to an expression tree node.
1311 * This is a no-op for node types that don't store their input collation.
1312 * Note we omit RowCompareExpr, which needs special treatment since it
1313 * contains multiple input collation OIDs.
1316 exprSetInputCollation(Node
*expr
, Oid inputcollation
)
1318 switch (nodeTag(expr
))
1321 ((Aggref
*) expr
)->inputcollid
= inputcollation
;
1324 ((WindowFunc
*) expr
)->inputcollid
= inputcollation
;
1327 ((FuncExpr
*) expr
)->inputcollid
= inputcollation
;
1330 ((OpExpr
*) expr
)->inputcollid
= inputcollation
;
1332 case T_DistinctExpr
:
1333 ((DistinctExpr
*) expr
)->inputcollid
= inputcollation
;
1336 ((NullIfExpr
*) expr
)->inputcollid
= inputcollation
;
1338 case T_ScalarArrayOpExpr
:
1339 ((ScalarArrayOpExpr
*) expr
)->inputcollid
= inputcollation
;
1342 ((MinMaxExpr
*) expr
)->inputcollid
= inputcollation
;
1352 * returns the parse location of an expression tree, for error reports
1354 * -1 is returned if the location can't be determined.
1356 * For expressions larger than a single token, the intent here is to
1357 * return the location of the expression's leftmost token, not necessarily
1358 * the topmost Node's location field. For example, an OpExpr's location
1359 * field will point at the operator name, but if it is not a prefix operator
1360 * then we should return the location of the left-hand operand instead.
1361 * The reason is that we want to reference the entire expression not just
1362 * that operator, and pointing to its start seems to be the most natural way.
1364 * The location is not perfect --- for example, since the grammar doesn't
1365 * explicitly represent parentheses in the parsetree, given something that
1366 * had been written "(a + b) * c" we are going to point at "a" not "(".
1367 * But it should be plenty good enough for error reporting purposes.
1369 * You might think that this code is overly general, for instance why check
1370 * the operands of a FuncExpr node, when the function name can be expected
1371 * to be to the left of them? There are a couple of reasons. The grammar
1372 * sometimes builds expressions that aren't quite what the user wrote;
1373 * for instance x IS NOT BETWEEN ... becomes a NOT-expression whose keyword
1374 * pointer is to the right of its leftmost argument. Also, nodes that were
1375 * inserted implicitly by parse analysis (such as FuncExprs for implicit
1376 * coercions) will have location -1, and so we can have odd combinations of
1377 * known and unknown locations in a tree.
1380 exprLocation(const Node
*expr
)
1386 switch (nodeTag(expr
))
1389 loc
= ((const RangeVar
*) expr
)->location
;
1392 loc
= ((const TableFunc
*) expr
)->location
;
1395 loc
= ((const Var
*) expr
)->location
;
1398 loc
= ((const Const
*) expr
)->location
;
1401 loc
= ((const Param
*) expr
)->location
;
1404 /* function name should always be the first thing */
1405 loc
= ((const Aggref
*) expr
)->location
;
1407 case T_GroupingFunc
:
1408 loc
= ((const GroupingFunc
*) expr
)->location
;
1411 /* function name should always be the first thing */
1412 loc
= ((const WindowFunc
*) expr
)->location
;
1414 case T_MergeSupportFunc
:
1415 loc
= ((const MergeSupportFunc
*) expr
)->location
;
1417 case T_SubscriptingRef
:
1418 /* just use container argument's location */
1419 loc
= exprLocation((Node
*) ((const SubscriptingRef
*) expr
)->refexpr
);
1423 const FuncExpr
*fexpr
= (const FuncExpr
*) expr
;
1425 /* consider both function name and leftmost arg */
1426 loc
= leftmostLoc(fexpr
->location
,
1427 exprLocation((Node
*) fexpr
->args
));
1430 case T_NamedArgExpr
:
1432 const NamedArgExpr
*na
= (const NamedArgExpr
*) expr
;
1434 /* consider both argument name and value */
1435 loc
= leftmostLoc(na
->location
,
1436 exprLocation((Node
*) na
->arg
));
1440 case T_DistinctExpr
: /* struct-equivalent to OpExpr */
1441 case T_NullIfExpr
: /* struct-equivalent to OpExpr */
1443 const OpExpr
*opexpr
= (const OpExpr
*) expr
;
1445 /* consider both operator name and leftmost arg */
1446 loc
= leftmostLoc(opexpr
->location
,
1447 exprLocation((Node
*) opexpr
->args
));
1450 case T_ScalarArrayOpExpr
:
1452 const ScalarArrayOpExpr
*saopexpr
= (const ScalarArrayOpExpr
*) expr
;
1454 /* consider both operator name and leftmost arg */
1455 loc
= leftmostLoc(saopexpr
->location
,
1456 exprLocation((Node
*) saopexpr
->args
));
1461 const BoolExpr
*bexpr
= (const BoolExpr
*) expr
;
1464 * Same as above, to handle either NOT or AND/OR. We can't
1465 * special-case NOT because of the way that it's used for
1466 * things like IS NOT BETWEEN.
1468 loc
= leftmostLoc(bexpr
->location
,
1469 exprLocation((Node
*) bexpr
->args
));
1474 const SubLink
*sublink
= (const SubLink
*) expr
;
1476 /* check the testexpr, if any, and the operator/keyword */
1477 loc
= leftmostLoc(exprLocation(sublink
->testexpr
),
1482 /* just use argument's location */
1483 loc
= exprLocation((Node
*) ((const FieldSelect
*) expr
)->arg
);
1486 /* just use argument's location */
1487 loc
= exprLocation((Node
*) ((const FieldStore
*) expr
)->arg
);
1491 const RelabelType
*rexpr
= (const RelabelType
*) expr
;
1494 loc
= leftmostLoc(rexpr
->location
,
1495 exprLocation((Node
*) rexpr
->arg
));
1500 const CoerceViaIO
*cexpr
= (const CoerceViaIO
*) expr
;
1503 loc
= leftmostLoc(cexpr
->location
,
1504 exprLocation((Node
*) cexpr
->arg
));
1507 case T_ArrayCoerceExpr
:
1509 const ArrayCoerceExpr
*cexpr
= (const ArrayCoerceExpr
*) expr
;
1512 loc
= leftmostLoc(cexpr
->location
,
1513 exprLocation((Node
*) cexpr
->arg
));
1516 case T_ConvertRowtypeExpr
:
1518 const ConvertRowtypeExpr
*cexpr
= (const ConvertRowtypeExpr
*) expr
;
1521 loc
= leftmostLoc(cexpr
->location
,
1522 exprLocation((Node
*) cexpr
->arg
));
1526 /* just use argument's location */
1527 loc
= exprLocation((Node
*) ((const CollateExpr
*) expr
)->arg
);
1530 /* CASE keyword should always be the first thing */
1531 loc
= ((const CaseExpr
*) expr
)->location
;
1534 /* WHEN keyword should always be the first thing */
1535 loc
= ((const CaseWhen
*) expr
)->location
;
1538 /* the location points at ARRAY or [, which must be leftmost */
1539 loc
= ((const ArrayExpr
*) expr
)->location
;
1542 /* the location points at ROW or (, which must be leftmost */
1543 loc
= ((const RowExpr
*) expr
)->location
;
1545 case T_RowCompareExpr
:
1546 /* just use leftmost argument's location */
1547 loc
= exprLocation((Node
*) ((const RowCompareExpr
*) expr
)->largs
);
1549 case T_CoalesceExpr
:
1550 /* COALESCE keyword should always be the first thing */
1551 loc
= ((const CoalesceExpr
*) expr
)->location
;
1554 /* GREATEST/LEAST keyword should always be the first thing */
1555 loc
= ((const MinMaxExpr
*) expr
)->location
;
1557 case T_SQLValueFunction
:
1558 /* function keyword should always be the first thing */
1559 loc
= ((const SQLValueFunction
*) expr
)->location
;
1563 const XmlExpr
*xexpr
= (const XmlExpr
*) expr
;
1565 /* consider both function name and leftmost arg */
1566 loc
= leftmostLoc(xexpr
->location
,
1567 exprLocation((Node
*) xexpr
->args
));
1571 loc
= ((const JsonFormat
*) expr
)->location
;
1573 case T_JsonValueExpr
:
1574 loc
= exprLocation((Node
*) ((const JsonValueExpr
*) expr
)->raw_expr
);
1576 case T_JsonConstructorExpr
:
1577 loc
= ((const JsonConstructorExpr
*) expr
)->location
;
1579 case T_JsonIsPredicate
:
1580 loc
= ((const JsonIsPredicate
*) expr
)->location
;
1584 const JsonExpr
*jsexpr
= (const JsonExpr
*) expr
;
1586 /* consider both function name and leftmost arg */
1587 loc
= leftmostLoc(jsexpr
->location
,
1588 exprLocation(jsexpr
->formatted_expr
));
1591 case T_JsonBehavior
:
1592 loc
= exprLocation(((JsonBehavior
*) expr
)->expr
);
1596 const NullTest
*nexpr
= (const NullTest
*) expr
;
1599 loc
= leftmostLoc(nexpr
->location
,
1600 exprLocation((Node
*) nexpr
->arg
));
1605 const BooleanTest
*bexpr
= (const BooleanTest
*) expr
;
1608 loc
= leftmostLoc(bexpr
->location
,
1609 exprLocation((Node
*) bexpr
->arg
));
1612 case T_CoerceToDomain
:
1614 const CoerceToDomain
*cexpr
= (const CoerceToDomain
*) expr
;
1617 loc
= leftmostLoc(cexpr
->location
,
1618 exprLocation((Node
*) cexpr
->arg
));
1621 case T_CoerceToDomainValue
:
1622 loc
= ((const CoerceToDomainValue
*) expr
)->location
;
1624 case T_SetToDefault
:
1625 loc
= ((const SetToDefault
*) expr
)->location
;
1628 /* just use argument's location */
1629 loc
= exprLocation((Node
*) ((const TargetEntry
*) expr
)->expr
);
1632 /* use the contained RangeVar's location --- close enough */
1633 loc
= exprLocation((Node
*) ((const IntoClause
*) expr
)->rel
);
1637 /* report location of first list member that has a location */
1640 loc
= -1; /* just to suppress compiler warning */
1641 foreach(lc
, (const List
*) expr
)
1643 loc
= exprLocation((Node
*) lfirst(lc
));
1651 const A_Expr
*aexpr
= (const A_Expr
*) expr
;
1653 /* use leftmost of operator or left operand (if any) */
1654 /* we assume right operand can't be to left of operator */
1655 loc
= leftmostLoc(aexpr
->location
,
1656 exprLocation(aexpr
->lexpr
));
1660 loc
= ((const ColumnRef
*) expr
)->location
;
1663 loc
= ((const ParamRef
*) expr
)->location
;
1666 loc
= ((const A_Const
*) expr
)->location
;
1670 const FuncCall
*fc
= (const FuncCall
*) expr
;
1672 /* consider both function name and leftmost arg */
1673 /* (we assume any ORDER BY nodes must be to right of name) */
1674 loc
= leftmostLoc(fc
->location
,
1675 exprLocation((Node
*) fc
->args
));
1679 /* the location points at ARRAY or [, which must be leftmost */
1680 loc
= ((const A_ArrayExpr
*) expr
)->location
;
1683 /* we need not examine the contained expression (if any) */
1684 loc
= ((const ResTarget
*) expr
)->location
;
1686 case T_MultiAssignRef
:
1687 loc
= exprLocation(((const MultiAssignRef
*) expr
)->source
);
1691 const TypeCast
*tc
= (const TypeCast
*) expr
;
1694 * This could represent CAST(), ::, or TypeName 'literal', so
1695 * any of the components might be leftmost.
1697 loc
= exprLocation(tc
->arg
);
1698 loc
= leftmostLoc(loc
, tc
->typeName
->location
);
1699 loc
= leftmostLoc(loc
, tc
->location
);
1702 case T_CollateClause
:
1703 /* just use argument's location */
1704 loc
= exprLocation(((const CollateClause
*) expr
)->arg
);
1707 /* just use argument's location (ignore operator, if any) */
1708 loc
= exprLocation(((const SortBy
*) expr
)->node
);
1711 loc
= ((const WindowDef
*) expr
)->location
;
1713 case T_RangeTableSample
:
1714 loc
= ((const RangeTableSample
*) expr
)->location
;
1717 loc
= ((const TypeName
*) expr
)->location
;
1720 loc
= ((const ColumnDef
*) expr
)->location
;
1723 loc
= ((const Constraint
*) expr
)->location
;
1725 case T_FunctionParameter
:
1726 loc
= ((const FunctionParameter
*) expr
)->location
;
1728 case T_XmlSerialize
:
1729 /* XMLSERIALIZE keyword should always be the first thing */
1730 loc
= ((const XmlSerialize
*) expr
)->location
;
1733 loc
= ((const GroupingSet
*) expr
)->location
;
1736 loc
= ((const WithClause
*) expr
)->location
;
1739 loc
= ((const InferClause
*) expr
)->location
;
1741 case T_OnConflictClause
:
1742 loc
= ((const OnConflictClause
*) expr
)->location
;
1744 case T_CTESearchClause
:
1745 loc
= ((const CTESearchClause
*) expr
)->location
;
1747 case T_CTECycleClause
:
1748 loc
= ((const CTECycleClause
*) expr
)->location
;
1750 case T_CommonTableExpr
:
1751 loc
= ((const CommonTableExpr
*) expr
)->location
;
1753 case T_JsonKeyValue
:
1754 /* just use the key's location */
1755 loc
= exprLocation((Node
*) ((const JsonKeyValue
*) expr
)->key
);
1757 case T_JsonObjectConstructor
:
1758 loc
= ((const JsonObjectConstructor
*) expr
)->location
;
1760 case T_JsonArrayConstructor
:
1761 loc
= ((const JsonArrayConstructor
*) expr
)->location
;
1763 case T_JsonArrayQueryConstructor
:
1764 loc
= ((const JsonArrayQueryConstructor
*) expr
)->location
;
1766 case T_JsonAggConstructor
:
1767 loc
= ((const JsonAggConstructor
*) expr
)->location
;
1769 case T_JsonObjectAgg
:
1770 loc
= exprLocation((Node
*) ((const JsonObjectAgg
*) expr
)->constructor
);
1772 case T_JsonArrayAgg
:
1773 loc
= exprLocation((Node
*) ((const JsonArrayAgg
*) expr
)->constructor
);
1775 case T_PlaceHolderVar
:
1776 /* just use argument's location */
1777 loc
= exprLocation((Node
*) ((const PlaceHolderVar
*) expr
)->phexpr
);
1779 case T_InferenceElem
:
1780 /* just use nested expr's location */
1781 loc
= exprLocation((Node
*) ((const InferenceElem
*) expr
)->expr
);
1783 case T_PartitionElem
:
1784 loc
= ((const PartitionElem
*) expr
)->location
;
1786 case T_PartitionSpec
:
1787 loc
= ((const PartitionSpec
*) expr
)->location
;
1789 case T_PartitionBoundSpec
:
1790 loc
= ((const PartitionBoundSpec
*) expr
)->location
;
1792 case T_PartitionRangeDatum
:
1793 loc
= ((const PartitionRangeDatum
*) expr
)->location
;
1796 /* for any other node type it's just unknown... */
1804 * leftmostLoc - support for exprLocation
1806 * Take the minimum of two parse location values, but ignore unknowns
1809 leftmostLoc(int loc1
, int loc2
)
1816 return Min(loc1
, loc2
);
1822 * Calculate opfuncid field from opno for each OpExpr node in given tree.
1823 * The given tree can be anything expression_tree_walker handles.
1825 * The argument is modified in-place. (This is OK since we'd want the
1826 * same change for any node, even if it gets visited more than once due to
1827 * shared structure.)
1830 fix_opfuncids(Node
*node
)
1832 /* This tree walk requires no special setup, so away we go... */
1833 fix_opfuncids_walker(node
, NULL
);
1837 fix_opfuncids_walker(Node
*node
, void *context
)
1841 if (IsA(node
, OpExpr
))
1842 set_opfuncid((OpExpr
*) node
);
1843 else if (IsA(node
, DistinctExpr
))
1844 set_opfuncid((OpExpr
*) node
); /* rely on struct equivalence */
1845 else if (IsA(node
, NullIfExpr
))
1846 set_opfuncid((OpExpr
*) node
); /* rely on struct equivalence */
1847 else if (IsA(node
, ScalarArrayOpExpr
))
1848 set_sa_opfuncid((ScalarArrayOpExpr
*) node
);
1849 return expression_tree_walker(node
, fix_opfuncids_walker
, context
);
1854 * Set the opfuncid (procedure OID) in an OpExpr node,
1855 * if it hasn't been set already.
1857 * Because of struct equivalence, this can also be used for
1858 * DistinctExpr and NullIfExpr nodes.
1861 set_opfuncid(OpExpr
*opexpr
)
1863 if (opexpr
->opfuncid
== InvalidOid
)
1864 opexpr
->opfuncid
= get_opcode(opexpr
->opno
);
1869 * As above, for ScalarArrayOpExpr nodes.
1872 set_sa_opfuncid(ScalarArrayOpExpr
*opexpr
)
1874 if (opexpr
->opfuncid
== InvalidOid
)
1875 opexpr
->opfuncid
= get_opcode(opexpr
->opno
);
1880 * check_functions_in_node -
1881 * apply checker() to each function OID contained in given expression node
1883 * Returns true if the checker() function does; for nodes representing more
1884 * than one function call, returns true if the checker() function does so
1885 * for any of those functions. Returns false if node does not invoke any
1886 * SQL-visible function. Caller must not pass node == NULL.
1888 * This function examines only the given node; it does not recurse into any
1889 * sub-expressions. Callers typically prefer to keep control of the recursion
1890 * for themselves, in case additional checks should be made, or because they
1891 * have special rules about which parts of the tree need to be visited.
1893 * Note: we ignore MinMaxExpr, SQLValueFunction, XmlExpr, CoerceToDomain,
1894 * and NextValueExpr nodes, because they do not contain SQL function OIDs.
1895 * However, they can invoke SQL-visible functions, so callers should take
1896 * thought about how to treat them.
1899 check_functions_in_node(Node
*node
, check_function_callback checker
,
1902 switch (nodeTag(node
))
1906 Aggref
*expr
= (Aggref
*) node
;
1908 if (checker(expr
->aggfnoid
, context
))
1914 WindowFunc
*expr
= (WindowFunc
*) node
;
1916 if (checker(expr
->winfnoid
, context
))
1922 FuncExpr
*expr
= (FuncExpr
*) node
;
1924 if (checker(expr
->funcid
, context
))
1929 case T_DistinctExpr
: /* struct-equivalent to OpExpr */
1930 case T_NullIfExpr
: /* struct-equivalent to OpExpr */
1932 OpExpr
*expr
= (OpExpr
*) node
;
1934 /* Set opfuncid if it wasn't set already */
1936 if (checker(expr
->opfuncid
, context
))
1940 case T_ScalarArrayOpExpr
:
1942 ScalarArrayOpExpr
*expr
= (ScalarArrayOpExpr
*) node
;
1944 set_sa_opfuncid(expr
);
1945 if (checker(expr
->opfuncid
, context
))
1951 CoerceViaIO
*expr
= (CoerceViaIO
*) node
;
1956 /* check the result type's input function */
1957 getTypeInputInfo(expr
->resulttype
,
1958 &iofunc
, &typioparam
);
1959 if (checker(iofunc
, context
))
1961 /* check the input type's output function */
1962 getTypeOutputInfo(exprType((Node
*) expr
->arg
),
1963 &iofunc
, &typisvarlena
);
1964 if (checker(iofunc
, context
))
1968 case T_RowCompareExpr
:
1970 RowCompareExpr
*rcexpr
= (RowCompareExpr
*) node
;
1973 foreach(opid
, rcexpr
->opnos
)
1975 Oid opfuncid
= get_opcode(lfirst_oid(opid
));
1977 if (checker(opfuncid
, context
))
1990 * Standard expression-tree walking support
1992 * We used to have near-duplicate code in many different routines that
1993 * understood how to recurse through an expression node tree. That was
1994 * a pain to maintain, and we frequently had bugs due to some particular
1995 * routine neglecting to support a particular node type. In most cases,
1996 * these routines only actually care about certain node types, and don't
1997 * care about other types except insofar as they have to recurse through
1998 * non-primitive node types. Therefore, we now provide generic tree-walking
1999 * logic to consolidate the redundant "boilerplate" code. There are
2000 * two versions: expression_tree_walker() and expression_tree_mutator().
2004 * expression_tree_walker() is designed to support routines that traverse
2005 * a tree in a read-only fashion (although it will also work for routines
2006 * that modify nodes in-place but never add/delete/replace nodes).
2007 * A walker routine should look like this:
2009 * bool my_walker (Node *node, my_struct *context)
2013 * // check for nodes that special work is required for, eg:
2014 * if (IsA(node, Var))
2016 * ... do special actions for Var nodes
2018 * else if (IsA(node, ...))
2020 * ... do special actions for other node types
2022 * // for any node type not specially processed, do:
2023 * return expression_tree_walker(node, my_walker, context);
2026 * The "context" argument points to a struct that holds whatever context
2027 * information the walker routine needs --- it can be used to return data
2028 * gathered by the walker, too. This argument is not touched by
2029 * expression_tree_walker, but it is passed down to recursive sub-invocations
2030 * of my_walker. The tree walk is started from a setup routine that
2031 * fills in the appropriate context struct, calls my_walker with the top-level
2032 * node of the tree, and then examines the results.
2034 * The walker routine should return "false" to continue the tree walk, or
2035 * "true" to abort the walk and immediately return "true" to the top-level
2036 * caller. This can be used to short-circuit the traversal if the walker
2037 * has found what it came for. "false" is returned to the top-level caller
2038 * iff no invocation of the walker returned "true".
2040 * The node types handled by expression_tree_walker include all those
2041 * normally found in target lists and qualifier clauses during the planning
2042 * stage. In particular, it handles List nodes since a cnf-ified qual clause
2043 * will have List structure at the top level, and it handles TargetEntry nodes
2044 * so that a scan of a target list can be handled without additional code.
2045 * Also, RangeTblRef, FromExpr, JoinExpr, and SetOperationStmt nodes are
2046 * handled, so that query jointrees and setOperation trees can be processed
2047 * without additional code.
2049 * expression_tree_walker will handle SubLink nodes by recursing normally
2050 * into the "testexpr" subtree (which is an expression belonging to the outer
2051 * plan). It will also call the walker on the sub-Query node; however, when
2052 * expression_tree_walker itself is called on a Query node, it does nothing
2053 * and returns "false". The net effect is that unless the walker does
2054 * something special at a Query node, sub-selects will not be visited during
2055 * an expression tree walk. This is exactly the behavior wanted in many cases
2056 * --- and for those walkers that do want to recurse into sub-selects, special
2057 * behavior is typically needed anyway at the entry to a sub-select (such as
2058 * incrementing a depth counter). A walker that wants to examine sub-selects
2059 * should include code along the lines of:
2061 * if (IsA(node, Query))
2063 * adjust context for subquery;
2064 * result = query_tree_walker((Query *) node, my_walker, context,
2065 * 0); // adjust flags as needed
2066 * restore context if needed;
2070 * query_tree_walker is a convenience routine (see below) that calls the
2071 * walker on all the expression subtrees of the given Query node.
2073 * expression_tree_walker will handle SubPlan nodes by recursing normally
2074 * into the "testexpr" and the "args" list (which are expressions belonging to
2075 * the outer plan). It will not touch the completed subplan, however. Since
2076 * there is no link to the original Query, it is not possible to recurse into
2077 * subselects of an already-planned expression tree. This is OK for current
2078 * uses, but may need to be revisited in future.
2082 expression_tree_walker_impl(Node
*node
,
2083 tree_walker_callback walker
,
2089 * The walker has already visited the current node, and so we need only
2090 * recurse into any sub-nodes it has.
2092 * We assume that the walker is not interested in List nodes per se, so
2093 * when we expect a List we just recurse directly to self without
2094 * bothering to call the walker.
2096 #define WALK(n) walker((Node *) (n), context)
2098 #define LIST_WALK(l) expression_tree_walker_impl((Node *) (l), walker, context)
2103 /* Guard against stack overflow due to overly complex expressions */
2104 check_stack_depth();
2106 switch (nodeTag(node
))
2111 case T_CaseTestExpr
:
2112 case T_SQLValueFunction
:
2113 case T_CoerceToDomainValue
:
2114 case T_SetToDefault
:
2115 case T_CurrentOfExpr
:
2116 case T_NextValueExpr
:
2118 case T_SortGroupClause
:
2119 case T_CTESearchClause
:
2120 case T_MergeSupportFunc
:
2121 /* primitive node types with no expression subnodes */
2123 case T_WithCheckOption
:
2124 return WALK(((WithCheckOption
*) node
)->qual
);
2127 Aggref
*expr
= (Aggref
*) node
;
2129 /* recurse directly on Lists */
2130 if (LIST_WALK(expr
->aggdirectargs
))
2132 if (LIST_WALK(expr
->args
))
2134 if (LIST_WALK(expr
->aggorder
))
2136 if (LIST_WALK(expr
->aggdistinct
))
2138 if (WALK(expr
->aggfilter
))
2142 case T_GroupingFunc
:
2144 GroupingFunc
*grouping
= (GroupingFunc
*) node
;
2146 if (LIST_WALK(grouping
->args
))
2152 WindowFunc
*expr
= (WindowFunc
*) node
;
2154 /* recurse directly on List */
2155 if (LIST_WALK(expr
->args
))
2157 if (WALK(expr
->aggfilter
))
2159 if (WALK(expr
->runCondition
))
2163 case T_WindowFuncRunCondition
:
2165 WindowFuncRunCondition
*expr
= (WindowFuncRunCondition
*) node
;
2167 if (WALK(expr
->arg
))
2171 case T_SubscriptingRef
:
2173 SubscriptingRef
*sbsref
= (SubscriptingRef
*) node
;
2175 /* recurse directly for upper/lower container index lists */
2176 if (LIST_WALK(sbsref
->refupperindexpr
))
2178 if (LIST_WALK(sbsref
->reflowerindexpr
))
2180 /* walker must see the refexpr and refassgnexpr, however */
2181 if (WALK(sbsref
->refexpr
))
2184 if (WALK(sbsref
->refassgnexpr
))
2190 FuncExpr
*expr
= (FuncExpr
*) node
;
2192 if (LIST_WALK(expr
->args
))
2196 case T_NamedArgExpr
:
2197 return WALK(((NamedArgExpr
*) node
)->arg
);
2199 case T_DistinctExpr
: /* struct-equivalent to OpExpr */
2200 case T_NullIfExpr
: /* struct-equivalent to OpExpr */
2202 OpExpr
*expr
= (OpExpr
*) node
;
2204 if (LIST_WALK(expr
->args
))
2208 case T_ScalarArrayOpExpr
:
2210 ScalarArrayOpExpr
*expr
= (ScalarArrayOpExpr
*) node
;
2212 if (LIST_WALK(expr
->args
))
2218 BoolExpr
*expr
= (BoolExpr
*) node
;
2220 if (LIST_WALK(expr
->args
))
2226 SubLink
*sublink
= (SubLink
*) node
;
2228 if (WALK(sublink
->testexpr
))
2232 * Also invoke the walker on the sublink's Query node, so it
2233 * can recurse into the sub-query if it wants to.
2235 return WALK(sublink
->subselect
);
2240 SubPlan
*subplan
= (SubPlan
*) node
;
2242 /* recurse into the testexpr, but not into the Plan */
2243 if (WALK(subplan
->testexpr
))
2245 /* also examine args list */
2246 if (LIST_WALK(subplan
->args
))
2250 case T_AlternativeSubPlan
:
2251 return LIST_WALK(((AlternativeSubPlan
*) node
)->subplans
);
2253 return WALK(((FieldSelect
*) node
)->arg
);
2256 FieldStore
*fstore
= (FieldStore
*) node
;
2258 if (WALK(fstore
->arg
))
2260 if (WALK(fstore
->newvals
))
2265 return WALK(((RelabelType
*) node
)->arg
);
2267 return WALK(((CoerceViaIO
*) node
)->arg
);
2268 case T_ArrayCoerceExpr
:
2270 ArrayCoerceExpr
*acoerce
= (ArrayCoerceExpr
*) node
;
2272 if (WALK(acoerce
->arg
))
2274 if (WALK(acoerce
->elemexpr
))
2278 case T_ConvertRowtypeExpr
:
2279 return WALK(((ConvertRowtypeExpr
*) node
)->arg
);
2281 return WALK(((CollateExpr
*) node
)->arg
);
2284 CaseExpr
*caseexpr
= (CaseExpr
*) node
;
2286 if (WALK(caseexpr
->arg
))
2288 /* we assume walker doesn't care about CaseWhens, either */
2289 foreach(temp
, caseexpr
->args
)
2291 CaseWhen
*when
= lfirst_node(CaseWhen
, temp
);
2293 if (WALK(when
->expr
))
2295 if (WALK(when
->result
))
2298 if (WALK(caseexpr
->defresult
))
2303 return WALK(((ArrayExpr
*) node
)->elements
);
2305 /* Assume colnames isn't interesting */
2306 return WALK(((RowExpr
*) node
)->args
);
2307 case T_RowCompareExpr
:
2309 RowCompareExpr
*rcexpr
= (RowCompareExpr
*) node
;
2311 if (WALK(rcexpr
->largs
))
2313 if (WALK(rcexpr
->rargs
))
2317 case T_CoalesceExpr
:
2318 return WALK(((CoalesceExpr
*) node
)->args
);
2320 return WALK(((MinMaxExpr
*) node
)->args
);
2323 XmlExpr
*xexpr
= (XmlExpr
*) node
;
2325 if (WALK(xexpr
->named_args
))
2327 /* we assume walker doesn't care about arg_names */
2328 if (WALK(xexpr
->args
))
2332 case T_JsonValueExpr
:
2334 JsonValueExpr
*jve
= (JsonValueExpr
*) node
;
2336 if (WALK(jve
->raw_expr
))
2338 if (WALK(jve
->formatted_expr
))
2342 case T_JsonConstructorExpr
:
2344 JsonConstructorExpr
*ctor
= (JsonConstructorExpr
*) node
;
2346 if (WALK(ctor
->args
))
2348 if (WALK(ctor
->func
))
2350 if (WALK(ctor
->coercion
))
2354 case T_JsonIsPredicate
:
2355 return WALK(((JsonIsPredicate
*) node
)->expr
);
2358 JsonExpr
*jexpr
= (JsonExpr
*) node
;
2360 if (WALK(jexpr
->formatted_expr
))
2362 if (WALK(jexpr
->path_spec
))
2364 if (WALK(jexpr
->passing_values
))
2366 /* we assume walker doesn't care about passing_names */
2367 if (WALK(jexpr
->on_empty
))
2369 if (WALK(jexpr
->on_error
))
2373 case T_JsonBehavior
:
2375 JsonBehavior
*behavior
= (JsonBehavior
*) node
;
2377 if (WALK(behavior
->expr
))
2382 return WALK(((NullTest
*) node
)->arg
);
2384 return WALK(((BooleanTest
*) node
)->arg
);
2385 case T_CoerceToDomain
:
2386 return WALK(((CoerceToDomain
*) node
)->arg
);
2388 return WALK(((TargetEntry
*) node
)->expr
);
2390 /* Do nothing with a sub-Query, per discussion above */
2392 case T_WindowClause
:
2394 WindowClause
*wc
= (WindowClause
*) node
;
2396 if (WALK(wc
->partitionClause
))
2398 if (WALK(wc
->orderClause
))
2400 if (WALK(wc
->startOffset
))
2402 if (WALK(wc
->endOffset
))
2406 case T_CTECycleClause
:
2408 CTECycleClause
*cc
= (CTECycleClause
*) node
;
2410 if (WALK(cc
->cycle_mark_value
))
2412 if (WALK(cc
->cycle_mark_default
))
2416 case T_CommonTableExpr
:
2418 CommonTableExpr
*cte
= (CommonTableExpr
*) node
;
2421 * Invoke the walker on the CTE's Query node, so it can
2422 * recurse into the sub-query if it wants to.
2424 if (WALK(cte
->ctequery
))
2427 if (WALK(cte
->search_clause
))
2429 if (WALK(cte
->cycle_clause
))
2433 case T_JsonKeyValue
:
2435 JsonKeyValue
*kv
= (JsonKeyValue
*) node
;
2439 if (WALK(kv
->value
))
2443 case T_JsonObjectConstructor
:
2445 JsonObjectConstructor
*ctor
= (JsonObjectConstructor
*) node
;
2447 if (LIST_WALK(ctor
->exprs
))
2451 case T_JsonArrayConstructor
:
2453 JsonArrayConstructor
*ctor
= (JsonArrayConstructor
*) node
;
2455 if (LIST_WALK(ctor
->exprs
))
2459 case T_JsonArrayQueryConstructor
:
2461 JsonArrayQueryConstructor
*ctor
= (JsonArrayQueryConstructor
*) node
;
2463 if (WALK(ctor
->query
))
2467 case T_JsonAggConstructor
:
2469 JsonAggConstructor
*ctor
= (JsonAggConstructor
*) node
;
2471 if (WALK(ctor
->agg_filter
))
2473 if (WALK(ctor
->agg_order
))
2475 if (WALK(ctor
->over
))
2479 case T_JsonObjectAgg
:
2481 JsonObjectAgg
*ctor
= (JsonObjectAgg
*) node
;
2483 if (WALK(ctor
->constructor
))
2485 if (WALK(ctor
->arg
))
2489 case T_JsonArrayAgg
:
2491 JsonArrayAgg
*ctor
= (JsonArrayAgg
*) node
;
2493 if (WALK(ctor
->constructor
))
2495 if (WALK(ctor
->arg
))
2500 case T_PartitionBoundSpec
:
2502 PartitionBoundSpec
*pbs
= (PartitionBoundSpec
*) node
;
2504 if (WALK(pbs
->listdatums
))
2506 if (WALK(pbs
->lowerdatums
))
2508 if (WALK(pbs
->upperdatums
))
2512 case T_PartitionRangeDatum
:
2514 PartitionRangeDatum
*prd
= (PartitionRangeDatum
*) node
;
2516 if (WALK(prd
->value
))
2521 foreach(temp
, (List
*) node
)
2523 if (WALK(lfirst(temp
)))
2529 FromExpr
*from
= (FromExpr
*) node
;
2531 if (LIST_WALK(from
->fromlist
))
2533 if (WALK(from
->quals
))
2537 case T_OnConflictExpr
:
2539 OnConflictExpr
*onconflict
= (OnConflictExpr
*) node
;
2541 if (WALK(onconflict
->arbiterElems
))
2543 if (WALK(onconflict
->arbiterWhere
))
2545 if (WALK(onconflict
->onConflictSet
))
2547 if (WALK(onconflict
->onConflictWhere
))
2549 if (WALK(onconflict
->exclRelTlist
))
2555 MergeAction
*action
= (MergeAction
*) node
;
2557 if (WALK(action
->qual
))
2559 if (WALK(action
->targetList
))
2563 case T_PartitionPruneStepOp
:
2565 PartitionPruneStepOp
*opstep
= (PartitionPruneStepOp
*) node
;
2567 if (WALK(opstep
->exprs
))
2571 case T_PartitionPruneStepCombine
:
2572 /* no expression subnodes */
2576 JoinExpr
*join
= (JoinExpr
*) node
;
2578 if (WALK(join
->larg
))
2580 if (WALK(join
->rarg
))
2582 if (WALK(join
->quals
))
2586 * alias clause, using list are deemed uninteresting.
2590 case T_SetOperationStmt
:
2592 SetOperationStmt
*setop
= (SetOperationStmt
*) node
;
2594 if (WALK(setop
->larg
))
2596 if (WALK(setop
->rarg
))
2599 /* groupClauses are deemed uninteresting */
2604 IndexClause
*iclause
= (IndexClause
*) node
;
2606 if (WALK(iclause
->rinfo
))
2608 if (LIST_WALK(iclause
->indexquals
))
2612 case T_PlaceHolderVar
:
2613 return WALK(((PlaceHolderVar
*) node
)->phexpr
);
2614 case T_InferenceElem
:
2615 return WALK(((InferenceElem
*) node
)->expr
);
2616 case T_AppendRelInfo
:
2618 AppendRelInfo
*appinfo
= (AppendRelInfo
*) node
;
2620 if (LIST_WALK(appinfo
->translated_vars
))
2624 case T_PlaceHolderInfo
:
2625 return WALK(((PlaceHolderInfo
*) node
)->ph_var
);
2626 case T_RangeTblFunction
:
2627 return WALK(((RangeTblFunction
*) node
)->funcexpr
);
2628 case T_TableSampleClause
:
2630 TableSampleClause
*tsc
= (TableSampleClause
*) node
;
2632 if (LIST_WALK(tsc
->args
))
2634 if (WALK(tsc
->repeatable
))
2640 TableFunc
*tf
= (TableFunc
*) node
;
2642 if (WALK(tf
->ns_uris
))
2644 if (WALK(tf
->docexpr
))
2646 if (WALK(tf
->rowexpr
))
2648 if (WALK(tf
->colexprs
))
2650 if (WALK(tf
->coldefexprs
))
2652 if (WALK(tf
->colvalexprs
))
2654 if (WALK(tf
->passingvalexprs
))
2659 elog(ERROR
, "unrecognized node type: %d",
2660 (int) nodeTag(node
));
2665 /* The WALK() macro can be re-used below, but LIST_WALK() not so much */
2670 * query_tree_walker --- initiate a walk of a Query's expressions
2672 * This routine exists just to reduce the number of places that need to know
2673 * where all the expression subtrees of a Query are. Note it can be used
2674 * for starting a walk at top level of a Query regardless of whether the
2675 * walker intends to descend into subqueries. It is also useful for
2676 * descending into subqueries within a walker.
2678 * Some callers want to suppress visitation of certain items in the sub-Query,
2679 * typically because they need to process them specially, or don't actually
2680 * want to recurse into subqueries. This is supported by the flags argument,
2681 * which is the bitwise OR of flag values to add or suppress visitation of
2682 * indicated items. (More flag bits may be added as needed.)
2685 query_tree_walker_impl(Query
*query
,
2686 tree_walker_callback walker
,
2690 Assert(query
!= NULL
&& IsA(query
, Query
));
2693 * We don't walk any utilityStmt here. However, we can't easily assert
2694 * that it is absent, since there are at least two code paths by which
2695 * action statements from CREATE RULE end up here, and NOTIFY is allowed
2699 if (WALK(query
->targetList
))
2701 if (WALK(query
->withCheckOptions
))
2703 if (WALK(query
->onConflict
))
2705 if (WALK(query
->mergeActionList
))
2707 if (WALK(query
->mergeJoinCondition
))
2709 if (WALK(query
->returningList
))
2711 if (WALK(query
->jointree
))
2713 if (WALK(query
->setOperations
))
2715 if (WALK(query
->havingQual
))
2717 if (WALK(query
->limitOffset
))
2719 if (WALK(query
->limitCount
))
2723 * Most callers aren't interested in SortGroupClause nodes since those
2724 * don't contain actual expressions. However they do contain OIDs which
2725 * may be needed by dependency walkers etc.
2727 if ((flags
& QTW_EXAMINE_SORTGROUP
))
2729 if (WALK(query
->groupClause
))
2731 if (WALK(query
->windowClause
))
2733 if (WALK(query
->sortClause
))
2735 if (WALK(query
->distinctClause
))
2741 * But we need to walk the expressions under WindowClause nodes even
2742 * if we're not interested in SortGroupClause nodes.
2746 foreach(lc
, query
->windowClause
)
2748 WindowClause
*wc
= lfirst_node(WindowClause
, lc
);
2750 if (WALK(wc
->startOffset
))
2752 if (WALK(wc
->endOffset
))
2758 * groupingSets and rowMarks are not walked:
2760 * groupingSets contain only ressortgrouprefs (integers) which are
2761 * meaningless without the corresponding groupClause or tlist.
2762 * Accordingly, any walker that needs to care about them needs to handle
2763 * them itself in its Query processing.
2765 * rowMarks is not walked because it contains only rangetable indexes (and
2766 * flags etc.) and therefore should be handled at Query level similarly.
2769 if (!(flags
& QTW_IGNORE_CTE_SUBQUERIES
))
2771 if (WALK(query
->cteList
))
2774 if (!(flags
& QTW_IGNORE_RANGE_TABLE
))
2776 if (range_table_walker(query
->rtable
, walker
, context
, flags
))
2783 * range_table_walker is just the part of query_tree_walker that scans
2784 * a query's rangetable. This is split out since it can be useful on
2788 range_table_walker_impl(List
*rtable
,
2789 tree_walker_callback walker
,
2797 RangeTblEntry
*rte
= lfirst_node(RangeTblEntry
, rt
);
2799 if (range_table_entry_walker(rte
, walker
, context
, flags
))
2806 * Some callers even want to scan the expressions in individual RTEs.
2809 range_table_entry_walker_impl(RangeTblEntry
*rte
,
2810 tree_walker_callback walker
,
2815 * Walkers might need to examine the RTE node itself either before or
2816 * after visiting its contents (or, conceivably, both). Note that if you
2817 * specify neither flag, the walker won't be called on the RTE at all.
2819 if (flags
& QTW_EXAMINE_RTES_BEFORE
)
2823 switch (rte
->rtekind
)
2826 if (WALK(rte
->tablesample
))
2830 if (!(flags
& QTW_IGNORE_RT_SUBQUERIES
))
2831 if (WALK(rte
->subquery
))
2835 if (!(flags
& QTW_IGNORE_JOINALIASES
))
2836 if (WALK(rte
->joinaliasvars
))
2840 if (WALK(rte
->functions
))
2844 if (WALK(rte
->tablefunc
))
2848 if (WALK(rte
->values_lists
))
2852 case RTE_NAMEDTUPLESTORE
:
2857 if (!(flags
& QTW_IGNORE_GROUPEXPRS
))
2858 if (WALK(rte
->groupexprs
))
2863 if (WALK(rte
->securityQuals
))
2866 if (flags
& QTW_EXAMINE_RTES_AFTER
)
2875 * expression_tree_mutator() is designed to support routines that make a
2876 * modified copy of an expression tree, with some nodes being added,
2877 * removed, or replaced by new subtrees. The original tree is (normally)
2878 * not changed. Each recursion level is responsible for returning a copy of
2879 * (or appropriately modified substitute for) the subtree it is handed.
2880 * A mutator routine should look like this:
2882 * Node * my_mutator (Node *node, my_struct *context)
2886 * // check for nodes that special work is required for, eg:
2887 * if (IsA(node, Var))
2889 * ... create and return modified copy of Var node
2891 * else if (IsA(node, ...))
2893 * ... do special transformations of other node types
2895 * // for any node type not specially processed, do:
2896 * return expression_tree_mutator(node, my_mutator, context);
2899 * The "context" argument points to a struct that holds whatever context
2900 * information the mutator routine needs --- it can be used to return extra
2901 * data gathered by the mutator, too. This argument is not touched by
2902 * expression_tree_mutator, but it is passed down to recursive sub-invocations
2903 * of my_mutator. The tree walk is started from a setup routine that
2904 * fills in the appropriate context struct, calls my_mutator with the
2905 * top-level node of the tree, and does any required post-processing.
2907 * Each level of recursion must return an appropriately modified Node.
2908 * If expression_tree_mutator() is called, it will make an exact copy
2909 * of the given Node, but invoke my_mutator() to copy the sub-node(s)
2910 * of that Node. In this way, my_mutator() has full control over the
2911 * copying process but need not directly deal with expression trees
2912 * that it has no interest in.
2914 * Just as for expression_tree_walker, the node types handled by
2915 * expression_tree_mutator include all those normally found in target lists
2916 * and qualifier clauses during the planning stage.
2918 * expression_tree_mutator will handle SubLink nodes by recursing normally
2919 * into the "testexpr" subtree (which is an expression belonging to the outer
2920 * plan). It will also call the mutator on the sub-Query node; however, when
2921 * expression_tree_mutator itself is called on a Query node, it does nothing
2922 * and returns the unmodified Query node. The net effect is that unless the
2923 * mutator does something special at a Query node, sub-selects will not be
2924 * visited or modified; the original sub-select will be linked to by the new
2925 * SubLink node. Mutators that want to descend into sub-selects will usually
2926 * do so by recognizing Query nodes and calling query_tree_mutator (below).
2928 * expression_tree_mutator will handle a SubPlan node by recursing into the
2929 * "testexpr" and the "args" list (which belong to the outer plan), but it
2930 * will simply copy the link to the inner plan, since that's typically what
2931 * expression tree mutators want. A mutator that wants to modify the subplan
2932 * can force appropriate behavior by recognizing SubPlan expression nodes
2933 * and doing the right thing.
2937 expression_tree_mutator_impl(Node
*node
,
2938 tree_mutator_callback mutator
,
2942 * The mutator has already decided not to modify the current node, but we
2943 * must call the mutator for any sub-nodes.
2946 #define FLATCOPY(newnode, node, nodetype) \
2947 ( (newnode) = (nodetype *) palloc(sizeof(nodetype)), \
2948 memcpy((newnode), (node), sizeof(nodetype)) )
2950 #define MUTATE(newfield, oldfield, fieldtype) \
2951 ( (newfield) = (fieldtype) mutator((Node *) (oldfield), context) )
2956 /* Guard against stack overflow due to overly complex expressions */
2957 check_stack_depth();
2959 switch (nodeTag(node
))
2962 * Primitive node types with no expression subnodes. Var and
2963 * Const are frequent enough to deserve special cases, the others
2964 * we just use copyObject for.
2968 Var
*var
= (Var
*) node
;
2971 FLATCOPY(newnode
, var
, Var
);
2972 /* Assume we need not copy the varnullingrels bitmapset */
2973 return (Node
*) newnode
;
2978 Const
*oldnode
= (Const
*) node
;
2981 FLATCOPY(newnode
, oldnode
, Const
);
2982 /* XXX we don't bother with datumCopy; should we? */
2983 return (Node
*) newnode
;
2987 case T_CaseTestExpr
:
2988 case T_SQLValueFunction
:
2990 case T_CoerceToDomainValue
:
2991 case T_SetToDefault
:
2992 case T_CurrentOfExpr
:
2993 case T_NextValueExpr
:
2995 case T_SortGroupClause
:
2996 case T_CTESearchClause
:
2997 case T_MergeSupportFunc
:
2998 return copyObject(node
);
2999 case T_WithCheckOption
:
3001 WithCheckOption
*wco
= (WithCheckOption
*) node
;
3002 WithCheckOption
*newnode
;
3004 FLATCOPY(newnode
, wco
, WithCheckOption
);
3005 MUTATE(newnode
->qual
, wco
->qual
, Node
*);
3006 return (Node
*) newnode
;
3010 Aggref
*aggref
= (Aggref
*) node
;
3013 FLATCOPY(newnode
, aggref
, Aggref
);
3014 /* assume mutation doesn't change types of arguments */
3015 newnode
->aggargtypes
= list_copy(aggref
->aggargtypes
);
3016 MUTATE(newnode
->aggdirectargs
, aggref
->aggdirectargs
, List
*);
3017 MUTATE(newnode
->args
, aggref
->args
, List
*);
3018 MUTATE(newnode
->aggorder
, aggref
->aggorder
, List
*);
3019 MUTATE(newnode
->aggdistinct
, aggref
->aggdistinct
, List
*);
3020 MUTATE(newnode
->aggfilter
, aggref
->aggfilter
, Expr
*);
3021 return (Node
*) newnode
;
3024 case T_GroupingFunc
:
3026 GroupingFunc
*grouping
= (GroupingFunc
*) node
;
3027 GroupingFunc
*newnode
;
3029 FLATCOPY(newnode
, grouping
, GroupingFunc
);
3030 MUTATE(newnode
->args
, grouping
->args
, List
*);
3033 * We assume here that mutating the arguments does not change
3034 * the semantics, i.e. that the arguments are not mutated in a
3035 * way that makes them semantically different from their
3036 * previously matching expressions in the GROUP BY clause.
3038 * If a mutator somehow wanted to do this, it would have to
3039 * handle the refs and cols lists itself as appropriate.
3041 newnode
->refs
= list_copy(grouping
->refs
);
3042 newnode
->cols
= list_copy(grouping
->cols
);
3044 return (Node
*) newnode
;
3049 WindowFunc
*wfunc
= (WindowFunc
*) node
;
3050 WindowFunc
*newnode
;
3052 FLATCOPY(newnode
, wfunc
, WindowFunc
);
3053 MUTATE(newnode
->args
, wfunc
->args
, List
*);
3054 MUTATE(newnode
->aggfilter
, wfunc
->aggfilter
, Expr
*);
3055 return (Node
*) newnode
;
3058 case T_WindowFuncRunCondition
:
3060 WindowFuncRunCondition
*wfuncrc
= (WindowFuncRunCondition
*) node
;
3061 WindowFuncRunCondition
*newnode
;
3063 FLATCOPY(newnode
, wfuncrc
, WindowFuncRunCondition
);
3064 MUTATE(newnode
->arg
, wfuncrc
->arg
, Expr
*);
3065 return (Node
*) newnode
;
3068 case T_SubscriptingRef
:
3070 SubscriptingRef
*sbsref
= (SubscriptingRef
*) node
;
3071 SubscriptingRef
*newnode
;
3073 FLATCOPY(newnode
, sbsref
, SubscriptingRef
);
3074 MUTATE(newnode
->refupperindexpr
, sbsref
->refupperindexpr
,
3076 MUTATE(newnode
->reflowerindexpr
, sbsref
->reflowerindexpr
,
3078 MUTATE(newnode
->refexpr
, sbsref
->refexpr
,
3080 MUTATE(newnode
->refassgnexpr
, sbsref
->refassgnexpr
,
3083 return (Node
*) newnode
;
3088 FuncExpr
*expr
= (FuncExpr
*) node
;
3091 FLATCOPY(newnode
, expr
, FuncExpr
);
3092 MUTATE(newnode
->args
, expr
->args
, List
*);
3093 return (Node
*) newnode
;
3096 case T_NamedArgExpr
:
3098 NamedArgExpr
*nexpr
= (NamedArgExpr
*) node
;
3099 NamedArgExpr
*newnode
;
3101 FLATCOPY(newnode
, nexpr
, NamedArgExpr
);
3102 MUTATE(newnode
->arg
, nexpr
->arg
, Expr
*);
3103 return (Node
*) newnode
;
3108 OpExpr
*expr
= (OpExpr
*) node
;
3111 FLATCOPY(newnode
, expr
, OpExpr
);
3112 MUTATE(newnode
->args
, expr
->args
, List
*);
3113 return (Node
*) newnode
;
3116 case T_DistinctExpr
:
3118 DistinctExpr
*expr
= (DistinctExpr
*) node
;
3119 DistinctExpr
*newnode
;
3121 FLATCOPY(newnode
, expr
, DistinctExpr
);
3122 MUTATE(newnode
->args
, expr
->args
, List
*);
3123 return (Node
*) newnode
;
3128 NullIfExpr
*expr
= (NullIfExpr
*) node
;
3129 NullIfExpr
*newnode
;
3131 FLATCOPY(newnode
, expr
, NullIfExpr
);
3132 MUTATE(newnode
->args
, expr
->args
, List
*);
3133 return (Node
*) newnode
;
3136 case T_ScalarArrayOpExpr
:
3138 ScalarArrayOpExpr
*expr
= (ScalarArrayOpExpr
*) node
;
3139 ScalarArrayOpExpr
*newnode
;
3141 FLATCOPY(newnode
, expr
, ScalarArrayOpExpr
);
3142 MUTATE(newnode
->args
, expr
->args
, List
*);
3143 return (Node
*) newnode
;
3148 BoolExpr
*expr
= (BoolExpr
*) node
;
3151 FLATCOPY(newnode
, expr
, BoolExpr
);
3152 MUTATE(newnode
->args
, expr
->args
, List
*);
3153 return (Node
*) newnode
;
3158 SubLink
*sublink
= (SubLink
*) node
;
3161 FLATCOPY(newnode
, sublink
, SubLink
);
3162 MUTATE(newnode
->testexpr
, sublink
->testexpr
, Node
*);
3165 * Also invoke the mutator on the sublink's Query node, so it
3166 * can recurse into the sub-query if it wants to.
3168 MUTATE(newnode
->subselect
, sublink
->subselect
, Node
*);
3169 return (Node
*) newnode
;
3174 SubPlan
*subplan
= (SubPlan
*) node
;
3177 FLATCOPY(newnode
, subplan
, SubPlan
);
3178 /* transform testexpr */
3179 MUTATE(newnode
->testexpr
, subplan
->testexpr
, Node
*);
3180 /* transform args list (params to be passed to subplan) */
3181 MUTATE(newnode
->args
, subplan
->args
, List
*);
3182 /* but not the sub-Plan itself, which is referenced as-is */
3183 return (Node
*) newnode
;
3186 case T_AlternativeSubPlan
:
3188 AlternativeSubPlan
*asplan
= (AlternativeSubPlan
*) node
;
3189 AlternativeSubPlan
*newnode
;
3191 FLATCOPY(newnode
, asplan
, AlternativeSubPlan
);
3192 MUTATE(newnode
->subplans
, asplan
->subplans
, List
*);
3193 return (Node
*) newnode
;
3198 FieldSelect
*fselect
= (FieldSelect
*) node
;
3199 FieldSelect
*newnode
;
3201 FLATCOPY(newnode
, fselect
, FieldSelect
);
3202 MUTATE(newnode
->arg
, fselect
->arg
, Expr
*);
3203 return (Node
*) newnode
;
3208 FieldStore
*fstore
= (FieldStore
*) node
;
3209 FieldStore
*newnode
;
3211 FLATCOPY(newnode
, fstore
, FieldStore
);
3212 MUTATE(newnode
->arg
, fstore
->arg
, Expr
*);
3213 MUTATE(newnode
->newvals
, fstore
->newvals
, List
*);
3214 newnode
->fieldnums
= list_copy(fstore
->fieldnums
);
3215 return (Node
*) newnode
;
3220 RelabelType
*relabel
= (RelabelType
*) node
;
3221 RelabelType
*newnode
;
3223 FLATCOPY(newnode
, relabel
, RelabelType
);
3224 MUTATE(newnode
->arg
, relabel
->arg
, Expr
*);
3225 return (Node
*) newnode
;
3230 CoerceViaIO
*iocoerce
= (CoerceViaIO
*) node
;
3231 CoerceViaIO
*newnode
;
3233 FLATCOPY(newnode
, iocoerce
, CoerceViaIO
);
3234 MUTATE(newnode
->arg
, iocoerce
->arg
, Expr
*);
3235 return (Node
*) newnode
;
3238 case T_ArrayCoerceExpr
:
3240 ArrayCoerceExpr
*acoerce
= (ArrayCoerceExpr
*) node
;
3241 ArrayCoerceExpr
*newnode
;
3243 FLATCOPY(newnode
, acoerce
, ArrayCoerceExpr
);
3244 MUTATE(newnode
->arg
, acoerce
->arg
, Expr
*);
3245 MUTATE(newnode
->elemexpr
, acoerce
->elemexpr
, Expr
*);
3246 return (Node
*) newnode
;
3249 case T_ConvertRowtypeExpr
:
3251 ConvertRowtypeExpr
*convexpr
= (ConvertRowtypeExpr
*) node
;
3252 ConvertRowtypeExpr
*newnode
;
3254 FLATCOPY(newnode
, convexpr
, ConvertRowtypeExpr
);
3255 MUTATE(newnode
->arg
, convexpr
->arg
, Expr
*);
3256 return (Node
*) newnode
;
3261 CollateExpr
*collate
= (CollateExpr
*) node
;
3262 CollateExpr
*newnode
;
3264 FLATCOPY(newnode
, collate
, CollateExpr
);
3265 MUTATE(newnode
->arg
, collate
->arg
, Expr
*);
3266 return (Node
*) newnode
;
3271 CaseExpr
*caseexpr
= (CaseExpr
*) node
;
3274 FLATCOPY(newnode
, caseexpr
, CaseExpr
);
3275 MUTATE(newnode
->arg
, caseexpr
->arg
, Expr
*);
3276 MUTATE(newnode
->args
, caseexpr
->args
, List
*);
3277 MUTATE(newnode
->defresult
, caseexpr
->defresult
, Expr
*);
3278 return (Node
*) newnode
;
3283 CaseWhen
*casewhen
= (CaseWhen
*) node
;
3286 FLATCOPY(newnode
, casewhen
, CaseWhen
);
3287 MUTATE(newnode
->expr
, casewhen
->expr
, Expr
*);
3288 MUTATE(newnode
->result
, casewhen
->result
, Expr
*);
3289 return (Node
*) newnode
;
3294 ArrayExpr
*arrayexpr
= (ArrayExpr
*) node
;
3297 FLATCOPY(newnode
, arrayexpr
, ArrayExpr
);
3298 MUTATE(newnode
->elements
, arrayexpr
->elements
, List
*);
3299 return (Node
*) newnode
;
3304 RowExpr
*rowexpr
= (RowExpr
*) node
;
3307 FLATCOPY(newnode
, rowexpr
, RowExpr
);
3308 MUTATE(newnode
->args
, rowexpr
->args
, List
*);
3309 /* Assume colnames needn't be duplicated */
3310 return (Node
*) newnode
;
3313 case T_RowCompareExpr
:
3315 RowCompareExpr
*rcexpr
= (RowCompareExpr
*) node
;
3316 RowCompareExpr
*newnode
;
3318 FLATCOPY(newnode
, rcexpr
, RowCompareExpr
);
3319 MUTATE(newnode
->largs
, rcexpr
->largs
, List
*);
3320 MUTATE(newnode
->rargs
, rcexpr
->rargs
, List
*);
3321 return (Node
*) newnode
;
3324 case T_CoalesceExpr
:
3326 CoalesceExpr
*coalesceexpr
= (CoalesceExpr
*) node
;
3327 CoalesceExpr
*newnode
;
3329 FLATCOPY(newnode
, coalesceexpr
, CoalesceExpr
);
3330 MUTATE(newnode
->args
, coalesceexpr
->args
, List
*);
3331 return (Node
*) newnode
;
3336 MinMaxExpr
*minmaxexpr
= (MinMaxExpr
*) node
;
3337 MinMaxExpr
*newnode
;
3339 FLATCOPY(newnode
, minmaxexpr
, MinMaxExpr
);
3340 MUTATE(newnode
->args
, minmaxexpr
->args
, List
*);
3341 return (Node
*) newnode
;
3346 XmlExpr
*xexpr
= (XmlExpr
*) node
;
3349 FLATCOPY(newnode
, xexpr
, XmlExpr
);
3350 MUTATE(newnode
->named_args
, xexpr
->named_args
, List
*);
3351 /* assume mutator does not care about arg_names */
3352 MUTATE(newnode
->args
, xexpr
->args
, List
*);
3353 return (Node
*) newnode
;
3356 case T_JsonReturning
:
3358 JsonReturning
*jr
= (JsonReturning
*) node
;
3359 JsonReturning
*newnode
;
3361 FLATCOPY(newnode
, jr
, JsonReturning
);
3362 MUTATE(newnode
->format
, jr
->format
, JsonFormat
*);
3364 return (Node
*) newnode
;
3366 case T_JsonValueExpr
:
3368 JsonValueExpr
*jve
= (JsonValueExpr
*) node
;
3369 JsonValueExpr
*newnode
;
3371 FLATCOPY(newnode
, jve
, JsonValueExpr
);
3372 MUTATE(newnode
->raw_expr
, jve
->raw_expr
, Expr
*);
3373 MUTATE(newnode
->formatted_expr
, jve
->formatted_expr
, Expr
*);
3374 MUTATE(newnode
->format
, jve
->format
, JsonFormat
*);
3376 return (Node
*) newnode
;
3378 case T_JsonConstructorExpr
:
3380 JsonConstructorExpr
*jce
= (JsonConstructorExpr
*) node
;
3381 JsonConstructorExpr
*newnode
;
3383 FLATCOPY(newnode
, jce
, JsonConstructorExpr
);
3384 MUTATE(newnode
->args
, jce
->args
, List
*);
3385 MUTATE(newnode
->func
, jce
->func
, Expr
*);
3386 MUTATE(newnode
->coercion
, jce
->coercion
, Expr
*);
3387 MUTATE(newnode
->returning
, jce
->returning
, JsonReturning
*);
3389 return (Node
*) newnode
;
3391 case T_JsonIsPredicate
:
3393 JsonIsPredicate
*pred
= (JsonIsPredicate
*) node
;
3394 JsonIsPredicate
*newnode
;
3396 FLATCOPY(newnode
, pred
, JsonIsPredicate
);
3397 MUTATE(newnode
->expr
, pred
->expr
, Node
*);
3398 MUTATE(newnode
->format
, pred
->format
, JsonFormat
*);
3400 return (Node
*) newnode
;
3404 JsonExpr
*jexpr
= (JsonExpr
*) node
;
3407 FLATCOPY(newnode
, jexpr
, JsonExpr
);
3408 MUTATE(newnode
->formatted_expr
, jexpr
->formatted_expr
, Node
*);
3409 MUTATE(newnode
->path_spec
, jexpr
->path_spec
, Node
*);
3410 MUTATE(newnode
->passing_values
, jexpr
->passing_values
, List
*);
3411 /* assume mutator does not care about passing_names */
3412 MUTATE(newnode
->on_empty
, jexpr
->on_empty
, JsonBehavior
*);
3413 MUTATE(newnode
->on_error
, jexpr
->on_error
, JsonBehavior
*);
3414 return (Node
*) newnode
;
3417 case T_JsonBehavior
:
3419 JsonBehavior
*behavior
= (JsonBehavior
*) node
;
3420 JsonBehavior
*newnode
;
3422 FLATCOPY(newnode
, behavior
, JsonBehavior
);
3423 MUTATE(newnode
->expr
, behavior
->expr
, Node
*);
3424 return (Node
*) newnode
;
3429 NullTest
*ntest
= (NullTest
*) node
;
3432 FLATCOPY(newnode
, ntest
, NullTest
);
3433 MUTATE(newnode
->arg
, ntest
->arg
, Expr
*);
3434 return (Node
*) newnode
;
3439 BooleanTest
*btest
= (BooleanTest
*) node
;
3440 BooleanTest
*newnode
;
3442 FLATCOPY(newnode
, btest
, BooleanTest
);
3443 MUTATE(newnode
->arg
, btest
->arg
, Expr
*);
3444 return (Node
*) newnode
;
3447 case T_CoerceToDomain
:
3449 CoerceToDomain
*ctest
= (CoerceToDomain
*) node
;
3450 CoerceToDomain
*newnode
;
3452 FLATCOPY(newnode
, ctest
, CoerceToDomain
);
3453 MUTATE(newnode
->arg
, ctest
->arg
, Expr
*);
3454 return (Node
*) newnode
;
3459 TargetEntry
*targetentry
= (TargetEntry
*) node
;
3460 TargetEntry
*newnode
;
3462 FLATCOPY(newnode
, targetentry
, TargetEntry
);
3463 MUTATE(newnode
->expr
, targetentry
->expr
, Expr
*);
3464 return (Node
*) newnode
;
3468 /* Do nothing with a sub-Query, per discussion above */
3470 case T_WindowClause
:
3472 WindowClause
*wc
= (WindowClause
*) node
;
3473 WindowClause
*newnode
;
3475 FLATCOPY(newnode
, wc
, WindowClause
);
3476 MUTATE(newnode
->partitionClause
, wc
->partitionClause
, List
*);
3477 MUTATE(newnode
->orderClause
, wc
->orderClause
, List
*);
3478 MUTATE(newnode
->startOffset
, wc
->startOffset
, Node
*);
3479 MUTATE(newnode
->endOffset
, wc
->endOffset
, Node
*);
3480 return (Node
*) newnode
;
3483 case T_CTECycleClause
:
3485 CTECycleClause
*cc
= (CTECycleClause
*) node
;
3486 CTECycleClause
*newnode
;
3488 FLATCOPY(newnode
, cc
, CTECycleClause
);
3489 MUTATE(newnode
->cycle_mark_value
, cc
->cycle_mark_value
, Node
*);
3490 MUTATE(newnode
->cycle_mark_default
, cc
->cycle_mark_default
, Node
*);
3491 return (Node
*) newnode
;
3494 case T_CommonTableExpr
:
3496 CommonTableExpr
*cte
= (CommonTableExpr
*) node
;
3497 CommonTableExpr
*newnode
;
3499 FLATCOPY(newnode
, cte
, CommonTableExpr
);
3502 * Also invoke the mutator on the CTE's Query node, so it can
3503 * recurse into the sub-query if it wants to.
3505 MUTATE(newnode
->ctequery
, cte
->ctequery
, Node
*);
3507 MUTATE(newnode
->search_clause
, cte
->search_clause
, CTESearchClause
*);
3508 MUTATE(newnode
->cycle_clause
, cte
->cycle_clause
, CTECycleClause
*);
3510 return (Node
*) newnode
;
3513 case T_PartitionBoundSpec
:
3515 PartitionBoundSpec
*pbs
= (PartitionBoundSpec
*) node
;
3516 PartitionBoundSpec
*newnode
;
3518 FLATCOPY(newnode
, pbs
, PartitionBoundSpec
);
3519 MUTATE(newnode
->listdatums
, pbs
->listdatums
, List
*);
3520 MUTATE(newnode
->lowerdatums
, pbs
->lowerdatums
, List
*);
3521 MUTATE(newnode
->upperdatums
, pbs
->upperdatums
, List
*);
3522 return (Node
*) newnode
;
3525 case T_PartitionRangeDatum
:
3527 PartitionRangeDatum
*prd
= (PartitionRangeDatum
*) node
;
3528 PartitionRangeDatum
*newnode
;
3530 FLATCOPY(newnode
, prd
, PartitionRangeDatum
);
3531 MUTATE(newnode
->value
, prd
->value
, Node
*);
3532 return (Node
*) newnode
;
3538 * We assume the mutator isn't interested in the list nodes
3539 * per se, so just invoke it on each list element. NOTE: this
3540 * would fail badly on a list with integer elements!
3546 foreach(temp
, (List
*) node
)
3548 resultlist
= lappend(resultlist
,
3549 mutator((Node
*) lfirst(temp
),
3552 return (Node
*) resultlist
;
3557 FromExpr
*from
= (FromExpr
*) node
;
3560 FLATCOPY(newnode
, from
, FromExpr
);
3561 MUTATE(newnode
->fromlist
, from
->fromlist
, List
*);
3562 MUTATE(newnode
->quals
, from
->quals
, Node
*);
3563 return (Node
*) newnode
;
3566 case T_OnConflictExpr
:
3568 OnConflictExpr
*oc
= (OnConflictExpr
*) node
;
3569 OnConflictExpr
*newnode
;
3571 FLATCOPY(newnode
, oc
, OnConflictExpr
);
3572 MUTATE(newnode
->arbiterElems
, oc
->arbiterElems
, List
*);
3573 MUTATE(newnode
->arbiterWhere
, oc
->arbiterWhere
, Node
*);
3574 MUTATE(newnode
->onConflictSet
, oc
->onConflictSet
, List
*);
3575 MUTATE(newnode
->onConflictWhere
, oc
->onConflictWhere
, Node
*);
3576 MUTATE(newnode
->exclRelTlist
, oc
->exclRelTlist
, List
*);
3578 return (Node
*) newnode
;
3583 MergeAction
*action
= (MergeAction
*) node
;
3584 MergeAction
*newnode
;
3586 FLATCOPY(newnode
, action
, MergeAction
);
3587 MUTATE(newnode
->qual
, action
->qual
, Node
*);
3588 MUTATE(newnode
->targetList
, action
->targetList
, List
*);
3590 return (Node
*) newnode
;
3593 case T_PartitionPruneStepOp
:
3595 PartitionPruneStepOp
*opstep
= (PartitionPruneStepOp
*) node
;
3596 PartitionPruneStepOp
*newnode
;
3598 FLATCOPY(newnode
, opstep
, PartitionPruneStepOp
);
3599 MUTATE(newnode
->exprs
, opstep
->exprs
, List
*);
3601 return (Node
*) newnode
;
3604 case T_PartitionPruneStepCombine
:
3605 /* no expression sub-nodes */
3606 return copyObject(node
);
3609 JoinExpr
*join
= (JoinExpr
*) node
;
3612 FLATCOPY(newnode
, join
, JoinExpr
);
3613 MUTATE(newnode
->larg
, join
->larg
, Node
*);
3614 MUTATE(newnode
->rarg
, join
->rarg
, Node
*);
3615 MUTATE(newnode
->quals
, join
->quals
, Node
*);
3616 /* We do not mutate alias or using by default */
3617 return (Node
*) newnode
;
3620 case T_SetOperationStmt
:
3622 SetOperationStmt
*setop
= (SetOperationStmt
*) node
;
3623 SetOperationStmt
*newnode
;
3625 FLATCOPY(newnode
, setop
, SetOperationStmt
);
3626 MUTATE(newnode
->larg
, setop
->larg
, Node
*);
3627 MUTATE(newnode
->rarg
, setop
->rarg
, Node
*);
3628 /* We do not mutate groupClauses by default */
3629 return (Node
*) newnode
;
3634 IndexClause
*iclause
= (IndexClause
*) node
;
3635 IndexClause
*newnode
;
3637 FLATCOPY(newnode
, iclause
, IndexClause
);
3638 MUTATE(newnode
->rinfo
, iclause
->rinfo
, RestrictInfo
*);
3639 MUTATE(newnode
->indexquals
, iclause
->indexquals
, List
*);
3640 return (Node
*) newnode
;
3643 case T_PlaceHolderVar
:
3645 PlaceHolderVar
*phv
= (PlaceHolderVar
*) node
;
3646 PlaceHolderVar
*newnode
;
3648 FLATCOPY(newnode
, phv
, PlaceHolderVar
);
3649 MUTATE(newnode
->phexpr
, phv
->phexpr
, Expr
*);
3650 /* Assume we need not copy the relids bitmapsets */
3651 return (Node
*) newnode
;
3654 case T_InferenceElem
:
3656 InferenceElem
*inferenceelemdexpr
= (InferenceElem
*) node
;
3657 InferenceElem
*newnode
;
3659 FLATCOPY(newnode
, inferenceelemdexpr
, InferenceElem
);
3660 MUTATE(newnode
->expr
, newnode
->expr
, Node
*);
3661 return (Node
*) newnode
;
3664 case T_AppendRelInfo
:
3666 AppendRelInfo
*appinfo
= (AppendRelInfo
*) node
;
3667 AppendRelInfo
*newnode
;
3669 FLATCOPY(newnode
, appinfo
, AppendRelInfo
);
3670 MUTATE(newnode
->translated_vars
, appinfo
->translated_vars
, List
*);
3671 /* Assume nothing need be done with parent_colnos[] */
3672 return (Node
*) newnode
;
3675 case T_PlaceHolderInfo
:
3677 PlaceHolderInfo
*phinfo
= (PlaceHolderInfo
*) node
;
3678 PlaceHolderInfo
*newnode
;
3680 FLATCOPY(newnode
, phinfo
, PlaceHolderInfo
);
3681 MUTATE(newnode
->ph_var
, phinfo
->ph_var
, PlaceHolderVar
*);
3682 /* Assume we need not copy the relids bitmapsets */
3683 return (Node
*) newnode
;
3686 case T_RangeTblFunction
:
3688 RangeTblFunction
*rtfunc
= (RangeTblFunction
*) node
;
3689 RangeTblFunction
*newnode
;
3691 FLATCOPY(newnode
, rtfunc
, RangeTblFunction
);
3692 MUTATE(newnode
->funcexpr
, rtfunc
->funcexpr
, Node
*);
3693 /* Assume we need not copy the coldef info lists */
3694 return (Node
*) newnode
;
3697 case T_TableSampleClause
:
3699 TableSampleClause
*tsc
= (TableSampleClause
*) node
;
3700 TableSampleClause
*newnode
;
3702 FLATCOPY(newnode
, tsc
, TableSampleClause
);
3703 MUTATE(newnode
->args
, tsc
->args
, List
*);
3704 MUTATE(newnode
->repeatable
, tsc
->repeatable
, Expr
*);
3705 return (Node
*) newnode
;
3710 TableFunc
*tf
= (TableFunc
*) node
;
3713 FLATCOPY(newnode
, tf
, TableFunc
);
3714 MUTATE(newnode
->ns_uris
, tf
->ns_uris
, List
*);
3715 MUTATE(newnode
->docexpr
, tf
->docexpr
, Node
*);
3716 MUTATE(newnode
->rowexpr
, tf
->rowexpr
, Node
*);
3717 MUTATE(newnode
->colexprs
, tf
->colexprs
, List
*);
3718 MUTATE(newnode
->coldefexprs
, tf
->coldefexprs
, List
*);
3719 MUTATE(newnode
->colvalexprs
, tf
->colvalexprs
, List
*);
3720 MUTATE(newnode
->passingvalexprs
, tf
->passingvalexprs
, List
*);
3721 return (Node
*) newnode
;
3725 elog(ERROR
, "unrecognized node type: %d",
3726 (int) nodeTag(node
));
3729 /* can't get here, but keep compiler happy */
3735 * query_tree_mutator --- initiate modification of a Query's expressions
3737 * This routine exists just to reduce the number of places that need to know
3738 * where all the expression subtrees of a Query are. Note it can be used
3739 * for starting a walk at top level of a Query regardless of whether the
3740 * mutator intends to descend into subqueries. It is also useful for
3741 * descending into subqueries within a mutator.
3743 * Some callers want to suppress mutating of certain items in the Query,
3744 * typically because they need to process them specially, or don't actually
3745 * want to recurse into subqueries. This is supported by the flags argument,
3746 * which is the bitwise OR of flag values to suppress mutating of
3747 * indicated items. (More flag bits may be added as needed.)
3749 * Normally the top-level Query node itself is copied, but some callers want
3750 * it to be modified in-place; they must pass QTW_DONT_COPY_QUERY in flags.
3751 * All modified substructure is safely copied in any case.
3754 query_tree_mutator_impl(Query
*query
,
3755 tree_mutator_callback mutator
,
3759 Assert(query
!= NULL
&& IsA(query
, Query
));
3761 if (!(flags
& QTW_DONT_COPY_QUERY
))
3765 FLATCOPY(newquery
, query
, Query
);
3769 MUTATE(query
->targetList
, query
->targetList
, List
*);
3770 MUTATE(query
->withCheckOptions
, query
->withCheckOptions
, List
*);
3771 MUTATE(query
->onConflict
, query
->onConflict
, OnConflictExpr
*);
3772 MUTATE(query
->mergeActionList
, query
->mergeActionList
, List
*);
3773 MUTATE(query
->mergeJoinCondition
, query
->mergeJoinCondition
, Node
*);
3774 MUTATE(query
->returningList
, query
->returningList
, List
*);
3775 MUTATE(query
->jointree
, query
->jointree
, FromExpr
*);
3776 MUTATE(query
->setOperations
, query
->setOperations
, Node
*);
3777 MUTATE(query
->havingQual
, query
->havingQual
, Node
*);
3778 MUTATE(query
->limitOffset
, query
->limitOffset
, Node
*);
3779 MUTATE(query
->limitCount
, query
->limitCount
, Node
*);
3782 * Most callers aren't interested in SortGroupClause nodes since those
3783 * don't contain actual expressions. However they do contain OIDs, which
3784 * may be of interest to some mutators.
3787 if ((flags
& QTW_EXAMINE_SORTGROUP
))
3789 MUTATE(query
->groupClause
, query
->groupClause
, List
*);
3790 MUTATE(query
->windowClause
, query
->windowClause
, List
*);
3791 MUTATE(query
->sortClause
, query
->sortClause
, List
*);
3792 MUTATE(query
->distinctClause
, query
->distinctClause
, List
*);
3797 * But we need to mutate the expressions under WindowClause nodes even
3798 * if we're not interested in SortGroupClause nodes.
3804 foreach(temp
, query
->windowClause
)
3806 WindowClause
*wc
= lfirst_node(WindowClause
, temp
);
3807 WindowClause
*newnode
;
3809 FLATCOPY(newnode
, wc
, WindowClause
);
3810 MUTATE(newnode
->startOffset
, wc
->startOffset
, Node
*);
3811 MUTATE(newnode
->endOffset
, wc
->endOffset
, Node
*);
3813 resultlist
= lappend(resultlist
, (Node
*) newnode
);
3815 query
->windowClause
= resultlist
;
3819 * groupingSets and rowMarks are not mutated:
3821 * groupingSets contain only ressortgroup refs (integers) which are
3822 * meaningless without the groupClause or tlist. Accordingly, any mutator
3823 * that needs to care about them needs to handle them itself in its Query
3826 * rowMarks contains only rangetable indexes (and flags etc.) and
3827 * therefore should be handled at Query level similarly.
3830 if (!(flags
& QTW_IGNORE_CTE_SUBQUERIES
))
3831 MUTATE(query
->cteList
, query
->cteList
, List
*);
3832 else /* else copy CTE list as-is */
3833 query
->cteList
= copyObject(query
->cteList
);
3834 query
->rtable
= range_table_mutator(query
->rtable
,
3835 mutator
, context
, flags
);
3840 * range_table_mutator is just the part of query_tree_mutator that processes
3841 * a query's rangetable. This is split out since it can be useful on
3845 range_table_mutator_impl(List
*rtable
,
3846 tree_mutator_callback mutator
,
3855 RangeTblEntry
*rte
= (RangeTblEntry
*) lfirst(rt
);
3856 RangeTblEntry
*newrte
;
3858 FLATCOPY(newrte
, rte
, RangeTblEntry
);
3859 switch (rte
->rtekind
)
3862 MUTATE(newrte
->tablesample
, rte
->tablesample
,
3863 TableSampleClause
*);
3864 /* we don't bother to copy eref, aliases, etc; OK? */
3867 if (!(flags
& QTW_IGNORE_RT_SUBQUERIES
))
3868 MUTATE(newrte
->subquery
, rte
->subquery
, Query
*);
3871 /* else, copy RT subqueries as-is */
3872 newrte
->subquery
= copyObject(rte
->subquery
);
3876 if (!(flags
& QTW_IGNORE_JOINALIASES
))
3877 MUTATE(newrte
->joinaliasvars
, rte
->joinaliasvars
, List
*);
3880 /* else, copy join aliases as-is */
3881 newrte
->joinaliasvars
= copyObject(rte
->joinaliasvars
);
3885 MUTATE(newrte
->functions
, rte
->functions
, List
*);
3888 MUTATE(newrte
->tablefunc
, rte
->tablefunc
, TableFunc
*);
3891 MUTATE(newrte
->values_lists
, rte
->values_lists
, List
*);
3894 case RTE_NAMEDTUPLESTORE
:
3899 if (!(flags
& QTW_IGNORE_GROUPEXPRS
))
3900 MUTATE(newrte
->groupexprs
, rte
->groupexprs
, List
*);
3903 /* else, copy grouping exprs as-is */
3904 newrte
->groupexprs
= copyObject(rte
->groupexprs
);
3908 MUTATE(newrte
->securityQuals
, rte
->securityQuals
, List
*);
3909 newrt
= lappend(newrt
, newrte
);
3915 * query_or_expression_tree_walker --- hybrid form
3917 * This routine will invoke query_tree_walker if called on a Query node,
3918 * else will invoke the walker directly. This is a useful way of starting
3919 * the recursion when the walker's normal change of state is not appropriate
3920 * for the outermost Query node.
3923 query_or_expression_tree_walker_impl(Node
*node
,
3924 tree_walker_callback walker
,
3928 if (node
&& IsA(node
, Query
))
3929 return query_tree_walker((Query
*) node
,
3938 * query_or_expression_tree_mutator --- hybrid form
3940 * This routine will invoke query_tree_mutator if called on a Query node,
3941 * else will invoke the mutator directly. This is a useful way of starting
3942 * the recursion when the mutator's normal change of state is not appropriate
3943 * for the outermost Query node.
3946 query_or_expression_tree_mutator_impl(Node
*node
,
3947 tree_mutator_callback mutator
,
3951 if (node
&& IsA(node
, Query
))
3952 return (Node
*) query_tree_mutator((Query
*) node
,
3957 return mutator(node
, context
);
3962 * raw_expression_tree_walker --- walk raw parse trees
3964 * This has exactly the same API as expression_tree_walker, but instead of
3965 * walking post-analysis parse trees, it knows how to walk the node types
3966 * found in raw grammar output. (There is not currently any need for a
3967 * combined walker, so we keep them separate in the name of efficiency.)
3968 * Unlike expression_tree_walker, there is no special rule about query
3969 * boundaries: we descend to everything that's possibly interesting.
3971 * Currently, the node type coverage here extends only to DML statements
3972 * (SELECT/INSERT/UPDATE/DELETE/MERGE) and nodes that can appear in them,
3973 * because this is used mainly during analysis of CTEs, and only DML
3974 * statements can appear in CTEs.
3977 raw_expression_tree_walker_impl(Node
*node
,
3978 tree_walker_callback walker
,
3984 * The walker has already visited the current node, and so we need only
3985 * recurse into any sub-nodes it has.
3990 /* Guard against stack overflow due to overly complex expressions */
3991 check_stack_depth();
3993 switch (nodeTag(node
))
3996 case T_SetToDefault
:
3997 case T_CurrentOfExpr
:
3998 case T_SQLValueFunction
:
4007 case T_MergeSupportFunc
:
4008 /* primitive node types with no subnodes */
4011 /* we assume the colnames list isn't interesting */
4014 return WALK(((RangeVar
*) node
)->alias
);
4015 case T_GroupingFunc
:
4016 return WALK(((GroupingFunc
*) node
)->args
);
4019 SubLink
*sublink
= (SubLink
*) node
;
4021 if (WALK(sublink
->testexpr
))
4023 /* we assume the operName is not interesting */
4024 if (WALK(sublink
->subselect
))
4030 CaseExpr
*caseexpr
= (CaseExpr
*) node
;
4032 if (WALK(caseexpr
->arg
))
4034 /* we assume walker doesn't care about CaseWhens, either */
4035 foreach(temp
, caseexpr
->args
)
4037 CaseWhen
*when
= lfirst_node(CaseWhen
, temp
);
4039 if (WALK(when
->expr
))
4041 if (WALK(when
->result
))
4044 if (WALK(caseexpr
->defresult
))
4049 /* Assume colnames isn't interesting */
4050 return WALK(((RowExpr
*) node
)->args
);
4051 case T_CoalesceExpr
:
4052 return WALK(((CoalesceExpr
*) node
)->args
);
4054 return WALK(((MinMaxExpr
*) node
)->args
);
4057 XmlExpr
*xexpr
= (XmlExpr
*) node
;
4059 if (WALK(xexpr
->named_args
))
4061 /* we assume walker doesn't care about arg_names */
4062 if (WALK(xexpr
->args
))
4066 case T_JsonReturning
:
4067 return WALK(((JsonReturning
*) node
)->format
);
4068 case T_JsonValueExpr
:
4070 JsonValueExpr
*jve
= (JsonValueExpr
*) node
;
4072 if (WALK(jve
->raw_expr
))
4074 if (WALK(jve
->formatted_expr
))
4076 if (WALK(jve
->format
))
4080 case T_JsonParseExpr
:
4082 JsonParseExpr
*jpe
= (JsonParseExpr
*) node
;
4084 if (WALK(jpe
->expr
))
4086 if (WALK(jpe
->output
))
4090 case T_JsonScalarExpr
:
4092 JsonScalarExpr
*jse
= (JsonScalarExpr
*) node
;
4094 if (WALK(jse
->expr
))
4096 if (WALK(jse
->output
))
4100 case T_JsonSerializeExpr
:
4102 JsonSerializeExpr
*jse
= (JsonSerializeExpr
*) node
;
4104 if (WALK(jse
->expr
))
4106 if (WALK(jse
->output
))
4110 case T_JsonConstructorExpr
:
4112 JsonConstructorExpr
*ctor
= (JsonConstructorExpr
*) node
;
4114 if (WALK(ctor
->args
))
4116 if (WALK(ctor
->func
))
4118 if (WALK(ctor
->coercion
))
4120 if (WALK(ctor
->returning
))
4124 case T_JsonIsPredicate
:
4125 return WALK(((JsonIsPredicate
*) node
)->expr
);
4126 case T_JsonArgument
:
4127 return WALK(((JsonArgument
*) node
)->val
);
4128 case T_JsonFuncExpr
:
4130 JsonFuncExpr
*jfe
= (JsonFuncExpr
*) node
;
4132 if (WALK(jfe
->context_item
))
4134 if (WALK(jfe
->pathspec
))
4136 if (WALK(jfe
->passing
))
4138 if (WALK(jfe
->output
))
4140 if (WALK(jfe
->on_empty
))
4142 if (WALK(jfe
->on_error
))
4146 case T_JsonBehavior
:
4148 JsonBehavior
*jb
= (JsonBehavior
*) node
;
4156 JsonTable
*jt
= (JsonTable
*) node
;
4158 if (WALK(jt
->context_item
))
4160 if (WALK(jt
->pathspec
))
4162 if (WALK(jt
->passing
))
4164 if (WALK(jt
->columns
))
4166 if (WALK(jt
->on_error
))
4170 case T_JsonTableColumn
:
4172 JsonTableColumn
*jtc
= (JsonTableColumn
*) node
;
4174 if (WALK(jtc
->typeName
))
4176 if (WALK(jtc
->on_empty
))
4178 if (WALK(jtc
->on_error
))
4180 if (WALK(jtc
->columns
))
4184 case T_JsonTablePathSpec
:
4185 return WALK(((JsonTablePathSpec
*) node
)->string
);
4187 return WALK(((NullTest
*) node
)->arg
);
4189 return WALK(((BooleanTest
*) node
)->arg
);
4192 JoinExpr
*join
= (JoinExpr
*) node
;
4194 if (WALK(join
->larg
))
4196 if (WALK(join
->rarg
))
4198 if (WALK(join
->quals
))
4200 if (WALK(join
->alias
))
4202 /* using list is deemed uninteresting */
4207 IntoClause
*into
= (IntoClause
*) node
;
4209 if (WALK(into
->rel
))
4211 /* colNames, options are deemed uninteresting */
4212 /* viewQuery should be null in raw parsetree, but check it */
4213 if (WALK(into
->viewQuery
))
4218 foreach(temp
, (List
*) node
)
4220 if (WALK((Node
*) lfirst(temp
)))
4226 InsertStmt
*stmt
= (InsertStmt
*) node
;
4228 if (WALK(stmt
->relation
))
4230 if (WALK(stmt
->cols
))
4232 if (WALK(stmt
->selectStmt
))
4234 if (WALK(stmt
->onConflictClause
))
4236 if (WALK(stmt
->returningList
))
4238 if (WALK(stmt
->withClause
))
4244 DeleteStmt
*stmt
= (DeleteStmt
*) node
;
4246 if (WALK(stmt
->relation
))
4248 if (WALK(stmt
->usingClause
))
4250 if (WALK(stmt
->whereClause
))
4252 if (WALK(stmt
->returningList
))
4254 if (WALK(stmt
->withClause
))
4260 UpdateStmt
*stmt
= (UpdateStmt
*) node
;
4262 if (WALK(stmt
->relation
))
4264 if (WALK(stmt
->targetList
))
4266 if (WALK(stmt
->whereClause
))
4268 if (WALK(stmt
->fromClause
))
4270 if (WALK(stmt
->returningList
))
4272 if (WALK(stmt
->withClause
))
4278 MergeStmt
*stmt
= (MergeStmt
*) node
;
4280 if (WALK(stmt
->relation
))
4282 if (WALK(stmt
->sourceRelation
))
4284 if (WALK(stmt
->joinCondition
))
4286 if (WALK(stmt
->mergeWhenClauses
))
4288 if (WALK(stmt
->returningList
))
4290 if (WALK(stmt
->withClause
))
4294 case T_MergeWhenClause
:
4296 MergeWhenClause
*mergeWhenClause
= (MergeWhenClause
*) node
;
4298 if (WALK(mergeWhenClause
->condition
))
4300 if (WALK(mergeWhenClause
->targetList
))
4302 if (WALK(mergeWhenClause
->values
))
4308 SelectStmt
*stmt
= (SelectStmt
*) node
;
4310 if (WALK(stmt
->distinctClause
))
4312 if (WALK(stmt
->intoClause
))
4314 if (WALK(stmt
->targetList
))
4316 if (WALK(stmt
->fromClause
))
4318 if (WALK(stmt
->whereClause
))
4320 if (WALK(stmt
->groupClause
))
4322 if (WALK(stmt
->havingClause
))
4324 if (WALK(stmt
->windowClause
))
4326 if (WALK(stmt
->valuesLists
))
4328 if (WALK(stmt
->sortClause
))
4330 if (WALK(stmt
->limitOffset
))
4332 if (WALK(stmt
->limitCount
))
4334 if (WALK(stmt
->lockingClause
))
4336 if (WALK(stmt
->withClause
))
4338 if (WALK(stmt
->larg
))
4340 if (WALK(stmt
->rarg
))
4344 case T_PLAssignStmt
:
4346 PLAssignStmt
*stmt
= (PLAssignStmt
*) node
;
4348 if (WALK(stmt
->indirection
))
4350 if (WALK(stmt
->val
))
4356 A_Expr
*expr
= (A_Expr
*) node
;
4358 if (WALK(expr
->lexpr
))
4360 if (WALK(expr
->rexpr
))
4362 /* operator name is deemed uninteresting */
4367 BoolExpr
*expr
= (BoolExpr
*) node
;
4369 if (WALK(expr
->args
))
4374 /* we assume the fields contain nothing interesting */
4378 FuncCall
*fcall
= (FuncCall
*) node
;
4380 if (WALK(fcall
->args
))
4382 if (WALK(fcall
->agg_order
))
4384 if (WALK(fcall
->agg_filter
))
4386 if (WALK(fcall
->over
))
4388 /* function name is deemed uninteresting */
4391 case T_NamedArgExpr
:
4392 return WALK(((NamedArgExpr
*) node
)->arg
);
4395 A_Indices
*indices
= (A_Indices
*) node
;
4397 if (WALK(indices
->lidx
))
4399 if (WALK(indices
->uidx
))
4403 case T_A_Indirection
:
4405 A_Indirection
*indir
= (A_Indirection
*) node
;
4407 if (WALK(indir
->arg
))
4409 if (WALK(indir
->indirection
))
4414 return WALK(((A_ArrayExpr
*) node
)->elements
);
4417 ResTarget
*rt
= (ResTarget
*) node
;
4419 if (WALK(rt
->indirection
))
4425 case T_MultiAssignRef
:
4426 return WALK(((MultiAssignRef
*) node
)->source
);
4429 TypeCast
*tc
= (TypeCast
*) node
;
4433 if (WALK(tc
->typeName
))
4437 case T_CollateClause
:
4438 return WALK(((CollateClause
*) node
)->arg
);
4440 return WALK(((SortBy
*) node
)->node
);
4443 WindowDef
*wd
= (WindowDef
*) node
;
4445 if (WALK(wd
->partitionClause
))
4447 if (WALK(wd
->orderClause
))
4449 if (WALK(wd
->startOffset
))
4451 if (WALK(wd
->endOffset
))
4455 case T_RangeSubselect
:
4457 RangeSubselect
*rs
= (RangeSubselect
*) node
;
4459 if (WALK(rs
->subquery
))
4461 if (WALK(rs
->alias
))
4465 case T_RangeFunction
:
4467 RangeFunction
*rf
= (RangeFunction
*) node
;
4469 if (WALK(rf
->functions
))
4471 if (WALK(rf
->alias
))
4473 if (WALK(rf
->coldeflist
))
4477 case T_RangeTableSample
:
4479 RangeTableSample
*rts
= (RangeTableSample
*) node
;
4481 if (WALK(rts
->relation
))
4483 /* method name is deemed uninteresting */
4484 if (WALK(rts
->args
))
4486 if (WALK(rts
->repeatable
))
4490 case T_RangeTableFunc
:
4492 RangeTableFunc
*rtf
= (RangeTableFunc
*) node
;
4494 if (WALK(rtf
->docexpr
))
4496 if (WALK(rtf
->rowexpr
))
4498 if (WALK(rtf
->namespaces
))
4500 if (WALK(rtf
->columns
))
4502 if (WALK(rtf
->alias
))
4506 case T_RangeTableFuncCol
:
4508 RangeTableFuncCol
*rtfc
= (RangeTableFuncCol
*) node
;
4510 if (WALK(rtfc
->colexpr
))
4512 if (WALK(rtfc
->coldefexpr
))
4518 TypeName
*tn
= (TypeName
*) node
;
4520 if (WALK(tn
->typmods
))
4522 if (WALK(tn
->arrayBounds
))
4524 /* type name itself is deemed uninteresting */
4529 ColumnDef
*coldef
= (ColumnDef
*) node
;
4531 if (WALK(coldef
->typeName
))
4533 if (WALK(coldef
->raw_default
))
4535 if (WALK(coldef
->collClause
))
4537 /* for now, constraints are ignored */
4542 IndexElem
*indelem
= (IndexElem
*) node
;
4544 if (WALK(indelem
->expr
))
4546 /* collation and opclass names are deemed uninteresting */
4550 return WALK(((GroupingSet
*) node
)->content
);
4551 case T_LockingClause
:
4552 return WALK(((LockingClause
*) node
)->lockedRels
);
4553 case T_XmlSerialize
:
4555 XmlSerialize
*xs
= (XmlSerialize
*) node
;
4559 if (WALK(xs
->typeName
))
4564 return WALK(((WithClause
*) node
)->ctes
);
4567 InferClause
*stmt
= (InferClause
*) node
;
4569 if (WALK(stmt
->indexElems
))
4571 if (WALK(stmt
->whereClause
))
4575 case T_OnConflictClause
:
4577 OnConflictClause
*stmt
= (OnConflictClause
*) node
;
4579 if (WALK(stmt
->infer
))
4581 if (WALK(stmt
->targetList
))
4583 if (WALK(stmt
->whereClause
))
4587 case T_CommonTableExpr
:
4588 /* search_clause and cycle_clause are not interesting here */
4589 return WALK(((CommonTableExpr
*) node
)->ctequery
);
4592 JsonOutput
*out
= (JsonOutput
*) node
;
4594 if (WALK(out
->typeName
))
4596 if (WALK(out
->returning
))
4600 case T_JsonKeyValue
:
4602 JsonKeyValue
*jkv
= (JsonKeyValue
*) node
;
4606 if (WALK(jkv
->value
))
4610 case T_JsonObjectConstructor
:
4612 JsonObjectConstructor
*joc
= (JsonObjectConstructor
*) node
;
4614 if (WALK(joc
->output
))
4616 if (WALK(joc
->exprs
))
4620 case T_JsonArrayConstructor
:
4622 JsonArrayConstructor
*jac
= (JsonArrayConstructor
*) node
;
4624 if (WALK(jac
->output
))
4626 if (WALK(jac
->exprs
))
4630 case T_JsonAggConstructor
:
4632 JsonAggConstructor
*ctor
= (JsonAggConstructor
*) node
;
4634 if (WALK(ctor
->output
))
4636 if (WALK(ctor
->agg_order
))
4638 if (WALK(ctor
->agg_filter
))
4640 if (WALK(ctor
->over
))
4644 case T_JsonObjectAgg
:
4646 JsonObjectAgg
*joa
= (JsonObjectAgg
*) node
;
4648 if (WALK(joa
->constructor
))
4654 case T_JsonArrayAgg
:
4656 JsonArrayAgg
*jaa
= (JsonArrayAgg
*) node
;
4658 if (WALK(jaa
->constructor
))
4664 case T_JsonArrayQueryConstructor
:
4666 JsonArrayQueryConstructor
*jaqc
= (JsonArrayQueryConstructor
*) node
;
4668 if (WALK(jaqc
->output
))
4670 if (WALK(jaqc
->query
))
4675 elog(ERROR
, "unrecognized node type: %d",
4676 (int) nodeTag(node
));
4683 * planstate_tree_walker --- walk plan state trees
4685 * The walker has already visited the current node, and so we need only
4686 * recurse into any sub-nodes it has.
4689 planstate_tree_walker_impl(PlanState
*planstate
,
4690 planstate_tree_walker_callback walker
,
4693 Plan
*plan
= planstate
->plan
;
4696 /* We don't need implicit coercions to Node here */
4697 #define PSWALK(n) walker(n, context)
4699 /* Guard against stack overflow due to overly complex plan trees */
4700 check_stack_depth();
4703 if (planstate_walk_subplans(planstate
->initPlan
, walker
, context
))
4707 if (outerPlanState(planstate
))
4709 if (PSWALK(outerPlanState(planstate
)))
4714 if (innerPlanState(planstate
))
4716 if (PSWALK(innerPlanState(planstate
)))
4720 /* special child plans */
4721 switch (nodeTag(plan
))
4724 if (planstate_walk_members(((AppendState
*) planstate
)->appendplans
,
4725 ((AppendState
*) planstate
)->as_nplans
,
4730 if (planstate_walk_members(((MergeAppendState
*) planstate
)->mergeplans
,
4731 ((MergeAppendState
*) planstate
)->ms_nplans
,
4736 if (planstate_walk_members(((BitmapAndState
*) planstate
)->bitmapplans
,
4737 ((BitmapAndState
*) planstate
)->nplans
,
4742 if (planstate_walk_members(((BitmapOrState
*) planstate
)->bitmapplans
,
4743 ((BitmapOrState
*) planstate
)->nplans
,
4747 case T_SubqueryScan
:
4748 if (PSWALK(((SubqueryScanState
*) planstate
)->subplan
))
4752 foreach(lc
, ((CustomScanState
*) planstate
)->custom_ps
)
4754 if (PSWALK(lfirst(lc
)))
4763 if (planstate_walk_subplans(planstate
->subPlan
, walker
, context
))
4770 * Walk a list of SubPlans (or initPlans, which also use SubPlan nodes).
4773 planstate_walk_subplans(List
*plans
,
4774 planstate_tree_walker_callback walker
,
4781 SubPlanState
*sps
= lfirst_node(SubPlanState
, lc
);
4783 if (PSWALK(sps
->planstate
))
4791 * Walk the constituent plans of a ModifyTable, Append, MergeAppend,
4792 * BitmapAnd, or BitmapOr node.
4795 planstate_walk_members(PlanState
**planstates
, int nplans
,
4796 planstate_tree_walker_callback walker
,
4801 for (j
= 0; j
< nplans
; j
++)
4803 if (PSWALK(planstates
[j
]))