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   0x10 /* examine RTEs */
 
#define QTW_DONT_COPY_QUERY   0x20 /* 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)
 
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   0x20 /* do not copy top Query */

Definition at line 26 of file nodeFuncs.h.

Referenced by query_tree_mutator().

◆ QTW_EXAMINE_RTES

#define QTW_EXAMINE_RTES   0x10 /* examine RTEs */

◆ 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 29 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 1651 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(), and max_parallel_hazard_walker().

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

◆ exprCollation()

Oid exprCollation ( const Node expr)

Definition at line 720 of file nodeFuncs.c.

References arg, ARRAY_SUBLINK, Assert, DEFAULT_COLLATION_OID, 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_ArrayRef, 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_Var, T_WindowFunc, T_XmlExpr, and Query::targetList.

Referenced by analyzeCTE(), analyzeCTETargetList(), assign_collations_walker(), assign_hypothetical_collations(), assign_nestloop_param_placeholdervar(), build_expression_pathkey(), build_pertrans_for_aggref(), build_subplan(), canonicalize_ec_expression(), ComputeIndexAttrs(), ComputePartitionAttrs(), convert_EXISTS_to_ANY(), create_ctas_nodata(), DefineVirtualRelation(), eval_const_expressions_mutator(), ExecInitFunctionScan(), ExecInitIndexScan(), ExecTypeFromExprList(), ExecTypeFromTLInternal(), expandRecordVariable(), expandRTE(), exprCollation(), exprSetCollation(), fix_indexqual_operand(), generate_setop_tlist(), generate_subquery_params(), get_first_col_type(), get_rte_attribute_type(), inline_function(), make_pathkey_from_sortop(), make_sort_from_groupcols(), make_sort_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_outer_placeholdervar(), scalararraysel(), set_dummy_tlist_references(), tlist_same_collations(), transformCaseExpr(), transformMultiAssignRef(), and transformSubLink().

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_ArrayRef:
748  coll = ((const ArrayRef *) 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  coll = InvalidOid; /* all cases return non-collatable types */
866  break;
867  case T_XmlExpr:
868 
869  /*
870  * XMLSERIALIZE returns text from non-collatable inputs, so its
871  * collation is always default. The other cases return boolean or
872  * XML, which are non-collatable.
873  */
874  if (((const XmlExpr *) expr)->op == IS_XMLSERIALIZE)
875  coll = DEFAULT_COLLATION_OID;
876  else
877  coll = InvalidOid;
878  break;
879  case T_NullTest:
880  coll = InvalidOid; /* result is always boolean */
881  break;
882  case T_BooleanTest:
883  coll = InvalidOid; /* result is always boolean */
884  break;
885  case T_CoerceToDomain:
886  coll = ((const CoerceToDomain *) expr)->resultcollid;
887  break;
889  coll = ((const CoerceToDomainValue *) expr)->collation;
890  break;
891  case T_SetToDefault:
892  coll = ((const SetToDefault *) expr)->collation;
893  break;
894  case T_CurrentOfExpr:
895  coll = InvalidOid; /* result is always boolean */
896  break;
897  case T_NextValueExpr:
898  coll = InvalidOid; /* result is always an integer type */
899  break;
900  case T_InferenceElem:
901  coll = exprCollation((Node *) ((const InferenceElem *) expr)->expr);
902  break;
903  case T_PlaceHolderVar:
904  coll = exprCollation((Node *) ((const PlaceHolderVar *) expr)->phexpr);
905  break;
906  default:
907  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
908  coll = InvalidOid; /* keep compiler quiet */
909  break;
910  }
911  return coll;
912 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:563
SubLinkType subLinkType
Definition: primnodes.h:684
Definition: nodes.h:512
unsigned int Oid
Definition: postgres_ext.h:31
Definition: primnodes.h:163
#define linitial_node(type, l)
Definition: pg_list.h:114
List * targetList
Definition: parsenodes.h:138
#define linitial(l)
Definition: pg_list.h:111
#define ERROR
Definition: elog.h:43
#define DEFAULT_COLLATION_OID
Definition: pg_collation.h:75
Definition: nodes.h:147
Definition: nodes.h:146
#define InvalidOid
Definition: postgres_ext.h:36
#define Assert(condition)
Definition: c.h:680
Oid exprCollation(const Node *expr)
Definition: nodeFuncs.c:720
#define nodeTag(nodeptr)
Definition: nodes.h:517
void * arg
Oid firstColCollation
Definition: primnodes.h:695
#define elog
Definition: elog.h:219
Definition: nodes.h:148

◆ 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 2409 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, FieldStore::fieldnums, FLATCOPY, FromExpr::fromlist, RangeTblFunction::funcexpr, 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, ArrayRef::refassgnexpr, ArrayRef::refexpr, ArrayRef::reflowerindexpr, GroupingFunc::refs, ArrayRef::refupperindexpr, TableSampleClause::repeatable, CaseWhen::result, TableFunc::rowexpr, WindowClause::startOffset, AlternativeSubPlan::subplans, SubLink::subselect, T_Aggref, T_AlternativeSubPlan, T_AppendRelInfo, T_ArrayCoerceExpr, T_ArrayExpr, T_ArrayRef, 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_InferenceElem, T_JoinExpr, T_List, T_MinMaxExpr, T_NamedArgExpr, T_NextValueExpr, T_NullIfExpr, T_NullTest, T_OnConflictExpr, T_OpExpr, T_Param, 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_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(), 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().

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

◆ expression_tree_walker()

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

Definition at line 1834 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(), FromExpr::fromlist, 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, ArrayRef::refassgnexpr, ArrayRef::refexpr, ArrayRef::reflowerindexpr, ArrayRef::refupperindexpr, TableSampleClause::repeatable, CaseWhen::result, TableFunc::rowexpr, WindowClause::startOffset, SubLink::subselect, T_Aggref, T_AlternativeSubPlan, T_AppendRelInfo, T_ArrayCoerceExpr, T_ArrayExpr, T_ArrayRef, 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_InferenceElem, T_JoinExpr, T_List, T_MinMaxExpr, T_NamedArgExpr, T_NextValueExpr, T_NullIfExpr, T_NullTest, T_OnConflictExpr, T_OpExpr, T_Param, 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_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_parameter_resolution_walker(), check_ungrouped_columns_walker(), checkExprHasSubLink_walker(), contain_agg_clause_walker(), contain_aggs_of_level_walker(), contain_context_dependent_node_walker(), contain_leaked_vars_walker(), contain_mutable_functions_walker(), contain_nonstrict_functions_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_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(), IncrementVarSublevelsUp_walker(), isQueryUsingTempRelation_walker(), locate_agg_of_level_walker(), locate_var_of_level_walker(), locate_windowfunc_walker(), max_parallel_hazard_walker(), OffsetVarNodes_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_multiple_relids_walker().

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

◆ exprInputCollation()

Oid exprInputCollation ( const Node expr)

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

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

◆ 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, INT4OID, 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:196
#define IsA(nodeptr, _type_)
Definition: nodes.h:563
List * args
Definition: primnodes.h:457
#define DatumGetInt32(X)
Definition: postgres.h:478
#define INT4OID
Definition: pg_type.h:316
#define lsecond(l)
Definition: pg_list.h:116
Oid consttype
Definition: primnodes.h:192
CoercionForm funcformat
Definition: primnodes.h:454
static int list_length(const List *l)
Definition: pg_list.h:89
int32 resulttypmod
Definition: primnodes.h:841
bool constisnull
Definition: primnodes.h:197

◆ exprLocation()

int exprLocation ( const Node expr)

Definition at line 1186 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_ArrayRef, 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_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(), transformArraySubscripts(), transformAssignedExpr(), transformCaseExpr(), transformCoalesceExpr(), transformDistinctClause(), transformDistinctOnClause(), transformFromClauseItem(), transformGroupClause(), transformGroupClauseExpr(), transformGroupingSet(), transformIndirection(), transformInsertRow(), transformInsertStmt(), transformMultiAssignRef(), transformOnConflictArbiter(), transformPartitionBound(), transformRangeFunction(), transformReturningList(), transformSelectStmt(), transformSetOperationStmt(), transformSetOperationTree(), transformValuesClause(), and validateInfiniteBounds().

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

◆ exprSetCollation()

void exprSetCollation ( Node expr,
Oid  collation 
)

Definition at line 969 of file nodeFuncs.c.

References arg, ARRAY_SUBLINK, Assert, DEFAULT_COLLATION_OID, elog, ERROR, EXPR_SUBLINK, exprCollation(), InvalidOid, IS_XMLSERIALIZE, IsA, linitial_node, nodeTag, OidIsValid, SubLink::subLinkType, SubLink::subselect, T_Aggref, T_ArrayCoerceExpr, T_ArrayExpr, T_ArrayRef, 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_Var, T_WindowFunc, T_XmlExpr, and Query::targetList.

Referenced by assign_collations_walker().

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

◆ exprSetInputCollation()

void exprSetInputCollation ( Node expr,
Oid  inputcollation 
)

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

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

◆ exprType()

Oid exprType ( const Node expr)

Definition at line 42 of file nodeFuncs.c.

References arg, ARRAY_SUBLINK, Assert, BOOLOID, elog, ereport, errcode(), errmsg(), ERROR, InferenceElem::expr, EXPR_SUBLINK, exprType(), SubPlan::firstColType, format_type_be(), get_promoted_array_type(), INT4OID, InvalidOid, IS_DOCUMENT, IS_XMLSERIALIZE, IsA, linitial, linitial_node, MULTIEXPR_SUBLINK, nodeTag, OidIsValid, RECORDOID, ArrayRef::refarraytype, ArrayRef::refassgnexpr, ArrayRef::refelemtype, ArrayRef::reflowerindexpr, SubLink::subLinkType, SubPlan::subLinkType, AlternativeSubPlan::subplans, SubLink::subselect, T_Aggref, T_AlternativeSubPlan, T_ArrayCoerceExpr, T_ArrayExpr, T_ArrayRef, 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_Var, T_WindowFunc, T_XmlExpr, Query::targetList, TEXTOID, generate_unaccent_rules::type, and XMLOID.

Referenced by addTargetToGroupList(), addTargetToSortList(), analyzeCTE(), analyzeCTETargetList(), appendAggOrderBy(), assign_collations_walker(), assign_hypothetical_collations(), assign_nestloop_param_placeholdervar(), 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(), IsTidEqualClause(), make_op(), make_scalar_array_op(), makeVarFromTargetEntry(), makeWholeRowVar(), 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_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(), transformArraySubscripts(), transformAssignedExpr(), transformAssignmentIndirection(), transformAssignmentSubscripts(), transformCaseExpr(), transformCollateClause(), transformExprRecurse(), 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_ArrayRef:
70  {
71  const ArrayRef *arrayref = (const ArrayRef *) expr;
72 
73  /* slice and/or store operations yield the array type */
74  if (arrayref->reflowerindexpr || arrayref->refassgnexpr)
75  type = arrayref->refarraytype;
76  else
77  type = arrayref->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:693
Expr * refassgnexpr
Definition: primnodes.h:410
#define IsA(nodeptr, _type_)
Definition: nodes.h:563
#define TEXTOID
Definition: pg_type.h:324
SubLinkType subLinkType
Definition: primnodes.h:684
#define INT4OID
Definition: pg_type.h:316
Definition: nodes.h:512
int errcode(int sqlerrcode)
Definition: elog.c:575
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
unsigned int Oid
Definition: postgres_ext.h:31
Definition: primnodes.h:163
#define linitial_node(type, l)
Definition: pg_list.h:114
#define OidIsValid(objectId)
Definition: c.h:586
List * targetList
Definition: parsenodes.h:138
#define linitial(l)
Definition: pg_list.h:111
#define ERROR
Definition: elog.h:43
#define XMLOID
Definition: pg_type.h:359
List * reflowerindexpr
Definition: primnodes.h:405
#define RECORDOID
Definition: pg_type.h:680
#define ereport(elevel, rest)
Definition: elog.h:122
Definition: nodes.h:147
Definition: nodes.h:146
Oid get_promoted_array_type(Oid typid)
Definition: lsyscache.c:2569
Oid refelemtype
Definition: primnodes.h:400
#define InvalidOid
Definition: postgres_ext.h:36
#define Assert(condition)
Definition: c.h:680
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
#define BOOLOID
Definition: pg_type.h:288
#define nodeTag(nodeptr)
Definition: nodes.h:517
Oid refarraytype
Definition: primnodes.h:399
int errmsg(const char *fmt,...)
Definition: elog.c:797
void * arg
#define elog
Definition: elog.h:219
Definition: nodes.h:148

◆ 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_head(), lnext, MinMaxExpr::minmaxtype, ArrayExpr::multidims, NIL, nodeTag, CaseWhen::result, SubLink::subLinkType, SubPlan::subLinkType, AlternativeSubPlan::subplans, SubLink::subselect, T_AlternativeSubPlan, T_ArrayCoerceExpr, T_ArrayExpr, T_ArrayRef, 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_Var, and Query::targetList.

Referenced by analyzeCTE(), analyzeCTETargetList(), assign_hypothetical_collations(), assign_nestloop_param_placeholdervar(), 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_transform(), makeVarFromTargetEntry(), numeric_transform(), RelationBuildPartitionKey(), remove_unused_subquery_outputs(), replace_outer_placeholdervar(), set_append_rel_size(), set_dummy_tlist_references(), set_pathtarget_cost_width(), set_rel_width(), TemporalTransform(), transformCaseExpr(), transformIndirection(), transformInsertStmt(), transformMultiAssignRef(), transformSetOperationTree(), transformSubLink(), transformValuesClause(), varbit_transform(), and varchar_transform().

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_ArrayRef:
290  /* typmod is the same for array or element */
291  return ((const ArrayRef *) 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, lnext(list_head(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, lnext(list_head(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:1070
bool multidims
Definition: primnodes.h:960
#define NIL
Definition: pg_list.h:69
List * args
Definition: primnodes.h:1074
#define IsA(nodeptr, _type_)
Definition: nodes.h:563
int32 exprTypmod(const Node *expr)
Definition: nodeFuncs.c:276
SubLinkType subLinkType
Definition: primnodes.h:684
Definition: nodes.h:512
bool exprIsLengthCoercion(const Node *expr, int32 *coercedTypmod)
Definition: nodeFuncs.c:513
Oid array_typeid
Definition: primnodes.h:956
Oid casetype
Definition: primnodes.h:910
unsigned int Oid
Definition: postgres_ext.h:31
Definition: primnodes.h:163
#define linitial_node(type, l)
Definition: pg_list.h:114
signed int int32
Definition: c.h:294
List * targetList
Definition: parsenodes.h:138
#define linitial(l)
Definition: pg_list.h:111
#define ERROR
Definition: elog.h:43
List * args
Definition: primnodes.h:1054
#define lfirst_node(type, lc)
Definition: pg_list.h:109
static ListCell * list_head(const List *l)
Definition: pg_list.h:77
List * elements
Definition: primnodes.h:959
#define lnext(lc)
Definition: pg_list.h:105
Definition: nodes.h:147
Definition: nodes.h:146
List * args
Definition: primnodes.h:913
int32 firstColTypmod
Definition: primnodes.h:694
#define Assert(condition)
Definition: c.h:680
#define lfirst(lc)
Definition: pg_list.h:106
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
#define for_each_cell(cell, initcell)
Definition: pg_list.h:169
#define nodeTag(nodeptr)
Definition: nodes.h:517
Oid element_typeid
Definition: primnodes.h:958
e
Definition: preproc-init.c:82
Oid coalescetype
Definition: primnodes.h:1052
void * arg
#define elog
Definition: elog.h:219
Expr * result
Definition: primnodes.h:925
List * args
Definition: primnodes.h:502
Expr * defresult
Definition: primnodes.h:914
Definition: nodes.h:148

◆ fix_opfuncids()

void fix_opfuncids ( Node node)

Definition at line 1582 of file nodeFuncs.c.

References fix_opfuncids_walker().

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

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

◆ planstate_tree_walker()

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

Definition at line 3697 of file nodeFuncs.c.

References 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(), and ExplainPreScanNode().

3700 {
3701  Plan *plan = planstate->plan;
3702  ListCell *lc;
3703 
3704  /* initPlan-s */
3705  if (planstate_walk_subplans(planstate->initPlan, walker, context))
3706  return true;
3707 
3708  /* lefttree */
3709  if (outerPlanState(planstate))
3710  {
3711  if (walker(outerPlanState(planstate), context))
3712  return true;
3713  }
3714 
3715  /* righttree */
3716  if (innerPlanState(planstate))
3717  {
3718  if (walker(innerPlanState(planstate), context))
3719  return true;
3720  }
3721 
3722  /* special child plans */
3723  switch (nodeTag(plan))
3724  {
3725  case T_ModifyTable:
3726  if (planstate_walk_members(((ModifyTable *) plan)->plans,
3727  ((ModifyTableState *) planstate)->mt_plans,
3728  walker, context))
3729  return true;
3730  break;
3731  case T_Append:
3732  if (planstate_walk_members(((Append *) plan)->appendplans,
3733  ((AppendState *) planstate)->appendplans,
3734  walker, context))
3735  return true;
3736  break;
3737  case T_MergeAppend:
3738  if (planstate_walk_members(((MergeAppend *) plan)->mergeplans,
3739  ((MergeAppendState *) planstate)->mergeplans,
3740  walker, context))
3741  return true;
3742  break;
3743  case T_BitmapAnd:
3744  if (planstate_walk_members(((BitmapAnd *) plan)->bitmapplans,
3745  ((BitmapAndState *) planstate)->bitmapplans,
3746  walker, context))
3747  return true;
3748  break;
3749  case T_BitmapOr:
3750  if (planstate_walk_members(((BitmapOr *) plan)->bitmapplans,
3751  ((BitmapOrState *) planstate)->bitmapplans,
3752  walker, context))
3753  return true;
3754  break;
3755  case T_SubqueryScan:
3756  if (walker(((SubqueryScanState *) planstate)->subplan, context))
3757  return true;
3758  break;
3759  case T_CustomScan:
3760  foreach(lc, ((CustomScanState *) planstate)->custom_ps)
3761  {
3762  if (walker((PlanState *) lfirst(lc), context))
3763  return true;
3764  }
3765  break;
3766  default:
3767  break;
3768  }
3769 
3770  /* subPlan-s */
3771  if (planstate_walk_subplans(planstate->subPlan, walker, context))
3772  return true;
3773 
3774  return false;
3775 }
List * initPlan
Definition: execnodes.h:871
Definition: nodes.h:48
#define outerPlanState(node)
Definition: execnodes.h:896
static bool planstate_walk_subplans(List *plans, bool(*walker)(), void *context)
Definition: nodeFuncs.c:3781
Plan * plan
Definition: execnodes.h:850
#define lfirst(lc)
Definition: pg_list.h:106
#define nodeTag(nodeptr)
Definition: nodes.h:517
static bool planstate_walk_members(List *plans, PlanState **planstates, bool(*walker)(), void *context)
Definition: nodeFuncs.c:3806
#define innerPlanState(node)
Definition: execnodes.h:895

◆ query_or_expression_tree_mutator()

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

Definition at line 3201 of file nodeFuncs.c.

References IsA, and query_tree_mutator().

Referenced by map_variable_attnos(), and replace_rte_variables().

3205 {
3206  if (node && IsA(node, Query))
3207  return (Node *) query_tree_mutator((Query *) node,
3208  mutator,
3209  context,
3210  flags);
3211  else
3212  return mutator(node, context);
3213 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:563
Definition: nodes.h:512
Query * query_tree_mutator(Query *query, Node *(*mutator)(), void *context, int flags)
Definition: nodeFuncs.c:3068

◆ query_or_expression_tree_walker()

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

Definition at line 3178 of file nodeFuncs.c.

References IsA, and query_tree_walker().

Referenced by checkExprHasSubLink(), contain_aggs_of_level(), contain_vars_of_level(), contain_windowfuncs(), 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_multiple_relids().

3182 {
3183  if (node && IsA(node, Query))
3184  return query_tree_walker((Query *) node,
3185  walker,
3186  context,
3187  flags);
3188  else
3189  return walker(node, context);
3190 }
bool query_tree_walker(Query *query, bool(*walker)(), void *context, int flags)
Definition: nodeFuncs.c:2245
#define IsA(nodeptr, _type_)
Definition: nodes.h:563

◆ query_tree_mutator()

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

Definition at line 3068 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(), map_variable_attnos_mutator(), query_or_expression_tree_mutator(), replace_rte_variables_mutator(), substitute_actual_srf_parameters(), and substitute_actual_srf_parameters_mutator().

3072 {
3073  Assert(query != NULL && IsA(query, Query));
3074 
3075  if (!(flags & QTW_DONT_COPY_QUERY))
3076  {
3077  Query *newquery;
3078 
3079  FLATCOPY(newquery, query, Query);
3080  query = newquery;
3081  }
3082 
3083  MUTATE(query->targetList, query->targetList, List *);
3084  MUTATE(query->withCheckOptions, query->withCheckOptions, List *);
3085  MUTATE(query->onConflict, query->onConflict, OnConflictExpr *);
3086  MUTATE(query->returningList, query->returningList, List *);
3087  MUTATE(query->jointree, query->jointree, FromExpr *);
3088  MUTATE(query->setOperations, query->setOperations, Node *);
3089  MUTATE(query->havingQual, query->havingQual, Node *);
3090  MUTATE(query->limitOffset, query->limitOffset, Node *);
3091  MUTATE(query->limitCount, query->limitCount, Node *);
3092  if (!(flags & QTW_IGNORE_CTE_SUBQUERIES))
3093  MUTATE(query->cteList, query->cteList, List *);
3094  else /* else copy CTE list as-is */
3095  query->cteList = copyObject(query->cteList);
3096  query->rtable = range_table_mutator(query->rtable,
3097  mutator, context, flags);
3098  return query;
3099 }
Node * limitOffset
Definition: parsenodes.h:158
#define IsA(nodeptr, _type_)
Definition: nodes.h:563
FromExpr * jointree
Definition: parsenodes.h:136
OnConflictExpr * onConflict
Definition: parsenodes.h:142
List * withCheckOptions
Definition: parsenodes.h:169
Definition: nodes.h:512
#define QTW_DONT_COPY_QUERY
Definition: nodeFuncs.h:26
List * targetList
Definition: parsenodes.h:138
#define QTW_IGNORE_CTE_SUBQUERIES
Definition: nodeFuncs.h:21
List * rtable
Definition: parsenodes.h:135
Node * limitCount
Definition: parsenodes.h:159
List * returningList
Definition: parsenodes.h:144
#define FLATCOPY(newnode, node, nodetype)
#define Assert(condition)
Definition: c.h:680
List * cteList
Definition: parsenodes.h:133
Node * setOperations
Definition: parsenodes.h:163
List * range_table_mutator(List *rtable, Node *(*mutator)(), void *context, int flags)
Definition: nodeFuncs.c:3107
#define copyObject(obj)
Definition: nodes.h:625
Node * havingQual
Definition: parsenodes.h:150
Definition: pg_list.h:45
#define MUTATE(newfield, oldfield, fieldtype)

◆ query_tree_walker()

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

Definition at line 2245 of file nodeFuncs.c.

References Assert, Query::cteList, Query::havingQual, IsA, Query::jointree, Query::limitCount, Query::limitOffset, Query::onConflict, QTW_IGNORE_CTE_SUBQUERIES, QTW_IGNORE_RANGE_TABLE, range_table_walker(), Query::returningList, Query::rtable, Query::setOperations, Query::targetList, and Query::withCheckOptions.

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

2249 {
2250  Assert(query != NULL && IsA(query, Query));
2251 
2252  if (walker((Node *) query->targetList, context))
2253  return true;
2254  if (walker((Node *) query->withCheckOptions, context))
2255  return true;
2256  if (walker((Node *) query->onConflict, context))
2257  return true;
2258  if (walker((Node *) query->returningList, context))
2259  return true;
2260  if (walker((Node *) query->jointree, context))
2261  return true;
2262  if (walker(query->setOperations, context))
2263  return true;
2264  if (walker(query->havingQual, context))
2265  return true;
2266  if (walker(query->limitOffset, context))
2267  return true;
2268  if (walker(query->limitCount, context))
2269  return true;
2270  if (!(flags & QTW_IGNORE_CTE_SUBQUERIES))
2271  {
2272  if (walker((Node *) query->cteList, context))
2273  return true;
2274  }
2275  if (!(flags & QTW_IGNORE_RANGE_TABLE))
2276  {
2277  if (range_table_walker(query->rtable, walker, context, flags))
2278  return true;
2279  }
2280  return false;
2281 }
Node * limitOffset
Definition: parsenodes.h:158
#define IsA(nodeptr, _type_)
Definition: nodes.h:563
FromExpr * jointree
Definition: parsenodes.h:136
OnConflictExpr * onConflict
Definition: parsenodes.h:142
List * withCheckOptions
Definition: parsenodes.h:169
Definition: nodes.h:512
List * targetList
Definition: parsenodes.h:138
#define QTW_IGNORE_CTE_SUBQUERIES
Definition: nodeFuncs.h:21
List * rtable
Definition: parsenodes.h:135
Node * limitCount
Definition: parsenodes.h:159
List * returningList
Definition: parsenodes.h:144
#define Assert(condition)
Definition: c.h:680
bool range_table_walker(List *rtable, bool(*walker)(), void *context, int flags)
Definition: nodeFuncs.c:2289
List * cteList
Definition: parsenodes.h:133
Node * setOperations
Definition: parsenodes.h:163
#define QTW_IGNORE_RANGE_TABLE
Definition: nodeFuncs.h:24
Node * havingQual
Definition: parsenodes.h:150

◆ range_table_mutator()

List* range_table_mutator ( List rtable,
Node *(*)()  mutator,
void *  context,
int  flags 
)

Definition at line 3107 of file nodeFuncs.c.

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

Referenced by query_tree_mutator().

3111 {
3112  List *newrt = NIL;
3113  ListCell *rt;
3114 
3115  foreach(rt, rtable)
3116  {
3117  RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
3118  RangeTblEntry *newrte;
3119 
3120  FLATCOPY(newrte, rte, RangeTblEntry);
3121  switch (rte->rtekind)
3122  {
3123  case RTE_RELATION:
3124  MUTATE(newrte->tablesample, rte->tablesample,
3125  TableSampleClause *);
3126  /* we don't bother to copy eref, aliases, etc; OK? */
3127  break;
3128  case RTE_CTE:
3129  case RTE_NAMEDTUPLESTORE:
3130  /* nothing to do */
3131  break;
3132  case RTE_SUBQUERY:
3133  if (!(flags & QTW_IGNORE_RT_SUBQUERIES))
3134  {
3135  CHECKFLATCOPY(newrte->subquery, rte->subquery, Query);
3136  MUTATE(newrte->subquery, newrte->subquery, Query *);
3137  }
3138  else
3139  {
3140  /* else, copy RT subqueries as-is */
3141  newrte->subquery = copyObject(rte->subquery);
3142  }
3143  break;
3144  case RTE_JOIN:
3145  if (!(flags & QTW_IGNORE_JOINALIASES))
3146  MUTATE(newrte->joinaliasvars, rte->joinaliasvars, List *);
3147  else
3148  {
3149  /* else, copy join aliases as-is */
3150  newrte->joinaliasvars = copyObject(rte->joinaliasvars);
3151  }
3152  break;
3153  case RTE_FUNCTION:
3154  MUTATE(newrte->functions, rte->functions, List *);
3155  break;
3156  case RTE_TABLEFUNC:
3157  MUTATE(newrte->tablefunc, rte->tablefunc, TableFunc *);
3158  break;
3159  case RTE_VALUES:
3160  MUTATE(newrte->values_lists, rte->values_lists, List *);
3161  break;
3162  }
3163  MUTATE(newrte->securityQuals, rte->securityQuals, List *);
3164  newrt = lappend(newrt, newrte);
3165  }
3166  return newrt;
3167 }
#define NIL
Definition: pg_list.h:69
List * joinaliasvars
Definition: parsenodes.h:995
#define CHECKFLATCOPY(newnode, node, nodetype)
List * securityQuals
Definition: parsenodes.h:1064
List * values_lists
Definition: parsenodes.h:1016
TableFunc * tablefunc
Definition: parsenodes.h:1011
List * lappend(List *list, void *datum)
Definition: list.c:128
#define FLATCOPY(newnode, node, nodetype)
#define lfirst(lc)
Definition: pg_list.h:106
List * functions
Definition: parsenodes.h:1005
RTEKind rtekind
Definition: parsenodes.h:951
#define QTW_IGNORE_RT_SUBQUERIES
Definition: nodeFuncs.h:20
Query * subquery
Definition: parsenodes.h:974
#define copyObject(obj)
Definition: nodes.h:625
Definition: pg_list.h:45
struct TableSampleClause * tablesample
Definition: parsenodes.h:969
#define MUTATE(newfield, oldfield, fieldtype)
#define QTW_IGNORE_JOINALIASES
Definition: nodeFuncs.h:23

◆ range_table_walker()

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

Definition at line 2289 of file nodeFuncs.c.

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

Referenced by IncrementVarSublevelsUp_rtable(), and query_tree_walker().

2293 {
2294  ListCell *rt;
2295 
2296  foreach(rt, rtable)
2297  {
2298  RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
2299 
2300  /* For historical reasons, visiting RTEs is not the default */
2301  if (flags & QTW_EXAMINE_RTES)
2302  if (walker(rte, context))
2303  return true;
2304 
2305  switch (rte->rtekind)
2306  {
2307  case RTE_RELATION:
2308  if (walker(rte->tablesample, context))
2309  return true;
2310  break;
2311  case RTE_CTE:
2312  case RTE_NAMEDTUPLESTORE:
2313  /* nothing to do */
2314  break;
2315  case RTE_SUBQUERY:
2316  if (!(flags & QTW_IGNORE_RT_SUBQUERIES))
2317  if (walker(rte->subquery, context))
2318  return true;
2319  break;
2320  case RTE_JOIN:
2321  if (!(flags & QTW_IGNORE_JOINALIASES))
2322  if (walker(rte->joinaliasvars, context))
2323  return true;
2324  break;
2325  case RTE_FUNCTION:
2326  if (walker(rte->functions, context))
2327  return true;
2328  break;
2329  case RTE_TABLEFUNC:
2330  if (walker(rte->tablefunc, context))
2331  return true;
2332  break;
2333  case RTE_VALUES:
2334  if (walker(rte->values_lists, context))
2335  return true;
2336  break;
2337  }
2338 
2339  if (walker(rte->securityQuals, context))
2340  return true;
2341  }
2342  return false;
2343 }
List * joinaliasvars
Definition: parsenodes.h:995
List * securityQuals
Definition: parsenodes.h:1064
List * values_lists
Definition: parsenodes.h:1016