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

Go to the source code of this file.

Macros

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

Typedefs

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

Functions

Oid exprType (const Node *expr)
 
int32 exprTypmod (const Node *expr)
 
bool exprIsLengthCoercion (const Node *expr, int32 *coercedTypmod)
 
Noderelabel_to_typmod (Node *expr, int32 typmod)
 
Nodestrip_implicit_coercions (Node *node)
 
bool expression_returns_set (Node *clause)
 
Oid exprCollation (const Node *expr)
 
Oid exprInputCollation (const Node *expr)
 
void exprSetCollation (Node *expr, Oid collation)
 
void exprSetInputCollation (Node *expr, Oid inputcollation)
 
int exprLocation (const Node *expr)
 
void fix_opfuncids (Node *node)
 
void set_opfuncid (OpExpr *opexpr)
 
void set_sa_opfuncid (ScalarArrayOpExpr *opexpr)
 
static bool is_funcclause (const void *clause)
 
static bool is_opclause (const void *clause)
 
static Nodeget_leftop (const void *clause)
 
static Nodeget_rightop (const void *clause)
 
static bool is_andclause (const void *clause)
 
static bool is_orclause (const void *clause)
 
static bool is_notclause (const void *clause)
 
static Exprget_notclausearg (const void *notclause)
 
bool check_functions_in_node (Node *node, check_function_callback checker, void *context)
 
bool expression_tree_walker (Node *node, bool(*walker)(), void *context)
 
Nodeexpression_tree_mutator (Node *node, Node *(*mutator)(), void *context)
 
bool query_tree_walker (Query *query, bool(*walker)(), void *context, int flags)
 
Queryquery_tree_mutator (Query *query, Node *(*mutator)(), void *context, int flags)
 
bool range_table_walker (List *rtable, bool(*walker)(), void *context, int flags)
 
Listrange_table_mutator (List *rtable, Node *(*mutator)(), void *context, int flags)
 
bool query_or_expression_tree_walker (Node *node, bool(*walker)(), void *context, int flags)
 
Nodequery_or_expression_tree_mutator (Node *node, Node *(*mutator)(), void *context, int flags)
 
bool raw_expression_tree_walker (Node *node, bool(*walker)(), void *context)
 
bool planstate_tree_walker (struct PlanState *planstate, bool(*walker)(), void *context)
 

Macro Definition Documentation

◆ QTW_DONT_COPY_QUERY

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

Definition at line 29 of file nodeFuncs.h.

Referenced by query_tree_mutator().

◆ QTW_EXAMINE_RTES_AFTER

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

Definition at line 27 of file nodeFuncs.h.

Referenced by inline_cte_walker(), and range_table_walker().

◆ QTW_EXAMINE_RTES_BEFORE

#define QTW_EXAMINE_RTES_BEFORE

◆ QTW_IGNORE_CTE_SUBQUERIES

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

Definition at line 21 of file nodeFuncs.h.

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

◆ QTW_IGNORE_JOINALIASES

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

◆ QTW_IGNORE_RANGE_TABLE

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

Definition at line 24 of file nodeFuncs.h.

Referenced by assign_query_collations(), and query_tree_walker().

◆ QTW_IGNORE_RC_SUBQUERIES

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

◆ QTW_IGNORE_RT_SUBQUERIES

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

Definition at line 20 of file nodeFuncs.h.

Referenced by range_table_mutator(), and range_table_walker().

Typedef Documentation

◆ check_function_callback

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

Definition at line 32 of file nodeFuncs.h.

Function Documentation

◆ check_functions_in_node()

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

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

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

◆ exprCollation()

Oid exprCollation ( const Node expr)

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

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

◆ expression_returns_set()

bool expression_returns_set ( Node clause)

◆ expression_tree_mutator()

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

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

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

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

926 {
927  Oid coll;
928 
929  if (!expr)
930  return InvalidOid;
931 
932  switch (nodeTag(expr))
933  {
934  case T_Aggref:
935  coll = ((const Aggref *) expr)->inputcollid;
936  break;
937  case T_WindowFunc:
938  coll = ((const WindowFunc *) expr)->inputcollid;
939  break;
940  case T_FuncExpr:
941  coll = ((const FuncExpr *) expr)->inputcollid;
942  break;
943  case T_OpExpr:
944  coll = ((const OpExpr *) expr)->inputcollid;
945  break;
946  case T_DistinctExpr:
947  coll = ((const DistinctExpr *) expr)->inputcollid;
948  break;
949  case T_NullIfExpr:
950  coll = ((const NullIfExpr *) expr)->inputcollid;
951  break;
952  case T_ScalarArrayOpExpr:
953  coll = ((const ScalarArrayOpExpr *) expr)->inputcollid;
954  break;
955  case T_MinMaxExpr:
956  coll = ((const MinMaxExpr *) expr)->inputcollid;
957  break;
958  default:
959  coll = InvalidOid;
960  break;
961  }
962  return coll;
963 }
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 513 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().

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

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

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

◆ exprSetInputCollation()

void exprSetInputCollation ( Node expr,
Oid  inputcollation 
)

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

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

◆ exprType()

Oid exprType ( const Node expr)

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

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

◆ exprTypmod()

int32 exprTypmod ( const Node expr)

Definition at line 276 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_first_col_type(), get_rte_attribute_type(), get_rule_expr(), get_rule_expr_funccall(), interval_support(), makeVarFromTargetEntry(), numeric_support(), RelationBuildPartitionKey(), 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().

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

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

◆ get_leftop()

static Node* get_leftop ( const void *  clause)
inlinestatic

◆ get_notclausearg()

◆ get_rightop()

static Node* get_rightop ( const void *  clause)
inlinestatic

◆ is_andclause()

◆ is_funcclause()

static bool is_funcclause ( const void *  clause)
inlinestatic

Definition at line 55 of file nodeFuncs.h.

References IsA.

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

56 {
57  return clause != NULL && IsA(clause, FuncExpr);
58 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:576

◆ is_notclause()

static bool is_notclause ( const void *  clause)
inlinestatic

Definition at line 111 of file nodeFuncs.h.

References boolop(), IsA, and NOT_EXPR.

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

112 {
113  return (clause != NULL &&
114  IsA(clause, BoolExpr) &&
115  ((const BoolExpr *) clause)->boolop == NOT_EXPR);
116 }
Datum boolop(PG_FUNCTION_ARGS)
Definition: _int_bool.c:420
#define IsA(nodeptr, _type_)
Definition: nodes.h:576

◆ is_opclause()

◆ is_orclause()

static bool is_orclause ( const void *  clause)
inlinestatic

Definition at line 102 of file nodeFuncs.h.

References boolop(), IsA, and OR_EXPR.

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

103 {
104  return (clause != NULL &&
105  IsA(clause, BoolExpr) &&
106  ((const BoolExpr *) clause)->boolop == OR_EXPR);
107 }
Datum boolop(PG_FUNCTION_ARGS)
Definition: _int_bool.c:420
#define IsA(nodeptr, _type_)
Definition: nodes.h:576

◆ planstate_tree_walker()

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

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

3765 {
3766  Plan *plan = planstate->plan;
3767  ListCell *lc;
3768 
3769  /* Guard against stack overflow due to overly complex plan trees */
3771 
3772  /* initPlan-s */
3773  if (planstate_walk_subplans(planstate->initPlan, walker, context))
3774  return true;
3775 
3776  /* lefttree */
3777  if (outerPlanState(planstate))
3778  {
3779  if (walker(outerPlanState(planstate), context))
3780  return true;
3781  }
3782 
3783  /* righttree */
3784  if (innerPlanState(planstate))
3785  {
3786  if (walker(innerPlanState(planstate), context))
3787  return true;
3788  }
3789 
3790  /* special child plans */
3791  switch (nodeTag(plan))
3792  {
3793  case T_ModifyTable:
3794  if (planstate_walk_members(((ModifyTableState *) planstate)->mt_plans,
3795  ((ModifyTableState *) planstate)->mt_nplans,
3796  walker, context))
3797  return true;
3798  break;
3799  case T_Append:
3800  if (planstate_walk_members(((AppendState *) planstate)->appendplans,
3801  ((AppendState *) planstate)->as_nplans,
3802  walker, context))
3803  return true;
3804  break;
3805  case T_MergeAppend:
3806  if (planstate_walk_members(((MergeAppendState *) planstate)->mergeplans,
3807  ((MergeAppendState *) planstate)->ms_nplans,
3808  walker, context))
3809  return true;
3810  break;
3811  case T_BitmapAnd:
3812  if (planstate_walk_members(((BitmapAndState *) planstate)->bitmapplans,
3813  ((BitmapAndState *) planstate)->nplans,
3814  walker, context))
3815  return true;
3816  break;
3817  case T_BitmapOr:
3818  if (planstate_walk_members(((BitmapOrState *) planstate)->bitmapplans,
3819  ((BitmapOrState *) planstate)->nplans,
3820  walker, context))
3821  return true;
3822  break;
3823  case T_SubqueryScan:
3824  if (walker(((SubqueryScanState *) planstate)->subplan, context))
3825  return true;
3826  break;
3827  case T_CustomScan:
3828  foreach(lc, ((CustomScanState *) planstate)->custom_ps)
3829  {
3830  if (walker((PlanState *) lfirst(lc), context))
3831  return true;
3832  }
3833  break;
3834  default:
3835  break;
3836  }
3837 
3838  /* subPlan-s */
3839  if (planstate_walk_subplans(planstate->subPlan, walker, context))
3840  return true;
3841 
3842  return false;
3843 }
List * initPlan
Definition: execnodes.h:965
static bool planstate_walk_members(PlanState **planstates, int nplans, bool(*walker)(), void *context)
Definition: nodeFuncs.c:3871
Definition: nodes.h:49
#define outerPlanState(node)
Definition: execnodes.h:1034
void check_stack_depth(void)
Definition: postgres.c:3262
static bool planstate_walk_subplans(List *plans, bool(*walker)(), void *context)
Definition: nodeFuncs.c:3849
Plan * plan
Definition: execnodes.h:940
#define lfirst(lc)
Definition: pg_list.h:190
#define nodeTag(nodeptr)
Definition: nodes.h:530
#define innerPlanState(node)
Definition: execnodes.h:1033

◆ query_or_expression_tree_mutator()

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

Definition at line 3266 of file nodeFuncs.c.

References IsA, and query_tree_mutator().

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

3270 {
3271  if (node && IsA(node, Query))
3272  return (Node *) query_tree_mutator((Query *) node,
3273  mutator,
3274  context,
3275  flags);
3276  else
3277  return mutator(node, context);
3278 }
#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:3132

◆ query_or_expression_tree_walker()

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

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

3247 {
3248  if (node && IsA(node, Query))
3249  return query_tree_walker((Query *) node,
3250  walker,
3251  context,
3252  flags);
3253  else
3254  return walker(node, context);
3255 }
bool query_tree_walker(Query *query, bool(*walker)(), void *context, int flags)
Definition: nodeFuncs.c:2274
#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 3132 of file nodeFuncs.c.

References Assert, copyObject, Query::cteList, FLATCOPY, Query::havingQual, IsA, Query::jointree, Query::limitCount, Query::limitOffset, MUTATE, Query::onConflict, QTW_DONT_COPY_QUERY, QTW_IGNORE_CTE_SUBQUERIES, range_table_mutator(), Query::returningList, Query::rtable, Query::setOperations, Query::targetList, 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().

3136 {
3137  Assert(query != NULL && IsA(query, Query));
3138 
3139  if (!(flags & QTW_DONT_COPY_QUERY))
3140  {
3141  Query *newquery;
3142 
3143  FLATCOPY(newquery, query, Query);
3144  query = newquery;
3145  }
3146 
3147  MUTATE(query->targetList, query->targetList, List *);
3148  MUTATE(query->withCheckOptions, query->withCheckOptions, List *);
3149  MUTATE(query->onConflict, query->onConflict, OnConflictExpr *);
3150  MUTATE(query->returningList, query->returningList, List *);
3151  MUTATE(query->jointree, query->jointree, FromExpr *);
3152  MUTATE(query->setOperations, query->setOperations, Node *);
3153  MUTATE(query->havingQual, query->havingQual, Node *);
3154  MUTATE(query->limitOffset, query->limitOffset, Node *);
3155  MUTATE(query->limitCount, query->limitCount, Node *);
3156  if (!(flags & QTW_IGNORE_CTE_SUBQUERIES))
3157  MUTATE(query->cteList, query->cteList, List *);
3158  else /* else copy CTE list as-is */
3159  query->cteList = copyObject(query->cteList);
3160  query->rtable = range_table_mutator(query->rtable,
3161  mutator, context, flags);
3162  return query;
3163 }
Node * limitOffset
Definition: parsenodes.h:160
#define IsA(nodeptr, _type_)
Definition: nodes.h:576
FromExpr * jointree
Definition: parsenodes.h:138
OnConflictExpr * onConflict
Definition: parsenodes.h:144
List * withCheckOptions
Definition: parsenodes.h:171
Definition: nodes.h:525
#define QTW_DONT_COPY_QUERY
Definition: nodeFuncs.h:29
List * targetList
Definition: parsenodes.h:140
#define QTW_IGNORE_CTE_SUBQUERIES
Definition: nodeFuncs.h:21
List * rtable
Definition: parsenodes.h:137
Node * limitCount
Definition: parsenodes.h:161
List * returningList
Definition: parsenodes.h:146
#define FLATCOPY(newnode, node, nodetype)
#define Assert(condition)
Definition: c.h:732
List * cteList
Definition: parsenod