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

Go to the source code of this file.

Macros

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

Functions

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

Macro Definition Documentation

◆ CHECKFLATCOPY

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

Referenced by range_table_mutator().

◆ FLATCOPY

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

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

◆ MUTATE

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

Function Documentation

◆ check_functions_in_node()

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

Definition at line 1656 of file nodeFuncs.c.

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

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

1658 {
1659  switch (nodeTag(node))
1660  {
1661  case T_Aggref:
1662  {
1663  Aggref *expr = (Aggref *) node;
1664 
1665  if (checker(expr->aggfnoid, context))
1666  return true;
1667  }
1668  break;
1669  case T_WindowFunc:
1670  {
1671  WindowFunc *expr = (WindowFunc *) node;
1672 
1673  if (checker(expr->winfnoid, context))
1674  return true;
1675  }
1676  break;
1677  case T_FuncExpr:
1678  {
1679  FuncExpr *expr = (FuncExpr *) node;
1680 
1681  if (checker(expr->funcid, context))
1682  return true;
1683  }
1684  break;
1685  case T_OpExpr:
1686  case T_DistinctExpr: /* struct-equivalent to OpExpr */
1687  case T_NullIfExpr: /* struct-equivalent to OpExpr */
1688  {
1689  OpExpr *expr = (OpExpr *) node;
1690 
1691  /* Set opfuncid if it wasn't set already */
1692  set_opfuncid(expr);
1693  if (checker(expr->opfuncid, context))
1694  return true;
1695  }
1696  break;
1697  case T_ScalarArrayOpExpr:
1698  {
1699  ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
1700 
1701  set_sa_opfuncid(expr);
1702  if (checker(expr->opfuncid, context))
1703  return true;
1704  }
1705  break;
1706  case T_CoerceViaIO:
1707  {
1708  CoerceViaIO *expr = (CoerceViaIO *) node;
1709  Oid iofunc;
1710  Oid typioparam;
1711  bool typisvarlena;
1712 
1713  /* check the result type's input function */
1715  &iofunc, &typioparam);
1716  if (checker(iofunc, context))
1717  return true;
1718  /* check the input type's output function */
1719  getTypeOutputInfo(exprType((Node *) expr->arg),
1720  &iofunc, &typisvarlena);
1721  if (checker(iofunc, context))
1722  return true;
1723  }
1724  break;
1725  case T_RowCompareExpr:
1726  {
1727  RowCompareExpr *rcexpr = (RowCompareExpr *) node;
1728  ListCell *opid;
1729 
1730  foreach(opid, rcexpr->opnos)
1731  {
1732  Oid opfuncid = get_opcode(lfirst_oid(opid));
1733 
1734  if (checker(opfuncid, context))
1735  return true;
1736  }
1737  }
1738  break;
1739  default:
1740  break;
1741  }
1742  return false;
1743 }
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2674
Oid resulttype
Definition: primnodes.h:821
Definition: nodes.h:525
unsigned int Oid
Definition: postgres_ext.h:31
Oid funcid
Definition: primnodes.h:455
Oid winfnoid
Definition: primnodes.h:359
Expr * arg
Definition: primnodes.h:820
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
Definition: lsyscache.c:2641
Oid opfuncid
Definition: primnodes.h:503
RegProcedure get_opcode(Oid opno)
Definition: lsyscache.c:1092
Oid aggfnoid
Definition: primnodes.h:298
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:41
#define nodeTag(nodeptr)
Definition: nodes.h:530
void set_opfuncid(OpExpr *opexpr)
Definition: nodeFuncs.c:1618
void set_sa_opfuncid(ScalarArrayOpExpr *opexpr)
Definition: nodeFuncs.c:1629
#define lfirst_oid(lc)
Definition: pg_list.h:192

◆ exprCollation()

Oid exprCollation ( const Node expr)

Definition at line 719 of file nodeFuncs.c.

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

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

720 {
721  Oid coll;
722 
723  if (!expr)
724  return InvalidOid;
725 
726  switch (nodeTag(expr))
727  {
728  case T_Var:
729  coll = ((const Var *) expr)->varcollid;
730  break;
731  case T_Const:
732  coll = ((const Const *) expr)->constcollid;
733  break;
734  case T_Param:
735  coll = ((const Param *) expr)->paramcollid;
736  break;
737  case T_Aggref:
738  coll = ((const Aggref *) expr)->aggcollid;
739  break;
740  case T_GroupingFunc:
741  coll = InvalidOid;
742  break;
743  case T_WindowFunc:
744  coll = ((const WindowFunc *) expr)->wincollid;
745  break;
746  case T_SubscriptingRef:
747  coll = ((const SubscriptingRef *) expr)->refcollid;
748  break;
749  case T_FuncExpr:
750  coll = ((const FuncExpr *) expr)->funccollid;
751  break;
752  case T_NamedArgExpr:
753  coll = exprCollation((Node *) ((const NamedArgExpr *) expr)->arg);
754  break;
755  case T_OpExpr:
756  coll = ((const OpExpr *) expr)->opcollid;
757  break;
758  case T_DistinctExpr:
759  coll = ((const DistinctExpr *) expr)->opcollid;
760  break;
761  case T_NullIfExpr:
762  coll = ((const NullIfExpr *) expr)->opcollid;
763  break;
764  case T_ScalarArrayOpExpr:
765  coll = InvalidOid; /* result is always boolean */
766  break;
767  case T_BoolExpr:
768  coll = InvalidOid; /* result is always boolean */
769  break;
770  case T_SubLink:
771  {
772  const SubLink *sublink = (const SubLink *) expr;
773 
774  if (sublink->subLinkType == EXPR_SUBLINK ||
775  sublink->subLinkType == ARRAY_SUBLINK)
776  {
777  /* get the collation of subselect's first target column */
778  Query *qtree = (Query *) sublink->subselect;
779  TargetEntry *tent;
780 
781  if (!qtree || !IsA(qtree, Query))
782  elog(ERROR, "cannot get collation for untransformed sublink");
783  tent = linitial_node(TargetEntry, qtree->targetList);
784  Assert(!tent->resjunk);
785  coll = exprCollation((Node *) tent->expr);
786  /* collation doesn't change if it's converted to array */
787  }
788  else
789  {
790  /* otherwise, result is RECORD or BOOLEAN */
791  coll = InvalidOid;
792  }
793  }
794  break;
795  case T_SubPlan:
796  {
797  const SubPlan *subplan = (const SubPlan *) expr;
798 
799  if (subplan->subLinkType == EXPR_SUBLINK ||
800  subplan->subLinkType == ARRAY_SUBLINK)
801  {
802  /* get the collation of subselect's first target column */
803  coll = subplan->firstColCollation;
804  /* collation doesn't change if it's converted to array */
805  }
806  else
807  {
808  /* otherwise, result is RECORD or BOOLEAN */
809  coll = InvalidOid;
810  }
811  }
812  break;
814  {
815  const AlternativeSubPlan *asplan = (const AlternativeSubPlan *) expr;
816 
817  /* subplans should all return the same thing */
818  coll = exprCollation((Node *) linitial(asplan->subplans));
819  }
820  break;
821  case T_FieldSelect:
822  coll = ((const FieldSelect *) expr)->resultcollid;
823  break;
824  case T_FieldStore:
825  coll = InvalidOid; /* result is always composite */
826  break;
827  case T_RelabelType:
828  coll = ((const RelabelType *) expr)->resultcollid;
829  break;
830  case T_CoerceViaIO:
831  coll = ((const CoerceViaIO *) expr)->resultcollid;
832  break;
833  case T_ArrayCoerceExpr:
834  coll = ((const ArrayCoerceExpr *) expr)->resultcollid;
835  break;
837  coll = InvalidOid; /* result is always composite */
838  break;
839  case T_CollateExpr:
840  coll = ((const CollateExpr *) expr)->collOid;
841  break;
842  case T_CaseExpr:
843  coll = ((const CaseExpr *) expr)->casecollid;
844  break;
845  case T_CaseTestExpr:
846  coll = ((const CaseTestExpr *) expr)->collation;
847  break;
848  case T_ArrayExpr:
849  coll = ((const ArrayExpr *) expr)->array_collid;
850  break;
851  case T_RowExpr:
852  coll = InvalidOid; /* result is always composite */
853  break;
854  case T_RowCompareExpr:
855  coll = InvalidOid; /* result is always boolean */
856  break;
857  case T_CoalesceExpr:
858  coll = ((const CoalesceExpr *) expr)->coalescecollid;
859  break;
860  case T_MinMaxExpr:
861  coll = ((const MinMaxExpr *) expr)->minmaxcollid;
862  break;
863  case T_SQLValueFunction:
864  /* Returns either NAME or a non-collatable type */
865  if (((const SQLValueFunction *) expr)->type == NAMEOID)
866  coll = C_COLLATION_OID;
867  else
868  coll = InvalidOid;
869  break;
870  case T_XmlExpr:
871 
872  /*
873  * XMLSERIALIZE returns text from non-collatable inputs, so its
874  * collation is always default. The other cases return boolean or
875  * XML, which are non-collatable.
876  */
877  if (((const XmlExpr *) expr)->op == IS_XMLSERIALIZE)
878  coll = DEFAULT_COLLATION_OID;
879  else
880  coll = InvalidOid;
881  break;
882  case T_NullTest:
883  coll = InvalidOid; /* result is always boolean */
884  break;
885  case T_BooleanTest:
886  coll = InvalidOid; /* result is always boolean */
887  break;
888  case T_CoerceToDomain:
889  coll = ((const CoerceToDomain *) expr)->resultcollid;
890  break;
892  coll = ((const CoerceToDomainValue *) expr)->collation;
893  break;
894  case T_SetToDefault:
895  coll = ((const SetToDefault *) expr)->collation;
896  break;
897  case T_CurrentOfExpr:
898  coll = InvalidOid; /* result is always boolean */
899  break;
900  case T_NextValueExpr:
901  coll = InvalidOid; /* result is always an integer type */
902  break;
903  case T_InferenceElem:
904  coll = exprCollation((Node *) ((const InferenceElem *) expr)->expr);
905  break;
906  case T_PlaceHolderVar:
907  coll = exprCollation((Node *) ((const PlaceHolderVar *) expr)->phexpr);
908  break;
909  default:
910  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
911  coll = InvalidOid; /* keep compiler quiet */
912  break;
913  }
914  return coll;
915 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:576
SubLinkType subLinkType
Definition: primnodes.h:690
Definition: nodes.h:525
unsigned int Oid
Definition: postgres_ext.h:31
Definition: primnodes.h:167
#define linitial_node(type, l)
Definition: pg_list.h:198
List * targetList
Definition: parsenodes.h:140
#define linitial(l)
Definition: pg_list.h:195
#define ERROR
Definition: elog.h:43
Definition: nodes.h:152
Definition: nodes.h:151
#define InvalidOid
Definition: postgres_ext.h:36
#define Assert(condition)
Definition: c.h:739
Oid exprCollation(const Node *expr)
Definition: nodeFuncs.c:719
#define nodeTag(nodeptr)
Definition: nodes.h:530
#define elog(elevel,...)
Definition: elog.h:228
void * arg
Oid firstColCollation
Definition: primnodes.h:701
Definition: nodes.h:153

◆ expression_returns_set()

bool expression_returns_set ( Node clause)

◆ expression_returns_set_walker()

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

Definition at line 675 of file nodeFuncs.c.

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

Referenced by expression_returns_set().

676 {
677  if (node == NULL)
678  return false;
679  if (IsA(node, FuncExpr))
680  {
681  FuncExpr *expr = (FuncExpr *) node;
682 
683  if (expr->funcretset)
684  return true;
685  /* else fall through to check args */
686  }
687  if (IsA(node, OpExpr))
688  {
689  OpExpr *expr = (OpExpr *) node;
690 
691  if (expr->opretset)
692  return true;
693  /* else fall through to check args */
694  }
695 
696  /* Avoid recursion for some cases that parser checks not to return a set */
697  if (IsA(node, Aggref))
698  return false;
699  if (IsA(node, WindowFunc))
700  return false;
701 
703  context);
704 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:576
static bool expression_returns_set_walker(Node *node, void *context)
Definition: nodeFuncs.c:675
bool funcretset
Definition: primnodes.h:457
bool expression_tree_walker(Node *node, bool(*walker)(), void *context)
Definition: nodeFuncs.c:1839
bool opretset
Definition: primnodes.h:505

◆ expression_tree_mutator()

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

Definition at line 2501 of file nodeFuncs.c.

References Aggref::aggargtypes, Aggref::aggdirectargs, Aggref::aggdistinct, Aggref::aggfilter, WindowFunc::aggfilter, Aggref::aggorder, OnConflictExpr::arbiterElems, OnConflictExpr::arbiterWhere, NamedArgExpr::arg, FieldSelect::arg, FieldStore::arg, RelabelType::arg, CoerceViaIO::arg, ArrayCoerceExpr::arg, ConvertRowtypeExpr::arg, CollateExpr::arg, CaseExpr::arg, NullTest::arg, BooleanTest::arg, CoerceToDomain::arg, Aggref::args, GroupingFunc::args, WindowFunc::args, FuncExpr::args, OpExpr::args, ScalarArrayOpExpr::args, BoolExpr::args, SubPlan::args, CaseExpr::args, RowExpr::args, CoalesceExpr::args, MinMaxExpr::args, TableSampleClause::args, XmlExpr::args, check_stack_depth(), TableFunc::coldefexprs, TableFunc::colexprs, GroupingFunc::cols, copyObject, CommonTableExpr::ctequery, CaseExpr::defresult, TableFunc::docexpr, ArrayExpr::elements, ArrayCoerceExpr::elemexpr, elog, WindowClause::endOffset, ERROR, OnConflictExpr::exclRelTlist, CaseWhen::expr, InferenceElem::expr, TargetEntry::expr, PartitionPruneStepOp::exprs, FieldStore::fieldnums, FLATCOPY, FromExpr::fromlist, RangeTblFunction::funcexpr, IndexClause::indexquals, lappend(), JoinExpr::larg, SetOperationStmt::larg, RowCompareExpr::largs, lfirst, list_copy(), MUTATE, XmlExpr::named_args, FieldStore::newvals, NIL, nodeTag, TableFunc::ns_uris, OnConflictExpr::onConflictSet, OnConflictExpr::onConflictWhere, WindowClause::orderClause, WindowClause::partitionClause, PlaceHolderInfo::ph_var, PlaceHolderVar::phexpr, WithCheckOption::qual, JoinExpr::quals, FromExpr::quals, JoinExpr::rarg, SetOperationStmt::rarg, RowCompareExpr::rargs, SubscriptingRef::refassgnexpr, SubscriptingRef::refexpr, SubscriptingRef::reflowerindexpr, GroupingFunc::refs, SubscriptingRef::refupperindexpr, TableSampleClause::repeatable, CaseWhen::result, IndexClause::rinfo, TableFunc::rowexpr, WindowClause::startOffset, AlternativeSubPlan::subplans, SubLink::subselect, T_Aggref, T_AlternativeSubPlan, T_AppendRelInfo, T_ArrayCoerceExpr, T_ArrayExpr, T_BooleanTest, T_BoolExpr, T_CaseExpr, T_CaseTestExpr, T_CaseWhen, T_CoalesceExpr, T_CoerceToDomain, T_CoerceToDomainValue, T_CoerceViaIO, T_CollateExpr, T_CommonTableExpr, T_Const, T_ConvertRowtypeExpr, T_CurrentOfExpr, T_DistinctExpr, T_FieldSelect, T_FieldStore, T_FromExpr, T_FuncExpr, T_GroupingFunc, T_IndexClause, T_InferenceElem, T_JoinExpr, T_List, T_MinMaxExpr, T_NamedArgExpr, T_NextValueExpr, T_NullIfExpr, T_NullTest, T_OnConflictExpr, T_OpExpr, T_Param, T_PartitionPruneStepCombine, T_PartitionPruneStepOp, T_PlaceHolderInfo, T_PlaceHolderVar, T_Query, T_RangeTblFunction, T_RangeTblRef, T_RelabelType, T_RowCompareExpr, T_RowExpr, T_ScalarArrayOpExpr, T_SetOperationStmt, T_SetToDefault, T_SortGroupClause, T_SQLValueFunction, T_SubLink, T_SubPlan, T_SubscriptingRef, T_TableFunc, T_TableSampleClause, T_TargetEntry, T_Var, T_WindowClause, T_WindowFunc, T_WithCheckOption, T_XmlExpr, SubLink::testexpr, SubPlan::testexpr, and AppendRelInfo::translated_vars.

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

2504 {
2505  /*
2506  * The mutator has already decided not to modify the current node, but we
2507  * must call the mutator for any sub-nodes.
2508  */
2509 
2510 #define FLATCOPY(newnode, node, nodetype) \
2511  ( (newnode) = (nodetype *) palloc(sizeof(nodetype)), \
2512  memcpy((newnode), (node), sizeof(nodetype)) )
2513 
2514 #define CHECKFLATCOPY(newnode, node, nodetype) \
2515  ( AssertMacro(IsA((node), nodetype)), \
2516  (newnode) = (nodetype *) palloc(sizeof(nodetype)), \
2517  memcpy((newnode), (node), sizeof(nodetype)) )
2518 
2519 #define MUTATE(newfield, oldfield, fieldtype) \
2520  ( (newfield) = (fieldtype) mutator((Node *) (oldfield), context) )
2521 
2522  if (node == NULL)
2523  return NULL;
2524 
2525  /* Guard against stack overflow due to overly complex expressions */
2527 
2528  switch (nodeTag(node))
2529  {
2530  /*
2531  * Primitive node types with no expression subnodes. Var and
2532  * Const are frequent enough to deserve special cases, the others
2533  * we just use copyObject for.
2534  */
2535  case T_Var:
2536  {
2537  Var *var = (Var *) node;
2538  Var *newnode;
2539 
2540  FLATCOPY(newnode, var, Var);
2541  return (Node *) newnode;
2542  }
2543  break;
2544  case T_Const:
2545  {
2546  Const *oldnode = (Const *) node;
2547  Const *newnode;
2548 
2549  FLATCOPY(newnode, oldnode, Const);
2550  /* XXX we don't bother with datumCopy; should we? */
2551  return (Node *) newnode;
2552  }
2553  break;
2554  case T_Param:
2555  case T_CaseTestExpr:
2556  case T_SQLValueFunction:
2557  case T_CoerceToDomainValue:
2558  case T_SetToDefault:
2559  case T_CurrentOfExpr:
2560  case T_NextValueExpr:
2561  case T_RangeTblRef:
2562  case T_SortGroupClause:
2563  return (Node *) copyObject(node);
2564  case T_WithCheckOption:
2565  {
2566  WithCheckOption *wco = (WithCheckOption *) node;
2567  WithCheckOption *newnode;
2568 
2569  FLATCOPY(newnode, wco, WithCheckOption);
2570  MUTATE(newnode->qual, wco->qual, Node *);
2571  return (Node *) newnode;
2572  }
2573  case T_Aggref:
2574  {
2575  Aggref *aggref = (Aggref *) node;
2576  Aggref *newnode;
2577 
2578  FLATCOPY(newnode, aggref, Aggref);
2579  /* assume mutation doesn't change types of arguments */
2580  newnode->aggargtypes = list_copy(aggref->aggargtypes);
2581  MUTATE(newnode->aggdirectargs, aggref->aggdirectargs, List *);
2582  MUTATE(newnode->args, aggref->args, List *);
2583  MUTATE(newnode->aggorder, aggref->aggorder, List *);
2584  MUTATE(newnode->aggdistinct, aggref->aggdistinct, List *);
2585  MUTATE(newnode->aggfilter, aggref->aggfilter, Expr *);
2586  return (Node *) newnode;
2587  }
2588  break;
2589  case T_GroupingFunc:
2590  {
2591  GroupingFunc *grouping = (GroupingFunc *) node;
2592  GroupingFunc *newnode;
2593 
2594  FLATCOPY(newnode, grouping, GroupingFunc);
2595  MUTATE(newnode->args, grouping->args, List *);
2596 
2597  /*
2598  * We assume here that mutating the arguments does not change
2599  * the semantics, i.e. that the arguments are not mutated in a
2600  * way that makes them semantically different from their
2601  * previously matching expressions in the GROUP BY clause.
2602  *
2603  * If a mutator somehow wanted to do this, it would have to
2604  * handle the refs and cols lists itself as appropriate.
2605  */
2606  newnode->refs = list_copy(grouping->refs);
2607  newnode->cols = list_copy(grouping->cols);
2608 
2609  return (Node *) newnode;
2610  }
2611  break;
2612  case T_WindowFunc:
2613  {
2614  WindowFunc *wfunc = (WindowFunc *) node;
2615  WindowFunc *newnode;
2616 
2617  FLATCOPY(newnode, wfunc, WindowFunc);
2618  MUTATE(newnode->args, wfunc->args, List *);
2619  MUTATE(newnode->aggfilter, wfunc->aggfilter, Expr *);
2620  return (Node *) newnode;
2621  }
2622  break;
2623  case T_SubscriptingRef:
2624  {
2625  SubscriptingRef *sbsref = (SubscriptingRef *) node;
2626  SubscriptingRef *newnode;
2627 
2628  FLATCOPY(newnode, sbsref, SubscriptingRef);
2629  MUTATE(newnode->refupperindexpr, sbsref->refupperindexpr,
2630  List *);
2631  MUTATE(newnode->reflowerindexpr, sbsref->reflowerindexpr,
2632  List *);
2633  MUTATE(newnode->refexpr, sbsref->refexpr,
2634  Expr *);
2635  MUTATE(newnode->refassgnexpr, sbsref->refassgnexpr,
2636  Expr *);
2637 
2638  return (Node *) newnode;
2639  }
2640  break;
2641  case T_FuncExpr:
2642  {
2643  FuncExpr *expr = (FuncExpr *) node;
2644  FuncExpr *newnode;
2645 
2646  FLATCOPY(newnode, expr, FuncExpr);
2647  MUTATE(newnode->args, expr->args, List *);
2648  return (Node *) newnode;
2649  }
2650  break;
2651  case T_NamedArgExpr:
2652  {
2653  NamedArgExpr *nexpr = (NamedArgExpr *) node;
2654  NamedArgExpr *newnode;
2655 
2656  FLATCOPY(newnode, nexpr, NamedArgExpr);
2657  MUTATE(newnode->arg, nexpr->arg, Expr *);
2658  return (Node *) newnode;
2659  }
2660  break;
2661  case T_OpExpr:
2662  {
2663  OpExpr *expr = (OpExpr *) node;
2664  OpExpr *newnode;
2665 
2666  FLATCOPY(newnode, expr, OpExpr);
2667  MUTATE(newnode->args, expr->args, List *);
2668  return (Node *) newnode;
2669  }
2670  break;
2671  case T_DistinctExpr:
2672  {
2673  DistinctExpr *expr = (DistinctExpr *) node;
2674  DistinctExpr *newnode;
2675 
2676  FLATCOPY(newnode, expr, DistinctExpr);
2677  MUTATE(newnode->args, expr->args, List *);
2678  return (Node *) newnode;
2679  }
2680  break;
2681  case T_NullIfExpr:
2682  {
2683  NullIfExpr *expr = (NullIfExpr *) node;
2684  NullIfExpr *newnode;
2685 
2686  FLATCOPY(newnode, expr, NullIfExpr);
2687  MUTATE(newnode->args, expr->args, List *);
2688  return (Node *) newnode;
2689  }
2690  break;
2691  case T_ScalarArrayOpExpr:
2692  {
2693  ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
2694  ScalarArrayOpExpr *newnode;
2695 
2696  FLATCOPY(newnode, expr, ScalarArrayOpExpr);
2697  MUTATE(newnode->args, expr->args, List *);
2698  return (Node *) newnode;
2699  }
2700  break;
2701  case T_BoolExpr:
2702  {
2703  BoolExpr *expr = (BoolExpr *) node;
2704  BoolExpr *newnode;
2705 
2706  FLATCOPY(newnode, expr, BoolExpr);
2707  MUTATE(newnode->args, expr->args, List *);
2708  return (Node *) newnode;
2709  }
2710  break;
2711  case T_SubLink:
2712  {
2713  SubLink *sublink = (SubLink *) node;
2714  SubLink *newnode;
2715 
2716  FLATCOPY(newnode, sublink, SubLink);
2717  MUTATE(newnode->testexpr, sublink->testexpr, Node *);
2718 
2719  /*
2720  * Also invoke the mutator on the sublink's Query node, so it
2721  * can recurse into the sub-query if it wants to.
2722  */
2723  MUTATE(newnode->subselect, sublink->subselect, Node *);
2724  return (Node *) newnode;
2725  }
2726  break;
2727  case T_SubPlan:
2728  {
2729  SubPlan *subplan = (SubPlan *) node;
2730  SubPlan *newnode;
2731 
2732  FLATCOPY(newnode, subplan, SubPlan);
2733  /* transform testexpr */
2734  MUTATE(newnode->testexpr, subplan->testexpr, Node *);
2735  /* transform args list (params to be passed to subplan) */
2736  MUTATE(newnode->args, subplan->args, List *);
2737  /* but not the sub-Plan itself, which is referenced as-is */
2738  return (Node *) newnode;
2739  }
2740  break;
2741  case T_AlternativeSubPlan:
2742  {
2743  AlternativeSubPlan *asplan = (AlternativeSubPlan *) node;
2744  AlternativeSubPlan *newnode;
2745 
2746  FLATCOPY(newnode, asplan, AlternativeSubPlan);
2747  MUTATE(newnode->subplans, asplan->subplans, List *);
2748  return (Node *) newnode;
2749  }
2750  break;
2751  case T_FieldSelect:
2752  {
2753  FieldSelect *fselect = (FieldSelect *) node;
2754  FieldSelect *newnode;
2755 
2756  FLATCOPY(newnode, fselect, FieldSelect);
2757  MUTATE(newnode->arg, fselect->arg, Expr *);
2758  return (Node *) newnode;
2759  }
2760  break;
2761  case T_FieldStore:
2762  {
2763  FieldStore *fstore = (FieldStore *) node;
2764  FieldStore *newnode;
2765 
2766  FLATCOPY(newnode, fstore, FieldStore);
2767  MUTATE(newnode->arg, fstore->arg, Expr *);
2768  MUTATE(newnode->newvals, fstore->newvals, List *);
2769  newnode->fieldnums = list_copy(fstore->fieldnums);
2770  return (Node *) newnode;
2771  }
2772  break;
2773  case T_RelabelType:
2774  {
2775  RelabelType *relabel = (RelabelType *) node;
2776  RelabelType *newnode;
2777 
2778  FLATCOPY(newnode, relabel, RelabelType);
2779  MUTATE(newnode->arg, relabel->arg, Expr *);
2780  return (Node *) newnode;
2781  }
2782  break;
2783  case T_CoerceViaIO:
2784  {
2785  CoerceViaIO *iocoerce = (CoerceViaIO *) node;
2786  CoerceViaIO *newnode;
2787 
2788  FLATCOPY(newnode, iocoerce, CoerceViaIO);
2789  MUTATE(newnode->arg, iocoerce->arg, Expr *);
2790  return (Node *) newnode;
2791  }
2792  break;
2793  case T_ArrayCoerceExpr:
2794  {
2795  ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node;
2796  ArrayCoerceExpr *newnode;
2797 
2798  FLATCOPY(newnode, acoerce, ArrayCoerceExpr);
2799  MUTATE(newnode->arg, acoerce->arg, Expr *);
2800  MUTATE(newnode->elemexpr, acoerce->elemexpr, Expr *);
2801  return (Node *) newnode;
2802  }
2803  break;
2804  case T_ConvertRowtypeExpr:
2805  {
2806  ConvertRowtypeExpr *convexpr = (ConvertRowtypeExpr *) node;
2807  ConvertRowtypeExpr *newnode;
2808 
2809  FLATCOPY(newnode, convexpr, ConvertRowtypeExpr);
2810  MUTATE(newnode->arg, convexpr->arg, Expr *);
2811  return (Node *) newnode;
2812  }
2813  break;
2814  case T_CollateExpr:
2815  {
2816  CollateExpr *collate = (CollateExpr *) node;
2817  CollateExpr *newnode;
2818 
2819  FLATCOPY(newnode, collate, CollateExpr);
2820  MUTATE(newnode->arg, collate->arg, Expr *);
2821  return (Node *) newnode;
2822  }
2823  break;
2824  case T_CaseExpr:
2825  {
2826  CaseExpr *caseexpr = (CaseExpr *) node;
2827  CaseExpr *newnode;
2828 
2829  FLATCOPY(newnode, caseexpr, CaseExpr);
2830  MUTATE(newnode->arg, caseexpr->arg, Expr *);
2831  MUTATE(newnode->args, caseexpr->args, List *);
2832  MUTATE(newnode->defresult, caseexpr->defresult, Expr *);
2833  return (Node *) newnode;
2834  }
2835  break;
2836  case T_CaseWhen:
2837  {
2838  CaseWhen *casewhen = (CaseWhen *) node;
2839  CaseWhen *newnode;
2840 
2841  FLATCOPY(newnode, casewhen, CaseWhen);
2842  MUTATE(newnode->expr, casewhen->expr, Expr *);
2843  MUTATE(newnode->result, casewhen->result, Expr *);
2844  return (Node *) newnode;
2845  }
2846  break;
2847  case T_ArrayExpr:
2848  {
2849  ArrayExpr *arrayexpr = (ArrayExpr *) node;
2850  ArrayExpr *newnode;
2851 
2852  FLATCOPY(newnode, arrayexpr, ArrayExpr);
2853  MUTATE(newnode->elements, arrayexpr->elements, List *);
2854  return (Node *) newnode;
2855  }
2856  break;
2857  case T_RowExpr:
2858  {
2859  RowExpr *rowexpr = (RowExpr *) node;
2860  RowExpr *newnode;
2861 
2862  FLATCOPY(newnode, rowexpr, RowExpr);
2863  MUTATE(newnode->args, rowexpr->args, List *);
2864  /* Assume colnames needn't be duplicated */
2865  return (Node *) newnode;
2866  }
2867  break;
2868  case T_RowCompareExpr:
2869  {
2870  RowCompareExpr *rcexpr = (RowCompareExpr *) node;
2871  RowCompareExpr *newnode;
2872 
2873  FLATCOPY(newnode, rcexpr, RowCompareExpr);
2874  MUTATE(newnode->largs, rcexpr->largs, List *);
2875  MUTATE(newnode->rargs, rcexpr->rargs, List *);
2876  return (Node *) newnode;
2877  }
2878  break;
2879  case T_CoalesceExpr:
2880  {
2881  CoalesceExpr *coalesceexpr = (CoalesceExpr *) node;
2882  CoalesceExpr *newnode;
2883 
2884  FLATCOPY(newnode, coalesceexpr, CoalesceExpr);
2885  MUTATE(newnode->args, coalesceexpr->args, List *);
2886  return (Node *) newnode;
2887  }
2888  break;
2889  case T_MinMaxExpr:
2890  {
2891  MinMaxExpr *minmaxexpr = (MinMaxExpr *) node;
2892  MinMaxExpr *newnode;
2893 
2894  FLATCOPY(newnode, minmaxexpr, MinMaxExpr);
2895  MUTATE(newnode->args, minmaxexpr->args, List *);
2896  return (Node *) newnode;
2897  }
2898  break;
2899  case T_XmlExpr:
2900  {
2901  XmlExpr *xexpr = (XmlExpr *) node;
2902  XmlExpr *newnode;
2903 
2904  FLATCOPY(newnode, xexpr, XmlExpr);
2905  MUTATE(newnode->named_args, xexpr->named_args, List *);
2906  /* assume mutator does not care about arg_names */
2907  MUTATE(newnode->args, xexpr->args, List *);
2908  return (Node *) newnode;
2909  }
2910  break;
2911  case T_NullTest:
2912  {
2913  NullTest *ntest = (NullTest *) node;
2914  NullTest *newnode;
2915 
2916  FLATCOPY(newnode, ntest, NullTest);
2917  MUTATE(newnode->arg, ntest->arg, Expr *);
2918  return (Node *) newnode;
2919  }
2920  break;
2921  case T_BooleanTest:
2922  {
2923  BooleanTest *btest = (BooleanTest *) node;
2924  BooleanTest *newnode;
2925 
2926  FLATCOPY(newnode, btest, BooleanTest);
2927  MUTATE(newnode->arg, btest->arg, Expr *);
2928  return (Node *) newnode;
2929  }
2930  break;
2931  case T_CoerceToDomain:
2932  {
2933  CoerceToDomain *ctest = (CoerceToDomain *) node;
2934  CoerceToDomain *newnode;
2935 
2936  FLATCOPY(newnode, ctest, CoerceToDomain);
2937  MUTATE(newnode->arg, ctest->arg, Expr *);
2938  return (Node *) newnode;
2939  }
2940  break;
2941  case T_TargetEntry:
2942  {
2943  TargetEntry *targetentry = (TargetEntry *) node;
2944  TargetEntry *newnode;
2945 
2946  FLATCOPY(newnode, targetentry, TargetEntry);
2947  MUTATE(newnode->expr, targetentry->expr, Expr *);
2948  return (Node *) newnode;
2949  }
2950  break;
2951  case T_Query:
2952  /* Do nothing with a sub-Query, per discussion above */
2953  return node;
2954  case T_WindowClause:
2955  {
2956  WindowClause *wc = (WindowClause *) node;
2957  WindowClause *newnode;
2958 
2959  FLATCOPY(newnode, wc, WindowClause);
2960  MUTATE(newnode->partitionClause, wc->partitionClause, List *);
2961  MUTATE(newnode->orderClause, wc->orderClause, List *);
2962  MUTATE(newnode->startOffset, wc->startOffset, Node *);
2963  MUTATE(newnode->endOffset, wc->endOffset, Node *);
2964  return (Node *) newnode;
2965  }
2966  break;
2967  case T_CommonTableExpr:
2968  {
2969  CommonTableExpr *cte = (CommonTableExpr *) node;
2970  CommonTableExpr *newnode;
2971 
2972  FLATCOPY(newnode, cte, CommonTableExpr);
2973 
2974  /*
2975  * Also invoke the mutator on the CTE's Query node, so it can
2976  * recurse into the sub-query if it wants to.
2977  */
2978  MUTATE(newnode->ctequery, cte->ctequery, Node *);
2979  return (Node *) newnode;
2980  }
2981  break;
2982  case T_List:
2983  {
2984  /*
2985  * We assume the mutator isn't interested in the list nodes
2986  * per se, so just invoke it on each list element. NOTE: this
2987  * would fail badly on a list with integer elements!
2988  */
2989  List *resultlist;
2990  ListCell *temp;
2991 
2992  resultlist = NIL;
2993  foreach(temp, (List *) node)
2994  {
2995  resultlist = lappend(resultlist,
2996  mutator((Node *) lfirst(temp),
2997  context));
2998  }
2999  return (Node *) resultlist;
3000  }
3001  break;
3002  case T_FromExpr:
3003  {
3004  FromExpr *from = (FromExpr *) node;
3005  FromExpr *newnode;
3006 
3007  FLATCOPY(newnode, from, FromExpr);
3008  MUTATE(newnode->fromlist, from->fromlist, List *);
3009  MUTATE(newnode->quals, from->quals, Node *);
3010  return (Node *) newnode;
3011  }
3012  break;
3013  case T_OnConflictExpr:
3014  {
3015  OnConflictExpr *oc = (OnConflictExpr *) node;
3016  OnConflictExpr *newnode;
3017 
3018  FLATCOPY(newnode, oc, OnConflictExpr);
3019  MUTATE(newnode->arbiterElems, oc->arbiterElems, List *);
3020  MUTATE(newnode->arbiterWhere, oc->arbiterWhere, Node *);
3021  MUTATE(newnode->onConflictSet, oc->onConflictSet, List *);
3022  MUTATE(newnode->onConflictWhere, oc->onConflictWhere, Node *);
3023  MUTATE(newnode->exclRelTlist, oc->exclRelTlist, List *);
3024 
3025  return (Node *) newnode;
3026  }
3027  break;
3029  {
3030  PartitionPruneStepOp *opstep = (PartitionPruneStepOp *) node;
3031  PartitionPruneStepOp *newnode;
3032 
3033  FLATCOPY(newnode, opstep, PartitionPruneStepOp);
3034  MUTATE(newnode->exprs, opstep->exprs, List *);
3035 
3036  return (Node *) newnode;
3037  }
3038  break;
3040  /* no expression sub-nodes */
3041  return (Node *) copyObject(node);
3042  case T_JoinExpr:
3043  {
3044  JoinExpr *join = (JoinExpr *) node;
3045  JoinExpr *newnode;
3046 
3047  FLATCOPY(newnode, join, JoinExpr);
3048  MUTATE(newnode->larg, join->larg, Node *);
3049  MUTATE(newnode->rarg, join->rarg, Node *);
3050  MUTATE(newnode->quals, join->quals, Node *);
3051  /* We do not mutate alias or using by default */
3052  return (Node *) newnode;
3053  }
3054  break;
3055  case T_SetOperationStmt:
3056  {
3057  SetOperationStmt *setop = (SetOperationStmt *) node;
3058  SetOperationStmt *newnode;
3059 
3060  FLATCOPY(newnode, setop, SetOperationStmt);
3061  MUTATE(newnode->larg, setop->larg, Node *);
3062  MUTATE(newnode->rarg, setop->rarg, Node *);
3063  /* We do not mutate groupClauses by default */
3064  return (Node *) newnode;
3065  }
3066  break;
3067  case T_IndexClause:
3068  {
3069  IndexClause *iclause = (IndexClause *) node;
3070  IndexClause *newnode;
3071 
3072  FLATCOPY(newnode, iclause, IndexClause);
3073  MUTATE(newnode->rinfo, iclause->rinfo, RestrictInfo *);
3074  MUTATE(newnode->indexquals, iclause->indexquals, List *);
3075  return (Node *) newnode;
3076  }
3077  break;
3078  case T_PlaceHolderVar:
3079  {
3080  PlaceHolderVar *phv = (PlaceHolderVar *) node;
3081  PlaceHolderVar *newnode;
3082 
3083  FLATCOPY(newnode, phv, PlaceHolderVar);
3084  MUTATE(newnode->phexpr, phv->phexpr, Expr *);
3085  /* Assume we need not copy the relids bitmapset */
3086  return (Node *) newnode;
3087  }
3088  break;
3089  case T_InferenceElem:
3090  {
3091  InferenceElem *inferenceelemdexpr = (InferenceElem *) node;
3092  InferenceElem *newnode;
3093 
3094  FLATCOPY(newnode, inferenceelemdexpr, InferenceElem);
3095  MUTATE(newnode->expr, newnode->expr, Node *);
3096  return (Node *) newnode;
3097  }
3098  break;
3099  case T_AppendRelInfo:
3100  {
3101  AppendRelInfo *appinfo = (AppendRelInfo *) node;
3102  AppendRelInfo *newnode;
3103 
3104  FLATCOPY(newnode, appinfo, AppendRelInfo);
3105  MUTATE(newnode->translated_vars, appinfo->translated_vars, List *);
3106  /* Assume nothing need be done with parent_colnos[] */
3107  return (Node *) newnode;
3108  }
3109  break;
3110  case T_PlaceHolderInfo:
3111  {
3112  PlaceHolderInfo *phinfo = (PlaceHolderInfo *) node;
3113  PlaceHolderInfo *newnode;
3114 
3115  FLATCOPY(newnode, phinfo, PlaceHolderInfo);
3116  MUTATE(newnode->ph_var, phinfo->ph_var, PlaceHolderVar *);
3117  /* Assume we need not copy the relids bitmapsets */
3118  return (Node *) newnode;
3119  }
3120  break;
3121  case T_RangeTblFunction:
3122  {
3123  RangeTblFunction *rtfunc = (RangeTblFunction *) node;
3124  RangeTblFunction *newnode;
3125 
3126  FLATCOPY(newnode, rtfunc, RangeTblFunction);
3127  MUTATE(newnode->funcexpr, rtfunc->funcexpr, Node *);
3128  /* Assume we need not copy the coldef info lists */
3129  return (Node *) newnode;
3130  }
3131  break;
3132  case T_TableSampleClause:
3133  {
3134  TableSampleClause *tsc = (TableSampleClause *) node;
3135  TableSampleClause *newnode;
3136 
3137  FLATCOPY(newnode, tsc, TableSampleClause);
3138  MUTATE(newnode->args, tsc->args, List *);
3139  MUTATE(newnode->repeatable, tsc->repeatable, Expr *);
3140  return (Node *) newnode;
3141  }
3142  break;
3143  case T_TableFunc:
3144  {
3145  TableFunc *tf = (TableFunc *) node;
3146  TableFunc *newnode;
3147 
3148  FLATCOPY(newnode, tf, TableFunc);
3149  MUTATE(newnode->ns_uris, tf->ns_uris, List *);
3150  MUTATE(newnode->docexpr, tf->docexpr, Node *);
3151  MUTATE(newnode->rowexpr, tf->rowexpr, Node *);
3152  MUTATE(newnode->colexprs, tf->colexprs, List *);
3153  MUTATE(newnode->coldefexprs, tf->coldefexprs, List *);
3154  return (Node *) newnode;
3155  }
3156  break;
3157  default:
3158  elog(ERROR, "unrecognized node type: %d",
3159  (int) nodeTag(node));
3160  break;
3161  }
3162  /* can't get here, but keep compiler happy */
3163  return NULL;
3164 }
List * aggdistinct
Definition: primnodes.h:307
#define NIL
Definition: pg_list.h:65
List * args
Definition: primnodes.h:1092
List * args
Definition: primnodes.h:1008
Node * docexpr
Definition: primnodes.h:87
Expr * arg
Definition: primnodes.h:777
PlaceHolderVar * ph_var
Definition: pathnodes.h:2267
List * args
Definition: primnodes.h:345
List * refs
Definition: primnodes.h:347
List * args
Definition: primnodes.h:363
List * args
Definition: primnodes.h:463
Expr * arg
Definition: primnodes.h:800
List * list_copy(const List *oldlist)
Definition: list.c:1404
Definition: nodes.h:525
List * args
Definition: primnodes.h:305
Expr * arg
Definition: primnodes.h:748
List * fromlist
Definition: primnodes.h:1496
Definition: primnodes.h:167
List * refupperindexpr
Definition: primnodes.h:408
List * translated_vars
Definition: pathnodes.h:2217
Node * quals
Definition: primnodes.h:1497
List * arbiterElems
Definition: primnodes.h:1515
Node * larg
Definition: primnodes.h:1476
List * aggargtypes
Definition: primnodes.h:303
#define ERROR
Definition: elog.h:43
List * partitionClause
Definition: parsenodes.h:1330
List * args
Definition: primnodes.h:1072
Expr * arg
Definition: primnodes.h:1205
List * coldefexprs
Definition: primnodes.h:94
Node * rowexpr
Definition: primnodes.h:88
struct RestrictInfo * rinfo
Definition: pathnodes.h:1225
List * exclRelTlist
Definition: primnodes.h:1524
void check_stack_depth(void)
Definition: postgres.c:3302
List * aggorder
Definition: primnodes.h:306
Expr * arg
Definition: primnodes.h:1228
List * aggdirectargs
Definition: primnodes.h:304
Expr * arg
Definition: primnodes.h:820
List * elements
Definition: primnodes.h:977
Expr * elemexpr
Definition: primnodes.h:845
List * indexquals
Definition: pathnodes.h:1226
Definition: nodes.h:297
List * newvals
Definition: primnodes.h:778
List * cols
Definition: primnodes.h:348
Definition: nodes.h:152
List * lappend(List *list, void *datum)
Definition: list.c:322
Definition: nodes.h:151
Node * startOffset
Definition: parsenodes.h:1333
List * args
Definition: primnodes.h:919
Definition: nodes.h:310
Node * quals
Definition: primnodes.h:1479
#define FLATCOPY(newnode, node, nodetype)
Node * testexpr
Definition: primnodes.h:692
List * colexprs
Definition: primnodes.h:93
List * named_args
Definition: primnodes.h:1169
List * args
Definition: primnodes.h:1171
Node * rarg
Definition: primnodes.h:1477
Expr * arg
Definition: primnodes.h:484
#define lfirst(lc)
Definition: pg_list.h:190
List * ns_uris
Definition: primnodes.h:85
Expr * aggfilter
Definition: primnodes.h:364
Expr * expr
Definition: primnodes.h:1393
Node * endOffset
Definition: parsenodes.h:1334
Expr * arg
Definition: primnodes.h:886
Expr * aggfilter
Definition: primnodes.h:308
List * args
Definition: primnodes.h:569
#define nodeTag(nodeptr)
Definition: nodes.h:530
Node * arbiterWhere
Definition: primnodes.h:1517
List * orderClause
Definition: parsenodes.h:1331
Expr * refassgnexpr
Definition: primnodes.h:416
List * fieldnums
Definition: primnodes.h:779
List * reflowerindexpr
Definition: primnodes.h:410
#define elog(elevel,...)
Definition: elog.h:228
List * onConflictSet
Definition: primnodes.h:1521
Expr * refexpr
Definition: primnodes.h:413
Expr * arg
Definition: primnodes.h:918
Expr * result
Definition: primnodes.h:931
#define copyObject(obj)
Definition: nodes.h:641
List * args
Definition: primnodes.h:508
Expr * defresult
Definition: primnodes.h:920
Expr * expr
Definition: primnodes.h:930
Node * onConflictWhere
Definition: primnodes.h:1522
Definition: pg_list.h:50
#define MUTATE(newfield, oldfield, fieldtype)
Definition: nodes.h:153
List * args
Definition: primnodes.h:716

◆ expression_tree_walker()

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

Definition at line 1839 of file nodeFuncs.c.

References Aggref::aggdirectargs, Aggref::aggdistinct, Aggref::aggfilter, WindowFunc::aggfilter, Aggref::aggorder, OnConflictExpr::arbiterElems, OnConflictExpr::arbiterWhere, arg, FieldStore::arg, ArrayCoerceExpr::arg, CaseExpr::arg, generate_unaccent_rules::args, Aggref::args, GroupingFunc::args, WindowFunc::args, FuncExpr::args, OpExpr::args, ScalarArrayOpExpr::args, BoolExpr::args, SubPlan::args, CaseExpr::args, TableSampleClause::args, XmlExpr::args, check_stack_depth(), TableFunc::coldefexprs, TableFunc::colexprs, CommonTableExpr::ctequery, CaseExpr::defresult, TableFunc::docexpr, ArrayCoerceExpr::elemexpr, elog, WindowClause::endOffset, ERROR, OnConflictExpr::exclRelTlist, CaseWhen::expr, expression_tree_walker(), PartitionPruneStepOp::exprs, FromExpr::fromlist, IndexClause::indexquals, JoinExpr::larg, SetOperationStmt::larg, RowCompareExpr::largs, lfirst, lfirst_node, XmlExpr::named_args, FieldStore::newvals, nodeTag, TableFunc::ns_uris, OnConflictExpr::onConflictSet, OnConflictExpr::onConflictWhere, WindowClause::orderClause, WindowClause::partitionClause, JoinExpr::quals, FromExpr::quals, JoinExpr::rarg, SetOperationStmt::rarg, RowCompareExpr::rargs, SubscriptingRef::refassgnexpr, SubscriptingRef::refexpr, SubscriptingRef::reflowerindexpr, SubscriptingRef::refupperindexpr, TableSampleClause::repeatable, CaseWhen::result, IndexClause::rinfo, TableFunc::rowexpr, WindowClause::startOffset, SubLink::subselect, T_Aggref, T_AlternativeSubPlan, T_AppendRelInfo, T_ArrayCoerceExpr, T_ArrayExpr, T_BooleanTest, T_BoolExpr, T_CaseExpr, T_CaseTestExpr, T_CoalesceExpr, T_CoerceToDomain, T_CoerceToDomainValue, T_CoerceViaIO, T_CollateExpr, T_CommonTableExpr, T_Const, T_ConvertRowtypeExpr, T_CurrentOfExpr, T_DistinctExpr, T_FieldSelect, T_FieldStore, T_FromExpr, T_FuncExpr, T_GroupingFunc, T_IndexClause, T_InferenceElem, T_JoinExpr, T_List, T_MinMaxExpr, T_NamedArgExpr, T_NextValueExpr, T_NullIfExpr, T_NullTest, T_OnConflictExpr, T_OpExpr, T_Param, T_PartitionPruneStepCombine, T_PartitionPruneStepOp, T_PlaceHolderInfo, T_PlaceHolderVar, T_Query, T_RangeTblFunction, T_RangeTblRef, T_RelabelType, T_RowCompareExpr, T_RowExpr, T_ScalarArrayOpExpr, T_SetOperationStmt, T_SetToDefault, T_SortGroupClause, T_SQLValueFunction, T_SubLink, T_SubPlan, T_SubscriptingRef, T_TableFunc, T_TableSampleClause, T_TargetEntry, T_Var, T_WindowClause, T_WindowFunc, T_WithCheckOption, T_XmlExpr, SubLink::testexpr, SubPlan::testexpr, and AppendRelInfo::translated_vars.

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

1842 {
1843  ListCell *temp;
1844 
1845  /*
1846  * The walker has already visited the current node, and so we need only
1847  * recurse into any sub-nodes it has.
1848  *
1849  * We assume that the walker is not interested in List nodes per se, so
1850  * when we expect a List we just recurse directly to self without
1851  * bothering to call the walker.
1852  */
1853  if (node == NULL)
1854  return false;
1855 
1856  /* Guard against stack overflow due to overly complex expressions */
1858 
1859  switch (nodeTag(node))
1860  {
1861  case T_Var:
1862  case T_Const:
1863  case T_Param:
1864  case T_CaseTestExpr:
1865  case T_SQLValueFunction:
1866  case T_CoerceToDomainValue:
1867  case T_SetToDefault:
1868  case T_CurrentOfExpr:
1869  case T_NextValueExpr:
1870  case T_RangeTblRef:
1871  case T_SortGroupClause:
1872  /* primitive node types with no expression subnodes */
1873  break;
1874  case T_WithCheckOption:
1875  return walker(((WithCheckOption *) node)->qual, context);
1876  case T_Aggref:
1877  {
1878  Aggref *expr = (Aggref *) node;
1879 
1880  /* recurse directly on List */
1882  walker, context))
1883  return true;
1884  if (expression_tree_walker((Node *) expr->args,
1885  walker, context))
1886  return true;
1887  if (expression_tree_walker((Node *) expr->aggorder,
1888  walker, context))
1889  return true;
1890  if (expression_tree_walker((Node *) expr->aggdistinct,
1891  walker, context))
1892  return true;
1893  if (walker((Node *) expr->aggfilter, context))
1894  return true;
1895  }
1896  break;
1897  case T_GroupingFunc:
1898  {
1899  GroupingFunc *grouping = (GroupingFunc *) node;
1900 
1901  if (expression_tree_walker((Node *) grouping->args,
1902  walker, context))
1903  return true;
1904  }
1905  break;
1906  case T_WindowFunc:
1907  {
1908  WindowFunc *expr = (WindowFunc *) node;
1909 
1910  /* recurse directly on List */
1911  if (expression_tree_walker((Node *) expr->args,
1912  walker, context))
1913  return true;
1914  if (walker((Node *) expr->aggfilter, context))
1915  return true;
1916  }
1917  break;
1918  case T_SubscriptingRef:
1919  {
1920  SubscriptingRef *sbsref = (SubscriptingRef *) node;
1921 
1922  /* recurse directly for upper/lower container index lists */
1924  walker, context))
1925  return true;
1927  walker, context))
1928  return true;
1929  /* walker must see the refexpr and refassgnexpr, however */
1930  if (walker(sbsref->refexpr, context))
1931  return true;
1932 
1933  if (walker(sbsref->refassgnexpr, context))
1934  return true;
1935  }
1936  break;
1937  case T_FuncExpr:
1938  {
1939  FuncExpr *expr = (FuncExpr *) node;
1940 
1941  if (expression_tree_walker((Node *) expr->args,
1942  walker, context))
1943  return true;
1944  }
1945  break;
1946  case T_NamedArgExpr:
1947  return walker(((NamedArgExpr *) node)->arg, context);
1948  case T_OpExpr:
1949  case T_DistinctExpr: /* struct-equivalent to OpExpr */
1950  case T_NullIfExpr: /* struct-equivalent to OpExpr */
1951  {
1952  OpExpr *expr = (OpExpr *) node;
1953 
1954  if (expression_tree_walker((Node *) expr->args,
1955  walker, context))
1956  return true;
1957  }
1958  break;
1959  case T_ScalarArrayOpExpr:
1960  {
1961  ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
1962 
1963  if (expression_tree_walker((Node *) expr->args,
1964  walker, context))
1965  return true;
1966  }
1967  break;
1968  case T_BoolExpr:
1969  {
1970  BoolExpr *expr = (BoolExpr *) node;
1971 
1972  if (expression_tree_walker((Node *) expr->args,
1973  walker, context))
1974  return true;
1975  }
1976  break;
1977  case T_SubLink:
1978  {
1979  SubLink *sublink = (SubLink *) node;
1980 
1981  if (walker(sublink->testexpr, context))
1982  return true;
1983 
1984  /*
1985  * Also invoke the walker on the sublink's Query node, so it
1986  * can recurse into the sub-query if it wants to.
1987  */
1988  return walker(sublink->subselect, context);
1989  }
1990  break;
1991  case T_SubPlan:
1992  {
1993  SubPlan *subplan = (SubPlan *) node;
1994 
1995  /* recurse into the testexpr, but not into the Plan */
1996  if (walker(subplan->testexpr, context))
1997  return true;
1998  /* also examine args list */
1999  if (expression_tree_walker((Node *) subplan->args,
2000  walker, context))
2001  return true;
2002  }
2003  break;
2004  case T_AlternativeSubPlan:
2005  return walker(((AlternativeSubPlan *) node)->subplans, context);
2006  case T_FieldSelect:
2007  return walker(((FieldSelect *) node)->arg, context);
2008  case T_FieldStore:
2009  {
2010  FieldStore *fstore = (FieldStore *) node;
2011 
2012  if (walker(fstore->arg, context))
2013  return true;
2014  if (walker(fstore->newvals, context))
2015  return true;
2016  }
2017  break;
2018  case T_RelabelType:
2019  return walker(((RelabelType *) node)->arg, context);
2020  case T_CoerceViaIO:
2021  return walker(((CoerceViaIO *) node)->arg, context);
2022  case T_ArrayCoerceExpr:
2023  {
2024  ArrayCoerceExpr *acoerce = (ArrayCoerceExpr *) node;
2025 
2026  if (walker(acoerce->arg, context))
2027  return true;
2028  if (walker(acoerce->elemexpr, context))
2029  return true;
2030  }
2031  break;
2032  case T_ConvertRowtypeExpr:
2033  return walker(((ConvertRowtypeExpr *) node)->arg, context);
2034  case T_CollateExpr:
2035  return walker(((CollateExpr *) node)->arg, context);
2036  case T_CaseExpr:
2037  {
2038  CaseExpr *caseexpr = (CaseExpr *) node;
2039 
2040  if (walker(caseexpr->arg, context))
2041  return true;
2042  /* we assume walker doesn't care about CaseWhens, either */
2043  foreach(temp, caseexpr->args)
2044  {
2045  CaseWhen *when = lfirst_node(CaseWhen, temp);
2046 
2047  if (walker(when->expr, context))
2048  return true;
2049  if (walker(when->result, context))
2050  return true;
2051  }
2052  if (walker(caseexpr->defresult, context))
2053  return true;
2054  }
2055  break;
2056  case T_ArrayExpr:
2057  return walker(((ArrayExpr *) node)->elements, context);
2058  case T_RowExpr:
2059  /* Assume colnames isn't interesting */
2060  return walker(((RowExpr *) node)->args, context);
2061  case T_RowCompareExpr:
2062  {
2063  RowCompareExpr *rcexpr = (RowCompareExpr *) node;
2064 
2065  if (walker(rcexpr->largs, context))
2066  return true;
2067  if (walker(rcexpr->rargs, context))
2068  return true;
2069  }
2070  break;
2071  case T_CoalesceExpr:
2072  return walker(((CoalesceExpr *) node)->args, context);
2073  case T_MinMaxExpr:
2074  return walker(((MinMaxExpr *) node)->args, context);
2075  case T_XmlExpr:
2076  {
2077  XmlExpr *xexpr = (XmlExpr *) node;
2078 
2079  if (walker(xexpr->named_args, context))
2080  return true;
2081  /* we assume walker doesn't care about arg_names */
2082  if (walker(xexpr->args, context))
2083  return true;
2084  }
2085  break;
2086  case T_NullTest:
2087  return walker(((NullTest *) node)->arg, context);
2088  case T_BooleanTest:
2089  return walker(((BooleanTest *) node)->arg, context);
2090  case T_CoerceToDomain:
2091  return walker(((CoerceToDomain *) node)->arg, context);
2092  case T_TargetEntry:
2093  return walker(((TargetEntry *) node)->expr, context);
2094  case T_Query:
2095  /* Do nothing with a sub-Query, per discussion above */
2096  break;
2097  case T_WindowClause:
2098  {
2099  WindowClause *wc = (WindowClause *) node;
2100 
2101  if (walker(wc->partitionClause, context))
2102  return true;
2103  if (walker(wc->orderClause, context))
2104  return true;
2105  if (walker(wc->startOffset, context))
2106  return true;
2107  if (walker(wc->endOffset, context))
2108  return true;
2109  }
2110  break;
2111  case T_CommonTableExpr:
2112  {
2113  CommonTableExpr *cte = (CommonTableExpr *) node;
2114 
2115  /*
2116  * Invoke the walker on the CTE's Query node, so it can
2117  * recurse into the sub-query if it wants to.
2118  */
2119  return walker(cte->ctequery, context);
2120  }
2121  break;
2122  case T_List:
2123  foreach(temp, (List *) node)
2124  {
2125  if (walker((Node *) lfirst(temp), context))
2126  return true;
2127  }
2128  break;
2129  case T_FromExpr:
2130  {
2131  FromExpr *from = (FromExpr *) node;
2132 
2133  if (walker(from->fromlist, context))
2134  return true;
2135  if (walker(from->quals, context))
2136  return true;
2137  }
2138  break;
2139  case T_OnConflictExpr:
2140  {
2141  OnConflictExpr *onconflict = (OnConflictExpr *) node;
2142 
2143  if (walker((Node *) onconflict->arbiterElems, context))
2144  return true;
2145  if (walker(onconflict->arbiterWhere, context))
2146  return true;
2147  if (walker(onconflict->onConflictSet, context))
2148  return true;
2149  if (walker(onconflict->onConflictWhere, context))
2150  return true;
2151  if (walker(onconflict->exclRelTlist, context))
2152  return true;
2153  }
2154  break;
2156  {
2157  PartitionPruneStepOp *opstep = (PartitionPruneStepOp *) node;
2158 
2159  if (walker((Node *) opstep->exprs, context))
2160  return true;
2161  }
2162  break;
2164  /* no expression subnodes */
2165  break;
2166  case T_JoinExpr:
2167  {
2168  JoinExpr *join = (JoinExpr *) node;
2169 
2170  if (walker(join->larg, context))
2171  return true;
2172  if (walker(join->rarg, context))
2173  return true;
2174  if (walker(join->quals, context))
2175  return true;
2176 
2177  /*
2178  * alias clause, using list are deemed uninteresting.
2179  */
2180  }
2181  break;
2182  case T_SetOperationStmt:
2183  {
2184  SetOperationStmt *setop = (SetOperationStmt *) node;
2185 
2186  if (walker(setop->larg, context))
2187  return true;
2188  if (walker(setop->rarg, context))
2189  return true;
2190 
2191  /* groupClauses are deemed uninteresting */
2192  }
2193  break;
2194  case T_IndexClause:
2195  {
2196  IndexClause *iclause = (IndexClause *) node;
2197 
2198  if (walker(iclause->rinfo, context))
2199  return true;
2200  if (expression_tree_walker((Node *) iclause->indexquals,
2201  walker, context))
2202  return true;
2203  }
2204  break;
2205  case T_PlaceHolderVar:
2206  return walker(((PlaceHolderVar *) node)->phexpr, context);
2207  case T_InferenceElem:
2208  return walker(((InferenceElem *) node)->expr, context);
2209  case T_AppendRelInfo:
2210  {
2211  AppendRelInfo *appinfo = (AppendRelInfo *) node;
2212 
2213  if (expression_tree_walker((Node *) appinfo->translated_vars,
2214  walker, context))
2215  return true;
2216  }
2217  break;
2218  case T_PlaceHolderInfo:
2219  return walker(((PlaceHolderInfo *) node)->ph_var, context);
2220  case T_RangeTblFunction:
2221  return walker(((RangeTblFunction *) node)->funcexpr, context);
2222  case T_TableSampleClause:
2223  {
2224  TableSampleClause *tsc = (TableSampleClause *) node;
2225 
2226  if (expression_tree_walker((Node *) tsc->args,
2227  walker, context))
2228  return true;
2229  if (walker((Node *) tsc->repeatable, context))
2230  return true;
2231  }
2232  break;
2233  case T_TableFunc:
2234  {
2235  TableFunc *tf = (TableFunc *) node;
2236 
2237  if (walker(tf->ns_uris, context))
2238  return true;
2239  if (walker(tf->docexpr, context))
2240  return true;
2241  if (walker(tf->rowexpr, context))
2242  return true;
2243  if (walker(tf->colexprs, context))
2244  return true;
2245  if (walker(tf->coldefexprs, context))
2246  return true;
2247  }
2248  break;
2249  default:
2250  elog(ERROR, "unrecognized node type: %d",
2251  (int) nodeTag(node));
2252  break;
2253  }
2254  return false;
2255 }
List * aggdistinct
Definition: primnodes.h:307
Node * docexpr
Definition: primnodes.h:87
Expr * arg
Definition: primnodes.h:777
List * args
Definition: primnodes.h:345
List * args
Definition: primnodes.h:363
List * args
Definition: primnodes.h:463
Definition: nodes.h:525
List * args
Definition: primnodes.h:305
List * fromlist
Definition: primnodes.h:1496
List * refupperindexpr
Definition: primnodes.h:408
List * translated_vars
Definition: pathnodes.h:2217
Node * quals
Definition: primnodes.h:1497
List * arbiterElems
Definition: primnodes.h:1515
Node * larg
Definition: primnodes.h:1476
#define ERROR
Definition: elog.h:43
List * partitionClause
Definition: parsenodes.h:1330
List * coldefexprs
Definition: primnodes.h:94
#define lfirst_node(type, lc)
Definition: pg_list.h:193
Node * rowexpr
Definition: primnodes.h:88
struct RestrictInfo * rinfo
Definition: pathnodes.h:1225
List * exclRelTlist
Definition: primnodes.h:1524
void check_stack_depth(void)
Definition: postgres.c:3302
List * aggorder
Definition: primnodes.h:306
List * aggdirectargs
Definition: primnodes.h:304
Expr * elemexpr
Definition: primnodes.h:845
Definition: type.h:82
List * indexquals
Definition: pathnodes.h:1226
Definition: nodes.h:297
List * newvals
Definition: primnodes.h:778
Definition: nodes.h:152
Definition: nodes.h:151
Node * startOffset
Definition: parsenodes.h:1333
List * args
Definition: primnodes.h:919
Definition: nodes.h:310
Node * quals
Definition: primnodes.h:1479
Node * testexpr
Definition: primnodes.h:692
List * colexprs
Definition: primnodes.h:93
List * named_args
Definition: primnodes.h:1169
List * args
Definition: primnodes.h:1171
Node * rarg
Definition: primnodes.h:1477
#define lfirst(lc)
Definition: pg_list.h:190
List * ns_uris
Definition: primnodes.h:85
Expr * aggfilter
Definition: primnodes.h:364
Node * endOffset
Definition: parsenodes.h:1334
bool expression_tree_walker(Node *node, bool(*walker)(), void *context)
Definition: nodeFuncs.c:1839
Expr * aggfilter
Definition: primnodes.h:308
List * args
Definition: primnodes.h:569
#define nodeTag(nodeptr)
Definition: nodes.h:530
Node * arbiterWhere
Definition: primnodes.h:1517
List * orderClause
Definition: parsenodes.h:1331
Expr * refassgnexpr
Definition: primnodes.h:416
List * reflowerindexpr
Definition: primnodes.h:410
#define elog(elevel,...)
Definition: elog.h:228
List * onConflictSet
Definition: primnodes.h:1521
void * arg
Expr * refexpr
Definition: primnodes.h:413
Expr * arg
Definition: primnodes.h:918
Expr * result
Definition: primnodes.h:931
List * args
Definition: primnodes.h:508
Expr * defresult
Definition: primnodes.h:920
Expr * expr
Definition: primnodes.h:930
Node * onConflictWhere
Definition: primnodes.h:1522
Definition: pg_list.h:50
Definition: nodes.h:153
List * args
Definition: primnodes.h:716

◆ exprInputCollation()

Oid exprInputCollation ( const Node expr)

Definition at line 924 of file nodeFuncs.c.

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

Referenced by resolve_polymorphic_tupdesc().

925 {
926  Oid coll;
927 
928  if (!expr)
929  return InvalidOid;
930 
931  switch (nodeTag(expr))
932  {
933  case T_Aggref:
934  coll = ((const Aggref *) expr)->inputcollid;
935  break;
936  case T_WindowFunc:
937  coll = ((const WindowFunc *) expr)->inputcollid;
938  break;
939  case T_FuncExpr:
940  coll = ((const FuncExpr *) expr)->inputcollid;
941  break;
942  case T_OpExpr:
943  coll = ((const OpExpr *) expr)->inputcollid;
944  break;
945  case T_DistinctExpr:
946  coll = ((const DistinctExpr *) expr)->inputcollid;
947  break;
948  case T_NullIfExpr:
949  coll = ((const NullIfExpr *) expr)->inputcollid;
950  break;
951  case T_ScalarArrayOpExpr:
952  coll = ((const ScalarArrayOpExpr *) expr)->inputcollid;
953  break;
954  case T_MinMaxExpr:
955  coll = ((const MinMaxExpr *) expr)->inputcollid;
956  break;
957  default:
958  coll = InvalidOid;
959  break;
960  }
961  return coll;
962 }
unsigned int Oid
Definition: postgres_ext.h:31
#define InvalidOid
Definition: postgres_ext.h:36
#define nodeTag(nodeptr)
Definition: nodes.h:530

◆ exprIsLengthCoercion()

bool exprIsLengthCoercion ( const Node expr,
int32 coercedTypmod 
)

Definition at line 512 of file nodeFuncs.c.

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

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

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

◆ exprLocation()

int exprLocation ( const Node expr)

Definition at line 1191 of file nodeFuncs.c.

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

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

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

◆ exprSetCollation()

void exprSetCollation ( Node expr,
Oid  collation 
)

Definition at line 972 of file nodeFuncs.c.

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

Referenced by assign_collations_walker().

973 {
974  switch (nodeTag(expr))
975  {
976  case T_Var:
977  ((Var *) expr)->varcollid = collation;
978  break;
979  case T_Const:
980  ((Const *) expr)->constcollid = collation;
981  break;
982  case T_Param:
983  ((Param *) expr)->paramcollid = collation;
984  break;
985  case T_Aggref:
986  ((Aggref *) expr)->aggcollid = collation;
987  break;
988  case T_GroupingFunc:
989  Assert(!OidIsValid(collation));
990  break;
991  case T_WindowFunc:
992  ((WindowFunc *) expr)->wincollid = collation;
993  break;
994  case T_SubscriptingRef:
995  ((SubscriptingRef *) expr)->refcollid = collation;
996  break;
997  case T_FuncExpr:
998  ((FuncExpr *) expr)->funccollid = collation;
999  break;
1000  case T_NamedArgExpr:
1001  Assert(collation == exprCollation((Node *) ((NamedArgExpr *) expr)->arg));
1002  break;
1003  case T_OpExpr:
1004  ((OpExpr *) expr)->opcollid = collation;
1005  break;
1006  case T_DistinctExpr:
1007  ((DistinctExpr *) expr)->opcollid = collation;
1008  break;
1009  case T_NullIfExpr:
1010  ((NullIfExpr *) expr)->opcollid = collation;
1011  break;
1012  case T_ScalarArrayOpExpr:
1013  Assert(!OidIsValid(collation)); /* result is always boolean */
1014  break;
1015  case T_BoolExpr:
1016  Assert(!OidIsValid(collation)); /* result is always boolean */
1017  break;
1018  case T_SubLink:
1019 #ifdef USE_ASSERT_CHECKING
1020  {
1021  SubLink *sublink = (SubLink *) expr;
1022 
1023  if (sublink->subLinkType == EXPR_SUBLINK ||
1024  sublink->subLinkType == ARRAY_SUBLINK)
1025  {
1026  /* get the collation of subselect's first target column */
1027  Query *qtree = (Query *) sublink->subselect;
1028  TargetEntry *tent;
1029 
1030  if (!qtree || !IsA(qtree, Query))
1031  elog(ERROR, "cannot set collation for untransformed sublink");
1032  tent = linitial_node(TargetEntry, qtree->targetList);
1033  Assert(!tent->resjunk);
1034  Assert(collation == exprCollation((Node *) tent->expr));
1035  }
1036  else
1037  {
1038  /* otherwise, result is RECORD or BOOLEAN */
1039  Assert(!OidIsValid(collation));
1040  }
1041  }
1042 #endif /* USE_ASSERT_CHECKING */
1043  break;
1044  case T_FieldSelect:
1045  ((FieldSelect *) expr)->resultcollid = collation;
1046  break;
1047  case T_FieldStore:
1048  Assert(!OidIsValid(collation)); /* result is always composite */
1049  break;
1050  case T_RelabelType:
1051  ((RelabelType *) expr)->resultcollid = collation;
1052  break;
1053  case T_CoerceViaIO:
1054  ((CoerceViaIO *) expr)->resultcollid = collation;
1055  break;
1056  case T_ArrayCoerceExpr:
1057  ((ArrayCoerceExpr *) expr)->resultcollid = collation;
1058  break;
1059  case T_ConvertRowtypeExpr:
1060  Assert(!OidIsValid(collation)); /* result is always composite */
1061  break;
1062  case T_CaseExpr:
1063  ((CaseExpr *) expr)->casecollid = collation;
1064  break;
1065  case T_ArrayExpr:
1066  ((ArrayExpr *) expr)->array_collid = collation;
1067  break;
1068  case T_RowExpr:
1069  Assert(!OidIsValid(collation)); /* result is always composite */
1070  break;
1071  case T_RowCompareExpr:
1072  Assert(!OidIsValid(collation)); /* result is always boolean */
1073  break;
1074  case T_CoalesceExpr:
1075  ((CoalesceExpr *) expr)->coalescecollid = collation;
1076  break;
1077  case T_MinMaxExpr:
1078  ((MinMaxExpr *) expr)->minmaxcollid = collation;
1079  break;
1080  case T_SQLValueFunction:
1081  Assert((((SQLValueFunction *) expr)->type == NAMEOID) ?
1082  (collation == C_COLLATION_OID) :
1083  (collation == InvalidOid));
1084  break;
1085  case T_XmlExpr:
1086  Assert((((XmlExpr *) expr)->op == IS_XMLSERIALIZE) ?
1087  (collation == DEFAULT_COLLATION_OID) :
1088  (collation == InvalidOid));
1089  break;
1090  case T_NullTest:
1091  Assert(!OidIsValid(collation)); /* result is always boolean */
1092  break;
1093  case T_BooleanTest:
1094  Assert(!OidIsValid(collation)); /* result is always boolean */
1095  break;
1096  case T_CoerceToDomain:
1097  ((CoerceToDomain *) expr)->resultcollid = collation;
1098  break;
1099  case T_CoerceToDomainValue:
1100  ((CoerceToDomainValue *) expr)->collation = collation;
1101  break;
1102  case T_SetToDefault:
1103  ((SetToDefault *) expr)->collation = collation;
1104  break;
1105  case T_CurrentOfExpr:
1106  Assert(!OidIsValid(collation)); /* result is always boolean */
1107  break;
1108  case T_NextValueExpr:
1109  Assert(!OidIsValid(collation)); /* result is always an integer
1110  * type */
1111  break;
1112  default:
1113  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
1114  break;
1115  }
1116 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:576
Definition: nodes.h:525
Definition: primnodes.h:167
#define linitial_node(type, l)
Definition: pg_list.h:198
#define OidIsValid(objectId)
Definition: c.h:645
List * targetList
Definition: parsenodes.h:140
#define ERROR
Definition: elog.h:43
Definition: nodes.h:152
Definition: nodes.h:151
#define InvalidOid
Definition: postgres_ext.h:36
#define Assert(condition)
Definition: c.h:739
Oid exprCollation(const Node *expr)
Definition: nodeFuncs.c:719
#define nodeTag(nodeptr)
Definition: nodes.h:530
#define elog(elevel,...)
Definition: elog.h:228
void * arg
Definition: nodes.h:153

◆ exprSetInputCollation()

void exprSetInputCollation ( Node expr,
Oid  inputcollation 
)

Definition at line 1127 of file nodeFuncs.c.

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

Referenced by assign_collations_walker().

1128 {
1129  switch (nodeTag(expr))
1130  {
1131  case T_Aggref:
1132  ((Aggref *) expr)->inputcollid = inputcollation;
1133  break;
1134  case T_WindowFunc:
1135  ((WindowFunc *) expr)->inputcollid = inputcollation;
1136  break;
1137  case T_FuncExpr:
1138  ((FuncExpr *) expr)->inputcollid = inputcollation;
1139  break;
1140  case T_OpExpr:
1141  ((OpExpr *) expr)->inputcollid = inputcollation;
1142  break;
1143  case T_DistinctExpr:
1144  ((DistinctExpr *) expr)->inputcollid = inputcollation;
1145  break;
1146  case T_NullIfExpr:
1147  ((NullIfExpr *) expr)->inputcollid = inputcollation;
1148  break;
1149  case T_ScalarArrayOpExpr:
1150  ((ScalarArrayOpExpr *) expr)->inputcollid = inputcollation;
1151  break;
1152  case T_MinMaxExpr:
1153  ((MinMaxExpr *) expr)->inputcollid = inputcollation;
1154  break;
1155  default:
1156  break;
1157  }
1158 }
#define nodeTag(nodeptr)
Definition: nodes.h:530

◆ exprType()

Oid exprType ( const Node expr)

Definition at line 41 of file nodeFuncs.c.

References arg, ARRAY_SUBLINK, Assert, elog, ereport, errcode(), errmsg(), ERROR, InferenceElem::expr, EXPR_SUBLINK, exprType(), SubPlan::firstColType, format_type_be(), get_promoted_array_type(), InvalidOid, IS_DOCUMENT, IS_XMLSERIALIZE, IsA, linitial, linitial_node, MULTIEXPR_SUBLINK, nodeTag, OidIsValid, SubscriptingRef::refassgnexpr, SubscriptingRef::refcontainertype, SubscriptingRef::refelemtype, SubscriptingRef::reflowerindexpr, SubLink::subLinkType, SubPlan::subLinkType, AlternativeSubPlan::subplans, SubLink::subselect, T_Aggref, T_AlternativeSubPlan, T_ArrayCoerceExpr, T_ArrayExpr, T_BooleanTest, T_BoolExpr, T_CaseExpr, T_CaseTestExpr, T_CoalesceExpr, T_CoerceToDomain, T_CoerceToDomainValue, T_CoerceViaIO, T_CollateExpr, T_Const, T_ConvertRowtypeExpr, T_CurrentOfExpr, T_DistinctExpr, T_FieldSelect, T_FieldStore, T_FuncExpr, T_GroupingFunc, T_InferenceElem, T_MinMaxExpr, T_NamedArgExpr, T_NextValueExpr, T_NullIfExpr, T_NullTest, T_OpExpr, T_Param, T_PlaceHolderVar, T_RelabelType, T_RowCompareExpr, T_RowExpr, T_ScalarArrayOpExpr, T_SetToDefault, T_SQLValueFunction, T_SubLink, T_SubPlan, T_SubscriptingRef, T_Var, T_WindowFunc, T_XmlExpr, Query::targetList, and generate_unaccent_rules::type.

Referenced by addTargetToGroupList(), addTargetToSortList(), analyzeCTE(), analyzeCTETargetList(), appendAggOrderBy(), assign_collations_walker(), assign_hypothetical_collations(), assign_param_for_placeholdervar(), ATExecAlterColumnType(), ATPrepAlterColumnType(), build_coercion_expression(), build_column_default(), build_subplan(), canonicalize_ec_expression(), check_functions_in_node(), check_hashjoinable(), check_mergejoinable(), check_sql_fn_retval(), checkRuleResultList(), coerce_record_to_complex(), coerce_to_boolean(), coerce_to_common_type(), coerce_to_specific_type_typmod(), compare_tlist_datatypes(), compute_semijoin_info(), ComputeIndexAttrs(), ComputePartitionAttrs(), ConstructTupleDescriptor(), convert_EXISTS_to_ANY(), cookDefault(), cost_qual_eval_walker(), create_ctas_nodata(), create_indexscan_plan(), DefineVirtualRelation(), deparseNullTest(), estimate_num_groups(), eval_const_expressions_mutator(), EvaluateParams(), examine_attribute(), examine_variable(), exec_save_simple_expr(), ExecBuildProjectionInfo(), ExecCheckPlanOutput(), ExecEvalConvertRowtype(), ExecEvalXmlExpr(), ExecInitExprRec(), ExecInitIndexScan(), ExecMakeTableFunctionResult(), ExecTypeFromExprList(), ExecTypeFromTLInternal(), ExecWindowAgg(), expandRecordVariable(), expandRTE(), exprType(), exprTypmod(), find_expr_references_walker(), find_minmax_aggs_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_agg_clause_costs_walker(), 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_rte_attribute_type(), get_rule_expr(), get_rule_expr_funccall(), get_rule_orderby(), get_simple_binary_op_name(), get_sublink_expr(), get_windowfunc_expr(), hash_ok_operator(), initialize_peragg(), inline_function(), internal_get_result_type(), make_op(), make_scalar_array_op(), makeVarFromTargetEntry(), makeWholeRowVar(), match_pattern_prefix(), ordered_set_startup(), ParseFuncOrColumn(), pg_get_indexdef_worker(), pg_get_partkeydef_worker(), prepare_query_params(), preprocess_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(), set_append_rel_size(), set_dummy_tlist_references(), set_pathtarget_cost_width(), set_rel_width(), show_sortorder_options(), tlist_matches_coltypelist(), tlist_same_datatypes(), transformAExprNullIf(), transformAExprOf(), transformAggregateCall(), transformArrayExpr(), transformAssignedExpr(), transformAssignmentIndirection(), transformAssignmentSubscripts(), transformCaseExpr(), transformCollateClause(), transformContainerSubscripts(), transformExprRecurse(), transformFrameOffset(), transformIndirection(), transformInsertStmt(), transformMultiAssignRef(), transformPartitionBoundValue(), transformSetOperationTree(), transformSubLink(), transformTypeCast(), unknown_attribute(), and xmlelement().

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

◆ exprTypmod()

int32 exprTypmod ( const Node expr)

Definition at line 275 of file nodeFuncs.c.

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

Referenced by analyzeCTE(), analyzeCTETargetList(), assign_hypothetical_collations(), build_coercion_expression(), build_subplan(), canonicalize_ec_expression(), checkRuleResultList(), coerce_type_typmod(), ConstructTupleDescriptor(), convert_EXISTS_to_ANY(), create_ctas_nodata(), DefineVirtualRelation(), eval_const_expressions_mutator(), examine_attribute(), examine_variable(), exec_save_simple_expr(), ExecTypeFromExprList(), ExecTypeFromTLInternal(), expandRecordVariable(), expandRTE(), exprTypmod(), find_placeholder_info(), generate_append_tlist(), generate_setop_tlist(), generate_subquery_params(), get_agg_clause_costs_walker(), get_expr_result_type(), get_first_col_type(), get_rte_attribute_type(), get_rule_expr(), get_rule_expr_funccall(), interval_support(), makeVarFromTargetEntry(), numeric_support(), RelationBuildPartitionKey(), RelationGetDummyIndexExpressions(), remove_unused_subquery_outputs(), replace_nestloop_param_placeholdervar(), replace_outer_placeholdervar(), set_append_rel_size(), set_dummy_tlist_references(), set_pathtarget_cost_width(), set_rel_width(), TemporalSimplify(), transformCaseExpr(), transformIndirection(), transformInsertStmt(), transformMultiAssignRef(), transformSetOperationTree(), transformSubLink(), transformValuesClause(), varbit_support(), and varchar_support().

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

◆ fix_opfuncids()

void fix_opfuncids ( Node node)

Definition at line 1587 of file nodeFuncs.c.

References fix_opfuncids_walker().

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

1588 {
1589  /* This tree walk requires no special setup, so away we go... */
1590  fix_opfuncids_walker(node, NULL);
1591 }
static bool fix_opfuncids_walker(Node *node, void *context)
Definition: nodeFuncs.c:1594

◆ fix_opfuncids_walker()

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

Definition at line 1594 of file nodeFuncs.c.

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

Referenced by fix_opfuncids().

1595 {
1596  if (node == NULL)
1597  return false;
1598  if (IsA(node, OpExpr))
1599  set_opfuncid((OpExpr *) node);
1600  else if (IsA(node, DistinctExpr))
1601  set_opfuncid((OpExpr *) node); /* rely on struct equivalence */
1602  else if (IsA(node, NullIfExpr))
1603  set_opfuncid((OpExpr *) node); /* rely on struct equivalence */
1604  else if (IsA(node, ScalarArrayOpExpr))
1606  return expression_tree_walker(node, fix_opfuncids_walker, context);
1607 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:576
static bool fix_opfuncids_walker(Node *node, void *context)
Definition: nodeFuncs.c:1594
bool expression_tree_walker(Node *node, bool(*walker)(), void *context)
Definition: nodeFuncs.c:1839
void set_opfuncid(OpExpr *opexpr)
Definition: nodeFuncs.c:1618
void set_sa_opfuncid(ScalarArrayOpExpr *opexpr)
Definition: nodeFuncs.c:1629

◆ leftmostLoc()

static int leftmostLoc ( int  loc1,
int  loc2 
)
static

Definition at line 1566 of file nodeFuncs.c.

References Min.

Referenced by exprLocation().

1567 {
1568  if (loc1 < 0)
1569  return loc2;
1570  else if (loc2 < 0)
1571  return loc1;
1572  else
1573  return Min(loc1, loc2);
1574 }
#define Min(x, y)
Definition: c.h:911

◆ planstate_tree_walker()

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

Definition at line 3867 of file nodeFuncs.c.

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

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

3870 {
3871  Plan *plan = planstate->plan;
3872  ListCell *lc;
3873 
3874  /* Guard against stack overflow due to overly complex plan trees */
3876 
3877  /* initPlan-s */
3878  if (planstate_walk_subplans(planstate->initPlan, walker, context))
3879  return true;
3880 
3881  /* lefttree */
3882  if (outerPlanState(planstate))
3883  {
3884  if (walker(outerPlanState(planstate), context))
3885  return true;
3886  }
3887 
3888  /* righttree */
3889  if (innerPlanState(planstate))
3890  {
3891  if (walker(innerPlanState(planstate), context))
3892  return true;
3893  }
3894 
3895  /* special child plans */
3896  switch (nodeTag(plan))
3897  {
3898  case T_ModifyTable:
3899  if (planstate_walk_members(((ModifyTableState *) planstate)->mt_plans,
3900  ((ModifyTableState *) planstate)->mt_nplans,
3901  walker, context))
3902  return true;
3903  break;
3904  case T_Append:
3905  if (planstate_walk_members(((AppendState *) planstate)->appendplans,
3906  ((AppendState *) planstate)->as_nplans,
3907  walker, context))
3908  return true;
3909  break;
3910  case T_MergeAppend:
3911  if (planstate_walk_members(((MergeAppendState *) planstate)->mergeplans,
3912  ((MergeAppendState *) planstate)->ms_nplans,
3913  walker, context))
3914  return true;
3915  break;
3916  case T_BitmapAnd:
3917  if (planstate_walk_members(((BitmapAndState *) planstate)->bitmapplans,
3918  ((BitmapAndState *) planstate)->nplans,
3919  walker, context))
3920  return true;
3921  break;
3922  case T_BitmapOr:
3923  if (planstate_walk_members(((BitmapOrState *) planstate)->bitmapplans,
3924  ((BitmapOrState *) planstate)->nplans,
3925  walker, context))
3926  return true;
3927  break;
3928  case T_SubqueryScan:
3929  if (walker(((SubqueryScanState *) planstate)->subplan, context))
3930  return true;
3931  break;
3932  case T_CustomScan:
3933  foreach(lc, ((CustomScanState *) planstate)->custom_ps)
3934  {
3935  if (walker((PlanState *) lfirst(lc), context))
3936  return true;
3937  }
3938  break;
3939  default:
3940  break;
3941  }
3942 
3943  /* subPlan-s */
3944  if (planstate_walk_subplans(planstate->subPlan, walker, context))
3945  return true;
3946 
3947  return false;
3948 }
List * initPlan
Definition: execnodes.h:964
static bool planstate_walk_members(PlanState **planstates, int nplans, bool(*walker)(), void *context)
Definition: nodeFuncs.c:3976
Definition: nodes.h:49
#define outerPlanState(node)
Definition: execnodes.h:1033
void check_stack_depth(void)
Definition: postgres.c:3302
static bool planstate_walk_subplans(List *plans, bool(*walker)(), void *context)
Definition: nodeFuncs.c:3954
Plan * plan
Definition: execnodes.h:939
#define lfirst(lc)
Definition: pg_list.h:190
#define nodeTag(nodeptr)
Definition: nodes.h:530
#define innerPlanState(node)
Definition: execnodes.h:1032

◆ planstate_walk_members()

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

Definition at line 3976 of file nodeFuncs.c.

Referenced by planstate_tree_walker().

3978 {
3979  int j;
3980 
3981  for (j = 0; j < nplans; j++)
3982  {
3983  if (walker(planstates[j], context))
3984  return true;
3985  }
3986 
3987  return false;
3988 }

◆ planstate_walk_subplans()

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

Definition at line 3954 of file nodeFuncs.c.

References lfirst_node, and SubPlanState::planstate.

Referenced by planstate_tree_walker().

3957 {
3958  ListCell *lc;
3959 
3960  foreach(lc, plans)
3961  {
3963 
3964  if (walker(sps->planstate, context))
3965  return true;
3966  }
3967 
3968  return false;
3969 }
struct PlanState * planstate
Definition: execnodes.h:847
#define lfirst_node(type, lc)
Definition: pg_list.h:193

◆ query_or_expression_tree_mutator()

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

Definition at line 3371 of file nodeFuncs.c.

References IsA, and query_tree_mutator().

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

3375 {
3376  if (node && IsA(node, Query))
3377  return (Node *) query_tree_mutator((Query *) node,
3378  mutator,
3379  context,
3380  flags);
3381  else
3382  return mutator(node, context);
3383 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:576
Definition: nodes.h:525
Query * query_tree_mutator(Query *query, Node *(*mutator)(), void *context, int flags)
Definition: nodeFuncs.c:3187

◆ query_or_expression_tree_walker()

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

Definition at line 3348 of file nodeFuncs.c.

References IsA, and query_tree_walker().

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

3352 {
3353  if (node && IsA(node, Query))
3354  return query_tree_walker((Query *) node,
3355  walker,
3356  context,
3357  flags);
3358  else
3359  return walker(node, context);
3360 }
bool query_tree_walker(Query *query, bool(*walker)(), void *context, int flags)
Definition: nodeFuncs.c:2273
#define IsA(nodeptr, _type_)
Definition: nodes.h:576

◆ query_tree_mutator()

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

Definition at line 3187 of file nodeFuncs.c.

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

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

3191 {
3192  Assert(query != NULL && IsA(query, Query));
3193 
3194  if (!(flags & QTW_DONT_COPY_QUERY))
3195  {
3196  Query *newquery;
3197 
3198  FLATCOPY(newquery, query, Query);
3199  query = newquery;
3200  }
3201 
3202  MUTATE(query->targetList, query->targetList, List *);
3203  MUTATE(query->withCheckOptions, query->withCheckOptions, List *);
3204  MUTATE(query->onConflict, query->onConflict, OnConflictExpr *);
3205  MUTATE(query->returningList, query->returningList, List *);
3206  MUTATE(query->jointree, query->jointree, FromExpr *);
3207  MUTATE(query->setOperations, query->setOperations, Node *);
3208  MUTATE(query->havingQual, query->havingQual, Node *);
3209  MUTATE(query->limitOffset, query->limitOffset, Node *);
3210  MUTATE(query->limitCount, query->limitCount, Node *);
3211 
3212  /*
3213  * Most callers aren't interested in SortGroupClause nodes since those
3214  * don't contain actual expressions. However they do contain OIDs, which
3215  * may be of interest to some mutators.
3216  */
3217 
3218  if ((flags & QTW_EXAMINE_SORTGROUP))
3219  {
3220  MUTATE(query->groupClause, query->groupClause, List *);
3221  MUTATE(query->windowClause, query->windowClause, List *);
3222  MUTATE(query->sortClause, query->sortClause, List *);
3223  MUTATE(query->distinctClause, query->distinctClause, List *);
3224  }
3225  else
3226  {
3227  /*
3228  * But we need to mutate the expressions under WindowClause nodes even
3229  * if we're not interested in SortGroupClause nodes.
3230  */
3231  List *resultlist;
3232  ListCell *temp;
3233 
3234  resultlist = NIL;
3235  foreach(temp, query->windowClause)
3236  {
3237  WindowClause *wc = lfirst_node(WindowClause, temp);
3238  WindowClause *newnode;
3239 
3240  FLATCOPY(newnode, wc, WindowClause);
3241  MUTATE(newnode->startOffset, wc->startOffset, Node *);
3242  MUTATE(newnode->endOffset, wc->endOffset, Node *);
3243 
3244  resultlist = lappend(resultlist, (Node *) newnode);
3245  }
3246  query->windowClause = resultlist;
3247  }
3248 
3249  /*
3250  * groupingSets and rowMarks are not mutated:
3251  *
3252  * groupingSets contain only ressortgroup refs (integers) which are
3253  * meaningless without the groupClause or tlist. Accordingly, any mutator
3254  * that needs to care about them needs to handle them itself in its Query
3255  * processing.
3256  *
3257  * rowMarks contains only rangetable indexes (and flags etc.) and
3258  * therefore should be handled at Query level similarly.
3259  */
3260 
3261  if (!(flags & QTW_IGNORE_CTE_SUBQUERIES))
3262  MUTATE(query->cteList, query->cteList, List *);
3263  else /* else copy CTE list as-is */
3264  query->cteList = copyObject(query->cteList);
3265  query->rtable = range_table_mutator(query->rtable,
3266  mutator, context, flags);
3267  return query;
3268 }
Node * limitOffset
Definition: parsenodes.h:160
#define NIL
Definition: pg_list.h:65
#define IsA(nodeptr, _type_)
Definition: nodes.h:576
List * sortClause
Definition: parsenodes.h:158
FromExpr * jointree
Definition: parsenodes.h:138
OnConflictExpr * onConflict
Definition: parsenodes.h:144
List * withCheckOptions
Definition: parsenodes.h:171
#define QTW_EXAMINE_SORTGROUP
Definition: nodeFuncs.h:30
Definition: nodes.h:525
#define QTW_DONT_COPY_QUERY
Definition: nodeFuncs.h:29
List * windowClause
Definition: parsenodes.h:154
List * targetList
Definition: parsenodes.h:140
#define QTW_IGNORE_CTE_SUBQUERIES
Definition: nodeFuncs.h:21
List * rtable
Definition: parsenodes.h:137
List * distinctClause
Definition: parsenodes.h:156
#define lfirst_node(type, lc)
Definition: pg_list.h:193
Node * limitCount
Definition: parsenodes.h:161
List * returningList
Definition: parsenodes.h:146
List * lappend(List *list, void *datum)
Definition: list.c:322
Node * startOffset
Definition: parsenodes.h:1333
#define FLATCOPY(newnode, node, nodetype)
#define Assert(condition)
Definition: c.h:739
Node * endOffset
Definition: parsenodes.h:1334
List * cteList
Definition: parsenodes.h:135
Node * setOperations
Definition: parsenodes.h:165
List * groupClause
Definition: parsenodes.h:148
List * range_table_mutator(List *rtable, Node *(*mutator)(), void *context, int flags)
Definition: nodeFuncs.c:3276
#define copyObject(obj)
Definition: nodes.h:641
Node * havingQual
Definition: parsenodes.h:152
Definition: pg_list.h:50
#define MUTATE(newfield, oldfield, fieldtype)

◆ query_tree_walker()

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

Definition at line 2273 of file nodeFuncs.c.

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

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

2277 {
2278  Assert(query != NULL &&