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

Go to the source code of this file.

Macros

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

Typedefs

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

Functions

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

Macro Definition Documentation

◆ expression_tree_mutator

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

Definition at line 153 of file nodeFuncs.h.

◆ expression_tree_walker

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

Definition at line 151 of file nodeFuncs.h.

◆ planstate_tree_walker

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

Definition at line 177 of file nodeFuncs.h.

◆ QTW_DONT_COPY_QUERY

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

Definition at line 29 of file nodeFuncs.h.

◆ QTW_EXAMINE_RTES_AFTER

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

Definition at line 28 of file nodeFuncs.h.

◆ QTW_EXAMINE_RTES_BEFORE

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

Definition at line 27 of file nodeFuncs.h.

◆ QTW_EXAMINE_SORTGROUP

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

Definition at line 30 of file nodeFuncs.h.

◆ QTW_IGNORE_CTE_SUBQUERIES

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

Definition at line 23 of file nodeFuncs.h.

◆ QTW_IGNORE_JOINALIASES

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

Definition at line 25 of file nodeFuncs.h.

◆ QTW_IGNORE_RANGE_TABLE

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

Definition at line 26 of file nodeFuncs.h.

◆ QTW_IGNORE_RC_SUBQUERIES

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

Definition at line 24 of file nodeFuncs.h.

◆ QTW_IGNORE_RT_SUBQUERIES

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

Definition at line 22 of file nodeFuncs.h.

◆ query_or_expression_tree_mutator

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

Definition at line 171 of file nodeFuncs.h.

◆ query_or_expression_tree_walker

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

Definition at line 169 of file nodeFuncs.h.

◆ query_tree_mutator

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

Definition at line 158 of file nodeFuncs.h.

◆ query_tree_walker

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

Definition at line 156 of file nodeFuncs.h.

◆ range_table_entry_walker

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

Definition at line 166 of file nodeFuncs.h.

◆ range_table_mutator

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

Definition at line 163 of file nodeFuncs.h.

◆ range_table_walker

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

Definition at line 161 of file nodeFuncs.h.

◆ raw_expression_tree_walker

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

Definition at line 174 of file nodeFuncs.h.

Typedef Documentation

◆ check_function_callback

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

Definition at line 33 of file nodeFuncs.h.

◆ planstate_tree_walker_callback

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

Definition at line 37 of file nodeFuncs.h.

◆ tree_mutator_callback

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

Definition at line 41 of file nodeFuncs.h.

◆ tree_walker_callback

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

Definition at line 36 of file nodeFuncs.h.

Function Documentation

◆ applyRelabelType()

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

Definition at line 603 of file nodeFuncs.c.

605 {
606  /*
607  * If we find stacked RelabelTypes (eg, from foo::int::oid) we can discard
608  * all but the top one, and must do so to ensure that semantically
609  * equivalent expressions are equal().
610  */
611  while (arg && IsA(arg, RelabelType))
612  arg = (Node *) ((RelabelType *) arg)->arg;
613 
614  if (arg && IsA(arg, Const))
615  {
616  /* Modify the Const directly to preserve const-flatness. */
617  Const *con = (Const *) arg;
618 
619  if (!overwrite_ok)
620  con = copyObject(con);
621  con->consttype = rtype;
622  con->consttypmod = rtypmod;
623  con->constcollid = rcollid;
624  /* We keep the Const's original location. */
625  return (Node *) con;
626  }
627  else if (exprType(arg) == rtype &&
628  exprTypmod(arg) == rtypmod &&
629  exprCollation(arg) == rcollid)
630  {
631  /* Sometimes we find a nest of relabels that net out to nothing. */
632  return arg;
633  }
634  else
635  {
636  /* Nope, gotta have a RelabelType. */
637  RelabelType *newrelabel = makeNode(RelabelType);
638 
639  newrelabel->arg = (Expr *) arg;
640  newrelabel->resulttype = rtype;
641  newrelabel->resulttypmod = rtypmod;
642  newrelabel->resultcollid = rcollid;
643  newrelabel->relabelformat = rformat;
644  newrelabel->location = rlocation;
645  return (Node *) newrelabel;
646  }
647 }
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
int32 exprTypmod(const Node *expr)
Definition: nodeFuncs.c:284
Oid exprCollation(const Node *expr)
Definition: nodeFuncs.c:788
#define IsA(nodeptr, _type_)
Definition: nodes.h:158
#define copyObject(obj)
Definition: nodes.h:223
#define makeNode(_type_)
Definition: nodes.h:155
void * arg
Oid consttype
Definition: primnodes.h:298
Definition: nodes.h:129
Oid resulttype
Definition: primnodes.h:1141
Expr * arg
Definition: primnodes.h:1140

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

1830 {
1831  switch (nodeTag(node))
1832  {
1833  case T_Aggref:
1834  {
1835  Aggref *expr = (Aggref *) node;
1836 
1837  if (checker(expr->aggfnoid, context))
1838  return true;
1839  }
1840  break;
1841  case T_WindowFunc:
1842  {
1843  WindowFunc *expr = (WindowFunc *) node;
1844 
1845  if (checker(expr->winfnoid, context))
1846  return true;
1847  }
1848  break;
1849  case T_FuncExpr:
1850  {
1851  FuncExpr *expr = (FuncExpr *) node;
1852 
1853  if (checker(expr->funcid, context))
1854  return true;
1855  }
1856  break;
1857  case T_OpExpr:
1858  case T_DistinctExpr: /* struct-equivalent to OpExpr */
1859  case T_NullIfExpr: /* struct-equivalent to OpExpr */
1860  {
1861  OpExpr *expr = (OpExpr *) node;
1862 
1863  /* Set opfuncid if it wasn't set already */
1864  set_opfuncid(expr);
1865  if (checker(expr->opfuncid, context))
1866  return true;
1867  }
1868  break;
1869  case T_ScalarArrayOpExpr:
1870  {
1871  ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
1872 
1873  set_sa_opfuncid(expr);
1874  if (checker(expr->opfuncid, context))
1875  return true;
1876  }
1877  break;
1878  case T_CoerceViaIO:
1879  {
1880  CoerceViaIO *expr = (CoerceViaIO *) node;
1881  Oid iofunc;
1882  Oid typioparam;
1883  bool typisvarlena;
1884 
1885  /* check the result type's input function */
1887  &iofunc, &typioparam);
1888  if (checker(iofunc, context))
1889  return true;
1890  /* check the input type's output function */
1891  getTypeOutputInfo(exprType((Node *) expr->arg),
1892  &iofunc, &typisvarlena);
1893  if (checker(iofunc, context))
1894  return true;
1895  }
1896  break;
1897  case T_RowCompareExpr:
1898  {
1899  RowCompareExpr *rcexpr = (RowCompareExpr *) node;
1900  ListCell *opid;
1901 
1902  foreach(opid, rcexpr->opnos)
1903  {
1904  Oid opfuncid = get_opcode(lfirst_oid(opid));
1905 
1906  if (checker(opfuncid, context))
1907  return true;
1908  }
1909  }
1910  break;
1911  default:
1912  break;
1913  }
1914  return false;
1915 }
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2863
RegProcedure get_opcode(Oid opno)
Definition: lsyscache.c:1263
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
Definition: lsyscache.c:2830
void set_sa_opfuncid(ScalarArrayOpExpr *opexpr)
Definition: nodeFuncs.c:1801
void set_opfuncid(OpExpr *opexpr)
Definition: nodeFuncs.c:1790
#define nodeTag(nodeptr)
Definition: nodes.h:133
#define lfirst_oid(lc)
Definition: pg_list.h:174
unsigned int Oid
Definition: postgres_ext.h:31
Oid aggfnoid
Definition: primnodes.h:430
Expr * arg
Definition: primnodes.h:1163
Oid resulttype
Definition: primnodes.h:1164
Oid funcid
Definition: primnodes.h:706
Oid winfnoid
Definition: primnodes.h:553

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

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

◆ exprCollation()

Oid exprCollation ( const Node expr)

Definition at line 788 of file nodeFuncs.c.

789 {
790  Oid coll;
791 
792  if (!expr)
793  return InvalidOid;
794 
795  switch (nodeTag(expr))
796  {
797  case T_Var:
798  coll = ((const Var *) expr)->varcollid;
799  break;
800  case T_Const:
801  coll = ((const Const *) expr)->constcollid;
802  break;
803  case T_Param:
804  coll = ((const Param *) expr)->paramcollid;
805  break;
806  case T_Aggref:
807  coll = ((const Aggref *) expr)->aggcollid;
808  break;
809  case T_GroupingFunc:
810  coll = InvalidOid;
811  break;
812  case T_WindowFunc:
813  coll = ((const WindowFunc *) expr)->wincollid;
814  break;
815  case T_MergeSupportFunc:
816  coll = ((const MergeSupportFunc *) expr)->msfcollid;
817  break;
818  case T_SubscriptingRef:
819  coll = ((const SubscriptingRef *) expr)->refcollid;
820  break;
821  case T_FuncExpr:
822  coll = ((const FuncExpr *) expr)->funccollid;
823  break;
824  case T_NamedArgExpr:
825  coll = exprCollation((Node *) ((const NamedArgExpr *) expr)->arg);
826  break;
827  case T_OpExpr:
828  coll = ((const OpExpr *) expr)->opcollid;
829  break;
830  case T_DistinctExpr:
831  coll = ((const DistinctExpr *) expr)->opcollid;
832  break;
833  case T_NullIfExpr:
834  coll = ((const NullIfExpr *) expr)->opcollid;
835  break;
836  case T_ScalarArrayOpExpr:
837  /* ScalarArrayOpExpr's result is boolean ... */
838  coll = InvalidOid; /* ... so it has no collation */
839  break;
840  case T_BoolExpr:
841  /* BoolExpr's result is boolean ... */
842  coll = InvalidOid; /* ... so it has no collation */
843  break;
844  case T_SubLink:
845  {
846  const SubLink *sublink = (const SubLink *) expr;
847 
848  if (sublink->subLinkType == EXPR_SUBLINK ||
849  sublink->subLinkType == ARRAY_SUBLINK)
850  {
851  /* get the collation of subselect's first target column */
852  Query *qtree = (Query *) sublink->subselect;
853  TargetEntry *tent;
854 
855  if (!qtree || !IsA(qtree, Query))
856  elog(ERROR, "cannot get collation for untransformed sublink");
857  tent = linitial_node(TargetEntry, qtree->targetList);
858  Assert(!tent->resjunk);
859  coll = exprCollation((Node *) tent->expr);
860  /* collation doesn't change if it's converted to array */
861  }
862  else
863  {
864  /* otherwise, SubLink's result is RECORD or BOOLEAN */
865  coll = InvalidOid; /* ... so it has no collation */
866  }
867  }
868  break;
869  case T_SubPlan:
870  {
871  const SubPlan *subplan = (const SubPlan *) expr;
872 
873  if (subplan->subLinkType == EXPR_SUBLINK ||
874  subplan->subLinkType == ARRAY_SUBLINK)
875  {
876  /* get the collation of subselect's first target column */
877  coll = subplan->firstColCollation;
878  /* collation doesn't change if it's converted to array */
879  }
880  else
881  {
882  /* otherwise, SubPlan's result is RECORD or BOOLEAN */
883  coll = InvalidOid; /* ... so it has no collation */
884  }
885  }
886  break;
887  case T_AlternativeSubPlan:
888  {
889  const AlternativeSubPlan *asplan = (const AlternativeSubPlan *) expr;
890 
891  /* subplans should all return the same thing */
892  coll = exprCollation((Node *) linitial(asplan->subplans));
893  }
894  break;
895  case T_FieldSelect:
896  coll = ((const FieldSelect *) expr)->resultcollid;
897  break;
898  case T_FieldStore:
899  /* FieldStore's result is composite ... */
900  coll = InvalidOid; /* ... so it has no collation */
901  break;
902  case T_RelabelType:
903  coll = ((const RelabelType *) expr)->resultcollid;
904  break;
905  case T_CoerceViaIO:
906  coll = ((const CoerceViaIO *) expr)->resultcollid;
907  break;
908  case T_ArrayCoerceExpr:
909  coll = ((const ArrayCoerceExpr *) expr)->resultcollid;
910  break;
911  case T_ConvertRowtypeExpr:
912  /* ConvertRowtypeExpr's result is composite ... */
913  coll = InvalidOid; /* ... so it has no collation */
914  break;
915  case T_CollateExpr:
916  coll = ((const CollateExpr *) expr)->collOid;
917  break;
918  case T_CaseExpr:
919  coll = ((const CaseExpr *) expr)->casecollid;
920  break;
921  case T_CaseTestExpr:
922  coll = ((const CaseTestExpr *) expr)->collation;
923  break;
924  case T_ArrayExpr:
925  coll = ((const ArrayExpr *) expr)->array_collid;
926  break;
927  case T_RowExpr:
928  /* RowExpr's result is composite ... */
929  coll = InvalidOid; /* ... so it has no collation */
930  break;
931  case T_RowCompareExpr:
932  /* RowCompareExpr's result is boolean ... */
933  coll = InvalidOid; /* ... so it has no collation */
934  break;
935  case T_CoalesceExpr:
936  coll = ((const CoalesceExpr *) expr)->coalescecollid;
937  break;
938  case T_MinMaxExpr:
939  coll = ((const MinMaxExpr *) expr)->minmaxcollid;
940  break;
941  case T_SQLValueFunction:
942  /* Returns either NAME or a non-collatable type */
943  if (((const SQLValueFunction *) expr)->type == NAMEOID)
944  coll = C_COLLATION_OID;
945  else
946  coll = InvalidOid;
947  break;
948  case T_XmlExpr:
949 
950  /*
951  * XMLSERIALIZE returns text from non-collatable inputs, so its
952  * collation is always default. The other cases return boolean or
953  * XML, which are non-collatable.
954  */
955  if (((const XmlExpr *) expr)->op == IS_XMLSERIALIZE)
956  coll = DEFAULT_COLLATION_OID;
957  else
958  coll = InvalidOid;
959  break;
960  case T_JsonValueExpr:
961  coll = exprCollation((Node *) ((const JsonValueExpr *) expr)->formatted_expr);
962  break;
963  case T_JsonConstructorExpr:
964  {
965  const JsonConstructorExpr *ctor = (const JsonConstructorExpr *) expr;
966 
967  if (ctor->coercion)
968  coll = exprCollation((Node *) ctor->coercion);
969  else
970  coll = InvalidOid;
971  }
972  break;
973  case T_JsonIsPredicate:
974  /* IS JSON's result is boolean ... */
975  coll = InvalidOid; /* ... so it has no collation */
976  break;
977  case T_NullTest:
978  /* NullTest's result is boolean ... */
979  coll = InvalidOid; /* ... so it has no collation */
980  break;
981  case T_BooleanTest:
982  /* BooleanTest's result is boolean ... */
983  coll = InvalidOid; /* ... so it has no collation */
984  break;
985  case T_CoerceToDomain:
986  coll = ((const CoerceToDomain *) expr)->resultcollid;
987  break;
988  case T_CoerceToDomainValue:
989  coll = ((const CoerceToDomainValue *) expr)->collation;
990  break;
991  case T_SetToDefault:
992  coll = ((const SetToDefault *) expr)->collation;
993  break;
994  case T_CurrentOfExpr:
995  /* CurrentOfExpr's result is boolean ... */
996  coll = InvalidOid; /* ... so it has no collation */
997  break;
998  case T_NextValueExpr:
999  /* NextValueExpr's result is an integer type ... */
1000  coll = InvalidOid; /* ... so it has no collation */
1001  break;
1002  case T_InferenceElem:
1003  coll = exprCollation((Node *) ((const InferenceElem *) expr)->expr);
1004  break;
1005  case T_PlaceHolderVar:
1006  coll = exprCollation((Node *) ((const PlaceHolderVar *) expr)->phexpr);
1007  break;
1008  default:
1009  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
1010  coll = InvalidOid; /* keep compiler quiet */
1011  break;
1012  }
1013  return coll;
1014 }
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
Assert(fmt[strlen(fmt) - 1] !='\n')
#define linitial_node(type, l)
Definition: pg_list.h:181
#define linitial(l)
Definition: pg_list.h:178
#define InvalidOid
Definition: postgres_ext.h:36
@ ARRAY_SUBLINK
Definition: primnodes.h:959
@ EXPR_SUBLINK
Definition: primnodes.h:957
@ IS_XMLSERIALIZE
Definition: primnodes.h:1542
List * targetList
Definition: parsenodes.h:190
Oid firstColCollation
Definition: primnodes.h:1032
SubLinkType subLinkType
Definition: primnodes.h:1021
Definition: primnodes.h:234
const char * type

References arg, ARRAY_SUBLINK, Assert(), JsonConstructorExpr::coercion, elog, ERROR, EXPR_SUBLINK, 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(), addRangeTableEntryForSubquery(), analyzeCTE(), analyzeCTETargetList(), applyRelabelType(), assign_collations_walker(), assign_hypothetical_collations(), build_expression_pathkey(), build_pertrans_for_aggref(), build_subplan(), canonicalize_ec_expression(), check_simple_rowfilter_expr_walker(), coerce_type_typmod(), ComputeIndexAttrs(), ComputePartitionAttrs(), convert_EXISTS_to_ANY(), create_ctas_nodata(), create_limit_plan(), create_memoize_plan(), create_unique_plan(), create_windowagg_plan(), DefineVirtualRelation(), eval_const_expressions_mutator(), examine_attribute(), examine_expression(), ExecInitFunctionScan(), ExecInitIndexScan(), ExecTypeFromExprList(), ExecTypeFromTLInternal(), expandRecordVariable(), expandRTE(), exprSetCollation(), extract_grouping_collations(), fix_indexqual_operand(), generate_setop_tlist(), generate_subquery_params(), get_expr_result_type(), get_first_col_type(), inline_function(), make_pathkey_from_sortop(), make_recursive_union(), make_setop(), make_sort_from_groupcols(), make_sort_from_sortclauses(), make_unique_from_sortclauses(), makeJsonConstructorExpr(), makeVarFromTargetEntry(), makeWholeRowVar(), mcv_match_expression(), ordered_set_startup(), pg_get_indexdef_worker(), pg_get_partkeydef_worker(), preprocess_minmax_aggregates(), relabel_to_typmod(), RelationBuildPartitionKey(), RelationGetDummyIndexExpressions(), remove_unused_subquery_outputs(), replace_nestloop_param_placeholdervar(), replace_outer_placeholdervar(), scalararraysel(), set_dummy_tlist_references(), set_joinrel_partition_key_exprs(), tlist_same_collations(), transformCaseExpr(), transformFromClauseItem(), transformMultiAssignRef(), transformPLAssignStmt(), transformSubLink(), and transformWindowDefinitions().

◆ expression_returns_set()

◆ expression_tree_mutator_impl()

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

Definition at line 2824 of file nodeFuncs.c.

2827 {
2828  /*
2829  * The mutator has already decided not to modify the current node, but we
2830  * must call the mutator for any sub-nodes.
2831  */
2832 
2833 #define FLATCOPY(newnode, node, nodetype) \
2834  ( (newnode) = (nodetype *) palloc(sizeof(nodetype)), \
2835  memcpy((newnode), (node), sizeof(nodetype)) )
2836 
2837 #define MUTATE(newfield, oldfield, fieldtype) \
2838  ( (newfield) = (fieldtype) mutator((Node *) (oldfield), context) )
2839 
2840  if (node == NULL)
2841  return NULL;
2842 
2843  /* Guard against stack overflow due to overly complex expressions */
2845 
2846  switch (nodeTag(node))
2847  {
2848  /*
2849  * Primitive node types with no expression subnodes. Var and
2850  * Const are frequent enough to deserve special cases, the others
2851  * we just use copyObject for.
2852  */
2853  case T_Var:
2854  {
2855  Var *var = (Var *) node;
2856  Var *newnode;
2857 
2858  FLATCOPY(newnode, var, Var);
2859  /* Assume we need not copy the varnullingrels bitmapset */
2860  return (Node *) newnode;
2861  }
2862  break;
2863  case T_Const:
2864  {
2865  Const *oldnode = (Const *) node;
2866  Const *newnode;
2867 
2868  FLATCOPY(newnode, oldnode, Const);
2869  /* XXX we don't bother with datumCopy; should we? */
2870  return (Node *) newnode;
2871  }
2872  break;
2873  case T_Param:
2874  case T_CaseTestExpr:
2875  case T_SQLValueFunction:
2876  case T_JsonFormat:
2877  case T_CoerceToDomainValue:
2878  case T_SetToDefault:
2879  case T_CurrentOfExpr:
2880  case T_NextValueExpr:
2881  case T_RangeTblRef:
2882  case T_SortGroupClause:
2883  case T_CTESearchClause:
2884  case T_MergeSupportFunc:
2885  return (Node *) copyObject(node);
2886  case T_WithCheckOption:
2887  {
2888  WithCheckOption *wco = (WithCheckOption *) node;
2889  WithCheckOption *newnode;
2890 
2891  FLATCOPY(newnode, wco, WithCheckOption);
2892  MUTATE(newnode->qual, wco->qual, Node *);
2893  return (Node *) newnode;
2894  }
2895  case T_Aggref:
2896  {
2897  Aggref *aggref = (Aggref *) node;
2898  Aggref *newnode;
2899 
2900  FLATCOPY(newnode, aggref, Aggref);
2901  /* assume mutation doesn't change types of arguments */
2902  newnode->aggargtypes = list_copy(aggref->aggargtypes);
2903  MUTATE(newnode->aggdirectargs, aggref->aggdirectargs, List *);
2904  MUTATE(newnode->args, aggref->args, List *);
2905  MUTATE(newnode->aggorder, aggref->aggorder, List *);
2906  MUTATE(newnode->aggdistinct, aggref->aggdistinct, List *);
2907  MUTATE(newnode->aggfilter, aggref->aggfilter, Expr *);
2908  return (Node *) newnode;
2909  }
2910  break;
2911  case T_GroupingFunc:
2912  {
2913  GroupingFunc *grouping = (GroupingFunc *) node;
2914  GroupingFunc *newnode;
2915 
2916  FLATCOPY(newnode, grouping, GroupingFunc);
2917  MUTATE(newnode->args, grouping->args, List *);
2918 
2919  /*
2920  * We assume here that mutating the arguments does not change
2921  * the semantics, i.e. that the arguments are not mutated in a
2922  * way that makes them semantically different from their
2923  * previously matching expressions in the GROUP BY clause.
2924  *
2925  * If a mutator somehow wanted to do this, it would have to
2926  * handle the refs and cols lists itself as appropriate.
2927  */
2928  newnode->refs = list_copy(grouping->refs);
2929  newnode->cols = list_copy(grouping->cols);
2930 
2931  return (Node *) newnode;
2932  }
2933  break;
2934  case T_WindowFunc:
2935  {
2936  WindowFunc *wfunc = (WindowFunc *) node;
2937  WindowFunc *newnode;
2938 
2939  FLATCOPY(newnode, wfunc, WindowFunc);
2940  MUTATE(newnode->args, wfunc->args, List *);
2941  MUTATE(newnode->aggfilter, wfunc->aggfilter, Expr *);
2942  return (Node *) newnode;
2943  }
2944  break;
2945  case T_SubscriptingRef:
2946  {
2947  SubscriptingRef *sbsref = (SubscriptingRef *) node;
2948  SubscriptingRef *newnode;
2949 
2950  FLATCOPY(newnode, sbsref, SubscriptingRef);
2951  MUTATE(newnode->refupperindexpr, sbsref->refupperindexpr,
2952  List *);
2953  MUTATE(newnode->reflowerindexpr, sbsref->reflowerindexpr,
2954  List *);
2955  MUTATE(newnode->refexpr, sbsref->refexpr,
2956  Expr *);
2957  MUTATE(newnode->refassgnexpr, sbsref->refassgnexpr,
2958  Expr *);
2959 
2960  return (Node *) newnode;
2961  }
2962  break;
2963  case T_FuncExpr:
2964  {
2965  FuncExpr *expr = (FuncExpr *) node;
2966  FuncExpr *newnode;
2967 
2968  FLATCOPY(newnode, expr, FuncExpr);
2969  MUTATE(newnode->args, expr->args, List *);
2970  return (Node *) newnode;
2971  }
2972  break;
2973  case T_NamedArgExpr:
2974  {
2975  NamedArgExpr *nexpr = (NamedArgExpr *) node;
2976  NamedArgExpr *newnode;
2977 
2978  FLATCOPY(newnode, nexpr, NamedArgExpr);
2979  MUTATE(newnode->arg, nexpr->arg, Expr *);
2980  return (Node *) newnode;
2981  }
2982  break;
2983  case T_OpExpr:
2984  {
2985  OpExpr *expr = (OpExpr *) node;
2986  OpExpr *newnode;
2987 
2988  FLATCOPY(newnode, expr, OpExpr);
2989  MUTATE(newnode->args, expr->args, List *);
2990  return (Node *) newnode;
2991  }
2992  break;
2993  case T_DistinctExpr:
2994  {
2995  DistinctExpr *expr = (DistinctExpr *) node;
2996  DistinctExpr *newnode;
2997 
2998  FLATCOPY(newnode, expr, DistinctExpr);
2999  MUTATE(newnode->args, expr->args, List *);
3000  return (Node *) newnode;
3001  }
3002  break;
3003  case T_NullIfExpr:
3004  {
3005  NullIfExpr *expr = (NullIfExpr *) node;
3006  NullIfExpr *newnode;
3007 
3008  FLATCOPY(newnode, expr, NullIfExpr);
3009  MUTATE(newnode->args, expr->args, List *);
3010  return (Node *) newnode;
3011  }
3012  break;
3013  case T_ScalarArrayOpExpr:
3014  {
3015  ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
3016  ScalarArrayOpExpr *newnode;
3017 
3018  FLATCOPY(newnode, expr, ScalarArrayOpExpr);
3019  MUTATE(newnode->args, expr->args, List *);
3020  return (Node *) newnode;
3021  }
3022  break;
3023  case T_BoolExpr:
3024  {
3025  BoolExpr *expr = (BoolExpr *) node;
3026  BoolExpr *newnode;
3027 
3028  FLATCOPY(newnode, expr, BoolExpr);
3029  MUTATE(newnode->args, expr->args, List *);
3030  return (Node *) newnode;
3031  }
3032  break;
3033  case T_SubLink:
3034  {
3035  SubLink *sublink = (SubLink *) node;
3036  SubLink *newnode;
3037 
3038  FLATCOPY(newnode, sublink, SubLink);
3039  MUTATE(newnode->testexpr, sublink->testexpr, Node *);
3040 
3041  /*
3042  * Also invoke the mutator on the sublink's Query node, so it
3043  * can recurse into the sub-query if it wants to.
3044  */
3045  MUTATE(newnode->subselect, sublink->subselect, Node *);
3046  return (Node *) newnode;
3047  }
3048  break;
3049  case T_SubPlan:
3050  {
3051  SubPlan *subplan = (SubPlan *) node;
3052  SubPlan *newnode;
3053 
3054  FLATCOPY(newnode, subplan, SubPlan);
3055  /* transform testexpr */
3056  MUTATE(newnode->testexpr, subplan->testexpr, Node *);
3057  /* transform args list (params to be passed to subplan) */
3058  MUTATE(newnode->args, subplan->args, List *);
3059  /* but not the sub-Plan itself, which is referenced as-is */
3060  return (Node *) newnode;
3061  }
3062  break;
3063  case T_AlternativeSubPlan:
3064  {
3065  AlternativeSubPlan *asplan = (AlternativeSubPlan *) node;
3066  AlternativeSubPlan *newnode;
3067 
3068  FLATCOPY(newnode, asplan, AlternativeSubPlan);
3069  MUTATE(newnode->subplans, asplan->subplans, List *);
3070  return (Node *) newnode;
3071  }
3072  break;
3073  case T_FieldSelect:
3074  {
3075  FieldSelect *fselect = (FieldSelect *) node;
3076  FieldSelect *newnode;
3077 
3078  FLATCOPY(newnode, fselect, FieldSelect);
3079  MUTATE(newnode->arg, fselect->arg, Expr *);
3080  return (Node *) newnode;
3081  }
3082  break;
3083  case T_FieldStore:
3084  {
3085  FieldStore *fstore = (FieldStore *) node;
3086  FieldStore *newnode;
3087 
3088  FLATCOPY(newnode, fstore, FieldStore);
3089  MUTATE(newnode->arg, fstore->arg, Expr *);
3090  MUTATE(newnode->newvals, fstore->newvals, List *);
3091  newnode->fieldnums = list_copy(fstore->fieldnums);
3092  return (Node *) newnode;
3093  }
3094  break;
3095  case T_RelabelType:
3096  {
3097  RelabelType *relabel = (RelabelType *) node;
3098  RelabelType *newnode;
3099 
3100  FLATCOPY(newnode, relabel, RelabelType);
3101  MUTATE(newnode->arg, relabel->arg, Expr *);
3102  return (Node *) newnode;
3103  }
3104  break;
3105  case T_CoerceViaIO:
3106  {
3107  CoerceViaIO *iocoerce = (CoerceViaIO *) node;
3108  CoerceViaIO *newnode;
3109 
3110  FLATCOPY(newnode, iocoerce, CoerceViaIO);
3111  MUTATE(newnode->arg, iocoerce->arg, Expr *);
3112  return (Node *) newnode;
3113  }
3114  break;
3115  case T_ArrayCoerceExpr:
3116  {
3117  ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node;
3118  ArrayCoerceExpr *newnode;
3119 
3120  FLATCOPY(newnode, acoerce, ArrayCoerceExpr);
3121  MUTATE(newnode->arg, acoerce->arg, Expr *);
3122  MUTATE(newnode->elemexpr, acoerce->elemexpr, Expr *);
3123  return (Node *) newnode;
3124  }
3125  break;
3126  case T_ConvertRowtypeExpr:
3127  {
3128  ConvertRowtypeExpr *convexpr = (ConvertRowtypeExpr *) node;
3129  ConvertRowtypeExpr *newnode;
3130 
3131  FLATCOPY(newnode, convexpr, ConvertRowtypeExpr);
3132  MUTATE(newnode->arg, convexpr->arg, Expr *);
3133  return (Node *) newnode;
3134  }
3135  break;
3136  case T_CollateExpr:
3137  {
3138  CollateExpr *collate = (CollateExpr *) node;
3139  CollateExpr *newnode;
3140 
3141  FLATCOPY(newnode, collate, CollateExpr);
3142  MUTATE(newnode->arg, collate->arg, Expr *);
3143  return (Node *) newnode;
3144  }
3145  break;
3146  case T_CaseExpr:
3147  {
3148  CaseExpr *caseexpr = (CaseExpr *) node;
3149  CaseExpr *newnode;
3150 
3151  FLATCOPY(newnode, caseexpr, CaseExpr);
3152  MUTATE(newnode->arg, caseexpr->arg, Expr *);
3153  MUTATE(newnode->args, caseexpr->args, List *);
3154  MUTATE(newnode->defresult, caseexpr->defresult, Expr *);
3155  return (Node *) newnode;
3156  }
3157  break;
3158  case T_CaseWhen:
3159  {
3160  CaseWhen *casewhen = (CaseWhen *) node;
3161  CaseWhen *newnode;
3162 
3163  FLATCOPY(newnode, casewhen, CaseWhen);
3164  MUTATE(newnode->expr, casewhen->expr, Expr *);
3165  MUTATE(newnode->result, casewhen->result, Expr *);
3166  return (Node *) newnode;
3167  }
3168  break;
3169  case T_ArrayExpr:
3170  {
3171  ArrayExpr *arrayexpr = (ArrayExpr *) node;
3172  ArrayExpr *newnode;
3173 
3174  FLATCOPY(newnode, arrayexpr, ArrayExpr);
3175  MUTATE(newnode->elements, arrayexpr->elements, List *);
3176  return (Node *) newnode;
3177  }
3178  break;
3179  case T_RowExpr:
3180  {
3181  RowExpr *rowexpr = (RowExpr *) node;
3182  RowExpr *newnode;
3183 
3184  FLATCOPY(newnode, rowexpr, RowExpr);
3185  MUTATE(newnode->args, rowexpr->args, List *);
3186  /* Assume colnames needn't be duplicated */
3187  return (Node *) newnode;
3188  }
3189  break;
3190  case T_RowCompareExpr:
3191  {
3192  RowCompareExpr *rcexpr = (RowCompareExpr *) node;
3193  RowCompareExpr *newnode;
3194 
3195  FLATCOPY(newnode, rcexpr, RowCompareExpr);
3196  MUTATE(newnode->largs, rcexpr->largs, List *);
3197  MUTATE(newnode->rargs, rcexpr->rargs, List *);
3198  return (Node *) newnode;
3199  }
3200  break;
3201  case T_CoalesceExpr:
3202  {
3203  CoalesceExpr *coalesceexpr = (CoalesceExpr *) node;
3204  CoalesceExpr *newnode;
3205 
3206  FLATCOPY(newnode, coalesceexpr, CoalesceExpr);
3207  MUTATE(newnode->args, coalesceexpr->args, List *);
3208  return (Node *) newnode;
3209  }
3210  break;
3211  case T_MinMaxExpr:
3212  {
3213  MinMaxExpr *minmaxexpr = (MinMaxExpr *) node;
3214  MinMaxExpr *newnode;
3215 
3216  FLATCOPY(newnode, minmaxexpr, MinMaxExpr);
3217  MUTATE(newnode->args, minmaxexpr->args, List *);
3218  return (Node *) newnode;
3219  }
3220  break;
3221  case T_XmlExpr:
3222  {
3223  XmlExpr *xexpr = (XmlExpr *) node;
3224  XmlExpr *newnode;
3225 
3226  FLATCOPY(newnode, xexpr, XmlExpr);
3227  MUTATE(newnode->named_args, xexpr->named_args, List *);
3228  /* assume mutator does not care about arg_names */
3229  MUTATE(newnode->args, xexpr->args, List *);
3230  return (Node *) newnode;
3231  }
3232  break;
3233  case T_JsonReturning:
3234  {
3235  JsonReturning *jr = (JsonReturning *) node;
3236  JsonReturning *newnode;
3237 
3238  FLATCOPY(newnode, jr, JsonReturning);
3239  MUTATE(newnode->format, jr->format, JsonFormat *);
3240 
3241  return (Node *) newnode;
3242  }
3243  case T_JsonValueExpr:
3244  {
3245  JsonValueExpr *jve = (JsonValueExpr *) node;
3246  JsonValueExpr *newnode;
3247 
3248  FLATCOPY(newnode, jve, JsonValueExpr);
3249  MUTATE(newnode->raw_expr, jve->raw_expr, Expr *);
3250  MUTATE(newnode->formatted_expr, jve->formatted_expr, Expr *);
3251  MUTATE(newnode->format, jve->format, JsonFormat *);
3252 
3253  return (Node *) newnode;
3254  }
3255  case T_JsonConstructorExpr:
3256  {
3257  JsonConstructorExpr *jce = (JsonConstructorExpr *) node;
3258  JsonConstructorExpr *newnode;
3259 
3260  FLATCOPY(newnode, jce, JsonConstructorExpr);
3261  MUTATE(newnode->args, jce->args, List *);
3262  MUTATE(newnode->func, jce->func, Expr *);
3263  MUTATE(newnode->coercion, jce->coercion, Expr *);
3264  MUTATE(newnode->returning, jce->returning, JsonReturning *);
3265 
3266  return (Node *) newnode;
3267  }
3268  case T_JsonIsPredicate:
3269  {
3270  JsonIsPredicate *pred = (JsonIsPredicate *) node;
3271  JsonIsPredicate *newnode;
3272 
3273  FLATCOPY(newnode, pred, JsonIsPredicate);
3274  MUTATE(newnode->expr, pred->expr, Node *);
3275  MUTATE(newnode->format, pred->format, JsonFormat *);
3276 
3277  return (Node *) newnode;
3278  }
3279  case T_NullTest:
3280  {
3281  NullTest *ntest = (NullTest *) node;
3282  NullTest *newnode;
3283 
3284  FLATCOPY(newnode, ntest, NullTest);
3285  MUTATE(newnode->arg, ntest->arg, Expr *);
3286  return (Node *) newnode;
3287  }
3288  break;
3289  case T_BooleanTest:
3290  {
3291  BooleanTest *btest = (BooleanTest *) node;
3292  BooleanTest *newnode;
3293 
3294  FLATCOPY(newnode, btest, BooleanTest);
3295  MUTATE(newnode->arg, btest->arg, Expr *);
3296  return (Node *) newnode;
3297  }
3298  break;
3299  case T_CoerceToDomain:
3300  {
3301  CoerceToDomain *ctest = (CoerceToDomain *) node;
3302  CoerceToDomain *newnode;
3303 
3304  FLATCOPY(newnode, ctest, CoerceToDomain);
3305  MUTATE(newnode->arg, ctest->arg, Expr *);
3306  return (Node *) newnode;
3307  }
3308  break;
3309  case T_TargetEntry:
3310  {
3311  TargetEntry *targetentry = (TargetEntry *) node;
3312  TargetEntry *newnode;
3313 
3314  FLATCOPY(newnode, targetentry, TargetEntry);
3315  MUTATE(newnode->expr, targetentry->expr, Expr *);
3316  return (Node *) newnode;
3317  }
3318  break;
3319  case T_Query:
3320  /* Do nothing with a sub-Query, per discussion above */
3321  return node;
3322  case T_WindowClause:
3323  {
3324  WindowClause *wc = (WindowClause *) node;
3325  WindowClause *newnode;
3326 
3327  FLATCOPY(newnode, wc, WindowClause);
3328  MUTATE(newnode->partitionClause, wc->partitionClause, List *);
3329  MUTATE(newnode->orderClause, wc->orderClause, List *);
3330  MUTATE(newnode->startOffset, wc->startOffset, Node *);
3331  MUTATE(newnode->endOffset, wc->endOffset, Node *);
3332  MUTATE(newnode->runCondition, wc->runCondition, List *);
3333  return (Node *) newnode;
3334  }
3335  break;
3336  case T_CTECycleClause:
3337  {
3338  CTECycleClause *cc = (CTECycleClause *) node;
3339  CTECycleClause *newnode;
3340 
3341  FLATCOPY(newnode, cc, CTECycleClause);
3342  MUTATE(newnode->cycle_mark_value, cc->cycle_mark_value, Node *);
3344  return (Node *) newnode;
3345  }
3346  break;
3347  case T_CommonTableExpr:
3348  {
3349  CommonTableExpr *cte = (CommonTableExpr *) node;
3350  CommonTableExpr *newnode;
3351 
3352  FLATCOPY(newnode, cte, CommonTableExpr);
3353 
3354  /*
3355  * Also invoke the mutator on the CTE's Query node, so it can
3356  * recurse into the sub-query if it wants to.
3357  */
3358  MUTATE(newnode->ctequery, cte->ctequery, Node *);
3359 
3360  MUTATE(newnode->search_clause, cte->search_clause, CTESearchClause *);
3361  MUTATE(newnode->cycle_clause, cte->cycle_clause, CTECycleClause *);
3362 
3363  return (Node *) newnode;
3364  }
3365  break;
3366  case T_PartitionBoundSpec:
3367  {
3368  PartitionBoundSpec *pbs = (PartitionBoundSpec *) node;
3369  PartitionBoundSpec *newnode;
3370 
3371  FLATCOPY(newnode, pbs, PartitionBoundSpec);
3372  MUTATE(newnode->listdatums, pbs->listdatums, List *);
3373  MUTATE(newnode->lowerdatums, pbs->lowerdatums, List *);
3374  MUTATE(newnode->upperdatums, pbs->upperdatums, List *);
3375  return (Node *) newnode;
3376  }
3377  break;
3378  case T_PartitionRangeDatum:
3379  {
3380  PartitionRangeDatum *prd = (PartitionRangeDatum *) node;
3381  PartitionRangeDatum *newnode;
3382 
3383  FLATCOPY(newnode, prd, PartitionRangeDatum);
3384  MUTATE(newnode->value, prd->value, Node *);
3385  return (Node *) newnode;
3386  }
3387  break;
3388  case T_List:
3389  {
3390  /*
3391  * We assume the mutator isn't interested in the list nodes
3392  * per se, so just invoke it on each list element. NOTE: this
3393  * would fail badly on a list with integer elements!
3394  */
3395  List *resultlist;
3396  ListCell *temp;
3397 
3398  resultlist = NIL;
3399  foreach(temp, (List *) node)
3400  {
3401  resultlist = lappend(resultlist,
3402  mutator((Node *) lfirst(temp),
3403  context));
3404  }
3405  return (Node *) resultlist;
3406  }
3407  break;
3408  case T_FromExpr:
3409  {
3410  FromExpr *from = (FromExpr *) node;
3411  FromExpr *newnode;
3412 
3413  FLATCOPY(newnode, from, FromExpr);
3414  MUTATE(newnode->fromlist, from->fromlist, List *);
3415  MUTATE(newnode->quals, from->quals, Node *);
3416  return (Node *) newnode;
3417  }
3418  break;
3419  case T_OnConflictExpr:
3420  {
3421  OnConflictExpr *oc = (OnConflictExpr *) node;
3422  OnConflictExpr *newnode;
3423 
3424  FLATCOPY(newnode, oc, OnConflictExpr);
3425  MUTATE(newnode->arbiterElems, oc->arbiterElems, List *);
3426  MUTATE(newnode->arbiterWhere, oc->arbiterWhere, Node *);
3427  MUTATE(newnode->onConflictSet, oc->onConflictSet, List *);
3428  MUTATE(newnode->onConflictWhere, oc->onConflictWhere, Node *);
3429  MUTATE(newnode->exclRelTlist, oc->exclRelTlist, List *);
3430 
3431  return (Node *) newnode;
3432  }
3433  break;
3434  case T_MergeAction:
3435  {
3436  MergeAction *action = (MergeAction *) node;
3437  MergeAction *newnode;
3438 
3439  FLATCOPY(newnode, action, MergeAction);
3440  MUTATE(newnode->qual, action->qual, Node *);
3441  MUTATE(newnode->targetList, action->targetList, List *);
3442 
3443  return (Node *) newnode;
3444  }
3445  break;
3446  case T_PartitionPruneStepOp:
3447  {
3448  PartitionPruneStepOp *opstep = (PartitionPruneStepOp *) node;
3449  PartitionPruneStepOp *newnode;
3450 
3451  FLATCOPY(newnode, opstep, PartitionPruneStepOp);
3452  MUTATE(newnode->exprs, opstep->exprs, List *);
3453 
3454  return (Node *) newnode;
3455  }
3456  break;
3457  case T_PartitionPruneStepCombine:
3458  /* no expression sub-nodes */
3459  return (Node *) copyObject(node);
3460  case T_JoinExpr:
3461  {
3462  JoinExpr *join = (JoinExpr *) node;
3463  JoinExpr *newnode;
3464 
3465  FLATCOPY(newnode, join, JoinExpr);
3466  MUTATE(newnode->larg, join->larg, Node *);
3467  MUTATE(newnode->rarg, join->rarg, Node *);
3468  MUTATE(newnode->quals, join->quals, Node *);
3469  /* We do not mutate alias or using by default */
3470  return (Node *) newnode;
3471  }
3472  break;
3473  case T_SetOperationStmt:
3474  {
3475  SetOperationStmt *setop = (SetOperationStmt *) node;
3476  SetOperationStmt *newnode;
3477 
3478  FLATCOPY(newnode, setop, SetOperationStmt);
3479  MUTATE(newnode->larg, setop->larg, Node *);
3480  MUTATE(newnode->rarg, setop->rarg, Node *);
3481  /* We do not mutate groupClauses by default */
3482  return (Node *) newnode;
3483  }
3484  break;
3485  case T_IndexClause:
3486  {
3487  IndexClause *iclause = (IndexClause *) node;
3488  IndexClause *newnode;
3489 
3490  FLATCOPY(newnode, iclause, IndexClause);
3491  MUTATE(newnode->rinfo, iclause->rinfo, RestrictInfo *);
3492  MUTATE(newnode->indexquals, iclause->indexquals, List *);
3493  return (Node *) newnode;
3494  }
3495  break;
3496  case T_PlaceHolderVar:
3497  {
3498  PlaceHolderVar *phv = (PlaceHolderVar *) node;
3499  PlaceHolderVar *newnode;
3500 
3501  FLATCOPY(newnode, phv, PlaceHolderVar);
3502  MUTATE(newnode->phexpr, phv->phexpr, Expr *);
3503  /* Assume we need not copy the relids bitmapsets */
3504  return (Node *) newnode;
3505  }
3506  break;
3507  case T_InferenceElem:
3508  {
3509  InferenceElem *inferenceelemdexpr = (InferenceElem *) node;
3510  InferenceElem *newnode;
3511 
3512  FLATCOPY(newnode, inferenceelemdexpr, InferenceElem);
3513  MUTATE(newnode->expr, newnode->expr, Node *);
3514  return (Node *) newnode;
3515  }
3516  break;
3517  case T_AppendRelInfo:
3518  {
3519  AppendRelInfo *appinfo = (AppendRelInfo *) node;
3520  AppendRelInfo *newnode;
3521 
3522  FLATCOPY(newnode, appinfo, AppendRelInfo);
3523  MUTATE(newnode->translated_vars, appinfo->translated_vars, List *);
3524  /* Assume nothing need be done with parent_colnos[] */
3525  return (Node *) newnode;
3526  }
3527  break;
3528  case T_PlaceHolderInfo:
3529  {
3530  PlaceHolderInfo *phinfo = (PlaceHolderInfo *) node;
3531  PlaceHolderInfo *newnode;
3532 
3533  FLATCOPY(newnode, phinfo, PlaceHolderInfo);
3534  MUTATE(newnode->ph_var, phinfo->ph_var, PlaceHolderVar *);
3535  /* Assume we need not copy the relids bitmapsets */
3536  return (Node *) newnode;
3537  }
3538  break;
3539  case T_RangeTblFunction:
3540  {
3541  RangeTblFunction *rtfunc = (RangeTblFunction *) node;
3542  RangeTblFunction *newnode;
3543 
3544  FLATCOPY(newnode, rtfunc, RangeTblFunction);
3545  MUTATE(newnode->funcexpr, rtfunc->funcexpr, Node *);
3546  /* Assume we need not copy the coldef info lists */
3547  return (Node *) newnode;
3548  }
3549  break;
3550  case T_TableSampleClause:
3551  {
3552  TableSampleClause *tsc = (TableSampleClause *) node;
3553  TableSampleClause *newnode;
3554 
3555  FLATCOPY(newnode, tsc, TableSampleClause);
3556  MUTATE(newnode->args, tsc->args, List *);
3557  MUTATE(newnode->repeatable, tsc->repeatable, Expr *);
3558  return (Node *) newnode;
3559  }
3560  break;
3561  case T_TableFunc:
3562  {
3563  TableFunc *tf = (TableFunc *) node;
3564  TableFunc *newnode;
3565 
3566  FLATCOPY(newnode, tf, TableFunc);
3567  MUTATE(newnode->ns_uris, tf->ns_uris, List *);
3568  MUTATE(newnode->docexpr, tf->docexpr, Node *);
3569  MUTATE(newnode->rowexpr, tf->rowexpr, Node *);
3570  MUTATE(newnode->colexprs, tf->colexprs, List *);
3571  MUTATE(newnode->coldefexprs, tf->coldefexprs, List *);
3572  return (Node *) newnode;
3573  }
3574  break;
3575  default:
3576  elog(ERROR, "unrecognized node type: %d",
3577  (int) nodeTag(node));
3578  break;
3579  }
3580  /* can't get here, but keep compiler happy */
3581  return NULL;
3582 }
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: postgres.c:3531
List * aggdistinct
Definition: primnodes.h:460
List * aggdirectargs
Definition: primnodes.h:451
List * args
Definition: primnodes.h:454
Expr * aggfilter
Definition: primnodes.h:463
List * aggorder
Definition: primnodes.h:457
List * translated_vars
Definition: pathnodes.h:2971
List * elements
Definition: primnodes.h:1336
List * args
Definition: primnodes.h:896
Expr * arg
Definition: primnodes.h:1745
Node * cycle_mark_default
Definition: parsenodes.h:1618
Node * cycle_mark_value
Definition: parsenodes.h:1617
Expr * arg
Definition: primnodes.h:1269
Expr * defresult
Definition: primnodes.h:1271
List * args
Definition: primnodes.h:1270
Expr * result
Definition: primnodes.h:1282
Expr * expr
Definition: primnodes.h:1281
List * args
Definition: primnodes.h:1448
Expr * arg
Definition: primnodes.h:1235
Expr * arg
Definition: primnodes.h:1084
List * newvals
Definition: primnodes.h:1116
Expr * arg
Definition: primnodes.h:1115
Node * quals
Definition: primnodes.h:2062
List * fromlist
Definition: primnodes.h:2061
List * args
Definition: primnodes.h:724
List * indexquals
Definition: pathnodes.h:1739
struct RestrictInfo * rinfo
Definition: pathnodes.h:1738
Node * quals
Definition: primnodes.h:2042
Node * larg
Definition: primnodes.h:2035
Node * rarg
Definition: primnodes.h:2036
JsonReturning * returning
Definition: primnodes.h:1662
JsonFormat * format
Definition: primnodes.h:1688
JsonFormat * format
Definition: primnodes.h:1619
Expr * formatted_expr
Definition: primnodes.h:1636
JsonFormat * format
Definition: primnodes.h:1637
Expr * raw_expr
Definition: primnodes.h:1635
Definition: pg_list.h:54
Node * qual
Definition: primnodes.h:1763
List * targetList
Definition: primnodes.h:1764
List * args
Definition: primnodes.h:1474
Expr * arg
Definition: primnodes.h:747
Expr * arg
Definition: primnodes.h:1721
List * arbiterElems
Definition: primnodes.h:2080
List * onConflictSet
Definition: primnodes.h:2086
List * exclRelTlist
Definition: primnodes.h:2089
Node * onConflictWhere
Definition: primnodes.h:2087
Node * arbiterWhere
Definition: primnodes.h:2082
List * args
Definition: primnodes.h:792
PlaceHolderVar * ph_var
Definition: pathnodes.h:3059
List * args
Definition: primnodes.h:1367
List * args
Definition: primnodes.h:1047
Node * testexpr
Definition: primnodes.h:1023
Expr * refassgnexpr
Definition: primnodes.h:659
List * refupperindexpr
Definition: primnodes.h:649
Expr * refexpr
Definition: primnodes.h:657
List * reflowerindexpr
Definition: primnodes.h:655
Node * docexpr
Definition: primnodes.h:111
Node * rowexpr
Definition: primnodes.h:113
List * colexprs
Definition: primnodes.h:123
Expr * expr
Definition: primnodes.h:1943
Node * startOffset
Definition: parsenodes.h:1505
List * partitionClause
Definition: parsenodes.h:1501
Node * endOffset
Definition: parsenodes.h:1506
List * orderClause
Definition: parsenodes.h:1503
List * args
Definition: primnodes.h:561
Expr * aggfilter
Definition: primnodes.h:563
List * args
Definition: primnodes.h:1564
List * named_args
Definition: primnodes.h:1560

References generate_unaccent_rules::action, Aggref::aggdirectargs, Aggref::aggdistinct, Aggref::aggfilter, WindowFunc::aggfilter, Aggref::aggorder, OnConflictExpr::arbiterElems, OnConflictExpr::arbiterWhere, NamedArgExpr::arg, FieldSelect::arg, FieldStore::arg, RelabelType::arg, CoerceViaIO::arg, ArrayCoerceExpr::arg, ConvertRowtypeExpr::arg, CollateExpr::arg, CaseExpr::arg, NullTest::arg, BooleanTest::arg, CoerceToDomain::arg, TableSampleClause::args, Aggref::args, WindowFunc::args, FuncExpr::args, OpExpr::args, ScalarArrayOpExpr::args, BoolExpr::args, SubPlan::args, CaseExpr::args, RowExpr::args, CoalesceExpr::args, MinMaxExpr::args, XmlExpr::args, JsonConstructorExpr::args, check_stack_depth(), JsonConstructorExpr::coercion, TableFunc::colexprs, copyObject, CommonTableExpr::ctequery, CTECycleClause::cycle_mark_default, CTECycleClause::cycle_mark_value, CaseExpr::defresult, TableFunc::docexpr, ArrayExpr::elements, ArrayCoerceExpr::elemexpr, elog, WindowClause::endOffset, ERROR, OnConflictExpr::exclRelTlist, CaseWhen::expr, JsonIsPredicate::expr, InferenceElem::expr, TargetEntry::expr, PartitionPruneStepOp::exprs, FLATCOPY, JsonReturning::format, JsonValueExpr::format, JsonIsPredicate::format, JsonValueExpr::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, OnConflictExpr::onConflictSet, OnConflictExpr::onConflictWhere, WindowClause::orderClause, WindowClause::partitionClause, 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, 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 2011 of file nodeFuncs.c.

2014 {
2015  ListCell *temp;
2016 
2017  /*
2018  * The walker has already visited the current node, and so we need only
2019  * recurse into any sub-nodes it has.
2020  *
2021  * We assume that the walker is not interested in List nodes per se, so
2022  * when we expect a List we just recurse directly to self without
2023  * bothering to call the walker.
2024  */
2025 #define WALK(n) walker((Node *) (n), context)
2026 
2027 #define LIST_WALK(l) expression_tree_walker_impl((Node *) (l), walker, context)
2028 
2029  if (node == NULL)
2030  return false;
2031 
2032  /* Guard against stack overflow due to overly complex expressions */
2034 
2035  switch (nodeTag(node))
2036  {
2037  case T_Var:
2038  case T_Const:
2039  case T_Param:
2040  case T_CaseTestExpr:
2041  case T_SQLValueFunction:
2042  case T_CoerceToDomainValue:
2043  case T_SetToDefault:
2044  case T_CurrentOfExpr:
2045  case T_NextValueExpr:
2046  case T_RangeTblRef:
2047  case T_SortGroupClause:
2048  case T_CTESearchClause:
2049  case T_MergeSupportFunc:
2050  /* primitive node types with no expression subnodes */
2051  break;
2052  case T_WithCheckOption:
2053  return WALK(((WithCheckOption *) node)->qual);
2054  case T_Aggref:
2055  {
2056  Aggref *expr = (Aggref *) node;
2057 
2058  /* recurse directly on Lists */
2059  if (LIST_WALK(expr->aggdirectargs))
2060  return true;
2061  if (LIST_WALK(expr->args))
2062  return true;
2063  if (LIST_WALK(expr->aggorder))
2064  return true;
2065  if (LIST_WALK(expr->aggdistinct))
2066  return true;
2067  if (WALK(expr->aggfilter))
2068  return true;
2069  }
2070  break;
2071  case T_GroupingFunc:
2072  {
2073  GroupingFunc *grouping = (GroupingFunc *) node;
2074 
2075  if (LIST_WALK(grouping->args))
2076  return true;
2077  }
2078  break;
2079  case T_WindowFunc:
2080  {
2081  WindowFunc *expr = (WindowFunc *) node;
2082 
2083  /* recurse directly on List */
2084  if (LIST_WALK(expr->args))
2085  return true;
2086  if (WALK(expr->aggfilter))
2087  return true;
2088  }
2089  break;
2090  case T_SubscriptingRef:
2091  {
2092  SubscriptingRef *sbsref = (SubscriptingRef *) node;
2093 
2094  /* recurse directly for upper/lower container index lists */
2095  if (LIST_WALK(sbsref->refupperindexpr))
2096  return true;
2097  if (LIST_WALK(sbsref->reflowerindexpr))
2098  return true;
2099  /* walker must see the refexpr and refassgnexpr, however */
2100  if (WALK(sbsref->refexpr))
2101  return true;
2102 
2103  if (WALK(sbsref->refassgnexpr))
2104  return true;
2105  }
2106  break;
2107  case T_FuncExpr:
2108  {
2109  FuncExpr *expr = (FuncExpr *) node;
2110 
2111  if (LIST_WALK(expr->args))
2112  return true;
2113  }
2114  break;
2115  case T_NamedArgExpr:
2116  return WALK(((NamedArgExpr *) node)->arg);
2117  case T_OpExpr:
2118  case T_DistinctExpr: /* struct-equivalent to OpExpr */
2119  case T_NullIfExpr: /* struct-equivalent to OpExpr */
2120  {
2121  OpExpr *expr = (OpExpr *) node;
2122 
2123  if (LIST_WALK(expr->args))
2124  return true;
2125  }
2126  break;
2127  case T_ScalarArrayOpExpr:
2128  {
2129  ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
2130 
2131  if (LIST_WALK(expr->args))
2132  return true;
2133  }
2134  break;
2135  case T_BoolExpr:
2136  {
2137  BoolExpr *expr = (BoolExpr *) node;
2138 
2139  if (LIST_WALK(expr->args))
2140  return true;
2141  }
2142  break;
2143  case T_SubLink:
2144  {
2145  SubLink *sublink = (SubLink *) node;
2146 
2147  if (WALK(sublink->testexpr))
2148  return true;
2149 
2150  /*
2151  * Also invoke the walker on the sublink's Query node, so it
2152  * can recurse into the sub-query if it wants to.
2153  */
2154  return WALK(sublink->subselect);
2155  }
2156  break;
2157  case T_SubPlan:
2158  {
2159  SubPlan *subplan = (SubPlan *) node;
2160 
2161  /* recurse into the testexpr, but not into the Plan */
2162  if (WALK(subplan->testexpr))
2163  return true;
2164  /* also examine args list */
2165  if (LIST_WALK(subplan->args))
2166  return true;
2167  }
2168  break;
2169  case T_AlternativeSubPlan:
2170  return LIST_WALK(((AlternativeSubPlan *) node)->subplans);
2171  case T_FieldSelect:
2172  return WALK(((FieldSelect *) node)->arg);
2173  case T_FieldStore:
2174  {
2175  FieldStore *fstore = (FieldStore *) node;
2176 
2177  if (WALK(fstore->arg))
2178  return true;
2179  if (WALK(fstore->newvals))
2180  return true;
2181  }
2182  break;
2183  case T_RelabelType:
2184  return WALK(((RelabelType *) node)->arg);
2185  case T_CoerceViaIO:
2186  return WALK(((CoerceViaIO *) node)->arg);
2187  case T_ArrayCoerceExpr:
2188  {
2189  ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node;
2190 
2191  if (WALK(acoerce->arg))
2192  return true;
2193  if (WALK(acoerce->elemexpr))
2194  return true;
2195  }
2196  break;
2197  case T_ConvertRowtypeExpr:
2198  return WALK(((ConvertRowtypeExpr *) node)->arg);
2199  case T_CollateExpr:
2200  return WALK(((CollateExpr *) node)->arg);
2201  case T_CaseExpr:
2202  {
2203  CaseExpr *caseexpr = (CaseExpr *) node;
2204 
2205  if (WALK(caseexpr->arg))
2206  return true;
2207  /* we assume walker doesn't care about CaseWhens, either */
2208  foreach(temp, caseexpr->args)
2209  {
2210  CaseWhen *when = lfirst_node(CaseWhen, temp);
2211 
2212  if (WALK(when->expr))
2213  return true;
2214  if (WALK(when->result))
2215  return true;
2216  }
2217  if (WALK(caseexpr->defresult))
2218  return true;
2219  }
2220  break;
2221  case T_ArrayExpr:
2222  return WALK(((ArrayExpr *) node)->elements);
2223  case T_RowExpr:
2224  /* Assume colnames isn't interesting */
2225  return WALK(((RowExpr *) node)->args);
2226  case T_RowCompareExpr:
2227  {
2228  RowCompareExpr *rcexpr = (RowCompareExpr *) node;
2229 
2230  if (WALK(rcexpr->largs))
2231  return true;
2232  if (WALK(rcexpr->rargs))
2233  return true;
2234  }
2235  break;
2236  case T_CoalesceExpr:
2237  return WALK(((CoalesceExpr *) node)->args);
2238  case T_MinMaxExpr:
2239  return WALK(((MinMaxExpr *) node)->args);
2240  case T_XmlExpr:
2241  {
2242  XmlExpr *xexpr = (XmlExpr *) node;
2243 
2244  if (WALK(xexpr->named_args))
2245  return true;
2246  /* we assume walker doesn't care about arg_names */
2247  if (WALK(xexpr->args))
2248  return true;
2249  }
2250  break;
2251  case T_JsonValueExpr:
2252  {
2253  JsonValueExpr *jve = (JsonValueExpr *) node;
2254 
2255  if (WALK(jve->raw_expr))
2256  return true;
2257  if (WALK(jve->formatted_expr))
2258  return true;
2259  }
2260  break;
2261  case T_JsonConstructorExpr:
2262  {
2263  JsonConstructorExpr *ctor = (JsonConstructorExpr *) node;
2264 
2265  if (WALK(ctor->args))
2266  return true;
2267  if (WALK(ctor->func))
2268  return true;
2269  if (WALK(ctor->coercion))
2270  return true;
2271  }
2272  break;
2273  case T_JsonIsPredicate:
2274  return WALK(((JsonIsPredicate *) node)->expr);
2275  case T_NullTest:
2276  return WALK(((NullTest *) node)->arg);
2277  case T_BooleanTest:
2278  return WALK(((BooleanTest *) node)->arg);
2279  case T_CoerceToDomain:
2280  return WALK(((CoerceToDomain *) node)->arg);
2281  case T_TargetEntry:
2282  return WALK(((TargetEntry *) node)->expr);
2283  case T_Query:
2284  /* Do nothing with a sub-Query, per discussion above */
2285  break;
2286  case T_WindowClause:
2287  {
2288  WindowClause *wc = (WindowClause *) node;
2289 
2290  if (WALK(wc->partitionClause))
2291  return true;
2292  if (WALK(wc->orderClause))
2293  return true;
2294  if (WALK(wc->startOffset))
2295  return true;
2296  if (WALK(wc->endOffset))
2297  return true;
2298  if (WALK(wc->runCondition))
2299  return true;
2300  }
2301  break;
2302  case T_CTECycleClause:
2303  {
2304  CTECycleClause *cc = (CTECycleClause *) node;
2305 
2306  if (WALK(cc->cycle_mark_value))
2307  return true;
2308  if (WALK(cc->cycle_mark_default))
2309  return true;
2310  }
2311  break;
2312  case T_CommonTableExpr:
2313  {
2314  CommonTableExpr *cte = (CommonTableExpr *) node;
2315 
2316  /*
2317  * Invoke the walker on the CTE's Query node, so it can
2318  * recurse into the sub-query if it wants to.
2319  */
2320  if (WALK(cte->ctequery))
2321  return true;
2322 
2323  if (WALK(cte->search_clause))
2324  return true;
2325  if (WALK(cte->cycle_clause))
2326  return true;
2327  }
2328  break;
2329  case T_JsonKeyValue:
2330  {
2331  JsonKeyValue *kv = (JsonKeyValue *) node;
2332 
2333  if (WALK(kv->key))
2334  return true;
2335  if (WALK(kv->value))
2336  return true;
2337  }
2338  break;
2339  case T_JsonObjectConstructor:
2340  {
2342 
2343  if (LIST_WALK(ctor->exprs))
2344  return true;
2345  }
2346  break;
2347  case T_JsonArrayConstructor:
2348  {
2349  JsonArrayConstructor *ctor = (JsonArrayConstructor *) node;
2350 
2351  if (LIST_WALK(ctor->exprs))
2352  return true;
2353  }
2354  break;
2355  case T_JsonArrayQueryConstructor:
2356  {
2358 
2359  if (WALK(ctor->query))
2360  return true;
2361  }
2362  break;
2363  case T_JsonAggConstructor:
2364  {
2365  JsonAggConstructor *ctor = (JsonAggConstructor *) node;
2366 
2367  if (WALK(ctor->agg_filter))
2368  return true;
2369  if (WALK(ctor->agg_order))
2370  return true;
2371  if (WALK(ctor->over))
2372  return true;
2373  }
2374  break;
2375  case T_JsonObjectAgg:
2376  {
2377  JsonObjectAgg *ctor = (JsonObjectAgg *) node;
2378 
2379  if (WALK(ctor->constructor))
2380  return true;
2381  if (WALK(ctor->arg))
2382  return true;
2383  }
2384  break;
2385  case T_JsonArrayAgg:
2386  {
2387  JsonArrayAgg *ctor = (JsonArrayAgg *) node;
2388 
2389  if (WALK(ctor->constructor))
2390  return true;
2391  if (WALK(ctor->arg))
2392  return true;
2393  }
2394  break;
2395 
2396  case T_PartitionBoundSpec:
2397  {
2398  PartitionBoundSpec *pbs = (PartitionBoundSpec *) node;
2399 
2400  if (WALK(pbs->listdatums))
2401  return true;
2402  if (WALK(pbs->lowerdatums))
2403  return true;
2404  if (WALK(pbs->upperdatums))
2405  return true;
2406  }
2407  break;
2408  case T_PartitionRangeDatum:
2409  {
2410  PartitionRangeDatum *prd = (PartitionRangeDatum *) node;
2411 
2412  if (WALK(prd->value))
2413  return true;
2414  }
2415  break;
2416  case T_List:
2417  foreach(temp, (List *) node)
2418  {
2419  if (WALK(lfirst(temp)))
2420  return true;
2421  }
2422  break;
2423  case T_FromExpr:
2424  {
2425  FromExpr *from = (FromExpr *) node;
2426 
2427  if (LIST_WALK(from->fromlist))
2428  return true;
2429  if (WALK(from->quals))
2430  return true;
2431  }
2432  break;
2433  case T_OnConflictExpr:
2434  {
2435  OnConflictExpr *onconflict = (OnConflictExpr *) node;
2436 
2437  if (WALK(onconflict->arbiterElems))
2438  return true;
2439  if (WALK(onconflict->arbiterWhere))
2440  return true;
2441  if (WALK(onconflict->onConflictSet))
2442  return true;
2443  if (WALK(onconflict->onConflictWhere))
2444  return true;
2445  if (WALK(onconflict->exclRelTlist))
2446  return true;
2447  }
2448  break;
2449  case T_MergeAction:
2450  {
2451  MergeAction *action = (MergeAction *) node;
2452 
2453  if (WALK(action->qual))
2454  return true;
2455  if (WALK(action->targetList))
2456  return true;
2457  }
2458  break;
2459  case T_PartitionPruneStepOp:
2460  {
2461  PartitionPruneStepOp *opstep = (PartitionPruneStepOp *) node;
2462 
2463  if (WALK(opstep->exprs))
2464  return true;
2465  }
2466  break;
2467  case T_PartitionPruneStepCombine:
2468  /* no expression subnodes */
2469  break;
2470  case T_JoinExpr:
2471  {
2472  JoinExpr *join = (JoinExpr *) node;
2473 
2474  if (WALK(join->larg))
2475  return true;
2476  if (WALK(join->rarg))
2477  return true;
2478  if (WALK(join->quals))
2479  return true;
2480 
2481  /*
2482  * alias clause, using list are deemed uninteresting.
2483  */
2484  }
2485  break;
2486  case T_SetOperationStmt:
2487  {
2488  SetOperationStmt *setop = (SetOperationStmt *) node;
2489 
2490  if (WALK(setop->larg))
2491  return true;
2492  if (WALK(setop->rarg))
2493  return true;
2494 
2495  /* groupClauses are deemed uninteresting */
2496  }
2497  break;
2498  case T_IndexClause:
2499  {
2500  IndexClause *iclause = (IndexClause *) node;
2501 
2502  if (WALK(iclause->rinfo))
2503  return true;
2504  if (LIST_WALK(iclause->indexquals))
2505  return true;
2506  }
2507  break;
2508  case T_PlaceHolderVar:
2509  return WALK(((PlaceHolderVar *) node)->phexpr);
2510  case T_InferenceElem:
2511  return WALK(((InferenceElem *) node)->expr);
2512  case T_AppendRelInfo:
2513  {
2514  AppendRelInfo *appinfo = (AppendRelInfo *) node;
2515 
2516  if (LIST_WALK(appinfo->translated_vars))
2517  return true;
2518  }
2519  break;
2520  case T_PlaceHolderInfo:
2521  return WALK(((PlaceHolderInfo *) node)->ph_var);
2522  case T_RangeTblFunction:
2523  return WALK(((RangeTblFunction *) node)->funcexpr);
2524  case T_TableSampleClause:
2525  {
2526  TableSampleClause *tsc = (TableSampleClause *) node;
2527 
2528  if (LIST_WALK(tsc->args))
2529  return true;
2530  if (WALK(tsc->repeatable))
2531  return true;
2532  }
2533  break;
2534  case T_TableFunc:
2535  {
2536  TableFunc *tf = (TableFunc *) node;
2537 
2538  if (WALK(tf->ns_uris))
2539  return true;
2540  if (WALK(tf->docexpr))
2541  return true;
2542  if (WALK(tf->rowexpr))
2543  return true;
2544  if (WALK(tf->colexprs))
2545  return true;
2546  if (WALK(tf->coldefexprs))
2547  return true;
2548  }
2549  break;
2550  default:
2551  elog(ERROR, "unrecognized node type: %d",
2552  (int) nodeTag(node));
2553  break;
2554  }
2555  return false;
2556 
2557  /* The WALK() macro can be re-used below, but LIST_WALK() not so much */
2558 #undef LIST_WALK
2559 }
#define LIST_WALK(l)
#define WALK(n)
#define lfirst_node(type, lc)
Definition: pg_list.h:176
struct WindowDef * over
Definition: parsenodes.h:1819
JsonValueExpr * arg
Definition: parsenodes.h:1844
JsonAggConstructor * constructor
Definition: parsenodes.h:1843
JsonValueExpr * value
Definition: parsenodes.h:1727
JsonAggConstructor * constructor
Definition: parsenodes.h:1830
JsonKeyValue * arg
Definition: parsenodes.h:1831
Definition: type.h:88

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, 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, JsonObjectConstructor::exprs, JsonArrayConstructor::exprs, PartitionPruneStepOp::exprs, JsonValueExpr::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, OnConflictExpr::onConflictSet, OnConflictExpr::onConflictWhere, WindowClause::orderClause, JsonAggConstructor::over, WindowClause::partitionClause, 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 1023 of file nodeFuncs.c.

1024 {
1025  Oid coll;
1026 
1027  if (!expr)
1028  return InvalidOid;
1029 
1030  switch (nodeTag(expr))
1031  {
1032  case T_Aggref:
1033  coll = ((const Aggref *) expr)->inputcollid;
1034  break;
1035  case T_WindowFunc:
1036  coll = ((const WindowFunc *) expr)->inputcollid;
1037  break;
1038  case T_FuncExpr:
1039  coll = ((const FuncExpr *) expr)->inputcollid;
1040  break;
1041  case T_OpExpr:
1042  coll = ((const OpExpr *) expr)->inputcollid;
1043  break;
1044  case T_DistinctExpr:
1045  coll = ((const DistinctExpr *) expr)->inputcollid;
1046  break;
1047  case T_NullIfExpr:
1048  coll = ((const NullIfExpr *) expr)->inputcollid;
1049  break;
1050  case T_ScalarArrayOpExpr:
1051  coll = ((const ScalarArrayOpExpr *) expr)->inputcollid;
1052  break;
1053  case T_MinMaxExpr:
1054  coll = ((const MinMaxExpr *) expr)->inputcollid;
1055  break;
1056  default:
1057  coll = InvalidOid;
1058  break;
1059  }
1060  return coll;
1061 }

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

525 {
526  if (coercedTypmod != NULL)
527  *coercedTypmod = -1; /* default result on failure */
528 
529  /*
530  * Scalar-type length coercions are FuncExprs, array-type length coercions
531  * are ArrayCoerceExprs
532  */
533  if (expr && IsA(expr, FuncExpr))
534  {
535  const FuncExpr *func = (const FuncExpr *) expr;
536  int nargs;
537  Const *second_arg;
538 
539  /*
540  * If it didn't come from a coercion context, reject.
541  */
542  if (func->funcformat != COERCE_EXPLICIT_CAST &&
543  func->funcformat != COERCE_IMPLICIT_CAST)
544  return false;
545 
546  /*
547  * If it's not a two-argument or three-argument function with the
548  * second argument being an int4 constant, it can't have been created
549  * from a length coercion (it must be a type coercion, instead).
550  */
551  nargs = list_length(func->args);
552  if (nargs < 2 || nargs > 3)
553  return false;
554 
555  second_arg = (Const *) lsecond(func->args);
556  if (!IsA(second_arg, Const) ||
557  second_arg->consttype != INT4OID ||
558  second_arg->constisnull)
559  return false;
560 
561  /*
562  * OK, it is indeed a length-coercion function.
563  */
564  if (coercedTypmod != NULL)
565  *coercedTypmod = DatumGetInt32(second_arg->constvalue);
566 
567  return true;
568  }
569 
570  if (expr && IsA(expr, ArrayCoerceExpr))
571  {
572  const ArrayCoerceExpr *acoerce = (const ArrayCoerceExpr *) expr;
573 
574  /* It's not a length coercion unless there's a nondefault typmod */
575  if (acoerce->resulttypmod < 0)
576  return false;
577 
578  /*
579  * OK, it is indeed a length-coercion expression.
580  */
581  if (coercedTypmod != NULL)
582  *coercedTypmod = acoerce->resulttypmod;
583 
584  return true;
585  }
586 
587  return false;
588 }
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:202
@ COERCE_IMPLICIT_CAST
Definition: primnodes.h:692
@ COERCE_EXPLICIT_CAST
Definition: primnodes.h:691

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

1321 {
1322  int loc;
1323 
1324  if (expr == NULL)
1325  return -1;
1326  switch (nodeTag(expr))
1327  {
1328  case T_RangeVar:
1329  loc = ((const RangeVar *) expr)->location;
1330  break;
1331  case T_TableFunc:
1332  loc = ((const TableFunc *) expr)->location;
1333  break;
1334  case T_Var:
1335  loc = ((const Var *) expr)->location;
1336  break;
1337  case T_Const:
1338  loc = ((const Const *) expr)->location;
1339  break;
1340  case T_Param:
1341  loc = ((const Param *) expr)->location;
1342  break;
1343  case T_Aggref:
1344  /* function name should always be the first thing */
1345  loc = ((const Aggref *) expr)->location;
1346  break;
1347  case T_GroupingFunc:
1348  loc = ((const GroupingFunc *) expr)->location;
1349  break;
1350  case T_WindowFunc:
1351  /* function name should always be the first thing */
1352  loc = ((const WindowFunc *) expr)->location;
1353  break;
1354  case T_MergeSupportFunc:
1355  loc = ((const MergeSupportFunc *) expr)->location;
1356  break;
1357  case T_SubscriptingRef:
1358  /* just use container argument's location */
1359  loc = exprLocation((Node *) ((const SubscriptingRef *) expr)->refexpr);
1360  break;
1361  case T_FuncExpr:
1362  {
1363  const FuncExpr *fexpr = (const FuncExpr *) expr;
1364 
1365  /* consider both function name and leftmost arg */
1366  loc = leftmostLoc(fexpr->location,
1367  exprLocation((Node *) fexpr->args));
1368  }
1369  break;
1370  case T_NamedArgExpr:
1371  {
1372  const NamedArgExpr *na = (const NamedArgExpr *) expr;
1373 
1374  /* consider both argument name and value */
1375  loc = leftmostLoc(na->location,
1376  exprLocation((Node *) na->arg));
1377  }
1378  break;
1379  case T_OpExpr:
1380  case T_DistinctExpr: /* struct-equivalent to OpExpr */
1381  case T_NullIfExpr: /* struct-equivalent to OpExpr */
1382  {
1383  const OpExpr *opexpr = (const OpExpr *) expr;
1384 
1385  /* consider both operator name and leftmost arg */
1386  loc = leftmostLoc(opexpr->location,
1387  exprLocation((Node *) opexpr->args));
1388  }
1389  break;
1390  case T_ScalarArrayOpExpr:
1391  {
1392  const ScalarArrayOpExpr *saopexpr = (const ScalarArrayOpExpr *) expr;
1393 
1394  /* consider both operator name and leftmost arg */
1395  loc = leftmostLoc(saopexpr->location,
1396  exprLocation((Node *) saopexpr->args));
1397  }
1398  break;
1399  case T_BoolExpr:
1400  {
1401  const BoolExpr *bexpr = (const BoolExpr *) expr;
1402 
1403  /*
1404  * Same as above, to handle either NOT or AND/OR. We can't
1405  * special-case NOT because of the way that it's used for
1406  * things like IS NOT BETWEEN.
1407  */
1408  loc = leftmostLoc(bexpr->location,
1409  exprLocation((Node *) bexpr->args));
1410  }
1411  break;
1412  case T_SubLink:
1413  {
1414  const SubLink *sublink = (const SubLink *) expr;
1415 
1416  /* check the testexpr, if any, and the operator/keyword */
1417  loc = leftmostLoc(exprLocation(sublink->testexpr),
1418  sublink->location);
1419  }
1420  break;
1421  case T_FieldSelect:
1422  /* just use argument's location */
1423  loc = exprLocation((Node *) ((const FieldSelect *) expr)->arg);
1424  break;
1425  case T_FieldStore:
1426  /* just use argument's location */
1427  loc = exprLocation((Node *) ((const FieldStore *) expr)->arg);
1428  break;
1429  case T_RelabelType:
1430  {
1431  const RelabelType *rexpr = (const RelabelType *) expr;
1432 
1433  /* Much as above */
1434  loc = leftmostLoc(rexpr->location,
1435  exprLocation((Node *) rexpr->arg));
1436  }
1437  break;
1438  case T_CoerceViaIO:
1439  {
1440  const CoerceViaIO *cexpr = (const CoerceViaIO *) expr;
1441 
1442  /* Much as above */
1443  loc = leftmostLoc(cexpr->location,
1444  exprLocation((Node *) cexpr->arg));
1445  }
1446  break;
1447  case T_ArrayCoerceExpr:
1448  {
1449  const ArrayCoerceExpr *cexpr = (const ArrayCoerceExpr *) expr;
1450 
1451  /* Much as above */
1452  loc = leftmostLoc(cexpr->location,
1453  exprLocation((Node *) cexpr->arg));
1454  }
1455  break;
1456  case T_ConvertRowtypeExpr:
1457  {
1458  const ConvertRowtypeExpr *cexpr = (const ConvertRowtypeExpr *) expr;
1459 
1460  /* Much as above */
1461  loc = leftmostLoc(cexpr->location,
1462  exprLocation((Node *) cexpr->arg));
1463  }
1464  break;
1465  case T_CollateExpr:
1466  /* just use argument's location */
1467  loc = exprLocation((Node *) ((const CollateExpr *) expr)->arg);
1468  break;
1469  case T_CaseExpr:
1470  /* CASE keyword should always be the first thing */
1471  loc = ((const CaseExpr *) expr)->location;
1472  break;
1473  case T_CaseWhen:
1474  /* WHEN keyword should always be the first thing */
1475  loc = ((const CaseWhen *) expr)->location;
1476  break;
1477  case T_ArrayExpr:
1478  /* the location points at ARRAY or [, which must be leftmost */
1479  loc = ((const ArrayExpr *) expr)->location;
1480  break;
1481  case T_RowExpr:
1482  /* the location points at ROW or (, which must be leftmost */
1483  loc = ((const RowExpr *) expr)->location;
1484  break;
1485  case T_RowCompareExpr:
1486  /* just use leftmost argument's location */
1487  loc = exprLocation((Node *) ((const RowCompareExpr *) expr)->largs);
1488  break;
1489  case T_CoalesceExpr:
1490  /* COALESCE keyword should always be the first thing */
1491  loc = ((const CoalesceExpr *) expr)->location;
1492  break;
1493  case T_MinMaxExpr:
1494  /* GREATEST/LEAST keyword should always be the first thing */
1495  loc = ((const MinMaxExpr *) expr)->location;
1496  break;
1497  case T_SQLValueFunction:
1498  /* function keyword should always be the first thing */
1499  loc = ((const SQLValueFunction *) expr)->location;
1500  break;
1501  case T_XmlExpr:
1502  {
1503  const XmlExpr *xexpr = (const XmlExpr *) expr;
1504 
1505  /* consider both function name and leftmost arg */
1506  loc = leftmostLoc(xexpr->location,
1507  exprLocation((Node *) xexpr->args));
1508  }
1509  break;
1510  case T_JsonFormat:
1511  loc = ((const JsonFormat *) expr)->location;
1512  break;
1513  case T_JsonValueExpr:
1514  loc = exprLocation((Node *) ((const JsonValueExpr *) expr)->raw_expr);
1515  break;
1516  case T_JsonConstructorExpr:
1517  loc = ((const JsonConstructorExpr *) expr)->location;
1518  break;
1519  case T_JsonIsPredicate:
1520  loc = ((const JsonIsPredicate *) expr)->location;
1521  break;
1522  case T_NullTest:
1523  {
1524  const NullTest *nexpr = (const NullTest *) expr;
1525 
1526  /* Much as above */
1527  loc = leftmostLoc(nexpr->location,
1528  exprLocation((Node *) nexpr->arg));
1529  }
1530  break;
1531  case T_BooleanTest:
1532  {
1533  const BooleanTest *bexpr = (const BooleanTest *) expr;
1534 
1535  /* Much as above */
1536  loc = leftmostLoc(bexpr->location,
1537  exprLocation((Node *) bexpr->arg));
1538  }
1539  break;
1540  case T_CoerceToDomain:
1541  {
1542  const CoerceToDomain *cexpr = (const CoerceToDomain *) expr;
1543 
1544  /* Much as above */
1545  loc = leftmostLoc(cexpr->location,
1546  exprLocation((Node *) cexpr->arg));
1547  }
1548  break;
1549  case T_CoerceToDomainValue:
1550  loc = ((const CoerceToDomainValue *) expr)->location;
1551  break;
1552  case T_SetToDefault:
1553  loc = ((const SetToDefault *) expr)->location;
1554  break;
1555  case T_TargetEntry:
1556  /* just use argument's location */
1557  loc = exprLocation((Node *) ((const TargetEntry *) expr)->expr);
1558  break;
1559  case T_IntoClause:
1560  /* use the contained RangeVar's location --- close enough */
1561  loc = exprLocation((Node *) ((const IntoClause *) expr)->rel);
1562  break;
1563  case T_List:
1564  {
1565  /* report location of first list member that has a location */
1566  ListCell *lc;
1567 
1568  loc = -1; /* just to suppress compiler warning */
1569  foreach(lc, (const List *) expr)
1570  {
1571  loc = exprLocation((Node *) lfirst(lc));
1572  if (loc >= 0)
1573  break;
1574  }
1575  }
1576  break;
1577  case T_A_Expr:
1578  {
1579  const A_Expr *aexpr = (const A_Expr *) expr;
1580 
1581  /* use leftmost of operator or left operand (if any) */
1582  /* we assume right operand can't be to left of operator */
1583  loc = leftmostLoc(aexpr->location,
1584  exprLocation(aexpr->lexpr));
1585  }
1586  break;
1587  case T_ColumnRef:
1588  loc = ((const ColumnRef *) expr)->location;
1589  break;
1590  case T_ParamRef:
1591  loc = ((const ParamRef *) expr)->location;
1592  break;
1593  case T_A_Const:
1594  loc = ((const A_Const *) expr)->location;
1595  break;
1596  case T_FuncCall:
1597  {
1598  const FuncCall *fc = (const FuncCall *) expr;
1599 
1600  /* consider both function name and leftmost arg */
1601  /* (we assume any ORDER BY nodes must be to right of name) */
1602  loc = leftmostLoc(fc->location,
1603  exprLocation((Node *) fc->args));
1604  }
1605  break;
1606  case T_A_ArrayExpr:
1607  /* the location points at ARRAY or [, which must be leftmost */
1608  loc = ((const A_ArrayExpr *) expr)->location;
1609  break;
1610  case T_ResTarget:
1611  /* we need not examine the contained expression (if any) */
1612  loc = ((const ResTarget *) expr)->location;
1613  break;
1614  case T_MultiAssignRef:
1615  loc = exprLocation(((const MultiAssignRef *) expr)->source);
1616  break;
1617  case T_TypeCast:
1618  {
1619  const TypeCast *tc = (const TypeCast *) expr;
1620 
1621  /*
1622  * This could represent CAST(), ::, or TypeName 'literal', so
1623  * any of the components might be leftmost.
1624  */
1625  loc = exprLocation(tc->arg);
1626  loc = leftmostLoc(loc, tc->typeName->location);
1627  loc = leftmostLoc(loc, tc->location);
1628  }
1629  break;
1630  case T_CollateClause:
1631  /* just use argument's location */
1632  loc = exprLocation(((const CollateClause *) expr)->arg);
1633  break;
1634  case T_SortBy:
1635  /* just use argument's location (ignore operator, if any) */
1636  loc = exprLocation(((const SortBy *) expr)->node);
1637  break;
1638  case T_WindowDef:
1639  loc = ((const WindowDef *) expr)->location;
1640  break;
1641  case T_RangeTableSample:
1642  loc = ((const RangeTableSample *) expr)->location;
1643  break;
1644  case T_TypeName:
1645  loc = ((const TypeName *) expr)->location;
1646  break;
1647  case T_ColumnDef:
1648  loc = ((const ColumnDef *) expr)->location;
1649  break;
1650  case T_Constraint:
1651  loc = ((const Constraint *) expr)->location;
1652  break;
1653  case T_FunctionParameter:
1654  /* just use typename's location */
1655  loc = exprLocation((Node *) ((const FunctionParameter *) expr)->argType);
1656  break;
1657  case T_XmlSerialize:
1658  /* XMLSERIALIZE keyword should always be the first thing */
1659  loc = ((const XmlSerialize *) expr)->location;
1660  break;
1661  case T_GroupingSet:
1662  loc = ((const GroupingSet *) expr)->location;
1663  break;
1664  case T_WithClause:
1665  loc = ((const WithClause *) expr)->location;
1666  break;
1667  case T_InferClause:
1668  loc = ((const InferClause *) expr)->location;
1669  break;
1670  case T_OnConflictClause:
1671  loc = ((const OnConflictClause *) expr)->location;
1672  break;
1673  case T_CTESearchClause:
1674  loc = ((const CTESearchClause *) expr)->location;
1675  break;
1676  case T_CTECycleClause:
1677  loc = ((const CTECycleClause *) expr)->location;
1678  break;
1679  case T_CommonTableExpr:
1680  loc = ((const CommonTableExpr *) expr)->location;
1681  break;
1682  case T_JsonKeyValue:
1683  /* just use the key's location */
1684  loc = exprLocation((Node *) ((const JsonKeyValue *) expr)->key);
1685  break;
1686  case T_JsonObjectConstructor:
1687  loc = ((const JsonObjectConstructor *) expr)->location;
1688  break;
1689  case T_JsonArrayConstructor:
1690  loc = ((const JsonArrayConstructor *) expr)->location;
1691  break;
1692  case T_JsonArrayQueryConstructor:
1693  loc = ((const JsonArrayQueryConstructor *) expr)->location;
1694  break;
1695  case T_JsonAggConstructor:
1696  loc = ((const JsonAggConstructor *) expr)->location;
1697  break;
1698  case T_JsonObjectAgg:
1699  loc = exprLocation((Node *) ((const JsonObjectAgg *) expr)->constructor);
1700  break;
1701  case T_JsonArrayAgg:
1702  loc = exprLocation((Node *) ((const JsonArrayAgg *) expr)->constructor);
1703  break;
1704  case T_PlaceHolderVar:
1705  /* just use argument's location */
1706  loc = exprLocation((Node *) ((const PlaceHolderVar *) expr)->phexpr);
1707  break;
1708  case T_InferenceElem:
1709  /* just use nested expr's location */
1710  loc = exprLocation((Node *) ((const InferenceElem *) expr)->expr);
1711  break;
1712  case T_PartitionElem:
1713  loc = ((const PartitionElem *) expr)->location;
1714  break;
1715  case T_PartitionSpec:
1716  loc = ((const PartitionSpec *) expr)->location;
1717  break;
1718  case T_PartitionBoundSpec:
1719  loc = ((const PartitionBoundSpec *) expr)->location;
1720  break;
1721  case T_PartitionRangeDatum:
1722  loc = ((const PartitionRangeDatum *) expr)->location;
1723  break;
1724  default:
1725  /* for any other node type it's just unknown... */
1726  loc = -1;
1727  break;
1728  }
1729  return loc;
1730 }
static int leftmostLoc(int loc1, int loc2)
Definition: nodeFuncs.c:1738
int exprLocation(const Node *expr)
Definition: nodeFuncs.c:1320
static rewind_source * source
Definition: pg_rewind.c:89
static int fc(const char *x)
Definition: preproc-init.c:99
int location
Definition: parsenodes.h:337
Node * lexpr
Definition: parsenodes.h:335
int location
Definition: primnodes.h:897
int location
Definition: primnodes.h:726
int location
Definition: primnodes.h:1725
int location
Definition: primnodes.h:795
TypeName * typeName
Definition: parsenodes.h:373
int location
Definition: parsenodes.h:374
Node * arg
Definition: parsenodes.h:372
int location
Definition: parsenodes.h:274
int location
Definition: primnodes.h:1573

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, fc(), 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, NullTest::location, BooleanTest::location, CoerceToDomain::location, nodeTag, source, SubLink::testexpr, and TypeCast::typeName.

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

◆ exprSetCollation()

void exprSetCollation ( Node expr,
Oid  collation 
)

Definition at line 1071 of file nodeFuncs.c.

1072 {
1073  switch (nodeTag(expr))
1074  {
1075  case T_Var:
1076  ((Var *) expr)->varcollid = collation;
1077  break;
1078  case T_Const:
1079  ((Const *) expr)->constcollid = collation;
1080  break;
1081  case T_Param:
1082  ((Param *) expr)->paramcollid = collation;
1083  break;
1084  case T_Aggref:
1085  ((Aggref *) expr)->aggcollid = collation;
1086  break;
1087  case T_GroupingFunc:
1088  Assert(!OidIsValid(collation));
1089  break;
1090  case T_WindowFunc:
1091  ((WindowFunc *) expr)->wincollid = collation;
1092  break;
1093  case T_MergeSupportFunc:
1094  ((MergeSupportFunc *) expr)->msfcollid = collation;
1095  break;
1096  case T_SubscriptingRef:
1097  ((SubscriptingRef *) expr)->refcollid = collation;
1098  break;
1099  case T_FuncExpr:
1100  ((FuncExpr *) expr)->funccollid = collation;
1101  break;
1102  case T_NamedArgExpr:
1103  Assert(collation == exprCollation((Node *) ((NamedArgExpr *) expr)->arg));
1104  break;
1105  case T_OpExpr:
1106  ((OpExpr *) expr)->opcollid = collation;
1107  break;
1108  case T_DistinctExpr:
1109  ((DistinctExpr *) expr)->opcollid = collation;
1110  break;
1111  case T_NullIfExpr:
1112  ((NullIfExpr *) expr)->opcollid = collation;
1113  break;
1114  case T_ScalarArrayOpExpr:
1115  /* ScalarArrayOpExpr's result is boolean ... */
1116  Assert(!OidIsValid(collation)); /* ... so never set a collation */
1117  break;
1118  case T_BoolExpr:
1119  /* BoolExpr's result is boolean ... */
1120  Assert(!OidIsValid(collation)); /* ... so never set a collation */
1121  break;
1122  case T_SubLink:
1123 #ifdef USE_ASSERT_CHECKING
1124  {
1125  SubLink *sublink = (SubLink *) expr;
1126 
1127  if (sublink->subLinkType == EXPR_SUBLINK ||
1128  sublink->subLinkType == ARRAY_SUBLINK)
1129  {
1130  /* get the collation of subselect's first target column */
1131  Query *qtree = (Query *) sublink->subselect;
1132  TargetEntry *tent;
1133 
1134  if (!qtree || !IsA(qtree, Query))
1135  elog(ERROR, "cannot set collation for untransformed sublink");
1136  tent = linitial_node(TargetEntry, qtree->targetList);
1137  Assert(!tent->resjunk);
1138  Assert(collation == exprCollation((Node *) tent->expr));
1139  }
1140  else
1141  {
1142  /* otherwise, result is RECORD or BOOLEAN */
1143  Assert(!OidIsValid(collation));
1144  }
1145  }
1146 #endif /* USE_ASSERT_CHECKING */
1147  break;
1148  case T_FieldSelect:
1149  ((FieldSelect *) expr)->resultcollid = collation;
1150  break;
1151  case T_FieldStore:
1152  /* FieldStore's result is composite ... */
1153  Assert(!OidIsValid(collation)); /* ... so never set a collation */
1154  break;
1155  case T_RelabelType:
1156  ((RelabelType *) expr)->resultcollid = collation;
1157  break;
1158  case T_CoerceViaIO:
1159  ((CoerceViaIO *) expr)->resultcollid = collation;
1160  break;
1161  case T_ArrayCoerceExpr:
1162  ((ArrayCoerceExpr *) expr)->resultcollid = collation;
1163  break;
1164  case T_ConvertRowtypeExpr:
1165  /* ConvertRowtypeExpr's result is composite ... */
1166  Assert(!OidIsValid(collation)); /* ... so never set a collation */
1167  break;
1168  case T_CaseExpr:
1169  ((CaseExpr *) expr)->casecollid = collation;
1170  break;
1171  case T_ArrayExpr:
1172  ((ArrayExpr *) expr)->array_collid = collation;
1173  break;
1174  case T_RowExpr:
1175  /* RowExpr's result is composite ... */
1176  Assert(!OidIsValid(collation)); /* ... so never set a collation */
1177  break;
1178  case T_RowCompareExpr:
1179  /* RowCompareExpr's result is boolean ... */
1180  Assert(!OidIsValid(collation)); /* ... so never set a collation */
1181  break;
1182  case T_CoalesceExpr:
1183  ((CoalesceExpr *) expr)->coalescecollid = collation;
1184  break;
1185  case T_MinMaxExpr:
1186  ((MinMaxExpr *) expr)->minmaxcollid = collation;
1187  break;
1188  case T_SQLValueFunction:
1189  Assert((((SQLValueFunction *) expr)->type == NAMEOID) ?
1190  (collation == C_COLLATION_OID) :
1191  (collation == InvalidOid));
1192  break;
1193  case T_XmlExpr:
1194  Assert((((XmlExpr *) expr)->op == IS_XMLSERIALIZE) ?
1195  (collation == DEFAULT_COLLATION_OID) :
1196  (collation == InvalidOid));
1197  break;
1198  case T_JsonValueExpr:
1199  exprSetCollation((Node *) ((JsonValueExpr *) expr)->formatted_expr,
1200  collation);
1201  break;
1202  case T_JsonConstructorExpr:
1203  {
1204  JsonConstructorExpr *ctor = (JsonConstructorExpr *) expr;
1205 
1206  if (ctor->coercion)
1207  exprSetCollation((Node *) ctor->coercion, collation);
1208  else
1209  Assert(!OidIsValid(collation)); /* result is always a
1210  * json[b] type */
1211  }
1212  break;
1213  case T_JsonIsPredicate:
1214  Assert(!OidIsValid(collation)); /* result is always boolean */
1215  break;
1216  case T_NullTest:
1217  /* NullTest's result is boolean ... */
1218  Assert(!OidIsValid(collation)); /* ... so never set a collation */
1219  break;
1220  case T_BooleanTest:
1221  /* BooleanTest's result is boolean ... */
1222  Assert(!OidIsValid(collation)); /* ... so never set a collation */
1223  break;
1224  case T_CoerceToDomain:
1225  ((CoerceToDomain *) expr)->resultcollid = collation;
1226  break;
1227  case T_CoerceToDomainValue:
1228  ((CoerceToDomainValue *) expr)->collation = collation;
1229  break;
1230  case T_SetToDefault:
1231  ((SetToDefault *) expr)->collation = collation;
1232  break;
1233  case T_CurrentOfExpr:
1234  /* CurrentOfExpr's result is boolean ... */
1235  Assert(!OidIsValid(collation)); /* ... so never set a collation */
1236  break;
1237  case T_NextValueExpr:
1238  /* NextValueExpr's result is an integer type ... */
1239  Assert(!OidIsValid(collation)); /* ... so never set a collation */
1240  break;
1241  default:
1242  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
1243  break;
1244  }
1245 }
#define OidIsValid(objectId)
Definition: c.h:762
void exprSetCollation(Node *expr, Oid collation)
Definition: nodeFuncs.c:1071

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

Referenced by assign_collations_walker().

◆ exprSetInputCollation()

void exprSetInputCollation ( Node expr,
Oid  inputcollation 
)

Definition at line 1256 of file nodeFuncs.c.

1257 {
1258  switch (nodeTag(expr))
1259  {
1260  case T_Aggref:
1261  ((Aggref *) expr)->inputcollid = inputcollation;
1262  break;
1263  case T_WindowFunc:
1264  ((WindowFunc *) expr)->inputcollid = inputcollation;
1265  break;
1266  case T_FuncExpr:
1267  ((FuncExpr *) expr)->inputcollid = inputcollation;
1268  break;
1269  case T_OpExpr:
1270  ((OpExpr *) expr)->inputcollid = inputcollation;
1271  break;
1272  case T_DistinctExpr:
1273  ((DistinctExpr *) expr)->inputcollid = inputcollation;
1274  break;
1275  case T_NullIfExpr:
1276  ((NullIfExpr *) expr)->inputcollid = inputcollation;
1277  break;
1278  case T_ScalarArrayOpExpr:
1279  ((ScalarArrayOpExpr *) expr)->inputcollid = inputcollation;
1280  break;
1281  case T_MinMaxExpr:
1282  ((MinMaxExpr *) expr)->inputcollid = inputcollation;
1283  break;
1284  default:
1285  break;
1286  }
1287 }

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))
116  ereport(ERROR,
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))
147  ereport(ERROR,
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_NullTest:
240  type = BOOLOID;
241  break;
242  case T_BooleanTest:
243  type = BOOLOID;
244  break;
245  case T_CoerceToDomain:
246  type = ((const CoerceToDomain *) expr)->resulttype;
247  break;
248  case T_CoerceToDomainValue:
249  type = ((const CoerceToDomainValue *) expr)->typeId;
250  break;
251  case T_SetToDefault:
252  type = ((const SetToDefault *) expr)->typeId;
253  break;
254  case T_CurrentOfExpr:
255  type = BOOLOID;
256  break;
257  case T_NextValueExpr:
258  type = ((const NextValueExpr *) expr)->typeId;
259  break;
260  case T_InferenceElem:
261  {
262  const InferenceElem *n = (const InferenceElem *) expr;
263 
264  type = exprType((Node *) n->expr);
265  }
266  break;
267  case T_PlaceHolderVar:
268  type = exprType((Node *) ((const PlaceHolderVar *) expr)->phexpr);
269  break;
270  default:
271  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
272  type = InvalidOid; /* keep compiler quiet */
273  break;
274  }
275  return type;
276 }
int errcode(int sqlerrcode)
Definition: elog.c:859
int errmsg(const char *fmt,...)
Definition: elog.c:1072
#define ereport(elevel,...)
Definition: elog.h:149
char * format_type_be(Oid type_oid)
Definition: format_type.c:343
Oid get_promoted_array_type(Oid typid)
Definition: lsyscache.c:2767
@ MULTIEXPR_SUBLINK
Definition: primnodes.h:958
@ IS_DOCUMENT
Definition: primnodes.h:1543
Oid firstColType
Definition: primnodes.h:1030

References arg, ARRAY_SUBLINK, Assert(), elog, ereport, errcode(), errmsg(), ERROR, InferenceElem::expr, EXPR_SUBLINK, 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, SubLink::subLinkType, SubPlan::subLinkType, AlternativeSubPlan::subplans, SubLink::subselect, Query::targetList, and type.

Referenced by add_row_identity_var(), addRangeTableEntryForFunction(), 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(), can_minmax_aggs(), canonicalize_ec_expression(), check_functions_in_node(), check_hashjoinable(), check_memoizable(), check_mergejoinable(), check_simple_rowfilter_expr_walker(), check_sql_fn_retval(), checkRuleResultList(), coerce_fn_result_column(), coerce_record_to_complex(), coerce_to_boolean(), coerce_to_common_type(), coerce_to_specific_type_typmod(), coerceJsonFuncExpr(), compare_tlist_datatypes(), compute_semijoin_info(), ComputeIndexAttrs(), ComputePartitionAttrs(), ConstructTupleDescriptor(), contain_mutable_functions_walker(), convert_EXISTS_to_ANY(), cookDefault(), cost_qual_eval_walker(), create_ctas_nodata(), create_indexscan_plan(), CreateStatistics(), DefineVirtualRelation(), deparseNullTest(), deparseOpExpr(), estimate_num_groups(), eval_const_expressions_mutator(), EvaluateParams(), examine_attribute(), examine_expression(), examine_variable(), exec_save_simple_expr(), ExecBuildProjectionInfo(), ExecBuildUpdateProjection(), ExecCheckPlanOutput(), ExecEvalJsonIsPredicate(), ExecEvalXmlExpr(), ExecInitExprRec(), ExecInitIndexScan(), ExecMakeTableFunctionResult(), ExecTypeFromExprList(), ExecTypeFromTLInternal(), ExecWindowAgg(), expandRecordVariable(), expandRTE(), exprTypmod(), find_expr_references_walker(), find_placeholder_info(), fix_indexqual_operand(), foreign_expr_walker(), generate_append_tlist(), generate_join_implied_equalities_normal(), generate_setop_tlist(), generate_subquery_params(), generateClonedIndexStmt(), get_call_expr_argtype(), get_expr_result_tupdesc(), get_expr_result_type(), get_expr_width(), get_first_col_type(), get_fn_expr_rettype(), get_func_expr(), get_oper_expr(), get_rule_expr(), get_rule_expr_funccall(), get_rule_orderby(), get_simple_binary_op_name(), get_sublink_expr(), get_windowfunc_expr_helper(), GetIndexInputType(), hash_ok_operator(), hstore_subscript_transform(), initialize_peragg(), inline_function(), internal_get_result_type(), jsonb_exec_setup(), jsonb_subscript_transform(), make_op(), make_scalar_array_op(), makeJsonConstructorExpr(), makeVarFromTargetEntry(), makeWholeRowVar(), 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(), 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(), transformJsonConstructorOutput(), transformJsonParseArg(), transformJsonScalarExpr(), transformJsonValueExpr(), transformMultiAssignRef(), transformPartitionBoundValue(), transformPLAssignStmt(), transformSetOperationTree(), transformSubLink(), transformTypeCast(), unknown_attribute(), verify_common_type(), and xmlelement().

◆ exprTypmod()

int32 exprTypmod ( const Node expr)

Definition at line 284 of file nodeFuncs.c.

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

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

Referenced by add_row_identity_var(), addRangeTableEntryForFunction(), 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(), ExecTypeFromExprList(), ExecTypeFromTLInternal(), expandRecordVariable(), expandRTE(), find_placeholder_info(), generate_append_tlist(), generate_setop_tlist(), generate_subquery_params(), get_expr_result_type(), get_expr_width(), get_first_col_type(), get_rule_expr(), get_rule_expr_funccall(), interval_support(), makeJsonConstructorExpr(), makeVarFromTargetEntry(), numeric_support(), preprocess_aggref(), RelationBuildPartitionKey(), RelationGetDummyIndexExpressions(), remove_unused_subquery_outputs(), replace_nestloop_param_placeholdervar(), replace_outer_placeholdervar(), select_common_typmod(), set_append_rel_size(), set_dummy_tlist_references(), set_rel_width(), TemporalSimplify(), transformCaseExpr(), transformFromClauseItem(), transformIndirection(), transformMultiAssignRef(), transformPLAssignStmt(), transformSubLink(), varbit_support(), and varchar_support().

◆ fix_opfuncids()

void fix_opfuncids ( Node node)

Definition at line 1759 of file nodeFuncs.c.

1760 {
1761  /* This tree walk requires no special setup, so away we go... */
1762  fix_opfuncids_walker(node, NULL);
1763 }
static bool fix_opfuncids_walker(Node *node, void *context)
Definition: nodeFuncs.c:1766

References fix_opfuncids_walker().

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

◆ get_leftop()

◆ get_notclausearg()

◆ get_rightop()

◆ is_andclause()

◆ is_funcclause()

static bool is_funcclause ( const void *  clause)
inlinestatic

◆ is_notclause()

◆ is_opclause()

◆ is_orclause()

◆ planstate_tree_walker_impl()

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

Definition at line 4471 of file nodeFuncs.c.

4474 {
4475  Plan *plan = planstate->plan;
4476  ListCell *lc;
4477 
4478  /* We don't need implicit coercions to Node here */
4479 #define PSWALK(n) walker(n, context)
4480 
4481  /* Guard against stack overflow due to overly complex plan trees */
4483 
4484  /* initPlan-s */
4485  if (planstate_walk_subplans(planstate->initPlan, walker, context))
4486  return true;
4487 
4488  /* lefttree */
4489  if (outerPlanState(planstate))
4490  {
4491  if (PSWALK(outerPlanState(planstate)))
4492  return true;
4493  }
4494 
4495  /* righttree */
4496  if (innerPlanState(planstate))
4497  {
4498  if (PSWALK(innerPlanState(planstate)))
4499  return true;
4500  }
4501 
4502  /* special child plans */
4503  switch (nodeTag(plan))
4504  {
4505  case T_Append:
4506  if (planstate_walk_members(((AppendState *) planstate)->appendplans,
4507  ((AppendState *) planstate)->as_nplans,
4508  walker, context))
4509  return true;
4510  break;
4511  case T_MergeAppend:
4512  if (planstate_walk_members(((MergeAppendState *) planstate)->mergeplans,
4513  ((MergeAppendState *) planstate)->ms_nplans,
4514  walker, context))
4515  return true;
4516  break;
4517  case T_BitmapAnd:
4518  if (planstate_walk_members(((BitmapAndState *) planstate)->bitmapplans,
4519  ((BitmapAndState *) planstate)->nplans,
4520  walker, context))
4521  return true;
4522  break;
4523  case T_BitmapOr:
4524  if (planstate_walk_members(((BitmapOrState *) planstate)->bitmapplans,
4525  ((BitmapOrState *) planstate)->nplans,
4526  walker, context))
4527  return true;
4528  break;
4529  case T_SubqueryScan:
4530  if (PSWALK(((SubqueryScanState *) planstate)->subplan))
4531  return true;
4532  break;
4533  case T_CustomScan:
4534  foreach(lc, ((CustomScanState *) planstate)->custom_ps)
4535  {
4536  if (PSWALK(lfirst(lc)))
4537  return true;
4538  }
4539  break;
4540  default:
4541  break;
4542  }
4543 
4544  /* subPlan-s */
4545  if (planstate_walk_subplans(planstate->subPlan, walker, context))
4546  return true;
4547 
4548  return false;
4549 }
#define outerPlanState(node)
Definition: execnodes.h:1139
#define innerPlanState(node)
Definition: execnodes.h:1138
static bool planstate_walk_subplans(List *plans, planstate_tree_walker_callback walker, void *context)
Definition: nodeFuncs.c:4555
#define PSWALK(n)
static bool planstate_walk_members(PlanState **planstates, int nplans, planstate_tree_walker_callback walker, void *context)
Definition: nodeFuncs.c:4577
#define plan(x)
Definition: pg_regress.c:162
Plan * plan
Definition: execnodes.h:1043
List * initPlan
Definition: execnodes.h:1068

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

◆ query_or_expression_tree_mutator_impl()

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

Definition at line 3788 of file nodeFuncs.c.

3792 {
3793  if (node && IsA(node, Query))
3794  return (Node *) query_tree_mutator((Query *) node,
3795  mutator,
3796  context,
3797  flags);
3798  else
3799  return mutator(node, context);
3800 }
#define query_tree_mutator(q, m, c, f)
Definition: nodeFuncs.h:158

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

3769 {
3770  if (node && IsA(node, Query))
3771  return query_tree_walker((Query *) node,
3772  walker,
3773  context,
3774  flags);
3775  else
3776  return WALK(node);
3777 }
#define query_tree_walker(q, w, c, f)
Definition: nodeFuncs.h:156

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

3609 {
3610  Assert(query != NULL && IsA(query, Query));
3611 
3612  if (!(flags & QTW_DONT_COPY_QUERY))
3613  {
3614  Query *newquery;
3615 
3616  FLATCOPY(newquery, query, Query);
3617  query = newquery;
3618  }
3619 
3620  MUTATE(query->targetList, query->targetList, List *);
3621  MUTATE(query->withCheckOptions, query->withCheckOptions, List *);
3622  MUTATE(query->onConflict, query->onConflict, OnConflictExpr *);
3623  MUTATE(query->mergeActionList, query->mergeActionList, List *);
3624  MUTATE(query->returningList, query->returningList, List *);
3625  MUTATE(query->jointree, query->jointree, FromExpr *);
3626  MUTATE(query->setOperations, query->setOperations, Node *);
3627  MUTATE(query->havingQual, query->havingQual, Node *);
3628  MUTATE(query->limitOffset, query->limitOffset, Node *);
3629  MUTATE(query->limitCount, query->limitCount, Node *);
3630 
3631  /*
3632  * Most callers aren't interested in SortGroupClause nodes since those
3633  * don't contain actual expressions. However they do contain OIDs, which
3634  * may be of interest to some mutators.
3635  */
3636 
3637  if ((flags & QTW_EXAMINE_SORTGROUP))
3638  {
3639  MUTATE(query->groupClause, query->groupClause, List *);
3640  MUTATE(query->windowClause, query->windowClause, List *);
3641  MUTATE(query->sortClause, query->sortClause, List *);
3642  MUTATE(query->distinctClause, query->distinctClause, List *);
3643  }
3644  else
3645  {
3646  /*
3647  * But we need to mutate the expressions under WindowClause nodes even
3648  * if we're not interested in SortGroupClause nodes.
3649  */
3650  List *resultlist;
3651  ListCell *temp;
3652 
3653  resultlist = NIL;
3654  foreach(temp, query->windowClause)
3655  {
3656  WindowClause *wc = lfirst_node(WindowClause, temp);
3657  WindowClause *newnode;
3658 
3659  FLATCOPY(newnode, wc, WindowClause);
3660  MUTATE(newnode->startOffset, wc->startOffset, Node *);
3661  MUTATE(newnode->endOffset, wc->endOffset, Node *);
3662  MUTATE(newnode->runCondition, wc->runCondition, List *);
3663 
3664  resultlist = lappend(resultlist, (Node *) newnode);
3665  }
3666  query->windowClause = resultlist;
3667  }
3668 
3669  /*
3670  * groupingSets and rowMarks are not mutated:
3671  *
3672  * groupingSets contain only ressortgroup refs (integers) which are
3673  * meaningless without the groupClause or tlist. Accordingly, any mutator
3674  * that needs to care about them needs to handle them itself in its Query
3675  * processing.
3676  *
3677  * rowMarks contains only rangetable indexes (and flags etc.) and
3678  * therefore should be handled at Query level similarly.
3679  */
3680 
3681  if (!(flags & QTW_IGNORE_CTE_SUBQUERIES))
3682  MUTATE(query->cteList, query->cteList, List *);
3683  else /* else copy CTE list as-is */
3684  query->cteList = copyObject(query->cteList);
3685  query->rtable = range_table_mutator(query->rtable,
3686  mutator, context, flags);
3687  return query;
3688 }
#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:163
Node * limitCount
Definition: parsenodes.h:213
FromExpr * jointree
Definition: parsenodes.h:175
List * returningList
Definition: parsenodes.h:197
Node * setOperations
Definition: parsenodes.h:218
List * cteList
Definition: parsenodes.h:166
OnConflictExpr * onConflict
Definition: parsenodes.h:195
List * groupClause
Definition: parsenodes.h:199
Node * havingQual
Definition: parsenodes.h:204
List * rtable
Definition: parsenodes.h:168
Node * limitOffset
Definition: parsenodes.h:212
List * mergeActionList
Definition: parsenodes.h:178
List * windowClause
Definition: parsenodes.h:206
List * distinctClause
Definition: parsenodes.h:208
List * sortClause
Definition: parsenodes.h:210

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

2581 {
2582  Assert(query != NULL && IsA(query, Query));
2583 
2584  /*
2585  * We don't walk any utilityStmt here. However, we can't easily assert
2586  * that it is absent, since there are at least two code paths by which
2587  * action statements from CREATE RULE end up here, and NOTIFY is allowed
2588  * in a rule action.
2589  */
2590 
2591  if (WALK(query->targetList))
2592  return true;
2593  if (WALK(query->withCheckOptions))
2594  return true;
2595  if (WALK(query->onConflict))
2596  return true;
2597  if (WALK(query->mergeActionList))
2598  return true;
2599  if (WALK(query->returningList))
2600  return true;
2601  if (WALK(query->jointree))
2602  return true;
2603  if (WALK(query->setOperations))
2604  return true;
2605  if (WALK(query->havingQual))
2606  return true;
2607  if (WALK(query->limitOffset))
2608  return true;
2609  if (WALK(query->limitCount))
2610  return true;
2611 
2612  /*
2613  * Most callers aren't interested in SortGroupClause nodes since those
2614  * don't contain actual expressions. However they do contain OIDs which
2615  * may be needed by dependency walkers etc.
2616  */
2617  if ((flags & QTW_EXAMINE_SORTGROUP))
2618  {
2619  if (WALK(query->groupClause))
2620  return true;
2621  if (WALK(query->windowClause))
2622  return true;
2623  if (WALK(query->sortClause))
2624  return true;
2625  if (WALK(query->distinctClause))
2626  return true;
2627  }
2628  else
2629  {
2630  /*
2631  * But we need to walk the expressions under WindowClause nodes even
2632  * if we're not interested in SortGroupClause nodes.
2633  */
2634  ListCell *lc;
2635 
2636  foreach(lc, query->windowClause)
2637  {
2639 
2640  if (WALK(wc->startOffset))
2641  return true;
2642  if (WALK(wc->endOffset))
2643  return true;
2644  if (WALK(wc->runCondition))
2645  return true;
2646  }
2647  }
2648 
2649  /*
2650  * groupingSets and rowMarks are not walked:
2651  *
2652  * groupingSets contain only ressortgrouprefs (integers) which are
2653  * meaningless without the corresponding groupClause or tlist.
2654  * Accordingly, any walker that needs to care about them needs to handle
2655  * them itself in its Query processing.
2656  *
2657  * rowMarks is not walked because it contains only rangetable indexes (and
2658  * flags etc.) and therefore should be handled at Query level similarly.
2659  */
2660 
2661  if (!(flags & QTW_IGNORE_CTE_SUBQUERIES))
2662  {
2663  if (WALK(query->cteList))
2664  return true;
2665  }
2666  if (!(flags & QTW_IGNORE_RANGE_TABLE))
2667  {
2668  if (range_table_walker(query->rtable, walker, context, flags))
2669  return true;
2670  }
2671  return false;
2672 }
#define range_table_walker(rt, w, c, f)
Definition: nodeFuncs.h:161
#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::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 2701 of file nodeFuncs.c.

2705 {
2706  /*
2707  * Walkers might need to examine the RTE node itself either before or
2708  * after visiting its contents (or, conceivably, both). Note that if you
2709  * specify neither flag, the walker won't be called on the RTE at all.
2710  */
2711  if (flags & QTW_EXAMINE_RTES_BEFORE)
2712  if (WALK(rte))
2713  return true;
2714 
2715  switch (rte->rtekind)
2716  {
2717  case RTE_RELATION:
2718  if (WALK(rte->tablesample))
2719  return true;
2720  break;
2721  case RTE_SUBQUERY:
2722  if (!(flags & QTW_IGNORE_RT_SUBQUERIES))
2723  if (WALK(rte->subquery))
2724  return true;
2725  break;
2726  case RTE_JOIN:
2727  if (!(flags & QTW_IGNORE_JOINALIASES))
2728  if (WALK(rte->joinaliasvars))
2729  return true;
2730  break;
2731  case RTE_FUNCTION:
2732  if (WALK(rte->functions))
2733  return true;
2734  break;
2735  case RTE_TABLEFUNC:
2736  if (WALK(rte->tablefunc))
2737  return true;
2738  break;
2739  case RTE_VALUES:
2740  if (WALK(rte->values_lists))
2741  return true;
2742  break;
2743  case RTE_CTE:
2744  case RTE_NAMEDTUPLESTORE:
2745  case RTE_RESULT:
2746  /* nothing to do */
2747  break;
2748  }
2749 
2750  if (WALK(rte->securityQuals))
2751  return true;
2752 
2753  if (flags & QTW_EXAMINE_RTES_AFTER)
2754  if (WALK(rte))
2755  return true;
2756 
2757  return false;
2758 }
#define QTW_IGNORE_RT_SUBQUERIES
Definition: nodeFuncs.h:22
#define QTW_EXAMINE_RTES_AFTER
Definition: nodeFuncs.h:28
#define QTW_EXAMINE_RTES_BEFORE
Definition: nodeFuncs.h:27
#define QTW_IGNORE_JOINALIASES
Definition: nodeFuncs.h:25
@ RTE_JOIN
Definition: parsenodes.h:1013
@ RTE_CTE
Definition: parsenodes.h:1017
@ RTE_NAMEDTUPLESTORE
Definition: parsenodes.h:1018
@ RTE_VALUES
Definition: parsenodes.h:1016
@ RTE_SUBQUERY
Definition: parsenodes.h:1012
@ RTE_RESULT
Definition: parsenodes.h:1019
@ RTE_FUNCTION
Definition: parsenodes.h:1014
@ RTE_TABLEFUNC
Definition: parsenodes.h:1015
@ RTE_RELATION
Definition: parsenodes.h:1011
TableFunc * tablefunc
Definition: parsenodes.h:1159
struct TableSampleClause * tablesample
Definition: parsenodes.h:1081
List * securityQuals
Definition: parsenodes.h:1208
Query * subquery
Definition: parsenodes.h:1086
List * values_lists
Definition: parsenodes.h:1164
List * joinaliasvars
Definition: parsenodes.h:1134
List * functions
Definition: parsenodes.h:1153
RTEKind rtekind
Definition: parsenodes.h:1030

References RangeTblEntry::functions, RangeTblEntry::joinaliasvars, QTW_EXAMINE_RTES_AFTER, QTW_EXAMINE_RTES_BEFORE, QTW_IGNORE_JOINALIASES, QTW_IGNORE_RT_SUBQUERIES, RTE_CTE, RTE_FUNCTION, RTE_JOIN, RTE_NAMEDTUPLESTORE, RTE_RELATION, RTE_RESULT, RTE_SUBQUERY, RTE_TABLEFUNC, RTE_VALUES, RangeTblEntry::rtekind, RangeTblEntry::securityQuals, 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 3696 of file nodeFuncs.c.

3700 {
3701  List *newrt = NIL;
3702  ListCell *rt;
3703 
3704  foreach(rt, rtable)
3705  {
3706  RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
3707  RangeTblEntry *newrte;
3708 
3709  FLATCOPY(newrte, rte, RangeTblEntry);
3710  switch (rte->rtekind)
3711  {
3712  case RTE_RELATION:
3713  MUTATE(newrte->tablesample, rte->tablesample,
3714  TableSampleClause *);
3715  /* we don't bother to copy eref, aliases, etc; OK? */
3716  break;
3717  case RTE_SUBQUERY:
3718  if (!(flags & QTW_IGNORE_RT_SUBQUERIES))
3719  MUTATE(newrte->subquery, rte->subquery, Query *);
3720  else
3721  {
3722  /* else, copy RT subqueries as-is */
3723  newrte->subquery = copyObject(rte->subquery);
3724  }
3725  break;
3726  case RTE_JOIN:
3727  if (!(flags & QTW_IGNORE_JOINALIASES))
3728  MUTATE(newrte->joinaliasvars, rte->joinaliasvars, List *);
3729  else
3730  {
3731  /* else, copy join aliases as-is */
3732  newrte->joinaliasvars = copyObject(rte->joinaliasvars);
3733  }
3734  break;
3735  case RTE_FUNCTION:
3736  MUTATE(newrte->functions, rte->functions, List *);
3737  break;
3738  case RTE_TABLEFUNC:
3739  MUTATE(newrte->tablefunc, rte->tablefunc, TableFunc *);
3740  break;
3741  case RTE_VALUES:
3742  MUTATE(newrte->values_lists, rte->values_lists, List *);
3743  break;
3744  case RTE_CTE:
3745  case RTE_NAMEDTUPLESTORE:
3746  case RTE_RESULT:
3747  /* nothing to do */
3748  break;
3749  }
3750  MUTATE(newrte->securityQuals, rte->securityQuals, List *);
3751  newrt = lappend(newrt, newrte);
3752  }
3753  return newrt;
3754 }

References copyObject, FLATCOPY, RangeTblEntry::functions, RangeTblEntry::joinaliasvars, lappend(), lfirst, MUTATE, NIL, QTW_IGNORE_JOINALIASES, QTW_IGNORE_RT_SUBQUERIES, RTE_CTE, RTE_FUNCTION, RTE_JOIN, RTE_NAMEDTUPLESTORE, RTE_RELATION, RTE_RESULT, RTE_SUBQUERY, RTE_TABLEFUNC, RTE_VALUES, RangeTblEntry::rtekind, RangeTblEntry::securityQuals, 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 2680 of file nodeFuncs.c.

2684 {
2685  ListCell *rt;
2686 
2687  foreach(rt, rtable)
2688  {
2690 
2691  if (range_table_entry_walker(rte, walker, context, flags))
2692  return true;
2693  }
2694  return false;
2695 }
#define range_table_entry_walker(r, w, c, f)
Definition: nodeFuncs.h:166

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

3822 {
3823  ListCell *temp;
3824 
3825  /*
3826  * The walker has already visited the current node, and so we need only
3827  * recurse into any sub-nodes it has.
3828  */
3829  if (node == NULL)
3830  return false;
3831 
3832  /* Guard against stack overflow due to overly complex expressions */
3834 
3835  switch (nodeTag(node))
3836  {
3837  case T_JsonFormat:
3838  case T_SetToDefault:
3839  case T_CurrentOfExpr:
3840  case T_SQLValueFunction:
3841  case T_Integer:
3842  case T_Float:
3843  case T_Boolean:
3844  case T_String:
3845  case T_BitString:
3846  case T_ParamRef:
3847  case T_A_Const:
3848  case T_A_Star:
3849  case T_MergeSupportFunc:
3850  /* primitive node types with no subnodes */
3851  break;
3852  case T_Alias:
3853  /* we assume the colnames list isn't interesting */
3854  break;
3855  case T_RangeVar:
3856  return WALK(((RangeVar *) node)->alias);
3857  case T_GroupingFunc:
3858  return WALK(((GroupingFunc *) node)->args);
3859  case T_SubLink:
3860  {
3861  SubLink *sublink = (SubLink *) node;
3862 
3863  if (WALK(sublink->testexpr))
3864  return true;
3865  /* we assume the operName is not interesting */
3866  if (WALK(sublink->subselect))
3867  return true;
3868  }
3869  break;
3870  case T_CaseExpr:
3871  {
3872  CaseExpr *caseexpr = (CaseExpr *) node;
3873 
3874  if (WALK(caseexpr->arg))
3875  return true;
3876  /* we assume walker doesn't care about CaseWhens, either */
3877  foreach(temp, caseexpr->args)
3878  {
3879  CaseWhen *when = lfirst_node(CaseWhen, temp);
3880 
3881  if (WALK(when->expr))
3882  return true;
3883  if (WALK(when->result))
3884  return true;
3885  }
3886  if (WALK(caseexpr->defresult))
3887  return true;
3888  }
3889  break;
3890  case T_RowExpr:
3891  /* Assume colnames isn't interesting */
3892  return WALK(((RowExpr *) node)->args);
3893  case T_CoalesceExpr:
3894  return WALK(((CoalesceExpr *) node)->args);
3895  case T_MinMaxExpr:
3896  return WALK(((MinMaxExpr *) node)->args);
3897  case T_XmlExpr:
3898  {
3899  XmlExpr *xexpr = (XmlExpr *) node;
3900 
3901  if (WALK(xexpr->named_args))
3902  return true;
3903  /* we assume walker doesn't care about arg_names */
3904  if (WALK(xexpr->args))
3905  return true;
3906  }
3907  break;
3908  case T_JsonReturning:
3909  return WALK(((JsonReturning *) node)->format);
3910  case T_JsonValueExpr:
3911  {
3912  JsonValueExpr *jve = (JsonValueExpr *) node;
3913 
3914  if (WALK(jve->raw_expr))
3915  return true;
3916  if (WALK(jve->formatted_expr))
3917  return true;
3918  if (WALK(jve->format))
3919  return true;
3920  }
3921  break;
3922  case T_JsonParseExpr:
3923  {
3924  JsonParseExpr *jpe = (JsonParseExpr *) node;
3925 
3926  if (WALK(jpe->expr))
3927  return true;
3928  if (WALK(jpe->output))
3929  return true;
3930  }
3931  break;
3932  case T_JsonScalarExpr:
3933  {
3934  JsonScalarExpr *jse = (JsonScalarExpr *) node;
3935 
3936  if (WALK(jse->expr))
3937  return true;
3938  if (WALK(jse->output))
3939  return true;
3940  }
3941  break;
3942  case T_JsonSerializeExpr:
3943  {
3944  JsonSerializeExpr *jse = (JsonSerializeExpr *) node;
3945 
3946  if (WALK(jse->expr))
3947  return true;
3948  if (WALK(jse->output))
3949  return true;
3950  }
3951  break;
3952  case T_JsonConstructorExpr:
3953  {
3954  JsonConstructorExpr *ctor = (JsonConstructorExpr *) node;
3955 
3956  if (WALK(ctor->args))
3957  return true;
3958  if (WALK(ctor->func))
3959  return true;
3960  if (WALK(ctor->coercion))
3961  return true;
3962  if (WALK(ctor->returning))
3963  return true;
3964  }
3965  break;
3966  case T_JsonIsPredicate:
3967  return WALK(((JsonIsPredicate *) node)->expr);
3968  case T_NullTest:
3969  return WALK(((NullTest *) node)->arg);
3970  case T_BooleanTest:
3971  return WALK(((BooleanTest *) node)->arg);
3972  case T_JoinExpr:
3973  {
3974  JoinExpr *join = (JoinExpr *) node;
3975 
3976  if (WALK(join->larg))
3977  return true;
3978  if (WALK(join->rarg))
3979  return true;
3980  if (WALK(join->quals))
3981  return true;
3982  if (WALK(join->alias))
3983  return true;
3984  /* using list is deemed uninteresting */
3985  }
3986  break;
3987  case T_IntoClause:
3988  {
3989  IntoClause *into = (IntoClause *) node;
3990 
3991  if (WALK(into->rel))
3992  return true;
3993  /* colNames, options are deemed uninteresting */
3994  /* viewQuery should be null in raw parsetree, but check it */
3995  if (WALK(into->viewQuery))
3996  return true;
3997  }
3998  break;
3999  case T_List:
4000  foreach(temp, (List *) node)
4001  {
4002  if (WALK((Node *) lfirst(temp)))
4003  return true;
4004  }
4005  break;
4006  case T_InsertStmt:
4007  {
4008  InsertStmt *stmt = (InsertStmt *) node;
4009 
4010  if (WALK(stmt->relation))
4011  return true;
4012  if (WALK(stmt->cols))
4013  return true;
4014  if (WALK(stmt->selectStmt))
4015  return true;
4016  if (WALK(stmt->onConflictClause))
4017  return true;
4018  if (WALK(stmt->returningList))
4019  return true;
4020  if (WALK(stmt->withClause))
4021  return true;
4022  }
4023  break;
4024  case T_DeleteStmt:
4025  {
4026  DeleteStmt *stmt = (DeleteStmt *) node;
4027 
4028  if (WALK(stmt->relation))
4029  return true;
4030  if (WALK(stmt->usingClause))
4031  return true;
4032  if (WALK(stmt->whereClause))
4033  return true;
4034  if (WALK(stmt->returningList))
4035  return true;
4036  if (WALK(stmt->withClause))
4037  return true;
4038  }
4039  break;
4040  case T_UpdateStmt:
4041  {
4042  UpdateStmt *stmt = (UpdateStmt *) node;
4043 
4044  if (WALK(stmt->relation))
4045  return true;
4046  if (WALK(stmt->targetList))
4047  return true;
4048  if (WALK(stmt->whereClause))
4049  return true;
4050  if (WALK(stmt->fromClause))
4051  return true;
4052  if (WALK(stmt->returningList))
4053  return true;
4054  if (WALK(stmt->withClause))
4055  return true;
4056  }
4057  break;
4058  case T_MergeStmt:
4059  {
4060  MergeStmt *stmt = (MergeStmt *) node;
4061 
4062  if (WALK(stmt->relation))
4063  return true;
4064  if (WALK(stmt->sourceRelation))
4065  return true;
4066  if (WALK(stmt->joinCondition))
4067  return true;
4068  if (WALK(stmt->mergeWhenClauses))
4069  return true;
4070  if (WALK(stmt->returningList))
4071  return true;
4072  if (WALK(stmt->withClause))
4073  return true;
4074  }
4075  break;
4076  case T_MergeWhenClause:
4077  {
4078  MergeWhenClause *mergeWhenClause = (MergeWhenClause *) node;
4079 
4080  if (WALK(mergeWhenClause->condition))
4081  return true;
4082  if (WALK(mergeWhenClause->targetList))
4083  return true;
4084  if (WALK(mergeWhenClause->values))
4085  return true;
4086  }
4087  break;
4088  case T_SelectStmt:
4089  {
4090  SelectStmt *stmt = (SelectStmt *) node;
4091 
4092  if (WALK(stmt->distinctClause))
4093  return true;
4094  if (WALK(stmt->intoClause))
4095  return true;
4096  if (WALK(stmt->targetList))
4097  return true;
4098  if (WALK(stmt->fromClause))
4099  return true;
4100  if (WALK(stmt->whereClause))
4101  return true;
4102  if (WALK(stmt->groupClause))
4103  return true;
4104  if (WALK(stmt->havingClause))
4105  return true;
4106  if (WALK(stmt->windowClause))
4107  return true;
4108  if (WALK(stmt->valuesLists))
4109  return true;
4110  if (WALK(stmt->sortClause))
4111  return true;
4112  if (WALK(stmt->limitOffset))
4113  return true;
4114  if (WALK(stmt->limitCount))
4115  return true;
4116  if (WALK(stmt->lockingClause))
4117  return true;
4118  if (WALK(stmt->withClause))
4119  return true;
4120  if (WALK(stmt->larg))
4121  return true;
4122  if (WALK(stmt->rarg))
4123  return true;
4124  }
4125  break;
4126  case T_PLAssignStmt:
4127  {
4128  PLAssignStmt *stmt = (PLAssignStmt *) node;
4129 
4130  if (WALK(stmt->indirection))
4131  return true;
4132  if (WALK(stmt->val))
4133  return true;
4134  }
4135  break;
4136  case T_A_Expr:
4137  {
4138  A_Expr *expr = (A_Expr *) node;
4139 
4140  if (WALK(expr->lexpr))
4141  return true;
4142  if (WALK(expr->rexpr))
4143  return true;
4144  /* operator name is deemed uninteresting */
4145  }
4146  break;
4147  case T_BoolExpr:
4148  {
4149  BoolExpr *expr = (BoolExpr *) node;
4150 
4151  if (WALK(expr->args))
4152  return true;
4153  }
4154  break;
4155  case T_ColumnRef:
4156  /* we assume the fields contain nothing interesting */
4157  break;
4158  case T_FuncCall:
4159  {
4160  FuncCall *fcall = (FuncCall *) node;
4161 
4162  if (WALK(fcall->args))
4163  return true;
4164  if (WALK(fcall->agg_order))
4165  return true;
4166  if (WALK(fcall->agg_filter))
4167  return true;
4168  if (WALK(fcall->over))
4169  return true;
4170  /* function name is deemed uninteresting */
4171  }
4172  break;
4173  case T_NamedArgExpr:
4174  return WALK(((NamedArgExpr *) node)->arg);
4175  case T_A_Indices:
4176  {
4177  A_Indices *indices = (A_Indices *) node;
4178 
4179  if (WALK(indices->lidx))
4180  return true;
4181  if (WALK(indices->uidx))
4182  return true;
4183  }
4184  break;
4185  case T_A_Indirection:
4186  {
4187  A_Indirection *indir = (A_Indirection *) node;
4188 
4189  if (WALK(indir->arg))
4190  return true;
4191  if (WALK(indir->indirection))
4192  return true;
4193  }
4194  break;
4195  case T_A_ArrayExpr:
4196  return WALK(((A_ArrayExpr *) node)->elements);
4197  case T_ResTarget:
4198  {
4199  ResTarget *rt = (ResTarget *) node;
4200 
4201  if (WALK(rt->indirection))
4202  return true;
4203  if (WALK(rt->val))
4204  return true;
4205  }
4206  break;
4207  case T_MultiAssignRef:
4208  return WALK(((MultiAssignRef *) node)->source);
4209  case T_TypeCast:
4210  {
4211  TypeCast *tc = (TypeCast *) node;
4212 
4213  if (WALK(tc->arg))
4214  return true;
4215  if (WALK(tc->typeName))
4216  return true;
4217  }
4218  break;
4219  case T_CollateClause:
4220  return WALK(((CollateClause *) node)->arg);
4221  case T_SortBy:
4222  return WALK(((SortBy *) node)->node);
4223  case T_WindowDef:
4224  {
4225  WindowDef *wd = (WindowDef *) node;
4226 
4227  if (WALK(wd->partitionClause))
4228  return true;
4229  if (WALK(wd->orderClause))
4230  return true;
4231  if (WALK(wd->startOffset))
4232  return true;
4233  if (WALK(wd->endOffset))
4234  return true;
4235  }
4236  break;
4237  case T_RangeSubselect:
4238  {
4239  RangeSubselect *rs = (RangeSubselect *) node;
4240 
4241  if (WALK(rs->subquery))
4242  return true;
4243  if (WALK(rs->alias))
4244  return true;
4245  }
4246  break;
4247  case T_RangeFunction:
4248  {
4249  RangeFunction *rf = (RangeFunction *) node;
4250 
4251  if (WALK(rf->functions))
4252  return true;
4253  if (WALK(rf->alias))
4254  return true;
4255  if (WALK(rf->coldeflist))
4256  return true;
4257  }
4258  break;
4259  case T_RangeTableSample:
4260  {
4261  RangeTableSample *rts = (RangeTableSample *) node;
4262 
4263  if (WALK(rts->relation))
4264  return true;
4265  /* method name is deemed uninteresting */
4266  if (WALK(rts->args))
4267  return true;
4268  if (WALK(rts->repeatable))
4269  return true;
4270  }
4271  break;
4272  case T_RangeTableFunc:
4273  {
4274  RangeTableFunc *rtf = (RangeTableFunc *) node;
4275 
4276  if (WALK(rtf->docexpr))
4277  return true;
4278  if (WALK(rtf->rowexpr))
4279  return true;
4280  if (WALK(rtf->namespaces))
4281  return true;
4282  if (WALK(rtf->columns))
4283  return true;
4284  if (WALK(rtf->alias))
4285  return true;
4286  }
4287  break;
4288  case T_RangeTableFuncCol:
4289  {
4290  RangeTableFuncCol *rtfc = (RangeTableFuncCol *) node;
4291 
4292  if (WALK(rtfc->colexpr))
4293  return true;
4294  if (WALK(rtfc->coldefexpr))
4295  return true;
4296  }
4297  break;
4298  case T_TypeName:
4299  {
4300  TypeName *tn = (TypeName *) node;
4301 
4302  if (WALK(tn->typmods))
4303  return true;
4304  if (WALK(tn->arrayBounds))
4305  return true;
4306  /* type name itself is deemed uninteresting */
4307  }
4308  break;
4309  case T_ColumnDef:
4310  {
4311  ColumnDef *coldef = (ColumnDef *) node;
4312 
4313  if (WALK(coldef->typeName))
4314  return true;
4315  if (WALK(coldef->raw_default))
4316  return true;
4317  if (WALK(coldef->collClause))
4318  return true;
4319  /* for now, constraints are ignored */
4320  }
4321  break;
4322  case T_IndexElem:
4323  {
4324  IndexElem *indelem = (IndexElem *) node;
4325 
4326  if (WALK(indelem->expr))
4327  return true;
4328  /* collation and opclass names are deemed uninteresting */
4329  }
4330  break;
4331  case T_GroupingSet:
4332  return WALK(((GroupingSet *) node)->content);
4333  case T_LockingClause:
4334  return WALK(((LockingClause *) node)->lockedRels);
4335  case T_XmlSerialize:
4336  {
4337  XmlSerialize *xs = (XmlSerialize *) node;
4338 
4339  if (WALK(xs->expr))
4340  return true;
4341  if (WALK(xs->typeName))
4342  return true;
4343  }
4344  break;
4345  case T_WithClause:
4346  return WALK(((WithClause *) node)->ctes);
4347  case T_InferClause:
4348  {
4349  InferClause *stmt = (InferClause *) node;
4350 
4351  if (WALK(stmt->indexElems))
4352  return true;
4353  if (WALK(stmt->whereClause))
4354  return true;
4355  }
4356  break;
4357  case T_OnConflictClause:
4358  {
4360 
4361  if (WALK(stmt->infer))
4362  return true;
4363  if (WALK(stmt->targetList))
4364  return true;
4365  if (WALK(stmt->whereClause))
4366  return true;
4367  }
4368  break;
4369  case T_CommonTableExpr:
4370  /* search_clause and cycle_clause are not interesting here */
4371  return WALK(((CommonTableExpr *) node)->ctequery);
4372  case T_JsonOutput:
4373  {
4374  JsonOutput *out = (JsonOutput *) node;
4375 
4376  if (WALK(out->typeName))
4377  return true;
4378  if (WALK(out->returning))
4379  return true;
4380  }
4381  break;
4382  case T_JsonKeyValue:
4383  {
4384  JsonKeyValue *jkv = (JsonKeyValue *) node;
4385 
4386  if (WALK(jkv->key))
4387  return true;
4388  if (WALK(jkv->value))
4389  return true;
4390  }
4391  break;
4392  case T_JsonObjectConstructor:
4393  {
4395 
4396  if (WALK(joc->output))
4397  return true;
4398  if (WALK(joc->exprs))
4399  return true;
4400  }
4401  break;
4402  case T_JsonArrayConstructor:
4403  {
4405 
4406  if (WALK(jac->output))
4407  return true;
4408  if (WALK(jac->exprs))
4409  return true;
4410  }
4411  break;
4412  case T_JsonAggConstructor:
4413  {
4414  JsonAggConstructor *ctor = (JsonAggConstructor *) node;
4415 
4416  if (WALK(ctor->output))
4417  return true;
4418  if (WALK(ctor->agg_order))
4419  return true;
4420  if (WALK(ctor->agg_filter))
4421  return true;
4422  if (WALK(ctor->over))
4423  return true;
4424  }
4425  break;
4426  case T_JsonObjectAgg:
4427  {
4428  JsonObjectAgg *joa = (JsonObjectAgg *) node;
4429 
4430  if (WALK(joa->constructor))
4431  return true;
4432  if (WALK(joa->arg))
4433  return true;
4434  }
4435  break;
4436  case T_JsonArrayAgg:
4437  {
4438  JsonArrayAgg *jaa = (JsonArrayAgg *) node;
4439 
4440  if (WALK(jaa->constructor))
4441  return true;
4442  if (WALK(jaa->arg))
4443  return true;
4444  }
4445  break;
4446  case T_JsonArrayQueryConstructor:
4447  {
4449 
4450  if (WALK(jaqc->output))
4451  return true;
4452  if (WALK(jaqc->query))
4453  return true;
4454  }
4455  break;
4456  default:
4457  elog(ERROR, "unrecognized node type: %d",
4458  (int) nodeTag(node));
4459  break;
4460  }
4461  return false;
4462 }
#define stmt
Definition: indent_codes.h:59
static char format
Node * rexpr
Definition: parsenodes.h:336
Node * uidx
Definition: parsenodes.h:460
Node * lidx
Definition: parsenodes.h:459
List * indirection
Definition: parsenodes.h:482
CollateClause * collClause
Definition: parsenodes.h:737
TypeName * typeName
Definition: parsenodes.h:723
Node * raw_default
Definition: parsenodes.h:731
Node * agg_filter
Definition: parsenodes.h:428
List * agg_order
Definition: parsenodes.h:427
List * args
Definition: parsenodes.h:426
struct WindowDef * over
Definition: parsenodes.h:429
Node * expr
Definition: parsenodes.h:780
RangeVar * rel
Definition: primnodes.h:148
JsonOutput * output
Definition: parsenodes.h:1816
JsonOutput * output
Definition: parsenodes.h:1789
JsonOutput * output
Definition: parsenodes.h:1775
JsonReturning * returning
Definition: parsenodes.h:1715
TypeName * typeName
Definition: parsenodes.h:1714
JsonValueExpr * expr
Definition: parsenodes.h:1737
JsonOutput * output
Definition: parsenodes.h:1738
JsonOutput * output
Definition: parsenodes.h:1751
JsonOutput * output
Definition: parsenodes.h:1763
JsonValueExpr * expr
Definition: parsenodes.h:1762
Alias * alias
Definition: parsenodes.h:643
List * coldeflist
Definition: parsenodes.h:644
List * functions
Definition: parsenodes.h:642
Node * subquery
Definition: parsenodes.h:618
Alias * alias
Definition: parsenodes.h:619
List * namespaces
Definition: parsenodes.h:657
Node * docexpr
Definition: parsenodes.h:655
Node * rowexpr
Definition: parsenodes.h:656
List * columns
Definition: parsenodes.h:658
Alias * alias
Definition: parsenodes.h:659
Node * val
Definition: parsenodes.h:518
List * indirection
Definition: parsenodes.h:517
List * arrayBounds
Definition: parsenodes.h:273
List * typmods
Definition: parsenodes.h:271
List * orderClause
Definition: parsenodes.h:566
List * partitionClause
Definition: parsenodes.h:565
Node * startOffset
Definition: parsenodes.h:568
Node * endOffset
Definition: parsenodes.h:569
TypeName * typeName
Definition: parsenodes.h:843
Node * expr
Definition: parsenodes.h:842

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, MergeWhenClause::condition, JsonObjectAgg::constructor, JsonArrayAgg::constructor, CaseExpr::defresult, RangeTableFunc::docexpr, elog, WindowDef::endOffset, ERROR, IndexElem::expr, XmlSerialize::expr, JsonParseExpr::expr, JsonScalarExpr::expr, JsonSerializeExpr::expr, 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, WindowDef::orderClause, JsonParseExpr::output, JsonScalarExpr::output, JsonSerializeExpr::output, JsonObjectConstructor::output, JsonArrayConstructor::output, JsonArrayQueryConstructor::output, JsonAggConstructor::output, FuncCall::over, JsonAggConstructor::over, WindowDef::partitionClause, 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, TypeName::typmods, A_Indices::uidx, ResTarget::val, JsonKeyValue::value, MergeWhenClause::values, and WALK.

◆ relabel_to_typmod()

Node* relabel_to_typmod ( Node expr,
int32  typmod 
)

Definition at line 656 of file nodeFuncs.c.

657 {
658  return applyRelabelType(expr, exprType(expr), typmod, exprCollation(expr),
659  COERCE_EXPLICIT_CAST, -1, false);
660 }
Node * applyRelabelType(Node *arg, Oid rtype, int32 rtypmod, Oid rcollid, CoercionForm rformat, int rlocation, bool overwrite_ok)
Definition: nodeFuncs.c:603

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

1802 {
1803  if (opexpr->opfuncid == InvalidOid)
1804  opexpr->opfuncid = get_opcode(opexpr->opno);
1805 }

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

673 {
674  if (node == NULL)
675  return NULL;
676  if (IsA(node, FuncExpr))
677  {
678  FuncExpr *f = (FuncExpr *) node;
679 
680  if (f->funcformat == COERCE_IMPLICIT_CAST)
682  }
683  else if (IsA(node, RelabelType))
684  {
685  RelabelType *r = (RelabelType *) node;
686 
687  if (r->relabelformat == COERCE_IMPLICIT_CAST)
688  return strip_implicit_coercions((Node *) r->arg);
689  }
690  else if (IsA(node, CoerceViaIO))
691  {
692  CoerceViaIO *c = (CoerceViaIO *) node;
693 
694  if (c->coerceformat == COERCE_IMPLICIT_CAST)
695  return strip_implicit_coercions((Node *) c->arg);
696  }
697  else if (IsA(node, ArrayCoerceExpr))
698  {
699  ArrayCoerceExpr *c = (ArrayCoerceExpr *) node;
700 
701  if (c->coerceformat == COERCE_IMPLICIT_CAST)
702  return strip_implicit_coercions((Node *) c->arg);
703  }
704  else if (IsA(node, ConvertRowtypeExpr))
705  {
707 
708  if (c->convertformat == COERCE_IMPLICIT_CAST)
709  return strip_implicit_coercions((Node *) c->arg);
710  }
711  else if (IsA(node, CoerceToDomain))
712  {
713  CoerceToDomain *c = (CoerceToDomain *) node;
714 
715  if (c->coercionformat == COERCE_IMPLICIT_CAST)
716  return strip_implicit_coercions((Node *) c->arg);
717  }
718  return node;
719 }
Node * strip_implicit_coercions(Node *node)
Definition: nodeFuncs.c:672
char * c

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

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