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

Go to the source code of this file.

Macros

#define FLATCOPY(newnode, node, nodetype)
 
#define MUTATE(newfield, oldfield, fieldtype)    ( (newfield) = (fieldtype) mutator((Node *) (oldfield), context) )
 

Functions

static bool expression_returns_set_walker (Node *node, void *context)
 
static int leftmostLoc (int loc1, int loc2)
 
static bool fix_opfuncids_walker (Node *node, void *context)
 
static bool planstate_walk_subplans (List *plans, bool(*walker)(), void *context)
 
static bool planstate_walk_members (PlanState **planstates, int nplans, bool(*walker)(), void *context)
 
Oid exprType (const Node *expr)
 
int32 exprTypmod (const Node *expr)
 
bool exprIsLengthCoercion (const Node *expr, int32 *coercedTypmod)
 
NodeapplyRelabelType (Node *arg, Oid rtype, int32 rtypmod, Oid rcollid, CoercionForm rformat, int rlocation, bool overwrite_ok)
 
Noderelabel_to_typmod (Node *expr, int32 typmod)
 
Nodestrip_implicit_coercions (Node *node)
 
bool expression_returns_set (Node *clause)
 
Oid exprCollation (const Node *expr)
 
Oid exprInputCollation (const Node *expr)
 
void exprSetCollation (Node *expr, Oid collation)
 
void exprSetInputCollation (Node *expr, Oid inputcollation)
 
int exprLocation (const Node *expr)
 
void fix_opfuncids (Node *node)
 
void set_opfuncid (OpExpr *opexpr)
 
void set_sa_opfuncid (ScalarArrayOpExpr *opexpr)
 
bool check_functions_in_node (Node *node, check_function_callback checker, void *context)
 
bool expression_tree_walker (Node *node, bool(*walker)(), void *context)
 
bool query_tree_walker (Query *query, bool(*walker)(), void *context, int flags)
 
bool range_table_walker (List *rtable, bool(*walker)(), void *context, int flags)
 
bool range_table_entry_walker (RangeTblEntry *rte, bool(*walker)(), void *context, int flags)
 
Nodeexpression_tree_mutator (Node *node, Node *(*mutator)(), void *context)
 
Queryquery_tree_mutator (Query *query, Node *(*mutator)(), void *context, int flags)
 
Listrange_table_mutator (List *rtable, Node *(*mutator)(), void *context, int flags)
 
bool query_or_expression_tree_walker (Node *node, bool(*walker)(), void *context, int flags)
 
Nodequery_or_expression_tree_mutator (Node *node, Node *(*mutator)(), void *context, int flags)
 
bool raw_expression_tree_walker (Node *node, bool(*walker)(), void *context)
 
bool planstate_tree_walker (PlanState *planstate, bool(*walker)(), void *context)
 

Macro Definition Documentation

◆ FLATCOPY

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

◆ MUTATE

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

Function Documentation

◆ applyRelabelType()

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

Definition at line 609 of file nodeFuncs.c.

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

References arg, RelabelType::arg, Const::constcollid, Const::consttype, Const::consttypmod, copyObject, exprCollation(), exprType(), exprTypmod(), IsA, RelabelType::location, makeNode, RelabelType::relabelformat, RelabelType::resultcollid, RelabelType::resulttype, and RelabelType::resulttypmod.

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

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

References Aggref::aggfnoid, CoerceViaIO::arg, exprType(), FuncExpr::funcid, get_opcode(), getTypeInputInfo(), getTypeOutputInfo(), lfirst_oid, nodeTag, OpExpr::opfuncid, ScalarArrayOpExpr::opfuncid, RowCompareExpr::opnos, CoerceViaIO::resulttype, set_opfuncid(), set_sa_opfuncid(), T_Aggref, T_CoerceViaIO, T_DistinctExpr, T_FuncExpr, T_NullIfExpr, T_OpExpr, T_RowCompareExpr, T_ScalarArrayOpExpr, T_WindowFunc, and WindowFunc::winfnoid.

Referenced by contain_leaked_vars_walker(), contain_mutable_functions_walker(), contain_nonstrict_functions_walker(), contain_volatile_functions_not_nextval_walker(), contain_volatile_functions_walker(), expr_allowed_in_node(), 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_SubscriptingRef:
816  coll = ((const SubscriptingRef *) expr)->refcollid;
817  break;
818  case T_FuncExpr:
819  coll = ((const FuncExpr *) expr)->funccollid;
820  break;
821  case T_NamedArgExpr:
822  coll = exprCollation((Node *) ((const NamedArgExpr *) expr)->arg);
823  break;
824  case T_OpExpr:
825  coll = ((const OpExpr *) expr)->opcollid;
826  break;
827  case T_DistinctExpr:
828  coll = ((const DistinctExpr *) expr)->opcollid;
829  break;
830  case T_NullIfExpr:
831  coll = ((const NullIfExpr *) expr)->opcollid;
832  break;
833  case T_ScalarArrayOpExpr:
834  /* ScalarArrayOpExpr's result is boolean ... */
835  coll = InvalidOid; /* ... so it has no collation */
836  break;
837  case T_BoolExpr:
838  /* BoolExpr's result is boolean ... */
839  coll = InvalidOid; /* ... so it has no collation */
840  break;
841  case T_SubLink:
842  {
843  const SubLink *sublink = (const SubLink *) expr;
844 
845  if (sublink->subLinkType == EXPR_SUBLINK ||
846  sublink->subLinkType == ARRAY_SUBLINK)
847  {
848  /* get the collation of subselect's first target column */
849  Query *qtree = (Query *) sublink->subselect;
850  TargetEntry *tent;
851 
852  if (!qtree || !IsA(qtree, Query))
853  elog(ERROR, "cannot get collation for untransformed sublink");
854  tent = linitial_node(TargetEntry, qtree->targetList);
855  Assert(!tent->resjunk);
856  coll = exprCollation((Node *) tent->expr);
857  /* collation doesn't change if it's converted to array */
858  }
859  else
860  {
861  /* otherwise, SubLink's result is RECORD or BOOLEAN */
862  coll = InvalidOid; /* ... so it has no collation */
863  }
864  }
865  break;
866  case T_SubPlan:
867  {
868  const SubPlan *subplan = (const SubPlan *) expr;
869 
870  if (subplan->subLinkType == EXPR_SUBLINK ||
871  subplan->subLinkType == ARRAY_SUBLINK)
872  {
873  /* get the collation of subselect's first target column */
874  coll = subplan->firstColCollation;
875  /* collation doesn't change if it's converted to array */
876  }
877  else
878  {
879  /* otherwise, SubPlan's result is RECORD or BOOLEAN */
880  coll = InvalidOid; /* ... so it has no collation */
881  }
882  }
883  break;
885  {
886  const AlternativeSubPlan *asplan = (const AlternativeSubPlan *) expr;
887 
888  /* subplans should all return the same thing */
889  coll = exprCollation((Node *) linitial(asplan->subplans));
890  }
891  break;
892  case T_FieldSelect:
893  coll = ((const FieldSelect *) expr)->resultcollid;
894  break;
895  case T_FieldStore:
896  /* FieldStore's result is composite ... */
897  coll = InvalidOid; /* ... so it has no collation */
898  break;
899  case T_RelabelType:
900  coll = ((const RelabelType *) expr)->resultcollid;
901  break;
902  case T_CoerceViaIO:
903  coll = ((const CoerceViaIO *) expr)->resultcollid;
904  break;
905  case T_ArrayCoerceExpr:
906  coll = ((const ArrayCoerceExpr *) expr)->resultcollid;
907  break;
909  /* ConvertRowtypeExpr's result is composite ... */
910  coll = InvalidOid; /* ... so it has no collation */
911  break;
912  case T_CollateExpr:
913  coll = ((const CollateExpr *) expr)->collOid;
914  break;
915  case T_CaseExpr:
916  coll = ((const CaseExpr *) expr)->casecollid;
917  break;
918  case T_CaseTestExpr:
919  coll = ((const CaseTestExpr *) expr)->collation;
920  break;
921  case T_ArrayExpr:
922  coll = ((const ArrayExpr *) expr)->array_collid;
923  break;
924  case T_RowExpr:
925  /* RowExpr's result is composite ... */
926  coll = InvalidOid; /* ... so it has no collation */
927  break;
928  case T_RowCompareExpr:
929  /* RowCompareExpr's result is boolean ... */
930  coll = InvalidOid; /* ... so it has no collation */
931  break;
932  case T_CoalesceExpr:
933  coll = ((const CoalesceExpr *) expr)->coalescecollid;
934  break;
935  case T_MinMaxExpr:
936  coll = ((const MinMaxExpr *) expr)->minmaxcollid;
937  break;
938  case T_SQLValueFunction:
939  /* Returns either NAME or a non-collatable type */
940  if (((const SQLValueFunction *) expr)->type == NAMEOID)
941  coll = C_COLLATION_OID;
942  else
943  coll = InvalidOid;
944  break;
945  case T_XmlExpr:
946 
947  /*
948  * XMLSERIALIZE returns text from non-collatable inputs, so its
949  * collation is always default. The other cases return boolean or
950  * XML, which are non-collatable.
951  */
952  if (((const XmlExpr *) expr)->op == IS_XMLSERIALIZE)
953  coll = DEFAULT_COLLATION_OID;
954  else
955  coll = InvalidOid;
956  break;
957  case T_NullTest:
958  /* NullTest's result is boolean ... */
959  coll = InvalidOid; /* ... so it has no collation */
960  break;
961  case T_BooleanTest:
962  /* BooleanTest's result is boolean ... */
963  coll = InvalidOid; /* ... so it has no collation */
964  break;
965  case T_CoerceToDomain:
966  coll = ((const CoerceToDomain *) expr)->resultcollid;
967  break;
969  coll = ((const CoerceToDomainValue *) expr)->collation;
970  break;
971  case T_SetToDefault:
972  coll = ((const SetToDefault *) expr)->collation;
973  break;
974  case T_CurrentOfExpr:
975  /* CurrentOfExpr's result is boolean ... */
976  coll = InvalidOid; /* ... so it has no collation */
977  break;
978  case T_NextValueExpr:
979  /* NextValueExpr's result is an integer type ... */
980  coll = InvalidOid; /* ... so it has no collation */
981  break;
982  case T_InferenceElem:
983  coll = exprCollation((Node *) ((const InferenceElem *) expr)->expr);
984  break;
985  case T_PlaceHolderVar:
986  coll = exprCollation((Node *) ((const PlaceHolderVar *) expr)->phexpr);
987  break;
988  case T_JsonValueExpr:
989  coll = exprCollation((Node *) ((const JsonValueExpr *) expr)->formatted_expr);
990  break;
992  {
993  const JsonConstructorExpr *ctor = (const JsonConstructorExpr *) expr;
994 
995  if (ctor->coercion)
996  coll = exprCollation((Node *) ctor->coercion);
997  else
998  coll = InvalidOid;
999  }
1000  break;
1001  case T_JsonIsPredicate:
1002  coll = InvalidOid; /* result is always an boolean type */
1003  break;
1004  case T_JsonExpr:
1005  {
1006  JsonExpr *jexpr = (JsonExpr *) expr;
1007  JsonCoercion *coercion = jexpr->result_coercion;
1008 
1009  if (!coercion)
1010  coll = InvalidOid;
1011  else if (coercion->expr)
1012  coll = exprCollation(coercion->expr);
1013  else if (coercion->via_io || coercion->via_populate)
1014  coll = coercion->collation;
1015  else
1016  coll = InvalidOid;
1017  }
1018  break;
1019  default:
1020  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
1021  coll = InvalidOid; /* keep compiler quiet */
1022  break;
1023  }
1024  return coll;
1025 }
#define ERROR
Definition: elog.h:33
#define elog(elevel,...)
Definition: elog.h:218
Assert(fmt[strlen(fmt) - 1] !='\n')
@ T_FieldStore
Definition: nodes.h:175
@ T_AlternativeSubPlan
Definition: nodes.h:173
@ T_CoalesceExpr
Definition: nodes.h:187
@ T_SubLink
Definition: nodes.h:171
@ T_InferenceElem
Definition: nodes.h:198
@ T_CoerceToDomainValue
Definition: nodes.h:194
@ T_FieldSelect
Definition: nodes.h:174
@ T_ArrayExpr
Definition: nodes.h:184
@ T_CollateExpr
Definition: nodes.h:180
@ T_BoolExpr
Definition: nodes.h:170
@ T_CaseExpr
Definition: nodes.h:181
@ T_RelabelType
Definition: nodes.h:176
@ T_XmlExpr
Definition: nodes.h:190
@ T_ConvertRowtypeExpr
Definition: nodes.h:179
@ T_JsonConstructorExpr
Definition: nodes.h:211
@ T_RowExpr
Definition: nodes.h:185
@ T_ArrayCoerceExpr
Definition: nodes.h:178
@ T_MinMaxExpr
Definition: nodes.h:188
@ T_CurrentOfExpr
Definition: nodes.h:196
@ T_BooleanTest
Definition: nodes.h:192
@ T_JsonIsPredicate
Definition: nodes.h:518
@ T_JsonValueExpr
Definition: nodes.h:207
@ T_SubPlan
Definition: nodes.h:172
@ T_SQLValueFunction
Definition: nodes.h:189
@ T_NamedArgExpr
Definition: nodes.h:165
@ T_Const
Definition: nodes.h:158
@ T_JsonExpr
Definition: nodes.h:212
@ T_NextValueExpr
Definition: nodes.h:197
@ T_Param
Definition: nodes.h:159
@ T_CoerceToDomain
Definition: nodes.h:193
@ T_GroupingFunc
Definition: nodes.h:161
@ T_Var
Definition: nodes.h:157
@ T_CaseTestExpr
Definition: nodes.h:183
@ T_NullTest
Definition: nodes.h:191
@ T_SubscriptingRef
Definition: nodes.h:163
@ T_SetToDefault
Definition: nodes.h:195
@ T_PlaceHolderVar
Definition: nodes.h:286
#define linitial_node(type, l)
Definition: pg_list.h:177
#define linitial(l)
Definition: pg_list.h:174
#define InvalidOid
Definition: postgres_ext.h:36
@ ARRAY_SUBLINK
Definition: primnodes.h:698
@ EXPR_SUBLINK
Definition: primnodes.h:696
@ IS_XMLSERIALIZE
Definition: primnodes.h:1221
Node * expr
Definition: primnodes.h:1420
bool via_populate
Definition: primnodes.h:1421
JsonCoercion * result_coercion
Definition: primnodes.h:1455
List * targetList
Definition: parsenodes.h:155
Oid firstColCollation
Definition: primnodes.h:767
SubLinkType subLinkType
Definition: primnodes.h:756
Definition: primnodes.h:196

References arg, ARRAY_SUBLINK, Assert(), JsonConstructorExpr::coercion, JsonCoercion::collation, elog, ERROR, JsonCoercion::expr, EXPR_SUBLINK, SubPlan::firstColCollation, if(), InvalidOid, IS_XMLSERIALIZE, IsA, linitial, linitial_node, nodeTag, JsonExpr::result_coercion, SubLink::subLinkType, SubPlan::subLinkType, AlternativeSubPlan::subplans, SubLink::subselect, T_Aggref, T_AlternativeSubPlan, T_ArrayCoerceExpr, T_ArrayExpr, T_BooleanTest, T_BoolExpr, T_CaseExpr, T_CaseTestExpr, T_CoalesceExpr, T_CoerceToDomain, T_CoerceToDomainValue, T_CoerceViaIO, T_CollateExpr, T_Const, T_ConvertRowtypeExpr, T_CurrentOfExpr, T_DistinctExpr, T_FieldSelect, T_FieldStore, T_FuncExpr, T_GroupingFunc, T_InferenceElem, T_JsonConstructorExpr, T_JsonExpr, T_JsonIsPredicate, T_JsonValueExpr, T_MinMaxExpr, T_NamedArgExpr, T_NextValueExpr, T_NullIfExpr, T_NullTest, T_OpExpr, T_Param, T_PlaceHolderVar, T_RelabelType, T_RowCompareExpr, T_RowExpr, T_ScalarArrayOpExpr, T_SetToDefault, T_SQLValueFunction, T_SubLink, T_SubPlan, T_SubscriptingRef, T_Var, T_WindowFunc, T_XmlExpr, Query::targetList, generate_unaccent_rules::type, JsonCoercion::via_io, and JsonCoercion::via_populate.

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(), 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(), expr_allowed_in_node(), 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(), makeCaseTestExpr(), 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()

bool expression_returns_set ( Node clause)

◆ expression_returns_set_walker()

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

Definition at line 742 of file nodeFuncs.c.

743 {
744  if (node == NULL)
745  return false;
746  if (IsA(node, FuncExpr))
747  {
748  FuncExpr *expr = (FuncExpr *) node;
749 
750  if (expr->funcretset)
751  return true;
752  /* else fall through to check args */
753  }
754  if (IsA(node, OpExpr))
755  {
756  OpExpr *expr = (OpExpr *) node;
757 
758  if (expr->opretset)
759  return true;
760  /* else fall through to check args */
761  }
762 
763  /* Avoid recursion for some cases that parser checks not to return a set */
764  if (IsA(node, Aggref))
765  return false;
766  if (IsA(node, GroupingFunc))
767  return false;
768  if (IsA(node, WindowFunc))
769  return false;
770 
772  context);
773 }
bool expression_tree_walker(Node *node, bool(*walker)(), void *context)
Definition: nodeFuncs.c:2015
bool funcretset
Definition: primnodes.h:506
bool opretset
Definition: primnodes.h:554

References expression_tree_walker(), FuncExpr::funcretset, IsA, and OpExpr::opretset.

Referenced by expression_returns_set().

◆ expression_tree_mutator()

Node* expression_tree_mutator ( Node node,
Node *(*)()  mutator,
void *  context 
)

Definition at line 2815 of file nodeFuncs.c.

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

References generate_unaccent_rules::action, Aggref::aggargtypes, 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, GroupingFunc::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, JsonItemCoercions::boolean, check_stack_depth(), JsonConstructorExpr::coercion, TableFunc::coldefexprs, TableFunc::colexprs, GroupingFunc::cols, TableFunc::colvalexprs, JsonItemCoercions::composite, copyObject, CommonTableExpr::ctequery, CommonTableExpr::cycle_clause, CTECycleClause::cycle_mark_default, CTECycleClause::cycle_mark_value, JsonItemCoercions::date, JsonBehavior::default_expr, CaseExpr::defresult, TableFunc::docexpr, ArrayExpr::elements, ArrayCoerceExpr::elemexpr, elog, WindowClause::endOffset, ERROR, OnConflictExpr::exclRelTlist, CaseWhen::expr, JsonIsPredicate::expr, JsonCoercion::expr, InferenceElem::expr, TargetEntry::expr, PartitionPruneStepOp::exprs, FieldStore::fieldnums, FLATCOPY, JsonReturning::format, JsonValueExpr::format, JsonValueExpr::formatted_expr, JsonExpr::formatted_expr, FromExpr::fromlist, JsonConstructorExpr::func, RangeTblFunction::funcexpr, IndexClause::indexquals, lappend(), SetOperationStmt::larg, JoinExpr::larg, RowCompareExpr::largs, lfirst, list_copy(), PartitionBoundSpec::listdatums, PartitionBoundSpec::lowerdatums, MUTATE, XmlExpr::named_args, FieldStore::newvals, NIL, nodeTag, TableFunc::ns_uris, JsonItemCoercions::null, JsonItemCoercions::numeric, JsonExpr::on_empty, JsonExpr::on_error, OnConflictExpr::onConflictSet, OnConflictExpr::onConflictWhere, WindowClause::orderClause, WindowClause::partitionClause, JsonExpr::passing_values, JsonExpr::path_spec, PlaceHolderInfo::ph_var, PlaceHolderVar::phexpr, WithCheckOption::qual, MergeAction::qual, JoinExpr::quals, FromExpr::quals, SetOperationStmt::rarg, JoinExpr::rarg, RowCompareExpr::rargs, JsonValueExpr::raw_expr, SubscriptingRef::refassgnexpr, SubscriptingRef::refexpr, SubscriptingRef::reflowerindexpr, GroupingFunc::refs, SubscriptingRef::refupperindexpr, TableSampleClause::repeatable, CaseWhen::result, JsonExpr::result_coercion, JsonConstructorExpr::returning, IndexClause::rinfo, TableFunc::rowexpr, CommonTableExpr::search_clause, WindowClause::startOffset, JsonItemCoercions::string, AlternativeSubPlan::subplans, SubLink::subselect, T_Aggref, T_AlternativeSubPlan, T_AppendRelInfo, T_ArrayCoerceExpr, T_ArrayExpr, T_BooleanTest, T_BoolExpr, T_CaseExpr, T_CaseTestExpr, T_CaseWhen, T_CoalesceExpr, T_CoerceToDomain, T_CoerceToDomainValue, T_CoerceViaIO, T_CollateExpr, T_CommonTableExpr, T_Const, T_ConvertRowtypeExpr, T_CTECycleClause, T_CTESearchClause, T_CurrentOfExpr, T_DistinctExpr, T_FieldSelect, T_FieldStore, T_FromExpr, T_FuncExpr, T_GroupingFunc, T_IndexClause, T_InferenceElem, T_JoinExpr, T_JsonCoercion, T_JsonConstructorExpr, T_JsonExpr, T_JsonFormat, T_JsonIsPredicate, T_JsonItemCoercions, T_JsonReturning, T_JsonValueExpr, T_List, T_MergeAction, T_MinMaxExpr, T_NamedArgExpr, T_NextValueExpr, T_NullIfExpr, T_NullTest, T_OnConflictExpr, T_OpExpr, T_Param, T_PartitionBoundSpec, T_PartitionPruneStepCombine, T_PartitionPruneStepOp, T_PartitionRangeDatum, T_PlaceHolderInfo, T_PlaceHolderVar, T_Query, T_RangeTblFunction, T_RangeTblRef, T_RelabelType, T_RowCompareExpr, T_RowExpr, T_ScalarArrayOpExpr, T_SetOperationStmt, T_SetToDefault, T_SortGroupClause, T_SQLValueFunction, T_SubLink, T_SubPlan, T_SubscriptingRef, T_TableFunc, T_TableSampleClause, T_TargetEntry, T_Var, T_WindowClause, T_WindowFunc, T_WithCheckOption, T_XmlExpr, MergeAction::targetList, SubLink::testexpr, SubPlan::testexpr, JsonItemCoercions::time, JsonItemCoercions::timestamp, JsonItemCoercions::timestamptz, JsonItemCoercions::timetz, AppendRelInfo::translated_vars, PartitionBoundSpec::upperdatums, and PartitionRangeDatum::value.

Referenced by adjust_appendrel_attrs_mutator(), convert_combining_aggrefs(), convert_testexpr_mutator(), eval_const_expressions_mutator(), fix_join_expr_mutator(), fix_scan_expr_mutator(), fix_upper_expr_mutator(), fix_windowagg_condition_expr_mutator(), flatten_join_alias_vars_mutator(), map_variable_attnos_mutator(), process_sublinks_mutator(), replace_correlation_vars_mutator(), replace_nestloop_params_mutator(), replace_rte_variables_mutator(), simplify_function(), substitute_actual_parameters_mutator(), and substitute_actual_srf_parameters_mutator().

◆ expression_tree_walker()

bool expression_tree_walker ( Node node,
bool(*)()  walker,
void *  context 
)

Definition at line 2015 of file nodeFuncs.c.

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

References generate_unaccent_rules::action, Aggref::aggdirectargs, Aggref::aggdistinct, Aggref::aggfilter, WindowFunc::aggfilter, Aggref::aggorder, OnConflictExpr::arbiterElems, OnConflictExpr::arbiterWhere, arg, FieldStore::arg, ArrayCoerceExpr::arg, CaseExpr::arg, generate_unaccent_rules::args, TableSampleClause::args, Aggref::args, GroupingFunc::args, WindowFunc::args, FuncExpr::args, OpExpr::args, ScalarArrayOpExpr::args, BoolExpr::args, SubPlan::args, CaseExpr::args, XmlExpr::args, JsonConstructorExpr::args, JsonItemCoercions::boolean, check_stack_depth(), JsonConstructorExpr::coercion, JsonExpr::coercions, TableFunc::coldefexprs, TableFunc::colexprs, TableFunc::colvalexprs, JsonItemCoercions::composite, CommonTableExpr::ctequery, CommonTableExpr::cycle_clause, CTECycleClause::cycle_mark_default, CTECycleClause::cycle_mark_value, JsonItemCoercions::date, JsonBehavior::default_expr, CaseExpr::defresult, TableFunc::docexpr, ArrayCoerceExpr::elemexpr, elog, WindowClause::endOffset, ERROR, OnConflictExpr::exclRelTlist, PartitionPruneStepOp::exprs, JsonValueExpr::formatted_expr, JsonExpr::formatted_expr, FromExpr::fromlist, JsonConstructorExpr::func, IndexClause::indexquals, SetOperationStmt::larg, JoinExpr::larg, RowCompareExpr::largs, lfirst, lfirst_node, PartitionBoundSpec::listdatums, PartitionBoundSpec::lowerdatums, XmlExpr::named_args, FieldStore::newvals, nodeTag, TableFunc::ns_uris, JsonItemCoercions::null, JsonItemCoercions::numeric, JsonExpr::on_empty, JsonExpr::on_error, OnConflictExpr::onConflictSet, OnConflictExpr::onConflictWhere, WindowClause::orderClause, WindowClause::partitionClause, JsonExpr::passing_values, JoinExpr::quals, FromExpr::quals, SetOperationStmt::rarg, JoinExpr::rarg, RowCompareExpr::rargs, JsonValueExpr::raw_expr, SubscriptingRef::refassgnexpr, SubscriptingRef::refexpr, SubscriptingRef::reflowerindexpr, SubscriptingRef::refupperindexpr, TableSampleClause::repeatable, JsonExpr::result_coercion, IndexClause::rinfo, TableFunc::rowexpr, CommonTableExpr::search_clause, WindowClause::startOffset, JsonItemCoercions::string, SubLink::subselect, T_Aggref, T_AlternativeSubPlan, T_AppendRelInfo, T_ArrayCoerceExpr, T_ArrayExpr, T_BooleanTest, T_BoolExpr, T_CaseExpr, T_CaseTestExpr, T_CoalesceExpr, T_CoerceToDomain, T_CoerceToDomainValue, T_CoerceViaIO, T_CollateExpr, T_CommonTableExpr, T_Const, T_ConvertRowtypeExpr, T_CTECycleClause, T_CTESearchClause, T_CurrentOfExpr, T_DistinctExpr, T_FieldSelect, T_FieldStore, T_FromExpr, T_FuncExpr, T_GroupingFunc, T_IndexClause, T_InferenceElem, T_JoinExpr, T_JsonCoercion, T_JsonConstructorExpr, T_JsonExpr, T_JsonIsPredicate, T_JsonItemCoercions, T_JsonValueExpr, T_List, T_MergeAction, T_MinMaxExpr, T_NamedArgExpr, T_NextValueExpr, T_NullIfExpr, T_NullTest, T_OnConflictExpr, T_OpExpr, T_Param, T_PartitionBoundSpec, T_PartitionPruneStepCombine, T_PartitionPruneStepOp, T_PartitionRangeDatum, T_PlaceHolderInfo, T_PlaceHolderVar, T_Query, T_RangeTblFunction, T_RangeTblRef, T_RelabelType, T_RowCompareExpr, T_RowExpr, T_ScalarArrayOpExpr, T_SetOperationStmt, T_SetToDefault, T_SortGroupClause, T_SQLValueFunction, T_SubLink, T_SubPlan, T_SubscriptingRef, T_TableFunc, T_TableSampleClause, T_TargetEntry, T_Var, T_WindowClause, T_WindowFunc, T_WithCheckOption, T_XmlExpr, SubLink::testexpr, SubPlan::testexpr, JsonItemCoercions::time, JsonItemCoercions::timestamp, JsonItemCoercions::timestamptz, JsonItemCoercions::timetz, AppendRelInfo::translated_vars, PartitionBoundSpec::upperdatums, and PartitionRangeDatum::value.

Referenced by acquireLocksOnSubLinks(), assign_collations_walker(), ChangeVarNodes_walker(), check_agg_arguments_walker(), check_nested_generated_walker(), check_parameter_resolution_walker(), check_simple_rowfilter_expr_walker(), check_ungrouped_columns_walker(), checkExprHasSubLink_walker(), contain_agg_clause_walker(), contain_aggs_of_level_walker(), contain_context_dependent_node_walker(), contain_dml_walker(), contain_exec_param_walker(), contain_invalid_rfcolumn_walker(), contain_leaked_vars_walker(), contain_mutable_functions_walker(), contain_non_const_walker(), contain_nonstrict_functions_walker(), contain_outer_selfref_walker(), contain_subplans_walker(), contain_var_clause_walker(), contain_vars_of_level_walker(), contain_volatile_functions_not_nextval_walker(), contain_volatile_functions_walker(), contain_windowfuncs_walker(), contains_multiexpr_param(), convert_saop_to_hashed_saop_walker(), cost_qual_eval_walker(), expression_returns_set_walker(), extract_query_dependencies_walker(), finalize_agg_primnode(), finalize_grouping_exprs_walker(), finalize_primnode(), find_cols_walker(), find_dependent_phvs_walker(), find_expr_references_walker(), find_window_functions_walker(), fireRIRonSubLink(), fireRIRrules(), fix_opfuncids_walker(), fix_scan_expr_walker(), flatten_rtes_walker(), get_last_attnums_walker(), IncrementVarSublevelsUp_walker(), index_expression_changed_walker(), inline_cte_walker(), isQueryUsingTempRelation_walker(), locate_agg_of_level_walker(), locate_var_of_level_walker(), locate_windowfunc_walker(), LockViewRecurse_walker(), max_parallel_hazard_walker(), OffsetVarNodes_walker(), preprocess_aggrefs_walker(), pull_exec_paramids_walker(), pull_paramids_walker(), pull_var_clause_walker(), pull_varattnos_walker(), pull_varnos_walker(), pull_vars_walker(), query_contains_extern_params_walker(), rangeTableEntry_used_walker(), ScanQueryWalker(), setRuleCheckAsUser_walker(), split_pathtarget_walker(), and substitute_phv_relids_walker().

◆ exprInputCollation()

Oid exprInputCollation ( const Node expr)

Definition at line 1034 of file nodeFuncs.c.

1035 {
1036  Oid coll;
1037 
1038  if (!expr)
1039  return InvalidOid;
1040 
1041  switch (nodeTag(expr))
1042  {
1043  case T_Aggref:
1044  coll = ((const Aggref *) expr)->inputcollid;
1045  break;
1046  case T_WindowFunc:
1047  coll = ((const WindowFunc *) expr)->inputcollid;
1048  break;
1049  case T_FuncExpr:
1050  coll = ((const FuncExpr *) expr)->inputcollid;
1051  break;
1052  case T_OpExpr:
1053  coll = ((const OpExpr *) expr)->inputcollid;
1054  break;
1055  case T_DistinctExpr:
1056  coll = ((const DistinctExpr *) expr)->inputcollid;
1057  break;
1058  case T_NullIfExpr:
1059  coll = ((const NullIfExpr *) expr)->inputcollid;
1060  break;
1061  case T_ScalarArrayOpExpr:
1062  coll = ((const ScalarArrayOpExpr *) expr)->inputcollid;
1063  break;
1064  case T_MinMaxExpr:
1065  coll = ((const MinMaxExpr *) expr)->inputcollid;
1066  break;
1067  default:
1068  coll = InvalidOid;
1069  break;
1070  }
1071  return coll;
1072 }

References InvalidOid, nodeTag, T_Aggref, T_DistinctExpr, T_FuncExpr, T_MinMaxExpr, T_NullIfExpr, T_OpExpr, T_ScalarArrayOpExpr, and T_WindowFunc.

Referenced by expr_allowed_in_node(), and resolve_polymorphic_tupdesc().

◆ exprIsLengthCoercion()

bool exprIsLengthCoercion ( const Node expr,
int32 coercedTypmod 
)

Definition at line 530 of file nodeFuncs.c.

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

References FuncExpr::args, COERCE_EXPLICIT_CAST, COERCE_IMPLICIT_CAST, Const::constisnull, Const::consttype, Const::constvalue, DatumGetInt32, FuncExpr::funcformat, IsA, list_length(), lsecond, and ArrayCoerceExpr::resulttypmod.

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

◆ exprLocation()

int exprLocation ( const Node expr)

Definition at line 1343 of file nodeFuncs.c.

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

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(), JsonExpr::formatted_expr, leftmostLoc(), A_Expr::lexpr, lfirst, TypeName::location, A_Expr::location, TypeCast::location, FuncExpr::location, NamedArgExpr::location, OpExpr::location, ScalarArrayOpExpr::location, BoolExpr::location, SubLink::location, RelabelType::location, CoerceViaIO::location, ArrayCoerceExpr::location, ConvertRowtypeExpr::location, XmlExpr::location, JsonExpr::location, NullTest::location, BooleanTest::location, CoerceToDomain::location, nodeTag, source, T_A_ArrayExpr, T_A_Const, T_A_Expr, T_Aggref, T_ArrayCoerceExpr, T_ArrayExpr, T_BooleanTest, T_BoolExpr, T_CaseExpr, T_CaseWhen, T_CoalesceExpr, T_CoerceToDomain, T_CoerceToDomainValue, T_CoerceViaIO, T_CollateClause, T_CollateExpr, T_ColumnDef, T_ColumnRef, T_CommonTableExpr, T_Const, T_Constraint, T_ConvertRowtypeExpr, T_CTECycleClause, T_CTESearchClause, T_DistinctExpr, T_FieldSelect, T_FieldStore, T_FuncCall, T_FuncExpr, T_FunctionParameter, T_GroupingFunc, T_GroupingSet, T_InferClause, T_InferenceElem, T_IntoClause, T_JsonConstructorExpr, T_JsonExpr, T_JsonIsPredicate, T_JsonValueExpr, T_List, T_MinMaxExpr, T_MultiAssignRef, T_NamedArgExpr, T_NullIfExpr, T_NullTest, T_OnConflictClause, T_OpExpr, T_Param, T_ParamRef, T_PartitionBoundSpec, T_PartitionElem, T_PartitionRangeDatum, T_PartitionSpec, T_PlaceHolderVar, T_RangeTableSample, T_RangeVar, T_RelabelType, T_ResTarget, T_RowCompareExpr, T_RowExpr, T_ScalarArrayOpExpr, T_SetToDefault, T_SortBy, T_SQLValueFunction, T_SubLink, T_SubscriptingRef, T_TableFunc, T_TargetEntry, T_TypeCast, T_TypeName, T_Var, T_WindowDef, T_WindowFunc, T_WithClause, T_XmlExpr, T_XmlSerialize, SubLink::testexpr, and TypeCast::typeName.

Referenced by addRangeTableEntryForFunction(), 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(), coerceDefaultJsonExpr(), 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(), transformJsonExprCommon(), transformJsonFuncExpr(), transformJsonParseArg(), transformJsonTable(), transformJsonValueExprExt(), transformMultiAssignRef(), transformOnConflictArbiter(), transformPartitionBound(), transformPartitionBoundValue(), transformPartitionRangeBounds(), transformPLAssignStmt(), transformRangeFunction(), transformReturningList(), transformSelectStmt(), transformSetOperationStmt(), transformSetOperationTree(), transformValuesClause(), and validateInfiniteBounds().

◆ exprSetCollation()

void exprSetCollation ( Node expr,
Oid  collation 
)

Definition at line 1082 of file nodeFuncs.c.

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

References arg, ARRAY_SUBLINK, Assert(), JsonConstructorExpr::coercion, JsonCoercion::collation, elog, ERROR, JsonCoercion::expr, EXPR_SUBLINK, exprCollation(), if(), InvalidOid, IS_XMLSERIALIZE, IsA, linitial_node, nodeTag, OidIsValid, JsonExpr::result_coercion, SubLink::subLinkType, SubLink::subselect, T_Aggref, T_ArrayCoerceExpr, T_ArrayExpr, T_BooleanTest, T_BoolExpr, T_CaseExpr, T_CoalesceExpr, T_CoerceToDomain, T_CoerceToDomainValue, T_CoerceViaIO, T_Const, T_ConvertRowtypeExpr, T_CurrentOfExpr, T_DistinctExpr, T_FieldSelect, T_FieldStore, T_FuncExpr, T_GroupingFunc, T_JsonConstructorExpr, T_JsonExpr, T_JsonIsPredicate, T_JsonValueExpr, T_MinMaxExpr, T_NamedArgExpr, T_NextValueExpr, T_NullIfExpr, T_NullTest, T_OpExpr, T_Param, T_RelabelType, T_RowCompareExpr, T_RowExpr, T_ScalarArrayOpExpr, T_SetToDefault, T_SQLValueFunction, T_SubLink, T_SubscriptingRef, T_Var, T_WindowFunc, T_XmlExpr, Query::targetList, generate_unaccent_rules::type, JsonCoercion::via_io, and JsonCoercion::via_populate.

Referenced by assign_collations_walker().

◆ exprSetInputCollation()

void exprSetInputCollation ( Node expr,
Oid  inputcollation 
)

Definition at line 1279 of file nodeFuncs.c.

1280 {
1281  switch (nodeTag(expr))
1282  {
1283  case T_Aggref:
1284  ((Aggref *) expr)->inputcollid = inputcollation;
1285  break;
1286  case T_WindowFunc:
1287  ((WindowFunc *) expr)->inputcollid = inputcollation;
1288  break;
1289  case T_FuncExpr:
1290  ((FuncExpr *) expr)->inputcollid = inputcollation;
1291  break;
1292  case T_OpExpr:
1293  ((OpExpr *) expr)->inputcollid = inputcollation;
1294  break;
1295  case T_DistinctExpr:
1296  ((DistinctExpr *) expr)->inputcollid = inputcollation;
1297  break;
1298  case T_NullIfExpr:
1299  ((NullIfExpr *) expr)->inputcollid = inputcollation;
1300  break;
1301  case T_ScalarArrayOpExpr:
1302  ((ScalarArrayOpExpr *) expr)->inputcollid = inputcollation;
1303  break;
1304  case T_MinMaxExpr:
1305  ((MinMaxExpr *) expr)->inputcollid = inputcollation;
1306  break;
1307  default:
1308  break;
1309  }
1310 }

References nodeTag, T_Aggref, T_DistinctExpr, T_FuncExpr, T_MinMaxExpr, T_NullIfExpr, T_OpExpr, T_ScalarArrayOpExpr, and T_WindowFunc.

Referenced by assign_collations_walker().

◆ exprType()

Oid exprType ( const Node expr)

Definition at line 41 of file nodeFuncs.c.

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

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, JsonValueExpr::raw_expr, SubLink::subLinkType, SubPlan::subLinkType, AlternativeSubPlan::subplans, SubLink::subselect, T_Aggref, T_AlternativeSubPlan, T_ArrayCoerceExpr, T_ArrayExpr, T_BooleanTest, T_BoolExpr, T_CaseExpr, T_CaseTestExpr, T_CoalesceExpr, T_CoerceToDomain, T_CoerceToDomainValue, T_CoerceViaIO, T_CollateExpr, T_Const, T_ConvertRowtypeExpr, T_CurrentOfExpr, T_DistinctExpr, T_FieldSelect, T_FieldStore, T_FuncExpr, T_GroupingFunc, T_InferenceElem, T_JsonCoercion, T_JsonConstructorExpr, T_JsonExpr, T_JsonIsPredicate, T_JsonValueExpr, T_MinMaxExpr, T_NamedArgExpr, T_NextValueExpr, T_NullIfExpr, T_NullTest, T_OpExpr, T_Param, T_PlaceHolderVar, T_RelabelType, T_RowCompareExpr, T_RowExpr, T_ScalarArrayOpExpr, T_SetToDefault, T_SQLValueFunction, T_SubLink, T_SubPlan, T_SubscriptingRef, T_Var, T_WindowFunc, T_XmlExpr, Query::targetList, and generate_unaccent_rules::type.

Referenced by add_row_identity_var(), addRangeTableEntryForFunction(), addRangeTableEntryForSubquery(), addTargetToGroupList(), addTargetToSortList(), analyzeCTE(), analyzeCTETargetList(), appendAggOrderBy(), appendJsonTableColumns(), appendOrderByClause(), applyRelabelType(), array_subscript_transform(), assign_collations_walker(), assign_hypothetical_collations(), assign_param_for_placeholdervar(), assignDefaultJsonReturningType(), 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_sql_fn_retval(), checkRuleResultList(), coerce_fn_result_column(), coerce_record_to_complex(), coerce_to_boolean(), coerce_to_common_type(), coerce_to_specific_type_typmod(), coerceDefaultJsonExpr(), 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_incremental(), 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(), expr_allowed_in_node(), 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_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_width_cost_multiplier(), get_windowfunc_expr_helper(), GetIndexInputType(), hash_ok_operator(), hstore_subscript_transform(), initialize_peragg(), inline_function(), internal_get_result_type(), jsonb_exec_setup(), jsonb_subscript_transform(), JsonTableInitOpaque(), jspIsMutableWalker(), make_op(), make_scalar_array_op(), makeCaseTestExpr(), 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_placeholdervar(), resolveTargetListUnknowns(), scalararraysel(), select_common_type(), select_common_typmod(), set_append_rel_size(), set_dummy_tlist_references(), set_joinrel_partition_key_exprs(), set_pathtarget_cost_width(), set_rel_width(), show_sortorder_options(), tlist_same_datatypes(), transformAExprNullIf(), transformAggregateCall(), transformArrayExpr(), transformAssignedExpr(), transformAssignmentIndirection(), transformAssignmentSubscripts(), transformCaseExpr(), transformCollateClause(), transformExprRecurse(), transformFrameOffset(), transformFromClauseItem(), transformIndirection(), transformInsertStmt(), transformJsonConstructorOutput(), transformJsonExprCommon(), transformJsonFuncExpr(), transformJsonParseArg(), transformJsonScalarExpr(), transformJsonTable(), transformJsonValueExprExt(), transformMultiAssignRef(), transformPartitionBoundValue(), transformPLAssignStmt(), transformSetOperationTree(), transformSubLink(), transformTypeCast(), unknown_attribute(), verify_common_type(), and xmlelement().

◆ exprTypmod()

int32 exprTypmod ( const Node expr)

Definition at line 286 of file nodeFuncs.c.

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

References arg, OpExpr::args, CaseExpr::args, CoalesceExpr::args, MinMaxExpr::args, ARRAY_SUBLINK, ArrayExpr::array_typeid, Assert(), CaseExpr::casetype, CoalesceExpr::coalescetype, CaseExpr::defresult, ArrayExpr::element_typeid, ArrayExpr::elements, elog, ERROR, EXPR_SUBLINK, exprIsLengthCoercion(), exprType(), SubPlan::firstColTypmod, for_each_from, if(), IsA, lfirst, lfirst_node, linitial, linitial_node, MinMaxExpr::minmaxtype, ArrayExpr::multidims, NIL, nodeTag, CaseWhen::result, SubLink::subLinkType, SubPlan::subLinkType, AlternativeSubPlan::subplans, SubLink::subselect, T_AlternativeSubPlan, T_ArrayCoerceExpr, T_ArrayExpr, T_CaseExpr, T_CaseTestExpr, T_CoalesceExpr, T_CoerceToDomain, T_CoerceToDomainValue, T_CollateExpr, T_Const, T_FieldSelect, T_FuncExpr, T_JsonCoercion, T_JsonConstructorExpr, T_JsonExpr, T_JsonValueExpr, T_MinMaxExpr, T_NamedArgExpr, T_NullIfExpr, T_Param, T_PlaceHolderVar, T_RelabelType, T_SetToDefault, T_SQLValueFunction, T_SubLink, T_SubPlan, T_SubscriptingRef, T_Var, and Query::targetList.

Referenced by add_row_identity_var(), addRangeTableEntryForFunction(), addRangeTableEntryForSubquery(), analyzeCTE(), analyzeCTETargetList(), appendJsonTableColumns(), 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(), ExecInitExprRec(), ExecTypeFromExprList(), ExecTypeFromTLInternal(), expandRecordVariable(), expandRTE(), find_placeholder_info(), generate_append_tlist(), generate_setop_tlist(), generate_subquery_params(), get_expr_result_type(), get_first_col_type(), get_rule_expr(), get_rule_expr_funccall(), get_width_cost_multiplier(), interval_support(), JsonTableInitOpaque(), makeCaseTestExpr(), 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_pathtarget_cost_width(), 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 1763 of file nodeFuncs.c.

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

References fix_opfuncids_walker().

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

◆ fix_opfuncids_walker()

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

Definition at line 1770 of file nodeFuncs.c.

1771 {
1772  if (node == NULL)
1773  return false;
1774  if (IsA(node, OpExpr))
1775  set_opfuncid((OpExpr *) node);
1776  else if (IsA(node, DistinctExpr))
1777  set_opfuncid((OpExpr *) node); /* rely on struct equivalence */
1778  else if (IsA(node, NullIfExpr))
1779  set_opfuncid((OpExpr *) node); /* rely on struct equivalence */
1780  else if (IsA(node, ScalarArrayOpExpr))
1782  return expression_tree_walker(node, fix_opfuncids_walker, context);
1783 }

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

Referenced by fix_opfuncids().

◆ leftmostLoc()

static int leftmostLoc ( int  loc1,
int  loc2 
)
static

Definition at line 1742 of file nodeFuncs.c.

1743 {
1744  if (loc1 < 0)
1745  return loc2;
1746  else if (loc2 < 0)
1747  return loc1;
1748  else
1749  return Min(loc1, loc2);
1750 }
#define Min(x, y)
Definition: c.h:997

References Min.

Referenced by exprLocation().

◆ planstate_tree_walker()

bool planstate_tree_walker ( PlanState planstate,
bool(*)()  walker,
void *  context 
)

Definition at line 4568 of file nodeFuncs.c.

4571 {
4572  Plan *plan = planstate->plan;
4573  ListCell *lc;
4574 
4575  /* Guard against stack overflow due to overly complex plan trees */
4577 
4578  /* initPlan-s */
4579  if (planstate_walk_subplans(planstate->initPlan, walker, context))
4580  return true;
4581 
4582  /* lefttree */
4583  if (outerPlanState(planstate))
4584  {
4585  if (walker(outerPlanState(planstate), context))
4586  return true;
4587  }
4588 
4589  /* righttree */
4590  if (innerPlanState(planstate))
4591  {
4592  if (walker(innerPlanState(planstate), context))
4593  return true;
4594  }
4595 
4596  /* special child plans */
4597  switch (nodeTag(plan))
4598  {
4599  case T_Append:
4600  if (planstate_walk_members(((AppendState *) planstate)->appendplans,
4601  ((AppendState *) planstate)->as_nplans,
4602  walker, context))
4603  return true;
4604  break;
4605  case T_MergeAppend:
4606  if (planstate_walk_members(((MergeAppendState *) planstate)->mergeplans,
4607  ((MergeAppendState *) planstate)->ms_nplans,
4608  walker, context))
4609  return true;
4610  break;
4611  case T_BitmapAnd:
4612  if (planstate_walk_members(((BitmapAndState *) planstate)->bitmapplans,
4613  ((BitmapAndState *) planstate)->nplans,
4614  walker, context))
4615  return true;
4616  break;
4617  case T_BitmapOr:
4618  if (planstate_walk_members(((BitmapOrState *) planstate)->bitmapplans,
4619  ((BitmapOrState *) planstate)->nplans,
4620  walker, context))
4621  return true;
4622  break;
4623  case T_SubqueryScan:
4624  if (walker(((SubqueryScanState *) planstate)->subplan, context))
4625  return true;
4626  break;
4627  case T_CustomScan:
4628  foreach(lc, ((CustomScanState *) planstate)->custom_ps)
4629  {
4630  if (walker((PlanState *) lfirst(lc), context))
4631  return true;
4632  }
4633  break;
4634  default:
4635  break;
4636  }
4637 
4638  /* subPlan-s */
4639  if (planstate_walk_subplans(planstate->subPlan, walker, context))
4640  return true;
4641 
4642  return false;
4643 }
#define outerPlanState(node)
Definition: execnodes.h:1094
#define innerPlanState(node)
Definition: execnodes.h:1093
static bool planstate_walk_subplans(List *plans, bool(*walker)(), void *context)
Definition: nodeFuncs.c:4649
static bool planstate_walk_members(PlanState **planstates, int nplans, bool(*walker)(), void *context)
Definition: nodeFuncs.c:4671
@ T_BitmapOr
Definition: nodes.h:54
@ T_Append
Definition: nodes.h:50
@ T_BitmapAnd
Definition: nodes.h:53
@ T_MergeAppend
Definition: nodes.h:51
@ T_CustomScan
Definition: nodes.h:72
@ T_SubqueryScan
Definition: nodes.h:64
Plan * plan
Definition: execnodes.h:998
List * initPlan
Definition: execnodes.h:1023

References check_stack_depth(), PlanState::initPlan, innerPlanState, lfirst, nodeTag, outerPlanState, PlanState::plan, planstate_walk_members(), planstate_walk_subplans(), PlanState::subPlan, T_Append, T_BitmapAnd, T_BitmapOr, T_CustomScan, T_MergeAppend, and T_SubqueryScan.

Referenced by ExecParallelEstimate(), ExecParallelInitializeDSM(), ExecParallelInitializeWorker(), ExecParallelReInitializeDSM(), ExecParallelReportInstrumentation(), ExecParallelRetrieveInstrumentation(), ExecShutdownNode(), and ExplainPreScanNode().

◆ planstate_walk_members()

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

Definition at line 4671 of file nodeFuncs.c.

4673 {
4674  int j;
4675 
4676  for (j = 0; j < nplans; j++)
4677  {
4678  if (walker(planstates[j], context))
4679  return true;
4680  }
4681 
4682  return false;
4683 }
int j
Definition: isn.c:74

References j.

Referenced by planstate_tree_walker().

◆ planstate_walk_subplans()

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

Definition at line 4649 of file nodeFuncs.c.

4652 {
4653  ListCell *lc;
4654 
4655  foreach(lc, plans)
4656  {
4658 
4659  if (walker(sps->planstate, context))
4660  return true;
4661  }
4662 
4663  return false;
4664 }
struct PlanState * planstate
Definition: execnodes.h:916

References lfirst_node, and SubPlanState::planstate.

Referenced by planstate_tree_walker().

◆ query_or_expression_tree_mutator()

Node* query_or_expression_tree_mutator ( Node node,
Node *(*)()  mutator,
void *  context,
int  flags 
)

Definition at line 3825 of file nodeFuncs.c.

3829 {
3830  if (node && IsA(node, Query))
3831  return (Node *) query_tree_mutator((Query *) node,
3832  mutator,
3833  context,
3834  flags);
3835  else
3836  return mutator(node, context);
3837 }
Query * query_tree_mutator(Query *query, Node *(*mutator)(), void *context, int flags)
Definition: nodeFuncs.c:3643

References IsA, and query_tree_mutator().

Referenced by map_variable_attnos(), and replace_rte_variables().

◆ query_or_expression_tree_walker()

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

Definition at line 3802 of file nodeFuncs.c.

3806 {
3807  if (node && IsA(node, Query))
3808  return query_tree_walker((Query *) node,
3809  walker,
3810  context,
3811  flags);
3812  else
3813  return walker(node, context);
3814 }
bool query_tree_walker(Query *query, bool(*walker)(), void *context, int flags)
Definition: nodeFuncs.c:2570

References IsA, and query_tree_walker().

Referenced by checkExprHasSubLink(), contain_aggs_of_level(), contain_vars_of_level(), contain_windowfuncs(), IncrementVarSublevelsUp(), locate_agg_of_level(), locate_var_of_level(), locate_windowfunc(), pull_varnos(), pull_varnos_of_level(), pull_vars_of_level(), rangeTableEntry_used(), and substitute_phv_relids().

◆ query_tree_mutator()

Query* query_tree_mutator ( Query query,
Node *(*)()  mutator,
void *  context,
int  flags 
)

Definition at line 3643 of file nodeFuncs.c.

3647 {
3648  Assert(query != NULL && IsA(query, Query));
3649 
3650  if (!(flags & QTW_DONT_COPY_QUERY))
3651  {
3652  Query *newquery;
3653 
3654  FLATCOPY(newquery, query, Query);
3655  query = newquery;
3656  }
3657 
3658  MUTATE(query->targetList, query->targetList, List *);
3659  MUTATE(query->withCheckOptions, query->withCheckOptions, List *);
3660  MUTATE(query->onConflict, query->onConflict, OnConflictExpr *);
3661  MUTATE(query->mergeActionList, query->mergeActionList, List *);
3662  MUTATE(query->returningList, query->returningList, List *);
3663  MUTATE(query->jointree, query->jointree, FromExpr *);
3664  MUTATE(query->setOperations, query->setOperations, Node *);
3665  MUTATE(query->havingQual, query->havingQual, Node *);
3666  MUTATE(query->limitOffset, query->limitOffset, Node *);
3667  MUTATE(query->limitCount, query->limitCount, Node *);
3668 
3669  /*
3670  * Most callers aren't interested in SortGroupClause nodes since those
3671  * don't contain actual expressions. However they do contain OIDs, which
3672  * may be of interest to some mutators.
3673  */
3674 
3675  if ((flags & QTW_EXAMINE_SORTGROUP))
3676  {
3677  MUTATE(query->groupClause, query->groupClause, List *);
3678  MUTATE(query->windowClause, query->windowClause, List *);
3679  MUTATE(query->sortClause, query->sortClause, List *);
3680  MUTATE(query->distinctClause, query->distinctClause, List *);
3681  }
3682  else
3683  {
3684  /*
3685  * But we need to mutate the expressions under WindowClause nodes even
3686  * if we're not interested in SortGroupClause nodes.
3687  */
3688  List *resultlist;
3689  ListCell *temp;
3690 
3691  resultlist = NIL;
3692  foreach(temp, query->windowClause)
3693  {
3694  WindowClause *wc = lfirst_node(WindowClause, temp);
3695  WindowClause *newnode;
3696 
3697  FLATCOPY(newnode, wc, WindowClause);
3698  MUTATE(newnode->startOffset, wc->startOffset, Node *);
3699  MUTATE(newnode->endOffset, wc->endOffset, Node *);
3700 
3701  resultlist = lappend(resultlist, (Node *) newnode);
3702  }
3703  query->windowClause = resultlist;
3704  }
3705 
3706  /*
3707  * groupingSets and rowMarks are not mutated:
3708  *
3709  * groupingSets contain only ressortgroup refs (integers) which are
3710  * meaningless without the groupClause or tlist. Accordingly, any mutator
3711  * that needs to care about them needs to handle them itself in its Query
3712  * processing.
3713  *
3714  * rowMarks contains only rangetable indexes (and flags etc.) and
3715  * therefore should be handled at Query level similarly.
3716  */
3717 
3718  if (!(flags & QTW_IGNORE_CTE_SUBQUERIES))
3719  MUTATE(query->cteList, query->cteList, List *);
3720  else /* else copy CTE list as-is */
3721  query->cteList = copyObject(query->cteList);
3722  query->rtable = range_table_mutator(query->rtable,
3723  mutator, context, flags);
3724  return query;
3725 }
List * range_table_mutator(List *rtable, Node *(*mutator)(), void *context, int flags)
Definition: nodeFuncs.c:3733
#define QTW_DONT_COPY_QUERY
Definition: nodeFuncs.h:27
#define QTW_IGNORE_CTE_SUBQUERIES
Definition: nodeFuncs.h:21
#define QTW_EXAMINE_SORTGROUP
Definition: nodeFuncs.h:28
List * withCheckOptions
Definition: parsenodes.h:188
Node * limitCount
Definition: parsenodes.h:177
FromExpr * jointree
Definition: parsenodes.h:149
List * returningList
Definition: parsenodes.h:161
Node * setOperations
Definition: parsenodes.h:182
List * cteList
Definition: parsenodes.h:146
OnConflictExpr * onConflict
Definition: parsenodes.h:159
List * groupClause
Definition: parsenodes.h:163
Node * havingQual
Definition: parsenodes.h:168
List * rtable
Definition: parsenodes.h:148
Node * limitOffset
Definition: parsenodes.h:176
List * mergeActionList
Definition: parsenodes.h:152
List * windowClause
Definition: parsenodes.h:170
List * distinctClause
Definition: parsenodes.h:172
List * sortClause
Definition: parsenodes.h:174

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, Query::windowClause, and Query::withCheckOptions.

Referenced by flatten_join_alias_vars_mutator(), map_variable_attnos_mutator(), query_or_expression_tree_mutator(), replace_rte_variables_mutator(), substitute_actual_srf_parameters(), and substitute_actual_srf_parameters_mutator().

◆ query_tree_walker()

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

Definition at line 2570 of file nodeFuncs.c.

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

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, Query::windowClause, and Query::withCheckOptions.

Referenced by AcquireRewriteLocks(), assign_query_collations(), ChangeVarNodes(), ChangeVarNodes_walker(), check_agg_arguments_walker(), check_parameter_resolution_walker(), check_ungrouped_columns_walker(), check_variable_parameters(), contain_aggs_of_level_walker(), contain_dml_walker(), contain_mutable_functions_walker(), contain_outer_selfref_walker(), contain_vars_of_level_walker(), contain_volatile_functions_not_nextval_walker(), contain_volatile_functions_walker(), extract_query_dependencies_walker(), finalize_grouping_exprs_walker(), find_dependent_phvs(), find_dependent_phvs_walker(), find_expr_references_walker(), fireRIRrules(), flatten_rtes_walker(), flatten_unplanned_rtes(), IncrementVarSublevelsUp_walker(), inline_cte_walker(), isQueryUsingTempRelation_walker(), locate_agg_of_level_walker(), locate_var_of_level_walker(), LockViewRecurse_walker(), max_parallel_hazard_walker(), OffsetVarNodes(), OffsetVarNodes_walker(), pull_varnos_walker(), pull_vars_walker(), query_contains_extern_params(), query_contains_extern_params_walker(), query_or_expression_tree_walker(), rangeTableEntry_used_walker(), rewriteTargetView(), ScanQueryForLocks(), setRuleCheckAsUser_Query(), and substitute_phv_relids_walker().

◆ range_table_entry_walker()

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

Definition at line 2692 of file nodeFuncs.c.

2696 {
2697  /*
2698  * Walkers might need to examine the RTE node itself either before or
2699  * after visiting its contents (or, conceivably, both). Note that if you
2700  * specify neither flag, the walker won't be called on the RTE at all.
2701  */
2702  if (flags & QTW_EXAMINE_RTES_BEFORE)
2703  if (walker(rte, context))
2704  return true;
2705 
2706  switch (rte->rtekind)
2707  {
2708  case RTE_RELATION:
2709  if (walker(rte->tablesample, context))
2710  return true;
2711  break;
2712  case RTE_SUBQUERY:
2713  if (!(flags & QTW_IGNORE_RT_SUBQUERIES))
2714  if (walker(rte->subquery, context))
2715  return true;
2716  break;
2717  case RTE_JOIN:
2718  if (!(flags & QTW_IGNORE_JOINALIASES))
2719  if (walker(rte->joinaliasvars, context))
2720  return true;
2721  break;
2722  case RTE_FUNCTION:
2723  if (walker(rte->functions, context))
2724  return true;
2725  break;
2726  case RTE_TABLEFUNC:
2727  if (walker(rte->tablefunc, context))
2728  return true;
2729  break;
2730  case RTE_VALUES:
2731  if (walker(rte->values_lists, context))
2732  return true;
2733  break;
2734  case RTE_CTE:
2735  case RTE_NAMEDTUPLESTORE:
2736  case RTE_RESULT:
2737  /* nothing to do */
2738  break;
2739  }
2740 
2741  if (walker(rte->securityQuals, context))
2742  return true;
2743 
2744  if (flags & QTW_EXAMINE_RTES_AFTER)
2745  if (walker(rte, context))
2746  return true;
2747 
2748  return false;
2749 }
#define QTW_IGNORE_RT_SUBQUERIES
Definition: nodeFuncs.h:20
#define QTW_EXAMINE_RTES_AFTER
Definition: nodeFuncs.h:26
#define QTW_EXAMINE_RTES_BEFORE
Definition: nodeFuncs.h:25
#define QTW_IGNORE_JOINALIASES
Definition: nodeFuncs.h:23
@ RTE_JOIN
Definition: parsenodes.h:1000
@ RTE_CTE
Definition: parsenodes.h:1004
@ RTE_NAMEDTUPLESTORE
Definition: parsenodes.h:1005
@ RTE_VALUES
Definition: parsenodes.h:1003
@ RTE_SUBQUERY
Definition: parsenodes.h:999
@ RTE_RESULT
Definition: parsenodes.h:1006
@ RTE_FUNCTION
Definition: parsenodes.h:1001
@ RTE_TABLEFUNC
Definition: parsenodes.h:1002
@ RTE_RELATION
Definition: parsenodes.h:998
TableFunc * tablefunc
Definition: parsenodes.h:1115
struct TableSampleClause * tablesample
Definition: parsenodes.h:1045
List * securityQuals
Definition: parsenodes.h:1171
Query * subquery
Definition: parsenodes.h:1050
List * values_lists
Definition: parsenodes.h:1120
List * joinaliasvars
Definition: parsenodes.h:1090
List * functions
Definition: parsenodes.h:1109
RTEKind rtekind
Definition: parsenodes.h:1015

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, and RangeTblEntry::values_lists.

Referenced by find_dependent_phvs_in_jointree(), and range_table_walker().

◆ range_table_mutator()

List* range_table_mutator ( List rtable,
Node *(*)()  mutator,
void *  context,
int  flags 
)

Definition at line 3733 of file nodeFuncs.c.

3737 {
3738  List *newrt = NIL;
3739  ListCell *rt;
3740 
3741  foreach(rt, rtable)
3742  {
3743  RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
3744  RangeTblEntry *newrte;
3745 
3746  FLATCOPY(newrte, rte, RangeTblEntry);
3747  switch (rte->rtekind)
3748  {
3749  case RTE_RELATION:
3750  MUTATE(newrte->tablesample, rte->tablesample,
3751  TableSampleClause *);
3752  /* we don't bother to copy eref, aliases, etc; OK? */
3753  break;
3754  case RTE_SUBQUERY:
3755  if (!(flags & QTW_IGNORE_RT_SUBQUERIES))
3756  MUTATE(newrte->subquery, rte->subquery, Query *);
3757  else
3758  {
3759  /* else, copy RT subqueries as-is */
3760  newrte->subquery = copyObject(rte->subquery);
3761  }
3762  break;
3763  case RTE_JOIN:
3764  if (!(flags & QTW_IGNORE_JOINALIASES))
3765  MUTATE(newrte->joinaliasvars, rte->joinaliasvars, List *);
3766  else
3767  {
3768  /* else, copy join aliases as-is */
3769  newrte->joinaliasvars = copyObject(rte->joinaliasvars);
3770  }
3771  break;
3772  case RTE_FUNCTION:
3773  MUTATE(newrte->functions, rte->functions, List *);
3774  break;
3775  case RTE_TABLEFUNC:
3776  MUTATE(newrte->tablefunc, rte->tablefunc, TableFunc *);
3777  break;
3778  case RTE_VALUES:
3779  MUTATE(newrte->values_lists, rte->values_lists, List *);
3780  break;
3781  case RTE_CTE:
3782  case RTE_NAMEDTUPLESTORE:
3783  case RTE_RESULT:
3784  /* nothing to do */
3785  break;
3786  }
3787  MUTATE(newrte->securityQuals, rte->securityQuals, List *);
3788  newrt = lappend(newrt, newrte);
3789  }
3790  return newrt;
3791 }

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.

Referenced by query_tree_mutator().

◆ range_table_walker()

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

Definition at line 2671 of file nodeFuncs.c.

2675 {
2676  ListCell *rt;
2677 
2678  foreach(rt, rtable)
2679  {
2681 
2682  if (range_table_entry_walker(rte, walker, context, flags))
2683  return true;
2684  }
2685  return false;
2686 }
bool range_table_entry_walker(RangeTblEntry *rte, bool(*walker)(), void *context, int flags)
Definition: nodeFuncs.c:2692

References lfirst_node, and range_table_entry_walker().

Referenced by IncrementVarSublevelsUp_rtable(), and query_tree_walker().

◆ raw_expression_tree_walker()

bool raw_expression_tree_walker ( Node node,
bool(*)()  walker,
void *  context 
)

Definition at line 3856 of file nodeFuncs.c.

3859 {
3860  ListCell *temp;
3861 
3862  /*
3863  * The walker has already visited the current node, and so we need only
3864  * recurse into any sub-nodes it has.
3865  */
3866  if (node == NULL)
3867  return false;
3868 
3869  /* Guard against stack overflow due to overly complex expressions */
3871 
3872  switch (nodeTag(node))
3873  {
3874  case T_SetToDefault:
3875  case