PostgreSQL Source Code git master
nodeFuncs.h File Reference
#include "nodes/parsenodes.h"
Include dependency graph for nodeFuncs.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define QTW_IGNORE_RT_SUBQUERIES   0x01 /* subqueries in rtable */
 
#define QTW_IGNORE_CTE_SUBQUERIES   0x02 /* subqueries in cteList */
 
#define QTW_IGNORE_RC_SUBQUERIES   0x03 /* both of above */
 
#define QTW_IGNORE_JOINALIASES   0x04 /* JOIN alias var lists */
 
#define QTW_IGNORE_RANGE_TABLE   0x08 /* skip rangetable entirely */
 
#define QTW_EXAMINE_RTES_BEFORE
 
#define QTW_EXAMINE_RTES_AFTER
 
#define QTW_DONT_COPY_QUERY   0x40 /* do not copy top Query */
 
#define QTW_EXAMINE_SORTGROUP   0x80 /* include SortGroupClause lists */
 
#define QTW_IGNORE_GROUPEXPRS   0x100 /* GROUP expressions list */
 
#define expression_tree_walker(n, w, c)    expression_tree_walker_impl(n, (tree_walker_callback) (w), c)
 
#define expression_tree_mutator(n, m, c)    expression_tree_mutator_impl(n, (tree_mutator_callback) (m), c)
 
#define query_tree_walker(q, w, c, f)    query_tree_walker_impl(q, (tree_walker_callback) (w), c, f)
 
#define query_tree_mutator(q, m, c, f)    query_tree_mutator_impl(q, (tree_mutator_callback) (m), c, f)
 
#define range_table_walker(rt, w, c, f)    range_table_walker_impl(rt, (tree_walker_callback) (w), c, f)
 
#define range_table_mutator(rt, m, c, f)    range_table_mutator_impl(rt, (tree_mutator_callback) (m), c, f)
 
#define range_table_entry_walker(r, w, c, f)    range_table_entry_walker_impl(r, (tree_walker_callback) (w), c, f)
 
#define query_or_expression_tree_walker(n, w, c, f)    query_or_expression_tree_walker_impl(n, (tree_walker_callback) (w), c, f)
 
#define query_or_expression_tree_mutator(n, m, c, f)    query_or_expression_tree_mutator_impl(n, (tree_mutator_callback) (m), c, f)
 
#define raw_expression_tree_walker(n, w, c)    raw_expression_tree_walker_impl(n, (tree_walker_callback) (w), c)
 
#define planstate_tree_walker(ps, w, c)    planstate_tree_walker_impl(ps, (planstate_tree_walker_callback) (w), c)
 

Typedefs

typedef bool(* check_function_callback) (Oid func_id, void *context)
 
typedef bool(* tree_walker_callback) (Node *node, void *context)
 
typedef bool(* planstate_tree_walker_callback) (struct PlanState *planstate, void *context)
 
typedef Node *(* tree_mutator_callback) (Node *node, void *context)
 

Functions

Oid exprType (const Node *expr)
 
int32 exprTypmod (const Node *expr)
 
bool exprIsLengthCoercion (const Node *expr, int32 *coercedTypmod)
 
NodeapplyRelabelType (Node *arg, Oid rtype, int32 rtypmod, Oid rcollid, CoercionForm rformat, int rlocation, bool overwrite_ok)
 
Noderelabel_to_typmod (Node *expr, int32 typmod)
 
Nodestrip_implicit_coercions (Node *node)
 
bool expression_returns_set (Node *clause)
 
Oid exprCollation (const Node *expr)
 
Oid exprInputCollation (const Node *expr)
 
void exprSetCollation (Node *expr, Oid collation)
 
void exprSetInputCollation (Node *expr, Oid inputcollation)
 
int exprLocation (const Node *expr)
 
void fix_opfuncids (Node *node)
 
void set_opfuncid (OpExpr *opexpr)
 
void set_sa_opfuncid (ScalarArrayOpExpr *opexpr)
 
static bool is_funcclause (const void *clause)
 
static bool is_opclause (const void *clause)
 
static Nodeget_leftop (const void *clause)
 
static Nodeget_rightop (const void *clause)
 
static bool is_andclause (const void *clause)
 
static bool is_orclause (const void *clause)
 
static bool is_notclause (const void *clause)
 
static Exprget_notclausearg (const void *notclause)
 
bool check_functions_in_node (Node *node, check_function_callback checker, void *context)
 
bool expression_tree_walker_impl (Node *node, tree_walker_callback walker, void *context)
 
Nodeexpression_tree_mutator_impl (Node *node, tree_mutator_callback mutator, void *context)
 
bool query_tree_walker_impl (Query *query, tree_walker_callback walker, void *context, int flags)
 
Queryquery_tree_mutator_impl (Query *query, tree_mutator_callback mutator, void *context, int flags)
 
bool range_table_walker_impl (List *rtable, tree_walker_callback walker, void *context, int flags)
 
Listrange_table_mutator_impl (List *rtable, tree_mutator_callback mutator, void *context, int flags)
 
bool range_table_entry_walker_impl (RangeTblEntry *rte, tree_walker_callback walker, void *context, int flags)
 
bool query_or_expression_tree_walker_impl (Node *node, tree_walker_callback walker, void *context, int flags)
 
Nodequery_or_expression_tree_mutator_impl (Node *node, tree_mutator_callback mutator, void *context, int flags)
 
bool raw_expression_tree_walker_impl (Node *node, tree_walker_callback walker, void *context)
 
bool planstate_tree_walker_impl (struct PlanState *planstate, planstate_tree_walker_callback walker, void *context)
 

Macro Definition Documentation

◆ expression_tree_mutator

#define expression_tree_mutator (   n,
  m,
  c 
)     expression_tree_mutator_impl(n, (tree_mutator_callback) (m), c)

Definition at line 155 of file nodeFuncs.h.

◆ expression_tree_walker

#define expression_tree_walker (   n,
  w,
  c 
)     expression_tree_walker_impl(n, (tree_walker_callback) (w), c)

Definition at line 153 of file nodeFuncs.h.

◆ planstate_tree_walker

#define planstate_tree_walker (   ps,
  w,
  c 
)     planstate_tree_walker_impl(ps, (planstate_tree_walker_callback) (w), c)

Definition at line 179 of file nodeFuncs.h.

◆ QTW_DONT_COPY_QUERY

#define QTW_DONT_COPY_QUERY   0x40 /* do not copy top Query */

Definition at line 29 of file nodeFuncs.h.

◆ QTW_EXAMINE_RTES_AFTER

#define QTW_EXAMINE_RTES_AFTER
Value:
0x20 /* examine RTE nodes after their
* contents */

Definition at line 28 of file nodeFuncs.h.

◆ QTW_EXAMINE_RTES_BEFORE

#define QTW_EXAMINE_RTES_BEFORE
Value:
0x10 /* examine RTE nodes before their
* contents */

Definition at line 27 of file nodeFuncs.h.

◆ QTW_EXAMINE_SORTGROUP

#define QTW_EXAMINE_SORTGROUP   0x80 /* include SortGroupClause lists */

Definition at line 30 of file nodeFuncs.h.

◆ QTW_IGNORE_CTE_SUBQUERIES

#define QTW_IGNORE_CTE_SUBQUERIES   0x02 /* subqueries in cteList */

Definition at line 23 of file nodeFuncs.h.

◆ QTW_IGNORE_GROUPEXPRS

#define QTW_IGNORE_GROUPEXPRS   0x100 /* GROUP expressions list */

Definition at line 32 of file nodeFuncs.h.

◆ QTW_IGNORE_JOINALIASES

#define QTW_IGNORE_JOINALIASES   0x04 /* JOIN alias var lists */

Definition at line 25 of file nodeFuncs.h.

◆ QTW_IGNORE_RANGE_TABLE

#define QTW_IGNORE_RANGE_TABLE   0x08 /* skip rangetable entirely */

Definition at line 26 of file nodeFuncs.h.

◆ QTW_IGNORE_RC_SUBQUERIES

#define QTW_IGNORE_RC_SUBQUERIES   0x03 /* both of above */

Definition at line 24 of file nodeFuncs.h.

◆ QTW_IGNORE_RT_SUBQUERIES

#define QTW_IGNORE_RT_SUBQUERIES   0x01 /* subqueries in rtable */

Definition at line 22 of file nodeFuncs.h.

◆ query_or_expression_tree_mutator

#define query_or_expression_tree_mutator (   n,
  m,
  c,
 
)     query_or_expression_tree_mutator_impl(n, (tree_mutator_callback) (m), c, f)

Definition at line 173 of file nodeFuncs.h.

◆ query_or_expression_tree_walker

#define query_or_expression_tree_walker (   n,
  w,
  c,
 
)     query_or_expression_tree_walker_impl(n, (tree_walker_callback) (w), c, f)

Definition at line 171 of file nodeFuncs.h.

◆ query_tree_mutator

#define query_tree_mutator (   q,
  m,
  c,
 
)     query_tree_mutator_impl(q, (tree_mutator_callback) (m), c, f)

Definition at line 160 of file nodeFuncs.h.

◆ query_tree_walker

#define query_tree_walker (   q,
  w,
  c,
 
)     query_tree_walker_impl(q, (tree_walker_callback) (w), c, f)

Definition at line 158 of file nodeFuncs.h.

◆ range_table_entry_walker

#define range_table_entry_walker (   r,
  w,
  c,
 
)     range_table_entry_walker_impl(r, (tree_walker_callback) (w), c, f)

Definition at line 168 of file nodeFuncs.h.

◆ range_table_mutator

#define range_table_mutator (   rt,
  m,
  c,
 
)     range_table_mutator_impl(rt, (tree_mutator_callback) (m), c, f)

Definition at line 165 of file nodeFuncs.h.

◆ range_table_walker

#define range_table_walker (   rt,
  w,
  c,
 
)     range_table_walker_impl(rt, (tree_walker_callback) (w), c, f)

Definition at line 163 of file nodeFuncs.h.

◆ raw_expression_tree_walker

#define raw_expression_tree_walker (   n,
  w,
  c 
)     raw_expression_tree_walker_impl(n, (tree_walker_callback) (w), c)

Definition at line 176 of file nodeFuncs.h.

Typedef Documentation

◆ check_function_callback

typedef bool(* check_function_callback) (Oid func_id, void *context)

Definition at line 35 of file nodeFuncs.h.

◆ planstate_tree_walker_callback

typedef bool(* planstate_tree_walker_callback) (struct PlanState *planstate, void *context)

Definition at line 39 of file nodeFuncs.h.

◆ tree_mutator_callback

typedef Node *(* tree_mutator_callback) (Node *node, void *context)

Definition at line 43 of file nodeFuncs.h.

◆ tree_walker_callback

typedef bool(* tree_walker_callback) (Node *node, void *context)

Definition at line 38 of file nodeFuncs.h.

Function Documentation

◆ applyRelabelType()

Node * applyRelabelType ( Node arg,
Oid  rtype,
int32  rtypmod,
Oid  rcollid,
CoercionForm  rformat,
int  rlocation,
bool  overwrite_ok 
)

Definition at line 636 of file nodeFuncs.c.

638{
639 /*
640 * If we find stacked RelabelTypes (eg, from foo::int::oid) we can discard
641 * all but the top one, and must do so to ensure that semantically
642 * equivalent expressions are equal().
643 */
644 while (arg && IsA(arg, RelabelType))
645 arg = (Node *) ((RelabelType *) arg)->arg;
646
647 if (arg && IsA(arg, Const))
648 {
649 /* Modify the Const directly to preserve const-flatness. */
650 Const *con = (Const *) arg;
651
652 if (!overwrite_ok)
653 con = copyObject(con);
654 con->consttype = rtype;
655 con->consttypmod = rtypmod;
656 con->constcollid = rcollid;
657 /* We keep the Const's original location. */
658 return (Node *) con;
659 }
660 else if (exprType(arg) == rtype &&
661 exprTypmod(arg) == rtypmod &&
662 exprCollation(arg) == rcollid)
663 {
664 /* Sometimes we find a nest of relabels that net out to nothing. */
665 return arg;
666 }
667 else
668 {
669 /* Nope, gotta have a RelabelType. */
670 RelabelType *newrelabel = makeNode(RelabelType);
671
672 newrelabel->arg = (Expr *) arg;
673 newrelabel->resulttype = rtype;
674 newrelabel->resulttypmod = rtypmod;
675 newrelabel->resultcollid = rcollid;
676 newrelabel->relabelformat = rformat;
677 newrelabel->location = rlocation;
678 return (Node *) newrelabel;
679 }
680}
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
int32 exprTypmod(const Node *expr)
Definition: nodeFuncs.c:301
Oid exprCollation(const Node *expr)
Definition: nodeFuncs.c:821
#define IsA(nodeptr, _type_)
Definition: nodes.h:158
#define copyObject(obj)
Definition: nodes.h:224
#define makeNode(_type_)
Definition: nodes.h:155
void * arg
Oid consttype
Definition: primnodes.h:328
Definition: nodes.h:129
Oid resulttype
Definition: primnodes.h:1201
ParseLoc location
Definition: primnodes.h:1208
Expr * arg
Definition: primnodes.h:1200

References arg, RelabelType::arg, Const::consttype, copyObject, exprCollation(), exprType(), exprTypmod(), IsA, RelabelType::location, makeNode, and RelabelType::resulttype.

Referenced by canonicalize_ec_expression(), coerce_type_typmod(), eval_const_expressions_mutator(), generate_setop_tlist(), and relabel_to_typmod().

◆ check_functions_in_node()

bool check_functions_in_node ( Node node,
check_function_callback  checker,
void *  context 
)

Definition at line 1910 of file nodeFuncs.c.

1912{
1913 switch (nodeTag(node))
1914 {
1915 case T_Aggref:
1916 {
1917 Aggref *expr = (Aggref *) node;
1918
1919 if (checker(expr->aggfnoid, context))
1920 return true;
1921 }
1922 break;
1923 case T_WindowFunc:
1924 {
1925 WindowFunc *expr = (WindowFunc *) node;
1926
1927 if (checker(expr->winfnoid, context))
1928 return true;
1929 }
1930 break;
1931 case T_FuncExpr:
1932 {
1933 FuncExpr *expr = (FuncExpr *) node;
1934
1935 if (checker(expr->funcid, context))
1936 return true;
1937 }
1938 break;
1939 case T_OpExpr:
1940 case T_DistinctExpr: /* struct-equivalent to OpExpr */
1941 case T_NullIfExpr: /* struct-equivalent to OpExpr */
1942 {
1943 OpExpr *expr = (OpExpr *) node;
1944
1945 /* Set opfuncid if it wasn't set already */
1946 set_opfuncid(expr);
1947 if (checker(expr->opfuncid, context))
1948 return true;
1949 }
1950 break;
1951 case T_ScalarArrayOpExpr:
1952 {
1953 ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
1954
1955 set_sa_opfuncid(expr);
1956 if (checker(expr->opfuncid, context))
1957 return true;
1958 }
1959 break;
1960 case T_CoerceViaIO:
1961 {
1962 CoerceViaIO *expr = (CoerceViaIO *) node;
1963 Oid iofunc;
1964 Oid typioparam;
1965 bool typisvarlena;
1966
1967 /* check the result type's input function */
1969 &iofunc, &typioparam);
1970 if (checker(iofunc, context))
1971 return true;
1972 /* check the input type's output function */
1974 &iofunc, &typisvarlena);
1975 if (checker(iofunc, context))
1976 return true;
1977 }
1978 break;
1979 case T_RowCompareExpr:
1980 {
1981 RowCompareExpr *rcexpr = (RowCompareExpr *) node;
1982 ListCell *opid;
1983
1984 foreach(opid, rcexpr->opnos)
1985 {
1986 Oid opfuncid = get_opcode(lfirst_oid(opid));
1987
1988 if (checker(opfuncid, context))
1989 return true;
1990 }
1991 }
1992 break;
1993 default:
1994 break;
1995 }
1996 return false;
1997}
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2907
RegProcedure get_opcode(Oid opno)
Definition: lsyscache.c:1285
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
Definition: lsyscache.c:2874
void set_sa_opfuncid(ScalarArrayOpExpr *opexpr)
Definition: nodeFuncs.c:1883
void set_opfuncid(OpExpr *opexpr)
Definition: nodeFuncs.c:1872
#define nodeTag(nodeptr)
Definition: nodes.h:133
#define lfirst_oid(lc)
Definition: pg_list.h:174
unsigned int Oid
Definition: postgres_ext.h:32
Oid aggfnoid
Definition: primnodes.h:460
Expr * arg
Definition: primnodes.h:1223
Oid resulttype
Definition: primnodes.h:1224
Oid funcid
Definition: primnodes.h:766
Oid winfnoid
Definition: primnodes.h:583

References Aggref::aggfnoid, CoerceViaIO::arg, exprType(), FuncExpr::funcid, get_opcode(), getTypeInputInfo(), getTypeOutputInfo(), lfirst_oid, nodeTag, CoerceViaIO::resulttype, set_opfuncid(), set_sa_opfuncid(), and WindowFunc::winfnoid.

Referenced by check_simple_rowfilter_expr_walker(), contain_leaked_vars_walker(), contain_mutable_functions_walker(), contain_nonstrict_functions_walker(), contain_volatile_functions_not_nextval_walker(), contain_volatile_functions_walker(), and max_parallel_hazard_walker().

◆ exprCollation()

Oid exprCollation ( const Node expr)

Definition at line 821 of file nodeFuncs.c.

822{
823 Oid coll;
824
825 if (!expr)
826 return InvalidOid;
827
828 switch (nodeTag(expr))
829 {
830 case T_Var:
831 coll = ((const Var *) expr)->varcollid;
832 break;
833 case T_Const:
834 coll = ((const Const *) expr)->constcollid;
835 break;
836 case T_Param:
837 coll = ((const Param *) expr)->paramcollid;
838 break;
839 case T_Aggref:
840 coll = ((const Aggref *) expr)->aggcollid;
841 break;
842 case T_GroupingFunc:
843 coll = InvalidOid;
844 break;
845 case T_WindowFunc:
846 coll = ((const WindowFunc *) expr)->wincollid;
847 break;
848 case T_MergeSupportFunc:
849 coll = ((const MergeSupportFunc *) expr)->msfcollid;
850 break;
851 case T_SubscriptingRef:
852 coll = ((const SubscriptingRef *) expr)->refcollid;
853 break;
854 case T_FuncExpr:
855 coll = ((const FuncExpr *) expr)->funccollid;
856 break;
857 case T_NamedArgExpr:
858 coll = exprCollation((Node *) ((const NamedArgExpr *) expr)->arg);
859 break;
860 case T_OpExpr:
861 coll = ((const OpExpr *) expr)->opcollid;
862 break;
863 case T_DistinctExpr:
864 coll = ((const DistinctExpr *) expr)->opcollid;
865 break;
866 case T_NullIfExpr:
867 coll = ((const NullIfExpr *) expr)->opcollid;
868 break;
869 case T_ScalarArrayOpExpr:
870 /* ScalarArrayOpExpr's result is boolean ... */
871 coll = InvalidOid; /* ... so it has no collation */
872 break;
873 case T_BoolExpr:
874 /* BoolExpr's result is boolean ... */
875 coll = InvalidOid; /* ... so it has no collation */
876 break;
877 case T_SubLink:
878 {
879 const SubLink *sublink = (const SubLink *) expr;
880
881 if (sublink->subLinkType == EXPR_SUBLINK ||
882 sublink->subLinkType == ARRAY_SUBLINK)
883 {
884 /* get the collation of subselect's first target column */
885 Query *qtree = (Query *) sublink->subselect;
886 TargetEntry *tent;
887
888 if (!qtree || !IsA(qtree, Query))
889 elog(ERROR, "cannot get collation for untransformed sublink");
890 tent = linitial_node(TargetEntry, qtree->targetList);
891 Assert(!tent->resjunk);
892 coll = exprCollation((Node *) tent->expr);
893 /* collation doesn't change if it's converted to array */
894 }
895 else
896 {
897 /* otherwise, SubLink's result is RECORD or BOOLEAN */
898 coll = InvalidOid; /* ... so it has no collation */
899 }
900 }
901 break;
902 case T_SubPlan:
903 {
904 const SubPlan *subplan = (const SubPlan *) expr;
905
906 if (subplan->subLinkType == EXPR_SUBLINK ||
907 subplan->subLinkType == ARRAY_SUBLINK)
908 {
909 /* get the collation of subselect's first target column */
910 coll = subplan->firstColCollation;
911 /* collation doesn't change if it's converted to array */
912 }
913 else
914 {
915 /* otherwise, SubPlan's result is RECORD or BOOLEAN */
916 coll = InvalidOid; /* ... so it has no collation */
917 }
918 }
919 break;
920 case T_AlternativeSubPlan:
921 {
922 const AlternativeSubPlan *asplan = (const AlternativeSubPlan *) expr;
923
924 /* subplans should all return the same thing */
925 coll = exprCollation((Node *) linitial(asplan->subplans));
926 }
927 break;
928 case T_FieldSelect:
929 coll = ((const FieldSelect *) expr)->resultcollid;
930 break;
931 case T_FieldStore:
932 /* FieldStore's result is composite ... */
933 coll = InvalidOid; /* ... so it has no collation */
934 break;
935 case T_RelabelType:
936 coll = ((const RelabelType *) expr)->resultcollid;
937 break;
938 case T_CoerceViaIO:
939 coll = ((const CoerceViaIO *) expr)->resultcollid;
940 break;
941 case T_ArrayCoerceExpr:
942 coll = ((const ArrayCoerceExpr *) expr)->resultcollid;
943 break;
944 case T_ConvertRowtypeExpr:
945 /* ConvertRowtypeExpr's result is composite ... */
946 coll = InvalidOid; /* ... so it has no collation */
947 break;
948 case T_CollateExpr:
949 coll = ((const CollateExpr *) expr)->collOid;
950 break;
951 case T_CaseExpr:
952 coll = ((const CaseExpr *) expr)->casecollid;
953 break;
954 case T_CaseTestExpr:
955 coll = ((const CaseTestExpr *) expr)->collation;
956 break;
957 case T_ArrayExpr:
958 coll = ((const ArrayExpr *) expr)->array_collid;
959 break;
960 case T_RowExpr:
961 /* RowExpr's result is composite ... */
962 coll = InvalidOid; /* ... so it has no collation */
963 break;
964 case T_RowCompareExpr:
965 /* RowCompareExpr's result is boolean ... */
966 coll = InvalidOid; /* ... so it has no collation */
967 break;
968 case T_CoalesceExpr:
969 coll = ((const CoalesceExpr *) expr)->coalescecollid;
970 break;
971 case T_MinMaxExpr:
972 coll = ((const MinMaxExpr *) expr)->minmaxcollid;
973 break;
974 case T_SQLValueFunction:
975 /* Returns either NAME or a non-collatable type */
976 if (((const SQLValueFunction *) expr)->type == NAMEOID)
977 coll = C_COLLATION_OID;
978 else
979 coll = InvalidOid;
980 break;
981 case T_XmlExpr:
982
983 /*
984 * XMLSERIALIZE returns text from non-collatable inputs, so its
985 * collation is always default. The other cases return boolean or
986 * XML, which are non-collatable.
987 */
988 if (((const XmlExpr *) expr)->op == IS_XMLSERIALIZE)
989 coll = DEFAULT_COLLATION_OID;
990 else
991 coll = InvalidOid;
992 break;
993 case T_JsonValueExpr:
994 coll = exprCollation((Node *) ((const JsonValueExpr *) expr)->formatted_expr);
995 break;
996 case T_JsonConstructorExpr:
997 {
998 const JsonConstructorExpr *ctor = (const JsonConstructorExpr *) expr;
999
1000 if (ctor->coercion)
1001 coll = exprCollation((Node *) ctor->coercion);
1002 else
1003 coll = InvalidOid;
1004 }
1005 break;
1006 case T_JsonIsPredicate:
1007 /* IS JSON's result is boolean ... */
1008 coll = InvalidOid; /* ... so it has no collation */
1009 break;
1010 case T_JsonExpr:
1011 {
1012 const JsonExpr *jsexpr = (JsonExpr *) expr;
1013
1014 coll = jsexpr->collation;
1015 }
1016 break;
1017 case T_JsonBehavior:
1018 {
1019 const JsonBehavior *behavior = (JsonBehavior *) expr;
1020
1021 if (behavior->expr)
1022 coll = exprCollation(behavior->expr);
1023 else
1024 coll = InvalidOid;
1025 }
1026 break;
1027 case T_NullTest:
1028 /* NullTest's result is boolean ... */
1029 coll = InvalidOid; /* ... so it has no collation */
1030 break;
1031 case T_BooleanTest:
1032 /* BooleanTest's result is boolean ... */
1033 coll = InvalidOid; /* ... so it has no collation */
1034 break;
1035 case T_CoerceToDomain:
1036 coll = ((const CoerceToDomain *) expr)->resultcollid;
1037 break;
1038 case T_CoerceToDomainValue:
1039 coll = ((const CoerceToDomainValue *) expr)->collation;
1040 break;
1041 case T_SetToDefault:
1042 coll = ((const SetToDefault *) expr)->collation;
1043 break;
1044 case T_CurrentOfExpr:
1045 /* CurrentOfExpr's result is boolean ... */
1046 coll = InvalidOid; /* ... so it has no collation */
1047 break;
1048 case T_NextValueExpr:
1049 /* NextValueExpr's result is an integer type ... */
1050 coll = InvalidOid; /* ... so it has no collation */
1051 break;
1052 case T_InferenceElem:
1053 coll = exprCollation((Node *) ((const InferenceElem *) expr)->expr);
1054 break;
1055 case T_ReturningExpr:
1056 coll = exprCollation((Node *) ((const ReturningExpr *) expr)->retexpr);
1057 break;
1058 case T_PlaceHolderVar:
1059 coll = exprCollation((Node *) ((const PlaceHolderVar *) expr)->phexpr);
1060 break;
1061 default:
1062 elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
1063 coll = InvalidOid; /* keep compiler quiet */
1064 break;
1065 }
1066 return coll;
1067}
#define Assert(condition)
Definition: c.h:815
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:76
#define linitial_node(type, l)
Definition: pg_list.h:181
#define linitial(l)
Definition: pg_list.h:178
#define InvalidOid
Definition: postgres_ext.h:37
@ ARRAY_SUBLINK
Definition: primnodes.h:1019
@ EXPR_SUBLINK
Definition: primnodes.h:1017
@ IS_XMLSERIALIZE
Definition: primnodes.h:1617
Node * expr
Definition: primnodes.h:1822
Oid collation
Definition: primnodes.h:1887
List * targetList
Definition: parsenodes.h:193
Oid firstColCollation
Definition: primnodes.h:1092
SubLinkType subLinkType
Definition: primnodes.h:1081
Definition: primnodes.h:261
const char * type

References arg, ARRAY_SUBLINK, Assert, JsonConstructorExpr::coercion, JsonExpr::collation, elog, ERROR, JsonBehavior::expr, EXPR_SUBLINK, exprCollation(), SubPlan::firstColCollation, if(), InvalidOid, IS_XMLSERIALIZE, IsA, linitial, linitial_node, nodeTag, SubLink::subLinkType, SubPlan::subLinkType, AlternativeSubPlan::subplans, SubLink::subselect, Query::targetList, and type.

Referenced by addRangeTableEntryForFunction(), addRangeTableEntryForGroup(), addRangeTableEntryForSubquery(), analyzeCTE(), analyzeCTETargetList(), applyRelabelType(), assign_collations_walker(), assign_hypothetical_collations(), build_expression_pathkey(), build_pertrans_for_aggref(), build_subplan(), canonicalize_ec_expression(), check_simple_rowfilter_expr_walker(), coerce_type_typmod(), ComputeIndexAttrs(), ComputePartitionAttrs(), convert_EXISTS_to_ANY(), create_ctas_nodata(), create_limit_plan(), create_memoize_plan(), create_unique_plan(), create_windowagg_plan(), DefineVirtualRelation(), eval_const_expressions_mutator(), examine_attribute(), examine_expression(), ExecInitFunctionScan(), ExecInitIndexScan(), ExecTypeFromExprList(), ExecTypeFromTLInternal(), expandRecordVariable(), expandRTE(), exprCollation(), exprSetCollation(), extract_grouping_collations(), fix_indexqual_operand(), generate_setop_tlist(), generate_subquery_params(), get_attr_stat_type(), get_expr_result_type(), get_first_col_type(), group_by_has_partkey(), have_partkey_equi_join(), inline_function(), make_pathkey_from_sortop(), make_recursive_union(), make_setop(), make_sort_from_groupcols(), make_sort_from_sortclauses(), make_unique_from_sortclauses(), makeJsonConstructorExpr(), makeVarFromTargetEntry(), makeWholeRowVar(), mcv_match_expression(), ordered_set_startup(), pg_get_indexdef_worker(), pg_get_partkeydef_worker(), preprocess_minmax_aggregates(), relabel_to_typmod(), RelationBuildPartitionKey(), RelationGetDummyIndexExpressions(), remove_unused_subquery_outputs(), replace_nestloop_param_placeholdervar(), replace_outer_placeholdervar(), replace_outer_returning(), scalararraysel(), set_dummy_tlist_references(), set_joinrel_partition_key_exprs(), tlist_same_collations(), transformCaseExpr(), transformFromClauseItem(), transformJsonTableColumns(), transformMultiAssignRef(), transformPLAssignStmt(), transformSubLink(), and transformWindowDefinitions().

◆ expression_returns_set()

◆ expression_tree_mutator_impl()

Node * expression_tree_mutator_impl ( Node node,
tree_mutator_callback  mutator,
void *  context 
)

Definition at line 2950 of file nodeFuncs.c.

2953{
2954 /*
2955 * The mutator has already decided not to modify the current node, but we
2956 * must call the mutator for any sub-nodes.
2957 */
2958
2959#define FLATCOPY(newnode, node, nodetype) \
2960 ( (newnode) = (nodetype *) palloc(sizeof(nodetype)), \
2961 memcpy((newnode), (node), sizeof(nodetype)) )
2962
2963#define MUTATE(newfield, oldfield, fieldtype) \
2964 ( (newfield) = (fieldtype) mutator((Node *) (oldfield), context) )
2965
2966 if (node == NULL)
2967 return NULL;
2968
2969 /* Guard against stack overflow due to overly complex expressions */
2971
2972 switch (nodeTag(node))
2973 {
2974 /*
2975 * Primitive node types with no expression subnodes. Var and
2976 * Const are frequent enough to deserve special cases, the others
2977 * we just use copyObject for.
2978 */
2979 case T_Var:
2980 {
2981 Var *var = (Var *) node;
2982 Var *newnode;
2983
2984 FLATCOPY(newnode, var, Var);
2985 /* Assume we need not copy the varnullingrels bitmapset */
2986 return (Node *) newnode;
2987 }
2988 break;
2989 case T_Const:
2990 {
2991 Const *oldnode = (Const *) node;
2992 Const *newnode;
2993
2994 FLATCOPY(newnode, oldnode, Const);
2995 /* XXX we don't bother with datumCopy; should we? */
2996 return (Node *) newnode;
2997 }
2998 break;
2999 case T_Param:
3000 case T_CaseTestExpr:
3001 case T_SQLValueFunction:
3002 case T_JsonFormat:
3003 case T_CoerceToDomainValue:
3004 case T_SetToDefault:
3005 case T_CurrentOfExpr:
3006 case T_NextValueExpr:
3007 case T_RangeTblRef:
3008 case T_SortGroupClause:
3009 case T_CTESearchClause:
3010 case T_MergeSupportFunc:
3011 return copyObject(node);
3012 case T_WithCheckOption:
3013 {
3014 WithCheckOption *wco = (WithCheckOption *) node;
3015 WithCheckOption *newnode;
3016
3017 FLATCOPY(newnode, wco, WithCheckOption);
3018 MUTATE(newnode->qual, wco->qual, Node *);
3019 return (Node *) newnode;
3020 }
3021 case T_Aggref:
3022 {
3023 Aggref *aggref = (Aggref *) node;
3024 Aggref *newnode;
3025
3026 FLATCOPY(newnode, aggref, Aggref);
3027 /* assume mutation doesn't change types of arguments */
3028 newnode->aggargtypes = list_copy(aggref->aggargtypes);
3029 MUTATE(newnode->aggdirectargs, aggref->aggdirectargs, List *);
3030 MUTATE(newnode->args, aggref->args, List *);
3031 MUTATE(newnode->aggorder, aggref->aggorder, List *);
3032 MUTATE(newnode->aggdistinct, aggref->aggdistinct, List *);
3033 MUTATE(newnode->aggfilter, aggref->aggfilter, Expr *);
3034 return (Node *) newnode;
3035 }
3036 break;
3037 case T_GroupingFunc:
3038 {
3039 GroupingFunc *grouping = (GroupingFunc *) node;
3040 GroupingFunc *newnode;
3041
3042 FLATCOPY(newnode, grouping, GroupingFunc);
3043 MUTATE(newnode->args, grouping->args, List *);
3044
3045 /*
3046 * We assume here that mutating the arguments does not change
3047 * the semantics, i.e. that the arguments are not mutated in a
3048 * way that makes them semantically different from their
3049 * previously matching expressions in the GROUP BY clause.
3050 *
3051 * If a mutator somehow wanted to do this, it would have to
3052 * handle the refs and cols lists itself as appropriate.
3053 */
3054 newnode->refs = list_copy(grouping->refs);
3055 newnode->cols = list_copy(grouping->cols);
3056
3057 return (Node *) newnode;
3058 }
3059 break;
3060 case T_WindowFunc:
3061 {
3062 WindowFunc *wfunc = (WindowFunc *) node;
3063 WindowFunc *newnode;
3064
3065 FLATCOPY(newnode, wfunc, WindowFunc);
3066 MUTATE(newnode->args, wfunc->args, List *);
3067 MUTATE(newnode->aggfilter, wfunc->aggfilter, Expr *);
3068 return (Node *) newnode;
3069 }
3070 break;
3071 case T_WindowFuncRunCondition:
3072 {
3074 WindowFuncRunCondition *newnode;
3075
3076 FLATCOPY(newnode, wfuncrc, WindowFuncRunCondition);
3077 MUTATE(newnode->arg, wfuncrc->arg, Expr *);
3078 return (Node *) newnode;
3079 }
3080 break;
3081 case T_SubscriptingRef:
3082 {
3083 SubscriptingRef *sbsref = (SubscriptingRef *) node;
3084 SubscriptingRef *newnode;
3085
3086 FLATCOPY(newnode, sbsref, SubscriptingRef);
3087 MUTATE(newnode->refupperindexpr, sbsref->refupperindexpr,
3088 List *);
3089 MUTATE(newnode->reflowerindexpr, sbsref->reflowerindexpr,
3090 List *);
3091 MUTATE(newnode->refexpr, sbsref->refexpr,
3092 Expr *);
3093 MUTATE(newnode->refassgnexpr, sbsref->refassgnexpr,
3094 Expr *);
3095
3096 return (Node *) newnode;
3097 }
3098 break;
3099 case T_FuncExpr:
3100 {
3101 FuncExpr *expr = (FuncExpr *) node;
3102 FuncExpr *newnode;
3103
3104 FLATCOPY(newnode, expr, FuncExpr);
3105 MUTATE(newnode->args, expr->args, List *);
3106 return (Node *) newnode;
3107 }
3108 break;
3109 case T_NamedArgExpr:
3110 {
3111 NamedArgExpr *nexpr = (NamedArgExpr *) node;
3112 NamedArgExpr *newnode;
3113
3114 FLATCOPY(newnode, nexpr, NamedArgExpr);
3115 MUTATE(newnode->arg, nexpr->arg, Expr *);
3116 return (Node *) newnode;
3117 }
3118 break;
3119 case T_OpExpr:
3120 {
3121 OpExpr *expr = (OpExpr *) node;
3122 OpExpr *newnode;
3123
3124 FLATCOPY(newnode, expr, OpExpr);
3125 MUTATE(newnode->args, expr->args, List *);
3126 return (Node *) newnode;
3127 }
3128 break;
3129 case T_DistinctExpr:
3130 {
3131 DistinctExpr *expr = (DistinctExpr *) node;
3132 DistinctExpr *newnode;
3133
3134 FLATCOPY(newnode, expr, DistinctExpr);
3135 MUTATE(newnode->args, expr->args, List *);
3136 return (Node *) newnode;
3137 }
3138 break;
3139 case T_NullIfExpr:
3140 {
3141 NullIfExpr *expr = (NullIfExpr *) node;
3142 NullIfExpr *newnode;
3143
3144 FLATCOPY(newnode, expr, NullIfExpr);
3145 MUTATE(newnode->args, expr->args, List *);
3146 return (Node *) newnode;
3147 }
3148 break;
3149 case T_ScalarArrayOpExpr:
3150 {
3151 ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
3152 ScalarArrayOpExpr *newnode;
3153
3154 FLATCOPY(newnode, expr, ScalarArrayOpExpr);
3155 MUTATE(newnode->args, expr->args, List *);
3156 return (Node *) newnode;
3157 }
3158 break;
3159 case T_BoolExpr:
3160 {
3161 BoolExpr *expr = (BoolExpr *) node;
3162 BoolExpr *newnode;
3163
3164 FLATCOPY(newnode, expr, BoolExpr);
3165 MUTATE(newnode->args, expr->args, List *);
3166 return (Node *) newnode;
3167 }
3168 break;
3169 case T_SubLink:
3170 {
3171 SubLink *sublink = (SubLink *) node;
3172 SubLink *newnode;
3173
3174 FLATCOPY(newnode, sublink, SubLink);
3175 MUTATE(newnode->testexpr, sublink->testexpr, Node *);
3176
3177 /*
3178 * Also invoke the mutator on the sublink's Query node, so it
3179 * can recurse into the sub-query if it wants to.
3180 */
3181 MUTATE(newnode->subselect, sublink->subselect, Node *);
3182 return (Node *) newnode;
3183 }
3184 break;
3185 case T_SubPlan:
3186 {
3187 SubPlan *subplan = (SubPlan *) node;
3188 SubPlan *newnode;
3189
3190 FLATCOPY(newnode, subplan, SubPlan);
3191 /* transform testexpr */
3192 MUTATE(newnode->testexpr, subplan->testexpr, Node *);
3193 /* transform args list (params to be passed to subplan) */
3194 MUTATE(newnode->args, subplan->args, List *);
3195 /* but not the sub-Plan itself, which is referenced as-is */
3196 return (Node *) newnode;
3197 }
3198 break;
3199 case T_AlternativeSubPlan:
3200 {
3201 AlternativeSubPlan *asplan = (AlternativeSubPlan *) node;
3202 AlternativeSubPlan *newnode;
3203
3204 FLATCOPY(newnode, asplan, AlternativeSubPlan);
3205 MUTATE(newnode->subplans, asplan->subplans, List *);
3206 return (Node *) newnode;
3207 }
3208 break;
3209 case T_FieldSelect:
3210 {
3211 FieldSelect *fselect = (FieldSelect *) node;
3212 FieldSelect *newnode;
3213
3214 FLATCOPY(newnode, fselect, FieldSelect);
3215 MUTATE(newnode->arg, fselect->arg, Expr *);
3216 return (Node *) newnode;
3217 }
3218 break;
3219 case T_FieldStore:
3220 {
3221 FieldStore *fstore = (FieldStore *) node;
3222 FieldStore *newnode;
3223
3224 FLATCOPY(newnode, fstore, FieldStore);
3225 MUTATE(newnode->arg, fstore->arg, Expr *);
3226 MUTATE(newnode->newvals, fstore->newvals, List *);
3227 newnode->fieldnums = list_copy(fstore->fieldnums);
3228 return (Node *) newnode;
3229 }
3230 break;
3231 case T_RelabelType:
3232 {
3233 RelabelType *relabel = (RelabelType *) node;
3234 RelabelType *newnode;
3235
3236 FLATCOPY(newnode, relabel, RelabelType);
3237 MUTATE(newnode->arg, relabel->arg, Expr *);
3238 return (Node *) newnode;
3239 }
3240 break;
3241 case T_CoerceViaIO:
3242 {
3243 CoerceViaIO *iocoerce = (CoerceViaIO *) node;
3244 CoerceViaIO *newnode;
3245
3246 FLATCOPY(newnode, iocoerce, CoerceViaIO);
3247 MUTATE(newnode->arg, iocoerce->arg, Expr *);
3248 return (Node *) newnode;
3249 }
3250 break;
3251 case T_ArrayCoerceExpr:
3252 {
3253 ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node;
3254 ArrayCoerceExpr *newnode;
3255
3256 FLATCOPY(newnode, acoerce, ArrayCoerceExpr);
3257 MUTATE(newnode->arg, acoerce->arg, Expr *);
3258 MUTATE(newnode->elemexpr, acoerce->elemexpr, Expr *);
3259 return (Node *) newnode;
3260 }
3261 break;
3262 case T_ConvertRowtypeExpr:
3263 {
3264 ConvertRowtypeExpr *convexpr = (ConvertRowtypeExpr *) node;
3265 ConvertRowtypeExpr *newnode;
3266
3267 FLATCOPY(newnode, convexpr, ConvertRowtypeExpr);
3268 MUTATE(newnode->arg, convexpr->arg, Expr *);
3269 return (Node *) newnode;
3270 }
3271 break;
3272 case T_CollateExpr:
3273 {
3274 CollateExpr *collate = (CollateExpr *) node;
3275 CollateExpr *newnode;
3276
3277 FLATCOPY(newnode, collate, CollateExpr);
3278 MUTATE(newnode->arg, collate->arg, Expr *);
3279 return (Node *) newnode;
3280 }
3281 break;
3282 case T_CaseExpr:
3283 {
3284 CaseExpr *caseexpr = (CaseExpr *) node;
3285 CaseExpr *newnode;
3286
3287 FLATCOPY(newnode, caseexpr, CaseExpr);
3288 MUTATE(newnode->arg, caseexpr->arg, Expr *);
3289 MUTATE(newnode->args, caseexpr->args, List *);
3290 MUTATE(newnode->defresult, caseexpr->defresult, Expr *);
3291 return (Node *) newnode;
3292 }
3293 break;
3294 case T_CaseWhen:
3295 {
3296 CaseWhen *casewhen = (CaseWhen *) node;
3297 CaseWhen *newnode;
3298
3299 FLATCOPY(newnode, casewhen, CaseWhen);
3300 MUTATE(newnode->expr, casewhen->expr, Expr *);
3301 MUTATE(newnode->result, casewhen->result, Expr *);
3302 return (Node *) newnode;
3303 }
3304 break;
3305 case T_ArrayExpr:
3306 {
3307 ArrayExpr *arrayexpr = (ArrayExpr *) node;
3308 ArrayExpr *newnode;
3309
3310 FLATCOPY(newnode, arrayexpr, ArrayExpr);
3311 MUTATE(newnode->elements, arrayexpr->elements, List *);
3312 return (Node *) newnode;
3313 }
3314 break;
3315 case T_RowExpr:
3316 {
3317 RowExpr *rowexpr = (RowExpr *) node;
3318 RowExpr *newnode;
3319
3320 FLATCOPY(newnode, rowexpr, RowExpr);
3321 MUTATE(newnode->args, rowexpr->args, List *);
3322 /* Assume colnames needn't be duplicated */
3323 return (Node *) newnode;
3324 }
3325 break;
3326 case T_RowCompareExpr:
3327 {
3328 RowCompareExpr *rcexpr = (RowCompareExpr *) node;
3329 RowCompareExpr *newnode;
3330
3331 FLATCOPY(newnode, rcexpr, RowCompareExpr);
3332 MUTATE(newnode->largs, rcexpr->largs, List *);
3333 MUTATE(newnode->rargs, rcexpr->rargs, List *);
3334 return (Node *) newnode;
3335 }
3336 break;
3337 case T_CoalesceExpr:
3338 {
3339 CoalesceExpr *coalesceexpr = (CoalesceExpr *) node;
3340 CoalesceExpr *newnode;
3341
3342 FLATCOPY(newnode, coalesceexpr, CoalesceExpr);
3343 MUTATE(newnode->args, coalesceexpr->args, List *);
3344 return (Node *) newnode;
3345 }
3346 break;
3347 case T_MinMaxExpr:
3348 {
3349 MinMaxExpr *minmaxexpr = (MinMaxExpr *) node;
3350 MinMaxExpr *newnode;
3351
3352 FLATCOPY(newnode, minmaxexpr, MinMaxExpr);
3353 MUTATE(newnode->args, minmaxexpr->args, List *);
3354 return (Node *) newnode;
3355 }
3356 break;
3357 case T_XmlExpr:
3358 {
3359 XmlExpr *xexpr = (XmlExpr *) node;
3360 XmlExpr *newnode;
3361
3362 FLATCOPY(newnode, xexpr, XmlExpr);
3363 MUTATE(newnode->named_args, xexpr->named_args, List *);
3364 /* assume mutator does not care about arg_names */
3365 MUTATE(newnode->args, xexpr->args, List *);
3366 return (Node *) newnode;
3367 }
3368 break;
3369 case T_JsonReturning:
3370 {
3371 JsonReturning *jr = (JsonReturning *) node;
3372 JsonReturning *newnode;
3373
3374 FLATCOPY(newnode, jr, JsonReturning);
3375 MUTATE(newnode->format, jr->format, JsonFormat *);
3376
3377 return (Node *) newnode;
3378 }
3379 case T_JsonValueExpr:
3380 {
3381 JsonValueExpr *jve = (JsonValueExpr *) node;
3382 JsonValueExpr *newnode;
3383
3384 FLATCOPY(newnode, jve, JsonValueExpr);
3385 MUTATE(newnode->raw_expr, jve->raw_expr, Expr *);
3386 MUTATE(newnode->formatted_expr, jve->formatted_expr, Expr *);
3387 MUTATE(newnode->format, jve->format, JsonFormat *);
3388
3389 return (Node *) newnode;
3390 }
3391 case T_JsonConstructorExpr:
3392 {
3394 JsonConstructorExpr *newnode;
3395
3396 FLATCOPY(newnode, jce, JsonConstructorExpr);
3397 MUTATE(newnode->args, jce->args, List *);
3398 MUTATE(newnode->func, jce->func, Expr *);
3399 MUTATE(newnode->coercion, jce->coercion, Expr *);
3400 MUTATE(newnode->returning, jce->returning, JsonReturning *);
3401
3402 return (Node *) newnode;
3403 }
3404 case T_JsonIsPredicate:
3405 {
3406 JsonIsPredicate *pred = (JsonIsPredicate *) node;
3407 JsonIsPredicate *newnode;
3408
3409 FLATCOPY(newnode, pred, JsonIsPredicate);
3410 MUTATE(newnode->expr, pred->expr, Node *);
3411 MUTATE(newnode->format, pred->format, JsonFormat *);
3412
3413 return (Node *) newnode;
3414 }
3415 case T_JsonExpr:
3416 {
3417 JsonExpr *jexpr = (JsonExpr *) node;
3418 JsonExpr *newnode;
3419
3420 FLATCOPY(newnode, jexpr, JsonExpr);
3421 MUTATE(newnode->formatted_expr, jexpr->formatted_expr, Node *);
3422 MUTATE(newnode->path_spec, jexpr->path_spec, Node *);
3423 MUTATE(newnode->passing_values, jexpr->passing_values, List *);
3424 /* assume mutator does not care about passing_names */
3425 MUTATE(newnode->on_empty, jexpr->on_empty, JsonBehavior *);
3426 MUTATE(newnode->on_error, jexpr->on_error, JsonBehavior *);
3427 return (Node *) newnode;
3428 }
3429 break;
3430 case T_JsonBehavior:
3431 {
3432 JsonBehavior *behavior = (JsonBehavior *) node;
3433 JsonBehavior *newnode;
3434
3435 FLATCOPY(newnode, behavior, JsonBehavior);
3436 MUTATE(newnode->expr, behavior->expr, Node *);
3437 return (Node *) newnode;
3438 }
3439 break;
3440 case T_NullTest:
3441 {
3442 NullTest *ntest = (NullTest *) node;
3443 NullTest *newnode;
3444
3445 FLATCOPY(newnode, ntest, NullTest);
3446 MUTATE(newnode->arg, ntest->arg, Expr *);
3447 return (Node *) newnode;
3448 }
3449 break;
3450 case T_BooleanTest:
3451 {
3452 BooleanTest *btest = (BooleanTest *) node;
3453 BooleanTest *newnode;
3454
3455 FLATCOPY(newnode, btest, BooleanTest);
3456 MUTATE(newnode->arg, btest->arg, Expr *);
3457 return (Node *) newnode;
3458 }
3459 break;
3460 case T_CoerceToDomain:
3461 {
3462 CoerceToDomain *ctest = (CoerceToDomain *) node;
3463 CoerceToDomain *newnode;
3464
3465 FLATCOPY(newnode, ctest, CoerceToDomain);
3466 MUTATE(newnode->arg, ctest->arg, Expr *);
3467 return (Node *) newnode;
3468 }
3469 break;
3470 case T_ReturningExpr:
3471 {
3472 ReturningExpr *rexpr = (ReturningExpr *) node;
3473 ReturningExpr *newnode;
3474
3475 FLATCOPY(newnode, rexpr, ReturningExpr);
3476 MUTATE(newnode->retexpr, rexpr->retexpr, Expr *);
3477 return (Node *) newnode;
3478 }
3479 break;
3480 case T_TargetEntry:
3481 {
3482 TargetEntry *targetentry = (TargetEntry *) node;
3483 TargetEntry *newnode;
3484
3485 FLATCOPY(newnode, targetentry, TargetEntry);
3486 MUTATE(newnode->expr, targetentry->expr, Expr *);
3487 return (Node *) newnode;
3488 }
3489 break;
3490 case T_Query:
3491 /* Do nothing with a sub-Query, per discussion above */
3492 return node;
3493 case T_WindowClause:
3494 {
3495 WindowClause *wc = (WindowClause *) node;
3496 WindowClause *newnode;
3497
3498 FLATCOPY(newnode, wc, WindowClause);
3499 MUTATE(newnode->partitionClause, wc->partitionClause, List *);
3500 MUTATE(newnode->orderClause, wc->orderClause, List *);
3501 MUTATE(newnode->startOffset, wc->startOffset, Node *);
3502 MUTATE(newnode->endOffset, wc->endOffset, Node *);
3503 return (Node *) newnode;
3504 }
3505 break;
3506 case T_CTECycleClause:
3507 {
3508 CTECycleClause *cc = (CTECycleClause *) node;
3509 CTECycleClause *newnode;
3510
3511 FLATCOPY(newnode, cc, CTECycleClause);
3512 MUTATE(newnode->cycle_mark_value, cc->cycle_mark_value, Node *);
3514 return (Node *) newnode;
3515 }
3516 break;
3517 case T_CommonTableExpr:
3518 {
3519 CommonTableExpr *cte = (CommonTableExpr *) node;
3520 CommonTableExpr *newnode;
3521
3522 FLATCOPY(newnode, cte, CommonTableExpr);
3523
3524 /*
3525 * Also invoke the mutator on the CTE's Query node, so it can
3526 * recurse into the sub-query if it wants to.
3527 */
3528 MUTATE(newnode->ctequery, cte->ctequery, Node *);
3529
3530 MUTATE(newnode->search_clause, cte->search_clause, CTESearchClause *);
3531 MUTATE(newnode->cycle_clause, cte->cycle_clause, CTECycleClause *);
3532
3533 return (Node *) newnode;
3534 }
3535 break;
3536 case T_PartitionBoundSpec:
3537 {
3538 PartitionBoundSpec *pbs = (PartitionBoundSpec *) node;
3539 PartitionBoundSpec *newnode;
3540
3541 FLATCOPY(newnode, pbs, PartitionBoundSpec);
3542 MUTATE(newnode->listdatums, pbs->listdatums, List *);
3543 MUTATE(newnode->lowerdatums, pbs->lowerdatums, List *);
3544 MUTATE(newnode->upperdatums, pbs->upperdatums, List *);
3545 return (Node *) newnode;
3546 }
3547 break;
3548 case T_PartitionRangeDatum:
3549 {
3551 PartitionRangeDatum *newnode;
3552
3553 FLATCOPY(newnode, prd, PartitionRangeDatum);
3554 MUTATE(newnode->value, prd->value, Node *);
3555 return (Node *) newnode;
3556 }
3557 break;
3558 case T_List:
3559 {
3560 /*
3561 * We assume the mutator isn't interested in the list nodes
3562 * per se, so just invoke it on each list element. NOTE: this
3563 * would fail badly on a list with integer elements!
3564 */
3565 List *resultlist;
3566 ListCell *temp;
3567
3568 resultlist = NIL;
3569 foreach(temp, (List *) node)
3570 {
3571 resultlist = lappend(resultlist,
3572 mutator((Node *) lfirst(temp),
3573 context));
3574 }
3575 return (Node *) resultlist;
3576 }
3577 break;
3578 case T_FromExpr:
3579 {
3580 FromExpr *from = (FromExpr *) node;
3581 FromExpr *newnode;
3582
3583 FLATCOPY(newnode, from, FromExpr);
3584 MUTATE(newnode->fromlist, from->fromlist, List *);
3585 MUTATE(newnode->quals, from->quals, Node *);
3586 return (Node *) newnode;
3587 }
3588 break;
3589 case T_OnConflictExpr:
3590 {
3591 OnConflictExpr *oc = (OnConflictExpr *) node;
3592 OnConflictExpr *newnode;
3593
3594 FLATCOPY(newnode, oc, OnConflictExpr);
3595 MUTATE(newnode->arbiterElems, oc->arbiterElems, List *);
3596 MUTATE(newnode->arbiterWhere, oc->arbiterWhere, Node *);
3597 MUTATE(newnode->onConflictSet, oc->onConflictSet, List *);
3598 MUTATE(newnode->onConflictWhere, oc->onConflictWhere, Node *);
3599 MUTATE(newnode->exclRelTlist, oc->exclRelTlist, List *);
3600
3601 return (Node *) newnode;
3602 }
3603 break;
3604 case T_MergeAction:
3605 {
3606 MergeAction *action = (MergeAction *) node;
3607 MergeAction *newnode;
3608
3609 FLATCOPY(newnode, action, MergeAction);
3610 MUTATE(newnode->qual, action->qual, Node *);
3611 MUTATE(newnode->targetList, action->targetList, List *);
3612
3613 return (Node *) newnode;
3614 }
3615 break;
3616 case T_PartitionPruneStepOp:
3617 {
3618 PartitionPruneStepOp *opstep = (PartitionPruneStepOp *) node;
3619 PartitionPruneStepOp *newnode;
3620
3621 FLATCOPY(newnode, opstep, PartitionPruneStepOp);
3622 MUTATE(newnode->exprs, opstep->exprs, List *);
3623
3624 return (Node *) newnode;
3625 }
3626 break;
3627 case T_PartitionPruneStepCombine:
3628 /* no expression sub-nodes */
3629 return copyObject(node);
3630 case T_JoinExpr:
3631 {
3632 JoinExpr *join = (JoinExpr *) node;
3633 JoinExpr *newnode;
3634
3635 FLATCOPY(newnode, join, JoinExpr);
3636 MUTATE(newnode->larg, join->larg, Node *);
3637 MUTATE(newnode->rarg, join->rarg, Node *);
3638 MUTATE(newnode->quals, join->quals, Node *);
3639 /* We do not mutate alias or using by default */
3640 return (Node *) newnode;
3641 }
3642 break;
3643 case T_SetOperationStmt:
3644 {
3645 SetOperationStmt *setop = (SetOperationStmt *) node;
3646 SetOperationStmt *newnode;
3647
3648 FLATCOPY(newnode, setop, SetOperationStmt);
3649 MUTATE(newnode->larg, setop->larg, Node *);
3650 MUTATE(newnode->rarg, setop->rarg, Node *);
3651 /* We do not mutate groupClauses by default */
3652 return (Node *) newnode;
3653 }
3654 break;
3655 case T_IndexClause:
3656 {
3657 IndexClause *iclause = (IndexClause *) node;
3658 IndexClause *newnode;
3659
3660 FLATCOPY(newnode, iclause, IndexClause);
3661 MUTATE(newnode->rinfo, iclause->rinfo, RestrictInfo *);
3662 MUTATE(newnode->indexquals, iclause->indexquals, List *);
3663 return (Node *) newnode;
3664 }
3665 break;
3666 case T_PlaceHolderVar:
3667 {
3668 PlaceHolderVar *phv = (PlaceHolderVar *) node;
3669 PlaceHolderVar *newnode;
3670
3671 FLATCOPY(newnode, phv, PlaceHolderVar);
3672 MUTATE(newnode->phexpr, phv->phexpr, Expr *);
3673 /* Assume we need not copy the relids bitmapsets */
3674 return (Node *) newnode;
3675 }
3676 break;
3677 case T_InferenceElem:
3678 {
3679 InferenceElem *inferenceelemdexpr = (InferenceElem *) node;
3680 InferenceElem *newnode;
3681
3682 FLATCOPY(newnode, inferenceelemdexpr, InferenceElem);
3683 MUTATE(newnode->expr, newnode->expr, Node *);
3684 return (Node *) newnode;
3685 }
3686 break;
3687 case T_AppendRelInfo:
3688 {
3689 AppendRelInfo *appinfo = (AppendRelInfo *) node;
3690 AppendRelInfo *newnode;
3691
3692 FLATCOPY(newnode, appinfo, AppendRelInfo);
3693 MUTATE(newnode->translated_vars, appinfo->translated_vars, List *);
3694 /* Assume nothing need be done with parent_colnos[] */
3695 return (Node *) newnode;
3696 }
3697 break;
3698 case T_PlaceHolderInfo:
3699 {
3700 PlaceHolderInfo *phinfo = (PlaceHolderInfo *) node;
3701 PlaceHolderInfo *newnode;
3702
3703 FLATCOPY(newnode, phinfo, PlaceHolderInfo);
3704 MUTATE(newnode->ph_var, phinfo->ph_var, PlaceHolderVar *);
3705 /* Assume we need not copy the relids bitmapsets */
3706 return (Node *) newnode;
3707 }
3708 break;
3709 case T_RangeTblFunction:
3710 {
3711 RangeTblFunction *rtfunc = (RangeTblFunction *) node;
3712 RangeTblFunction *newnode;
3713
3714 FLATCOPY(newnode, rtfunc, RangeTblFunction);
3715 MUTATE(newnode->funcexpr, rtfunc->funcexpr, Node *);
3716 /* Assume we need not copy the coldef info lists */
3717 return (Node *) newnode;
3718 }
3719 break;
3720 case T_TableSampleClause:
3721 {
3722 TableSampleClause *tsc = (TableSampleClause *) node;
3723 TableSampleClause *newnode;
3724
3725 FLATCOPY(newnode, tsc, TableSampleClause);
3726 MUTATE(newnode->args, tsc->args, List *);
3727 MUTATE(newnode->repeatable, tsc->repeatable, Expr *);
3728 return (Node *) newnode;
3729 }
3730 break;
3731 case T_TableFunc:
3732 {
3733 TableFunc *tf = (TableFunc *) node;
3734 TableFunc *newnode;
3735
3736 FLATCOPY(newnode, tf, TableFunc);
3737 MUTATE(newnode->ns_uris, tf->ns_uris, List *);
3738 MUTATE(newnode->docexpr, tf->docexpr, Node *);
3739 MUTATE(newnode->rowexpr, tf->rowexpr, Node *);
3740 MUTATE(newnode->colexprs, tf->colexprs, List *);
3741 MUTATE(newnode->coldefexprs, tf->coldefexprs, List *);
3742 MUTATE(newnode->colvalexprs, tf->colvalexprs, List *);
3743 MUTATE(newnode->passingvalexprs, tf->passingvalexprs, List *);
3744 return (Node *) newnode;
3745 }
3746 break;
3747 default:
3748 elog(ERROR, "unrecognized node type: %d",
3749 (int) nodeTag(node));
3750 break;
3751 }
3752 /* can't get here, but keep compiler happy */
3753 return NULL;
3754}
List * lappend(List *list, void *datum)
Definition: list.c:339
List * list_copy(const List *oldlist)
Definition: list.c:1573
#define FLATCOPY(newnode, node, nodetype)
#define MUTATE(newfield, oldfield, fieldtype)
#define lfirst(lc)
Definition: pg_list.h:172
#define NIL
Definition: pg_list.h:68
void check_stack_depth(void)
Definition: stack_depth.c:95
List * aggdistinct
Definition: primnodes.h:490
List * aggdirectargs
Definition: primnodes.h:481
List * args
Definition: primnodes.h:484
Expr * aggfilter
Definition: primnodes.h:493
List * aggorder
Definition: primnodes.h:487
List * translated_vars
Definition: pathnodes.h:3008
List * elements
Definition: primnodes.h:1396
List * args
Definition: primnodes.h:956
Expr * arg
Definition: primnodes.h:2013
Node * cycle_mark_default
Definition: parsenodes.h:1667
Node * cycle_mark_value
Definition: parsenodes.h:1666
Expr * arg
Definition: primnodes.h:1329
Expr * defresult
Definition: primnodes.h:1331
List * args
Definition: primnodes.h:1330
Expr * result
Definition: primnodes.h:1342
Expr * expr
Definition: primnodes.h:1341
List * args
Definition: primnodes.h:1523
Expr * arg
Definition: primnodes.h:1295
Expr * arg
Definition: primnodes.h:1144
List * newvals
Definition: primnodes.h:1176
Expr * arg
Definition: primnodes.h:1175
Node * quals
Definition: primnodes.h:2364
List * fromlist
Definition: primnodes.h:2363
List * args
Definition: primnodes.h:784
List * indexquals
Definition: pathnodes.h:1771
struct RestrictInfo * rinfo
Definition: pathnodes.h:1770
Node * quals
Definition: primnodes.h:2344
Node * larg
Definition: primnodes.h:2337
Node * rarg
Definition: primnodes.h:2338
JsonReturning * returning
Definition: primnodes.h:1741
Node * formatted_expr
Definition: primnodes.h:1854
List * passing_values
Definition: primnodes.h:1867
JsonBehavior * on_empty
Definition: primnodes.h:1870
Node * path_spec
Definition: primnodes.h:1860
JsonBehavior * on_error
Definition: primnodes.h:1871
JsonFormat * format
Definition: primnodes.h:1767
JsonFormat * format
Definition: primnodes.h:1694
Expr * formatted_expr
Definition: primnodes.h:1715
JsonFormat * format
Definition: primnodes.h:1716
Expr * raw_expr
Definition: primnodes.h:1714
Definition: pg_list.h:54
Node * qual
Definition: primnodes.h:2041
List * targetList
Definition: primnodes.h:2042
List * args
Definition: primnodes.h:1549
Expr * arg
Definition: primnodes.h:807
Expr * arg
Definition: primnodes.h:1989
List * arbiterElems
Definition: primnodes.h:2382
List * onConflictSet
Definition: primnodes.h:2388
List * exclRelTlist
Definition: primnodes.h:2391
Node * onConflictWhere
Definition: primnodes.h:2389
Node * arbiterWhere
Definition: primnodes.h:2384
List * args
Definition: primnodes.h:852
PlaceHolderVar * ph_var
Definition: pathnodes.h:3096
Expr * retexpr
Definition: primnodes.h:2183
List * args
Definition: primnodes.h:1427
List * args
Definition: primnodes.h:1107
Node * testexpr
Definition: primnodes.h:1083
Expr * refassgnexpr
Definition: primnodes.h:719
List * refupperindexpr
Definition: primnodes.h:709
Expr * refexpr
Definition: primnodes.h:717
List * reflowerindexpr
Definition: primnodes.h:715
Node * docexpr
Definition: primnodes.h:119
Node * rowexpr
Definition: primnodes.h:121
List * colexprs
Definition: primnodes.h:131
Expr * expr
Definition: primnodes.h:2245
Node * startOffset
Definition: parsenodes.h:1556
List * partitionClause
Definition: parsenodes.h:1552
Node * endOffset
Definition: parsenodes.h:1557
List * orderClause
Definition: parsenodes.h:1554
List * args
Definition: primnodes.h:591
Expr * aggfilter
Definition: primnodes.h:593
List * args
Definition: primnodes.h:1639
List * named_args
Definition: primnodes.h:1635

References generate_unaccent_rules::action, Aggref::aggdirectargs, Aggref::aggdistinct, Aggref::aggfilter, WindowFunc::aggfilter, Aggref::aggorder, OnConflictExpr::arbiterElems, OnConflictExpr::arbiterWhere, WindowFuncRunCondition::arg, NamedArgExpr::arg, FieldSelect::arg, FieldStore::arg, RelabelType::arg, CoerceViaIO::arg, ArrayCoerceExpr::arg, ConvertRowtypeExpr::arg, CollateExpr::arg, CaseExpr::arg, NullTest::arg, BooleanTest::arg, CoerceToDomain::arg, TableSampleClause::args, Aggref::args, WindowFunc::args, FuncExpr::args, OpExpr::args, ScalarArrayOpExpr::args, BoolExpr::args, SubPlan::args, CaseExpr::args, RowExpr::args, CoalesceExpr::args, MinMaxExpr::args, XmlExpr::args, JsonConstructorExpr::args, check_stack_depth(), JsonConstructorExpr::coercion, TableFunc::colexprs, copyObject, CommonTableExpr::ctequery, CTECycleClause::cycle_mark_default, CTECycleClause::cycle_mark_value, CaseExpr::defresult, TableFunc::docexpr, ArrayExpr::elements, ArrayCoerceExpr::elemexpr, elog, WindowClause::endOffset, ERROR, OnConflictExpr::exclRelTlist, CaseWhen::expr, JsonIsPredicate::expr, JsonBehavior::expr, InferenceElem::expr, TargetEntry::expr, PartitionPruneStepOp::exprs, FLATCOPY, JsonReturning::format, JsonValueExpr::format, JsonIsPredicate::format, JsonValueExpr::formatted_expr, JsonExpr::formatted_expr, FromExpr::fromlist, JsonConstructorExpr::func, RangeTblFunction::funcexpr, IndexClause::indexquals, lappend(), SetOperationStmt::larg, JoinExpr::larg, RowCompareExpr::largs, lfirst, list_copy(), PartitionBoundSpec::listdatums, PartitionBoundSpec::lowerdatums, MUTATE, XmlExpr::named_args, FieldStore::newvals, NIL, nodeTag, JsonExpr::on_empty, JsonExpr::on_error, OnConflictExpr::onConflictSet, OnConflictExpr::onConflictWhere, WindowClause::orderClause, WindowClause::partitionClause, JsonExpr::passing_values, JsonExpr::path_spec, PlaceHolderInfo::ph_var, WithCheckOption::qual, MergeAction::qual, JoinExpr::quals, FromExpr::quals, SetOperationStmt::rarg, JoinExpr::rarg, RowCompareExpr::rargs, JsonValueExpr::raw_expr, SubscriptingRef::refassgnexpr, SubscriptingRef::refexpr, SubscriptingRef::reflowerindexpr, SubscriptingRef::refupperindexpr, TableSampleClause::repeatable, CaseWhen::result, ReturningExpr::retexpr, JsonConstructorExpr::returning, IndexClause::rinfo, TableFunc::rowexpr, WindowClause::startOffset, AlternativeSubPlan::subplans, SubLink::subselect, MergeAction::targetList, SubLink::testexpr, SubPlan::testexpr, AppendRelInfo::translated_vars, PartitionBoundSpec::upperdatums, and PartitionRangeDatum::value.

◆ expression_tree_walker_impl()

bool expression_tree_walker_impl ( Node node,
tree_walker_callback  walker,
void *  context 
)

Definition at line 2093 of file nodeFuncs.c.

2096{
2097 ListCell *temp;
2098
2099 /*
2100 * The walker has already visited the current node, and so we need only
2101 * recurse into any sub-nodes it has.
2102 *
2103 * We assume that the walker is not interested in List nodes per se, so
2104 * when we expect a List we just recurse directly to self without
2105 * bothering to call the walker.
2106 */
2107#define WALK(n) walker((Node *) (n), context)
2108
2109#define LIST_WALK(l) expression_tree_walker_impl((Node *) (l), walker, context)
2110
2111 if (node == NULL)
2112 return false;
2113
2114 /* Guard against stack overflow due to overly complex expressions */
2116
2117 switch (nodeTag(node))
2118 {
2119 case T_Var:
2120 case T_Const:
2121 case T_Param:
2122 case T_CaseTestExpr:
2123 case T_SQLValueFunction:
2124 case T_CoerceToDomainValue:
2125 case T_SetToDefault:
2126 case T_CurrentOfExpr:
2127 case T_NextValueExpr:
2128 case T_RangeTblRef:
2129 case T_SortGroupClause:
2130 case T_CTESearchClause:
2131 case T_MergeSupportFunc:
2132 /* primitive node types with no expression subnodes */
2133 break;
2134 case T_WithCheckOption:
2135 return WALK(((WithCheckOption *) node)->qual);
2136 case T_Aggref:
2137 {
2138 Aggref *expr = (Aggref *) node;
2139
2140 /* recurse directly on Lists */
2141 if (LIST_WALK(expr->aggdirectargs))
2142 return true;
2143 if (LIST_WALK(expr->args))
2144 return true;
2145 if (LIST_WALK(expr->aggorder))
2146 return true;
2147 if (LIST_WALK(expr->aggdistinct))
2148 return true;
2149 if (WALK(expr->aggfilter))
2150 return true;
2151 }
2152 break;
2153 case T_GroupingFunc:
2154 {
2155 GroupingFunc *grouping = (GroupingFunc *) node;
2156
2157 if (LIST_WALK(grouping->args))
2158 return true;
2159 }
2160 break;
2161 case T_WindowFunc:
2162 {
2163 WindowFunc *expr = (WindowFunc *) node;
2164
2165 /* recurse directly on List */
2166 if (LIST_WALK(expr->args))
2167 return true;
2168 if (WALK(expr->aggfilter))
2169 return true;
2170 if (WALK(expr->runCondition))
2171 return true;
2172 }
2173 break;
2174 case T_WindowFuncRunCondition:
2175 {
2177
2178 if (WALK(expr->arg))
2179 return true;
2180 }
2181 break;
2182 case T_SubscriptingRef:
2183 {
2184 SubscriptingRef *sbsref = (SubscriptingRef *) node;
2185
2186 /* recurse directly for upper/lower container index lists */
2187 if (LIST_WALK(sbsref->refupperindexpr))
2188 return true;
2189 if (LIST_WALK(sbsref->reflowerindexpr))
2190 return true;
2191 /* walker must see the refexpr and refassgnexpr, however */
2192 if (WALK(sbsref->refexpr))
2193 return true;
2194
2195 if (WALK(sbsref->refassgnexpr))
2196 return true;
2197 }
2198 break;
2199 case T_FuncExpr:
2200 {
2201 FuncExpr *expr = (FuncExpr *) node;
2202
2203 if (LIST_WALK(expr->args))
2204 return true;
2205 }
2206 break;
2207 case T_NamedArgExpr:
2208 return WALK(((NamedArgExpr *) node)->arg);
2209 case T_OpExpr:
2210 case T_DistinctExpr: /* struct-equivalent to OpExpr */
2211 case T_NullIfExpr: /* struct-equivalent to OpExpr */
2212 {
2213 OpExpr *expr = (OpExpr *) node;
2214
2215 if (LIST_WALK(expr->args))
2216 return true;
2217 }
2218 break;
2219 case T_ScalarArrayOpExpr:
2220 {
2221 ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
2222
2223 if (LIST_WALK(expr->args))
2224 return true;
2225 }
2226 break;
2227 case T_BoolExpr:
2228 {
2229 BoolExpr *expr = (BoolExpr *) node;
2230
2231 if (LIST_WALK(expr->args))
2232 return true;
2233 }
2234 break;
2235 case T_SubLink:
2236 {
2237 SubLink *sublink = (SubLink *) node;
2238
2239 if (WALK(sublink->testexpr))
2240 return true;
2241
2242 /*
2243 * Also invoke the walker on the sublink's Query node, so it
2244 * can recurse into the sub-query if it wants to.
2245 */
2246 return WALK(sublink->subselect);
2247 }
2248 break;
2249 case T_SubPlan:
2250 {
2251 SubPlan *subplan = (SubPlan *) node;
2252
2253 /* recurse into the testexpr, but not into the Plan */
2254 if (WALK(subplan->testexpr))
2255 return true;
2256 /* also examine args list */
2257 if (LIST_WALK(subplan->args))
2258 return true;
2259 }
2260 break;
2261 case T_AlternativeSubPlan:
2262 return LIST_WALK(((AlternativeSubPlan *) node)->subplans);
2263 case T_FieldSelect:
2264 return WALK(((FieldSelect *) node)->arg);
2265 case T_FieldStore:
2266 {
2267 FieldStore *fstore = (FieldStore *) node;
2268
2269 if (WALK(fstore->arg))
2270 return true;
2271 if (WALK(fstore->newvals))
2272 return true;
2273 }
2274 break;
2275 case T_RelabelType:
2276 return WALK(((RelabelType *) node)->arg);
2277 case T_CoerceViaIO:
2278 return WALK(((CoerceViaIO *) node)->arg);
2279 case T_ArrayCoerceExpr:
2280 {
2281 ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node;
2282
2283 if (WALK(acoerce->arg))
2284 return true;
2285 if (WALK(acoerce->elemexpr))
2286 return true;
2287 }
2288 break;
2289 case T_ConvertRowtypeExpr:
2290 return WALK(((ConvertRowtypeExpr *) node)->arg);
2291 case T_CollateExpr:
2292 return WALK(((CollateExpr *) node)->arg);
2293 case T_CaseExpr:
2294 {
2295 CaseExpr *caseexpr = (CaseExpr *) node;
2296
2297 if (WALK(caseexpr->arg))
2298 return true;
2299 /* we assume walker doesn't care about CaseWhens, either */
2300 foreach(temp, caseexpr->args)
2301 {
2303
2304 if (WALK(when->expr))
2305 return true;
2306 if (WALK(when->result))
2307 return true;
2308 }
2309 if (WALK(caseexpr->defresult))
2310 return true;
2311 }
2312 break;
2313 case T_ArrayExpr:
2314 return WALK(((ArrayExpr *) node)->elements);
2315 case T_RowExpr:
2316 /* Assume colnames isn't interesting */
2317 return WALK(((RowExpr *) node)->args);
2318 case T_RowCompareExpr:
2319 {
2320 RowCompareExpr *rcexpr = (RowCompareExpr *) node;
2321
2322 if (WALK(rcexpr->largs))
2323 return true;
2324 if (WALK(rcexpr->rargs))
2325 return true;
2326 }
2327 break;
2328 case T_CoalesceExpr:
2329 return WALK(((CoalesceExpr *) node)->args);
2330 case T_MinMaxExpr:
2331 return WALK(((MinMaxExpr *) node)->args);
2332 case T_XmlExpr:
2333 {
2334 XmlExpr *xexpr = (XmlExpr *) node;
2335
2336 if (WALK(xexpr->named_args))
2337 return true;
2338 /* we assume walker doesn't care about arg_names */
2339 if (WALK(xexpr->args))
2340 return true;
2341 }
2342 break;
2343 case T_JsonValueExpr:
2344 {
2345 JsonValueExpr *jve = (JsonValueExpr *) node;
2346
2347 if (WALK(jve->raw_expr))
2348 return true;
2349 if (WALK(jve->formatted_expr))
2350 return true;
2351 }
2352 break;
2353 case T_JsonConstructorExpr:
2354 {
2356
2357 if (WALK(ctor->args))
2358 return true;
2359 if (WALK(ctor->func))
2360 return true;
2361 if (WALK(ctor->coercion))
2362 return true;
2363 }
2364 break;
2365 case T_JsonIsPredicate:
2366 return WALK(((JsonIsPredicate *) node)->expr);
2367 case T_JsonExpr:
2368 {
2369 JsonExpr *jexpr = (JsonExpr *) node;
2370
2371 if (WALK(jexpr->formatted_expr))
2372 return true;
2373 if (WALK(jexpr->path_spec))
2374 return true;
2375 if (WALK(jexpr->passing_values))
2376 return true;
2377 /* we assume walker doesn't care about passing_names */
2378 if (WALK(jexpr->on_empty))
2379 return true;
2380 if (WALK(jexpr->on_error))
2381 return true;
2382 }
2383 break;
2384 case T_JsonBehavior:
2385 {
2386 JsonBehavior *behavior = (JsonBehavior *) node;
2387
2388 if (WALK(behavior->expr))
2389 return true;
2390 }
2391 break;
2392 case T_NullTest:
2393 return WALK(((NullTest *) node)->arg);
2394 case T_BooleanTest:
2395 return WALK(((BooleanTest *) node)->arg);
2396 case T_CoerceToDomain:
2397 return WALK(((CoerceToDomain *) node)->arg);
2398 case T_TargetEntry:
2399 return WALK(((TargetEntry *) node)->expr);
2400 case T_Query:
2401 /* Do nothing with a sub-Query, per discussion above */
2402 break;
2403 case T_WindowClause:
2404 {
2405 WindowClause *wc = (WindowClause *) node;
2406
2407 if (WALK(wc->partitionClause))
2408 return true;
2409 if (WALK(wc->orderClause))
2410 return true;
2411 if (WALK(wc->startOffset))
2412 return true;
2413 if (WALK(wc->endOffset))
2414 return true;
2415 }
2416 break;
2417 case T_CTECycleClause:
2418 {
2419 CTECycleClause *cc = (CTECycleClause *) node;
2420
2421 if (WALK(cc->cycle_mark_value))
2422 return true;
2423 if (WALK(cc->cycle_mark_default))
2424 return true;
2425 }
2426 break;
2427 case T_CommonTableExpr:
2428 {
2429 CommonTableExpr *cte = (CommonTableExpr *) node;
2430
2431 /*
2432 * Invoke the walker on the CTE's Query node, so it can
2433 * recurse into the sub-query if it wants to.
2434 */
2435 if (WALK(cte->ctequery))
2436 return true;
2437
2438 if (WALK(cte->search_clause))
2439 return true;
2440 if (WALK(cte->cycle_clause))
2441 return true;
2442 }
2443 break;
2444 case T_JsonKeyValue:
2445 {
2446 JsonKeyValue *kv = (JsonKeyValue *) node;
2447
2448 if (WALK(kv->key))
2449 return true;
2450 if (WALK(kv->value))
2451 return true;
2452 }
2453 break;
2454 case T_JsonObjectConstructor:
2455 {
2457
2458 if (LIST_WALK(ctor->exprs))
2459 return true;
2460 }
2461 break;
2462 case T_JsonArrayConstructor:
2463 {
2465
2466 if (LIST_WALK(ctor->exprs))
2467 return true;
2468 }
2469 break;
2470 case T_JsonArrayQueryConstructor:
2471 {
2473
2474 if (WALK(ctor->query))
2475 return true;
2476 }
2477 break;
2478 case T_JsonAggConstructor:
2479 {
2480 JsonAggConstructor *ctor = (JsonAggConstructor *) node;
2481
2482 if (WALK(ctor->agg_filter))
2483 return true;
2484 if (WALK(ctor->agg_order))
2485 return true;
2486 if (WALK(ctor->over))
2487 return true;
2488 }
2489 break;
2490 case T_JsonObjectAgg:
2491 {
2492 JsonObjectAgg *ctor = (JsonObjectAgg *) node;
2493
2494 if (WALK(ctor->constructor))
2495 return true;
2496 if (WALK(ctor->arg))
2497 return true;
2498 }
2499 break;
2500 case T_JsonArrayAgg:
2501 {
2502 JsonArrayAgg *ctor = (JsonArrayAgg *) node;
2503
2504 if (WALK(ctor->constructor))
2505 return true;
2506 if (WALK(ctor->arg))
2507 return true;
2508 }
2509 break;
2510
2511 case T_PartitionBoundSpec:
2512 {
2513 PartitionBoundSpec *pbs = (PartitionBoundSpec *) node;
2514
2515 if (WALK(pbs->listdatums))
2516 return true;
2517 if (WALK(pbs->lowerdatums))
2518 return true;
2519 if (WALK(pbs->upperdatums))
2520 return true;
2521 }
2522 break;
2523 case T_PartitionRangeDatum:
2524 {
2526
2527 if (WALK(prd->value))
2528 return true;
2529 }
2530 break;
2531 case T_List:
2532 foreach(temp, (List *) node)
2533 {
2534 if (WALK(lfirst(temp)))
2535 return true;
2536 }
2537 break;
2538 case T_FromExpr:
2539 {
2540 FromExpr *from = (FromExpr *) node;
2541
2542 if (LIST_WALK(from->fromlist))
2543 return true;
2544 if (WALK(from->quals))
2545 return true;
2546 }
2547 break;
2548 case T_OnConflictExpr:
2549 {
2550 OnConflictExpr *onconflict = (OnConflictExpr *) node;
2551
2552 if (WALK(onconflict->arbiterElems))
2553 return true;
2554 if (WALK(onconflict->arbiterWhere))
2555 return true;
2556 if (WALK(onconflict->onConflictSet))
2557 return true;
2558 if (WALK(onconflict->onConflictWhere))
2559 return true;
2560 if (WALK(onconflict->exclRelTlist))
2561 return true;
2562 }
2563 break;
2564 case T_MergeAction:
2565 {
2566 MergeAction *action = (MergeAction *) node;
2567
2568 if (WALK(action->qual))
2569 return true;
2570 if (WALK(action->targetList))
2571 return true;
2572 }
2573 break;
2574 case T_PartitionPruneStepOp:
2575 {
2576 PartitionPruneStepOp *opstep = (PartitionPruneStepOp *) node;
2577
2578 if (WALK(opstep->exprs))
2579 return true;
2580 }
2581 break;
2582 case T_PartitionPruneStepCombine:
2583 /* no expression subnodes */
2584 break;
2585 case T_JoinExpr:
2586 {
2587 JoinExpr *join = (JoinExpr *) node;
2588
2589 if (WALK(join->larg))
2590 return true;
2591 if (WALK(join->rarg))
2592 return true;
2593 if (WALK(join->quals))
2594 return true;
2595
2596 /*
2597 * alias clause, using list are deemed uninteresting.
2598 */
2599 }
2600 break;
2601 case T_SetOperationStmt:
2602 {
2603 SetOperationStmt *setop = (SetOperationStmt *) node;
2604
2605 if (WALK(setop->larg))
2606 return true;
2607 if (WALK(setop->rarg))
2608 return true;
2609
2610 /* groupClauses are deemed uninteresting */
2611 }
2612 break;
2613 case T_IndexClause:
2614 {
2615 IndexClause *iclause = (IndexClause *) node;
2616
2617 if (WALK(iclause->rinfo))
2618 return true;
2619 if (LIST_WALK(iclause->indexquals))
2620 return true;
2621 }
2622 break;
2623 case T_PlaceHolderVar:
2624 return WALK(((PlaceHolderVar *) node)->phexpr);
2625 case T_InferenceElem:
2626 return WALK(((InferenceElem *) node)->expr);
2627 case T_ReturningExpr:
2628 return WALK(((ReturningExpr *) node)->retexpr);
2629 case T_AppendRelInfo:
2630 {
2631 AppendRelInfo *appinfo = (AppendRelInfo *) node;
2632
2633 if (LIST_WALK(appinfo->translated_vars))
2634 return true;
2635 }
2636 break;
2637 case T_PlaceHolderInfo:
2638 return WALK(((PlaceHolderInfo *) node)->ph_var);
2639 case T_RangeTblFunction:
2640 return WALK(((RangeTblFunction *) node)->funcexpr);
2641 case T_TableSampleClause:
2642 {
2643 TableSampleClause *tsc = (TableSampleClause *) node;
2644
2645 if (LIST_WALK(tsc->args))
2646 return true;
2647 if (WALK(tsc->repeatable))
2648 return true;
2649 }
2650 break;
2651 case T_TableFunc:
2652 {
2653 TableFunc *tf = (TableFunc *) node;
2654
2655 if (WALK(tf->ns_uris))
2656 return true;
2657 if (WALK(tf->docexpr))
2658 return true;
2659 if (WALK(tf->rowexpr))
2660 return true;
2661 if (WALK(tf->colexprs))
2662 return true;
2663 if (WALK(tf->coldefexprs))
2664 return true;
2665 if (WALK(tf->colvalexprs))
2666 return true;
2667 if (WALK(tf->passingvalexprs))
2668 return true;
2669 }
2670 break;
2671 default:
2672 elog(ERROR, "unrecognized node type: %d",
2673 (int) nodeTag(node));
2674 break;
2675 }
2676 return false;
2677
2678 /* The WALK() macro can be re-used below, but LIST_WALK() not so much */
2679#undef LIST_WALK
2680}
#define LIST_WALK(l)
#define WALK(n)
#define lfirst_node(type, lc)
Definition: pg_list.h:176
struct WindowDef * over
Definition: parsenodes.h:2012
JsonValueExpr * arg
Definition: parsenodes.h:2037
JsonAggConstructor * constructor
Definition: parsenodes.h:2036
JsonValueExpr * value
Definition: parsenodes.h:1920
JsonAggConstructor * constructor
Definition: parsenodes.h:2023
JsonKeyValue * arg
Definition: parsenodes.h:2024
Definition: type.h:89

References generate_unaccent_rules::action, JsonAggConstructor::agg_filter, JsonAggConstructor::agg_order, Aggref::aggdirectargs, Aggref::aggdistinct, Aggref::aggfilter, WindowFunc::aggfilter, Aggref::aggorder, OnConflictExpr::arbiterElems, OnConflictExpr::arbiterWhere, arg, JsonObjectAgg::arg, JsonArrayAgg::arg, WindowFuncRunCondition::arg, FieldStore::arg, ArrayCoerceExpr::arg, CaseExpr::arg, generate_unaccent_rules::args, TableSampleClause::args, Aggref::args, WindowFunc::args, FuncExpr::args, OpExpr::args, ScalarArrayOpExpr::args, BoolExpr::args, SubPlan::args, CaseExpr::args, XmlExpr::args, JsonConstructorExpr::args, check_stack_depth(), JsonConstructorExpr::coercion, TableFunc::colexprs, JsonObjectAgg::constructor, JsonArrayAgg::constructor, CommonTableExpr::ctequery, CTECycleClause::cycle_mark_default, CTECycleClause::cycle_mark_value, CaseExpr::defresult, TableFunc::docexpr, ArrayCoerceExpr::elemexpr, elog, WindowClause::endOffset, ERROR, OnConflictExpr::exclRelTlist, JsonBehavior::expr, JsonObjectConstructor::exprs, JsonArrayConstructor::exprs, PartitionPruneStepOp::exprs, JsonValueExpr::formatted_expr, JsonExpr::formatted_expr, FromExpr::fromlist, JsonConstructorExpr::func, IndexClause::indexquals, JsonKeyValue::key, SetOperationStmt::larg, JoinExpr::larg, RowCompareExpr::largs, lfirst, lfirst_node, LIST_WALK, PartitionBoundSpec::listdatums, PartitionBoundSpec::lowerdatums, XmlExpr::named_args, FieldStore::newvals, nodeTag, JsonExpr::on_empty, JsonExpr::on_error, OnConflictExpr::onConflictSet, OnConflictExpr::onConflictWhere, WindowClause::orderClause, JsonAggConstructor::over, WindowClause::partitionClause, JsonExpr::passing_values, JsonExpr::path_spec, JoinExpr::quals, FromExpr::quals, JsonArrayQueryConstructor::query, SetOperationStmt::rarg, JoinExpr::rarg, RowCompareExpr::rargs, JsonValueExpr::raw_expr, SubscriptingRef::refassgnexpr, SubscriptingRef::refexpr, SubscriptingRef::reflowerindexpr, SubscriptingRef::refupperindexpr, TableSampleClause::repeatable, IndexClause::rinfo, TableFunc::rowexpr, WindowClause::startOffset, SubLink::subselect, SubLink::testexpr, SubPlan::testexpr, AppendRelInfo::translated_vars, PartitionBoundSpec::upperdatums, PartitionRangeDatum::value, JsonKeyValue::value, and WALK.

◆ exprInputCollation()

Oid exprInputCollation ( const Node expr)

Definition at line 1076 of file nodeFuncs.c.

1077{
1078 Oid coll;
1079
1080 if (!expr)
1081 return InvalidOid;
1082
1083 switch (nodeTag(expr))
1084 {
1085 case T_Aggref:
1086 coll = ((const Aggref *) expr)->inputcollid;
1087 break;
1088 case T_WindowFunc:
1089 coll = ((const WindowFunc *) expr)->inputcollid;
1090 break;
1091 case T_FuncExpr:
1092 coll = ((const FuncExpr *) expr)->inputcollid;
1093 break;
1094 case T_OpExpr:
1095 coll = ((const OpExpr *) expr)->inputcollid;
1096 break;
1097 case T_DistinctExpr:
1098 coll = ((const DistinctExpr *) expr)->inputcollid;
1099 break;
1100 case T_NullIfExpr:
1101 coll = ((const NullIfExpr *) expr)->inputcollid;
1102 break;
1103 case T_ScalarArrayOpExpr:
1104 coll = ((const ScalarArrayOpExpr *) expr)->inputcollid;
1105 break;
1106 case T_MinMaxExpr:
1107 coll = ((const MinMaxExpr *) expr)->inputcollid;
1108 break;
1109 default:
1110 coll = InvalidOid;
1111 break;
1112 }
1113 return coll;
1114}

References InvalidOid, and nodeTag.

Referenced by check_simple_rowfilter_expr_walker(), and resolve_polymorphic_tupdesc().

◆ exprIsLengthCoercion()

bool exprIsLengthCoercion ( const Node expr,
int32 coercedTypmod 
)

Definition at line 557 of file nodeFuncs.c.

558{
559 if (coercedTypmod != NULL)
560 *coercedTypmod = -1; /* default result on failure */
561
562 /*
563 * Scalar-type length coercions are FuncExprs, array-type length coercions
564 * are ArrayCoerceExprs
565 */
566 if (expr && IsA(expr, FuncExpr))
567 {
568 const FuncExpr *func = (const FuncExpr *) expr;
569 int nargs;
570 Const *second_arg;
571
572 /*
573 * If it didn't come from a coercion context, reject.
574 */
575 if (func->funcformat != COERCE_EXPLICIT_CAST &&
576 func->funcformat != COERCE_IMPLICIT_CAST)
577 return false;
578
579 /*
580 * If it's not a two-argument or three-argument function with the
581 * second argument being an int4 constant, it can't have been created
582 * from a length coercion (it must be a type coercion, instead).
583 */
584 nargs = list_length(func->args);
585 if (nargs < 2 || nargs > 3)
586 return false;
587
588 second_arg = (Const *) lsecond(func->args);
589 if (!IsA(second_arg, Const) ||
590 second_arg->consttype != INT4OID ||
591 second_arg->constisnull)
592 return false;
593
594 /*
595 * OK, it is indeed a length-coercion function.
596 */
597 if (coercedTypmod != NULL)
598 *coercedTypmod = DatumGetInt32(second_arg->constvalue);
599
600 return true;
601 }
602
603 if (expr && IsA(expr, ArrayCoerceExpr))
604 {
605 const ArrayCoerceExpr *acoerce = (const ArrayCoerceExpr *) expr;
606
607 /* It's not a length coercion unless there's a nondefault typmod */
608 if (acoerce->resulttypmod < 0)
609 return false;
610
611 /*
612 * OK, it is indeed a length-coercion expression.
613 */
614 if (coercedTypmod != NULL)
615 *coercedTypmod = acoerce->resulttypmod;
616
617 return true;
618 }
619
620 return false;
621}
static int list_length(const List *l)
Definition: pg_list.h:152
#define lsecond(l)
Definition: pg_list.h:183
static int32 DatumGetInt32(Datum X)
Definition: postgres.h:207
@ COERCE_IMPLICIT_CAST
Definition: primnodes.h:752
@ COERCE_EXPLICIT_CAST
Definition: primnodes.h:751

References FuncExpr::args, COERCE_EXPLICIT_CAST, COERCE_IMPLICIT_CAST, Const::consttype, DatumGetInt32(), IsA, list_length(), and lsecond.

Referenced by deparseFuncExpr(), exprTypmod(), and get_func_expr().

◆ exprLocation()

int exprLocation ( const Node expr)

Definition at line 1388 of file nodeFuncs.c.

1389{
1390 int loc;
1391
1392 if (expr == NULL)
1393 return -1;
1394 switch (nodeTag(expr))
1395 {
1396 case T_RangeVar:
1397 loc = ((const RangeVar *) expr)->location;
1398 break;
1399 case T_TableFunc:
1400 loc = ((const TableFunc *) expr)->location;
1401 break;
1402 case T_Var:
1403 loc = ((const Var *) expr)->location;
1404 break;
1405 case T_Const:
1406 loc = ((const Const *) expr)->location;
1407 break;
1408 case T_Param:
1409 loc = ((const Param *) expr)->location;
1410 break;
1411 case T_Aggref:
1412 /* function name should always be the first thing */
1413 loc = ((const Aggref *) expr)->location;
1414 break;
1415 case T_GroupingFunc:
1416 loc = ((const GroupingFunc *) expr)->location;
1417 break;
1418 case T_WindowFunc:
1419 /* function name should always be the first thing */
1420 loc = ((const WindowFunc *) expr)->location;
1421 break;
1422 case T_MergeSupportFunc:
1423 loc = ((const MergeSupportFunc *) expr)->location;
1424 break;
1425 case T_SubscriptingRef:
1426 /* just use container argument's location */
1427 loc = exprLocation((Node *) ((const SubscriptingRef *) expr)->refexpr);
1428 break;
1429 case T_FuncExpr:
1430 {
1431 const FuncExpr *fexpr = (const FuncExpr *) expr;
1432
1433 /* consider both function name and leftmost arg */
1434 loc = leftmostLoc(fexpr->location,
1435 exprLocation((Node *) fexpr->args));
1436 }
1437 break;
1438 case T_NamedArgExpr:
1439 {
1440 const NamedArgExpr *na = (const NamedArgExpr *) expr;
1441
1442 /* consider both argument name and value */
1443 loc = leftmostLoc(na->location,
1444 exprLocation((Node *) na->arg));
1445 }
1446 break;
1447 case T_OpExpr:
1448 case T_DistinctExpr: /* struct-equivalent to OpExpr */
1449 case T_NullIfExpr: /* struct-equivalent to OpExpr */
1450 {
1451 const OpExpr *opexpr = (const OpExpr *) expr;
1452
1453 /* consider both operator name and leftmost arg */
1454 loc = leftmostLoc(opexpr->location,
1455 exprLocation((Node *) opexpr->args));
1456 }
1457 break;
1458 case T_ScalarArrayOpExpr:
1459 {
1460 const ScalarArrayOpExpr *saopexpr = (const ScalarArrayOpExpr *) expr;
1461
1462 /* consider both operator name and leftmost arg */
1463 loc = leftmostLoc(saopexpr->location,
1464 exprLocation((Node *) saopexpr->args));
1465 }
1466 break;
1467 case T_BoolExpr:
1468 {
1469 const BoolExpr *bexpr = (const BoolExpr *) expr;
1470
1471 /*
1472 * Same as above, to handle either NOT or AND/OR. We can't
1473 * special-case NOT because of the way that it's used for
1474 * things like IS NOT BETWEEN.
1475 */
1476 loc = leftmostLoc(bexpr->location,
1477 exprLocation((Node *) bexpr->args));
1478 }
1479 break;
1480 case T_SubLink:
1481 {
1482 const SubLink *sublink = (const SubLink *) expr;
1483
1484 /* check the testexpr, if any, and the operator/keyword */
1485 loc = leftmostLoc(exprLocation(sublink->testexpr),
1486 sublink->location);
1487 }
1488 break;
1489 case T_FieldSelect:
1490 /* just use argument's location */
1491 loc = exprLocation((Node *) ((const FieldSelect *) expr)->arg);
1492 break;
1493 case T_FieldStore:
1494 /* just use argument's location */
1495 loc = exprLocation((Node *) ((const FieldStore *) expr)->arg);
1496 break;
1497 case T_RelabelType:
1498 {
1499 const RelabelType *rexpr = (const RelabelType *) expr;
1500
1501 /* Much as above */
1502 loc = leftmostLoc(rexpr->location,
1503 exprLocation((Node *) rexpr->arg));
1504 }
1505 break;
1506 case T_CoerceViaIO:
1507 {
1508 const CoerceViaIO *cexpr = (const CoerceViaIO *) expr;
1509
1510 /* Much as above */
1511 loc = leftmostLoc(cexpr->location,
1512 exprLocation((Node *) cexpr->arg));
1513 }
1514 break;
1515 case T_ArrayCoerceExpr:
1516 {
1517 const ArrayCoerceExpr *cexpr = (const ArrayCoerceExpr *) expr;
1518
1519 /* Much as above */
1520 loc = leftmostLoc(cexpr->location,
1521 exprLocation((Node *) cexpr->arg));
1522 }
1523 break;
1524 case T_ConvertRowtypeExpr:
1525 {
1526 const ConvertRowtypeExpr *cexpr = (const ConvertRowtypeExpr *) expr;
1527
1528 /* Much as above */
1529 loc = leftmostLoc(cexpr->location,
1530 exprLocation((Node *) cexpr->arg));
1531 }
1532 break;
1533 case T_CollateExpr:
1534 /* just use argument's location */
1535 loc = exprLocation((Node *) ((const CollateExpr *) expr)->arg);
1536 break;
1537 case T_CaseExpr:
1538 /* CASE keyword should always be the first thing */
1539 loc = ((const CaseExpr *) expr)->location;
1540 break;
1541 case T_CaseWhen:
1542 /* WHEN keyword should always be the first thing */
1543 loc = ((const CaseWhen *) expr)->location;
1544 break;
1545 case T_ArrayExpr:
1546 /* the location points at ARRAY or [, which must be leftmost */
1547 loc = ((const ArrayExpr *) expr)->location;
1548 break;
1549 case T_RowExpr:
1550 /* the location points at ROW or (, which must be leftmost */
1551 loc = ((const RowExpr *) expr)->location;
1552 break;
1553 case T_RowCompareExpr:
1554 /* just use leftmost argument's location */
1555 loc = exprLocation((Node *) ((const RowCompareExpr *) expr)->largs);
1556 break;
1557 case T_CoalesceExpr:
1558 /* COALESCE keyword should always be the first thing */
1559 loc = ((const CoalesceExpr *) expr)->location;
1560 break;
1561 case T_MinMaxExpr:
1562 /* GREATEST/LEAST keyword should always be the first thing */
1563 loc = ((const MinMaxExpr *) expr)->location;
1564 break;
1565 case T_SQLValueFunction:
1566 /* function keyword should always be the first thing */
1567 loc = ((const SQLValueFunction *) expr)->location;
1568 break;
1569 case T_XmlExpr:
1570 {
1571 const XmlExpr *xexpr = (const XmlExpr *) expr;
1572
1573 /* consider both function name and leftmost arg */
1574 loc = leftmostLoc(xexpr->location,
1575 exprLocation((Node *) xexpr->args));
1576 }
1577 break;
1578 case T_JsonFormat:
1579 loc = ((const JsonFormat *) expr)->location;
1580 break;
1581 case T_JsonValueExpr:
1582 loc = exprLocation((Node *) ((const JsonValueExpr *) expr)->raw_expr);
1583 break;
1584 case T_JsonConstructorExpr:
1585 loc = ((const JsonConstructorExpr *) expr)->location;
1586 break;
1587 case T_JsonIsPredicate:
1588 loc = ((const JsonIsPredicate *) expr)->location;
1589 break;
1590 case T_JsonExpr:
1591 {
1592 const JsonExpr *jsexpr = (const JsonExpr *) expr;
1593
1594 /* consider both function name and leftmost arg */
1595 loc = leftmostLoc(jsexpr->location,
1596 exprLocation(jsexpr->formatted_expr));
1597 }
1598 break;
1599 case T_JsonBehavior:
1600 loc = exprLocation(((JsonBehavior *) expr)->expr);
1601 break;
1602 case T_NullTest:
1603 {
1604 const NullTest *nexpr = (const NullTest *) expr;
1605
1606 /* Much as above */
1607 loc = leftmostLoc(nexpr->location,
1608 exprLocation((Node *) nexpr->arg));
1609 }
1610 break;
1611 case T_BooleanTest:
1612 {
1613 const BooleanTest *bexpr = (const BooleanTest *) expr;
1614
1615 /* Much as above */
1616 loc = leftmostLoc(bexpr->location,
1617 exprLocation((Node *) bexpr->arg));
1618 }
1619 break;
1620 case T_CoerceToDomain:
1621 {
1622 const CoerceToDomain *cexpr = (const CoerceToDomain *) expr;
1623
1624 /* Much as above */
1625 loc = leftmostLoc(cexpr->location,
1626 exprLocation((Node *) cexpr->arg));
1627 }
1628 break;
1629 case T_CoerceToDomainValue:
1630 loc = ((const CoerceToDomainValue *) expr)->location;
1631 break;
1632 case T_SetToDefault:
1633 loc = ((const SetToDefault *) expr)->location;
1634 break;
1635 case T_ReturningExpr:
1636 loc = exprLocation((Node *) ((const ReturningExpr *) expr)->retexpr);
1637 break;
1638 case T_TargetEntry:
1639 /* just use argument's location */
1640 loc = exprLocation((Node *) ((const TargetEntry *) expr)->expr);
1641 break;
1642 case T_IntoClause:
1643 /* use the contained RangeVar's location --- close enough */
1644 loc = exprLocation((Node *) ((const IntoClause *) expr)->rel);
1645 break;
1646 case T_List:
1647 {
1648 /* report location of first list member that has a location */
1649 ListCell *lc;
1650
1651 loc = -1; /* just to suppress compiler warning */
1652 foreach(lc, (const List *) expr)
1653 {
1654 loc = exprLocation((Node *) lfirst(lc));
1655 if (loc >= 0)
1656 break;
1657 }
1658 }
1659 break;
1660 case T_A_Expr:
1661 {
1662 const A_Expr *aexpr = (const A_Expr *) expr;
1663
1664 /* use leftmost of operator or left operand (if any) */
1665 /* we assume right operand can't be to left of operator */
1666 loc = leftmostLoc(aexpr->location,
1667 exprLocation(aexpr->lexpr));
1668 }
1669 break;
1670 case T_ColumnRef:
1671 loc = ((const ColumnRef *) expr)->location;
1672 break;
1673 case T_ParamRef:
1674 loc = ((const ParamRef *) expr)->location;
1675 break;
1676 case T_A_Const:
1677 loc = ((const A_Const *) expr)->location;
1678 break;
1679 case T_FuncCall:
1680 {
1681 const FuncCall *fc = (const FuncCall *) expr;
1682
1683 /* consider both function name and leftmost arg */
1684 /* (we assume any ORDER BY nodes must be to right of name) */
1685 loc = leftmostLoc(fc->location,
1686 exprLocation((Node *) fc->args));
1687 }
1688 break;
1689 case T_A_ArrayExpr:
1690 /* the location points at ARRAY or [, which must be leftmost */
1691 loc = ((const A_ArrayExpr *) expr)->location;
1692 break;
1693 case T_ResTarget:
1694 /* we need not examine the contained expression (if any) */
1695 loc = ((const ResTarget *) expr)->location;
1696 break;
1697 case T_MultiAssignRef:
1698 loc = exprLocation(((const MultiAssignRef *) expr)->source);
1699 break;
1700 case T_TypeCast:
1701 {
1702 const TypeCast *tc = (const TypeCast *) expr;
1703
1704 /*
1705 * This could represent CAST(), ::, or TypeName 'literal', so
1706 * any of the components might be leftmost.
1707 */
1708 loc = exprLocation(tc->arg);
1709 loc = leftmostLoc(loc, tc->typeName->location);
1710 loc = leftmostLoc(loc, tc->location);
1711 }
1712 break;
1713 case T_CollateClause:
1714 /* just use argument's location */
1715 loc = exprLocation(((const CollateClause *) expr)->arg);
1716 break;
1717 case T_SortBy:
1718 /* just use argument's location (ignore operator, if any) */
1719 loc = exprLocation(((const SortBy *) expr)->node);
1720 break;
1721 case T_WindowDef:
1722 loc = ((const WindowDef *) expr)->location;
1723 break;
1724 case T_RangeTableSample:
1725 loc = ((const RangeTableSample *) expr)->location;
1726 break;
1727 case T_TypeName:
1728 loc = ((const TypeName *) expr)->location;
1729 break;
1730 case T_ColumnDef:
1731 loc = ((const ColumnDef *) expr)->location;
1732 break;
1733 case T_Constraint:
1734 loc = ((const Constraint *) expr)->location;
1735 break;
1736 case T_FunctionParameter:
1737 loc = ((const FunctionParameter *) expr)->location;
1738 break;
1739 case T_XmlSerialize:
1740 /* XMLSERIALIZE keyword should always be the first thing */
1741 loc = ((const XmlSerialize *) expr)->location;
1742 break;
1743 case T_GroupingSet:
1744 loc = ((const GroupingSet *) expr)->location;
1745 break;
1746 case T_WithClause:
1747 loc = ((const WithClause *) expr)->location;
1748 break;
1749 case T_InferClause:
1750 loc = ((const InferClause *) expr)->location;
1751 break;
1752 case T_OnConflictClause:
1753 loc = ((const OnConflictClause *) expr)->location;
1754 break;
1755 case T_CTESearchClause:
1756 loc = ((const CTESearchClause *) expr)->location;
1757 break;
1758 case T_CTECycleClause:
1759 loc = ((const CTECycleClause *) expr)->location;
1760 break;
1761 case T_CommonTableExpr:
1762 loc = ((const CommonTableExpr *) expr)->location;
1763 break;
1764 case T_JsonKeyValue:
1765 /* just use the key's location */
1766 loc = exprLocation((Node *) ((const JsonKeyValue *) expr)->key);
1767 break;
1768 case T_JsonObjectConstructor:
1769 loc = ((const JsonObjectConstructor *) expr)->location;
1770 break;
1771 case T_JsonArrayConstructor:
1772 loc = ((const JsonArrayConstructor *) expr)->location;
1773 break;
1774 case T_JsonArrayQueryConstructor:
1775 loc = ((const JsonArrayQueryConstructor *) expr)->location;
1776 break;
1777 case T_JsonAggConstructor:
1778 loc = ((const JsonAggConstructor *) expr)->location;
1779 break;
1780 case T_JsonObjectAgg:
1781 loc = exprLocation((Node *) ((const JsonObjectAgg *) expr)->constructor);
1782 break;
1783 case T_JsonArrayAgg:
1784 loc = exprLocation((Node *) ((const JsonArrayAgg *) expr)->constructor);
1785 break;
1786 case T_PlaceHolderVar:
1787 /* just use argument's location */
1788 loc = exprLocation((Node *) ((const PlaceHolderVar *) expr)->phexpr);
1789 break;
1790 case T_InferenceElem:
1791 /* just use nested expr's location */
1792 loc = exprLocation((Node *) ((const InferenceElem *) expr)->expr);
1793 break;
1794 case T_PartitionElem:
1795 loc = ((const PartitionElem *) expr)->location;
1796 break;
1797 case T_PartitionSpec:
1798 loc = ((const PartitionSpec *) expr)->location;
1799 break;
1800 case T_PartitionBoundSpec:
1801 loc = ((const PartitionBoundSpec *) expr)->location;
1802 break;
1803 case T_PartitionRangeDatum:
1804 loc = ((const PartitionRangeDatum *) expr)->location;
1805 break;
1806 default:
1807 /* for any other node type it's just unknown... */
1808 loc = -1;
1809 break;
1810 }
1811 return loc;
1812}
static int leftmostLoc(int loc1, int loc2)
Definition: nodeFuncs.c:1820
int exprLocation(const Node *expr)
Definition: nodeFuncs.c:1388
static rewind_source * source
Definition: pg_rewind.c:89
static int fc(const char *x)
Definition: preproc-init.c:99
ParseLoc location
Definition: parsenodes.h:349
Node * lexpr
Definition: parsenodes.h:347
ParseLoc location
Definition: primnodes.h:1258
ParseLoc location
Definition: primnodes.h:957
ParseLoc location
Definition: primnodes.h:2015
ParseLoc location
Definition: primnodes.h:2067
ParseLoc location
Definition: primnodes.h:1230
ParseLoc location
Definition: primnodes.h:786
ParseLoc location
Definition: primnodes.h:1890
ParseLoc location
Definition: primnodes.h:813
ParseLoc location
Definition: primnodes.h:1993
ParseLoc location
Definition: primnodes.h:855
ParseLoc location
Definition: primnodes.h:935
TypeName * typeName
Definition: parsenodes.h:385
ParseLoc location
Definition: parsenodes.h:386
Node * arg
Definition: parsenodes.h:384
ParseLoc location
Definition: parsenodes.h:286
ParseLoc location
Definition: primnodes.h:1648

References arg, TypeCast::arg, NamedArgExpr::arg, RelabelType::arg, CoerceViaIO::arg, ArrayCoerceExpr::arg, ConvertRowtypeExpr::arg, NullTest::arg, BooleanTest::arg, CoerceToDomain::arg, FuncExpr::args, OpExpr::args, ScalarArrayOpExpr::args, BoolExpr::args, XmlExpr::args, exprLocation(), fc(), JsonExpr::formatted_expr, sort-test::key, leftmostLoc(), A_Expr::lexpr, lfirst, TypeName::location, A_Expr::location, TypeCast::location, FuncExpr::location, NamedArgExpr::location, OpExpr::location, ScalarArrayOpExpr::location, BoolExpr::location, SubLink::location, RelabelType::location, CoerceViaIO::location, ArrayCoerceExpr::location, ConvertRowtypeExpr::location, XmlExpr::location, JsonExpr::location, NullTest::location, BooleanTest::location, CoerceToDomain::location, nodeTag, source, SubLink::testexpr, and TypeCast::typeName.

Referenced by addRangeTableEntryForFunction(), addRangeTableEntryForTableFunc(), addTargetToSortList(), analyzeCTE(), array_subscript_transform(), assign_collations_walker(), check_agg_arguments_walker(), check_simple_rowfilter_expr_walker(), check_srf_call_placement(), checkWellFormedRecursion(), coerce_to_boolean(), coerce_to_common_type(), coerce_to_specific_type_typmod(), coerceJsonFuncExpr(), EvaluateParams(), ExecInitFunc(), ExecInitSubscriptingRef(), exprLocation(), finalize_grouping_exprs_walker(), get_matching_location(), hstore_subscript_transform(), init_sexpr(), jsonb_subscript_transform(), parseCheckAggregates(), ParseFuncOrColumn(), parser_coercion_errposition(), replace_outer_returning(), resolve_unique_index_expr(), select_common_type(), transformAggregateCall(), transformArrayExpr(), transformAssignedExpr(), transformCaseExpr(), transformCoalesceExpr(), transformContainerSubscripts(), transformDistinctClause(), transformDistinctOnClause(), transformFrameOffset(), transformFromClauseItem(), transformGroupClause(), transformGroupClauseExpr(), transformGroupingSet(), transformIndirection(), transformInsertRow(), transformInsertStmt(), transformJsonBehavior(), transformJsonFuncExpr(), transformJsonParseArg(), transformJsonValueExpr(), transformMultiAssignRef(), transformOnConflictArbiter(), transformPartitionBound(), transformPartitionBoundValue(), transformPartitionRangeBounds(), transformPLAssignStmt(), transformRangeFunction(), transformReturningClause(), transformSelectStmt(), transformSetOperationStmt(), transformSetOperationTree(), transformValuesClause(), and validateInfiniteBounds().

◆ exprSetCollation()

void exprSetCollation ( Node expr,
Oid  collation 
)

Definition at line 1124 of file nodeFuncs.c.

1125{
1126 switch (nodeTag(expr))
1127 {
1128 case T_Var:
1129 ((Var *) expr)->varcollid = collation;
1130 break;
1131 case T_Const:
1132 ((Const *) expr)->constcollid = collation;
1133 break;
1134 case T_Param:
1135 ((Param *) expr)->paramcollid = collation;
1136 break;
1137 case T_Aggref:
1138 ((Aggref *) expr)->aggcollid = collation;
1139 break;
1140 case T_GroupingFunc:
1141 Assert(!OidIsValid(collation));
1142 break;
1143 case T_WindowFunc:
1144 ((WindowFunc *) expr)->wincollid = collation;
1145 break;
1146 case T_MergeSupportFunc:
1147 ((MergeSupportFunc *) expr)->msfcollid = collation;
1148 break;
1149 case T_SubscriptingRef:
1150 ((SubscriptingRef *) expr)->refcollid = collation;
1151 break;
1152 case T_FuncExpr:
1153 ((FuncExpr *) expr)->funccollid = collation;
1154 break;
1155 case T_NamedArgExpr:
1156 Assert(collation == exprCollation((Node *) ((NamedArgExpr *) expr)->arg));
1157 break;
1158 case T_OpExpr:
1159 ((OpExpr *) expr)->opcollid = collation;
1160 break;
1161 case T_DistinctExpr:
1162 ((DistinctExpr *) expr)->opcollid = collation;
1163 break;
1164 case T_NullIfExpr:
1165 ((NullIfExpr *) expr)->opcollid = collation;
1166 break;
1167 case T_ScalarArrayOpExpr:
1168 /* ScalarArrayOpExpr's result is boolean ... */
1169 Assert(!OidIsValid(collation)); /* ... so never set a collation */
1170 break;
1171 case T_BoolExpr:
1172 /* BoolExpr's result is boolean ... */
1173 Assert(!OidIsValid(collation)); /* ... so never set a collation */
1174 break;
1175 case T_SubLink:
1176#ifdef USE_ASSERT_CHECKING
1177 {
1178 SubLink *sublink = (SubLink *) expr;
1179
1180 if (sublink->subLinkType == EXPR_SUBLINK ||
1181 sublink->subLinkType == ARRAY_SUBLINK)
1182 {
1183 /* get the collation of subselect's first target column */
1184 Query *qtree = (Query *) sublink->subselect;
1185 TargetEntry *tent;
1186
1187 if (!qtree || !IsA(qtree, Query))
1188 elog(ERROR, "cannot set collation for untransformed sublink");
1189 tent = linitial_node(TargetEntry, qtree->targetList);
1190 Assert(!tent->resjunk);
1191 Assert(collation == exprCollation((Node *) tent->expr));
1192 }
1193 else
1194 {
1195 /* otherwise, result is RECORD or BOOLEAN */
1196 Assert(!OidIsValid(collation));
1197 }
1198 }
1199#endif /* USE_ASSERT_CHECKING */
1200 break;
1201 case T_FieldSelect:
1202 ((FieldSelect *) expr)->resultcollid = collation;
1203 break;
1204 case T_FieldStore:
1205 /* FieldStore's result is composite ... */
1206 Assert(!OidIsValid(collation)); /* ... so never set a collation */
1207 break;
1208 case T_RelabelType:
1209 ((RelabelType *) expr)->resultcollid = collation;
1210 break;
1211 case T_CoerceViaIO:
1212 ((CoerceViaIO *) expr)->resultcollid = collation;
1213 break;
1214 case T_ArrayCoerceExpr:
1215 ((ArrayCoerceExpr *) expr)->resultcollid = collation;
1216 break;
1217 case T_ConvertRowtypeExpr:
1218 /* ConvertRowtypeExpr's result is composite ... */
1219 Assert(!OidIsValid(collation)); /* ... so never set a collation */
1220 break;
1221 case T_CaseExpr:
1222 ((CaseExpr *) expr)->casecollid = collation;
1223 break;
1224 case T_ArrayExpr:
1225 ((ArrayExpr *) expr)->array_collid = collation;
1226 break;
1227 case T_RowExpr:
1228 /* RowExpr's result is composite ... */
1229 Assert(!OidIsValid(collation)); /* ... so never set a collation */
1230 break;
1231 case T_RowCompareExpr:
1232 /* RowCompareExpr's result is boolean ... */
1233 Assert(!OidIsValid(collation)); /* ... so never set a collation */
1234 break;
1235 case T_CoalesceExpr:
1236 ((CoalesceExpr *) expr)->coalescecollid = collation;
1237 break;
1238 case T_MinMaxExpr:
1239 ((MinMaxExpr *) expr)->minmaxcollid = collation;
1240 break;
1241 case T_SQLValueFunction:
1242 Assert((((SQLValueFunction *) expr)->type == NAMEOID) ?
1243 (collation == C_COLLATION_OID) :
1244 (collation == InvalidOid));
1245 break;
1246 case T_XmlExpr:
1247 Assert((((XmlExpr *) expr)->op == IS_XMLSERIALIZE) ?
1248 (collation == DEFAULT_COLLATION_OID) :
1249 (collation == InvalidOid));
1250 break;
1251 case T_JsonValueExpr:
1252 exprSetCollation((Node *) ((JsonValueExpr *) expr)->formatted_expr,
1253 collation);
1254 break;
1255 case T_JsonConstructorExpr:
1256 {
1258
1259 if (ctor->coercion)
1260 exprSetCollation((Node *) ctor->coercion, collation);
1261 else
1262 Assert(!OidIsValid(collation)); /* result is always a
1263 * json[b] type */
1264 }
1265 break;
1266 case T_JsonIsPredicate:
1267 Assert(!OidIsValid(collation)); /* result is always boolean */
1268 break;
1269 case T_JsonExpr:
1270 {
1271 JsonExpr *jexpr = (JsonExpr *) expr;
1272
1273 jexpr->collation = collation;
1274 }
1275 break;
1276 case T_JsonBehavior:
1277 {
1278 JsonBehavior *behavior = (JsonBehavior *) expr;
1279
1280 if (behavior->expr)
1281 exprSetCollation(behavior->expr, collation);
1282 }
1283 break;
1284 case T_NullTest:
1285 /* NullTest's result is boolean ... */
1286 Assert(!OidIsValid(collation)); /* ... so never set a collation */
1287 break;
1288 case T_BooleanTest:
1289 /* BooleanTest's result is boolean ... */
1290 Assert(!OidIsValid(collation)); /* ... so never set a collation */
1291 break;
1292 case T_CoerceToDomain:
1293 ((CoerceToDomain *) expr)->resultcollid = collation;
1294 break;
1295 case T_CoerceToDomainValue:
1296 ((CoerceToDomainValue *) expr)->collation = collation;
1297 break;
1298 case T_SetToDefault:
1299 ((SetToDefault *) expr)->collation = collation;
1300 break;
1301 case T_CurrentOfExpr:
1302 /* CurrentOfExpr's result is boolean ... */
1303 Assert(!OidIsValid(collation)); /* ... so never set a collation */
1304 break;
1305 case T_NextValueExpr:
1306 /* NextValueExpr's result is an integer type ... */
1307 Assert(!OidIsValid(collation)); /* ... so never set a collation */
1308 break;
1309 default:
1310 elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
1311 break;
1312 }
1313}
#define OidIsValid(objectId)
Definition: c.h:732
void exprSetCollation(Node *expr, Oid collation)
Definition: nodeFuncs.c:1124

References arg, ARRAY_SUBLINK, Assert, JsonConstructorExpr::coercion, JsonExpr::collation, elog, ERROR, JsonBehavior::expr, EXPR_SUBLINK, exprCollation(), exprSetCollation(), if(), InvalidOid, IS_XMLSERIALIZE, IsA, linitial_node, nodeTag, OidIsValid, SubLink::subLinkType, SubLink::subselect, Query::targetList, and type.

Referenced by assign_collations_walker(), and exprSetCollation().

◆ exprSetInputCollation()

void exprSetInputCollation ( Node expr,
Oid  inputcollation 
)

Definition at line 1324 of file nodeFuncs.c.

1325{
1326 switch (nodeTag(expr))
1327 {
1328 case T_Aggref:
1329 ((Aggref *) expr)->inputcollid = inputcollation;
1330 break;
1331 case T_WindowFunc:
1332 ((WindowFunc *) expr)->inputcollid = inputcollation;
1333 break;
1334 case T_FuncExpr:
1335 ((FuncExpr *) expr)->inputcollid = inputcollation;
1336 break;
1337 case T_OpExpr:
1338 ((OpExpr *) expr)->inputcollid = inputcollation;
1339 break;
1340 case T_DistinctExpr:
1341 ((DistinctExpr *) expr)->inputcollid = inputcollation;
1342 break;
1343 case T_NullIfExpr:
1344 ((NullIfExpr *) expr)->inputcollid = inputcollation;
1345 break;
1346 case T_ScalarArrayOpExpr:
1347 ((ScalarArrayOpExpr *) expr)->inputcollid = inputcollation;
1348 break;
1349 case T_MinMaxExpr:
1350 ((MinMaxExpr *) expr)->inputcollid = inputcollation;
1351 break;
1352 default:
1353 break;
1354 }
1355}

References nodeTag.

Referenced by assign_collations_walker().

◆ exprType()

Oid exprType ( const Node expr)

Definition at line 42 of file nodeFuncs.c.

43{
44 Oid type;
45
46 if (!expr)
47 return InvalidOid;
48
49 switch (nodeTag(expr))
50 {
51 case T_Var:
52 type = ((const Var *) expr)->vartype;
53 break;
54 case T_Const:
55 type = ((const Const *) expr)->consttype;
56 break;
57 case T_Param:
58 type = ((const Param *) expr)->paramtype;
59 break;
60 case T_Aggref:
61 type = ((const Aggref *) expr)->aggtype;
62 break;
63 case T_GroupingFunc:
64 type = INT4OID;
65 break;
66 case T_WindowFunc:
67 type = ((const WindowFunc *) expr)->wintype;
68 break;
69 case T_MergeSupportFunc:
70 type = ((const MergeSupportFunc *) expr)->msftype;
71 break;
72 case T_SubscriptingRef:
73 type = ((const SubscriptingRef *) expr)->refrestype;
74 break;
75 case T_FuncExpr:
76 type = ((const FuncExpr *) expr)->funcresulttype;
77 break;
78 case T_NamedArgExpr:
79 type = exprType((Node *) ((const NamedArgExpr *) expr)->arg);
80 break;
81 case T_OpExpr:
82 type = ((const OpExpr *) expr)->opresulttype;
83 break;
84 case T_DistinctExpr:
85 type = ((const DistinctExpr *) expr)->opresulttype;
86 break;
87 case T_NullIfExpr:
88 type = ((const NullIfExpr *) expr)->opresulttype;
89 break;
90 case T_ScalarArrayOpExpr:
91 type = BOOLOID;
92 break;
93 case T_BoolExpr:
94 type = BOOLOID;
95 break;
96 case T_SubLink:
97 {
98 const SubLink *sublink = (const SubLink *) expr;
99
100 if (sublink->subLinkType == EXPR_SUBLINK ||
101 sublink->subLinkType == ARRAY_SUBLINK)
102 {
103 /* get the type of the subselect's first target column */
104 Query *qtree = (Query *) sublink->subselect;
105 TargetEntry *tent;
106
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)
113 {
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)))));
120 }
121 }
122 else if (sublink->subLinkType == MULTIEXPR_SUBLINK)
123 {
124 /* MULTIEXPR is always considered to return RECORD */
125 type = RECORDOID;
126 }
127 else
128 {
129 /* for all other sublink types, result is boolean */
130 type = BOOLOID;
131 }
132 }
133 break;
134 case T_SubPlan:
135 {
136 const SubPlan *subplan = (const SubPlan *) expr;
137
138 if (subplan->subLinkType == EXPR_SUBLINK ||
139 subplan->subLinkType == ARRAY_SUBLINK)
140 {
141 /* get the type of the subselect's first target column */
142 type = subplan->firstColType;
143 if (subplan->subLinkType == ARRAY_SUBLINK)
144 {
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))));
151 }
152 }
153 else if (subplan->subLinkType == MULTIEXPR_SUBLINK)
154 {
155 /* MULTIEXPR is always considered to return RECORD */
156 type = RECORDOID;
157 }
158 else
159 {
160 /* for all other subplan types, result is boolean */
161 type = BOOLOID;
162 }
163 }
164 break;
165 case T_AlternativeSubPlan:
166 {
167 const AlternativeSubPlan *asplan = (const AlternativeSubPlan *) expr;
168
169 /* subplans should all return the same thing */
170 type = exprType((Node *) linitial(asplan->subplans));
171 }
172 break;
173 case T_FieldSelect:
174 type = ((const FieldSelect *) expr)->resulttype;
175 break;
176 case T_FieldStore:
177 type = ((const FieldStore *) expr)->resulttype;
178 break;
179 case T_RelabelType:
180 type = ((const RelabelType *) expr)->resulttype;
181 break;
182 case T_CoerceViaIO:
183 type = ((const CoerceViaIO *) expr)->resulttype;
184 break;
185 case T_ArrayCoerceExpr:
186 type = ((const ArrayCoerceExpr *) expr)->resulttype;
187 break;
188 case T_ConvertRowtypeExpr:
189 type = ((const ConvertRowtypeExpr *) expr)->resulttype;
190 break;
191 case T_CollateExpr:
192 type = exprType((Node *) ((const CollateExpr *) expr)->arg);
193 break;
194 case T_CaseExpr:
195 type = ((const CaseExpr *) expr)->casetype;
196 break;
197 case T_CaseTestExpr:
198 type = ((const CaseTestExpr *) expr)->typeId;
199 break;
200 case T_ArrayExpr:
201 type = ((const ArrayExpr *) expr)->array_typeid;
202 break;
203 case T_RowExpr:
204 type = ((const RowExpr *) expr)->row_typeid;
205 break;
206 case T_RowCompareExpr:
207 type = BOOLOID;
208 break;
209 case T_CoalesceExpr:
210 type = ((const CoalesceExpr *) expr)->coalescetype;
211 break;
212 case T_MinMaxExpr:
213 type = ((const MinMaxExpr *) expr)->minmaxtype;
214 break;
215 case T_SQLValueFunction:
216 type = ((const SQLValueFunction *) expr)->type;
217 break;
218 case T_XmlExpr:
219 if (((const XmlExpr *) expr)->op == IS_DOCUMENT)
220 type = BOOLOID;
221 else if (((const XmlExpr *) expr)->op == IS_XMLSERIALIZE)
222 type = TEXTOID;
223 else
224 type = XMLOID;
225 break;
226 case T_JsonValueExpr:
227 {
228 const JsonValueExpr *jve = (const JsonValueExpr *) expr;
229
230 type = exprType((Node *) jve->formatted_expr);
231 }
232 break;
233 case T_JsonConstructorExpr:
234 type = ((const JsonConstructorExpr *) expr)->returning->typid;
235 break;
236 case T_JsonIsPredicate:
237 type = BOOLOID;
238 break;
239 case T_JsonExpr:
240 {
241 const JsonExpr *jexpr = (const JsonExpr *) expr;
242
243 type = jexpr->returning->typid;
244 break;
245 }
246 case T_JsonBehavior:
247 {
248 const JsonBehavior *behavior = (const JsonBehavior *) expr;
249
250 type = exprType(behavior->expr);
251 break;
252 }
253 case T_NullTest:
254 type = BOOLOID;
255 break;
256 case T_BooleanTest:
257 type = BOOLOID;
258 break;
259 case T_CoerceToDomain:
260 type = ((const CoerceToDomain *) expr)->resulttype;
261 break;
262 case T_CoerceToDomainValue:
263 type = ((const CoerceToDomainValue *) expr)->typeId;
264 break;
265 case T_SetToDefault:
266 type = ((const SetToDefault *) expr)->typeId;
267 break;
268 case T_CurrentOfExpr:
269 type = BOOLOID;
270 break;
271 case T_NextValueExpr:
272 type = ((const NextValueExpr *) expr)->typeId;
273 break;
274 case T_InferenceElem:
275 {
276 const InferenceElem *n = (const InferenceElem *) expr;
277
278 type = exprType((Node *) n->expr);
279 }
280 break;
281 case T_ReturningExpr:
282 type = exprType((Node *) ((const ReturningExpr *) expr)->retexpr);
283 break;
284 case T_PlaceHolderVar:
285 type = exprType((Node *) ((const PlaceHolderVar *) expr)->phexpr);
286 break;
287 default:
288 elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
289 type = InvalidOid; /* keep compiler quiet */
290 break;
291 }
292 return type;
293}
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ereport(elevel,...)
Definition: elog.h:149
char * format_type_be(Oid type_oid)
Definition: format_type.c:343
Oid get_promoted_array_type(Oid typid)
Definition: lsyscache.c:2811
@ MULTIEXPR_SUBLINK
Definition: primnodes.h:1018
@ IS_DOCUMENT
Definition: primnodes.h:1618
JsonReturning * returning
Definition: primnodes.h:1863
Oid firstColType
Definition: primnodes.h:1090

References arg, ARRAY_SUBLINK, Assert, elog, ereport, errcode(), errmsg(), ERROR, JsonBehavior::expr, InferenceElem::expr, EXPR_SUBLINK, exprType(), SubPlan::firstColType, format_type_be(), JsonValueExpr::formatted_expr, get_promoted_array_type(), if(), InvalidOid, IS_DOCUMENT, IS_XMLSERIALIZE, IsA, linitial, linitial_node, MULTIEXPR_SUBLINK, nodeTag, OidIsValid, JsonExpr::returning, SubLink::subLinkType, SubPlan::subLinkType, AlternativeSubPlan::subplans, SubLink::subselect, Query::targetList, type, and JsonReturning::typid.

Referenced by add_row_identity_var(), add_setop_child_rel_equivalences(), addRangeTableEntryForFunction(), addRangeTableEntryForGroup(), addRangeTableEntryForSubquery(), addTargetToGroupList(), addTargetToSortList(), agg_args_support_sendreceive(), analyzeCTE(), analyzeCTETargetList(), appendAggOrderBy(), appendOrderByClause(), applyRelabelType(), array_subscript_transform(), assign_collations_walker(), assign_hypothetical_collations(), assign_param_for_placeholdervar(), ATExecAlterColumnType(), ATPrepAlterColumnType(), build_coercion_expression(), build_column_default(), build_subplan(), calculate_frame_offsets(), CallStmtResultDesc(), can_minmax_aggs(), canonicalize_ec_expression(), check_functions_in_node(), check_hashjoinable(), check_memoizable(), check_mergejoinable(), check_simple_rowfilter_expr_walker(), check_sql_fn_retval(), checkRuleResultList(), coerce_fn_result_column(), coerce_record_to_complex(), coerce_to_boolean(), coerce_to_common_type(), coerce_to_specific_type_typmod(), coerceJsonFuncExpr(), compare_tlist_datatypes(), compute_semijoin_info(), ComputeIndexAttrs(), ComputePartitionAttrs(), ConstructTupleDescriptor(), contain_mutable_functions_walker(), convert_EXISTS_to_ANY(), cookDefault(), cost_qual_eval_walker(), create_ctas_nodata(), create_indexscan_plan(), CreateStatistics(), DefineVirtualRelation(), deparseNullTest(), deparseOpExpr(), estimate_num_groups(), eval_const_expressions_mutator(), EvaluateParams(), examine_attribute(), examine_expression(), examine_variable(), exec_save_simple_expr(), ExecBuildProjectionInfo(), ExecBuildUpdateProjection(), ExecCheckPlanOutput(), ExecEvalJsonIsPredicate(), ExecEvalXmlExpr(), ExecInitExprRec(), ExecInitIndexScan(), ExecInitJsonExpr(), ExecInitSubPlanExpr(), ExecMakeTableFunctionResult(), ExecTypeFromExprList(), ExecTypeFromTLInternal(), expandRecordVariable(), expandRTE(), exprType(), exprTypmod(), find_expr_references_walker(), find_placeholder_info(), fix_indexqual_operand(), foreign_expr_walker(), generate_append_tlist(), generate_join_implied_equalities_normal(), generate_setop_child_grouplist(), generate_setop_tlist(), generate_subquery_params(), generateClonedIndexStmt(), get_attr_stat_type(), get_call_expr_argtype(), get_expr_result_tupdesc(), get_expr_result_type(), get_expr_width(), get_first_col_type(), get_fn_expr_rettype(), get_func_expr(), get_oper_expr(), get_rule_expr(), get_rule_expr_funccall(), get_rule_orderby(), get_simple_binary_op_name(), get_sublink_expr(), get_windowfunc_expr_helper(), GetIndexInputType(), hash_ok_operator(), hstore_subscript_transform(), initialize_peragg(), inline_function(), internal_get_result_type(), jsonb_exec_setup(), jsonb_subscript_transform(), JsonTableInitOpaque(), jspIsMutableWalker(), make_op(), make_scalar_array_op(), makeJsonConstructorExpr(), makeVarFromTargetEntry(), makeWholeRowVar(), match_orclause_to_indexcol(), match_pattern_prefix(), ordered_set_startup(), paraminfo_get_equal_hashops(), ParseFuncOrColumn(), pg_get_indexdef_worker(), pg_get_partkeydef_worker(), prepare_query_params(), preprocess_aggref(), preprocess_minmax_aggregates(), ProcedureCreate(), process_equivalence(), process_matched_tle(), recheck_cast_function_args(), relabel_to_typmod(), RelationBuildPartitionKey(), RelationGetDummyIndexExpressions(), remove_unused_subquery_outputs(), replace_nestloop_param_placeholdervar(), replace_outer_grouping(), replace_outer_merge_support(), replace_outer_placeholdervar(), replace_outer_returning(), resolveTargetListUnknowns(), scalararraysel(), select_common_type(), select_common_typmod(), set_append_rel_size(), set_dummy_tlist_references(), set_joinrel_partition_key_exprs(), set_rel_width(), show_sortorder_options(), tlist_same_datatypes(), transformAExprNullIf(), transformAggregateCall(), transformArrayExpr(), transformAssignedExpr(), transformAssignmentIndirection(), transformAssignmentSubscripts(), transformCaseExpr(), transformCollateClause(), transformExprRecurse(), transformFrameOffset(), transformFromClauseItem(), transformIndirection(), transformInsertStmt(), transformJsonBehavior(), transformJsonConstructorOutput(), transformJsonFuncExpr(), transformJsonParseArg(), transformJsonScalarExpr(), transformJsonTableColumns(), transformJsonValueExpr(), transformMultiAssignRef(), transformPartitionBoundValue(), transformPLAssignStmt(), transformSetOperationTree(), transformSubLink(), transformTypeCast(), unknown_attribute(), verify_common_type(), and xmlelement().

◆ exprTypmod()

int32 exprTypmod ( const Node expr)

Definition at line 301 of file nodeFuncs.c.

302{
303 if (!expr)
304 return -1;
305
306 switch (nodeTag(expr))
307 {
308 case T_Var:
309 return ((const Var *) expr)->vartypmod;
310 case T_Const:
311 return ((const Const *) expr)->consttypmod;
312 case T_Param:
313 return ((const Param *) expr)->paramtypmod;
314 case T_SubscriptingRef:
315 return ((const SubscriptingRef *) expr)->reftypmod;
316 case T_FuncExpr:
317 {
318 int32 coercedTypmod;
319
320 /* Be smart about length-coercion functions... */
321 if (exprIsLengthCoercion(expr, &coercedTypmod))
322 return coercedTypmod;
323 }
324 break;
325 case T_NamedArgExpr:
326 return exprTypmod((Node *) ((const NamedArgExpr *) expr)->arg);
327 case T_NullIfExpr:
328 {
329 /*
330 * Result is either first argument or NULL, so we can report
331 * first argument's typmod if known.
332 */
333 const NullIfExpr *nexpr = (const NullIfExpr *) expr;
334
335 return exprTypmod((Node *) linitial(nexpr->args));
336 }
337 break;
338 case T_SubLink:
339 {
340 const SubLink *sublink = (const SubLink *) expr;
341
342 if (sublink->subLinkType == EXPR_SUBLINK ||
343 sublink->subLinkType == ARRAY_SUBLINK)
344 {
345 /* get the typmod of the subselect's first target column */
346 Query *qtree = (Query *) sublink->subselect;
347 TargetEntry *tent;
348
349 if (!qtree || !IsA(qtree, Query))
350 elog(ERROR, "cannot get type for untransformed sublink");
351 tent = linitial_node(TargetEntry, qtree->targetList);
352 Assert(!tent->resjunk);
353 return exprTypmod((Node *) tent->expr);
354 /* note we don't need to care if it's an array */
355 }
356 /* otherwise, result is RECORD or BOOLEAN, typmod is -1 */
357 }
358 break;
359 case T_SubPlan:
360 {
361 const SubPlan *subplan = (const SubPlan *) expr;
362
363 if (subplan->subLinkType == EXPR_SUBLINK ||
364 subplan->subLinkType == ARRAY_SUBLINK)
365 {
366 /* get the typmod of the subselect's first target column */
367 /* note we don't need to care if it's an array */
368 return subplan->firstColTypmod;
369 }
370 /* otherwise, result is RECORD or BOOLEAN, typmod is -1 */
371 }
372 break;
373 case T_AlternativeSubPlan:
374 {
375 const AlternativeSubPlan *asplan = (const AlternativeSubPlan *) expr;
376
377 /* subplans should all return the same thing */
378 return exprTypmod((Node *) linitial(asplan->subplans));
379 }
380 break;
381 case T_FieldSelect:
382 return ((const FieldSelect *) expr)->resulttypmod;
383 case T_RelabelType:
384 return ((const RelabelType *) expr)->resulttypmod;
385 case T_ArrayCoerceExpr:
386 return ((const ArrayCoerceExpr *) expr)->resulttypmod;
387 case T_CollateExpr:
388 return exprTypmod((Node *) ((const CollateExpr *) expr)->arg);
389 case T_CaseExpr:
390 {
391 /*
392 * If all the alternatives agree on type/typmod, return that
393 * typmod, else use -1
394 */
395 const CaseExpr *cexpr = (const CaseExpr *) expr;
396 Oid casetype = cexpr->casetype;
397 int32 typmod;
398 ListCell *arg;
399
400 if (!cexpr->defresult)
401 return -1;
402 if (exprType((Node *) cexpr->defresult) != casetype)
403 return -1;
404 typmod = exprTypmod((Node *) cexpr->defresult);
405 if (typmod < 0)
406 return -1; /* no point in trying harder */
407 foreach(arg, cexpr->args)
408 {
410
411 if (exprType((Node *) w->result) != casetype)
412 return -1;
413 if (exprTypmod((Node *) w->result) != typmod)
414 return -1;
415 }
416 return typmod;
417 }
418 break;
419 case T_CaseTestExpr:
420 return ((const CaseTestExpr *) expr)->typeMod;
421 case T_ArrayExpr:
422 {
423 /*
424 * If all the elements agree on type/typmod, return that
425 * typmod, else use -1
426 */
427 const ArrayExpr *arrayexpr = (const ArrayExpr *) expr;
428 Oid commontype;
429 int32 typmod;
430 ListCell *elem;
431
432 if (arrayexpr->elements == NIL)
433 return -1;
434 typmod = exprTypmod((Node *) linitial(arrayexpr->elements));
435 if (typmod < 0)
436 return -1; /* no point in trying harder */
437 if (arrayexpr->multidims)
438 commontype = arrayexpr->array_typeid;
439 else
440 commontype = arrayexpr->element_typeid;
441 foreach(elem, arrayexpr->elements)
442 {
443 Node *e = (Node *) lfirst(elem);
444
445 if (exprType(e) != commontype)
446 return -1;
447 if (exprTypmod(e) != typmod)
448 return -1;
449 }
450 return typmod;
451 }
452 break;
453 case T_CoalesceExpr:
454 {
455 /*
456 * If all the alternatives agree on type/typmod, return that
457 * typmod, else use -1
458 */
459 const CoalesceExpr *cexpr = (const CoalesceExpr *) expr;
460 Oid coalescetype = cexpr->coalescetype;
461 int32 typmod;
462 ListCell *arg;
463
464 if (exprType((Node *) linitial(cexpr->args)) != coalescetype)
465 return -1;
466 typmod = exprTypmod((Node *) linitial(cexpr->args));
467 if (typmod < 0)
468 return -1; /* no point in trying harder */
469 for_each_from(arg, cexpr->args, 1)
470 {
471 Node *e = (Node *) lfirst(arg);
472
473 if (exprType(e) != coalescetype)
474 return -1;
475 if (exprTypmod(e) != typmod)
476 return -1;
477 }
478 return typmod;
479 }
480 break;
481 case T_MinMaxExpr:
482 {
483 /*
484 * If all the alternatives agree on type/typmod, return that
485 * typmod, else use -1
486 */
487 const MinMaxExpr *mexpr = (const MinMaxExpr *) expr;
488 Oid minmaxtype = mexpr->minmaxtype;
489 int32 typmod;
490 ListCell *arg;
491
492 if (exprType((Node *) linitial(mexpr->args)) != minmaxtype)
493 return -1;
494 typmod = exprTypmod((Node *) linitial(mexpr->args));
495 if (typmod < 0)
496 return -1; /* no point in trying harder */
497 for_each_from(arg, mexpr->args, 1)
498 {
499 Node *e = (Node *) lfirst(arg);
500
501 if (exprType(e) != minmaxtype)
502 return -1;
503 if (exprTypmod(e) != typmod)
504 return -1;
505 }
506 return typmod;
507 }
508 break;
509 case T_SQLValueFunction:
510 return ((const SQLValueFunction *) expr)->typmod;
511 case T_JsonValueExpr:
512 return exprTypmod((Node *) ((const JsonValueExpr *) expr)->formatted_expr);
513 case T_JsonConstructorExpr:
514 return ((const JsonConstructorExpr *) expr)->returning->typmod;
515 case T_JsonExpr:
516 {
517 const JsonExpr *jexpr = (const JsonExpr *) expr;
518
519 return jexpr->returning->typmod;
520 }
521 break;
522 case T_JsonBehavior:
523 {
524 const JsonBehavior *behavior = (const JsonBehavior *) expr;
525
526 return exprTypmod(behavior->expr);
527 }
528 break;
529 case T_CoerceToDomain:
530 return ((const CoerceToDomain *) expr)->resulttypmod;
531 case T_CoerceToDomainValue:
532 return ((const CoerceToDomainValue *) expr)->typeMod;
533 case T_SetToDefault:
534 return ((const SetToDefault *) expr)->typeMod;
535 case T_ReturningExpr:
536 return exprTypmod((Node *) ((const ReturningExpr *) expr)->retexpr);
537 case T_PlaceHolderVar:
538 return exprTypmod((Node *) ((const PlaceHolderVar *) expr)->phexpr);
539 default:
540 break;
541 }
542 return -1;
543}
int32_t int32
Definition: c.h:484
bool exprIsLengthCoercion(const Node *expr, int32 *coercedTypmod)
Definition: nodeFuncs.c:557
#define for_each_from(cell, lst, N)
Definition: pg_list.h:414
e
Definition: preproc-init.c:82
int32 firstColTypmod
Definition: primnodes.h:1091

References arg, OpExpr::args, CaseExpr::args, CoalesceExpr::args, MinMaxExpr::args, ARRAY_SUBLINK, Assert, CaseExpr::defresult, ArrayExpr::elements, elog, ERROR, JsonBehavior::expr, EXPR_SUBLINK, exprIsLengthCoercion(), exprType(), exprTypmod(), SubPlan::firstColTypmod, for_each_from, if(), IsA, lfirst, lfirst_node, linitial, linitial_node, NIL, nodeTag, CaseWhen::result, JsonExpr::returning, SubLink::subLinkType, SubPlan::subLinkType, AlternativeSubPlan::subplans, SubLink::subselect, Query::targetList, and JsonReturning::typmod.

Referenced by add_row_identity_var(), addRangeTableEntryForFunction(), addRangeTableEntryForGroup(), addRangeTableEntryForSubquery(), analyzeCTE(), analyzeCTETargetList(), applyRelabelType(), assign_hypothetical_collations(), build_coercion_expression(), build_subplan(), canonicalize_ec_expression(), checkRuleResultList(), coerce_type_typmod(), ConstructTupleDescriptor(), convert_EXISTS_to_ANY(), create_ctas_nodata(), DefineVirtualRelation(), eval_const_expressions_mutator(), examine_attribute(), examine_expression(), examine_variable(), exec_save_simple_expr(), ExecInitJsonExpr(), ExecTypeFromExprList(), ExecTypeFromTLInternal(), expandRecordVariable(), expandRTE(), exprTypmod(), find_placeholder_info(), generate_append_tlist(), generate_setop_tlist(), generate_subquery_params(), get_attr_stat_type(), get_expr_result_type(), get_expr_width(), get_first_col_type(), get_rule_expr(), get_rule_expr_funccall(), interval_support(), JsonTableInitOpaque(), makeJsonConstructorExpr(), makeVarFromTargetEntry(), numeric_support(), preprocess_aggref(), RelationBuildPartitionKey(), RelationGetDummyIndexExpressions(), remove_unused_subquery_outputs(), replace_nestloop_param_placeholdervar(), replace_outer_placeholdervar(), replace_outer_returning(), select_common_typmod(), set_append_rel_size(), set_dummy_tlist_references(), set_rel_width(), TemporalSimplify(), transformCaseExpr(), transformFromClauseItem(), transformIndirection(), transformJsonTableColumns(), transformMultiAssignRef(), transformPLAssignStmt(), transformSubLink(), varbit_support(), and varchar_support().

◆ fix_opfuncids()

void fix_opfuncids ( Node node)

Definition at line 1841 of file nodeFuncs.c.

1842{
1843 /* This tree walk requires no special setup, so away we go... */
1844 fix_opfuncids_walker(node, NULL);
1845}
static bool fix_opfuncids_walker(Node *node, void *context)
Definition: nodeFuncs.c:1848

References fix_opfuncids_walker().

Referenced by evaluate_expr(), expression_planner(), expression_planner_with_deps(), fetch_statentries_for_relation(), get_qual_for_range(), get_relation_statistics(), operator_predicate_proof(), RelationBuildPartitionKey(), RelationGetIndexExpressions(), and RelationGetIndexPredicate().

◆ get_leftop()

◆ get_notclausearg()

◆ get_rightop()

◆ is_andclause()

◆ is_funcclause()

◆ is_notclause()

◆ is_opclause()

◆ is_orclause()

◆ planstate_tree_walker_impl()

bool planstate_tree_walker_impl ( struct PlanState planstate,
planstate_tree_walker_callback  walker,
void *  context 
)

Definition at line 4723 of file nodeFuncs.c.

4726{
4727 Plan *plan = planstate->plan;
4728 ListCell *lc;
4729
4730 /* We don't need implicit coercions to Node here */
4731#define PSWALK(n) walker(n, context)
4732
4733 /* Guard against stack overflow due to overly complex plan trees */
4735
4736 /* initPlan-s */
4737 if (planstate_walk_subplans(planstate->initPlan, walker, context))
4738 return true;
4739
4740 /* lefttree */
4741 if (outerPlanState(planstate))
4742 {
4743 if (PSWALK(outerPlanState(planstate)))
4744 return true;
4745 }
4746
4747 /* righttree */
4748 if (innerPlanState(planstate))
4749 {
4750 if (PSWALK(innerPlanState(planstate)))
4751 return true;
4752 }
4753
4754 /* special child plans */
4755 switch (nodeTag(plan))
4756 {
4757 case T_Append:
4758 if (planstate_walk_members(((AppendState *) planstate)->appendplans,
4759 ((AppendState *) planstate)->as_nplans,
4760 walker, context))
4761 return true;
4762 break;
4763 case T_MergeAppend:
4764 if (planstate_walk_members(((MergeAppendState *) planstate)->mergeplans,
4765 ((MergeAppendState *) planstate)->ms_nplans,
4766 walker, context))
4767 return true;
4768 break;
4769 case T_BitmapAnd:
4770 if (planstate_walk_members(((BitmapAndState *) planstate)->bitmapplans,
4771 ((BitmapAndState *) planstate)->nplans,
4772 walker, context))
4773 return true;
4774 break;
4775 case T_BitmapOr:
4776 if (planstate_walk_members(((BitmapOrState *) planstate)->bitmapplans,
4777 ((BitmapOrState *) planstate)->nplans,
4778 walker, context))
4779 return true;
4780 break;
4781 case T_SubqueryScan:
4782 if (PSWALK(((SubqueryScanState *) planstate)->subplan))
4783 return true;
4784 break;
4785 case T_CustomScan:
4786 foreach(lc, ((CustomScanState *) planstate)->custom_ps)
4787 {
4788 if (PSWALK(lfirst(lc)))
4789 return true;
4790 }
4791 break;
4792 default:
4793 break;
4794 }
4795
4796 /* subPlan-s */
4797 if (planstate_walk_subplans(planstate->subPlan, walker, context))
4798 return true;
4799
4800 return false;
4801}
#define outerPlanState(node)
Definition: execnodes.h:1237
#define innerPlanState(node)
Definition: execnodes.h:1236
static bool planstate_walk_subplans(List *plans, planstate_tree_walker_callback walker, void *context)
Definition: nodeFuncs.c:4807
#define PSWALK(n)
static bool planstate_walk_members(PlanState **planstates, int nplans, planstate_tree_walker_callback walker, void *context)
Definition: nodeFuncs.c:4829
#define plan(x)
Definition: pg_regress.c:161
Plan * plan
Definition: execnodes.h:1141
List * initPlan
Definition: execnodes.h:1166

References check_stack_depth(), PlanState::initPlan, innerPlanState, lfirst, nodeTag, outerPlanState, PlanState::plan, plan, planstate_walk_members(), planstate_walk_subplans(), PSWALK, and PlanState::subPlan.

◆ query_or_expression_tree_mutator_impl()

Node * query_or_expression_tree_mutator_impl ( Node node,
tree_mutator_callback  mutator,
void *  context,
int  flags 
)

Definition at line 3969 of file nodeFuncs.c.

3973{
3974 if (node && IsA(node, Query))
3975 return (Node *) query_tree_mutator((Query *) node,
3976 mutator,
3977 context,
3978 flags);
3979 else
3980 return mutator(node, context);
3981}
#define query_tree_mutator(q, m, c, f)
Definition: nodeFuncs.h:160

References IsA, and query_tree_mutator.

◆ query_or_expression_tree_walker_impl()

bool query_or_expression_tree_walker_impl ( Node node,
tree_walker_callback  walker,
void *  context,
int  flags 
)

Definition at line 3946 of file nodeFuncs.c.

3950{
3951 if (node && IsA(node, Query))
3952 return query_tree_walker((Query *) node,
3953 walker,
3954 context,
3955 flags);
3956 else
3957 return WALK(node);
3958}
#define query_tree_walker(q, w, c, f)
Definition: nodeFuncs.h:158

References IsA, query_tree_walker, and WALK.

◆ query_tree_mutator_impl()

Query * query_tree_mutator_impl ( Query query,
tree_mutator_callback  mutator,
void *  context,
int  flags 
)

Definition at line 3777 of file nodeFuncs.c.

3781{
3782 Assert(query != NULL && IsA(query, Query));
3783
3784 if (!(flags & QTW_DONT_COPY_QUERY))
3785 {
3786 Query *newquery;
3787
3788 FLATCOPY(newquery, query, Query);
3789 query = newquery;
3790 }
3791
3792 MUTATE(query->targetList, query->targetList, List *);
3793 MUTATE(query->withCheckOptions, query->withCheckOptions, List *);
3794 MUTATE(query->onConflict, query->onConflict, OnConflictExpr *);
3795 MUTATE(query->mergeActionList, query->mergeActionList, List *);
3797 MUTATE(query->returningList, query->returningList, List *);
3798 MUTATE(query->jointree, query->jointree, FromExpr *);
3799 MUTATE(query->setOperations, query->setOperations, Node *);
3800 MUTATE(query->havingQual, query->havingQual, Node *);
3801 MUTATE(query->limitOffset, query->limitOffset, Node *);
3802 MUTATE(query->limitCount, query->limitCount, Node *);
3803
3804 /*
3805 * Most callers aren't interested in SortGroupClause nodes since those
3806 * don't contain actual expressions. However they do contain OIDs, which
3807 * may be of interest to some mutators.
3808 */
3809
3810 if ((flags & QTW_EXAMINE_SORTGROUP))
3811 {
3812 MUTATE(query->groupClause, query->groupClause, List *);
3813 MUTATE(query->windowClause, query->windowClause, List *);
3814 MUTATE(query->sortClause, query->sortClause, List *);
3815 MUTATE(query->distinctClause, query->distinctClause, List *);
3816 }
3817 else
3818 {
3819 /*
3820 * But we need to mutate the expressions under WindowClause nodes even
3821 * if we're not interested in SortGroupClause nodes.
3822 */
3823 List *resultlist;
3824 ListCell *temp;
3825
3826 resultlist = NIL;
3827 foreach(temp, query->windowClause)
3828 {
3830 WindowClause *newnode;
3831
3832 FLATCOPY(newnode, wc, WindowClause);
3833 MUTATE(newnode->startOffset, wc->startOffset, Node *);
3834 MUTATE(newnode->endOffset, wc->endOffset, Node *);
3835
3836 resultlist = lappend(resultlist, (Node *) newnode);
3837 }
3838 query->windowClause = resultlist;
3839 }
3840
3841 /*
3842 * groupingSets and rowMarks are not mutated:
3843 *
3844 * groupingSets contain only ressortgroup refs (integers) which are
3845 * meaningless without the groupClause or tlist. Accordingly, any mutator
3846 * that needs to care about them needs to handle them itself in its Query
3847 * processing.
3848 *
3849 * rowMarks contains only rangetable indexes (and flags etc.) and
3850 * therefore should be handled at Query level similarly.
3851 */
3852
3853 if (!(flags & QTW_IGNORE_CTE_SUBQUERIES))
3854 MUTATE(query->cteList, query->cteList, List *);
3855 else /* else copy CTE list as-is */
3856 query->cteList = copyObject(query->cteList);
3857 query->rtable = range_table_mutator(query->rtable,
3858 mutator, context, flags);
3859 return query;
3860}
#define QTW_DONT_COPY_QUERY
Definition: nodeFuncs.h:29
#define QTW_IGNORE_CTE_SUBQUERIES
Definition: nodeFuncs.h:23
#define QTW_EXAMINE_SORTGROUP
Definition: nodeFuncs.h:30
#define range_table_mutator(rt, m, c, f)
Definition: nodeFuncs.h:165
Node * mergeJoinCondition
Definition: parsenodes.h:191
Node * limitCount
Definition: parsenodes.h:225
FromExpr * jointree
Definition: parsenodes.h:177
List * returningList
Definition: parsenodes.h:209
Node * setOperations
Definition: parsenodes.h:230
List * cteList
Definition: parsenodes.h:168
OnConflictExpr * onConflict
Definition: parsenodes.h:198
List * groupClause
Definition: parsenodes.h:211
Node * havingQual
Definition: parsenodes.h:216
List * rtable
Definition: parsenodes.h:170
Node * limitOffset
Definition: parsenodes.h:224
List * mergeActionList
Definition: parsenodes.h:180
List * windowClause
Definition: parsenodes.h:218
List * distinctClause
Definition: parsenodes.h:220
List * sortClause
Definition: parsenodes.h:222

References Assert, copyObject, Query::cteList, Query::distinctClause, WindowClause::endOffset, FLATCOPY, Query::groupClause, Query::havingQual, IsA, Query::jointree, lappend(), lfirst_node, Query::limitCount, Query::limitOffset, Query::mergeActionList, Query::mergeJoinCondition, MUTATE, NIL, Query::onConflict, QTW_DONT_COPY_QUERY, QTW_EXAMINE_SORTGROUP, QTW_IGNORE_CTE_SUBQUERIES, range_table_mutator, Query::returningList, Query::rtable, Query::setOperations, Query::sortClause, WindowClause::startOffset, Query::targetList, and Query::windowClause.

◆ query_tree_walker_impl()

bool query_tree_walker_impl ( Query query,
tree_walker_callback  walker,
void *  context,
int  flags 
)

Definition at line 2698 of file nodeFuncs.c.

2702{
2703 Assert(query != NULL && IsA(query, Query));
2704
2705 /*
2706 * We don't walk any utilityStmt here. However, we can't easily assert
2707 * that it is absent, since there are at least two code paths by which
2708 * action statements from CREATE RULE end up here, and NOTIFY is allowed
2709 * in a rule action.
2710 */
2711
2712 if (WALK(query->targetList))
2713 return true;
2714 if (WALK(query->withCheckOptions))
2715 return true;
2716 if (WALK(query->onConflict))
2717 return true;
2718 if (WALK(query->mergeActionList))
2719 return true;
2720 if (WALK(query->mergeJoinCondition))
2721 return true;
2722 if (WALK(query->returningList))
2723 return true;
2724 if (WALK(query->jointree))
2725 return true;
2726 if (WALK(query->setOperations))
2727 return true;
2728 if (WALK(query->havingQual))
2729 return true;
2730 if (WALK(query->limitOffset))
2731 return true;
2732 if (WALK(query->limitCount))
2733 return true;
2734
2735 /*
2736 * Most callers aren't interested in SortGroupClause nodes since those
2737 * don't contain actual expressions. However they do contain OIDs which
2738 * may be needed by dependency walkers etc.
2739 */
2740 if ((flags & QTW_EXAMINE_SORTGROUP))
2741 {
2742 if (WALK(query->groupClause))
2743 return true;
2744 if (WALK(query->windowClause))
2745 return true;
2746 if (WALK(query->sortClause))
2747 return true;
2748 if (WALK(query->distinctClause))
2749 return true;
2750 }
2751 else
2752 {
2753 /*
2754 * But we need to walk the expressions under WindowClause nodes even
2755 * if we're not interested in SortGroupClause nodes.
2756 */
2757 ListCell *lc;
2758
2759 foreach(lc, query->windowClause)
2760 {
2762
2763 if (WALK(wc->startOffset))
2764 return true;
2765 if (WALK(wc->endOffset))
2766 return true;
2767 }
2768 }
2769
2770 /*
2771 * groupingSets and rowMarks are not walked:
2772 *
2773 * groupingSets contain only ressortgrouprefs (integers) which are
2774 * meaningless without the corresponding groupClause or tlist.
2775 * Accordingly, any walker that needs to care about them needs to handle
2776 * them itself in its Query processing.
2777 *
2778 * rowMarks is not walked because it contains only rangetable indexes (and
2779 * flags etc.) and therefore should be handled at Query level similarly.
2780 */
2781
2782 if (!(flags & QTW_IGNORE_CTE_SUBQUERIES))
2783 {
2784 if (WALK(query->cteList))
2785 return true;
2786 }
2787 if (!(flags & QTW_IGNORE_RANGE_TABLE))
2788 {
2789 if (range_table_walker(query->rtable, walker, context, flags))
2790 return true;
2791 }
2792 return false;
2793}
#define range_table_walker(rt, w, c, f)
Definition: nodeFuncs.h:163
#define QTW_IGNORE_RANGE_TABLE
Definition: nodeFuncs.h:26

References Assert, Query::cteList, Query::distinctClause, WindowClause::endOffset, Query::groupClause, Query::havingQual, IsA, Query::jointree, lfirst_node, Query::limitCount, Query::limitOffset, Query::mergeActionList, Query::mergeJoinCondition, Query::onConflict, QTW_EXAMINE_SORTGROUP, QTW_IGNORE_CTE_SUBQUERIES, QTW_IGNORE_RANGE_TABLE, range_table_walker, Query::returningList, Query::rtable, Query::setOperations, Query::sortClause, WindowClause::startOffset, Query::targetList, WALK, and Query::windowClause.

◆ range_table_entry_walker_impl()

bool range_table_entry_walker_impl ( RangeTblEntry rte,
tree_walker_callback  walker,
void *  context,
int  flags 
)

Definition at line 2822 of file nodeFuncs.c.

2826{
2827 /*
2828 * Walkers might need to examine the RTE node itself either before or
2829 * after visiting its contents (or, conceivably, both). Note that if you
2830 * specify neither flag, the walker won't be called on the RTE at all.
2831 */
2832 if (flags & QTW_EXAMINE_RTES_BEFORE)
2833 if (WALK(rte))
2834 return true;
2835
2836 switch (rte->rtekind)
2837 {
2838 case RTE_RELATION:
2839 if (WALK(rte->tablesample))
2840 return true;
2841 break;
2842 case RTE_SUBQUERY:
2843 if (!(flags & QTW_IGNORE_RT_SUBQUERIES))
2844 if (WALK(rte->subquery))
2845 return true;
2846 break;
2847 case RTE_JOIN:
2848 if (!(flags & QTW_IGNORE_JOINALIASES))
2849 if (WALK(rte->joinaliasvars))
2850 return true;
2851 break;
2852 case RTE_FUNCTION:
2853 if (WALK(rte->functions))
2854 return true;
2855 break;
2856 case RTE_TABLEFUNC:
2857 if (WALK(rte->tablefunc))
2858 return true;
2859 break;
2860 case RTE_VALUES:
2861 if (WALK(rte->values_lists))
2862 return true;
2863 break;
2864 case RTE_CTE:
2866 case RTE_RESULT:
2867 /* nothing to do */
2868 break;
2869 case RTE_GROUP:
2870 if (!(flags & QTW_IGNORE_GROUPEXPRS))
2871 if (WALK(rte->groupexprs))
2872 return true;
2873 break;
2874 }
2875
2876 if (WALK(rte->securityQuals))
2877 return true;
2878
2879 if (flags & QTW_EXAMINE_RTES_AFTER)
2880 if (WALK(rte))
2881 return true;
2882
2883 return false;
2884}
#define QTW_IGNORE_RT_SUBQUERIES
Definition: nodeFuncs.h:22
#define QTW_EXAMINE_RTES_AFTER
Definition: nodeFuncs.h:28
#define QTW_IGNORE_GROUPEXPRS
Definition: nodeFuncs.h:32
#define QTW_EXAMINE_RTES_BEFORE
Definition: nodeFuncs.h:27
#define QTW_IGNORE_JOINALIASES
Definition: nodeFuncs.h:25
@ RTE_JOIN
Definition: parsenodes.h:1028
@ RTE_CTE
Definition: parsenodes.h:1032
@ RTE_NAMEDTUPLESTORE
Definition: parsenodes.h:1033
@ RTE_VALUES
Definition: parsenodes.h:1031
@ RTE_SUBQUERY
Definition: parsenodes.h:1027
@ RTE_RESULT
Definition: parsenodes.h:1034
@ RTE_FUNCTION
Definition: parsenodes.h:1029
@ RTE_TABLEFUNC
Definition: parsenodes.h:1030
@ RTE_GROUP
Definition: parsenodes.h:1037
@ RTE_RELATION
Definition: parsenodes.h:1026
TableFunc * tablefunc
Definition: parsenodes.h:1193
struct TableSampleClause * tablesample
Definition: parsenodes.h:1107
Query * subquery
Definition: parsenodes.h:1113
List * values_lists
Definition: parsenodes.h:1199
List * functions
Definition: parsenodes.h:1186
RTEKind rtekind
Definition: parsenodes.h:1056

References RangeTblEntry::functions, QTW_EXAMINE_RTES_AFTER, QTW_EXAMINE_RTES_BEFORE, QTW_IGNORE_GROUPEXPRS, QTW_IGNORE_JOINALIASES, QTW_IGNORE_RT_SUBQUERIES, RTE_CTE, RTE_FUNCTION, RTE_GROUP, RTE_JOIN, RTE_NAMEDTUPLESTORE, RTE_RELATION, RTE_RESULT, RTE_SUBQUERY, RTE_TABLEFUNC, RTE_VALUES, RangeTblEntry::rtekind, RangeTblEntry::subquery, RangeTblEntry::tablefunc, RangeTblEntry::tablesample, RangeTblEntry::values_lists, and WALK.

◆ range_table_mutator_impl()

List * range_table_mutator_impl ( List rtable,
tree_mutator_callback  mutator,
void *  context,
int  flags 
)

Definition at line 3868 of file nodeFuncs.c.

3872{
3873 List *newrt = NIL;
3874 ListCell *rt;
3875
3876 foreach(rt, rtable)
3877 {
3878 RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
3879 RangeTblEntry *newrte;
3880
3881 FLATCOPY(newrte, rte, RangeTblEntry);
3882 switch (rte->rtekind)
3883 {
3884 case RTE_RELATION:
3885 MUTATE(newrte->tablesample, rte->tablesample,
3887 /* we don't bother to copy eref, aliases, etc; OK? */
3888 break;
3889 case RTE_SUBQUERY:
3890 if (!(flags & QTW_IGNORE_RT_SUBQUERIES))
3891 MUTATE(newrte->subquery, rte->subquery, Query *);
3892 else
3893 {
3894 /* else, copy RT subqueries as-is */
3895 newrte->subquery = copyObject(rte->subquery);
3896 }
3897 break;
3898 case RTE_JOIN:
3899 if (!(flags & QTW_IGNORE_JOINALIASES))
3900 MUTATE(newrte->joinaliasvars, rte->joinaliasvars, List *);
3901 else
3902 {
3903 /* else, copy join aliases as-is */
3904 newrte->joinaliasvars = copyObject(rte->joinaliasvars);
3905 }
3906 break;
3907 case RTE_FUNCTION:
3908 MUTATE(newrte->functions, rte->functions, List *);
3909 break;
3910 case RTE_TABLEFUNC:
3911 MUTATE(newrte->tablefunc, rte->tablefunc, TableFunc *);
3912 break;
3913 case RTE_VALUES:
3914 MUTATE(newrte->values_lists, rte->values_lists, List *);
3915 break;
3916 case RTE_CTE:
3918 case RTE_RESULT:
3919 /* nothing to do */
3920 break;
3921 case RTE_GROUP:
3922 if (!(flags & QTW_IGNORE_GROUPEXPRS))
3923 MUTATE(newrte->groupexprs, rte->groupexprs, List *);
3924 else
3925 {
3926 /* else, copy grouping exprs as-is */
3927 newrte->groupexprs = copyObject(rte->groupexprs);
3928 }
3929 break;
3930 }
3931 MUTATE(newrte->securityQuals, rte->securityQuals, List *);
3932 newrt = lappend(newrt, newrte);
3933 }
3934 return newrt;
3935}

References copyObject, FLATCOPY, RangeTblEntry::functions, lappend(), lfirst, MUTATE, NIL, QTW_IGNORE_GROUPEXPRS, QTW_IGNORE_JOINALIASES, QTW_IGNORE_RT_SUBQUERIES, RTE_CTE, RTE_FUNCTION, RTE_GROUP, RTE_JOIN, RTE_NAMEDTUPLESTORE, RTE_RELATION, RTE_RESULT, RTE_SUBQUERY, RTE_TABLEFUNC, RTE_VALUES, RangeTblEntry::rtekind, RangeTblEntry::subquery, RangeTblEntry::tablefunc, RangeTblEntry::tablesample, and RangeTblEntry::values_lists.

◆ range_table_walker_impl()

bool range_table_walker_impl ( List rtable,
tree_walker_callback  walker,
void *  context,
int  flags 
)

Definition at line 2801 of file nodeFuncs.c.

2805{
2806 ListCell *rt;
2807
2808 foreach(rt, rtable)
2809 {
2811
2812 if (range_table_entry_walker(rte, walker, context, flags))
2813 return true;
2814 }
2815 return false;
2816}
#define range_table_entry_walker(r, w, c, f)
Definition: nodeFuncs.h:168

References lfirst_node, and range_table_entry_walker.

◆ raw_expression_tree_walker_impl()

bool raw_expression_tree_walker_impl ( Node node,
tree_walker_callback  walker,
void *  context 
)

Definition at line 4000 of file nodeFuncs.c.

4003{
4004 ListCell *temp;
4005
4006 /*
4007 * The walker has already visited the current node, and so we need only
4008 * recurse into any sub-nodes it has.
4009 */
4010 if (node == NULL)
4011 return false;
4012
4013 /* Guard against stack overflow due to overly complex expressions */
4015
4016 switch (nodeTag(node))
4017 {
4018 case T_JsonFormat:
4019 case T_SetToDefault:
4020 case T_CurrentOfExpr:
4021 case T_SQLValueFunction:
4022 case T_Integer:
4023 case T_Float:
4024 case T_Boolean:
4025 case T_String:
4026 case T_BitString:
4027 case T_ParamRef:
4028 case T_A_Const:
4029 case T_A_Star:
4030 case T_MergeSupportFunc:
4031 case T_ReturningOption:
4032 /* primitive node types with no subnodes */
4033 break;
4034 case T_Alias:
4035 /* we assume the colnames list isn't interesting */
4036 break;
4037 case T_RangeVar:
4038 return WALK(((RangeVar *) node)->alias);
4039 case T_GroupingFunc:
4040 return WALK(((GroupingFunc *) node)->args);
4041 case T_SubLink:
4042 {
4043 SubLink *sublink = (SubLink *) node;
4044
4045 if (WALK(sublink->testexpr))
4046 return true;
4047 /* we assume the operName is not interesting */
4048 if (WALK(sublink->subselect))
4049 return true;
4050 }
4051 break;
4052 case T_CaseExpr:
4053 {
4054 CaseExpr *caseexpr = (CaseExpr *) node;
4055
4056 if (WALK(caseexpr->arg))
4057 return true;
4058 /* we assume walker doesn't care about CaseWhens, either */
4059 foreach(temp, caseexpr->args)
4060 {
4062
4063 if (WALK(when->expr))
4064 return true;
4065 if (WALK(when->result))
4066 return true;
4067 }
4068 if (WALK(caseexpr->defresult))
4069 return true;
4070 }
4071 break;
4072 case T_RowExpr:
4073 /* Assume colnames isn't interesting */
4074 return WALK(((RowExpr *) node)->args);
4075 case T_CoalesceExpr:
4076 return WALK(((CoalesceExpr *) node)->args);
4077 case T_MinMaxExpr:
4078 return WALK(((MinMaxExpr *) node)->args);
4079 case T_XmlExpr:
4080 {
4081 XmlExpr *xexpr = (XmlExpr *) node;
4082
4083 if (WALK(xexpr->named_args))
4084 return true;
4085 /* we assume walker doesn't care about arg_names */
4086 if (WALK(xexpr->args))
4087 return true;
4088 }
4089 break;
4090 case T_JsonReturning:
4091 return WALK(((JsonReturning *) node)->format);
4092 case T_JsonValueExpr:
4093 {
4094 JsonValueExpr *jve = (JsonValueExpr *) node;
4095
4096 if (WALK(jve->raw_expr))
4097 return true;
4098 if (WALK(jve->formatted_expr))
4099 return true;
4100 if (WALK(jve->format))
4101 return true;
4102 }
4103 break;
4104 case T_JsonParseExpr:
4105 {
4106 JsonParseExpr *jpe = (JsonParseExpr *) node;
4107
4108 if (WALK(jpe->expr))
4109 return true;
4110 if (WALK(jpe->output))
4111 return true;
4112 }
4113 break;
4114 case T_JsonScalarExpr:
4115 {
4116 JsonScalarExpr *jse = (JsonScalarExpr *) node;
4117
4118 if (WALK(jse->expr))
4119 return true;
4120 if (WALK(jse->output))
4121 return true;
4122 }
4123 break;
4124 case T_JsonSerializeExpr:
4125 {
4126 JsonSerializeExpr *jse = (JsonSerializeExpr *) node;
4127
4128 if (WALK(jse->expr))
4129 return true;
4130 if (WALK(jse->output))
4131 return true;
4132 }
4133 break;
4134 case T_JsonConstructorExpr:
4135 {
4137
4138 if (WALK(ctor->args))
4139 return true;
4140 if (WALK(ctor->func))
4141 return true;
4142 if (WALK(ctor->coercion))
4143 return true;
4144 if (WALK(ctor->returning))
4145 return true;
4146 }
4147 break;
4148 case T_JsonIsPredicate:
4149 return WALK(((JsonIsPredicate *) node)->expr);
4150 case T_JsonArgument:
4151 return WALK(((JsonArgument *) node)->val);
4152 case T_JsonFuncExpr:
4153 {
4154 JsonFuncExpr *jfe = (JsonFuncExpr *) node;
4155
4156 if (WALK(jfe->context_item))
4157 return true;
4158 if (WALK(jfe->pathspec))
4159 return true;
4160 if (WALK(jfe->passing))
4161 return true;
4162 if (WALK(jfe->output))
4163 return true;
4164 if (WALK(jfe->on_empty))
4165 return true;
4166 if (WALK(jfe->on_error))
4167 return true;
4168 }
4169 break;
4170 case T_JsonBehavior:
4171 {
4172 JsonBehavior *jb = (JsonBehavior *) node;
4173
4174 if (WALK(jb->expr))
4175 return true;
4176 }
4177 break;
4178 case T_JsonTable:
4179 {
4180 JsonTable *jt = (JsonTable *) node;
4181
4182 if (WALK(jt->context_item))
4183 return true;
4184 if (WALK(jt->pathspec))
4185 return true;
4186 if (WALK(jt->passing))
4187 return true;
4188 if (WALK(jt->columns))
4189 return true;
4190 if (WALK(jt->on_error))
4191 return true;
4192 }
4193 break;
4194 case T_JsonTableColumn:
4195 {
4196 JsonTableColumn *jtc = (JsonTableColumn *) node;
4197
4198 if (WALK(jtc->typeName))
4199 return true;
4200 if (WALK(jtc->on_empty))
4201 return true;
4202 if (WALK(jtc->on_error))
4203 return true;
4204 if (WALK(jtc->columns))
4205 return true;
4206 }
4207 break;
4208 case T_JsonTablePathSpec:
4209 return WALK(((JsonTablePathSpec *) node)->string);
4210 case T_NullTest:
4211 return WALK(((NullTest *) node)->arg);
4212 case T_BooleanTest:
4213 return WALK(((BooleanTest *) node)->arg);
4214 case T_JoinExpr:
4215 {
4216 JoinExpr *join = (JoinExpr *) node;
4217
4218 if (WALK(join->larg))
4219 return true;
4220 if (WALK(join->rarg))
4221 return true;
4222 if (WALK(join->quals))
4223 return true;
4224 if (WALK(join->alias))
4225 return true;
4226 /* using list is deemed uninteresting */
4227 }
4228 break;
4229 case T_IntoClause:
4230 {
4231 IntoClause *into = (IntoClause *) node;
4232
4233 if (WALK(into->rel))
4234 return true;
4235 /* colNames, options are deemed uninteresting */
4236 /* viewQuery should be null in raw parsetree, but check it */
4237 if (WALK(into->viewQuery))
4238 return true;
4239 }
4240 break;
4241 case T_List:
4242 foreach(temp, (List *) node)
4243 {
4244 if (WALK((Node *) lfirst(temp)))
4245 return true;
4246 }
4247 break;
4248 case T_InsertStmt:
4249 {
4250 InsertStmt *stmt = (InsertStmt *) node;
4251
4252 if (WALK(stmt->relation))
4253 return true;
4254 if (WALK(stmt->cols))
4255 return true;
4256 if (WALK(stmt->selectStmt))
4257 return true;
4258 if (WALK(stmt->onConflictClause))
4259 return true;
4260 if (WALK(stmt->returningClause))
4261 return true;
4262 if (WALK(stmt->withClause))
4263 return true;
4264 }
4265 break;
4266 case T_DeleteStmt:
4267 {
4268 DeleteStmt *stmt = (DeleteStmt *) node;
4269
4270 if (WALK(stmt->relation))
4271 return true;
4272 if (WALK(stmt->usingClause))
4273 return true;
4274 if (WALK(stmt->whereClause))
4275 return true;
4276 if (WALK(stmt->returningClause))
4277 return true;
4278 if (WALK(stmt->withClause))
4279 return true;
4280 }
4281 break;
4282 case T_UpdateStmt:
4283 {
4284 UpdateStmt *stmt = (UpdateStmt *) node;
4285
4286 if (WALK(stmt->relation))
4287 return true;
4288 if (WALK(stmt->targetList))
4289 return true;
4290 if (WALK(stmt->whereClause))
4291 return true;
4292 if (WALK(stmt->fromClause))
4293 return true;
4294 if (WALK(stmt->returningClause))
4295 return true;
4296 if (WALK(stmt->withClause))
4297 return true;
4298 }
4299 break;
4300 case T_MergeStmt:
4301 {
4302 MergeStmt *stmt = (MergeStmt *) node;
4303
4304 if (WALK(stmt->relation))
4305 return true;
4306 if (WALK(stmt->sourceRelation))
4307 return true;
4308 if (WALK(stmt->joinCondition))
4309 return true;
4310 if (WALK(stmt->mergeWhenClauses))
4311 return true;
4312 if (WALK(stmt->returningClause))
4313 return true;
4314 if (WALK(stmt->withClause))
4315 return true;
4316 }
4317 break;
4318 case T_MergeWhenClause:
4319 {
4320 MergeWhenClause *mergeWhenClause = (MergeWhenClause *) node;
4321
4322 if (WALK(mergeWhenClause->condition))
4323 return true;
4324 if (WALK(mergeWhenClause->targetList))
4325 return true;
4326 if (WALK(mergeWhenClause->values))
4327 return true;
4328 }
4329 break;
4330 case T_ReturningClause:
4331 {
4332 ReturningClause *returning = (ReturningClause *) node;
4333
4334 if (WALK(returning->options))
4335 return true;
4336 if (WALK(returning->exprs))
4337 return true;
4338 }
4339 break;
4340 case T_SelectStmt:
4341 {
4342 SelectStmt *stmt = (SelectStmt *) node;
4343
4344 if (WALK(stmt->distinctClause))
4345 return true;
4346 if (WALK(stmt->intoClause))
4347 return true;
4348 if (WALK(stmt->targetList))
4349 return true;
4350 if (WALK(stmt->fromClause))
4351 return true;
4352 if (WALK(stmt->whereClause))
4353 return true;
4354 if (WALK(stmt->groupClause))
4355 return true;
4356 if (WALK(stmt->havingClause))
4357 return true;
4358 if (WALK(stmt->windowClause))
4359 return true;
4360 if (WALK(stmt->valuesLists))
4361 return true;
4362 if (WALK(stmt->sortClause))
4363 return true;
4364 if (WALK(stmt->limitOffset))
4365 return true;
4366 if (WALK(stmt->limitCount))
4367 return true;
4368 if (WALK(stmt->lockingClause))
4369 return true;
4370 if (WALK(stmt->withClause))
4371 return true;
4372 if (WALK(stmt->larg))
4373 return true;
4374 if (WALK(stmt->rarg))
4375 return true;
4376 }
4377 break;
4378 case T_PLAssignStmt:
4379 {
4380 PLAssignStmt *stmt = (PLAssignStmt *) node;
4381
4382 if (WALK(stmt->indirection))
4383 return true;
4384 if (WALK(stmt->val))
4385 return true;
4386 }
4387 break;
4388 case T_A_Expr:
4389 {
4390 A_Expr *expr = (A_Expr *) node;
4391
4392 if (WALK(expr->lexpr))
4393 return true;
4394 if (WALK(expr->rexpr))
4395 return true;
4396 /* operator name is deemed uninteresting */
4397 }
4398 break;
4399 case T_BoolExpr:
4400 {
4401 BoolExpr *expr = (BoolExpr *) node;
4402
4403 if (WALK(expr->args))
4404 return true;
4405 }
4406 break;
4407 case T_ColumnRef:
4408 /* we assume the fields contain nothing interesting */
4409 break;
4410 case T_FuncCall:
4411 {
4412 FuncCall *fcall = (FuncCall *) node;
4413
4414 if (WALK(fcall->args))
4415 return true;
4416 if (WALK(fcall->agg_order))
4417 return true;
4418 if (WALK(fcall->agg_filter))
4419 return true;
4420 if (WALK(fcall->over))
4421 return true;
4422 /* function name is deemed uninteresting */
4423 }
4424 break;
4425 case T_NamedArgExpr:
4426 return WALK(((NamedArgExpr *) node)->arg);
4427 case T_A_Indices:
4428 {
4429 A_Indices *indices = (A_Indices *) node;
4430
4431 if (WALK(indices->lidx))
4432 return true;
4433 if (WALK(indices->uidx))
4434 return true;
4435 }
4436 break;
4437 case T_A_Indirection:
4438 {
4439 A_Indirection *indir = (A_Indirection *) node;
4440
4441 if (WALK(indir->arg))
4442 return true;
4443 if (WALK(indir->indirection))
4444 return true;
4445 }
4446 break;
4447 case T_A_ArrayExpr:
4448 return WALK(((A_ArrayExpr *) node)->elements);
4449 case T_ResTarget:
4450 {
4451 ResTarget *rt = (ResTarget *) node;
4452
4453 if (WALK(rt->indirection))
4454 return true;
4455 if (WALK(rt->val))
4456 return true;
4457 }
4458 break;
4459 case T_MultiAssignRef:
4460 return WALK(((MultiAssignRef *) node)->source);
4461 case T_TypeCast:
4462 {
4463 TypeCast *tc = (TypeCast *) node;
4464
4465 if (WALK(tc->arg))
4466 return true;
4467 if (WALK(tc->typeName))
4468 return true;
4469 }
4470 break;
4471 case T_CollateClause:
4472 return WALK(((CollateClause *) node)->arg);
4473 case T_SortBy:
4474 return WALK(((SortBy *) node)->node);
4475 case T_WindowDef:
4476 {
4477 WindowDef *wd = (WindowDef *) node;
4478
4479 if (WALK(wd->partitionClause))
4480 return true;
4481 if (WALK(wd->orderClause))
4482 return true;
4483 if (WALK(wd->startOffset))
4484 return true;
4485 if (WALK(wd->endOffset))
4486 return true;
4487 }
4488 break;
4489 case T_RangeSubselect:
4490 {
4491 RangeSubselect *rs = (RangeSubselect *) node;
4492
4493 if (WALK(rs->subquery))
4494 return true;
4495 if (WALK(rs->alias))
4496 return true;
4497 }
4498 break;
4499 case T_RangeFunction:
4500 {
4501 RangeFunction *rf = (RangeFunction *) node;
4502
4503 if (WALK(rf->functions))
4504 return true;
4505 if (WALK(rf->alias))
4506 return true;
4507 if (WALK(rf->coldeflist))
4508 return true;
4509 }
4510 break;
4511 case T_RangeTableSample:
4512 {
4513 RangeTableSample *rts = (RangeTableSample *) node;
4514
4515 if (WALK(rts->relation))
4516 return true;
4517 /* method name is deemed uninteresting */
4518 if (WALK(rts->args))
4519 return true;
4520 if (WALK(rts->repeatable))
4521 return true;
4522 }
4523 break;
4524 case T_RangeTableFunc:
4525 {
4526 RangeTableFunc *rtf = (RangeTableFunc *) node;
4527
4528 if (WALK(rtf->docexpr))
4529 return true;
4530 if (WALK(rtf->rowexpr))
4531 return true;
4532 if (WALK(rtf->namespaces))
4533 return true;
4534 if (WALK(rtf->columns))
4535 return true;
4536 if (WALK(rtf->alias))
4537 return true;
4538 }
4539 break;
4540 case T_RangeTableFuncCol:
4541 {
4542 RangeTableFuncCol *rtfc = (RangeTableFuncCol *) node;
4543
4544 if (WALK(rtfc->colexpr))
4545 return true;
4546 if (WALK(rtfc->coldefexpr))
4547 return true;
4548 }
4549 break;
4550 case T_TypeName:
4551 {
4552 TypeName *tn = (TypeName *) node;
4553
4554 if (WALK(tn->typmods))
4555 return true;
4556 if (WALK(tn->arrayBounds))
4557 return true;
4558 /* type name itself is deemed uninteresting */
4559 }
4560 break;
4561 case T_ColumnDef:
4562 {
4563 ColumnDef *coldef = (ColumnDef *) node;
4564
4565 if (WALK(coldef->typeName))
4566 return true;
4567 if (WALK(coldef->raw_default))
4568 return true;
4569 if (WALK(coldef->collClause))
4570 return true;
4571 /* for now, constraints are ignored */
4572 }
4573 break;
4574 case T_IndexElem:
4575 {
4576 IndexElem *indelem = (IndexElem *) node;
4577
4578 if (WALK(indelem->expr))
4579 return true;
4580 /* collation and opclass names are deemed uninteresting */
4581 }
4582 break;
4583 case T_GroupingSet:
4584 return WALK(((GroupingSet *) node)->content);
4585 case T_LockingClause:
4586 return WALK(((LockingClause *) node)->lockedRels);
4587 case T_XmlSerialize:
4588 {
4589 XmlSerialize *xs = (XmlSerialize *) node;
4590
4591 if (WALK(xs->expr))
4592 return true;
4593 if (WALK(xs->typeName))
4594 return true;
4595 }
4596 break;
4597 case T_WithClause:
4598 return WALK(((WithClause *) node)->ctes);
4599 case T_InferClause:
4600 {
4601 InferClause *stmt = (InferClause *) node;
4602
4603 if (WALK(stmt->indexElems))
4604 return true;
4605 if (WALK(stmt->whereClause))
4606 return true;
4607 }
4608 break;
4609 case T_OnConflictClause:
4610 {
4612
4613 if (WALK(stmt->infer))
4614 return true;
4615 if (WALK(stmt->targetList))
4616 return true;
4617 if (WALK(stmt->whereClause))
4618 return true;
4619 }
4620 break;
4621 case T_CommonTableExpr:
4622 /* search_clause and cycle_clause are not interesting here */
4623 return WALK(((CommonTableExpr *) node)->ctequery);
4624 case T_JsonOutput:
4625 {
4626 JsonOutput *out = (JsonOutput *) node;
4627
4628 if (WALK(out->typeName))
4629 return true;
4630 if (WALK(out->returning))
4631 return true;
4632 }
4633 break;
4634 case T_JsonKeyValue:
4635 {
4636 JsonKeyValue *jkv = (JsonKeyValue *) node;
4637
4638 if (WALK(jkv->key))
4639 return true;
4640 if (WALK(jkv->value))
4641 return true;
4642 }
4643 break;
4644 case T_JsonObjectConstructor:
4645 {
4647
4648 if (WALK(joc->output))
4649 return true;
4650 if (WALK(joc->exprs))
4651 return true;
4652 }
4653 break;
4654 case T_JsonArrayConstructor:
4655 {
4657
4658 if (WALK(jac->output))
4659 return true;
4660 if (WALK(jac->exprs))
4661 return true;
4662 }
4663 break;
4664 case T_JsonAggConstructor:
4665 {
4666 JsonAggConstructor *ctor = (JsonAggConstructor *) node;
4667
4668 if (WALK(ctor->output))
4669 return true;
4670 if (WALK(ctor->agg_order))
4671 return true;
4672 if (WALK(ctor->agg_filter))
4673 return true;
4674 if (WALK(ctor->over))
4675 return true;
4676 }
4677 break;
4678 case T_JsonObjectAgg:
4679 {
4680 JsonObjectAgg *joa = (JsonObjectAgg *) node;
4681
4682 if (WALK(joa->constructor))
4683 return true;
4684 if (WALK(joa->arg))
4685 return true;
4686 }
4687 break;
4688 case T_JsonArrayAgg:
4689 {
4690 JsonArrayAgg *jaa = (JsonArrayAgg *) node;
4691
4692 if (WALK(jaa->constructor))
4693 return true;
4694 if (WALK(jaa->arg))
4695 return true;
4696 }
4697 break;
4698 case T_JsonArrayQueryConstructor:
4699 {
4701
4702 if (WALK(jaqc->output))
4703 return true;
4704 if (WALK(jaqc->query))
4705 return true;
4706 }
4707 break;
4708 default:
4709 elog(ERROR, "unrecognized node type: %d",
4710 (int) nodeTag(node));
4711 break;
4712 }
4713 return false;
4714}
#define stmt
Definition: indent_codes.h:59
long val
Definition: informix.c:689
static char format
Node * rexpr
Definition: parsenodes.h:348
Node * uidx
Definition: parsenodes.h:472
Node * lidx
Definition: parsenodes.h:471
List * indirection
Definition: parsenodes.h:494
CollateClause * collClause
Definition: parsenodes.h:752
TypeName * typeName
Definition: parsenodes.h:738
Node * raw_default
Definition: parsenodes.h:746
Node * agg_filter
Definition: parsenodes.h:440
List * agg_order
Definition: parsenodes.h:439
List * args
Definition: parsenodes.h:438
struct WindowDef * over
Definition: parsenodes.h:441
Node * expr
Definition: parsenodes.h:795
RangeVar * rel
Definition: primnodes.h:162
JsonOutput * output
Definition: parsenodes.h:2009
JsonOutput * output
Definition: parsenodes.h:1982
JsonOutput * output
Definition: parsenodes.h:1838
List * passing
Definition: parsenodes.h:1837
JsonBehavior * on_empty
Definition: parsenodes.h:1839
Node * pathspec
Definition: parsenodes.h:1836
JsonBehavior * on_error
Definition: parsenodes.h:1840
JsonValueExpr * context_item
Definition: parsenodes.h:1835
JsonOutput * output
Definition: parsenodes.h:1968
JsonReturning * returning
Definition: parsenodes.h:1799