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

Go to the source code of this file.

Macros

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

Functions

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

Macro Definition Documentation

◆ CHECKFLATCOPY

#define CHECKFLATCOPY (   newnode,
  node,
  nodetype 
)
Value:
( AssertMacro(IsA((node), nodetype)), \
(newnode) = (nodetype *) palloc(sizeof(nodetype)), \
memcpy((newnode), (node), sizeof(nodetype)) )
#define IsA(nodeptr, _type_)
Definition: nodes.h:578
#define AssertMacro(condition)
Definition: c.h:801
void * palloc(Size size)
Definition: mcxt.c:950

Referenced by range_table_mutator().

◆ FLATCOPY

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

Referenced by expression_tree_mutator(), query_tree_mutator(), and range_table_mutator().

◆ MUTATE

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

Function Documentation

◆ applyRelabelType()

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

Definition at line 591 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().

593 {
594  /*
595  * If we find stacked RelabelTypes (eg, from foo::int::oid) we can discard
596  * all but the top one, and must do so to ensure that semantically
597  * equivalent expressions are equal().
598  */
599  while (arg && IsA(arg, RelabelType))
600  arg = (Node *) ((RelabelType *) arg)->arg;
601 
602  if (arg && IsA(arg, Const))
603  {
604  /* Modify the Const directly to preserve const-flatness. */
605  Const *con = (Const *) arg;
606 
607  if (!overwrite_ok)
608  con = copyObject(con);
609  con->consttype = rtype;
610  con->consttypmod = rtypmod;
611  con->constcollid = rcollid;
612  /* We keep the Const's original location. */
613  return (Node *) con;
614  }
615  else if (exprType(arg) == rtype &&
616  exprTypmod(arg) == rtypmod &&
617  exprCollation(arg) == rcollid)
618  {
619  /* Sometimes we find a nest of relabels that net out to nothing. */
620  return arg;
621  }
622  else
623  {
624  /* Nope, gotta have a RelabelType. */
625  RelabelType *newrelabel = makeNode(RelabelType);
626 
627  newrelabel->arg = (Expr *) arg;
628  newrelabel->resulttype = rtype;
629  newrelabel->resulttypmod = rtypmod;
630  newrelabel->resultcollid = rcollid;
631  newrelabel->relabelformat = rformat;
632  newrelabel->location = rlocation;
633  return (Node *) newrelabel;
634  }
635 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:578
int32 exprTypmod(const Node *expr)
Definition: nodeFuncs.c:275
Expr * arg
Definition: primnodes.h:829
Definition: nodes.h:527
Oid consttype
Definition: primnodes.h:210
Oid constcollid
Definition: primnodes.h:212
Oid resulttype
Definition: primnodes.h:830
Oid resultcollid
Definition: primnodes.h:832
#define makeNode(_type_)
Definition: nodes.h:575
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:41
Oid exprCollation(const Node *expr)
Definition: nodeFuncs.c:768
int32 consttypmod
Definition: primnodes.h:211
void * arg
int32 resulttypmod
Definition: primnodes.h:831
#define copyObject(obj)
Definition: nodes.h:643
CoercionForm relabelformat
Definition: primnodes.h:833
int location
Definition: primnodes.h:834

◆ check_functions_in_node()

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

Definition at line 1705 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().

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

◆ exprCollation()

Oid exprCollation ( const Node expr)

Definition at line 768 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(), transformSubLink(), and transformWindowDefinitions().

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

◆ expression_returns_set()

bool expression_returns_set ( Node clause)

◆ expression_returns_set_walker()

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

Definition at line 724 of file nodeFuncs.c.

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

Referenced by expression_returns_set().

725 {
726  if (node == NULL)
727  return false;
728  if (IsA(node, FuncExpr))
729  {
730  FuncExpr *expr = (FuncExpr *) node;
731 
732  if (expr->funcretset)
733  return true;
734  /* else fall through to check args */
735  }
736  if (IsA(node, OpExpr))
737  {
738  OpExpr *expr = (OpExpr *) node;
739 
740  if (expr->opretset)
741  return true;
742  /* else fall through to check args */
743  }
744 
745  /* Avoid recursion for some cases that parser checks not to return a set */
746  if (IsA(node, Aggref))
747  return false;
748  if (IsA(node, WindowFunc))
749  return false;
750 
752  context);
753 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:578
static bool expression_returns_set_walker(Node *node, void *context)
Definition: nodeFuncs.c:724
bool funcretset
Definition: primnodes.h:483
bool expression_tree_walker(Node *node, bool(*walker)(), void *context)
Definition: nodeFuncs.c:1888
bool opretset
Definition: primnodes.h:531

◆ expression_tree_mutator()

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

Definition at line 2565 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, 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, 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_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().

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

◆ expression_tree_walker()

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

Definition at line 1888 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, 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, 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_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(), contains_target_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(), 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().

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

◆ exprInputCollation()

Oid exprInputCollation ( const Node expr)

Definition at line 973 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().

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

◆ exprIsLengthCoercion()

bool exprIsLengthCoercion ( const Node expr,
int32 coercedTypmod 
)

Definition at line 512 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().

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

◆ exprLocation()

int exprLocation ( const Node expr)

Definition at line 1240 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_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(), 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(), exprLocation(), finalize_grouping_exprs_walker(), get_matching_location(), init_sexpr(), 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(), transformRangeFunction(), transformReturningList(), transformSelectStmt(), transformSetOperationStmt(), transformSetOperationTree(), transformValuesClause(), and validateInfiniteBounds().

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

◆ exprSetCollation()

void exprSetCollation ( Node expr,
Oid  collation 
)

Definition at line 1021 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().

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

◆ exprSetInputCollation()

void exprSetInputCollation ( Node expr,
Oid  inputcollation 
)

Definition at line 1176 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().

1177 {
1178  switch (nodeTag(expr))
1179  {
1180  case T_Aggref:
1181  ((Aggref *) expr)->inputcollid = inputcollation;
1182  break;
1183  case T_WindowFunc:
1184  ((WindowFunc *) expr)->inputcollid = inputcollation;
1185  break;
1186  case T_FuncExpr:
1187  ((FuncExpr *) expr)->inputcollid = inputcollation;
1188  break;
1189  case T_OpExpr:
1190  ((OpExpr *) expr)->inputcollid = inputcollation;
1191  break;
1192  case T_DistinctExpr:
1193  ((DistinctExpr *) expr)->inputcollid = inputcollation;
1194  break;
1195  case T_NullIfExpr:
1196  ((NullIfExpr *) expr)->inputcollid = inputcollation;
1197  break;
1198  case T_ScalarArrayOpExpr:
1199  ((ScalarArrayOpExpr *) expr)->inputcollid = inputcollation;
1200  break;
1201  case T_MinMaxExpr:
1202  ((MinMaxExpr *) expr)->inputcollid = inputcollation;
1203  break;
1204  default:
1205  break;
1206  }
1207 }
#define nodeTag(nodeptr)
Definition: nodes.h:532

◆ 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, SubscriptingRef::refassgnexpr, SubscriptingRef::refcontainertype, SubscriptingRef::refelemtype, SubscriptingRef::reflowerindexpr, 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(), 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(), initialize_peragg(), inline_function(), internal_get_result_type(), 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(), transformContainerSubscripts(), transformExprRecurse(), transformFrameOffset(), transformFromClauseItem(), transformIndirection(), transformInsertStmt(), transformMultiAssignRef(), transformPartitionBoundValue(), 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  {
70  const SubscriptingRef *sbsref = (const SubscriptingRef *) expr;
71 
72  /* slice and/or store operations yield the container type */
73  if (sbsref->reflowerindexpr || sbsref->refassgnexpr)
74  type = sbsref->refcontainertype;
75  else
76  type = sbsref->refelemtype;
77  }
78  break;
79  case T_FuncExpr:
80  type = ((const FuncExpr *) expr)->funcresulttype;
81  break;
82  case T_NamedArgExpr:
83  type = exprType((Node *) ((const NamedArgExpr *) expr)->arg);
84  break;
85  case T_OpExpr:
86  type = ((const OpExpr *) expr)->opresulttype;
87  break;
88  case T_DistinctExpr:
89  type = ((const DistinctExpr *) expr)->opresulttype;
90  break;
91  case T_NullIfExpr:
92  type = ((const NullIfExpr *) expr)->opresulttype;
93  break;
95  type = BOOLOID;
96  break;
97  case T_BoolExpr:
98  type = BOOLOID;
99  break;
100  case T_SubLink:
101  {
102  const SubLink *sublink = (const SubLink *) expr;
103 
104  if (sublink->subLinkType == EXPR_SUBLINK ||
105  sublink->subLinkType == ARRAY_SUBLINK)
106  {
107  /* get the type of the subselect's first target column */
108  Query *qtree = (Query *) sublink->subselect;
109  TargetEntry *tent;
110 
111  if (!qtree || !IsA(qtree, Query))
112  elog(ERROR, "cannot get type for untransformed sublink");
113  tent = linitial_node(TargetEntry, qtree->targetList);
114  Assert(!tent->resjunk);
115  type = exprType((Node *) tent->expr);
116  if (sublink->subLinkType == ARRAY_SUBLINK)
117  {
118  type = get_promoted_array_type(type);
119  if (!OidIsValid(type))
120  ereport(ERROR,
121  (errcode(ERRCODE_UNDEFINED_OBJECT),
122  errmsg("could not find array type for data type %s",
123  format_type_be(exprType((Node *) tent->expr)))));
124  }
125  }
126  else if (sublink->subLinkType == MULTIEXPR_SUBLINK)
127  {
128  /* MULTIEXPR is always considered to return RECORD */
129  type = RECORDOID;
130  }
131  else
132  {
133  /* for all other sublink types, result is boolean */
134  type = BOOLOID;
135  }
136  }
137  break;
138  case T_SubPlan:
139  {
140  const SubPlan *subplan = (const SubPlan *) expr;
141 
142  if (subplan->subLinkType == EXPR_SUBLINK ||
143  subplan->subLinkType == ARRAY_SUBLINK)
144  {
145  /* get the type of the subselect's first target column */
146  type = subplan->firstColType;
147  if (subplan->subLinkType == ARRAY_SUBLINK)
148  {
149  type = get_promoted_array_type(type);
150  if (!OidIsValid(type))
151  ereport(ERROR,
152  (errcode(ERRCODE_UNDEFINED_OBJECT),
153  errmsg("could not find array type for data type %s",
154  format_type_be(subplan->firstColType))));
155  }
156  }
157  else if (subplan->subLinkType == MULTIEXPR_SUBLINK)
158  {
159  /* MULTIEXPR is always considered to return RECORD */
160  type = RECORDOID;
161  }
162  else
163  {
164  /* for all other subplan types, result is boolean */
165  type = BOOLOID;
166  }
167  }
168  break;
170  {
171  const AlternativeSubPlan *asplan = (const AlternativeSubPlan *) expr;
172 
173  /* subplans should all return the same thing */
174  type = exprType((Node *) linitial(asplan->subplans));
175  }
176  break;
177  case T_FieldSelect:
178  type = ((const FieldSelect *) expr)->resulttype;
179  break;
180  case T_FieldStore:
181  type = ((const FieldStore *) expr)->resulttype;
182  break;
183  case T_RelabelType:
184  type = ((const RelabelType *) expr)->resulttype;
185  break;
186  case T_CoerceViaIO:
187  type = ((const CoerceViaIO *) expr)->resulttype;
188  break;
189  case T_ArrayCoerceExpr:
190  type = ((const ArrayCoerceExpr *) expr)->resulttype;
191  break;
193  type = ((const ConvertRowtypeExpr *) expr)->resulttype;
194  break;
195  case T_CollateExpr:
196  type = exprType((Node *) ((const CollateExpr *) expr)->arg);
197  break;
198  case T_CaseExpr:
199  type = ((const CaseExpr *) expr)->casetype;
200  break;
201  case T_CaseTestExpr:
202  type = ((const CaseTestExpr *) expr)->typeId;
203  break;
204  case T_ArrayExpr:
205  type = ((const ArrayExpr *) expr)->array_typeid;
206  break;
207  case T_RowExpr:
208  type = ((const RowExpr *) expr)->row_typeid;
209  break;
210  case T_RowCompareExpr:
211  type = BOOLOID;
212  break;
213  case T_CoalesceExpr:
214  type = ((const CoalesceExpr *) expr)->coalescetype;
215  break;
216  case T_MinMaxExpr:
217  type = ((const MinMaxExpr *) expr)->minmaxtype;
218  break;
219  case T_SQLValueFunction:
220  type = ((const SQLValueFunction *) expr)->type;
221  break;
222  case T_XmlExpr:
223  if (((const XmlExpr *) expr)->op == IS_DOCUMENT)
224  type = BOOLOID;
225  else if (((const XmlExpr *) expr)->op == IS_XMLSERIALIZE)
226  type = TEXTOID;
227  else
228  type = XMLOID;
229  break;
230  case T_NullTest:
231  type = BOOLOID;
232  break;
233  case T_BooleanTest:
234  type = BOOLOID;
235  break;
236  case T_CoerceToDomain:
237  type = ((const CoerceToDomain *) expr)->resulttype;
238  break;
240  type = ((const CoerceToDomainValue *) expr)->typeId;
241  break;
242  case T_SetToDefault:
243  type = ((const SetToDefault *) expr)->typeId;
244  break;
245  case T_CurrentOfExpr:
246  type = BOOLOID;
247  break;
248  case T_NextValueExpr:
249  type = ((const NextValueExpr *) expr)->typeId;
250  break;
251  case T_InferenceElem:
252  {
253  const InferenceElem *n = (const InferenceElem *) expr;
254 
255  type = exprType((Node *) n->expr);
256  }
257  break;
258  case T_PlaceHolderVar:
259  type = exprType((Node *) ((const PlaceHolderVar *) expr)->phexpr);
260  break;
261  default:
262  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
263  type = InvalidOid; /* keep compiler quiet */
264  break;
265  }
266  return type;
267 }
Oid firstColType
Definition: primnodes.h:725
#define IsA(nodeptr, _type_)
Definition: nodes.h:578
SubLinkType subLinkType
Definition: primnodes.h:716
Definition: nodes.h:527
int errcode(int sqlerrcode)
Definition: elog.c:691
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:706
List * targetList
Definition: parsenodes.h:140
#define linitial(l)
Definition: pg_list.h:174
#define ERROR
Definition: elog.h:43
Definition: nodes.h:154
Definition: nodes.h:153
Oid get_promoted_array_type(Oid typid)
Definition: lsyscache.c:2693
#define InvalidOid
Definition: postgres_ext.h:36
#define ereport(elevel,...)
Definition: elog.h:155
#define Assert(condition)
Definition: c.h:800
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:41
#define nodeTag(nodeptr)
Definition: nodes.h:532
Expr * refassgnexpr
Definition: primnodes.h:438
int errmsg(const char *fmt,...)
Definition: elog.c:902
List * reflowerindexpr
Definition: primnodes.h:432
#define elog(elevel,...)
Definition: elog.h:228
void * arg
Oid refcontainertype
Definition: primnodes.h:426
Definition: nodes.h:155

◆ exprTypmod()

int32 exprTypmod ( const Node expr)

Definition at line 275 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(), transformSubLink(), varbit_support(), and varchar_support().

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

◆ fix_opfuncids()

void fix_opfuncids ( Node node)

Definition at line 1636 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().

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

◆ fix_opfuncids_walker()

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

Definition at line 1643 of file nodeFuncs.c.

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

Referenced by fix_opfuncids().

1644 {
1645  if (node == NULL)
1646  return false;
1647  if (IsA(node, OpExpr))
1648  set_opfuncid((OpExpr *) node);
1649  else if (IsA(node, DistinctExpr))
1650  set_opfuncid((OpExpr *) node); /* rely on struct equivalence */
1651  else if (IsA(node, NullIfExpr))
1652  set_opfuncid((OpExpr *) node); /* rely on struct equivalence */
1653  else if (IsA(node, ScalarArrayOpExpr))
1655  return expression_tree_walker(node, fix_opfuncids_walker, context);
1656 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:578
static bool fix_opfuncids_walker(Node *node, void *context)
Definition: nodeFuncs.c:1643
bool expression_tree_walker(Node *node, bool(*walker)(), void *context)
Definition: nodeFuncs.c:1888
void set_opfuncid(OpExpr *opexpr)
Definition: nodeFuncs.c:1667
void set_sa_opfuncid(ScalarArrayOpExpr *opexpr)
Definition: nodeFuncs.c:1678

◆ leftmostLoc()

static int leftmostLoc ( int  loc1,
int  loc2 
)
static

Definition at line 1615 of file nodeFuncs.c.

References Min.

Referenced by exprLocation().

1616 {
1617  if (loc1 < 0)
1618  return loc2;
1619  else if (loc2 < 0)
1620  return loc1;
1621  else
1622  return Min(loc1, loc2);
1623 }
#define Min(x, y)
Definition: c.h:982

◆ planstate_tree_walker()

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

Definition at line 3931 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().

3934 {
3935  Plan *plan = planstate->plan;
3936  ListCell *lc;
3937 
3938  /* Guard against stack overflow due to overly complex plan trees */
3940 
3941  /* initPlan-s */
3942  if (planstate_walk_subplans(planstate->initPlan, walker, context))
3943  return true;
3944 
3945  /* lefttree */
3946  if (outerPlanState(planstate))
3947  {
3948  if (walker(outerPlanState(planstate), context))
3949  return true;
3950  }
3951 
3952  /* righttree */
3953  if (innerPlanState(planstate))
3954  {
3955  if (walker(innerPlanState(planstate), context))
3956  return true;
3957  }
3958 
3959  /* special child plans */
3960  switch (nodeTag(plan))
3961  {
3962  case T_ModifyTable:
3963  if (planstate_walk_members(((ModifyTableState *) planstate)->mt_plans,
3964  ((ModifyTableState *) planstate)->mt_nplans,
3965  walker, context))
3966  return true;
3967  break;
3968  case T_Append:
3969  if (planstate_walk_members(((AppendState *) planstate)->appendplans,
3970  ((AppendState *) planstate)->as_nplans,
3971  walker, context))
3972  return true;
3973  break;
3974  case T_MergeAppend:
3975  if (planstate_walk_members(((MergeAppendState *) planstate)->mergeplans,
3976  ((MergeAppendState *) planstate)->ms_nplans,
3977  walker, context))
3978  return true;
3979  break;
3980  case T_BitmapAnd:
3981  if (planstate_walk_members(((BitmapAndState *) planstate)->bitmapplans,
3982  ((BitmapAndState *) planstate)->nplans,
3983  walker, context))
3984  return true;
3985  break;
3986  case T_BitmapOr:
3987  if (planstate_walk_members(((BitmapOrState *) planstate)->bitmapplans,
3988  ((BitmapOrState *) planstate)->nplans,
3989  walker, context))
3990  return true;
3991  break;
3992  case T_SubqueryScan:
3993  if (walker(((SubqueryScanState *) planstate)->subplan, context))
3994  return true;
3995  break;
3996  case T_CustomScan:
3997  foreach(lc, ((CustomScanState *) planstate)->custom_ps)
3998  {
3999  if (walker((PlanState *) lfirst(lc), context))
4000  return true;
4001  }
4002  break;
4003  default:
4004  break;
4005  }
4006 
4007  /* subPlan-s */
4008  if (planstate_walk_subplans(planstate->subPlan, walker, context))
4009  return true;
4010 
4011  return false;
4012 }
List * initPlan
Definition: execnodes.h:953
static bool planstate_walk_members(PlanState **planstates, int nplans, bool(*walker)(), void *context)
Definition: nodeFuncs.c:4040
Definition: nodes.h:49
#define outerPlanState(node)
Definition: execnodes.h:1022
void check_stack_depth(void)
Definition: postgres.c:3312
static bool planstate_walk_subplans(List *plans, bool(*walker)(), void *context)
Definition: nodeFuncs.c:4018
Plan * plan
Definition: execnodes.h:928
#define lfirst(lc)
Definition: pg_list.h:169
#define nodeTag(nodeptr)
Definition: nodes.h:532
#define innerPlanState(node)
Definition: execnodes.h:1021

◆ planstate_walk_members()

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

Definition at line 4040 of file nodeFuncs.c.

Referenced by planstate_tree_walker().

4042 {
4043  int j;
4044 
4045  for (j = 0; j < nplans; j++)
4046  {
4047  if (walker(planstates[j], context))
4048  return true;
4049  }
4050 
4051  return false;
4052 }

◆ planstate_walk_subplans()

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

Definition at line 4018 of file nodeFuncs.c.

References lfirst_node, and SubPlanState::planstate.

Referenced by planstate_tree_walker().

4021 {
4022  ListCell *lc;
4023 
4024  foreach(lc, plans)
4025  {
4027 
4028  if (walker(sps->planstate, context))
4029  return true;
4030  }
4031 
4032  return false;
4033 }
struct PlanState * planstate
Definition: execnodes.h:846
#define lfirst_node(type, lc)
Definition: pg_list.h:172

◆ query_or_expression_tree_mutator()

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

Definition at line 3435 of file nodeFuncs.c.

References IsA, and query_tree_mutator().

Referenced by get_notclausearg(), map_variable_attnos(), and replace_rte_variables().

3439 {
3440  if (node && IsA(node, Query))
3441  return (Node *) query_tree_mutator((Query *) node,
3442  mutator,
3443  context,
3444  flags);
3445  else
3446  return mutator(node, context);
3447 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:578
Definition: nodes.h:527
Query * query_tree_mutator(Query *query, Node *(*mutator)(), void *context, int flags)
Definition: nodeFuncs.c:3251

◆ query_or_expression_tree_walker()

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

Definition at line 3412 of file nodeFuncs.c.

References IsA, and query_tree_walker().

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

3416 {
3417  if (node && IsA(node, Query))
3418  return query_tree_walker((Query *) node,
3419  walker,
3420  context,
3421  flags);
3422  else
3423  return walker(node, context);
3424 }
bool query_tree_walker(Query *query, bool(*walker)(), void *context, int flags)
Definition: nodeFuncs.c:2322
#define IsA(nodeptr, _type_)
Definition: nodes.h:578

◆ query_tree_mutator()

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

Definition at line 3251 of file nodeFuncs.c.

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

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

3255 {
3256  Assert(query != NULL && IsA(query, Query));
3257 
3258  if (!(flags & QTW_DONT_COPY_QUERY))
3259  {
3260  Query *newquery;
3261 
3262  FLATCOPY(newquery, query, Query);
3263  query = newquery;
3264  }
3265 
3266  MUTATE(query->targetList, query->targetList, List *);
3267  MUTATE(query->withCheckOptions, query->withCheckOptions, List *);
3268  MUTATE(query->onConflict, query->onConflict, OnConflictExpr *);
3269  MUTATE(query->returningList, query->returningList, List *);
3270  MUTATE(query->jointree, query->jointree, FromExpr *);
3271  MUTATE(query->setOperations, query->setOperations, Node *);
3272  MUTATE(query->havingQual, query->havingQual, Node *);
3273  MUTATE(query->limitOffset, query->limitOffset, Node *);
3274  MUTATE(query->limitCount, query->limitCount, Node *);
3275 
3276  /*
3277  * Most callers aren't interested in SortGroupClause nodes since those
3278  * don't contain actual expressions. However they do contain OIDs, which
3279  * may be of interest to some mutators.
3280  */
3281 
3282  if ((flags & QTW_EXAMINE_SORTGROUP))
3283  {
3284  MUTATE(query->groupClause, query->groupClause, List *);
3285  MUTATE(query->windowClause, query->windowClause, List *);
3286  MUTATE(query->sortClause, query->sortClause, List *);
3287  MUTATE(query->distinctClause, query->distinctClause, List *);
3288  }
3289  else
3290  {
3291  /*
3292  * But we need to mutate the expressions under WindowClause nodes even
3293  * if we're not interested in SortGroupClause nodes.
3294  */
3295  List *resultlist;
3296  ListCell *temp;
3297 
3298  resultlist = NIL;
3299  foreach(temp, query->windowClause)
3300  {
3301  WindowClause *wc = lfirst_node(WindowClause, temp);
3302  WindowClause *newnode;
3303 
3304  FLATCOPY(newnode, wc, WindowClause);
3305  MUTATE(newnode->startOffset, wc->startOffset, Node *);
3306  MUTATE(newnode->endOffset, wc->endOffset, Node *);
3307 
3308  resultlist = lappend(resultlist, (Node *) newnode);
3309  }
3310  query->windowClause = resultlist;
3311  }
3312 
3313  /*
3314  * groupingSets and rowMarks are not mutated:
3315  *
3316  * groupingSets contain only ressortgroup refs (integers) which are
3317  * meaningless without the groupClause or tlist. Accordingly, any mutator
3318  * that needs to care about them needs to handle them itself in its Query
3319  * processing.
3320  *
3321  * rowMarks contains only rangetable indexes (and flags etc.) and
3322  * therefore should be handled at Query level similarly.
3323  */
3324 
3325  if (!(flags & QTW_IGNORE_CTE_SUBQUERIES))
3326  MUTATE(query->