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

Go to the source code of this file.

Macros

#define QTW_IGNORE_RT_SUBQUERIES   0x01 /* subqueries in rtable */
 
#define QTW_IGNORE_CTE_SUBQUERIES   0x02 /* subqueries in cteList */
 
#define QTW_IGNORE_RC_SUBQUERIES   0x03 /* both of above */
 
#define QTW_IGNORE_JOINALIASES   0x04 /* JOIN alias var lists */
 
#define QTW_IGNORE_RANGE_TABLE   0x08 /* skip rangetable entirely */
 
#define QTW_EXAMINE_RTES_BEFORE
 
#define QTW_EXAMINE_RTES_AFTER
 
#define QTW_DONT_COPY_QUERY   0x40 /* do not copy top Query */
 
#define QTW_EXAMINE_SORTGROUP   0x80 /* include SortGroupNode lists */
 

Typedefs

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

Functions

Oid exprType (const Node *expr)
 
int32 exprTypmod (const Node *expr)
 
bool exprIsLengthCoercion (const Node *expr, int32 *coercedTypmod)
 
NodeapplyRelabelType (Node *arg, Oid rtype, int32 rtypmod, Oid rcollid, CoercionForm rformat, int rlocation, bool overwrite_ok)
 
Noderelabel_to_typmod (Node *expr, int32 typmod)
 
Nodestrip_implicit_coercions (Node *node)
 
bool expression_returns_set (Node *clause)
 
Oid exprCollation (const Node *expr)
 
Oid exprInputCollation (const Node *expr)
 
void exprSetCollation (Node *expr, Oid collation)
 
void exprSetInputCollation (Node *expr, Oid inputcollation)
 
int exprLocation (const Node *expr)
 
void fix_opfuncids (Node *node)
 
void set_opfuncid (OpExpr *opexpr)
 
void set_sa_opfuncid (ScalarArrayOpExpr *opexpr)
 
static bool is_funcclause (const void *clause)
 
static bool is_opclause (const void *clause)
 
static Nodeget_leftop (const void *clause)
 
static Nodeget_rightop (const void *clause)
 
static bool is_andclause (const void *clause)
 
static bool is_orclause (const void *clause)
 
static bool is_notclause (const void *clause)
 
static Exprget_notclausearg (const void *notclause)
 
bool check_functions_in_node (Node *node, check_function_callback checker, void *context)
 
bool expression_tree_walker (Node *node, bool(*walker)(), void *context)
 
Nodeexpression_tree_mutator (Node *node, Node *(*mutator)(), void *context)
 
bool query_tree_walker (Query *query, bool(*walker)(), void *context, int flags)
 
Queryquery_tree_mutator (Query *query, Node *(*mutator)(), void *context, int flags)
 
bool range_table_walker (List *rtable, bool(*walker)(), void *context, int flags)
 
Listrange_table_mutator (List *rtable, Node *(*mutator)(), void *context, int flags)
 
bool range_table_entry_walker (RangeTblEntry *rte, bool(*walker)(), 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 (struct PlanState *planstate, bool(*walker)(), void *context)
 

Macro Definition Documentation

◆ QTW_DONT_COPY_QUERY

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

Definition at line 29 of file nodeFuncs.h.

Referenced by query_tree_mutator().

◆ QTW_EXAMINE_RTES_AFTER

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

Definition at line 27 of file nodeFuncs.h.

Referenced by inline_cte_walker(), and range_table_entry_walker().

◆ QTW_EXAMINE_RTES_BEFORE

#define QTW_EXAMINE_RTES_BEFORE

◆ QTW_EXAMINE_SORTGROUP

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

Definition at line 30 of file nodeFuncs.h.

Referenced by find_expr_references_walker(), query_tree_mutator(), and query_tree_walker().

◆ QTW_IGNORE_CTE_SUBQUERIES

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

Definition at line 21 of file nodeFuncs.h.

Referenced by assign_query_collations(), query_tree_mutator(), and query_tree_walker().

◆ QTW_IGNORE_JOINALIASES

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

◆ QTW_IGNORE_RANGE_TABLE

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

Definition at line 24 of file nodeFuncs.h.

Referenced by assign_query_collations(), and query_tree_walker().

◆ QTW_IGNORE_RC_SUBQUERIES

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

◆ QTW_IGNORE_RT_SUBQUERIES

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

Definition at line 20 of file nodeFuncs.h.

Referenced by range_table_entry_walker(), and range_table_mutator().

Typedef Documentation

◆ check_function_callback

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

Definition at line 33 of file nodeFuncs.h.

Function Documentation

◆ applyRelabelType()

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

Definition at line 582 of file nodeFuncs.c.

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(), eval_const_expressions_mutator(), generate_setop_tlist(), and relabel_to_typmod().

584 {
585  /*
586  * If we find stacked RelabelTypes (eg, from foo::int::oid) we can discard
587  * all but the top one, and must do so to ensure that semantically
588  * equivalent expressions are equal().
589  */
590  while (arg && IsA(arg, RelabelType))
591  arg = (Node *) ((RelabelType *) arg)->arg;
592 
593  if (arg && IsA(arg, Const))
594  {
595  /* Modify the Const directly to preserve const-flatness. */
596  Const *con = (Const *) arg;
597 
598  if (!overwrite_ok)
599  con = copyObject(con);
600  con->consttype = rtype;
601  con->consttypmod = rtypmod;
602  con->constcollid = rcollid;
603  /* We keep the Const's original location. */
604  return (Node *) con;
605  }
606  else if (exprType(arg) == rtype &&
607  exprTypmod(arg) == rtypmod &&
608  exprCollation(arg) == rcollid)
609  {
610  /* Sometimes we find a nest of relabels that net out to nothing. */
611  return arg;
612  }
613  else
614  {
615  /* Nope, gotta have a RelabelType. */
616  RelabelType *newrelabel = makeNode(RelabelType);
617 
618  newrelabel->arg = (Expr *) arg;
619  newrelabel->resulttype = rtype;
620  newrelabel->resulttypmod = rtypmod;
621  newrelabel->resultcollid = rcollid;
622  newrelabel->relabelformat = rformat;
623  newrelabel->location = rlocation;
624  return (Node *) newrelabel;
625  }
626 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:584
int32 exprTypmod(const Node *expr)
Definition: nodeFuncs.c:267
Expr * arg
Definition: primnodes.h:838
Definition: nodes.h:533
Oid consttype
Definition: primnodes.h:210
Oid constcollid
Definition: primnodes.h:212
Oid resulttype
Definition: primnodes.h:839
Oid resultcollid
Definition: primnodes.h:841
#define makeNode(_type_)
Definition: nodes.h:581
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:41
Oid exprCollation(const Node *expr)
Definition: nodeFuncs.c:759
int32 consttypmod
Definition: primnodes.h:211
void * arg
int32 resulttypmod
Definition: primnodes.h:840
#define copyObject(obj)
Definition: nodes.h:649
CoercionForm relabelformat
Definition: primnodes.h:842
int location
Definition: primnodes.h:843

◆ check_functions_in_node()

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

Definition at line 1702 of file nodeFuncs.c.

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(), get_notclausearg(), and max_parallel_hazard_walker().

1704 {
1705  switch (nodeTag(node))
1706  {
1707  case T_Aggref:
1708  {
1709  Aggref *expr = (Aggref *) node;
1710 
1711  if (checker(expr->aggfnoid, context))
1712  return true;
1713  }
1714  break;
1715  case T_WindowFunc:
1716  {
1717  WindowFunc *expr = (WindowFunc *) node;
1718 
1719  if (checker(expr->winfnoid, context))
1720  return true;
1721  }
1722  break;
1723  case T_FuncExpr:
1724  {
1725  FuncExpr *expr = (FuncExpr *) node;
1726 
1727  if (checker(expr->funcid, context))
1728  return true;
1729  }
1730  break;
1731  case T_OpExpr:
1732  case T_DistinctExpr: /* struct-equivalent to OpExpr */
1733  case T_NullIfExpr: /* struct-equivalent to OpExpr */
1734  {
1735  OpExpr *expr = (OpExpr *) node;
1736 
1737  /* Set opfuncid if it wasn't set already */
1738  set_opfuncid(expr);
1739  if (checker(expr->opfuncid, context))
1740  return true;
1741  }
1742  break;
1743  case T_ScalarArrayOpExpr:
1744  {
1745  ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
1746 
1747  set_sa_opfuncid(expr);
1748  if (checker(expr->opfuncid, context))
1749  return true;
1750  }
1751  break;
1752  case T_CoerceViaIO:
1753  {
1754  CoerceViaIO *expr = (CoerceViaIO *) node;
1755  Oid iofunc;
1756  Oid typioparam;
1757  bool typisvarlena;
1758 
1759  /* check the result type's input function */
1761  &iofunc, &typioparam);
1762  if (checker(iofunc, context))
1763  return true;
1764  /* check the input type's output function */
1765  getTypeOutputInfo(exprType((Node *) expr->arg),
1766  &iofunc, &typisvarlena);
1767  if (checker(iofunc, context))
1768  return true;
1769  }
1770  break;
1771  case T_RowCompareExpr:
1772  {
1773  RowCompareExpr *rcexpr = (RowCompareExpr *) node;
1774  ListCell *opid;
1775 
1776  foreach(opid, rcexpr->opnos)
1777  {
1778  Oid opfuncid = get_opcode(lfirst_oid(opid));
1779 
1780  if (checker(opfuncid, context))
1781  return true;
1782  }
1783  }
1784  break;
1785  default:
1786  break;
1787  }
1788  return false;
1789 }
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2854
Oid resulttype
Definition: primnodes.h:859
Definition: nodes.h:533
unsigned int Oid
Definition: postgres_ext.h:31
Oid funcid
Definition: primnodes.h:490
Oid winfnoid
Definition: primnodes.h:381
Expr * arg
Definition: primnodes.h:858
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
Definition: lsyscache.c:2821
Oid opfuncid
Definition: primnodes.h:538
RegProcedure get_opcode(Oid opno)
Definition: lsyscache.c:1256
Oid aggfnoid
Definition: primnodes.h:318
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:41
#define nodeTag(nodeptr)
Definition: nodes.h:538
void set_opfuncid(OpExpr *opexpr)
Definition: nodeFuncs.c:1664
void set_sa_opfuncid(ScalarArrayOpExpr *opexpr)
Definition: nodeFuncs.c:1675
#define lfirst_oid(lc)
Definition: pg_list.h:171

◆ exprCollation()

Oid exprCollation ( const Node expr)

Definition at line 759 of file nodeFuncs.c.

References arg, ARRAY_SUBLINK, Assert, elog, ERROR, EXPR_SUBLINK, exprCollation(), SubPlan::firstColCollation, InvalidOid, IS_XMLSERIALIZE, IsA, linitial, linitial_node, nodeTag, 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_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 addRangeTableEntryForFunction(), addRangeTableEntryForSubquery(), analyzeCTE(), analyzeCTETargetList(), applyRelabelType(), assign_collations_walker(), assign_hypothetical_collations(), build_expression_pathkey(), build_pertrans_for_aggref(), build_subplan(), canonicalize_ec_expression(), ComputeIndexAttrs(), ComputePartitionAttrs(), convert_EXISTS_to_ANY(), create_ctas_nodata(), create_limit_plan(), create_unique_plan(), create_windowagg_plan(), DefineVirtualRelation(), eval_const_expressions_mutator(), examine_attribute(), ExecInitFunctionScan(), ExecInitIndexScan(), ExecTypeFromExprList(), ExecTypeFromTLInternal(), expandRecordVariable(), expandRTE(), exprCollation(), 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(), makeVarFromTargetEntry(), makeWholeRowVar(), 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().

760 {
761  Oid coll;
762 
763  if (!expr)
764  return InvalidOid;
765 
766  switch (nodeTag(expr))
767  {
768  case T_Var:
769  coll = ((const Var *) expr)->varcollid;
770  break;
771  case T_Const:
772  coll = ((const Const *) expr)->constcollid;
773  break;
774  case T_Param:
775  coll = ((const Param *) expr)->paramcollid;
776  break;
777  case T_Aggref:
778  coll = ((const Aggref *) expr)->aggcollid;
779  break;
780  case T_GroupingFunc:
781  coll = InvalidOid;
782  break;
783  case T_WindowFunc:
784  coll = ((const WindowFunc *) expr)->wincollid;
785  break;
786  case T_SubscriptingRef:
787  coll = ((const SubscriptingRef *) expr)->refcollid;
788  break;
789  case T_FuncExpr:
790  coll = ((const FuncExpr *) expr)->funccollid;
791  break;
792  case T_NamedArgExpr:
793  coll = exprCollation((Node *) ((const NamedArgExpr *) expr)->arg);
794  break;
795  case T_OpExpr:
796  coll = ((const OpExpr *) expr)->opcollid;
797  break;
798  case T_DistinctExpr:
799  coll = ((const DistinctExpr *) expr)->opcollid;
800  break;
801  case T_NullIfExpr:
802  coll = ((const NullIfExpr *) expr)->opcollid;
803  break;
804  case T_ScalarArrayOpExpr:
805  coll = InvalidOid; /* result is always boolean */
806  break;
807  case T_BoolExpr:
808  coll = InvalidOid; /* result is always boolean */
809  break;
810  case T_SubLink:
811  {
812  const SubLink *sublink = (const SubLink *) expr;
813 
814  if (sublink->subLinkType == EXPR_SUBLINK ||
815  sublink->subLinkType == ARRAY_SUBLINK)
816  {
817  /* get the collation of subselect's first target column */
818  Query *qtree = (Query *) sublink->subselect;
819  TargetEntry *tent;
820 
821  if (!qtree || !IsA(qtree, Query))
822  elog(ERROR, "cannot get collation for untransformed sublink");
823  tent = linitial_node(TargetEntry, qtree->targetList);
824  Assert(!tent->resjunk);
825  coll = exprCollation((Node *) tent->expr);
826  /* collation doesn't change if it's converted to array */
827  }
828  else
829  {
830  /* otherwise, result is RECORD or BOOLEAN */
831  coll = InvalidOid;
832  }
833  }
834  break;
835  case T_SubPlan:
836  {
837  const SubPlan *subplan = (const SubPlan *) expr;
838 
839  if (subplan->subLinkType == EXPR_SUBLINK ||
840  subplan->subLinkType == ARRAY_SUBLINK)
841  {
842  /* get the collation of subselect's first target column */
843  coll = subplan->firstColCollation;
844  /* collation doesn't change if it's converted to array */
845  }
846  else
847  {
848  /* otherwise, result is RECORD or BOOLEAN */
849  coll = InvalidOid;
850  }
851  }
852  break;
854  {
855  const AlternativeSubPlan *asplan = (const AlternativeSubPlan *) expr;
856 
857  /* subplans should all return the same thing */
858  coll = exprCollation((Node *) linitial(asplan->subplans));
859  }
860  break;
861  case T_FieldSelect:
862  coll = ((const FieldSelect *) expr)->resultcollid;
863  break;
864  case T_FieldStore:
865  coll = InvalidOid; /* result is always composite */
866  break;
867  case T_RelabelType:
868  coll = ((const RelabelType *) expr)->resultcollid;
869  break;
870  case T_CoerceViaIO:
871  coll = ((const CoerceViaIO *) expr)->resultcollid;
872  break;
873  case T_ArrayCoerceExpr:
874  coll = ((const ArrayCoerceExpr *) expr)->resultcollid;
875  break;
877  coll = InvalidOid; /* result is always composite */
878  break;
879  case T_CollateExpr:
880  coll = ((const CollateExpr *) expr)->collOid;
881  break;
882  case T_CaseExpr:
883  coll = ((const CaseExpr *) expr)->casecollid;
884  break;
885  case T_CaseTestExpr:
886  coll = ((const CaseTestExpr *) expr)->collation;
887  break;
888  case T_ArrayExpr:
889  coll = ((const ArrayExpr *) expr)->array_collid;
890  break;
891  case T_RowExpr:
892  coll = InvalidOid; /* result is always composite */
893  break;
894  case T_RowCompareExpr:
895  coll = InvalidOid; /* result is always boolean */
896  break;
897  case T_CoalesceExpr:
898  coll = ((const CoalesceExpr *) expr)->coalescecollid;
899  break;
900  case T_MinMaxExpr:
901  coll = ((const MinMaxExpr *) expr)->minmaxcollid;
902  break;
903  case T_SQLValueFunction:
904  /* Returns either NAME or a non-collatable type */
905  if (((const SQLValueFunction *) expr)->type == NAMEOID)
906  coll = C_COLLATION_OID;
907  else
908  coll = InvalidOid;
909  break;
910  case T_XmlExpr:
911 
912  /*
913  * XMLSERIALIZE returns text from non-collatable inputs, so its
914  * collation is always default. The other cases return boolean or
915  * XML, which are non-collatable.
916  */
917  if (((const XmlExpr *) expr)->op == IS_XMLSERIALIZE)
918  coll = DEFAULT_COLLATION_OID;
919  else
920  coll = InvalidOid;
921  break;
922  case T_NullTest:
923  coll = InvalidOid; /* result is always boolean */
924  break;
925  case T_BooleanTest:
926  coll = InvalidOid; /* result is always boolean */
927  break;
928  case T_CoerceToDomain:
929  coll = ((const CoerceToDomain *) expr)->resultcollid;
930  break;
932  coll = ((const CoerceToDomainValue *) expr)->collation;
933  break;
934  case T_SetToDefault:
935  coll = ((const SetToDefault *) expr)->collation;
936  break;
937  case T_CurrentOfExpr:
938  coll = InvalidOid; /* result is always boolean */
939  break;
940  case T_NextValueExpr:
941  coll = InvalidOid; /* result is always an integer type */
942  break;
943  case T_InferenceElem:
944  coll = exprCollation((Node *) ((const InferenceElem *) expr)->expr);
945  break;
946  case T_PlaceHolderVar:
947  coll = exprCollation((Node *) ((const PlaceHolderVar *) expr)->phexpr);
948  break;
949  default:
950  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
951  coll = InvalidOid; /* keep compiler quiet */
952  break;
953  }
954  return coll;
955 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:584
SubLinkType subLinkType
Definition: primnodes.h:725
Definition: nodes.h:533
unsigned int Oid
Definition: postgres_ext.h:31
Definition: primnodes.h:181
#define linitial_node(type, l)
Definition: pg_list.h:177
List * targetList
Definition: parsenodes.h:140
#define linitial(l)
Definition: pg_list.h:174
#define ERROR
Definition: elog.h:45
Definition: nodes.h:156
Definition: nodes.h:155
#define InvalidOid
Definition: postgres_ext.h:36
#define Assert(condition)
Definition: c.h:804
Oid exprCollation(const Node *expr)
Definition: nodeFuncs.c:759
#define nodeTag(nodeptr)
Definition: nodes.h:538
#define elog(elevel,...)
Definition: elog.h:227
void * arg
Oid firstColCollation
Definition: primnodes.h:736
Definition: nodes.h:157

◆ expression_returns_set()

bool expression_returns_set ( Node clause)

◆ expression_tree_mutator()

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

Definition at line 2579 of file nodeFuncs.c.

References 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, Aggref::args, GroupingFunc::args, WindowFunc::args, FuncExpr::args, OpExpr::args, ScalarArrayOpExpr::args, BoolExpr::args, SubPlan::args, CaseExpr::args, RowExpr::args, CoalesceExpr::args, MinMaxExpr::args, TableSampleClause::args, XmlExpr::args, check_stack_depth(), TableFunc::coldefexprs, TableFunc::colexprs, GroupingFunc::cols, copyObject, CommonTableExpr::ctequery, CommonTableExpr::cycle_clause, CTECycleClause::cycle_mark_default, CTECycleClause::cycle_mark_value, CaseExpr::defresult, TableFunc::docexpr, ArrayExpr::elements, ArrayCoerceExpr::elemexpr, elog, WindowClause::endOffset, ERROR, OnConflictExpr::exclRelTlist, CaseWhen::expr, InferenceElem::expr, TargetEntry::expr, PartitionPruneStepOp::exprs, FieldStore::fieldnums, FLATCOPY, FromExpr::fromlist, RangeTblFunction::funcexpr, IndexClause::indexquals, lappend(), JoinExpr::larg, SetOperationStmt::larg, RowCompareExpr::largs, lfirst, list_copy(), MUTATE, XmlExpr::named_args, FieldStore::newvals, NIL, nodeTag, TableFunc::ns_uris, OnConflictExpr::onConflictSet, OnConflictExpr::onConflictWhere, WindowClause::orderClause, WindowClause::partitionClause, PlaceHolderInfo::ph_var, PlaceHolderVar::phexpr, WithCheckOption::qual, JoinExpr::quals, FromExpr::quals, JoinExpr::rarg, SetOperationStmt::rarg, RowCompareExpr::rargs, SubscriptingRef::refassgnexpr, SubscriptingRef::refexpr, SubscriptingRef::reflowerindexpr, GroupingFunc::refs, SubscriptingRef::refupperindexpr, TableSampleClause::repeatable, CaseWhen::result, IndexClause::rinfo, TableFunc::rowexpr, CommonTableExpr::search_clause, WindowClause::startOffset, 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_List, T_MinMaxExpr, T_NamedArgExpr, T_NextValueExpr, T_NullIfExpr, T_NullTest, T_OnConflictExpr, T_OpExpr, T_Param, T_PartitionPruneStepCombine, T_PartitionPruneStepOp, 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, and AppendRelInfo::translated_vars.

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(), flatten_join_alias_vars_mutator(), get_notclausearg(), 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().

2582 {
2583  /*
2584  * The mutator has already decided not to modify the current node, but we
2585  * must call the mutator for any sub-nodes.
2586  */
2587 
2588 #define FLATCOPY(newnode, node, nodetype) \
2589  ( (newnode) = (nodetype *) palloc(sizeof(nodetype)), \
2590  memcpy((newnode), (node), sizeof(nodetype)) )
2591 
2592 #define CHECKFLATCOPY(newnode, node, nodetype) \
2593  ( AssertMacro(IsA((node), nodetype)), \
2594  (newnode) = (nodetype *) palloc(sizeof(nodetype)), \
2595  memcpy((newnode), (node), sizeof(nodetype)) )
2596 
2597 #define MUTATE(newfield, oldfield, fieldtype) \
2598  ( (newfield) = (fieldtype) mutator((Node *) (oldfield), context) )
2599 
2600  if (node == NULL)
2601  return NULL;
2602 
2603  /* Guard against stack overflow due to overly complex expressions */
2605 
2606  switch (nodeTag(node))
2607  {
2608  /*
2609  * Primitive node types with no expression subnodes. Var and
2610  * Const are frequent enough to deserve special cases, the others
2611  * we just use copyObject for.
2612  */
2613  case T_Var:
2614  {
2615  Var *var = (Var *) node;
2616  Var *newnode;
2617 
2618  FLATCOPY(newnode, var, Var);
2619  return (Node *) newnode;
2620  }
2621  break;
2622  case T_Const:
2623  {
2624  Const *oldnode = (Const *) node;
2625  Const *newnode;
2626 
2627  FLATCOPY(newnode, oldnode, Const);
2628  /* XXX we don't bother with datumCopy; should we? */
2629  return (Node *) newnode;
2630  }
2631  break;
2632  case T_Param:
2633  case T_CaseTestExpr:
2634  case T_SQLValueFunction:
2635  case T_CoerceToDomainValue:
2636  case T_SetToDefault:
2637  case T_CurrentOfExpr:
2638  case T_NextValueExpr:
2639  case T_RangeTblRef:
2640  case T_SortGroupClause:
2641  case T_CTESearchClause:
2642  return (Node *) copyObject(node);
2643  case T_WithCheckOption:
2644  {
2645  WithCheckOption *wco = (WithCheckOption *) node;
2646  WithCheckOption *newnode;
2647 
2648  FLATCOPY(newnode, wco, WithCheckOption);
2649  MUTATE(newnode->qual, wco->qual, Node *);
2650  return (Node *) newnode;
2651  }
2652  case T_Aggref:
2653  {
2654  Aggref *aggref = (Aggref *) node;
2655  Aggref *newnode;
2656 
2657  FLATCOPY(newnode, aggref, Aggref);
2658  /* assume mutation doesn't change types of arguments */
2659  newnode->aggargtypes = list_copy(aggref->aggargtypes);
2660  MUTATE(newnode->aggdirectargs, aggref->aggdirectargs, List *);
2661  MUTATE(newnode->args, aggref->args, List *);
2662  MUTATE(newnode->aggorder, aggref->aggorder, List *);
2663  MUTATE(newnode->aggdistinct, aggref->aggdistinct, List *);
2664  MUTATE(newnode->aggfilter, aggref->aggfilter, Expr *);
2665  return (Node *) newnode;
2666  }
2667  break;
2668  case T_GroupingFunc:
2669  {
2670  GroupingFunc *grouping = (GroupingFunc *) node;
2671  GroupingFunc *newnode;
2672 
2673  FLATCOPY(newnode, grouping, GroupingFunc);
2674  MUTATE(newnode->args, grouping->args, List *);
2675 
2676  /*
2677  * We assume here that mutating the arguments does not change
2678  * the semantics, i.e. that the arguments are not mutated in a
2679  * way that makes them semantically different from their
2680  * previously matching expressions in the GROUP BY clause.
2681  *
2682  * If a mutator somehow wanted to do this, it would have to
2683  * handle the refs and cols lists itself as appropriate.
2684  */
2685  newnode->refs = list_copy(grouping->refs);
2686  newnode->cols = list_copy(grouping->cols);
2687 
2688  return (Node *) newnode;
2689  }
2690  break;
2691  case T_WindowFunc:
2692  {
2693  WindowFunc *wfunc = (WindowFunc *) node;
2694  WindowFunc *newnode;
2695 
2696  FLATCOPY(newnode, wfunc, WindowFunc);
2697  MUTATE(newnode->args, wfunc->args, List *);
2698  MUTATE(newnode->aggfilter, wfunc->aggfilter, Expr *);
2699  return (Node *) newnode;
2700  }
2701  break;
2702  case T_SubscriptingRef:
2703  {
2704  SubscriptingRef *sbsref = (SubscriptingRef *) node;
2705  SubscriptingRef *newnode;
2706 
2707  FLATCOPY(newnode, sbsref, SubscriptingRef);
2708  MUTATE(newnode->refupperindexpr, sbsref->refupperindexpr,
2709  List *);
2710  MUTATE(newnode->reflowerindexpr, sbsref->reflowerindexpr,
2711  List *);
2712  MUTATE(newnode->refexpr, sbsref->refexpr,
2713  Expr *);
2714  MUTATE(newnode->refassgnexpr, sbsref->refassgnexpr,
2715  Expr *);
2716 
2717  return (Node *) newnode;
2718  }
2719  break;
2720  case T_FuncExpr:
2721  {
2722  FuncExpr *expr = (FuncExpr *) node;
2723  FuncExpr *newnode;
2724 
2725  FLATCOPY(newnode, expr, FuncExpr);
2726  MUTATE(newnode->args, expr->args, List *);
2727  return (Node *) newnode;
2728  }
2729  break;
2730  case T_NamedArgExpr:
2731  {
2732  NamedArgExpr *nexpr = (NamedArgExpr *) node;
2733  NamedArgExpr *newnode;
2734 
2735  FLATCOPY(newnode, nexpr, NamedArgExpr);
2736  MUTATE(newnode->arg, nexpr->arg, Expr *);
2737  return (Node *) newnode;
2738  }
2739  break;
2740  case T_OpExpr:
2741  {
2742  OpExpr *expr = (OpExpr *) node;
2743  OpExpr *newnode;
2744 
2745  FLATCOPY(newnode, expr, OpExpr);
2746  MUTATE(newnode->args, expr->args, List *);
2747  return (Node *) newnode;
2748  }
2749  break;
2750  case T_DistinctExpr:
2751  {
2752  DistinctExpr *expr = (DistinctExpr *) node;
2753  DistinctExpr *newnode;
2754 
2755  FLATCOPY(newnode, expr, DistinctExpr);
2756  MUTATE(newnode->args, expr->args, List *);
2757  return (Node *) newnode;
2758  }
2759  break;
2760  case T_NullIfExpr:
2761  {
2762  NullIfExpr *expr = (NullIfExpr *) node;
2763  NullIfExpr *newnode;
2764 
2765  FLATCOPY(newnode, expr, NullIfExpr);
2766  MUTATE(newnode->args, expr->args, List *);
2767  return (Node *) newnode;
2768  }
2769  break;
2770  case T_ScalarArrayOpExpr:
2771  {
2772  ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
2773  ScalarArrayOpExpr *newnode;
2774 
2775  FLATCOPY(newnode, expr, ScalarArrayOpExpr);
2776  MUTATE(newnode->args, expr->args, List *);
2777  return (Node *) newnode;
2778  }
2779  break;
2780  case T_BoolExpr:
2781  {
2782  BoolExpr *expr = (BoolExpr *) node;
2783  BoolExpr *newnode;
2784 
2785  FLATCOPY(newnode, expr, BoolExpr);
2786  MUTATE(newnode->args, expr->args, List *);
2787  return (Node *) newnode;
2788  }
2789  break;
2790  case T_SubLink:
2791  {
2792  SubLink *sublink = (SubLink *) node;
2793  SubLink *newnode;
2794 
2795  FLATCOPY(newnode, sublink, SubLink);
2796  MUTATE(newnode->testexpr, sublink->testexpr, Node *);
2797 
2798  /*
2799  * Also invoke the mutator on the sublink's Query node, so it
2800  * can recurse into the sub-query if it wants to.
2801  */
2802  MUTATE(newnode->subselect, sublink->subselect, Node *);
2803  return (Node *) newnode;
2804  }
2805  break;
2806  case T_SubPlan:
2807  {
2808  SubPlan *subplan = (SubPlan *) node;
2809  SubPlan *newnode;
2810 
2811  FLATCOPY(newnode, subplan, SubPlan);
2812  /* transform testexpr */
2813  MUTATE(newnode->testexpr, subplan->testexpr, Node *);
2814  /* transform args list (params to be passed to subplan) */
2815  MUTATE(newnode->args, subplan->args, List *);
2816  /* but not the sub-Plan itself, which is referenced as-is */
2817  return (Node *) newnode;
2818  }
2819  break;
2820  case T_AlternativeSubPlan:
2821  {
2822  AlternativeSubPlan *asplan = (AlternativeSubPlan *) node;
2823  AlternativeSubPlan *newnode;
2824 
2825  FLATCOPY(newnode, asplan, AlternativeSubPlan);
2826  MUTATE(newnode->subplans, asplan->subplans, List *);
2827  return (Node *) newnode;
2828  }
2829  break;
2830  case T_FieldSelect:
2831  {
2832  FieldSelect *fselect = (FieldSelect *) node;
2833  FieldSelect *newnode;
2834 
2835  FLATCOPY(newnode, fselect, FieldSelect);
2836  MUTATE(newnode->arg, fselect->arg, Expr *);
2837  return (Node *) newnode;
2838  }
2839  break;
2840  case T_FieldStore:
2841  {
2842  FieldStore *fstore = (FieldStore *) node;
2843  FieldStore *newnode;
2844 
2845  FLATCOPY(newnode, fstore, FieldStore);
2846  MUTATE(newnode->arg, fstore->arg, Expr *);
2847  MUTATE(newnode->newvals, fstore->newvals, List *);
2848  newnode->fieldnums = list_copy(fstore->fieldnums);
2849  return (Node *) newnode;
2850  }
2851  break;
2852  case T_RelabelType:
2853  {
2854  RelabelType *relabel = (RelabelType *) node;
2855  RelabelType *newnode;
2856 
2857  FLATCOPY(newnode, relabel, RelabelType);
2858  MUTATE(newnode->arg, relabel->arg, Expr *);
2859  return (Node *) newnode;
2860  }
2861  break;
2862  case T_CoerceViaIO:
2863  {
2864  CoerceViaIO *iocoerce = (CoerceViaIO *) node;
2865  CoerceViaIO *newnode;
2866 
2867  FLATCOPY(newnode, iocoerce, CoerceViaIO);
2868  MUTATE(newnode->arg, iocoerce->arg, Expr *);
2869  return (Node *) newnode;
2870  }
2871  break;
2872  case T_ArrayCoerceExpr:
2873  {
2874  ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node;
2875  ArrayCoerceExpr *newnode;
2876 
2877  FLATCOPY(newnode, acoerce, ArrayCoerceExpr);
2878  MUTATE(newnode->arg, acoerce->arg, Expr *);
2879  MUTATE(newnode->elemexpr, acoerce->elemexpr, Expr *);
2880  return (Node *) newnode;
2881  }
2882  break;
2883  case T_ConvertRowtypeExpr:
2884  {
2885  ConvertRowtypeExpr *convexpr = (ConvertRowtypeExpr *) node;
2886  ConvertRowtypeExpr *newnode;
2887 
2888  FLATCOPY(newnode, convexpr, ConvertRowtypeExpr);
2889  MUTATE(newnode->arg, convexpr->arg, Expr *);
2890  return (Node *) newnode;
2891  }
2892  break;
2893  case T_CollateExpr:
2894  {
2895  CollateExpr *collate = (CollateExpr *) node;
2896  CollateExpr *newnode;
2897 
2898  FLATCOPY(newnode, collate, CollateExpr);
2899  MUTATE(newnode->arg, collate->arg, Expr *);
2900  return (Node *) newnode;
2901  }
2902  break;
2903  case T_CaseExpr:
2904  {
2905  CaseExpr *caseexpr = (CaseExpr *) node;
2906  CaseExpr *newnode;
2907 
2908  FLATCOPY(newnode, caseexpr, CaseExpr);
2909  MUTATE(newnode->arg, caseexpr->arg, Expr *);
2910  MUTATE(newnode->args, caseexpr->args, List *);
2911  MUTATE(newnode->defresult, caseexpr->defresult, Expr *);
2912  return (Node *) newnode;
2913  }
2914  break;
2915  case T_CaseWhen:
2916  {
2917  CaseWhen *casewhen = (CaseWhen *) node;
2918  CaseWhen *newnode;
2919 
2920  FLATCOPY(newnode, casewhen, CaseWhen);
2921  MUTATE(newnode->expr, casewhen->expr, Expr *);
2922  MUTATE(newnode->result, casewhen->result, Expr *);
2923  return (Node *) newnode;
2924  }
2925  break;
2926  case T_ArrayExpr:
2927  {
2928  ArrayExpr *arrayexpr = (ArrayExpr *) node;
2929  ArrayExpr *newnode;
2930 
2931  FLATCOPY(newnode, arrayexpr, ArrayExpr);
2932  MUTATE(newnode->elements, arrayexpr->elements, List *);
2933  return (Node *) newnode;
2934  }
2935  break;
2936  case T_RowExpr:
2937  {
2938  RowExpr *rowexpr = (RowExpr *) node;
2939  RowExpr *newnode;
2940 
2941  FLATCOPY(newnode, rowexpr, RowExpr);
2942  MUTATE(newnode->args, rowexpr->args, List *);
2943  /* Assume colnames needn't be duplicated */
2944  return (Node *) newnode;
2945  }
2946  break;
2947  case T_RowCompareExpr:
2948  {
2949  RowCompareExpr *rcexpr = (RowCompareExpr *) node;
2950  RowCompareExpr *newnode;
2951 
2952  FLATCOPY(newnode, rcexpr, RowCompareExpr);
2953  MUTATE(newnode->largs, rcexpr->largs, List *);
2954  MUTATE(newnode->rargs, rcexpr->rargs, List *);
2955  return (Node *) newnode;
2956  }
2957  break;
2958  case T_CoalesceExpr:
2959  {
2960  CoalesceExpr *coalesceexpr = (CoalesceExpr *) node;
2961  CoalesceExpr *newnode;
2962 
2963  FLATCOPY(newnode, coalesceexpr, CoalesceExpr);
2964  MUTATE(newnode->args, coalesceexpr->args, List *);
2965  return (Node *) newnode;
2966  }
2967  break;
2968  case T_MinMaxExpr:
2969  {
2970  MinMaxExpr *minmaxexpr = (MinMaxExpr *) node;
2971  MinMaxExpr *newnode;
2972 
2973  FLATCOPY(newnode, minmaxexpr, MinMaxExpr);
2974  MUTATE(newnode->args, minmaxexpr->args, List *);
2975  return (Node *) newnode;
2976  }
2977  break;
2978  case T_XmlExpr:
2979  {
2980  XmlExpr *xexpr = (XmlExpr *) node;
2981  XmlExpr *newnode;
2982 
2983  FLATCOPY(newnode, xexpr, XmlExpr);
2984  MUTATE(newnode->named_args, xexpr->named_args, List *);
2985  /* assume mutator does not care about arg_names */
2986  MUTATE(newnode->args, xexpr->args, List *);
2987  return (Node *) newnode;
2988  }
2989  break;
2990  case T_NullTest:
2991  {
2992  NullTest *ntest = (NullTest *) node;
2993  NullTest *newnode;
2994 
2995  FLATCOPY(newnode, ntest, NullTest);
2996  MUTATE(newnode->arg, ntest->arg, Expr *);
2997  return (Node *) newnode;
2998  }
2999  break;
3000  case T_BooleanTest:
3001  {
3002  BooleanTest *btest = (BooleanTest *) node;
3003  BooleanTest *newnode;
3004 
3005  FLATCOPY(newnode, btest, BooleanTest);
3006  MUTATE(newnode->arg, btest->arg, Expr *);
3007  return (Node *) newnode;
3008  }
3009  break;
3010  case T_CoerceToDomain:
3011  {
3012  CoerceToDomain *ctest = (CoerceToDomain *) node;
3013  CoerceToDomain *newnode;
3014 
3015  FLATCOPY(newnode, ctest, CoerceToDomain);
3016  MUTATE(newnode->arg, ctest->arg, Expr *);
3017  return (Node *) newnode;
3018  }
3019  break;
3020  case T_TargetEntry:
3021  {
3022  TargetEntry *targetentry = (TargetEntry *) node;
3023  TargetEntry *newnode;
3024 
3025  FLATCOPY(newnode, targetentry, TargetEntry);
3026  MUTATE(newnode->expr, targetentry->expr, Expr *);
3027  return (Node *) newnode;
3028  }
3029  break;
3030  case T_Query:
3031  /* Do nothing with a sub-Query, per discussion above */
3032  return node;
3033  case T_WindowClause:
3034  {
3035  WindowClause *wc = (WindowClause *) node;
3036  WindowClause *newnode;
3037 
3038  FLATCOPY(newnode, wc, WindowClause);
3039  MUTATE(newnode->partitionClause, wc->partitionClause, List *);
3040  MUTATE(newnode->orderClause, wc->orderClause, List *);
3041  MUTATE(newnode->startOffset, wc->startOffset, Node *);
3042  MUTATE(newnode->endOffset, wc->endOffset, Node *);
3043  return (Node *) newnode;
3044  }
3045  break;
3046  case T_CTECycleClause:
3047  {
3048  CTECycleClause *cc = (CTECycleClause *) node;
3049  CTECycleClause *newnode;
3050 
3051  FLATCOPY(newnode, cc, CTECycleClause);
3052  MUTATE(newnode->cycle_mark_value, cc->cycle_mark_value, Node *);
3054  return (Node *) newnode;
3055  }
3056  break;
3057  case T_CommonTableExpr:
3058  {
3059  CommonTableExpr *cte = (CommonTableExpr *) node;
3060  CommonTableExpr *newnode;
3061 
3062  FLATCOPY(newnode, cte, CommonTableExpr);
3063 
3064  /*
3065  * Also invoke the mutator on the CTE's Query node, so it can
3066  * recurse into the sub-query if it wants to.
3067  */
3068  MUTATE(newnode->ctequery, cte->ctequery, Node *);
3069 
3071  MUTATE(newnode->cycle_clause, cte->cycle_clause, CTECycleClause *);
3072 
3073  return (Node *) newnode;
3074  }
3075  break;
3076  case T_List:
3077  {
3078  /*
3079  * We assume the mutator isn't interested in the list nodes
3080  * per se, so just invoke it on each list element. NOTE: this
3081  * would fail badly on a list with integer elements!
3082  */
3083  List *resultlist;
3084  ListCell *temp;
3085 
3086  resultlist = NIL;
3087  foreach(temp, (List *) node)
3088  {
3089  resultlist = lappend(resultlist,
3090  mutator((Node *) lfirst(temp),
3091  context));
3092  }
3093  return (Node *) resultlist;
3094  }
3095  break;
3096  case T_FromExpr:
3097  {
3098  FromExpr *from = (FromExpr *) node;
3099  FromExpr *newnode;
3100 
3101  FLATCOPY(newnode, from, FromExpr);
3102  MUTATE(newnode->fromlist, from->fromlist, List *);
3103  MUTATE(newnode->quals, from->quals, Node *);
3104  return (Node *) newnode;
3105  }
3106  break;
3107  case T_OnConflictExpr:
3108  {
3109  OnConflictExpr *oc = (OnConflictExpr *) node;
3110  OnConflictExpr *newnode;
3111 
3112  FLATCOPY(newnode, oc, OnConflictExpr);
3113  MUTATE(newnode->arbiterElems, oc->arbiterElems, List *);
3114  MUTATE(newnode->arbiterWhere, oc->arbiterWhere, Node *);
3115  MUTATE(newnode->onConflictSet, oc->onConflictSet, List *);
3116  MUTATE(newnode->onConflictWhere, oc->onConflictWhere, Node *);
3117  MUTATE(newnode->exclRelTlist, oc->exclRelTlist, List *);
3118 
3119  return (Node *) newnode;
3120  }
3121  break;
3123  {
3124  PartitionPruneStepOp *opstep = (PartitionPruneStepOp *) node;
3125  PartitionPruneStepOp *newnode;
3126 
3127  FLATCOPY(newnode, opstep, PartitionPruneStepOp);
3128  MUTATE(newnode->exprs, opstep->exprs, List *);
3129 
3130  return (Node *) newnode;
3131  }
3132  break;
3134  /* no expression sub-nodes */
3135  return (Node *) copyObject(node);
3136  case T_JoinExpr:
3137  {
3138  JoinExpr *join = (JoinExpr *) node;
3139  JoinExpr *newnode;
3140 
3141  FLATCOPY(newnode, join, JoinExpr);
3142  MUTATE(newnode->larg, join->larg, Node *);
3143  MUTATE(newnode->rarg, join->rarg, Node *);
3144  MUTATE(newnode->quals, join->quals, Node *);
3145  /* We do not mutate alias or using by default */
3146  return (Node *) newnode;
3147  }
3148  break;
3149  case T_SetOperationStmt:
3150  {
3151  SetOperationStmt *setop = (SetOperationStmt *) node;
3152  SetOperationStmt *newnode;
3153 
3154  FLATCOPY(newnode, setop, SetOperationStmt);
3155  MUTATE(newnode->larg, setop->larg, Node *);
3156  MUTATE(newnode->rarg, setop->rarg, Node *);
3157  /* We do not mutate groupClauses by default */
3158  return (Node *) newnode;
3159  }
3160  break;
3161  case T_IndexClause:
3162  {
3163  IndexClause *iclause = (IndexClause *) node;
3164  IndexClause *newnode;
3165 
3166  FLATCOPY(newnode, iclause, IndexClause);
3167  MUTATE(newnode->rinfo, iclause->rinfo, RestrictInfo *);
3168  MUTATE(newnode->indexquals, iclause->indexquals, List *);
3169  return (Node *) newnode;
3170  }
3171  break;
3172  case T_PlaceHolderVar:
3173  {
3174  PlaceHolderVar *phv = (PlaceHolderVar *) node;
3175  PlaceHolderVar *newnode;
3176 
3177  FLATCOPY(newnode, phv, PlaceHolderVar);
3178  MUTATE(newnode->phexpr, phv->phexpr, Expr *);
3179  /* Assume we need not copy the relids bitmapset */
3180  return (Node *) newnode;
3181  }
3182  break;
3183  case T_InferenceElem:
3184  {
3185  InferenceElem *inferenceelemdexpr = (InferenceElem *) node;
3186  InferenceElem *newnode;
3187 
3188  FLATCOPY(newnode, inferenceelemdexpr, InferenceElem);
3189  MUTATE(newnode->expr, newnode->expr, Node *);
3190  return (Node *) newnode;
3191  }
3192  break;
3193  case T_AppendRelInfo:
3194  {
3195  AppendRelInfo *appinfo = (AppendRelInfo *) node;
3196  AppendRelInfo *newnode;
3197 
3198  FLATCOPY(newnode, appinfo, AppendRelInfo);
3199  MUTATE(newnode->translated_vars, appinfo->translated_vars, List *);
3200  /* Assume nothing need be done with parent_colnos[] */
3201  return (Node *) newnode;
3202  }
3203  break;
3204  case T_PlaceHolderInfo:
3205  {
3206  PlaceHolderInfo *phinfo = (PlaceHolderInfo *) node;
3207  PlaceHolderInfo *newnode;
3208 
3209  FLATCOPY(newnode, phinfo, PlaceHolderInfo);
3210  MUTATE(newnode->ph_var, phinfo->ph_var, PlaceHolderVar *);
3211  /* Assume we need not copy the relids bitmapsets */
3212  return (Node *) newnode;
3213  }
3214  break;
3215  case T_RangeTblFunction:
3216  {
3217  RangeTblFunction *rtfunc = (RangeTblFunction *) node;
3218  RangeTblFunction *newnode;
3219 
3220  FLATCOPY(newnode, rtfunc, RangeTblFunction);
3221  MUTATE(newnode->funcexpr, rtfunc->funcexpr, Node *);
3222  /* Assume we need not copy the coldef info lists */
3223  return (Node *) newnode;
3224  }
3225  break;
3226  case T_TableSampleClause:
3227  {
3228  TableSampleClause *tsc = (TableSampleClause *) node;
3229  TableSampleClause *newnode;
3230 
3231  FLATCOPY(newnode, tsc, TableSampleClause);
3232  MUTATE(newnode->args, tsc->args, List *);
3233  MUTATE(newnode->repeatable, tsc->repeatable, Expr *);
3234  return (Node *) newnode;
3235  }
3236  break;
3237  case T_TableFunc:
3238  {
3239  TableFunc *tf = (TableFunc *) node;
3240  TableFunc *newnode;
3241 
3242  FLATCOPY(newnode, tf, TableFunc);
3243  MUTATE(newnode->ns_uris, tf->ns_uris, List *);
3244  MUTATE(newnode->docexpr, tf->docexpr, Node *);
3245  MUTATE(newnode->rowexpr, tf->rowexpr, Node *);
3246  MUTATE(newnode->colexprs, tf->colexprs, List *);
3247  MUTATE(newnode->coldefexprs, tf->coldefexprs, List *);
3248  return (Node *) newnode;
3249  }
3250  break;
3251  default:
3252  elog(ERROR, "unrecognized node type: %d",
3253  (int) nodeTag(node));
3254  break;
3255  }
3256  /* can't get here, but keep compiler happy */
3257  return NULL;
3258 }
List * aggdistinct
Definition: primnodes.h:327
#define NIL
Definition: pg_list.h:65
List * args
Definition: primnodes.h:1130
List * args
Definition: primnodes.h:1046
Node * docexpr
Definition: primnodes.h:87
Expr * arg
Definition: primnodes.h:815
PlaceHolderVar * ph_var
Definition: pathnodes.h:2328
List * args
Definition: primnodes.h:367
List * refs
Definition: primnodes.h:369
List * args
Definition: primnodes.h:385
List * args
Definition: primnodes.h:498
Expr * arg
Definition: primnodes.h:838
List * list_copy(const List *oldlist)
Definition: list.c:1418
Definition: nodes.h:533
List * args
Definition: primnodes.h:325
Expr * arg
Definition: primnodes.h:786
List * fromlist
Definition: primnodes.h:1534
Definition: primnodes.h:181
List * refupperindexpr
Definition: primnodes.h:439
List * translated_vars
Definition: pathnodes.h:2278
Node * quals
Definition: primnodes.h:1535
List * arbiterElems
Definition: primnodes.h:1553
Node * larg
Definition: primnodes.h:1514
List * aggargtypes
Definition: primnodes.h:323
#define ERROR
Definition: elog.h:45
CTESearchClause * search_clause
Definition: parsenodes.h:1484
List * partitionClause
Definition: parsenodes.h:1358
List * args
Definition: primnodes.h:1110
Expr * arg
Definition: primnodes.h:1243
List * coldefexprs
Definition: primnodes.h:94
Node * rowexpr
Definition: primnodes.h:88
struct RestrictInfo * rinfo
Definition: pathnodes.h:1263
List * exclRelTlist
Definition: primnodes.h:1562
void check_stack_depth(void)
Definition: postgres.c:3310
List * aggorder
Definition: primnodes.h:326
Expr * arg
Definition: primnodes.h:1266
List * aggdirectargs
Definition: primnodes.h:324
Expr * arg
Definition: primnodes.h:858
List * elements
Definition: primnodes.h:1015
Expr * elemexpr
Definition: primnodes.h:883
List * indexquals
Definition: pathnodes.h:1264
Definition: nodes.h:301
List * newvals
Definition: primnodes.h:816
List * cols
Definition: primnodes.h:370
Definition: nodes.h:156
List * lappend(List *list, void *datum)
Definition: list.c:336
Definition: nodes.h:155
Node * startOffset
Definition: parsenodes.h:1361
List * args
Definition: primnodes.h:957
Definition: nodes.h:314
Node * quals
Definition: primnodes.h:1517
#define FLATCOPY(newnode, node, nodetype)
Node * testexpr
Definition: primnodes.h:727
List * colexprs
Definition: primnodes.h:93
List * named_args
Definition: primnodes.h:1207
List * args
Definition: primnodes.h:1209
Node * rarg
Definition: primnodes.h:1515
Expr * arg
Definition: primnodes.h:519
#define lfirst(lc)
Definition: pg_list.h:169
List * ns_uris
Definition: primnodes.h:85
Expr * aggfilter
Definition: primnodes.h:386
Expr * expr
Definition: primnodes.h:1431
Node * endOffset
Definition: parsenodes.h:1362
Expr * arg
Definition: primnodes.h:924
Node * cycle_mark_value
Definition: parsenodes.h:1465
Expr * aggfilter
Definition: primnodes.h:328
List * args
Definition: primnodes.h:604
Node * cycle_mark_default
Definition: parsenodes.h:1466
#define nodeTag(nodeptr)
Definition: nodes.h:538
Node * arbiterWhere
Definition: primnodes.h:1555
List * orderClause
Definition: parsenodes.h:1359
Expr * refassgnexpr
Definition: primnodes.h:446
CTECycleClause * cycle_clause
Definition: parsenodes.h:1485
List * fieldnums
Definition: primnodes.h:817
List * reflowerindexpr
Definition: primnodes.h:441
#define elog(elevel,...)
Definition: elog.h:227
List * onConflictSet
Definition: primnodes.h:1559
Expr * refexpr
Definition: primnodes.h:444
Expr * arg
Definition: primnodes.h:956
Expr * result
Definition: primnodes.h:969
#define copyObject(obj)
Definition: nodes.h:649
List * args
Definition: primnodes.h:543
Expr * defresult
Definition: primnodes.h:958
Expr * expr
Definition: primnodes.h:968
Node * onConflictWhere
Definition: primnodes.h:1560
Definition: pg_list.h:50
#define MUTATE(newfield, oldfield, fieldtype)
Definition: nodes.h:157
List * args
Definition: primnodes.h:751

◆ expression_tree_walker()

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

Definition at line 1885 of file nodeFuncs.c.

References 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, Aggref::args, GroupingFunc::args, WindowFunc::args, FuncExpr::args, OpExpr::args, ScalarArrayOpExpr::args, BoolExpr::args, SubPlan::args, CaseExpr::args, TableSampleClause::args, XmlExpr::args, check_stack_depth(), TableFunc::coldefexprs, TableFunc::colexprs, CommonTableExpr::ctequery, CommonTableExpr::cycle_clause, CTECycleClause::cycle_mark_default, CTECycleClause::cycle_mark_value, CaseExpr::defresult, TableFunc::docexpr, ArrayCoerceExpr::elemexpr, elog, WindowClause::endOffset, ERROR, OnConflictExpr::exclRelTlist, CaseWhen::expr, expression_tree_walker(), PartitionPruneStepOp::exprs, FromExpr::fromlist, IndexClause::indexquals, JoinExpr::larg, SetOperationStmt::larg, RowCompareExpr::largs, lfirst, lfirst_node, XmlExpr::named_args, FieldStore::newvals, nodeTag, TableFunc::ns_uris, OnConflictExpr::onConflictSet, OnConflictExpr::onConflictWhere, WindowClause::orderClause, WindowClause::partitionClause, JoinExpr::quals, FromExpr::quals, JoinExpr::rarg, SetOperationStmt::rarg, RowCompareExpr::rargs, SubscriptingRef::refassgnexpr, SubscriptingRef::refexpr, SubscriptingRef::reflowerindexpr, SubscriptingRef::refupperindexpr, TableSampleClause::repeatable, CaseWhen::result, IndexClause::rinfo, TableFunc::rowexpr, CommonTableExpr::search_clause, WindowClause::startOffset, 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_List, T_MinMaxExpr, T_NamedArgExpr, T_NextValueExpr, T_NullIfExpr, T_NullTest, T_OnConflictExpr, T_OpExpr, T_Param, T_PartitionPruneStepCombine, T_PartitionPruneStepOp, 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, and AppendRelInfo::translated_vars.

Referenced by acquireLocksOnSubLinks(), assign_collations_walker(), ChangeVarNodes_walker(), check_agg_arguments(), check_agg_arguments_walker(), check_nested_generated_walker(), check_parameter_resolution_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_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(), cost_qual_eval_walker(), expression_returns_set_walker(), expression_tree_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(), get_notclausearg(), 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_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().

1888 {
1889  ListCell *temp;
1890 
1891  /*
1892  * The walker has already visited the current node, and so we need only
1893  * recurse into any sub-nodes it has.
1894  *
1895  * We assume that the walker is not interested in List nodes per se, so
1896  * when we expect a List we just recurse directly to self without
1897  * bothering to call the walker.
1898  */
1899  if (node == NULL)
1900  return false;
1901 
1902  /* Guard against stack overflow due to overly complex expressions */
1904 
1905  switch (nodeTag(node))
1906  {
1907  case T_Var:
1908  case T_Const:
1909  case T_Param:
1910  case T_CaseTestExpr:
1911  case T_SQLValueFunction:
1912  case T_CoerceToDomainValue:
1913  case T_SetToDefault:
1914  case T_CurrentOfExpr:
1915  case T_NextValueExpr:
1916  case T_RangeTblRef:
1917  case T_SortGroupClause:
1918  case T_CTESearchClause:
1919  /* primitive node types with no expression subnodes */
1920  break;
1921  case T_WithCheckOption:
1922  return walker(((WithCheckOption *) node)->qual, context);
1923  case T_Aggref:
1924  {
1925  Aggref *expr = (Aggref *) node;
1926 
1927  /* recurse directly on List */
1929  walker, context))
1930  return true;
1931  if (expression_tree_walker((Node *) expr->args,
1932  walker, context))
1933  return true;
1934  if (expression_tree_walker((Node *) expr->aggorder,
1935  walker, context))
1936  return true;
1937  if (expression_tree_walker((Node *) expr->aggdistinct,
1938  walker, context))
1939  return true;
1940  if (walker((Node *) expr->aggfilter, context))
1941  return true;
1942  }
1943  break;
1944  case T_GroupingFunc:
1945  {
1946  GroupingFunc *grouping = (GroupingFunc *) node;
1947 
1948  if (expression_tree_walker((Node *) grouping->args,
1949  walker, context))
1950  return true;
1951  }
1952  break;
1953  case T_WindowFunc:
1954  {
1955  WindowFunc *expr = (WindowFunc *) node;
1956 
1957  /* recurse directly on List */
1958  if (expression_tree_walker((Node *) expr->args,
1959  walker, context))
1960  return true;
1961  if (walker((Node *) expr->aggfilter, context))
1962  return true;
1963  }
1964  break;
1965  case T_SubscriptingRef:
1966  {
1967  SubscriptingRef *sbsref = (SubscriptingRef *) node;
1968 
1969  /* recurse directly for upper/lower container index lists */
1971  walker, context))
1972  return true;
1974  walker, context))
1975  return true;
1976  /* walker must see the refexpr and refassgnexpr, however */
1977  if (walker(sbsref->refexpr, context))
1978  return true;
1979 
1980  if (walker(sbsref->refassgnexpr, context))
1981  return true;
1982  }
1983  break;
1984  case T_FuncExpr:
1985  {
1986  FuncExpr *expr = (FuncExpr *) node;
1987 
1988  if (expression_tree_walker((Node *) expr->args,
1989  walker, context))
1990  return true;
1991  }
1992  break;
1993  case T_NamedArgExpr:
1994  return walker(((NamedArgExpr *) node)->arg, context);
1995  case T_OpExpr:
1996  case T_DistinctExpr: /* struct-equivalent to OpExpr */
1997  case T_NullIfExpr: /* struct-equivalent to OpExpr */
1998  {
1999  OpExpr *expr = (OpExpr *) node;
2000 
2001  if (expression_tree_walker((Node *) expr->args,
2002  walker, context))
2003  return true;
2004  }
2005  break;
2006  case T_ScalarArrayOpExpr:
2007  {
2008  ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
2009 
2010  if (expression_tree_walker((Node *) expr->args,
2011  walker, context))
2012  return true;
2013  }
2014  break;
2015  case T_BoolExpr:
2016  {
2017  BoolExpr *expr = (BoolExpr *) node;
2018 
2019  if (expression_tree_walker((Node *) expr->args,
2020  walker, context))
2021  return true;
2022  }
2023  break;
2024  case T_SubLink:
2025  {
2026  SubLink *sublink = (SubLink *) node;
2027 
2028  if (walker(sublink->testexpr, context))
2029  return true;
2030 
2031  /*
2032  * Also invoke the walker on the sublink's Query node, so it
2033  * can recurse into the sub-query if it wants to.
2034  */
2035  return walker(sublink->subselect, context);
2036  }
2037  break;
2038  case T_SubPlan:
2039  {
2040  SubPlan *subplan = (SubPlan *) node;
2041 
2042  /* recurse into the testexpr, but not into the Plan */
2043  if (walker(subplan->testexpr, context))
2044  return true;
2045  /* also examine args list */
2046  if (expression_tree_walker((Node *) subplan->args,
2047  walker, context))
2048  return true;
2049  }
2050  break;
2051  case T_AlternativeSubPlan:
2052  return walker(((AlternativeSubPlan *) node)->subplans, context);
2053  case T_FieldSelect:
2054  return walker(((FieldSelect *) node)->arg, context);
2055  case T_FieldStore:
2056  {
2057  FieldStore *fstore = (FieldStore *) node;
2058 
2059  if (walker(fstore->arg, context))
2060  return true;
2061  if (walker(fstore->newvals, context))
2062  return true;
2063  }
2064  break;
2065  case T_RelabelType:
2066  return walker(((RelabelType *) node)->arg, context);
2067  case T_CoerceViaIO:
2068  return walker(((CoerceViaIO *) node)->arg, context);
2069  case T_ArrayCoerceExpr:
2070  {
2071  ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node;
2072 
2073  if (walker(acoerce->arg, context))
2074  return true;
2075  if (walker(acoerce->elemexpr, context))
2076  return true;
2077  }
2078  break;
2079  case T_ConvertRowtypeExpr:
2080  return walker(((ConvertRowtypeExpr *) node)->arg, context);
2081  case T_CollateExpr:
2082  return walker(((CollateExpr *) node)->arg, context);
2083  case T_CaseExpr:
2084  {
2085  CaseExpr *caseexpr = (CaseExpr *) node;
2086 
2087  if (walker(caseexpr->arg, context))
2088  return true;
2089  /* we assume walker doesn't care about CaseWhens, either */
2090  foreach(temp, caseexpr->args)
2091  {
2092  CaseWhen *when = lfirst_node(CaseWhen, temp);
2093 
2094  if (walker(when->expr, context))
2095  return true;
2096  if (walker(when->result, context))
2097  return true;
2098  }
2099  if (walker(caseexpr->defresult, context))
2100  return true;
2101  }
2102  break;
2103  case T_ArrayExpr:
2104  return walker(((ArrayExpr *) node)->elements, context);
2105  case T_RowExpr:
2106  /* Assume colnames isn't interesting */
2107  return walker(((RowExpr *) node)->args, context);
2108  case T_RowCompareExpr:
2109  {
2110  RowCompareExpr *rcexpr = (RowCompareExpr *) node;
2111 
2112  if (walker(rcexpr->largs, context))
2113  return true;
2114  if (walker(rcexpr->rargs, context))
2115  return true;
2116  }
2117  break;
2118  case T_CoalesceExpr:
2119  return walker(((CoalesceExpr *) node)->args, context);
2120  case T_MinMaxExpr:
2121  return walker(((MinMaxExpr *) node)->args, context);
2122  case T_XmlExpr:
2123  {
2124  XmlExpr *xexpr = (XmlExpr *) node;
2125 
2126  if (walker(xexpr->named_args, context))
2127  return true;
2128  /* we assume walker doesn't care about arg_names */
2129  if (walker(xexpr->args, context))
2130  return true;
2131  }
2132  break;
2133  case T_NullTest:
2134  return walker(((NullTest *) node)->arg, context);
2135  case T_BooleanTest:
2136  return walker(((BooleanTest *) node)->arg, context);
2137  case T_CoerceToDomain:
2138  return walker(((CoerceToDomain *) node)->arg, context);
2139  case T_TargetEntry:
2140  return walker(((TargetEntry *) node)->expr, context);
2141  case T_Query:
2142  /* Do nothing with a sub-Query, per discussion above */
2143  break;
2144  case T_WindowClause:
2145  {
2146  WindowClause *wc = (WindowClause *) node;
2147 
2148  if (walker(wc->partitionClause, context))
2149  return true;
2150  if (walker(wc->orderClause, context))
2151  return true;
2152  if (walker(wc->startOffset, context))
2153  return true;
2154  if (walker(wc->endOffset, context))
2155  return true;
2156  }
2157  break;
2158  case T_CTECycleClause:
2159  {
2160  CTECycleClause *cc = (CTECycleClause *) node;
2161 
2162  if (walker(cc->cycle_mark_value, context))
2163  return true;
2164  if (walker(cc->cycle_mark_default, context))
2165  return true;
2166  }
2167  break;
2168  case T_CommonTableExpr:
2169  {
2170  CommonTableExpr *cte = (CommonTableExpr *) node;
2171 
2172  /*
2173  * Invoke the walker on the CTE's Query node, so it can
2174  * recurse into the sub-query if it wants to.
2175  */
2176  if (walker(cte->ctequery, context))
2177  return true;
2178 
2179  if (walker(cte->search_clause, context))
2180  return true;
2181  if (walker(cte->cycle_clause, context))
2182  return true;
2183  }
2184  break;
2185  case T_List:
2186  foreach(temp, (List *) node)
2187  {
2188  if (walker((Node *) lfirst(temp), context))
2189  return true;
2190  }
2191  break;
2192  case T_FromExpr:
2193  {
2194  FromExpr *from = (FromExpr *) node;
2195 
2196  if (walker(from->fromlist, context))
2197  return true;
2198  if (walker(from->quals, context))
2199  return true;
2200  }
2201  break;
2202  case T_OnConflictExpr:
2203  {
2204  OnConflictExpr *onconflict = (OnConflictExpr *) node;
2205 
2206  if (walker((Node *) onconflict->arbiterElems, context))
2207  return true;
2208  if (walker(onconflict->arbiterWhere, context))
2209  return true;
2210  if (walker(onconflict->onConflictSet, context))
2211  return true;
2212  if (walker(onconflict->onConflictWhere, context))
2213  return true;
2214  if (walker(onconflict->exclRelTlist, context))
2215  return true;
2216  }
2217  break;
2219  {
2220  PartitionPruneStepOp *opstep = (PartitionPruneStepOp *) node;
2221 
2222  if (walker((Node *) opstep->exprs, context))
2223  return true;
2224  }
2225  break;
2227  /* no expression subnodes */
2228  break;
2229  case T_JoinExpr:
2230  {
2231  JoinExpr *join = (JoinExpr *) node;
2232 
2233  if (walker(join->larg, context))
2234  return true;
2235  if (walker(join->rarg, context))
2236  return true;
2237  if (walker(join->quals, context))
2238  return true;
2239 
2240  /*
2241  * alias clause, using list are deemed uninteresting.
2242  */
2243  }
2244  break;
2245  case T_SetOperationStmt:
2246  {
2247  SetOperationStmt *setop = (SetOperationStmt *) node;
2248 
2249  if (walker(setop->larg, context))
2250  return true;
2251  if (walker(setop->rarg, context))
2252  return true;
2253 
2254  /* groupClauses are deemed uninteresting */
2255  }
2256  break;
2257  case T_IndexClause:
2258  {
2259  IndexClause *iclause = (IndexClause *) node;
2260 
2261  if (walker(iclause->rinfo, context))
2262  return true;
2263  if (expression_tree_walker((Node *) iclause->indexquals,
2264  walker, context))
2265  return true;
2266  }
2267  break;
2268  case T_PlaceHolderVar:
2269  return walker(((PlaceHolderVar *) node)->phexpr, context);
2270  case T_InferenceElem:
2271  return walker(((InferenceElem *) node)->expr, context);
2272  case T_AppendRelInfo:
2273  {
2274  AppendRelInfo *appinfo = (AppendRelInfo *) node;
2275 
2276  if (expression_tree_walker((Node *) appinfo->translated_vars,
2277  walker, context))
2278  return true;
2279  }
2280  break;
2281  case T_PlaceHolderInfo:
2282  return walker(((PlaceHolderInfo *) node)->ph_var, context);
2283  case T_RangeTblFunction:
2284  return walker(((RangeTblFunction *) node)->funcexpr, context);
2285  case T_TableSampleClause:
2286  {
2287  TableSampleClause *tsc = (TableSampleClause *) node;
2288 
2289  if (expression_tree_walker((Node *) tsc->args,
2290  walker, context))
2291  return true;
2292  if (walker((Node *) tsc->repeatable, context))
2293  return true;
2294  }
2295  break;
2296  case T_TableFunc:
2297  {
2298  TableFunc *tf = (TableFunc *) node;
2299 
2300  if (walker(tf->ns_uris, context))
2301  return true;
2302  if (walker(tf->docexpr, context))
2303  return true;
2304  if (walker(tf->rowexpr, context))
2305  return true;
2306  if (walker(tf->colexprs, context))
2307  return true;
2308  if (walker(tf->coldefexprs, context))
2309  return true;
2310  }
2311  break;
2312  default:
2313  elog(ERROR, "unrecognized node type: %d",
2314  (int) nodeTag(node));
2315  break;
2316  }
2317  return false;
2318 }
List * aggdistinct
Definition: primnodes.h:327
Node * docexpr
Definition: primnodes.h:87
Expr * arg
Definition: primnodes.h:815
List * args
Definition: primnodes.h:367
List * args
Definition: primnodes.h:385
List * args
Definition: primnodes.h:498
Definition: nodes.h:533
List * args
Definition: primnodes.h:325
List * fromlist
Definition: primnodes.h:1534
List * refupperindexpr
Definition: primnodes.h:439
List * translated_vars
Definition: pathnodes.h:2278
Node * quals
Definition: primnodes.h:1535
List * arbiterElems
Definition: primnodes.h:1553
Node * larg
Definition: primnodes.h:1514
#define ERROR
Definition: elog.h:45
CTESearchClause * search_clause
Definition: parsenodes.h:1484
List * partitionClause
Definition: parsenodes.h:1358
List * coldefexprs
Definition: primnodes.h:94
#define lfirst_node(type, lc)
Definition: pg_list.h:172
Node * rowexpr
Definition: primnodes.h:88
struct RestrictInfo * rinfo
Definition: pathnodes.h:1263
List * exclRelTlist
Definition: primnodes.h:1562
void check_stack_depth(void)
Definition: postgres.c:3310
List * aggorder
Definition: primnodes.h:326
List * aggdirectargs
Definition: primnodes.h:324
Expr * elemexpr
Definition: primnodes.h:883
Definition: type.h:82
List * indexquals
Definition: pathnodes.h:1264
Definition: nodes.h:301
List * newvals
Definition: primnodes.h:816
Definition: nodes.h:156
Definition: nodes.h:155
Node * startOffset
Definition: parsenodes.h:1361
List * args
Definition: primnodes.h:957
Definition: nodes.h:314
Node * quals
Definition: primnodes.h:1517
Node * testexpr
Definition: primnodes.h:727
List * colexprs
Definition: primnodes.h:93
List * named_args
Definition: primnodes.h:1207
List * args
Definition: primnodes.h:1209
Node * rarg
Definition: primnodes.h:1515
#define lfirst(lc)
Definition: pg_list.h:169
List * ns_uris
Definition: primnodes.h:85
Expr * aggfilter
Definition: primnodes.h:386
Node * endOffset
Definition: parsenodes.h:1362
bool expression_tree_walker(Node *node, bool(*walker)(), void *context)
Definition: nodeFuncs.c:1885
Node * cycle_mark_value
Definition: parsenodes.h:1465
Expr * aggfilter
Definition: primnodes.h:328
List * args
Definition: primnodes.h:604
Node * cycle_mark_default
Definition: parsenodes.h:1466
#define nodeTag(nodeptr)
Definition: nodes.h:538
Node * arbiterWhere
Definition: primnodes.h:1555
List * orderClause
Definition: parsenodes.h:1359
Expr * refassgnexpr
Definition: primnodes.h:446
CTECycleClause * cycle_clause
Definition: parsenodes.h:1485
List * reflowerindexpr
Definition: primnodes.h:441
#define elog(elevel,...)
Definition: elog.h:227
List * onConflictSet
Definition: primnodes.h:1559
void * arg
Expr * refexpr
Definition: primnodes.h:444
Expr * arg
Definition: primnodes.h:956
Expr * result
Definition: primnodes.h:969
List * args
Definition: primnodes.h:543
Expr * defresult
Definition: primnodes.h:958
Expr * expr
Definition: primnodes.h:968
Node * onConflictWhere
Definition: primnodes.h:1560
Definition: pg_list.h:50
Definition: nodes.h:157
List * args
Definition: primnodes.h:751

◆ exprInputCollation()

Oid exprInputCollation ( const Node expr)

Definition at line 964 of file nodeFuncs.c.

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

Referenced by resolve_polymorphic_tupdesc().

965 {
966  Oid coll;
967 
968  if (!expr)
969  return InvalidOid;
970 
971  switch (nodeTag(expr))
972  {
973  case T_Aggref:
974  coll = ((const Aggref *) expr)->inputcollid;
975  break;
976  case T_WindowFunc:
977  coll = ((const WindowFunc *) expr)->inputcollid;
978  break;
979  case T_FuncExpr:
980  coll = ((const FuncExpr *) expr)->inputcollid;
981  break;
982  case T_OpExpr:
983  coll = ((const OpExpr *) expr)->inputcollid;
984  break;
985  case T_DistinctExpr:
986  coll = ((const DistinctExpr *) expr)->inputcollid;
987  break;
988  case T_NullIfExpr:
989  coll = ((const NullIfExpr *) expr)->inputcollid;
990  break;
991  case T_ScalarArrayOpExpr:
992  coll = ((const ScalarArrayOpExpr *) expr)->inputcollid;
993  break;
994  case T_MinMaxExpr:
995  coll = ((const MinMaxExpr *) expr)->inputcollid;
996  break;
997  default:
998  coll = InvalidOid;
999  break;
1000  }
1001  return coll;
1002 }
unsigned int Oid
Definition: postgres_ext.h:31
#define InvalidOid
Definition: postgres_ext.h:36
#define nodeTag(nodeptr)
Definition: nodes.h:538

◆ exprIsLengthCoercion()

bool exprIsLengthCoercion ( const Node expr,
int32 coercedTypmod 
)

Definition at line 503 of file nodeFuncs.c.

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

504 {
505  if (coercedTypmod != NULL)
506  *coercedTypmod = -1; /* default result on failure */
507 
508  /*
509  * Scalar-type length coercions are FuncExprs, array-type length coercions
510  * are ArrayCoerceExprs
511  */
512  if (expr && IsA(expr, FuncExpr))
513  {
514  const FuncExpr *func = (const FuncExpr *) expr;
515  int nargs;
516  Const *second_arg;
517 
518  /*
519  * If it didn't come from a coercion context, reject.
520  */
521  if (func->funcformat != COERCE_EXPLICIT_CAST &&
523  return false;
524 
525  /*
526  * If it's not a two-argument or three-argument function with the
527  * second argument being an int4 constant, it can't have been created
528  * from a length coercion (it must be a type coercion, instead).
529  */
530  nargs = list_length(func->args);
531  if (nargs < 2 || nargs > 3)
532  return false;
533 
534  second_arg = (Const *) lsecond(func->args);
535  if (!IsA(second_arg, Const) ||
536  second_arg->consttype != INT4OID ||
537  second_arg->constisnull)
538  return false;
539 
540  /*
541  * OK, it is indeed a length-coercion function.
542  */
543  if (coercedTypmod != NULL)
544  *coercedTypmod = DatumGetInt32(second_arg->constvalue);
545 
546  return true;
547  }
548 
549  if (expr && IsA(expr, ArrayCoerceExpr))
550  {
551  const ArrayCoerceExpr *acoerce = (const ArrayCoerceExpr *) expr;
552 
553  /* It's not a length coercion unless there's a nondefault typmod */
554  if (acoerce->resulttypmod < 0)
555  return false;
556 
557  /*
558  * OK, it is indeed a length-coercion expression.
559  */
560  if (coercedTypmod != NULL)
561  *coercedTypmod = acoerce->resulttypmod;
562 
563  return true;
564  }
565 
566  return false;
567 }
Datum constvalue
Definition: primnodes.h:214
#define IsA(nodeptr, _type_)
Definition: nodes.h:584
List * args
Definition: primnodes.h:498
#define DatumGetInt32(X)
Definition: postgres.h:472
#define lsecond(l)
Definition: pg_list.h:179
Oid consttype
Definition: primnodes.h:210
CoercionForm funcformat
Definition: primnodes.h:495
static int list_length(const List *l)
Definition: pg_list.h:149
int32 resulttypmod
Definition: primnodes.h:885
bool constisnull
Definition: primnodes.h:215

◆ exprLocation()

int exprLocation ( const Node expr)

Definition at line 1231 of file nodeFuncs.c.

References arg, TypeCast::arg, NamedArgExpr::arg, RelabelType::arg, CoerceViaIO::arg, ArrayCoerceExpr::arg, ConvertRowtypeExpr::arg, NullTest::arg, BooleanTest::arg, CoerceToDomain::arg, FuncCall::args, FuncExpr::args, OpExpr::args, ScalarArrayOpExpr::args, BoolExpr::args, XmlExpr::args, exprLocation(), fc(), leftmostLoc(), A_Expr::lexpr, lfirst, TypeName::location, A_Expr::location, TypeCast::location, FuncCall::location, FuncExpr::location, NamedArgExpr::location, OpExpr::location, ScalarArrayOpExpr::location, BoolExpr::location, SubLink::location, RelabelType::location, CoerceViaIO::location, ArrayCoerceExpr::location, ConvertRowtypeExpr::location, XmlExpr::location, NullTest::location, BooleanTest::location, CoerceToDomain::location, nodeTag, source, 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_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_srf_call_placement(), checkWellFormedRecursion(), coerce_to_boolean(), coerce_to_common_type(), coerce_to_specific_type_typmod(), EvaluateParams(), ExecInitFunc(), ExecInitSubscriptingRef(), exprLocation(), 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(), transformMultiAssignRef(), transformOnConflictArbiter(), transformPartitionBound(), transformPartitionBoundValue(), transformPartitionRangeBounds(), transformPLAssignStmt(), transformRangeFunction(), transformReturningList(), transformSelectStmt(), transformSetOperationStmt(), transformSetOperationTree(), transformValuesClause(), and validateInfiniteBounds().

1232 {
1233  int loc;
1234 
1235  if (expr == NULL)
1236  return -1;
1237  switch (nodeTag(expr))
1238  {
1239  case T_RangeVar:
1240  loc = ((const RangeVar *) expr)->location;
1241  break;
1242  case T_TableFunc:
1243  loc = ((const TableFunc *) expr)->location;
1244  break;
1245  case T_Var:
1246  loc = ((const Var *) expr)->location;
1247  break;
1248  case T_Const:
1249  loc = ((const Const *) expr)->location;
1250  break;
1251  case T_Param:
1252  loc = ((const Param *) expr)->location;
1253  break;
1254  case T_Aggref:
1255  /* function name should always be the first thing */
1256  loc = ((const Aggref *) expr)->location;
1257  break;
1258  case T_GroupingFunc:
1259  loc = ((const GroupingFunc *) expr)->location;
1260  break;
1261  case T_WindowFunc:
1262  /* function name should always be the first thing */
1263  loc = ((const WindowFunc *) expr)->location;
1264  break;
1265  case T_SubscriptingRef:
1266  /* just use container argument's location */
1267  loc = exprLocation((Node *) ((const SubscriptingRef *) expr)->refexpr);
1268  break;
1269  case T_FuncExpr:
1270  {
1271  const FuncExpr *fexpr = (const FuncExpr *) expr;
1272 
1273  /* consider both function name and leftmost arg */
1274  loc = leftmostLoc(fexpr->location,
1275  exprLocation((Node *) fexpr->args));
1276  }
1277  break;
1278  case T_NamedArgExpr:
1279  {
1280  const NamedArgExpr *na = (const NamedArgExpr *) expr;
1281 
1282  /* consider both argument name and value */
1283  loc = leftmostLoc(na->location,
1284  exprLocation((Node *) na->arg));
1285  }
1286  break;
1287  case T_OpExpr:
1288  case T_DistinctExpr: /* struct-equivalent to OpExpr */
1289  case T_NullIfExpr: /* struct-equivalent to OpExpr */
1290  {
1291  const OpExpr *opexpr = (const OpExpr *) expr;
1292 
1293  /* consider both operator name and leftmost arg */
1294  loc = leftmostLoc(opexpr->location,
1295  exprLocation((Node *) opexpr->args));
1296  }
1297  break;
1298  case T_ScalarArrayOpExpr:
1299  {
1300  const ScalarArrayOpExpr *saopexpr = (const ScalarArrayOpExpr *) expr;
1301 
1302  /* consider both operator name and leftmost arg */
1303  loc = leftmostLoc(saopexpr->location,
1304  exprLocation((Node *) saopexpr->args));
1305  }
1306  break;
1307  case T_BoolExpr:
1308  {
1309  const BoolExpr *bexpr = (const BoolExpr *) expr;
1310 
1311  /*
1312  * Same as above, to handle either NOT or AND/OR. We can't
1313  * special-case NOT because of the way that it's used for
1314  * things like IS NOT BETWEEN.
1315  */
1316  loc = leftmostLoc(bexpr->location,
1317  exprLocation((Node *) bexpr->args));
1318  }
1319  break;
1320  case T_SubLink:
1321  {
1322  const SubLink *sublink = (const SubLink *) expr;
1323 
1324  /* check the testexpr, if any, and the operator/keyword */
1325  loc = leftmostLoc(exprLocation(sublink->testexpr),
1326  sublink->location);
1327  }
1328  break;
1329  case T_FieldSelect:
1330  /* just use argument's location */
1331  loc = exprLocation((Node *) ((const FieldSelect *) expr)->arg);
1332  break;
1333  case T_FieldStore:
1334  /* just use argument's location */
1335  loc = exprLocation((Node *) ((const FieldStore *) expr)->arg);
1336  break;
1337  case T_RelabelType:
1338  {
1339  const RelabelType *rexpr = (const RelabelType *) expr;
1340 
1341  /* Much as above */
1342  loc = leftmostLoc(rexpr->location,
1343  exprLocation((Node *) rexpr->arg));
1344  }
1345  break;
1346  case T_CoerceViaIO:
1347  {
1348  const CoerceViaIO *cexpr = (const CoerceViaIO *) expr;
1349 
1350  /* Much as above */
1351  loc = leftmostLoc(cexpr->location,
1352  exprLocation((Node *) cexpr->arg));
1353  }
1354  break;
1355  case T_ArrayCoerceExpr:
1356  {
1357  const ArrayCoerceExpr *cexpr = (const ArrayCoerceExpr *) expr;
1358 
1359  /* Much as above */
1360  loc = leftmostLoc(cexpr->location,
1361  exprLocation((Node *) cexpr->arg));
1362  }
1363  break;
1364  case T_ConvertRowtypeExpr:
1365  {
1366  const ConvertRowtypeExpr *cexpr = (const ConvertRowtypeExpr *) expr;
1367 
1368  /* Much as above */
1369  loc = leftmostLoc(cexpr->location,
1370  exprLocation((Node *) cexpr->arg));
1371  }
1372  break;
1373  case T_CollateExpr:
1374  /* just use argument's location */
1375  loc = exprLocation((Node *) ((const CollateExpr *) expr)->arg);
1376  break;
1377  case T_CaseExpr:
1378  /* CASE keyword should always be the first thing */
1379  loc = ((const CaseExpr *) expr)->location;
1380  break;
1381  case T_CaseWhen:
1382  /* WHEN keyword should always be the first thing */
1383  loc = ((const CaseWhen *) expr)->location;
1384  break;
1385  case T_ArrayExpr:
1386  /* the location points at ARRAY or [, which must be leftmost */
1387  loc = ((const ArrayExpr *) expr)->location;
1388  break;
1389  case T_RowExpr:
1390  /* the location points at ROW or (, which must be leftmost */
1391  loc = ((const RowExpr *) expr)->location;
1392  break;
1393  case T_RowCompareExpr:
1394  /* just use leftmost argument's location */
1395  loc = exprLocation((Node *) ((const RowCompareExpr *) expr)->largs);
1396  break;
1397  case T_CoalesceExpr:
1398  /* COALESCE keyword should always be the first thing */
1399  loc = ((const CoalesceExpr *) expr)->location;
1400  break;
1401  case T_MinMaxExpr:
1402  /* GREATEST/LEAST keyword should always be the first thing */
1403  loc = ((const MinMaxExpr *) expr)->location;
1404  break;
1405  case T_SQLValueFunction:
1406  /* function keyword should always be the first thing */
1407  loc = ((const SQLValueFunction *) expr)->location;
1408  break;
1409  case T_XmlExpr:
1410  {
1411  const XmlExpr *xexpr = (const XmlExpr *) expr;
1412 
1413  /* consider both function name and leftmost arg */
1414  loc = leftmostLoc(xexpr->location,
1415  exprLocation((Node *) xexpr->args));
1416  }
1417  break;
1418  case T_NullTest:
1419  {
1420  const NullTest *nexpr = (const NullTest *) expr;
1421 
1422  /* Much as above */
1423  loc = leftmostLoc(nexpr->location,
1424  exprLocation((Node *) nexpr->arg));
1425  }
1426  break;
1427  case T_BooleanTest:
1428  {
1429  const BooleanTest *bexpr = (const BooleanTest *) expr;
1430 
1431  /* Much as above */
1432  loc = leftmostLoc(bexpr->location,
1433  exprLocation((Node *) bexpr->arg));
1434  }
1435  break;
1436  case T_CoerceToDomain:
1437  {
1438  const CoerceToDomain *cexpr = (const CoerceToDomain *) expr;
1439 
1440  /* Much as above */
1441  loc = leftmostLoc(cexpr->location,
1442  exprLocation((Node *) cexpr->arg));
1443  }
1444  break;
1445  case T_CoerceToDomainValue:
1446  loc = ((const CoerceToDomainValue *) expr)->location;
1447  break;
1448  case T_SetToDefault:
1449  loc = ((const SetToDefault *) expr)->location;
1450  break;
1451  case T_TargetEntry:
1452  /* just use argument's location */
1453  loc = exprLocation((Node *) ((const TargetEntry *) expr)->expr);
1454  break;
1455  case T_IntoClause:
1456  /* use the contained RangeVar's location --- close enough */
1457  loc = exprLocation((Node *) ((const IntoClause *) expr)->rel);
1458  break;
1459  case T_List:
1460  {
1461  /* report location of first list member that has a location */
1462  ListCell *lc;
1463 
1464  loc = -1; /* just to suppress compiler warning */
1465  foreach(lc, (const List *) expr)
1466  {
1467  loc = exprLocation((Node *) lfirst(lc));
1468  if (loc >= 0)
1469  break;
1470  }
1471  }
1472  break;
1473  case T_A_Expr:
1474  {
1475  const A_Expr *aexpr = (const A_Expr *) expr;
1476 
1477  /* use leftmost of operator or left operand (if any) */
1478  /* we assume right operand can't be to left of operator */
1479  loc = leftmostLoc(aexpr->location,
1480  exprLocation(aexpr->lexpr));
1481  }
1482  break;
1483  case T_ColumnRef:
1484  loc = ((const ColumnRef *) expr)->location;
1485  break;
1486  case T_ParamRef:
1487  loc = ((const ParamRef *) expr)->location;
1488  break;
1489  case T_A_Const:
1490  loc = ((const A_Const *) expr)->location;
1491  break;
1492  case T_FuncCall:
1493  {
1494  const FuncCall *fc = (const FuncCall *) expr;
1495 
1496  /* consider both function name and leftmost arg */
1497  /* (we assume any ORDER BY nodes must be to right of name) */
1498  loc = leftmostLoc(fc->location,
1499  exprLocation((Node *) fc->args));
1500  }
1501  break;
1502  case T_A_ArrayExpr:
1503  /* the location points at ARRAY or [, which must be leftmost */
1504  loc = ((const A_ArrayExpr *) expr)->location;
1505  break;
1506  case T_ResTarget:
1507  /* we need not examine the contained expression (if any) */
1508  loc = ((const ResTarget *) expr)->location;
1509  break;
1510  case T_MultiAssignRef:
1511  loc = exprLocation(((const MultiAssignRef *) expr)->source);
1512  break;
1513  case T_TypeCast:
1514  {
1515  const TypeCast *tc = (const TypeCast *) expr;
1516 
1517  /*
1518  * This could represent CAST(), ::, or TypeName 'literal', so
1519  * any of the components might be leftmost.
1520  */
1521  loc = exprLocation(tc->arg);
1522  loc = leftmostLoc(loc, tc->typeName->location);
1523  loc = leftmostLoc(loc, tc->location);
1524  }
1525  break;
1526  case T_CollateClause:
1527  /* just use argument's location */
1528  loc = exprLocation(((const CollateClause *) expr)->arg);
1529  break;
1530  case T_SortBy:
1531  /* just use argument's location (ignore operator, if any) */
1532  loc = exprLocation(((const SortBy *) expr)->node);
1533  break;
1534  case T_WindowDef:
1535  loc = ((const WindowDef *) expr)->location;
1536  break;
1537  case T_RangeTableSample:
1538  loc = ((const RangeTableSample *) expr)->location;
1539  break;
1540  case T_TypeName:
1541  loc = ((const TypeName *) expr)->location;
1542  break;
1543  case T_ColumnDef:
1544  loc = ((const ColumnDef *) expr)->location;
1545  break;
1546  case T_Constraint:
1547  loc = ((const Constraint *) expr)->location;
1548  break;
1549  case T_FunctionParameter:
1550  /* just use typename's location */
1551  loc = exprLocation((Node *) ((const FunctionParameter *) expr)->argType);
1552  break;
1553  case T_XmlSerialize:
1554  /* XMLSERIALIZE keyword should always be the first thing */
1555  loc = ((const XmlSerialize *) expr)->location;
1556  break;
1557  case T_GroupingSet:
1558  loc = ((const GroupingSet *) expr)->location;
1559  break;
1560  case T_WithClause:
1561  loc = ((const WithClause *) expr)->location;
1562  break;
1563  case T_InferClause:
1564  loc = ((const InferClause *) expr)->location;
1565  break;
1566  case T_OnConflictClause:
1567  loc = ((const OnConflictClause *) expr)->location;
1568  break;
1569  case T_CTESearchClause:
1570  loc = ((const CTESearchClause *) expr)->location;
1571  break;
1572  case T_CTECycleClause:
1573  loc = ((const CTECycleClause *) expr)->location;
1574  break;
1575  case T_CommonTableExpr:
1576  loc = ((const CommonTableExpr *) expr)->location;
1577  break;
1578  case T_PlaceHolderVar:
1579  /* just use argument's location */
1580  loc = exprLocation((Node *) ((const PlaceHolderVar *) expr)->phexpr);
1581  break;
1582  case T_InferenceElem:
1583  /* just use nested expr's location */
1584  loc = exprLocation((Node *) ((const InferenceElem *) expr)->expr);
1585  break;
1586  case T_PartitionElem:
1587  loc = ((const PartitionElem *) expr)->location;
1588  break;
1589  case T_PartitionSpec:
1590  loc = ((const PartitionSpec *) expr)->location;
1591  break;
1592  case T_PartitionBoundSpec:
1593  loc = ((const PartitionBoundSpec *) expr)->location;
1594  break;
1595  case T_PartitionRangeDatum:
1596  loc = ((const PartitionRangeDatum *) expr)->location;
1597  break;
1598  default:
1599  /* for any other node type it's just unknown... */
1600  loc = -1;
1601  break;
1602  }
1603  return loc;
1604 }
int exprLocation(const Node *expr)
Definition: nodeFuncs.c:1231
List * args
Definition: primnodes.h:498
static int leftmostLoc(int loc1, int loc2)
Definition: nodeFuncs.c:1612
int location
Definition: primnodes.h:1213
Expr * arg
Definition: primnodes.h:838
Definition: nodes.h:533
static int fc(const char *x)
Definition: preproc-init.c:99
int location
Definition: parsenodes.h:360
Definition: primnodes.h:181
int location
Definition: primnodes.h:605
int location
Definition: parsenodes.h:299
Expr * arg
Definition: primnodes.h:1243
int location
Definition: primnodes.h:544
Expr * arg
Definition: primnodes.h:1266
int location
Definition: parsenodes.h:278
Expr * arg
Definition: primnodes.h:858
Node * lexpr
Definition: parsenodes.h:276
Definition: nodes.h:301
Definition: nodes.h:156
Definition: nodes.h:155
TypeName * typeName
Definition: parsenodes.h:298
List * args
Definition: primnodes.h:1209
int location
Definition: primnodes.h:863
Expr * arg
Definition: primnodes.h:519
#define lfirst(lc)
Definition: pg_list.h:169
static rewind_source * source
Definition: pg_rewind.c:79
int location
Definition: parsenodes.h:217
int location
Definition: primnodes.h:1246
List * args
Definition: parsenodes.h:351
List * args
Definition: primnodes.h:604
#define nodeTag(nodeptr)
Definition: nodes.h:538
void * arg
int location
Definition: primnodes.h:499
List * args
Definition: primnodes.h:543
Definition: pg_list.h:50
int location
Definition: primnodes.h:843
Node * arg
Definition: parsenodes.h:297
Definition: nodes.h:157

◆ exprSetCollation()

void exprSetCollation ( Node expr,
Oid  collation 
)

Definition at line 1012 of file nodeFuncs.c.

References arg, ARRAY_SUBLINK, Assert, elog, ERROR, EXPR_SUBLINK, exprCollation(), InvalidOid, IS_XMLSERIALIZE, IsA, linitial_node, nodeTag, OidIsValid, 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_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, and generate_unaccent_rules::type.

Referenced by assign_collations_walker().

1013 {
1014  switch (nodeTag(expr))
1015  {
1016  case T_Var:
1017  ((Var *) expr)->varcollid = collation;
1018  break;
1019  case T_Const:
1020  ((Const *) expr)->constcollid = collation;
1021  break;
1022  case T_Param:
1023  ((Param *) expr)->paramcollid = collation;
1024  break;
1025  case T_Aggref:
1026  ((Aggref *) expr)->aggcollid = collation;
1027  break;
1028  case T_GroupingFunc:
1029  Assert(!OidIsValid(collation));
1030  break;
1031  case T_WindowFunc:
1032  ((WindowFunc *) expr)->wincollid = collation;
1033  break;
1034  case T_SubscriptingRef:
1035  ((SubscriptingRef *) expr)->refcollid = collation;
1036  break;
1037  case T_FuncExpr:
1038  ((FuncExpr *) expr)->funccollid = collation;
1039  break;
1040  case T_NamedArgExpr:
1041  Assert(collation == exprCollation((Node *) ((NamedArgExpr *) expr)->arg));
1042  break;
1043  case T_OpExpr:
1044  ((OpExpr *) expr)->opcollid = collation;
1045  break;
1046  case T_DistinctExpr:
1047  ((DistinctExpr *) expr)->opcollid = collation;
1048  break;
1049  case T_NullIfExpr:
1050  ((NullIfExpr *) expr)->opcollid = collation;
1051  break;
1052  case T_ScalarArrayOpExpr:
1053  Assert(!OidIsValid(collation)); /* result is always boolean */
1054  break;
1055  case T_BoolExpr:
1056  Assert(!OidIsValid(collation)); /* result is always boolean */
1057  break;
1058  case T_SubLink:
1059 #ifdef USE_ASSERT_CHECKING
1060  {
1061  SubLink *sublink = (SubLink *) expr;
1062 
1063  if (sublink->subLinkType == EXPR_SUBLINK ||
1064  sublink->subLinkType == ARRAY_SUBLINK)
1065  {
1066  /* get the collation of subselect's first target column */
1067  Query *qtree = (Query *) sublink->subselect;
1068  TargetEntry *tent;
1069 
1070  if (!qtree || !IsA(qtree, Query))
1071  elog(ERROR, "cannot set collation for untransformed sublink");
1072  tent = linitial_node(TargetEntry, qtree->targetList);
1073  Assert(!tent->resjunk);
1074  Assert(collation == exprCollation((Node *) tent->expr));
1075  }
1076  else
1077  {
1078  /* otherwise, result is RECORD or BOOLEAN */
1079  Assert(!OidIsValid(collation));
1080  }
1081  }
1082 #endif /* USE_ASSERT_CHECKING */
1083  break;
1084  case T_FieldSelect:
1085  ((FieldSelect *) expr)->resultcollid = collation;
1086  break;
1087  case T_FieldStore:
1088  Assert(!OidIsValid(collation)); /* result is always composite */
1089  break;
1090  case T_RelabelType:
1091  ((RelabelType *) expr)->resultcollid = collation;
1092  break;
1093  case T_CoerceViaIO:
1094  ((CoerceViaIO *) expr)->resultcollid = collation;
1095  break;
1096  case T_ArrayCoerceExpr:
1097  ((ArrayCoerceExpr *) expr)->resultcollid = collation;
1098  break;
1099  case T_ConvertRowtypeExpr:
1100  Assert(!OidIsValid(collation)); /* result is always composite */
1101  break;
1102  case T_CaseExpr:
1103  ((CaseExpr *) expr)->casecollid = collation;
1104  break;
1105  case T_ArrayExpr:
1106  ((ArrayExpr *) expr)->array_collid = collation;
1107  break;
1108  case T_RowExpr:
1109  Assert(!OidIsValid(collation)); /* result is always composite */
1110  break;
1111  case T_RowCompareExpr:
1112  Assert(!OidIsValid(collation)); /* result is always boolean */
1113  break;
1114  case T_CoalesceExpr:
1115  ((CoalesceExpr *) expr)->coalescecollid = collation;
1116  break;
1117  case T_MinMaxExpr:
1118  ((MinMaxExpr *) expr)->minmaxcollid = collation;
1119  break;
1120  case T_SQLValueFunction:
1121  Assert((((SQLValueFunction *) expr)->type == NAMEOID) ?
1122  (collation == C_COLLATION_OID) :
1123  (collation == InvalidOid));
1124  break;
1125  case T_XmlExpr:
1126  Assert((((XmlExpr *) expr)->op == IS_XMLSERIALIZE) ?
1127  (collation == DEFAULT_COLLATION_OID) :
1128  (collation == InvalidOid));
1129  break;
1130  case T_NullTest:
1131  Assert(!OidIsValid(collation)); /* result is always boolean */
1132  break;
1133  case T_BooleanTest:
1134  Assert(!OidIsValid(collation)); /* result is always boolean */
1135  break;
1136  case T_CoerceToDomain:
1137  ((CoerceToDomain *) expr)->resultcollid = collation;
1138  break;
1139  case T_CoerceToDomainValue:
1140  ((CoerceToDomainValue *) expr)->collation = collation;
1141  break;
1142  case T_SetToDefault:
1143  ((SetToDefault *) expr)->collation = collation;
1144  break;
1145  case T_CurrentOfExpr:
1146  Assert(!OidIsValid(collation)); /* result is always boolean */
1147  break;
1148  case T_NextValueExpr:
1149  Assert(!OidIsValid(collation)); /* result is always an integer
1150  * type */
1151  break;
1152  default:
1153  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
1154  break;
1155  }
1156 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:584
Definition: nodes.h:533
Definition: primnodes.h:181
#define linitial_node(type, l)
Definition: pg_list.h:177
#define OidIsValid(objectId)
Definition: c.h:710
List * targetList
Definition: parsenodes.h:140
#define ERROR
Definition: elog.h:45
Definition: nodes.h:156
Definition: nodes.h:155
#define InvalidOid
Definition: postgres_ext.h:36
#define Assert(condition)
Definition: c.h:804
Oid exprCollation(const Node *expr)
Definition: nodeFuncs.c:759
#define nodeTag(nodeptr)
Definition: nodes.h:538
#define elog(elevel,...)
Definition: elog.h:227
void * arg
Definition: nodes.h:157

◆ exprSetInputCollation()

void exprSetInputCollation ( Node expr,
Oid  inputcollation 
)

Definition at line 1167 of file nodeFuncs.c.

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

Referenced by assign_collations_walker().

1168 {
1169  switch (nodeTag(expr))
1170  {
1171  case T_Aggref:
1172  ((Aggref *) expr)->inputcollid = inputcollation;
1173  break;
1174  case T_WindowFunc:
1175  ((WindowFunc *) expr)->inputcollid = inputcollation;
1176  break;
1177  case T_FuncExpr:
1178  ((FuncExpr *) expr)->inputcollid = inputcollation;
1179  break;
1180  case T_OpExpr:
1181  ((OpExpr *) expr)->inputcollid = inputcollation;
1182  break;
1183  case T_DistinctExpr:
1184  ((DistinctExpr *) expr)->inputcollid = inputcollation;
1185  break;
1186  case T_NullIfExpr:
1187  ((NullIfExpr *) expr)->inputcollid = inputcollation;
1188  break;
1189  case T_ScalarArrayOpExpr:
1190  ((ScalarArrayOpExpr *) expr)->inputcollid = inputcollation;
1191  break;
1192  case T_MinMaxExpr:
1193  ((MinMaxExpr *) expr)->inputcollid = inputcollation;
1194  break;
1195  default:
1196  break;
1197  }
1198 }
#define nodeTag(nodeptr)
Definition: nodes.h:538

◆ exprType()

Oid exprType ( const Node expr)

Definition at line 41 of file nodeFuncs.c.

References arg, ARRAY_SUBLINK, Assert, elog, ereport, errcode(), errmsg(), ERROR, InferenceElem::expr, EXPR_SUBLINK, exprType(), SubPlan::firstColType, format_type_be(), get_promoted_array_type(), InvalidOid, IS_DOCUMENT, IS_XMLSERIALIZE, IsA, linitial, linitial_node, MULTIEXPR_SUBLINK, nodeTag, OidIsValid, 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_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 addRangeTableEntryForFunction(), addRangeTableEntryForSubquery(), addTargetToGroupList(), addTargetToSortList(), analyzeCTE(), analyzeCTETargetList(), appendAggOrderBy(), applyRelabelType(), array_subscript_transform(), assign_collations_walker(), assign_hypothetical_collations(), assign_param_for_placeholdervar(), ATExecAlterColumnType(), ATPrepAlterColumnType(), build_coercion_expression(), build_column_default(), build_subplan(), can_minmax_aggs(), canonicalize_ec_expression(), check_functions_in_node(), check_hashjoinable(), check_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(), compare_tlist_datatypes(), compute_semijoin_info(), ComputeIndexAttrs(), ComputePartitionAttrs(), ConstructTupleDescriptor(), convert_EXISTS_to_ANY(), cookDefault(), cost_qual_eval_walker(), create_ctas_nodata(), create_indexscan_plan(), DefineVirtualRelation(), deparseNullTest(), estimate_num_groups(), eval_const_expressions_mutator(), EvaluateParams(), examine_attribute(), examine_variable(), exec_save_simple_expr(), ExecBuildProjectionInfo(), ExecCheckPlanOutput(), ExecEvalConvertRowtype(), ExecEvalXmlExpr(), ExecInitExprRec(), ExecInitIndexScan(), ExecMakeTableFunctionResult(), ExecTypeFromExprList(), ExecTypeFromTLInternal(), ExecWindowAgg(), expandRecordVariable(), expandRTE(), exprType(), exprTypmod(), find_expr_references_walker(), find_placeholder_info(), fix_indexqual_operand(), foreign_expr_walker(), generate_append_tlist(), generate_join_implied_equalities_normal(), generate_setop_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_windowfunc_expr(), hash_ok_operator(), hstore_subscript_transform(), initialize_peragg(), inline_function(), internal_get_result_type(), jsonb_exec_setup(), jsonb_subscript_transform(), make_op(), make_scalar_array_op(), makeVarFromTargetEntry(), makeWholeRowVar(), match_pattern_prefix(), ordered_set_startup(), 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(), transformMultiAssignRef(), transformPartitionBoundValue(), transformPLAssignStmt(), transformSetOperationTree(), transformSubLink(), transformTypeCast(), unknown_attribute(), and xmlelement().

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  {
110  type = get_promoted_array_type(type);
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  {
141  type = get_promoted_array_type(type);
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  default:
254  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
255  type = InvalidOid; /* keep compiler quiet */
256  break;
257  }
258  return type;
259 }
Oid firstColType
Definition: primnodes.h:734
#define IsA(nodeptr, _type_)
Definition: nodes.h:584
SubLinkType subLinkType
Definition: primnodes.h:725
Definition: nodes.h:533
int errcode(int sqlerrcode)
Definition: elog.c:694
char * format_type_be(Oid type_oid)
Definition: format_type.c:339
unsigned int Oid
Definition: postgres_ext.h:31
Definition: primnodes.h:181
#define linitial_node(type, l)
Definition: pg_list.h:177
#define OidIsValid(objectId)
Definition: c.h:710
List * targetList
Definition: parsenodes.h:140
#define linitial(l)
Definition: pg_list.h:174
#define ERROR
Definition: elog.h:45
Definition: nodes.h:156
Definition: nodes.h:155
Oid get_promoted_array_type(Oid typid)
Definition: lsyscache.c:2758
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:155
#define Assert(condition)
Definition: c.h:804
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:41
#define nodeTag(nodeptr)
Definition: nodes.h:538
int errmsg(const char *fmt,...)
Definition: elog.c:905
#define elog(elevel,...)
Definition: elog.h:227
void * arg
Definition: nodes.h:157

◆ exprTypmod()

int32 exprTypmod ( const Node expr)

Definition at line 267 of file nodeFuncs.c.

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(), exprTypmod(), SubPlan::firstColTypmod, for_each_from, 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_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 addRangeTableEntryForFunction(), addRangeTableEntryForSubquery(), analyzeCTE(), analyzeCTETargetList(), applyRelabelType(), assign_hypothetical_collations(), build_coercion_expression(), build_subplan(), canonicalize_ec_expression(), checkRuleResultList(), coerce_type_typmod(), ConstructTupleDescriptor(), convert_EXISTS_to_ANY(), create_ctas_nodata(), DefineVirtualRelation(), eval_const_expressions_mutator(), examine_attribute(), examine_variable(), exec_save_simple_expr(), ExecTypeFromExprList(), ExecTypeFromTLInternal(), expandRecordVariable(), expandRTE(), exprTypmod(), 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(), interval_support(), 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(), transformInsertStmt(), transformMultiAssignRef(), transformPLAssignStmt(), transformSubLink(), varbit_support(), and varchar_support().

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

◆ fix_opfuncids()

void fix_opfuncids ( Node node)

Definition at line 1633 of file nodeFuncs.c.

References fix_opfuncids_walker().

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

1634 {
1635  /* This tree walk requires no special setup, so away we go... */
1636  fix_opfuncids_walker(node, NULL);
1637 }
static bool fix_opfuncids_walker(Node *node, void *context)
Definition: nodeFuncs.c:1640

◆ get_leftop()

static Node* get_leftop ( const void *  clause)
inlinestatic

◆ get_notclausearg()

◆ get_rightop()

static Node* get_rightop ( const void *  clause)
inlinestatic

◆ is_andclause()

◆ is_funcclause()

static bool is_funcclause ( const void *  clause)
inlinestatic

Definition at line 59 of file nodeFuncs.h.

References IsA.

Referenced by array_unnest_support(), clause_is_strict_for(), clause_selectivity_ext(), generate_series_int4_support(), generate_series_int8_support(), like_regex_support(), and network_subset_support().

60 {
61  return clause != NULL && IsA(clause, FuncExpr);
62 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:584

◆ is_notclause()

static bool is_notclause ( const void *  clause)
inlinestatic

Definition at line 115 of file nodeFuncs.h.

References boolop(), IsA, and NOT_EXPR.

Referenced by clause_selectivity_ext(), dependency_is_compatible_clause(), match_boolean_index_clause(), match_boolean_partition_clause(), matches_boolean_partition_clause(), mcv_get_match_bitmap(), pull_up_sublinks_qual_recurse(), and statext_is_compatible_clause_internal().

116 {
117  return (clause != NULL &&
118  IsA(clause, BoolExpr) &&
119  ((const BoolExpr *) clause)->boolop == NOT_EXPR);
120 }
Datum boolop(PG_FUNCTION_ARGS)
Definition: _int_bool.c:419
#define IsA(nodeptr, _type_)
Definition: nodes.h:584

◆ is_opclause()

◆ is_orclause()

static bool is_orclause ( const void *  clause)
inlinestatic

Definition at line 106 of file nodeFuncs.h.

References boolop(), IsA, and OR_EXPR.

Referenced by clause_selectivity_ext(), dependency_is_compatible_clause(), extract_or_clause(), find_duplicate_ors(), gen_partprune_steps_internal(), make_restrictinfo(), make_sub_restrictinfos(), mcv_get_match_bitmap(), predicate_classify(), process_sublinks_mutator(), pull_ors(), simplify_or_arguments(), and statext_is_compatible_clause_internal().

107 {
108  return (clause != NULL &&
109  IsA(clause, BoolExpr) &&
110  ((const BoolExpr *) clause)->boolop == OR_EXPR);
111 }
Datum boolop(PG_FUNCTION_ARGS)
Definition: _int_bool.c:419
#define IsA(nodeptr, _type_)
Definition: nodes.h:584

◆ planstate_tree_walker()

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

Definition at line 3972 of file nodeFuncs.c.

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, T_ModifyTable, and T_SubqueryScan.

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

3975 {
3976  Plan *plan = planstate->plan;
3977  ListCell *lc;
3978 
3979  /* Guard against stack overflow due to overly complex plan trees */
3981 
3982  /* initPlan-s */
3983  if (planstate_walk_subplans(planstate->initPlan, walker, context))
3984  return true;
3985 
3986  /* lefttree */
3987  if (outerPlanState(planstate))
3988  {
3989  if (walker(outerPlanState(planstate), context))
3990  return true;
3991  }
3992 
3993  /* righttree */
3994  if (innerPlanState(planstate))
3995  {
3996  if (walker(innerPlanState(planstate), context))
3997  return true;
3998  }
3999 
4000  /* special child plans */
4001  switch (nodeTag(plan))
4002  {
4003  case T_ModifyTable:
4004  if (planstate_walk_members(((ModifyTableState *) planstate)->mt_plans,
4005  ((ModifyTableState *) planstate)->mt_nplans,
4006  walker, context))
4007  return true;
4008  break;
4009  case T_Append:
4010  if (planstate_walk_members(((AppendState *) planstate)->appendplans,
4011  ((AppendState *) planstate)->as_nplans,
4012  walker, context))
4013  return true;
4014  break;
4015  case T_MergeAppend:
4016  if (planstate_walk_members(((MergeAppendState *) planstate)->mergeplans,
4017  ((MergeAppendState *) planstate)->ms_nplans,
4018  walker, context))
4019  return true;
4020  break;
4021  case T_BitmapAnd:
4022  if (planstate_walk_members(((BitmapAndState *) planstate)->bitmapplans,
4023  ((BitmapAndState *) planstate)->nplans,
4024  walker, context))
4025  return true;
4026  break;
4027  case T_BitmapOr:
4028  if (planstate_walk_members(((BitmapOrState *) planstate)->bitmapplans,
4029  ((BitmapOrState *) planstate)->nplans,
4030  walker, context))
4031  return true;
4032  break;
4033  case T_SubqueryScan:
4034  if (walker(((SubqueryScanState *) planstate)->subplan, context))
4035  return true;
4036  break;
4037  case T_CustomScan:
4038  foreach(lc, ((