PostgreSQL Source Code git master
nodeFuncs.c File Reference
#include "postgres.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_type.h"
#include "miscadmin.h"
#include "nodes/execnodes.h"
#include "nodes/nodeFuncs.h"
#include "nodes/pathnodes.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
Include dependency graph for nodeFuncs.c:

Go to the source code of this file.

Macros

#define WALK(n)   walker((Node *) (n), context)
 
#define LIST_WALK(l)   expression_tree_walker_impl((Node *) (l), walker, context)
 
#define FLATCOPY(newnode, node, nodetype)
 
#define MUTATE(newfield, oldfield, fieldtype)    ( (newfield) = (fieldtype) mutator((Node *) (oldfield), context) )
 
#define PSWALK(n)   walker(n, context)
 

Functions

static bool expression_returns_set_walker (Node *node, void *context)
 
static int leftmostLoc (int loc1, int loc2)
 
static bool fix_opfuncids_walker (Node *node, void *context)
 
static bool planstate_walk_subplans (List *plans, planstate_tree_walker_callback walker, void *context)
 
static bool planstate_walk_members (PlanState **planstates, int nplans, planstate_tree_walker_callback walker, void *context)
 
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)
 
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)
 
bool query_tree_walker_impl (Query *query, tree_walker_callback walker, void *context, int flags)
 
bool range_table_walker_impl (List *rtable, tree_walker_callback walker, void *context, int flags)
 
bool range_table_entry_walker_impl (RangeTblEntry *rte, tree_walker_callback walker, void *context, int flags)
 
Nodeexpression_tree_mutator_impl (Node *node, tree_mutator_callback mutator, void *context)
 
Queryquery_tree_mutator_impl (Query *query, tree_mutator_callback mutator, void *context, int flags)
 
Listrange_table_mutator_impl (List *rtable, tree_mutator_callback mutator, 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 (PlanState *planstate, planstate_tree_walker_callback walker, void *context)
 

Macro Definition Documentation

◆ FLATCOPY

#define FLATCOPY (   newnode,
  node,
  nodetype 
)
Value:
( (newnode) = (nodetype *) palloc(sizeof(nodetype)), \
memcpy((newnode), (node), sizeof(nodetype)) )
void * palloc(Size size)
Definition: mcxt.c:1365

◆ LIST_WALK

#define LIST_WALK (   l)    expression_tree_walker_impl((Node *) (l), walker, context)

◆ MUTATE

#define MUTATE (   newfield,
  oldfield,
  fieldtype 
)     ( (newfield) = (fieldtype) mutator((Node *) (oldfield), context) )

◆ PSWALK

#define PSWALK (   n)    walker(n, context)

◆ WALK

#define WALK (   n)    walker((Node *) (n), context)

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:164
#define copyObject(obj)
Definition: nodes.h:232
#define makeNode(_type_)
Definition: nodes.h:161
void * arg
Oid consttype
Definition: primnodes.h:329
Definition: nodes.h:135
Oid resulttype
Definition: primnodes.h:1218
ParseLoc location
Definition: primnodes.h:1225
Expr * arg
Definition: primnodes.h:1217

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 1906 of file nodeFuncs.c.

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

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(), check_virtual_generated_security_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 ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:226
Assert(PointerIsAligned(start, uint64))
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:81
#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:1035
@ EXPR_SUBLINK
Definition: primnodes.h:1033
@ IS_XMLSERIALIZE
Definition: primnodes.h:1611
Node * expr
Definition: primnodes.h:1816
Oid collation
Definition: primnodes.h:1881
List * targetList
Definition: parsenodes.h:198
Oid firstColCollation
Definition: primnodes.h:1108
SubLinkType subLinkType
Definition: primnodes.h:1097
Definition: primnodes.h:262
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_generation_expression(), 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_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_eclass_for_sortgroupclause(), 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(), 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(), transformJsonBehavior(), transformJsonTableColumns(), transformMultiAssignRef(), transformPLAssignStmtTarget(), transformSubLink(), and transformWindowDefinitions().

◆ expression_returns_set()

◆ expression_returns_set_walker()

static bool expression_returns_set_walker ( Node node,
void *  context 
)
static

Definition at line 769 of file nodeFuncs.c.

770{
771 if (node == NULL)
772 return false;
773 if (IsA(node, FuncExpr))
774 {
775 FuncExpr *expr = (FuncExpr *) node;
776
777 if (expr->funcretset)
778 return true;
779 /* else fall through to check args */
780 }
781 if (IsA(node, OpExpr))
782 {
783 OpExpr *expr = (OpExpr *) node;
784
785 if (expr->opretset)
786 return true;
787 /* else fall through to check args */
788 }
789
790 /*
791 * If you add any more cases that return sets, also fix
792 * expression_returns_set_rows() in clauses.c and IS_SRF_CALL() in
793 * tlist.c.
794 */
795
796 /* Avoid recursion for some cases that parser checks not to return a set */
797 if (IsA(node, Aggref))
798 return false;
799 if (IsA(node, GroupingFunc))
800 return false;
801 if (IsA(node, WindowFunc))
802 return false;
803
805 context);
806}
#define expression_tree_walker(n, w, c)
Definition: nodeFuncs.h:153

References expression_returns_set_walker(), expression_tree_walker, and IsA.

Referenced by expression_returns_set(), and expression_returns_set_walker().

◆ expression_tree_mutator_impl()

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

Definition at line 2946 of file nodeFuncs.c.

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

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, 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 2089 of file nodeFuncs.c.

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

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 1384 of file nodeFuncs.c.

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

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(), check_virtual_generated_security_walker(), 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(), transformPLAssignStmtTarget(), 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 Assert(((JsonBehavior *) expr)->expr == NULL ||
1278 exprCollation(((JsonBehavior *) expr)->expr) == collation);
1279 break;
1280 case T_NullTest:
1281 /* NullTest's result is boolean ... */
1282 Assert(!OidIsValid(collation)); /* ... so never set a collation */
1283 break;
1284 case T_BooleanTest:
1285 /* BooleanTest's result is boolean ... */
1286 Assert(!OidIsValid(collation)); /* ... so never set a collation */
1287 break;
1288 case T_CoerceToDomain:
1289 ((CoerceToDomain *) expr)->resultcollid = collation;
1290 break;
1291 case T_CoerceToDomainValue:
1292 ((CoerceToDomainValue *) expr)->collation = collation;
1293 break;
1294 case T_SetToDefault:
1295 ((SetToDefault *) expr)->collation = collation;
1296 break;
1297 case T_CurrentOfExpr:
1298 /* CurrentOfExpr's result is boolean ... */
1299 Assert(!OidIsValid(collation)); /* ... so never set a collation */
1300 break;
1301 case T_NextValueExpr:
1302 /* NextValueExpr's result is an integer type ... */
1303 Assert(!OidIsValid(collation)); /* ... so never set a collation */
1304 break;
1305 default:
1306 elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
1307 break;
1308 }
1309}
#define OidIsValid(objectId)
Definition: c.h:778
void exprSetCollation(Node *expr, Oid collation)
Definition: nodeFuncs.c:1124

References arg, ARRAY_SUBLINK, Assert(), JsonConstructorExpr::coercion, JsonExpr::collation, elog, ERROR, 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 1320 of file nodeFuncs.c.

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

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:863
int errmsg(const char *fmt,...)
Definition: elog.c:1080
#define ereport(elevel,...)
Definition: elog.h:150
char * format_type_be(Oid type_oid)
Definition: format_type.c:343
Oid get_promoted_array_type(Oid typid)
Definition: lsyscache.c:2978
@ MULTIEXPR_SUBLINK
Definition: primnodes.h:1034
@ IS_DOCUMENT
Definition: primnodes.h:1612
JsonReturning * returning
Definition: primnodes.h:1857
Oid firstColType
Definition: primnodes.h:1106

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_stmt_retval(), check_virtual_generated_security_walker(), 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(), convert_VALUES_to_ANY(), cookDefault(), cost_qual_eval_walker(), create_ctas_nodata(), create_grouping_expr_infos(), 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(), init_grouping_targets(), 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(), transformPLAssignStmtTarget(), 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:538
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:1107

References arg, OpExpr::args, CaseExpr::args, CoalesceExpr::args, MinMaxExpr::args, ARRAY_SUBLINK, Assert(), CaseExpr::defresult, 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(), transformPLAssignStmtTarget(), transformSubLink(), varbit_support(), and varchar_support().

◆ fix_opfuncids()

void fix_opfuncids ( Node node)

Definition at line 1837 of file nodeFuncs.c.

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

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().

◆ fix_opfuncids_walker()

static bool fix_opfuncids_walker ( Node node,
void *  context 
)
static

Definition at line 1844 of file nodeFuncs.c.

1845{
1846 if (node == NULL)
1847 return false;
1848 if (IsA(node, OpExpr))
1849 set_opfuncid((OpExpr *) node);
1850 else if (IsA(node, DistinctExpr))
1851 set_opfuncid((OpExpr *) node); /* rely on struct equivalence */
1852 else if (IsA(node, NullIfExpr))
1853 set_opfuncid((OpExpr *) node); /* rely on struct equivalence */
1854 else if (IsA(node, ScalarArrayOpExpr))
1856 return expression_tree_walker(node, fix_opfuncids_walker, context);
1857}

References expression_tree_walker, fix_opfuncids_walker(), IsA, set_opfuncid(), and set_sa_opfuncid().

Referenced by fix_opfuncids(), and fix_opfuncids_walker().

◆ leftmostLoc()

static int leftmostLoc ( int  loc1,
int  loc2 
)
static

Definition at line 1816 of file nodeFuncs.c.

1817{
1818 if (loc1 < 0)
1819 return loc2;
1820 else if (loc2 < 0)
1821 return loc1;
1822 else
1823 return Min(loc1, loc2);
1824}
#define Min(x, y)
Definition: c.h:1007

References Min.

Referenced by exprLocation().

◆ planstate_tree_walker_impl()

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

Definition at line 4719 of file nodeFuncs.c.

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

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

◆ planstate_walk_members()

static bool planstate_walk_members ( PlanState **  planstates,
int  nplans,
planstate_tree_walker_callback  walker,
void *  context 
)
static

Definition at line 4825 of file nodeFuncs.c.

4828{
4829 int j;
4830
4831 for (j = 0; j < nplans; j++)
4832 {
4833 if (PSWALK(planstates[j]))
4834 return true;
4835 }
4836
4837 return false;
4838}
int j
Definition: isn.c:78

References j, and PSWALK.

Referenced by planstate_tree_walker_impl().

◆ planstate_walk_subplans()

static bool planstate_walk_subplans ( List plans,
planstate_tree_walker_callback  walker,
void *  context 
)
static

Definition at line 4803 of file nodeFuncs.c.

4806{
4807 ListCell *lc;
4808
4809 foreach(lc, plans)
4810 {
4812
4813 if (PSWALK(sps->planstate))
4814 return true;
4815 }
4816
4817 return false;
4818}
PlanState * planstate
Definition: execnodes.h:1013

References lfirst_node, SubPlanState::planstate, and PSWALK.

Referenced by planstate_tree_walker_impl().

◆ 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 3965 of file nodeFuncs.c.

3969{
3970 if (node && IsA(node, Query))
3971 return (Node *) query_tree_mutator((Query *) node,
3972 mutator,
3973 context,
3974 flags);
3975 else
3976 return mutator(node, context);
3977}
#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 3942 of file nodeFuncs.c.

3946{
3947 if (node && IsA(node, Query))
3948 return query_tree_walker((Query *) node,
3949 walker,
3950 context,
3951 flags);
3952 else
3953 return WALK(node);
3954}
#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 3773 of file nodeFuncs.c.

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

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 2694 of file nodeFuncs.c.

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

2822{
2823 /*
2824 * Walkers might need to examine the RTE node itself either before or
2825 * after visiting its contents (or, conceivably, both). Note that if you
2826 * specify neither flag, the walker won't be called on the RTE at all.
2827 */
2828 if (flags & QTW_EXAMINE_RTES_BEFORE)
2829 if (WALK(rte))
2830 return true;
2831
2832 switch (rte->rtekind)
2833 {
2834 case RTE_RELATION:
2835 if (WALK(rte->tablesample))
2836 return true;
2837 break;
2838 case RTE_SUBQUERY:
2839 if (!(flags & QTW_IGNORE_RT_SUBQUERIES))
2840 if (WALK(rte->subquery))
2841 return true;
2842 break;
2843 case RTE_JOIN:
2844 if (!(flags & QTW_IGNORE_JOINALIASES))
2845 if (WALK(rte->joinaliasvars))
2846 return true;
2847 break;
2848 case RTE_FUNCTION:
2849 if (WALK(rte->functions))
2850 return true;
2851 break;
2852 case RTE_TABLEFUNC:
2853 if (WALK(rte->tablefunc))
2854 return true;
2855 break;
2856 case RTE_VALUES:
2857 if (WALK(rte->values_lists))
2858 return true;
2859 break;
2860 case RTE_CTE:
2862 case RTE_RESULT:
2863 /* nothing to do */
2864 break;
2865 case RTE_GROUP:
2866 if (!(flags & QTW_IGNORE_GROUPEXPRS))
2867 if (WALK(rte->groupexprs))
2868 return true;
2869 break;
2870 }
2871
2872 if (WALK(rte->securityQuals))
2873 return true;
2874
2875 if (flags & QTW_EXAMINE_RTES_AFTER)
2876 if (WALK(rte))
2877 return true;
2878
2879 return false;
2880}
#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:1045
@ RTE_CTE
Definition: parsenodes.h:1049
@ RTE_NAMEDTUPLESTORE
Definition: parsenodes.h:1050
@ RTE_VALUES
Definition: parsenodes.h:1048
@ RTE_SUBQUERY
Definition: parsenodes.h:1044
@ RTE_RESULT
Definition: parsenodes.h:1051
@ RTE_FUNCTION
Definition: parsenodes.h:1046
@ RTE_TABLEFUNC
Definition: parsenodes.h:1047
@ RTE_GROUP
Definition: parsenodes.h:1054
@ RTE_RELATION
Definition: parsenodes.h:1043
TableFunc * tablefunc
Definition: parsenodes.h:1215
struct TableSampleClause * tablesample
Definition: parsenodes.h:1129
Query * subquery
Definition: parsenodes.h:1135
List * values_lists
Definition: parsenodes.h:1221
List * functions
Definition: parsenodes.h:1208
RTEKind rtekind
Definition: parsenodes.h:1078

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 3864 of file nodeFuncs.c.

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

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 2797 of file nodeFuncs.c.

2801{
2802 ListCell *rt;
2803
2804 foreach(rt, rtable)
2805 {
2807
2808 if (range_table_entry_walker(rte, walker, context, flags))
2809 return true;
2810 }
2811 return false;
2812}
#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 3996 of file nodeFuncs.c.

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

References FuncCall::agg_filter, JsonAggConstructor::agg_filter, FuncCall::agg_order, JsonAggConstructor::agg_order, RangeSubselect::alias, RangeFunction::alias, RangeTableFunc::alias, arg, TypeCast::arg, A_Indirection::arg, JsonObjectAgg::arg, JsonArrayAgg::arg, CaseExpr::arg, generate_unaccent_rules::args, FuncCall::args, RangeTableSample::args, BoolExpr::args, CaseExpr::args, XmlExpr::args, JsonConstructorExpr::args, TypeName::arrayBounds, check_stack_depth(), JsonConstructorExpr::coercion, RangeTableFuncCol::coldefexpr, RangeFunction::coldeflist, RangeTableFuncCol::colexpr, ColumnDef::collClause, RangeTableFunc::columns, JsonTable::columns, JsonTableColumn::columns, MergeWhenClause::condition, JsonObjectAgg::constructor, JsonArrayAgg::constructor, JsonFuncExpr::context_item, JsonTable::context_item, CaseExpr::defresult, RangeTableFunc::docexpr, elog, WindowDef::endOffset, ERROR, IndexElem::expr, XmlSerialize::expr, JsonParseExpr::expr, JsonScalarExpr::expr, JsonSerializeExpr::expr, JsonBehavior::expr, ReturningClause::exprs, JsonObjectConstructor::exprs, JsonArrayConstructor::exprs, format, JsonValueExpr::format, JsonValueExpr::formatted_expr, JsonConstructorExpr::func, RangeFunction::functions, A_Indirection::indirection, ResTarget::indirection, JsonKeyValue::key, JoinExpr::larg, A_Expr::lexpr, lfirst, lfirst_node, A_Indices::lidx, XmlExpr::named_args, RangeTableFunc::namespaces, nodeTag, JsonFuncExpr::on_empty, JsonTableColumn::on_empty, JsonFuncExpr::on_error, JsonTable::on_error, JsonTableColumn::on_error, ReturningClause::options, WindowDef::orderClause, JsonFuncExpr::output, JsonParseExpr::output, JsonScalarExpr::output, JsonSerializeExpr::output, JsonObjectConstructor::output, JsonArrayConstructor::output, JsonArrayQueryConstructor::output, JsonAggConstructor::output, FuncCall::over, JsonAggConstructor::over, WindowDef::partitionClause, JsonFuncExpr::passing, JsonTable::passing, JsonFuncExpr::pathspec, JsonTable::pathspec, JoinExpr::quals, JsonArrayQueryConstructor::query, JoinExpr::rarg, ColumnDef::raw_default, JsonValueExpr::raw_expr, IntoClause::rel, RangeTableSample::relation, RangeTableSample::repeatable, JsonOutput::returning, JsonConstructorExpr::returning, A_Expr::rexpr, RangeTableFunc::rowexpr, source, WindowDef::startOffset, stmt, RangeSubselect::subquery, SubLink::subselect, MergeWhenClause::targetList, SubLink::testexpr, TypeCast::typeName, ColumnDef::typeName, XmlSerialize::typeName, JsonOutput::typeName, JsonTableColumn::typeName, TypeName::typmods, A_Indices::uidx, ResTarget::val, val, JsonKeyValue::value, MergeWhenClause::values, and WALK.

◆ relabel_to_typmod()

Node * relabel_to_typmod ( Node expr,
int32  typmod 
)

Definition at line 689 of file nodeFuncs.c.

690{
691 return applyRelabelType(expr, exprType(expr), typmod, exprCollation(expr),
692 COERCE_EXPLICIT_CAST, -1, false);
693}
Node * applyRelabelType(Node *arg, Oid rtype, int32 rtypmod, Oid rcollid, CoercionForm rformat, int rlocation, bool overwrite_ok)
Definition: nodeFuncs.c:636

References applyRelabelType(), COERCE_EXPLICIT_CAST, exprCollation(), and exprType().

Referenced by interval_support(), numeric_support(), TemporalSimplify(), varbit_support(), and varchar_support().

◆ set_opfuncid()

◆ set_sa_opfuncid()

void set_sa_opfuncid ( ScalarArrayOpExpr opexpr)

Definition at line 1879 of file nodeFuncs.c.

1880{
1881 if (opexpr->opfuncid == InvalidOid)
1882 opexpr->opfuncid = get_opcode(opexpr->opno);
1883}

References get_opcode(), InvalidOid, and ScalarArrayOpExpr::opno.

Referenced by check_functions_in_node(), cost_qual_eval_walker(), eval_const_expressions_mutator(), fix_expr_common(), fix_opfuncids_walker(), and is_strict_saop().

◆ strip_implicit_coercions()

Node * strip_implicit_coercions ( Node node)

Definition at line 705 of file nodeFuncs.c.

706{
707 if (node == NULL)
708 return NULL;
709 if (IsA(node, FuncExpr))
710 {
711 FuncExpr *f = (FuncExpr *) node;
712
713 if (f->funcformat == COERCE_IMPLICIT_CAST)
715 }
716 else if (IsA(node, RelabelType))
717 {
718 RelabelType *r = (RelabelType *) node;
719
720 if (r->relabelformat == COERCE_IMPLICIT_CAST)
721 return strip_implicit_coercions((Node *) r->arg);
722 }
723 else if (IsA(node, CoerceViaIO))
724 {
725 CoerceViaIO *c = (CoerceViaIO *) node;
726
727 if (c->coerceformat == COERCE_IMPLICIT_CAST)
728 return strip_implicit_coercions((Node *) c->arg);
729 }
730 else if (IsA(node, ArrayCoerceExpr))
731 {
733
734 if (c->coerceformat == COERCE_IMPLICIT_CAST)
735 return strip_implicit_coercions((Node *) c->arg);
736 }
737 else if (IsA(node, ConvertRowtypeExpr))
738 {
740
741 if (c->convertformat == COERCE_IMPLICIT_CAST)
742 return strip_implicit_coercions((Node *) c->arg);
743 }
744 else if (IsA(node, CoerceToDomain))
745 {
746 CoerceToDomain *c = (CoerceToDomain *) node;
747
748 if (c->coercionformat == COERCE_IMPLICIT_CAST)
749 return strip_implicit_coercions((Node *) c->arg);
750 }
751 return node;
752}
Node * strip_implicit_coercions(Node *node)
Definition: nodeFuncs.c:705
char * c

References RelabelType::arg, FuncExpr::args, COERCE_IMPLICIT_CAST, IsA, linitial, and strip_implicit_coercions().

Referenced by AcquireRewriteLocks(), ATExecAlterColumnType(), findTargetlistEntrySQL99(), foreign_expr_walker(), get_rule_expr(), get_update_query_targetlist_def(), and strip_implicit_coercions().