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 WALK(n)   walker((Node *) (n), context)
 
#define LIST_WALK(l)   expression_tree_walker_impl((Node *) (l), walker, context)
 
#define FLATCOPY(newnode, node, nodetype)
 
#define MUTATE(newfield, oldfield, fieldtype)    ( (newfield) = (fieldtype) mutator((Node *) (oldfield), context) )
 
#define PSWALK(n)   walker(n, context)
 

Functions

static bool expression_returns_set_walker (Node *node, void *context)
 
static int leftmostLoc (int loc1, int loc2)
 
static bool fix_opfuncids_walker (Node *node, void *context)
 
static bool planstate_walk_subplans (List *plans, planstate_tree_walker_callback walker, void *context)
 
static bool planstate_walk_members (PlanState **planstates, int nplans, planstate_tree_walker_callback walker, void *context)
 
Oid exprType (const Node *expr)
 
int32 exprTypmod (const Node *expr)
 
bool exprIsLengthCoercion (const Node *expr, int32 *coercedTypmod)
 
NodeapplyRelabelType (Node *arg, Oid rtype, int32 rtypmod, Oid rcollid, CoercionForm rformat, int rlocation, bool overwrite_ok)
 
Noderelabel_to_typmod (Node *expr, int32 typmod)
 
Nodestrip_implicit_coercions (Node *node)
 
bool expression_returns_set (Node *clause)
 
Oid exprCollation (const Node *expr)
 
Oid exprInputCollation (const Node *expr)
 
void exprSetCollation (Node *expr, Oid collation)
 
void exprSetInputCollation (Node *expr, Oid inputcollation)
 
int exprLocation (const Node *expr)
 
void fix_opfuncids (Node *node)
 
void set_opfuncid (OpExpr *opexpr)
 
void set_sa_opfuncid (ScalarArrayOpExpr *opexpr)
 
bool check_functions_in_node (Node *node, check_function_callback checker, void *context)
 
bool expression_tree_walker_impl (Node *node, tree_walker_callback walker, void *context)
 
bool query_tree_walker_impl (Query *query, tree_walker_callback walker, void *context, int flags)
 
bool range_table_walker_impl (List *rtable, tree_walker_callback walker, void *context, int flags)
 
bool range_table_entry_walker_impl (RangeTblEntry *rte, tree_walker_callback walker, void *context, int flags)
 
Nodeexpression_tree_mutator_impl (Node *node, tree_mutator_callback mutator, void *context)
 
Queryquery_tree_mutator_impl (Query *query, tree_mutator_callback mutator, void *context, int flags)
 
Listrange_table_mutator_impl (List *rtable, tree_mutator_callback mutator, void *context, int flags)
 
bool query_or_expression_tree_walker_impl (Node *node, tree_walker_callback walker, void *context, int flags)
 
Nodequery_or_expression_tree_mutator_impl (Node *node, tree_mutator_callback mutator, void *context, int flags)
 
bool raw_expression_tree_walker_impl (Node *node, tree_walker_callback walker, void *context)
 
bool planstate_tree_walker_impl (PlanState *planstate, planstate_tree_walker_callback walker, void *context)
 

Macro Definition Documentation

◆ FLATCOPY

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

◆ LIST_WALK

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

◆ MUTATE

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

◆ PSWALK

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

◆ WALK

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

Function Documentation

◆ applyRelabelType()

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

Definition at line 579 of file nodeFuncs.c.

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

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

Referenced by canonicalize_ec_expression(), coerce_type_typmod(), eval_const_expressions_mutator(), generate_setop_tlist(), and relabel_to_typmod().

◆ check_functions_in_node()

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

Definition at line 1710 of file nodeFuncs.c.

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

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

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

◆ exprCollation()

Oid exprCollation ( const Node expr)

Definition at line 764 of file nodeFuncs.c.

765 {
766  Oid coll;
767 
768  if (!expr)
769  return InvalidOid;
770 
771  switch (nodeTag(expr))
772  {
773  case T_Var:
774  coll = ((const Var *) expr)->varcollid;
775  break;
776  case T_Const:
777  coll = ((const Const *) expr)->constcollid;
778  break;
779  case T_Param:
780  coll = ((const Param *) expr)->paramcollid;
781  break;
782  case T_Aggref:
783  coll = ((const Aggref *) expr)->aggcollid;
784  break;
785  case T_GroupingFunc:
786  coll = InvalidOid;
787  break;
788  case T_WindowFunc:
789  coll = ((const WindowFunc *) expr)->wincollid;
790  break;
791  case T_SubscriptingRef:
792  coll = ((const SubscriptingRef *) expr)->refcollid;
793  break;
794  case T_FuncExpr:
795  coll = ((const FuncExpr *) expr)->funccollid;
796  break;
797  case T_NamedArgExpr:
798  coll = exprCollation((Node *) ((const NamedArgExpr *) expr)->arg);
799  break;
800  case T_OpExpr:
801  coll = ((const OpExpr *) expr)->opcollid;
802  break;
803  case T_DistinctExpr:
804  coll = ((const DistinctExpr *) expr)->opcollid;
805  break;
806  case T_NullIfExpr:
807  coll = ((const NullIfExpr *) expr)->opcollid;
808  break;
809  case T_ScalarArrayOpExpr:
810  /* ScalarArrayOpExpr's result is boolean ... */
811  coll = InvalidOid; /* ... so it has no collation */
812  break;
813  case T_BoolExpr:
814  /* BoolExpr's result is boolean ... */
815  coll = InvalidOid; /* ... so it has no collation */
816  break;
817  case T_SubLink:
818  {
819  const SubLink *sublink = (const SubLink *) expr;
820 
821  if (sublink->subLinkType == EXPR_SUBLINK ||
822  sublink->subLinkType == ARRAY_SUBLINK)
823  {
824  /* get the collation of subselect's first target column */
825  Query *qtree = (Query *) sublink->subselect;
826  TargetEntry *tent;
827 
828  if (!qtree || !IsA(qtree, Query))
829  elog(ERROR, "cannot get collation for untransformed sublink");
830  tent = linitial_node(TargetEntry, qtree->targetList);
831  Assert(!tent->resjunk);
832  coll = exprCollation((Node *) tent->expr);
833  /* collation doesn't change if it's converted to array */
834  }
835  else
836  {
837  /* otherwise, SubLink's result is RECORD or BOOLEAN */
838  coll = InvalidOid; /* ... so it has no collation */
839  }
840  }
841  break;
842  case T_SubPlan:
843  {
844  const SubPlan *subplan = (const SubPlan *) expr;
845 
846  if (subplan->subLinkType == EXPR_SUBLINK ||
847  subplan->subLinkType == ARRAY_SUBLINK)
848  {
849  /* get the collation of subselect's first target column */
850  coll = subplan->firstColCollation;
851  /* collation doesn't change if it's converted to array */
852  }
853  else
854  {
855  /* otherwise, SubPlan's result is RECORD or BOOLEAN */
856  coll = InvalidOid; /* ... so it has no collation */
857  }
858  }
859  break;
860  case T_AlternativeSubPlan:
861  {
862  const AlternativeSubPlan *asplan = (const AlternativeSubPlan *) expr;
863 
864  /* subplans should all return the same thing */
865  coll = exprCollation((Node *) linitial(asplan->subplans));
866  }
867  break;
868  case T_FieldSelect:
869  coll = ((const FieldSelect *) expr)->resultcollid;
870  break;
871  case T_FieldStore:
872  /* FieldStore's result is composite ... */
873  coll = InvalidOid; /* ... so it has no collation */
874  break;
875  case T_RelabelType:
876  coll = ((const RelabelType *) expr)->resultcollid;
877  break;
878  case T_CoerceViaIO:
879  coll = ((const CoerceViaIO *) expr)->resultcollid;
880  break;
881  case T_ArrayCoerceExpr:
882  coll = ((const ArrayCoerceExpr *) expr)->resultcollid;
883  break;
884  case T_ConvertRowtypeExpr:
885  /* ConvertRowtypeExpr's result is composite ... */
886  coll = InvalidOid; /* ... so it has no collation */
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  /* RowExpr's result is composite ... */
902  coll = InvalidOid; /* ... so it has no collation */
903  break;
904  case T_RowCompareExpr:
905  /* RowCompareExpr's result is boolean ... */
906  coll = InvalidOid; /* ... so it has no collation */
907  break;
908  case T_CoalesceExpr:
909  coll = ((const CoalesceExpr *) expr)->coalescecollid;
910  break;
911  case T_MinMaxExpr:
912  coll = ((const MinMaxExpr *) expr)->minmaxcollid;
913  break;
914  case T_XmlExpr:
915 
916  /*
917  * XMLSERIALIZE returns text from non-collatable inputs, so its
918  * collation is always default. The other cases return boolean or
919  * XML, which are non-collatable.
920  */
921  if (((const XmlExpr *) expr)->op == IS_XMLSERIALIZE)
922  coll = DEFAULT_COLLATION_OID;
923  else
924  coll = InvalidOid;
925  break;
926  case T_NullTest:
927  /* NullTest's result is boolean ... */
928  coll = InvalidOid; /* ... so it has no collation */
929  break;
930  case T_BooleanTest:
931  /* BooleanTest's result is boolean ... */
932  coll = InvalidOid; /* ... so it has no collation */
933  break;
934  case T_CoerceToDomain:
935  coll = ((const CoerceToDomain *) expr)->resultcollid;
936  break;
937  case T_CoerceToDomainValue:
938  coll = ((const CoerceToDomainValue *) expr)->collation;
939  break;
940  case T_SetToDefault:
941  coll = ((const SetToDefault *) expr)->collation;
942  break;
943  case T_CurrentOfExpr:
944  /* CurrentOfExpr's result is boolean ... */
945  coll = InvalidOid; /* ... so it has no collation */
946  break;
947  case T_NextValueExpr:
948  /* NextValueExpr's result is an integer type ... */
949  coll = InvalidOid; /* ... so it has no collation */
950  break;
951  case T_InferenceElem:
952  coll = exprCollation((Node *) ((const InferenceElem *) expr)->expr);
953  break;
954  case T_PlaceHolderVar:
955  coll = exprCollation((Node *) ((const PlaceHolderVar *) expr)->phexpr);
956  break;
957  default:
958  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
959  coll = InvalidOid; /* keep compiler quiet */
960  break;
961  }
962  return coll;
963 }
#define ERROR
Definition: elog.h:35
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
Assert(fmt[strlen(fmt) - 1] !='\n')
#define linitial_node(type, l)
Definition: pg_list.h:179
#define linitial(l)
Definition: pg_list.h:176
#define InvalidOid
Definition: postgres_ext.h:36
@ ARRAY_SUBLINK
Definition: primnodes.h:830
@ EXPR_SUBLINK
Definition: primnodes.h:828
@ IS_XMLSERIALIZE
Definition: primnodes.h:1314
List * targetList
Definition: parsenodes.h:162
Oid firstColCollation
Definition: primnodes.h:899
SubLinkType subLinkType
Definition: primnodes.h:888
Definition: primnodes.h:205

References arg, ARRAY_SUBLINK, Assert(), elog(), ERROR, EXPR_SUBLINK, SubPlan::firstColCollation, if(), InvalidOid, IS_XMLSERIALIZE, IsA, linitial, linitial_node, nodeTag, SubLink::subLinkType, SubPlan::subLinkType, AlternativeSubPlan::subplans, SubLink::subselect, and Query::targetList.

Referenced by addRangeTableEntryForFunction(), addRangeTableEntryForSubquery(), analyzeCTE(), analyzeCTETargetList(), applyRelabelType(), assign_collations_walker(), assign_hypothetical_collations(), build_expression_pathkey(), build_pertrans_for_aggref(), build_subplan(), canonicalize_ec_expression(), check_simple_rowfilter_expr_walker(), coerce_type_typmod(), ComputeIndexAttrs(), ComputePartitionAttrs(), convert_EXISTS_to_ANY(), create_ctas_nodata(), create_limit_plan(), create_memoize_plan(), create_unique_plan(), create_windowagg_plan(), DefineVirtualRelation(), eval_const_expressions_mutator(), examine_attribute(), examine_expression(), ExecInitFunctionScan(), ExecInitIndexScan(), ExecTypeFromExprList(), ExecTypeFromTLInternal(), expandRecordVariable(), expandRTE(), exprSetCollation(), extract_grouping_collations(), fix_indexqual_operand(), generate_setop_tlist(), generate_subquery_params(), get_expr_result_type(), get_first_col_type(), inline_function(), make_pathkey_from_sortop(), make_recursive_union(), make_setop(), make_sort_from_groupcols(), make_sort_from_sortclauses(), make_unique_from_sortclauses(), makeVarFromTargetEntry(), makeWholeRowVar(), mcv_match_expression(), ordered_set_startup(), pg_get_indexdef_worker(), pg_get_partkeydef_worker(), preprocess_minmax_aggregates(), relabel_to_typmod(), RelationBuildPartitionKey(), RelationGetDummyIndexExpressions(), remove_unused_subquery_outputs(), replace_nestloop_param_placeholdervar(), replace_outer_placeholdervar(), scalararraysel(), set_dummy_tlist_references(), set_joinrel_partition_key_exprs(), tlist_same_collations(), transformCaseExpr(), transformFromClauseItem(), transformMultiAssignRef(), transformPLAssignStmt(), transformSubLink(), and transformWindowDefinitions().

◆ expression_returns_set()

◆ expression_returns_set_walker()

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

Definition at line 712 of file nodeFuncs.c.

713 {
714  if (node == NULL)
715  return false;
716  if (IsA(node, FuncExpr))
717  {
718  FuncExpr *expr = (FuncExpr *) node;
719 
720  if (expr->funcretset)
721  return true;
722  /* else fall through to check args */
723  }
724  if (IsA(node, OpExpr))
725  {
726  OpExpr *expr = (OpExpr *) node;
727 
728  if (expr->opretset)
729  return true;
730  /* else fall through to check args */
731  }
732 
733  /*
734  * If you add any more cases that return sets, also fix
735  * expression_returns_set_rows() in clauses.c and IS_SRF_CALL() in
736  * tlist.c.
737  */
738 
739  /* Avoid recursion for some cases that parser checks not to return a set */
740  if (IsA(node, Aggref))
741  return false;
742  if (IsA(node, GroupingFunc))
743  return false;
744  if (IsA(node, WindowFunc))
745  return false;
746 
748  context);
749 }
#define expression_tree_walker(n, w, c)
Definition: nodeFuncs.h:151
bool funcretset
Definition: primnodes.h:600
bool opretset
Definition: primnodes.h:657

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

Referenced by expression_returns_set().

◆ expression_tree_mutator_impl()

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

Definition at line 2609 of file nodeFuncs.c.

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

References generate_unaccent_rules::action, Aggref::aggargtypes, Aggref::aggdirectargs, Aggref::aggdistinct, Aggref::aggfilter, WindowFunc::aggfilter, Aggref::aggorder, OnConflictExpr::arbiterElems, OnConflictExpr::arbiterWhere, NamedArgExpr::arg, FieldSelect::arg, FieldStore::arg, RelabelType::arg, CoerceViaIO::arg, ArrayCoerceExpr::arg, ConvertRowtypeExpr::arg, CollateExpr::arg, CaseExpr::arg, NullTest::arg, BooleanTest::arg, CoerceToDomain::arg, TableSampleClause::args, Aggref::args, GroupingFunc::args, WindowFunc::args, FuncExpr::args, OpExpr::args, ScalarArrayOpExpr::args, BoolExpr::args, SubPlan::args, CaseExpr::args, RowExpr::args, CoalesceExpr::args, MinMaxExpr::args, XmlExpr::args, check_stack_depth(), TableFunc::coldefexprs, TableFunc::colexprs, copyObject, CommonTableExpr::ctequery, CommonTableExpr::cycle_clause, CTECycleClause::cycle_mark_default, CTECycleClause::cycle_mark_value, CaseExpr::defresult, TableFunc::docexpr, ArrayExpr::elements, ArrayCoerceExpr::elemexpr, elog(), WindowClause::endOffset, ERROR, OnConflictExpr::exclRelTlist, CaseWhen::expr, InferenceElem::expr, TargetEntry::expr, PartitionPruneStepOp::exprs, FieldStore::fieldnums, FLATCOPY, FromExpr::fromlist, RangeTblFunction::funcexpr, IndexClause::indexquals, lappend(), SetOperationStmt::larg, JoinExpr::larg, RowCompareExpr::largs, lfirst, list_copy(), PartitionBoundSpec::listdatums, PartitionBoundSpec::lowerdatums, MUTATE, XmlExpr::named_args, FieldStore::newvals, NIL, nodeTag, TableFunc::ns_uris, OnConflictExpr::onConflictSet, OnConflictExpr::onConflictWhere, WindowClause::orderClause, WindowClause::partitionClause, PlaceHolderInfo::ph_var, WithCheckOption::qual, MergeAction::qual, JoinExpr::quals, FromExpr::quals, SetOperationStmt::rarg, JoinExpr::rarg, RowCompareExpr::rargs, SubscriptingRef::refassgnexpr, SubscriptingRef::refexpr, SubscriptingRef::reflowerindexpr, SubscriptingRef::refupperindexpr, TableSampleClause::repeatable, CaseWhen::result, IndexClause::rinfo, TableFunc::rowexpr, CommonTableExpr::search_clause, WindowClause::startOffset, AlternativeSubPlan::subplans, SubLink::subselect, MergeAction::targetList, SubLink::testexpr, SubPlan::testexpr, AppendRelInfo::translated_vars, PartitionBoundSpec::upperdatums, and PartitionRangeDatum::value.

◆ expression_tree_walker_impl()

bool expression_tree_walker_impl ( Node node,
tree_walker_callback  walker,
void *  context 
)

Definition at line 1893 of file nodeFuncs.c.

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

References generate_unaccent_rules::action, Aggref::aggdirectargs, Aggref::aggdistinct, Aggref::aggfilter, WindowFunc::aggfilter, Aggref::aggorder, OnConflictExpr::arbiterElems, OnConflictExpr::arbiterWhere, arg, FieldStore::arg, ArrayCoerceExpr::arg, CaseExpr::arg, generate_unaccent_rules::args, TableSampleClause::args, Aggref::args, GroupingFunc::args, WindowFunc::args, FuncExpr::args, OpExpr::args, ScalarArrayOpExpr::args, BoolExpr::args, SubPlan::args, CaseExpr::args, XmlExpr::args, check_stack_depth(), TableFunc::coldefexprs, TableFunc::colexprs, CommonTableExpr::ctequery, CommonTableExpr::cycle_clause, CTECycleClause::cycle_mark_default, CTECycleClause::cycle_mark_value, CaseExpr::defresult, TableFunc::docexpr, ArrayCoerceExpr::elemexpr, elog(), WindowClause::endOffset, ERROR, OnConflictExpr::exclRelTlist, PartitionPruneStepOp::exprs, FromExpr::fromlist, IndexClause::indexquals, SetOperationStmt::larg, JoinExpr::larg, RowCompareExpr::largs, lfirst, lfirst_node, LIST_WALK, PartitionBoundSpec::listdatums, PartitionBoundSpec::lowerdatums, XmlExpr::named_args, FieldStore::newvals, nodeTag, TableFunc::ns_uris, OnConflictExpr::onConflictSet, OnConflictExpr::onConflictWhere, WindowClause::orderClause, WindowClause::partitionClause, JoinExpr::quals, FromExpr::quals, SetOperationStmt::rarg, JoinExpr::rarg, RowCompareExpr::rargs, SubscriptingRef::refassgnexpr, SubscriptingRef::refexpr, SubscriptingRef::reflowerindexpr, SubscriptingRef::refupperindexpr, TableSampleClause::repeatable, IndexClause::rinfo, TableFunc::rowexpr, CommonTableExpr::search_clause, WindowClause::startOffset, SubLink::subselect, SubLink::testexpr, SubPlan::testexpr, AppendRelInfo::translated_vars, PartitionBoundSpec::upperdatums, PartitionRangeDatum::value, and WALK.

◆ exprInputCollation()

Oid exprInputCollation ( const Node expr)

Definition at line 972 of file nodeFuncs.c.

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

References InvalidOid, and nodeTag.

Referenced by check_simple_rowfilter_expr_walker(), and resolve_polymorphic_tupdesc().

◆ exprIsLengthCoercion()

bool exprIsLengthCoercion ( const Node expr,
int32 coercedTypmod 
)

Definition at line 500 of file nodeFuncs.c.

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

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

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

◆ exprLocation()

int exprLocation ( const Node expr)

Definition at line 1243 of file nodeFuncs.c.

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

References arg, TypeCast::arg, NamedArgExpr::arg, RelabelType::arg, CoerceViaIO::arg, ArrayCoerceExpr::arg, ConvertRowtypeExpr::arg, NullTest::arg, BooleanTest::arg, CoerceToDomain::arg, FuncExpr::args, OpExpr::args, ScalarArrayOpExpr::args, BoolExpr::args, XmlExpr::args, fc(), leftmostLoc(), A_Expr::lexpr, lfirst, TypeName::location, A_Expr::location, TypeCast::location, FuncExpr::location, NamedArgExpr::location, OpExpr::location, ScalarArrayOpExpr::location, BoolExpr::location, SubLink::location, RelabelType::location, CoerceViaIO::location, ArrayCoerceExpr::location, ConvertRowtypeExpr::location, XmlExpr::location, NullTest::location, BooleanTest::location, CoerceToDomain::location, nodeTag, source, SubLink::testexpr, and TypeCast::typeName.

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

◆ exprSetCollation()

void exprSetCollation ( Node expr,
Oid  collation 
)

Definition at line 1020 of file nodeFuncs.c.

1021 {
1022  switch (nodeTag(expr))
1023  {
1024  case T_Var:
1025  ((Var *) expr)->varcollid = collation;
1026  break;
1027  case T_Const:
1028  ((Const *) expr)->constcollid = collation;
1029  break;
1030  case T_Param:
1031  ((Param *) expr)->paramcollid = collation;
1032  break;
1033  case T_Aggref:
1034  ((Aggref *) expr)->aggcollid = collation;
1035  break;
1036  case T_GroupingFunc:
1037  Assert(!OidIsValid(collation));
1038  break;
1039  case T_WindowFunc:
1040  ((WindowFunc *) expr)->wincollid = collation;
1041  break;
1042  case T_SubscriptingRef:
1043  ((SubscriptingRef *) expr)->refcollid = collation;
1044  break;
1045  case T_FuncExpr:
1046  ((FuncExpr *) expr)->funccollid = collation;
1047  break;
1048  case T_NamedArgExpr:
1049  Assert(collation == exprCollation((Node *) ((NamedArgExpr *) expr)->arg));
1050  break;
1051  case T_OpExpr:
1052  ((OpExpr *) expr)->opcollid = collation;
1053  break;
1054  case T_DistinctExpr:
1055  ((DistinctExpr *) expr)->opcollid = collation;
1056  break;
1057  case T_NullIfExpr:
1058  ((NullIfExpr *) expr)->opcollid = collation;
1059  break;
1060  case T_ScalarArrayOpExpr:
1061  /* ScalarArrayOpExpr's result is boolean ... */
1062  Assert(!OidIsValid(collation)); /* ... so never set a collation */
1063  break;
1064  case T_BoolExpr:
1065  /* BoolExpr's result is boolean ... */
1066  Assert(!OidIsValid(collation)); /* ... so never set a collation */
1067  break;
1068  case T_SubLink:
1069 #ifdef USE_ASSERT_CHECKING
1070  {
1071  SubLink *sublink = (SubLink *) expr;
1072 
1073  if (sublink->subLinkType == EXPR_SUBLINK ||
1074  sublink->subLinkType == ARRAY_SUBLINK)
1075  {
1076  /* get the collation of subselect's first target column */
1077  Query *qtree = (Query *) sublink->subselect;
1078  TargetEntry *tent;
1079 
1080  if (!qtree || !IsA(qtree, Query))
1081  elog(ERROR, "cannot set collation for untransformed sublink");
1082  tent = linitial_node(TargetEntry, qtree->targetList);
1083  Assert(!tent->resjunk);
1084  Assert(collation == exprCollation((Node *) tent->expr));
1085  }
1086  else
1087  {
1088  /* otherwise, result is RECORD or BOOLEAN */
1089  Assert(!OidIsValid(collation));
1090  }
1091  }
1092 #endif /* USE_ASSERT_CHECKING */
1093  break;
1094  case T_FieldSelect:
1095  ((FieldSelect *) expr)->resultcollid = collation;
1096  break;
1097  case T_FieldStore:
1098  /* FieldStore's result is composite ... */
1099  Assert(!OidIsValid(collation)); /* ... so never set a collation */
1100  break;
1101  case T_RelabelType:
1102  ((RelabelType *) expr)->resultcollid = collation;
1103  break;
1104  case T_CoerceViaIO:
1105  ((CoerceViaIO *) expr)->resultcollid = collation;
1106  break;
1107  case T_ArrayCoerceExpr:
1108  ((ArrayCoerceExpr *) expr)->resultcollid = collation;
1109  break;
1110  case T_ConvertRowtypeExpr:
1111  /* ConvertRowtypeExpr's result is composite ... */
1112  Assert(!OidIsValid(collation)); /* ... so never set a collation */
1113  break;
1114  case T_CaseExpr:
1115  ((CaseExpr *) expr)->casecollid = collation;
1116  break;
1117  case T_ArrayExpr:
1118  ((ArrayExpr *) expr)->array_collid = collation;
1119  break;
1120  case T_RowExpr:
1121  /* RowExpr's result is composite ... */
1122  Assert(!OidIsValid(collation)); /* ... so never set a collation */
1123  break;
1124  case T_RowCompareExpr:
1125  /* RowCompareExpr's result is boolean ... */
1126  Assert(!OidIsValid(collation)); /* ... so never set a collation */
1127  break;
1128  case T_CoalesceExpr:
1129  ((CoalesceExpr *) expr)->coalescecollid = collation;
1130  break;
1131  case T_MinMaxExpr:
1132  ((MinMaxExpr *) expr)->minmaxcollid = collation;
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  /* NullTest's result is boolean ... */
1141  Assert(!OidIsValid(collation)); /* ... so never set a collation */
1142  break;
1143  case T_BooleanTest:
1144  /* BooleanTest's result is boolean ... */
1145  Assert(!OidIsValid(collation)); /* ... so never set a collation */
1146  break;
1147  case T_CoerceToDomain:
1148  ((CoerceToDomain *) expr)->resultcollid = collation;
1149  break;
1150  case T_CoerceToDomainValue:
1151  ((CoerceToDomainValue *) expr)->collation = collation;
1152  break;
1153  case T_SetToDefault:
1154  ((SetToDefault *) expr)->collation = collation;
1155  break;
1156  case T_CurrentOfExpr:
1157  /* CurrentOfExpr's result is boolean ... */
1158  Assert(!OidIsValid(collation)); /* ... so never set a collation */
1159  break;
1160  case T_NextValueExpr:
1161  /* NextValueExpr's result is an integer type ... */
1162  Assert(!OidIsValid(collation)); /* ... so never set a collation */
1163  break;
1164  default:
1165  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
1166  break;
1167  }
1168 }
#define OidIsValid(objectId)
Definition: c.h:711

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

Referenced by assign_collations_walker().

◆ exprSetInputCollation()

void exprSetInputCollation ( Node expr,
Oid  inputcollation 
)

Definition at line 1179 of file nodeFuncs.c.

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

References nodeTag.

Referenced by assign_collations_walker().

◆ exprType()

Oid exprType ( const Node expr)

Definition at line 43 of file nodeFuncs.c.

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

References arg, ARRAY_SUBLINK, Assert(), elog(), ereport, errcode(), errmsg(), ERROR, InferenceElem::expr, EXPR_SUBLINK, SubPlan::firstColType, format_type_be(), get_promoted_array_type(), if(), InvalidOid, IS_DOCUMENT, IS_XMLSERIALIZE, IsA, linitial, linitial_node, MULTIEXPR_SUBLINK, nodeTag, OidIsValid, SubLink::subLinkType, SubPlan::subLinkType, AlternativeSubPlan::subplans, SubLink::subselect, Query::targetList, and generate_unaccent_rules::type.

Referenced by add_row_identity_var(), addRangeTableEntryForFunction(), addRangeTableEntryForSubquery(), addTargetToGroupList(), addTargetToSortList(), analyzeCTE(), analyzeCTETargetList(), appendAggOrderBy(), appendOrderByClause(), applyRelabelType(), array_subscript_transform(), assign_collations_walker(), assign_hypothetical_collations(), assign_param_for_placeholdervar(), ATExecAlterColumnType(), ATPrepAlterColumnType(), build_coercion_expression(), build_column_default(), build_subplan(), can_minmax_aggs(), canonicalize_ec_expression(), check_functions_in_node(), check_hashjoinable(), check_memoizable(), check_mergejoinable(), check_simple_rowfilter_expr_walker(), check_sql_fn_retval(), checkRuleResultList(), coerce_fn_result_column(), coerce_record_to_complex(), coerce_to_boolean(), coerce_to_common_type(), coerce_to_specific_type_typmod(), compare_tlist_datatypes(), compute_semijoin_info(), ComputeIndexAttrs(), ComputePartitionAttrs(), ConstructTupleDescriptor(), convert_EXISTS_to_ANY(), cookDefault(), cost_qual_eval_walker(), create_ctas_nodata(), create_indexscan_plan(), CreateStatistics(), DefineVirtualRelation(), deparseNullTest(), deparseOpExpr(), estimate_num_groups(), eval_const_expressions_mutator(), EvaluateParams(), examine_attribute(), examine_expression(), examine_variable(), exec_save_simple_expr(), ExecBuildProjectionInfo(), ExecBuildUpdateProjection(), ExecCheckPlanOutput(), ExecEvalXmlExpr(), ExecInitExprRec(), ExecInitIndexScan(), ExecMakeTableFunctionResult(), ExecTypeFromExprList(), ExecTypeFromTLInternal(), ExecWindowAgg(), expandRecordVariable(), expandRTE(), exprTypmod(), find_expr_references_walker(), find_placeholder_info(), fix_indexqual_operand(), foreign_expr_walker(), generate_append_tlist(), generate_join_implied_equalities_normal(), generate_setop_tlist(), generate_subquery_params(), generateClonedIndexStmt(), get_call_expr_argtype(), get_expr_result_tupdesc(), get_expr_result_type(), get_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(), GetIndexInputType(), hash_ok_operator(), hstore_subscript_transform(), initialize_peragg(), inline_function(), internal_get_result_type(), jsonb_exec_setup(), jsonb_subscript_transform(), make_op(), make_scalar_array_op(), makeVarFromTargetEntry(), makeWholeRowVar(), match_pattern_prefix(), ordered_set_startup(), paraminfo_get_equal_hashops(), ParseFuncOrColumn(), pg_get_indexdef_worker(), pg_get_partkeydef_worker(), prepare_query_params(), preprocess_aggref(), preprocess_minmax_aggregates(), ProcedureCreate(), process_equivalence(), process_matched_tle(), recheck_cast_function_args(), relabel_to_typmod(), RelationBuildPartitionKey(), RelationGetDummyIndexExpressions(), remove_unused_subquery_outputs(), replace_nestloop_param_placeholdervar(), replace_outer_grouping(), replace_outer_placeholdervar(), resolveTargetListUnknowns(), scalararraysel(), select_common_type(), select_common_typmod(), set_append_rel_size(), set_dummy_tlist_references(), set_joinrel_partition_key_exprs(), set_pathtarget_cost_width(), set_rel_width(), show_sortorder_options(), tlist_same_datatypes(), transformAExprNullIf(), transformAggregateCall(), transformArrayExpr(), transformAssignedExpr(), transformAssignmentIndirection(), transformAssignmentSubscripts(), transformCaseExpr(), transformCollateClause(), transformExprRecurse(), transformFrameOffset(), transformFromClauseItem(), transformIndirection(), transformInsertStmt(), transformMultiAssignRef(), transformPartitionBoundValue(), transformPLAssignStmt(), transformSetOperationTree(), transformSubLink(), transformTypeCast(), unknown_attribute(), verify_common_type(), and xmlelement().

◆ exprTypmod()

int32 exprTypmod ( const Node expr)

Definition at line 266 of file nodeFuncs.c.

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

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

Referenced by add_row_identity_var(), addRangeTableEntryForFunction(), addRangeTableEntryForSubquery(), analyzeCTE(), analyzeCTETargetList(), applyRelabelType(), assign_hypothetical_collations(), build_coercion_expression(), build_subplan(), canonicalize_ec_expression(), checkRuleResultList(), coerce_type_typmod(), ConstructTupleDescriptor(), convert_EXISTS_to_ANY(), create_ctas_nodata(), DefineVirtualRelation(), eval_const_expressions_mutator(), examine_attribute(), examine_expression(), examine_variable(), exec_save_simple_expr(), ExecTypeFromExprList(), ExecTypeFromTLInternal(), expandRecordVariable(), expandRTE(), find_placeholder_info(), generate_append_tlist(), generate_setop_tlist(), generate_subquery_params(), get_expr_result_type(), get_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(), transformMultiAssignRef(), transformPLAssignStmt(), transformSubLink(), varbit_support(), and varchar_support().

◆ fix_opfuncids()

void fix_opfuncids ( Node node)

Definition at line 1641 of file nodeFuncs.c.

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

References fix_opfuncids_walker().

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

◆ fix_opfuncids_walker()

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

Definition at line 1648 of file nodeFuncs.c.

1649 {
1650  if (node == NULL)
1651  return false;
1652  if (IsA(node, OpExpr))
1653  set_opfuncid((OpExpr *) node);
1654  else if (IsA(node, DistinctExpr))
1655  set_opfuncid((OpExpr *) node); /* rely on struct equivalence */
1656  else if (IsA(node, NullIfExpr))
1657  set_opfuncid((OpExpr *) node); /* rely on struct equivalence */
1658  else if (IsA(node, ScalarArrayOpExpr))
1660  return expression_tree_walker(node, fix_opfuncids_walker, context);
1661 }

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

Referenced by fix_opfuncids().

◆ leftmostLoc()

static int leftmostLoc ( int  loc1,
int  loc2 
)
static

Definition at line 1620 of file nodeFuncs.c.

1621 {
1622  if (loc1 < 0)
1623  return loc2;
1624  else if (loc2 < 0)
1625  return loc1;
1626  else
1627  return Min(loc1, loc2);
1628 }
#define Min(x, y)
Definition: c.h:937

References Min.

Referenced by exprLocation().

◆ planstate_tree_walker_impl()

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

Definition at line 4057 of file nodeFuncs.c.

4060 {
4061  Plan *plan = planstate->plan;
4062  ListCell *lc;
4063 
4064  /* We don't need implicit coercions to Node here */
4065 #define PSWALK(n) walker(n, context)
4066 
4067  /* Guard against stack overflow due to overly complex plan trees */
4069 
4070  /* initPlan-s */
4071  if (planstate_walk_subplans(planstate->initPlan, walker, context))
4072  return true;
4073 
4074  /* lefttree */
4075  if (outerPlanState(planstate))
4076  {
4077  if (PSWALK(outerPlanState(planstate)))
4078  return true;
4079  }
4080 
4081  /* righttree */
4082  if (innerPlanState(planstate))
4083  {
4084  if (PSWALK(innerPlanState(planstate)))
4085  return true;
4086  }
4087 
4088  /* special child plans */
4089  switch (nodeTag(plan))
4090  {
4091  case T_Append:
4092  if (planstate_walk_members(((AppendState *) planstate)->appendplans,
4093  ((AppendState *) planstate)->as_nplans,
4094  walker, context))
4095  return true;
4096  break;
4097  case T_MergeAppend:
4098  if (planstate_walk_members(((MergeAppendState *) planstate)->mergeplans,
4099  ((MergeAppendState *) planstate)->ms_nplans,
4100  walker, context))
4101  return true;
4102  break;
4103  case T_BitmapAnd:
4104  if (planstate_walk_members(((BitmapAndState *) planstate)->bitmapplans,
4105  ((BitmapAndState *) planstate)->nplans,
4106  walker, context))
4107  return true;
4108  break;
4109  case T_BitmapOr:
4110  if (planstate_walk_members(((BitmapOrState *) planstate)->bitmapplans,
4111  ((BitmapOrState *) planstate)->nplans,
4112  walker, context))
4113  return true;
4114  break;
4115  case T_SubqueryScan:
4116  if (PSWALK(((SubqueryScanState *) planstate)->subplan))
4117  return true;
4118  break;
4119  case T_CustomScan:
4120  foreach(lc, ((CustomScanState *) planstate)->custom_ps)
4121  {
4122  if (PSWALK(lfirst(lc)))
4123  return true;
4124  }
4125  break;
4126  default:
4127  break;
4128  }
4129 
4130  /* subPlan-s */
4131  if (planstate_walk_subplans(planstate->subPlan, walker, context))
4132  return true;
4133 
4134  return false;
4135 }
#define outerPlanState(node)
Definition: execnodes.h:1125
#define innerPlanState(node)
Definition: execnodes.h:1124
static bool planstate_walk_subplans(List *plans, planstate_tree_walker_callback walker, void *context)
Definition: nodeFuncs.c:4141
#define PSWALK(n)
static bool planstate_walk_members(PlanState **planstates, int nplans, planstate_tree_walker_callback walker, void *context)
Definition: nodeFuncs.c:4163
Plan * plan
Definition: execnodes.h:1029
List * initPlan
Definition: execnodes.h:1054

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

◆ planstate_walk_members()

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

Definition at line 4163 of file nodeFuncs.c.

4166 {
4167  int j;
4168 
4169  for (j = 0; j < nplans; j++)
4170  {
4171  if (PSWALK(planstates[j]))
4172  return true;
4173  }
4174 
4175  return false;
4176 }
int j
Definition: isn.c:74

References j, and PSWALK.

Referenced by planstate_tree_walker_impl().

◆ planstate_walk_subplans()

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

Definition at line 4141 of file nodeFuncs.c.

4144 {
4145  ListCell *lc;
4146 
4147  foreach(lc, plans)
4148  {
4150 
4151  if (PSWALK(sps->planstate))
4152  return true;
4153  }
4154 
4155  return false;
4156 }
struct PlanState * planstate
Definition: execnodes.h:945

References lfirst_node, SubPlanState::planstate, and PSWALK.

Referenced by planstate_tree_walker_impl().

◆ query_or_expression_tree_mutator_impl()

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

Definition at line 3521 of file nodeFuncs.c.

3525 {
3526  if (node && IsA(node, Query))
3527  return (Node *) query_tree_mutator((Query *) node,
3528  mutator,
3529  context,
3530  flags);
3531  else
3532  return mutator(node, context);
3533 }
#define query_tree_mutator(q, m, c, f)
Definition: nodeFuncs.h:158

References IsA, and query_tree_mutator.

◆ query_or_expression_tree_walker_impl()

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

Definition at line 3498 of file nodeFuncs.c.

3502 {
3503  if (node && IsA(node, Query))
3504  return query_tree_walker((Query *) node,
3505  walker,
3506  context,
3507  flags);
3508  else
3509  return WALK(node);
3510 }
#define query_tree_walker(q, w, c, f)
Definition: nodeFuncs.h:156

References IsA, query_tree_walker, and WALK.

◆ query_tree_mutator_impl()

Query* query_tree_mutator_impl ( Query query,
tree_mutator_callback  mutator,
void *  context,
int  flags 
)

Definition at line 3339 of file nodeFuncs.c.

3343 {
3344  Assert(query != NULL && IsA(query, Query));
3345 
3346  if (!(flags & QTW_DONT_COPY_QUERY))
3347  {
3348  Query *newquery;
3349 
3350  FLATCOPY(newquery, query, Query);
3351  query = newquery;
3352  }
3353 
3354  MUTATE(query->targetList, query->targetList, List *);
3355  MUTATE(query->withCheckOptions, query->withCheckOptions, List *);
3356  MUTATE(query->onConflict, query->onConflict, OnConflictExpr *);
3357  MUTATE(query->mergeActionList, query->mergeActionList, List *);
3358  MUTATE(query->returningList, query->returningList, List *);
3359  MUTATE(query->jointree, query->jointree, FromExpr *);
3360  MUTATE(query->setOperations, query->setOperations, Node *);
3361  MUTATE(query->havingQual, query->havingQual, Node *);
3362  MUTATE(query->limitOffset, query->limitOffset, Node *);
3363  MUTATE(query->limitCount, query->limitCount, Node *);
3364 
3365  /*
3366  * Most callers aren't interested in SortGroupClause nodes since those
3367  * don't contain actual expressions. However they do contain OIDs, which
3368  * may be of interest to some mutators.
3369  */
3370 
3371  if ((flags & QTW_EXAMINE_SORTGROUP))
3372  {
3373  MUTATE(query->groupClause, query->groupClause, List *);
3374  MUTATE(query->windowClause, query->windowClause, List *);
3375  MUTATE(query->sortClause, query->sortClause, List *);
3376  MUTATE(query->distinctClause, query->distinctClause, List *);
3377  }
3378  else
3379  {
3380  /*
3381  * But we need to mutate the expressions under WindowClause nodes even
3382  * if we're not interested in SortGroupClause nodes.
3383  */
3384  List *resultlist;
3385  ListCell *temp;
3386 
3387  resultlist = NIL;
3388  foreach(temp, query->windowClause)
3389  {
3390  WindowClause *wc = lfirst_node(WindowClause, temp);
3391  WindowClause *newnode;
3392 
3393  FLATCOPY(newnode, wc, WindowClause);
3394  MUTATE(newnode->startOffset, wc->startOffset, Node *);
3395  MUTATE(newnode->endOffset, wc->endOffset, Node *);
3396 
3397  resultlist = lappend(resultlist, (Node *) newnode);
3398  }
3399  query->windowClause = resultlist;
3400  }
3401 
3402  /*
3403  * groupingSets and rowMarks are not mutated:
3404  *
3405  * groupingSets contain only ressortgroup refs (integers) which are
3406  * meaningless without the groupClause or tlist. Accordingly, any mutator
3407  * that needs to care about them needs to handle them itself in its Query
3408  * processing.
3409  *
3410  * rowMarks contains only rangetable indexes (and flags etc.) and
3411  * therefore should be handled at Query level similarly.
3412  */
3413 
3414  if (!(flags & QTW_IGNORE_CTE_SUBQUERIES))
3415  MUTATE(query->cteList, query->cteList, List *);
3416  else /* else copy CTE list as-is */
3417  query->cteList = copyObject(query->cteList);
3418  query->rtable = range_table_mutator(query->rtable,
3419  mutator, context, flags);
3420  return query;
3421 }
#define QTW_DONT_COPY_QUERY
Definition: nodeFuncs.h:29
#define QTW_IGNORE_CTE_SUBQUERIES
Definition: nodeFuncs.h:23
#define QTW_EXAMINE_SORTGROUP
Definition: nodeFuncs.h:30
#define range_table_mutator(rt, m, c, f)
Definition: nodeFuncs.h:163
List * withCheckOptions
Definition: parsenodes.h:195
Node * limitCount
Definition: parsenodes.h:184
FromExpr * jointree
Definition: parsenodes.h:156
List * returningList
Definition: parsenodes.h:168
Node * setOperations
Definition: parsenodes.h:189
List * cteList
Definition: parsenodes.h:153
OnConflictExpr * onConflict
Definition: parsenodes.h:166
List * groupClause
Definition: parsenodes.h:170
Node * havingQual
Definition: parsenodes.h:175
List * rtable
Definition: parsenodes.h:155
Node * limitOffset
Definition: parsenodes.h:183
List * mergeActionList
Definition: parsenodes.h:159
List * windowClause
Definition: parsenodes.h:177
List * distinctClause
Definition: parsenodes.h:179
List * sortClause
Definition: parsenodes.h:181

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

◆ query_tree_walker_impl()

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

Definition at line 2364 of file nodeFuncs.c.

2368 {
2369  Assert(query != NULL && IsA(query, Query));
2370 
2371  /*
2372  * We don't walk any utilityStmt here. However, we can't easily assert
2373  * that it is absent, since there are at least two code paths by which
2374  * action statements from CREATE RULE end up here, and NOTIFY is allowed
2375  * in a rule action.
2376  */
2377 
2378  if (WALK(query->targetList))
2379  return true;
2380  if (WALK(query->withCheckOptions))
2381  return true;
2382  if (WALK(query->onConflict))
2383  return true;
2384  if (WALK(query->mergeActionList))
2385  return true;
2386  if (WALK(query->returningList))
2387  return true;
2388  if (WALK(query->jointree))
2389  return true;
2390  if (WALK(query->setOperations))
2391  return true;
2392  if (WALK(query->havingQual))
2393  return true;
2394  if (WALK(query->limitOffset))
2395  return true;
2396  if (WALK(query->limitCount))
2397  return true;
2398 
2399  /*
2400  * Most callers aren't interested in SortGroupClause nodes since those
2401  * don't contain actual expressions. However they do contain OIDs which
2402  * may be needed by dependency walkers etc.
2403  */
2404  if ((flags & QTW_EXAMINE_SORTGROUP))
2405  {
2406  if (WALK(query->groupClause))
2407  return true;
2408  if (WALK(query->windowClause))
2409  return true;
2410  if (WALK(query->sortClause))
2411  return true;
2412  if (WALK(query->distinctClause))
2413  return true;
2414  }
2415  else
2416  {
2417  /*
2418  * But we need to walk the expressions under WindowClause nodes even
2419  * if we're not interested in SortGroupClause nodes.
2420  */
2421  ListCell *lc;
2422 
2423  foreach(lc, query->windowClause)
2424  {
2426 
2427  if (WALK(wc->startOffset))
2428  return true;
2429  if (WALK(wc->endOffset))
2430  return true;
2431  }
2432  }
2433 
2434  /*
2435  * groupingSets and rowMarks are not walked:
2436  *
2437  * groupingSets contain only ressortgrouprefs (integers) which are
2438  * meaningless without the corresponding groupClause or tlist.
2439  * Accordingly, any walker that needs to care about them needs to handle
2440  * them itself in its Query processing.
2441  *
2442  * rowMarks is not walked because it contains only rangetable indexes (and
2443  * flags etc.) and therefore should be handled at Query level similarly.
2444  */
2445 
2446  if (!(flags & QTW_IGNORE_CTE_SUBQUERIES))
2447  {
2448  if (WALK(query->cteList))
2449  return true;
2450  }
2451  if (!(flags & QTW_IGNORE_RANGE_TABLE))
2452  {
2453  if (range_table_walker(query->rtable, walker, context, flags))
2454  return true;
2455  }
2456  return false;
2457 }
#define range_table_walker(rt, w, c, f)
Definition: nodeFuncs.h:161
#define QTW_IGNORE_RANGE_TABLE
Definition: nodeFuncs.h:26

References Assert(), Query::cteList, Query::distinctClause, WindowClause::endOffset, Query::groupClause, Query::havingQual, IsA, Query::jointree, lfirst_node, Query::limitCount, Query::limitOffset, Query::mergeActionList, Query::onConflict, QTW_EXAMINE_SORTGROUP, QTW_IGNORE_CTE_SUBQUERIES, QTW_IGNORE_RANGE_TABLE, range_table_walker, Query::returningList, Query::rtable, Query::setOperations, Query::sortClause, WindowClause::startOffset, Query::targetList, WALK, Query::windowClause, and Query::withCheckOptions.

◆ range_table_entry_walker_impl()

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

Definition at line 2486 of file nodeFuncs.c.

2490 {
2491  /*
2492  * Walkers might need to examine the RTE node itself either before or
2493  * after visiting its contents (or, conceivably, both). Note that if you
2494  * specify neither flag, the walker won't be called on the RTE at all.
2495  */
2496  if (flags & QTW_EXAMINE_RTES_BEFORE)
2497  if (WALK(rte))
2498  return true;
2499 
2500  switch (rte->rtekind)
2501  {
2502  case RTE_RELATION:
2503  if (WALK(rte->tablesample))
2504  return true;
2505  break;
2506  case RTE_SUBQUERY:
2507  if (!(flags & QTW_IGNORE_RT_SUBQUERIES))
2508  if (WALK(rte->subquery))
2509  return true;
2510  break;
2511  case RTE_JOIN:
2512  if (!(flags & QTW_IGNORE_JOINALIASES))
2513  if (WALK(rte->joinaliasvars))
2514  return true;
2515  break;
2516  case RTE_FUNCTION:
2517  if (WALK(rte->functions))
2518  return true;
2519  break;
2520  case RTE_TABLEFUNC:
2521  if (WALK(rte->tablefunc))
2522  return true;
2523  break;
2524  case RTE_VALUES:
2525  if (WALK(rte->values_lists))
2526  return true;
2527  break;
2528  case RTE_CTE:
2529  case RTE_NAMEDTUPLESTORE:
2530  case RTE_RESULT:
2531  /* nothing to do */
2532  break;
2533  }
2534 
2535  if (WALK(rte->securityQuals))
2536  return true;
2537 
2538  if (flags & QTW_EXAMINE_RTES_AFTER)
2539  if (WALK(rte))
2540  return true;
2541 
2542  return false;
2543 }
#define QTW_IGNORE_RT_SUBQUERIES
Definition: nodeFuncs.h:22
#define QTW_EXAMINE_RTES_AFTER
Definition: nodeFuncs.h:28
#define QTW_EXAMINE_RTES_BEFORE
Definition: nodeFuncs.h:27
#define QTW_IGNORE_JOINALIASES
Definition: nodeFuncs.h:25
@ RTE_JOIN
Definition: parsenodes.h:1013
@ RTE_CTE
Definition: parsenodes.h:1017
@ RTE_NAMEDTUPLESTORE
Definition: parsenodes.h:1018
@ RTE_VALUES
Definition: parsenodes.h:1016
@ RTE_SUBQUERY
Definition: parsenodes.h:1012
@ RTE_RESULT
Definition: parsenodes.h:1019
@ RTE_FUNCTION
Definition: parsenodes.h:1014
@ RTE_TABLEFUNC
Definition: parsenodes.h:1015
@ RTE_RELATION
Definition: parsenodes.h:1011
TableFunc * tablefunc
Definition: parsenodes.h:1130
struct TableSampleClause * tablesample
Definition: parsenodes.h:1060
List * securityQuals
Definition: parsenodes.h:1186
Query * subquery
Definition: parsenodes.h:1065
List * values_lists
Definition: parsenodes.h:1135
List * joinaliasvars
Definition: parsenodes.h:1105
List * functions
Definition: parsenodes.h:1124
RTEKind rtekind
Definition: parsenodes.h:1030

References RangeTblEntry::functions, RangeTblEntry::joinaliasvars, QTW_EXAMINE_RTES_AFTER, QTW_EXAMINE_RTES_BEFORE, QTW_IGNORE_JOINALIASES, QTW_IGNORE_RT_SUBQUERIES, RTE_CTE, RTE_FUNCTION, RTE_JOIN, RTE_NAMEDTUPLESTORE, RTE_RELATION, RTE_RESULT, RTE_SUBQUERY, RTE_TABLEFUNC, RTE_VALUES, RangeTblEntry::rtekind, RangeTblEntry::securityQuals, RangeTblEntry::subquery, RangeTblEntry::tablefunc, RangeTblEntry::tablesample, RangeTblEntry::values_lists, and WALK.

◆ range_table_mutator_impl()

List* range_table_mutator_impl ( List rtable,
tree_mutator_callback  mutator,
void *  context,
int  flags 
)

Definition at line 3429 of file nodeFuncs.c.

3433 {
3434  List *newrt = NIL;
3435  ListCell *rt;
3436 
3437  foreach(rt, rtable)
3438  {
3439  RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
3440  RangeTblEntry *newrte;
3441 
3442  FLATCOPY(newrte, rte, RangeTblEntry);
3443  switch (rte->rtekind)
3444  {
3445  case RTE_RELATION:
3446  MUTATE(newrte->tablesample, rte->tablesample,
3447  TableSampleClause *);
3448  /* we don't bother to copy eref, aliases, etc; OK? */
3449  break;
3450  case RTE_SUBQUERY:
3451  if (!(flags & QTW_IGNORE_RT_SUBQUERIES))
3452  MUTATE(newrte->subquery, rte->subquery, Query *);
3453  else
3454  {
3455  /* else, copy RT subqueries as-is */
3456  newrte->subquery = copyObject(rte->subquery);
3457  }
3458  break;
3459  case RTE_JOIN:
3460  if (!(flags & QTW_IGNORE_JOINALIASES))
3461  MUTATE(newrte->joinaliasvars, rte->joinaliasvars, List *);
3462  else
3463  {
3464  /* else, copy join aliases as-is */
3465  newrte->joinaliasvars = copyObject(rte->joinaliasvars);
3466  }
3467  break;
3468  case RTE_FUNCTION:
3469  MUTATE(newrte->functions, rte->functions, List *);
3470  break;
3471  case RTE_TABLEFUNC:
3472  MUTATE(newrte->tablefunc, rte->tablefunc, TableFunc *);
3473  break;
3474  case RTE_VALUES:
3475  MUTATE(newrte->values_lists, rte->values_lists, List *);
3476  break;
3477  case RTE_CTE:
3478  case RTE_NAMEDTUPLESTORE:
3479  case RTE_RESULT:
3480  /* nothing to do */
3481  break;
3482  }
3483  MUTATE(newrte->securityQuals, rte->securityQuals, List *);
3484  newrt = lappend(newrt, newrte);
3485  }
3486  return newrt;
3487 }

References copyObject, FLATCOPY, RangeTblEntry::functions, RangeTblEntry::joinaliasvars, lappend(), lfirst, MUTATE, NIL, QTW_IGNORE_JOINALIASES, QTW_IGNORE_RT_SUBQUERIES, RTE_CTE, RTE_FUNCTION, RTE_JOIN, RTE_NAMEDTUPLESTORE, RTE_RELATION, RTE_RESULT, RTE_SUBQUERY, RTE_TABLEFUNC, RTE_VALUES, RangeTblEntry::rtekind, RangeTblEntry::securityQuals, RangeTblEntry::subquery, RangeTblEntry::tablefunc, RangeTblEntry::tablesample, and RangeTblEntry::values_lists.

◆ range_table_walker_impl()

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

Definition at line 2465 of file nodeFuncs.c.

2469 {
2470  ListCell *rt;
2471 
2472  foreach(rt, rtable)
2473  {
2475 
2476  if (range_table_entry_walker(rte, walker, context, flags))
2477  return true;
2478  }
2479  return false;
2480 }
#define range_table_entry_walker(r, w, c, f)
Definition: nodeFuncs.h:166

References lfirst_node, and range_table_entry_walker.

◆ raw_expression_tree_walker_impl()

bool raw_expression_tree_walker_impl ( Node node,
tree_walker_callback  walker,
void *  context 
)

Definition at line 3552 of file nodeFuncs.c.

3555 {
3556  ListCell *temp;
3557 
3558  /*
3559  * The walker has already visited the current node, and so we need only
3560  * recurse into any sub-nodes it has.
3561  */
3562  if (node == NULL)
3563  return false;
3564 
3565  /* Guard against stack overflow due to overly complex expressions */
3567 
3568  switch (nodeTag(node))
3569  {
3570  case T_SetToDefault:
3571  case T_CurrentOfExpr:
3572  case T_Integer:
3573  case T_Float:
3574  case T_Boolean:
3575  case T_String:
3576  case T_BitString:
3577  case T_ParamRef:
3578  case T_A_Const:
3579  case T_A_Star:
3580  /* primitive node types with no subnodes */
3581  break;
3582  case T_Alias:
3583  /* we assume the colnames list isn't interesting */
3584  break;
3585  case T_RangeVar:
3586  return WALK(((RangeVar *) node)->alias);
3587  case T_GroupingFunc:
3588  return WALK(((GroupingFunc *) node)->args);
3589  case T_SubLink:
3590  {
3591  SubLink *sublink = (SubLink *) node;
3592 
3593  if (WALK(sublink->testexpr))
3594  return true;
3595  /* we assume the operName is not interesting */
3596  if (WALK(sublink->subselect))
3597  return true;
3598  }
3599  break;
3600  case T_CaseExpr:
3601  {
3602  CaseExpr *caseexpr = (CaseExpr *) node;
3603 
3604  if (WALK(caseexpr->arg))
3605  return true;
3606  /* we assume walker doesn't care about CaseWhens, either */
3607  foreach(temp, caseexpr->args)
3608  {
3609  CaseWhen *when = lfirst_node(CaseWhen, temp);
3610 
3611  if (WALK(when->expr))
3612  return true;
3613  if (WALK(when->result))
3614  return true;
3615  }
3616  if (WALK(caseexpr->defresult))
3617  return true;
3618  }
3619  break;
3620  case T_RowExpr:
3621  /* Assume colnames isn't interesting */
3622  return WALK(((RowExpr *) node)->args);
3623  case T_CoalesceExpr:
3624  return WALK(((CoalesceExpr *) node)->args);
3625  case T_MinMaxExpr:
3626  return WALK(((MinMaxExpr *) node)->args);
3627  case T_XmlExpr:
3628  {
3629  XmlExpr *xexpr = (XmlExpr *) node;
3630 
3631  if (WALK(xexpr->named_args))
3632  return true;
3633  /* we assume walker doesn't care about arg_names */
3634  if (WALK(xexpr->args))
3635  return true;
3636  }
3637  break;
3638  case T_NullTest:
3639  return WALK(((NullTest *) node)->arg);
3640  case T_BooleanTest:
3641  return WALK(((BooleanTest *) node)->arg);
3642  case T_JoinExpr:
3643  {
3644  JoinExpr *join = (JoinExpr *) node;
3645 
3646  if (WALK(join->larg))
3647  return true;
3648  if (WALK(join->rarg))
3649  return true;
3650  if (WALK(join->quals))
3651  return true;
3652  if (WALK(join->alias))
3653  return true;
3654  /* using list is deemed uninteresting */
3655  }
3656  break;
3657  case T_IntoClause:
3658  {
3659  IntoClause *into = (IntoClause *) node;
3660 
3661  if (WALK(into->rel))
3662  return true;
3663  /* colNames, options are deemed uninteresting */
3664  /* viewQuery should be null in raw parsetree, but check it */
3665  if (WALK(into->viewQuery))
3666  return true;
3667  }
3668  break;
3669  case T_List:
3670  foreach(temp, (List *) node)
3671  {
3672  if (WALK((Node *) lfirst(temp)))
3673  return true;
3674  }
3675  break;
3676  case T_InsertStmt:
3677  {
3678  InsertStmt *stmt = (InsertStmt *) node;
3679 
3680  if (WALK(stmt->relation))
3681  return true;
3682  if (WALK(stmt->cols))
3683  return true;
3684  if (WALK(stmt->selectStmt))
3685  return true;
3686  if (WALK(stmt->onConflictClause))
3687  return true;
3688  if (WALK(stmt->returningList))
3689  return true;
3690  if (WALK(stmt->withClause))
3691  return true;
3692  }
3693  break;
3694  case T_DeleteStmt:
3695  {
3696  DeleteStmt *stmt = (DeleteStmt *) node;
3697 
3698  if (WALK(stmt->relation))
3699  return true;
3700  if (WALK(stmt->usingClause))
3701  return true;
3702  if (WALK(stmt->whereClause))
3703  return true;
3704  if (WALK(stmt->returningList))
3705  return true;
3706  if (WALK(stmt->withClause))
3707  return true;
3708  }
3709  break;
3710  case T_UpdateStmt:
3711  {
3712  UpdateStmt *stmt = (UpdateStmt *) node;
3713 
3714  if (WALK(stmt->relation))
3715  return true;
3716  if (WALK(stmt->targetList))
3717  return true;
3718  if (WALK(stmt->whereClause))
3719  return true;
3720  if (WALK(stmt->fromClause))
3721  return true;
3722  if (WALK(stmt->returningList))
3723  return true;
3724  if (WALK(stmt->withClause))
3725  return true;
3726  }
3727  break;
3728  case T_MergeStmt:
3729  {
3730  MergeStmt *stmt = (MergeStmt *) node;
3731 
3732  if (WALK(stmt->relation))
3733  return true;
3734  if (WALK(stmt->sourceRelation))
3735  return true;
3736  if (WALK(stmt->joinCondition))
3737  return true;
3738  if (WALK(stmt->mergeWhenClauses))
3739  return true;
3740  if (WALK(stmt->withClause))
3741  return true;
3742  }
3743  break;
3744  case T_MergeWhenClause:
3745  {
3746  MergeWhenClause *mergeWhenClause = (MergeWhenClause *) node;
3747 
3748  if (WALK(mergeWhenClause->condition))
3749  return true;
3750  if (WALK(mergeWhenClause->targetList))
3751  return true;
3752  if (WALK(mergeWhenClause->values))
3753  return true;
3754  }
3755  break;
3756  case T_SelectStmt:
3757  {
3758  SelectStmt *stmt = (SelectStmt *) node;
3759 
3760  if (WALK(stmt->distinctClause))
3761  return true;
3762  if (WALK(stmt->intoClause))
3763  return true;
3764  if (WALK(stmt->targetList))
3765  return true;
3766  if (WALK(stmt->fromClause))
3767  return true;
3768  if (WALK(stmt->whereClause))
3769  return true;
3770  if (WALK(stmt->groupClause))
3771  return true;
3772  if (WALK(stmt->havingClause))
3773  return true;
3774  if (WALK(stmt->windowClause))
3775  return true;
3776  if (WALK(stmt->valuesLists))
3777  return true;
3778  if (WALK(stmt->sortClause))
3779  return true;
3780  if (WALK(stmt->limitOffset))
3781  return true;
3782  if (WALK(stmt->limitCount))
3783  return true;
3784  if (WALK(stmt->lockingClause))
3785  return true;
3786  if (WALK(stmt->withClause))
3787  return true;
3788  if (WALK(stmt->larg))
3789  return true;
3790  if (WALK(stmt->rarg))
3791  return true;
3792  }
3793  break;
3794  case T_PLAssignStmt:
3795  {
3796  PLAssignStmt *stmt = (PLAssignStmt *) node;
3797 
3798  if (WALK(stmt->indirection))
3799  return true;
3800  if (WALK(stmt->val))
3801  return true;
3802  }
3803  break;
3804  case T_A_Expr:
3805  {
3806  A_Expr *expr = (A_Expr *) node;
3807 
3808  if (WALK(expr->lexpr))
3809  return true;
3810  if (WALK(expr->rexpr))
3811  return true;
3812  /* operator name is deemed uninteresting */
3813  }
3814  break;
3815  case T_BoolExpr:
3816  {
3817  BoolExpr *expr = (BoolExpr *) node;
3818 
3819  if (WALK(expr->args))
3820  return true;
3821  }
3822  break;
3823  case T_ColumnRef:
3824  /* we assume the fields contain nothing interesting */
3825  break;
3826  case T_FuncCall:
3827  {
3828  FuncCall *fcall = (FuncCall *) node;
3829 
3830  if (WALK(fcall->args))
3831  return true;
3832  if (WALK(fcall->agg_order))
3833  return true;
3834  if (WALK(fcall->agg_filter))
3835  return true;
3836  if (WALK(fcall->over))
3837  return true;
3838  /* function name is deemed uninteresting */
3839  }
3840  break;
3841  case T_NamedArgExpr:
3842  return WALK(((NamedArgExpr *) node)->arg);
3843  case T_A_Indices:
3844  {
3845  A_Indices *indices = (A_Indices *) node;
3846 
3847  if (WALK(indices->lidx))
3848  return true;
3849  if (WALK(indices->uidx))
3850  return true;
3851  }
3852  break;
3853  case T_A_Indirection:
3854  {
3855  A_Indirection *indir = (A_Indirection *) node;
3856 
3857  if (WALK(indir->arg))
3858  return true;
3859  if (WALK(indir->indirection))
3860  return true;
3861  }
3862  break;
3863  case T_A_ArrayExpr:
3864  return WALK(((A_ArrayExpr *) node)->elements);
3865  case T_ResTarget:
3866  {
3867  ResTarget *rt = (ResTarget *) node;
3868 
3869  if (WALK(rt->indirection))
3870  return true;
3871  if (WALK(rt->val))
3872  return true;
3873  }
3874  break;
3875  case T_MultiAssignRef:
3876  return WALK(((MultiAssignRef *) node)->source);
3877  case T_TypeCast:
3878  {
3879  TypeCast *tc = (TypeCast *) node;
3880 
3881  if (WALK(tc->arg))
3882  return true;
3883  if (WALK(tc->typeName))
3884  return true;
3885  }
3886  break;
3887  case T_CollateClause:
3888  return WALK(((CollateClause *) node)->arg);
3889  case T_SortBy:
3890  return WALK(((SortBy *) node)->node);
3891  case T_WindowDef:
3892  {
3893  WindowDef *wd = (WindowDef *) node;
3894 
3895  if (WALK(wd->partitionClause))
3896  return true;
3897  if (WALK(wd->orderClause))
3898  return true;
3899  if (WALK(wd->startOffset))
3900  return true;
3901  if (WALK(wd->endOffset))
3902  return true;
3903  }
3904  break;
3905  case T_RangeSubselect:
3906  {
3907  RangeSubselect *rs = (RangeSubselect *) node;
3908 
3909  if (WALK(rs->subquery))
3910  return true;
3911  if (WALK(rs->alias))
3912  return true;
3913  }
3914  break;
3915  case T_RangeFunction:
3916  {
3917  RangeFunction *rf = (RangeFunction *) node;
3918 
3919  if (WALK(rf->functions))
3920  return true;
3921  if (WALK(rf->alias))
3922  return true;
3923  if (WALK(rf->coldeflist))
3924  return true;
3925  }
3926  break;
3927  case T_RangeTableSample:
3928  {
3929  RangeTableSample *rts = (RangeTableSample *) node;
3930 
3931  if (WALK(rts->relation))
3932  return true;
3933  /* method name is deemed uninteresting */
3934  if (WALK(rts->args))
3935  return true;
3936  if (WALK(rts->repeatable))
3937  return true;
3938  }
3939  break;
3940  case T_RangeTableFunc:
3941  {
3942  RangeTableFunc *rtf = (RangeTableFunc *) node;
3943 
3944  if (WALK(rtf->docexpr))
3945  return true;
3946  if (WALK(rtf->rowexpr))
3947  return true;
3948  if (WALK(rtf->namespaces))
3949  return true;
3950  if (WALK(rtf->columns))
3951  return true;
3952  if (WALK(rtf->alias))
3953  return true;
3954  }
3955  break;
3956  case T_RangeTableFuncCol:
3957  {
3958  RangeTableFuncCol *rtfc = (RangeTableFuncCol *) node;
3959 
3960  if (WALK(rtfc->colexpr))
3961  return true;
3962  if (WALK(rtfc->coldefexpr))
3963  return true;
3964  }
3965  break;
3966  case T_TypeName:
3967  {
3968  TypeName *tn = (TypeName *) node;
3969 
3970  if (WALK(tn->typmods))
3971  return true;
3972  if (WALK(tn->arrayBounds))
3973  return true;
3974  /* type name itself is deemed uninteresting */
3975  }
3976  break;
3977  case T_ColumnDef:
3978  {
3979  ColumnDef *coldef = (ColumnDef *) node;
3980 
3981  if (WALK(coldef->typeName))
3982  return true;
3983  if (WALK(coldef->compression))
3984  return true;
3985  if (WALK(coldef->raw_default))
3986  return true;
3987  if (WALK(coldef->collClause))
3988  return true;
3989  /* for now, constraints are ignored */
3990  }
3991  break;
3992  case T_IndexElem:
3993  {
3994  IndexElem *indelem = (IndexElem *) node;
3995 
3996  if (WALK(indelem->expr))
3997  return true;
3998  /* collation and opclass names are deemed uninteresting */
3999  }
4000  break;
4001  case T_GroupingSet:
4002  return WALK(((GroupingSet *) node)->content);
4003  case T_LockingClause:
4004  return WALK(((LockingClause *) node)->lockedRels);
4005  case T_XmlSerialize:
4006  {
4007  XmlSerialize *xs = (XmlSerialize *) node;
4008 
4009  if (WALK(xs->expr))
4010  return true;
4011  if (WALK(xs->typeName))
4012  return true;
4013  }
4014  break;
4015  case T_WithClause:
4016  return WALK(((WithClause *) node)->ctes);
4017  case T_InferClause:
4018  {
4019  InferClause *stmt = (InferClause *) node;
4020 
4021  if (WALK(stmt->indexElems))
4022  return true;
4023  if (WALK(stmt->whereClause))
4024  return true;
4025  }
4026  break;
4027  case T_OnConflictClause:
4028  {
4029  OnConflictClause *stmt = (OnConflictClause *) node;
4030 
4031  if (WALK(stmt->infer))
4032  return true;
4033  if (WALK(stmt->targetList))
4034  return true;
4035  if (WALK(stmt->whereClause))
4036  return true;
4037  }
4038  break;
4039  case T_CommonTableExpr:
4040  /* search_clause and cycle_clause are not interesting here */
4041  return WALK(((CommonTableExpr *) node)->ctequery);
4042  default:
4043  elog(ERROR, "unrecognized node type: %d",
4044  (int) nodeTag(node));
4045  break;
4046  }
4047  return false;
4048 }
Node * rexpr
Definition: parsenodes.h:302
Node * uidx
Definition: parsenodes.h:426
Node * lidx
Definition: parsenodes.h:425
List * indirection
Definition: parsenodes.h:448
CollateClause * collClause
Definition: parsenodes.h:703
TypeName * typeName
Definition: parsenodes.h:689
Node * raw_default
Definition: parsenodes.h:697
char * compression
Definition: parsenodes.h:690
WithClause * withClause
Definition: parsenodes.h:1671
Node * whereClause
Definition: parsenodes.h:1669
RangeVar * relation
Definition: parsenodes.h:1667
List * usingClause
Definition: parsenodes.h:1668
List * returningList
Definition: parsenodes.h:1670
Node * agg_filter
Definition: parsenodes.h:394
List * agg_order
Definition: parsenodes.h:393
List * args
Definition: parsenodes.h:392
struct WindowDef * over
Definition: parsenodes.h:395
Node * expr
Definition: parsenodes.h:746
List * indexElems
Definition: parsenodes.h:1476
Node * whereClause
Definition: parsenodes.h:1477
OnConflictClause * onConflictClause
Definition: parsenodes.h:1654
Node * selectStmt
Definition: parsenodes.h:1653
WithClause * withClause
Definition: parsenodes.h:1656
RangeVar * relation
Definition: parsenodes.h:1651
List * cols
Definition: parsenodes.h:1652
List * returningList
Definition: parsenodes.h:1655
Node * viewQuery
Definition: primnodes.h:134
RangeVar * rel
Definition: primnodes.h:128
Alias * alias
Definition: primnodes.h:1648
Node * sourceRelation
Definition: parsenodes.h:1697
List * mergeWhenClauses
Definition: parsenodes.h:1699
RangeVar * relation
Definition: parsenodes.h:1696
Node * joinCondition
Definition: parsenodes.h:1698
WithClause * withClause
Definition: parsenodes.h:1700
InferClause * infer
Definition: parsenodes.h:1492
SelectStmt * val
Definition: parsenodes.h:1835
List * indirection
Definition: parsenodes.h:1833
Alias * alias
Definition: parsenodes.h:609
List * coldeflist
Definition: parsenodes.h:610
List * functions
Definition: parsenodes.h:608
Node * subquery
Definition: parsenodes.h:584
Alias * alias
Definition: parsenodes.h:585
List * namespaces
Definition: parsenodes.h:623
Node * docexpr
Definition: parsenodes.h:621
Node * rowexpr
Definition: parsenodes.h:622
List * columns
Definition: parsenodes.h:624
Alias * alias
Definition: parsenodes.h:625
Node * val
Definition: parsenodes.h:484
List * indirection
Definition: parsenodes.h:483
List * sortClause
Definition: parsenodes.h:1756
List * targetList
Definition: parsenodes.h:1734
IntoClause * intoClause
Definition: parsenodes.h:1733
Node * limitOffset
Definition: parsenodes.h:1757
List * fromClause
Definition: parsenodes.h:1735
List * groupClause
Definition: parsenodes.h:1737
Node * havingClause
Definition: parsenodes.h:1739
List * lockingClause
Definition: parsenodes.h:1760
Node * limitCount
Definition: parsenodes.h:1758
List * windowClause
Definition: parsenodes.h:1740
List * distinctClause
Definition: parsenodes.h:1731
List * valuesLists
Definition: parsenodes.h:1750
struct SelectStmt * larg
Definition: parsenodes.h:1768
struct SelectStmt * rarg
Definition: parsenodes.h:1769
Node * whereClause
Definition: parsenodes.h:1736
WithClause * withClause
Definition: parsenodes.h:1761
List * arrayBounds
Definition: parsenodes.h:239
List * typmods
Definition: parsenodes.h:237
List * targetList
Definition: parsenodes.h:1682
List * returningList
Definition: parsenodes.h:1685
List * fromClause
Definition: parsenodes.h:1684
Node * whereClause
Definition: parsenodes.h:1683
RangeVar * relation
Definition: parsenodes.h:1681
WithClause * withClause
Definition: parsenodes.h:1686
List * orderClause
Definition: parsenodes.h:532
List * partitionClause
Definition: parsenodes.h:531
Node * startOffset
Definition: parsenodes.h:534
Node * endOffset
Definition: parsenodes.h:535
TypeName * typeName
Definition: parsenodes.h:809
Node * expr
Definition: parsenodes.h:808

References FuncCall::agg_filter, FuncCall::agg_order, RangeSubselect::alias, RangeFunction::alias, RangeTableFunc::alias, JoinExpr::alias, arg, TypeCast::arg, A_Indirection::arg, CaseExpr::arg, generate_unaccent_rules::args, FuncCall::args, RangeTableSample::args, BoolExpr::args, CaseExpr::args, XmlExpr::args, TypeName::arrayBounds, check_stack_depth(), RangeTableFuncCol::coldefexpr, RangeFunction::coldeflist, RangeTableFuncCol::colexpr, ColumnDef::collClause, InsertStmt::cols, RangeTableFunc::columns, ColumnDef::compression, MergeWhenClause::condition, CaseExpr::defresult, SelectStmt::distinctClause, RangeTableFunc::docexpr, elog(), WindowDef::endOffset, ERROR, IndexElem::expr, XmlSerialize::expr, UpdateStmt::fromClause, SelectStmt::fromClause, RangeFunction::functions, SelectStmt::groupClause, SelectStmt::havingClause, InferClause::indexElems, A_Indirection::indirection, ResTarget::indirection, PLAssignStmt::indirection, OnConflictClause::infer, SelectStmt::intoClause, MergeStmt::joinCondition, SelectStmt::larg, JoinExpr::larg, A_Expr::lexpr, lfirst, lfirst_node, A_Indices::lidx, SelectStmt::limitCount, SelectStmt::limitOffset, SelectStmt::lockingClause, MergeStmt::mergeWhenClauses, XmlExpr::named_args, RangeTableFunc::namespaces, nodeTag, InsertStmt::onConflictClause, WindowDef::orderClause, FuncCall::over, WindowDef::partitionClause, JoinExpr::quals, SelectStmt::rarg, JoinExpr::rarg, ColumnDef::raw_default, IntoClause::rel, RangeTableSample::relation, InsertStmt::relation, DeleteStmt::relation, UpdateStmt::relation, MergeStmt::relation, RangeTableSample::repeatable, InsertStmt::returningList, DeleteStmt::returningList, UpdateStmt::returningList, A_Expr::rexpr, RangeTableFunc::rowexpr, InsertStmt::selectStmt, SelectStmt::sortClause, source, MergeStmt::sourceRelation, WindowDef::startOffset, RangeSubselect::subquery, SubLink::subselect, OnConflictClause::targetList, MergeWhenClause::targetList, UpdateStmt::targetList, SelectStmt::targetList, SubLink::testexpr, TypeCast::typeName, ColumnDef::typeName, XmlSerialize::typeName, TypeName::typmods, A_Indices::uidx, DeleteStmt::usingClause, ResTarget::val, PLAssignStmt::val, MergeWhenClause::values, SelectStmt::valuesLists, IntoClause::viewQuery, WALK, InferClause::whereClause, OnConflictClause::whereClause, DeleteStmt::whereClause, UpdateStmt::whereClause, SelectStmt::whereClause, SelectStmt::windowClause, InsertStmt::withClause, DeleteStmt::withClause, UpdateStmt::withClause, MergeStmt::withClause, and SelectStmt::withClause.

◆ relabel_to_typmod()

Node* relabel_to_typmod ( Node expr,
int32  typmod 
)

Definition at line 632 of file nodeFuncs.c.

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

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

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

◆ set_opfuncid()

◆ set_sa_opfuncid()

void set_sa_opfuncid ( ScalarArrayOpExpr opexpr)

Definition at line 1683 of file nodeFuncs.c.

1684 {
1685  if (opexpr->opfuncid == InvalidOid)
1686  opexpr->opfuncid = get_opcode(opexpr->opno);
1687 }

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

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

◆ strip_implicit_coercions()

Node* strip_implicit_coercions ( Node node)

Definition at line 648 of file nodeFuncs.c.

649 {
650  if (node == NULL)
651  return NULL;
652  if (IsA(node, FuncExpr))
653  {
654  FuncExpr *f = (FuncExpr *) node;
655 
658  }
659  else if (IsA(node, RelabelType))
660  {
661  RelabelType *r = (RelabelType *) node;
662 
664  return strip_implicit_coercions((Node *) r->arg);
665  }
666  else if (IsA(node, CoerceViaIO))
667  {
668  CoerceViaIO *c = (CoerceViaIO *) node;
669 
670  if (c->coerceformat == COERCE_IMPLICIT_CAST)
671  return strip_implicit_coercions((Node *) c->arg);
672  }
673  else if (IsA(node, ArrayCoerceExpr))
674  {
675  ArrayCoerceExpr *c = (ArrayCoerceExpr *) node;
676 
677  if (c->coerceformat == COERCE_IMPLICIT_CAST)
678  return strip_implicit_coercions((Node *) c->arg);
679  }
680  else if (IsA(node, ConvertRowtypeExpr))
681  {
683 
684  if (c->convertformat == COERCE_IMPLICIT_CAST)
685  return strip_implicit_coercions((Node *) c->arg);
686  }
687  else if (IsA(node, CoerceToDomain))
688  {
689  CoerceToDomain *c = (CoerceToDomain *) node;
690 
691  if (c->coercionformat == COERCE_IMPLICIT_CAST)
692  return strip_implicit_coercions((Node *) c->arg);
693  }
694  return node;
695 }
Node * strip_implicit_coercions(Node *node)
Definition: nodeFuncs.c:648
char * c

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

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