PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
nodeFuncs.c File Reference
#include "postgres.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_type.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "nodes/execnodes.h"
#include "nodes/nodeFuncs.h"
#include "nodes/relation.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
Include dependency graph for nodeFuncs.c:

Go to the source code of this file.

Macros

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

Functions

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

Macro Definition Documentation

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

Referenced by range_table_mutator().

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

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

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

Function Documentation

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

Definition at line 1660 of file nodeFuncs.c.

References Aggref::aggfnoid, CoerceViaIO::arg, ArrayCoerceExpr::elemfuncid, exprType(), FuncExpr::funcid, get_opcode(), getTypeInputInfo(), getTypeOutputInfo(), lfirst_oid, nodeTag, OidIsValid, OpExpr::opfuncid, ScalarArrayOpExpr::opfuncid, RowCompareExpr::opnos, CoerceViaIO::resulttype, set_opfuncid(), set_sa_opfuncid(), T_Aggref, T_ArrayCoerceExpr, 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().

1662 {
1663  switch (nodeTag(node))
1664  {
1665  case T_Aggref:
1666  {
1667  Aggref *expr = (Aggref *) node;
1668 
1669  if (checker(expr->aggfnoid, context))
1670  return true;
1671  }
1672  break;
1673  case T_WindowFunc:
1674  {
1675  WindowFunc *expr = (WindowFunc *) node;
1676 
1677  if (checker(expr->winfnoid, context))
1678  return true;
1679  }
1680  break;
1681  case T_FuncExpr:
1682  {
1683  FuncExpr *expr = (FuncExpr *) node;
1684 
1685  if (checker(expr->funcid, context))
1686  return true;
1687  }
1688  break;
1689  case T_OpExpr:
1690  case T_DistinctExpr: /* struct-equivalent to OpExpr */
1691  case T_NullIfExpr: /* struct-equivalent to OpExpr */
1692  {
1693  OpExpr *expr = (OpExpr *) node;
1694 
1695  /* Set opfuncid if it wasn't set already */
1696  set_opfuncid(expr);
1697  if (checker(expr->opfuncid, context))
1698  return true;
1699  }
1700  break;
1701  case T_ScalarArrayOpExpr:
1702  {
1703  ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
1704 
1705  set_sa_opfuncid(expr);
1706  if (checker(expr->opfuncid, context))
1707  return true;
1708  }
1709  break;
1710  case T_CoerceViaIO:
1711  {
1712  CoerceViaIO *expr = (CoerceViaIO *) node;
1713  Oid iofunc;
1714  Oid typioparam;
1715  bool typisvarlena;
1716 
1717  /* check the result type's input function */
1719  &iofunc, &typioparam);
1720  if (checker(iofunc, context))
1721  return true;
1722  /* check the input type's output function */
1723  getTypeOutputInfo(exprType((Node *) expr->arg),
1724  &iofunc, &typisvarlena);
1725  if (checker(iofunc, context))
1726  return true;
1727  }
1728  break;
1729  case T_ArrayCoerceExpr:
1730  {
1731  ArrayCoerceExpr *expr = (ArrayCoerceExpr *) node;
1732 
1733  if (OidIsValid(expr->elemfuncid) &&
1734  checker(expr->elemfuncid, context))
1735  return true;
1736  }
1737  break;
1738  case T_RowCompareExpr:
1739  {
1740  RowCompareExpr *rcexpr = (RowCompareExpr *) node;
1741  ListCell *opid;
1742 
1743  foreach(opid, rcexpr->opnos)
1744  {
1745  Oid opfuncid = get_opcode(lfirst_oid(opid));
1746 
1747  if (checker(opfuncid, context))
1748  return true;
1749  }
1750  }
1751  break;
1752  default:
1753  break;
1754  }
1755  return false;
1756 }
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2600
Oid resulttype
Definition: primnodes.h:788
Definition: nodes.h:508
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:534
Oid funcid
Definition: primnodes.h:426
Oid winfnoid
Definition: primnodes.h:333
Expr * arg
Definition: primnodes.h:787
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
Definition: lsyscache.c:2567
Oid opfuncid
Definition: primnodes.h:474
RegProcedure get_opcode(Oid opno)
Definition: lsyscache.c:1062
Oid aggfnoid
Definition: primnodes.h:272
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
#define nodeTag(nodeptr)
Definition: nodes.h:513
void set_opfuncid(OpExpr *opexpr)
Definition: nodeFuncs.c:1622
void set_sa_opfuncid(ScalarArrayOpExpr *opexpr)
Definition: nodeFuncs.c:1633
#define lfirst_oid(lc)
Definition: pg_list.h:108
Oid exprCollation ( const Node expr)

Definition at line 745 of file nodeFuncs.c.

References arg, ARRAY_SUBLINK, Assert, castNode, DEFAULT_COLLATION_OID, elog, ERROR, EXPR_SUBLINK, exprCollation(), SubPlan::firstColCollation, InvalidOid, IS_XMLSERIALIZE, IsA, linitial, 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_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().

746 {
747  Oid coll;
748 
749  if (!expr)
750  return InvalidOid;
751 
752  switch (nodeTag(expr))
753  {
754  case T_Var:
755  coll = ((const Var *) expr)->varcollid;
756  break;
757  case T_Const:
758  coll = ((const Const *) expr)->constcollid;
759  break;
760  case T_Param:
761  coll = ((const Param *) expr)->paramcollid;
762  break;
763  case T_Aggref:
764  coll = ((const Aggref *) expr)->aggcollid;
765  break;
766  case T_GroupingFunc:
767  coll = InvalidOid;
768  break;
769  case T_WindowFunc:
770  coll = ((const WindowFunc *) expr)->wincollid;
771  break;
772  case T_ArrayRef:
773  coll = ((const ArrayRef *) expr)->refcollid;
774  break;
775  case T_FuncExpr:
776  coll = ((const FuncExpr *) expr)->funccollid;
777  break;
778  case T_NamedArgExpr:
779  coll = exprCollation((Node *) ((const NamedArgExpr *) expr)->arg);
780  break;
781  case T_OpExpr:
782  coll = ((const OpExpr *) expr)->opcollid;
783  break;
784  case T_DistinctExpr:
785  coll = ((const DistinctExpr *) expr)->opcollid;
786  break;
787  case T_NullIfExpr:
788  coll = ((const NullIfExpr *) expr)->opcollid;
789  break;
790  case T_ScalarArrayOpExpr:
791  coll = InvalidOid; /* result is always boolean */
792  break;
793  case T_BoolExpr:
794  coll = InvalidOid; /* result is always boolean */
795  break;
796  case T_SubLink:
797  {
798  const SubLink *sublink = (const SubLink *) expr;
799 
800  if (sublink->subLinkType == EXPR_SUBLINK ||
801  sublink->subLinkType == ARRAY_SUBLINK)
802  {
803  /* get the collation of subselect's first target column */
804  Query *qtree = (Query *) sublink->subselect;
805  TargetEntry *tent;
806 
807  if (!qtree || !IsA(qtree, Query))
808  elog(ERROR, "cannot get collation for untransformed sublink");
809  tent = castNode(TargetEntry, linitial(qtree->targetList));
810  Assert(!tent->resjunk);
811  coll = exprCollation((Node *) tent->expr);
812  /* collation doesn't change if it's converted to array */
813  }
814  else
815  {
816  /* otherwise, result is RECORD or BOOLEAN */
817  coll = InvalidOid;
818  }
819  }
820  break;
821  case T_SubPlan:
822  {
823  const SubPlan *subplan = (const SubPlan *) expr;
824 
825  if (subplan->subLinkType == EXPR_SUBLINK ||
826  subplan->subLinkType == ARRAY_SUBLINK)
827  {
828  /* get the collation of subselect's first target column */
829  coll = subplan->firstColCollation;
830  /* collation doesn't change if it's converted to array */
831  }
832  else
833  {
834  /* otherwise, result is RECORD or BOOLEAN */
835  coll = InvalidOid;
836  }
837  }
838  break;
840  {
841  const AlternativeSubPlan *asplan = (const AlternativeSubPlan *) expr;
842 
843  /* subplans should all return the same thing */
844  coll = exprCollation((Node *) linitial(asplan->subplans));
845  }
846  break;
847  case T_FieldSelect:
848  coll = ((const FieldSelect *) expr)->resultcollid;
849  break;
850  case T_FieldStore:
851  coll = InvalidOid; /* result is always composite */
852  break;
853  case T_RelabelType:
854  coll = ((const RelabelType *) expr)->resultcollid;
855  break;
856  case T_CoerceViaIO:
857  coll = ((const CoerceViaIO *) expr)->resultcollid;
858  break;
859  case T_ArrayCoerceExpr:
860  coll = ((const ArrayCoerceExpr *) expr)->resultcollid;
861  break;
863  coll = InvalidOid; /* result is always composite */
864  break;
865  case T_CollateExpr:
866  coll = ((const CollateExpr *) expr)->collOid;
867  break;
868  case T_CaseExpr:
869  coll = ((const CaseExpr *) expr)->casecollid;
870  break;
871  case T_CaseTestExpr:
872  coll = ((const CaseTestExpr *) expr)->collation;
873  break;
874  case T_ArrayExpr:
875  coll = ((const ArrayExpr *) expr)->array_collid;
876  break;
877  case T_RowExpr:
878  coll = InvalidOid; /* result is always composite */
879  break;
880  case T_RowCompareExpr:
881  coll = InvalidOid; /* result is always boolean */
882  break;
883  case T_CoalesceExpr:
884  coll = ((const CoalesceExpr *) expr)->coalescecollid;
885  break;
886  case T_MinMaxExpr:
887  coll = ((const MinMaxExpr *) expr)->minmaxcollid;
888  break;
889  case T_SQLValueFunction:
890  coll = InvalidOid; /* all cases return non-collatable types */
891  break;
892  case T_XmlExpr:
893 
894  /*
895  * XMLSERIALIZE returns text from non-collatable inputs, so its
896  * collation is always default. The other cases return boolean or
897  * XML, which are non-collatable.
898  */
899  if (((const XmlExpr *) expr)->op == IS_XMLSERIALIZE)
900  coll = DEFAULT_COLLATION_OID;
901  else
902  coll = InvalidOid;
903  break;
904  case T_NullTest:
905  coll = InvalidOid; /* result is always boolean */
906  break;
907  case T_BooleanTest:
908  coll = InvalidOid; /* result is always boolean */
909  break;
910  case T_CoerceToDomain:
911  coll = ((const CoerceToDomain *) expr)->resultcollid;
912  break;
914  coll = ((const CoerceToDomainValue *) expr)->collation;
915  break;
916  case T_SetToDefault:
917  coll = ((const SetToDefault *) expr)->collation;
918  break;
919  case T_CurrentOfExpr:
920  coll = InvalidOid; /* result is always boolean */
921  break;
922  case T_InferenceElem:
923  coll = exprCollation((Node *) ((const InferenceElem *) expr)->expr);
924  break;
925  case T_PlaceHolderVar:
926  coll = exprCollation((Node *) ((const PlaceHolderVar *) expr)->phexpr);
927  break;
928  default:
929  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
930  coll = InvalidOid; /* keep compiler quiet */
931  break;
932  }
933  return coll;
934 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:559
#define castNode(_type_, nodeptr)
Definition: nodes.h:577
SubLinkType subLinkType
Definition: primnodes.h:661
Definition: nodes.h:508
unsigned int Oid
Definition: postgres_ext.h:31
Definition: primnodes.h:141
List * targetList
Definition: parsenodes.h:131
#define linitial(l)
Definition: pg_list.h:110
#define ERROR
Definition: elog.h:43
#define DEFAULT_COLLATION_OID
Definition: pg_collation.h:68
Definition: nodes.h:140
Definition: nodes.h:139
#define InvalidOid
Definition: postgres_ext.h:36
#define Assert(condition)
Definition: c.h:671
Oid exprCollation(const Node *expr)
Definition: nodeFuncs.c:745
#define nodeTag(nodeptr)
Definition: nodes.h:513
void * arg
Oid firstColCollation
Definition: primnodes.h:672
#define elog
Definition: elog.h:219
Definition: nodes.h:141
bool expression_returns_set ( Node clause)
static bool expression_returns_set_walker ( Node node,
void *  context 
)
static

Definition at line 673 of file nodeFuncs.c.

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

Referenced by expression_returns_set().

674 {
675  if (node == NULL)
676  return false;
677  if (IsA(node, FuncExpr))
678  {
679  FuncExpr *expr = (FuncExpr *) node;
680 
681  if (expr->funcretset)
682  return true;
683  /* else fall through to check args */
684  }
685  if (IsA(node, OpExpr))
686  {
687  OpExpr *expr = (OpExpr *) node;
688 
689  if (expr->opretset)
690  return true;
691  /* else fall through to check args */
692  }
693 
694  /* Avoid recursion for some cases that can't return a set */
695  if (IsA(node, Aggref))
696  return false;
697  if (IsA(node, WindowFunc))
698  return false;
699  if (IsA(node, DistinctExpr))
700  return false;
701  if (IsA(node, NullIfExpr))
702  return false;
703  if (IsA(node, ScalarArrayOpExpr))
704  return false;
705  if (IsA(node, BoolExpr))
706  return false;
707  if (IsA(node, SubLink))
708  return false;
709  if (IsA(node, SubPlan))
710  return false;
711  if (IsA(node, AlternativeSubPlan))
712  return false;
713  if (IsA(node, ArrayExpr))
714  return false;
715  if (IsA(node, RowExpr))
716  return false;
717  if (IsA(node, RowCompareExpr))
718  return false;
719  if (IsA(node, CoalesceExpr))
720  return false;
721  if (IsA(node, MinMaxExpr))
722  return false;
723  if (IsA(node, SQLValueFunction))
724  return false;
725  if (IsA(node, XmlExpr))
726  return false;
727 
729  context);
730 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:559
static bool expression_returns_set_walker(Node *node, void *context)
Definition: nodeFuncs.c:673
bool funcretset
Definition: primnodes.h:428
#define NULL
Definition: c.h:226
bool expression_tree_walker(Node *node, bool(*walker)(), void *context)
Definition: nodeFuncs.c:1852
bool opretset
Definition: primnodes.h:476
Node* expression_tree_mutator ( Node node,
Node *(*)()  mutator,
void *  context 
)

Definition at line 2397 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, TableSampleClause::args, CoalesceExpr::args, MinMaxExpr::args, XmlExpr::args, check_stack_depth(), GroupingFunc::cols, copyObject(), CommonTableExpr::ctequery, CaseExpr::defresult, ArrayExpr::elements, 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, NULL, 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, 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_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_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().

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

Definition at line 1852 of file nodeFuncs.c.

References Aggref::aggdirectargs, Aggref::aggdistinct, Aggref::aggfilter, WindowFunc::aggfilter, Aggref::aggorder, OnConflictExpr::arbiterElems, OnConflictExpr::arbiterWhere, arg, FieldStore::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, castNode, check_stack_depth(), CommonTableExpr::ctequery, CaseExpr::defresult, elog, WindowClause::endOffset, ERROR, OnConflictExpr::exclRelTlist, CaseWhen::expr, expression_tree_walker(), FromExpr::fromlist, JoinExpr::larg, SetOperationStmt::larg, RowCompareExpr::largs, lfirst, XmlExpr::named_args, FieldStore::newvals, nodeTag, NULL, 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, 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_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_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(), 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().

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

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

944 {
945  Oid coll;
946 
947  if (!expr)
948  return InvalidOid;
949 
950  switch (nodeTag(expr))
951  {
952  case T_Aggref:
953  coll = ((const Aggref *) expr)->inputcollid;
954  break;
955  case T_WindowFunc:
956  coll = ((const WindowFunc *) expr)->inputcollid;
957  break;
958  case T_FuncExpr:
959  coll = ((const FuncExpr *) expr)->inputcollid;
960  break;
961  case T_OpExpr:
962  coll = ((const OpExpr *) expr)->inputcollid;
963  break;
964  case T_DistinctExpr:
965  coll = ((const DistinctExpr *) expr)->inputcollid;
966  break;
967  case T_NullIfExpr:
968  coll = ((const NullIfExpr *) expr)->inputcollid;
969  break;
970  case T_ScalarArrayOpExpr:
971  coll = ((const ScalarArrayOpExpr *) expr)->inputcollid;
972  break;
973  case T_MinMaxExpr:
974  coll = ((const MinMaxExpr *) expr)->inputcollid;
975  break;
976  default:
977  coll = InvalidOid;
978  break;
979  }
980  return coll;
981 }
unsigned int Oid
Definition: postgres_ext.h:31
#define InvalidOid
Definition: postgres_ext.h:36
#define nodeTag(nodeptr)
Definition: nodes.h:513
bool exprIsLengthCoercion ( const Node expr,
int32 coercedTypmod 
)

Definition at line 510 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, NULL, and ArrayCoerceExpr::resulttypmod.

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

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

Definition at line 1204 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, NULL, 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_PartitionRangeDatum, 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_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(), checkWellFormedRecursion(), coerce_to_boolean(), coerce_to_common_type(), coerce_to_specific_type(), exprLocation(), finalize_grouping_exprs_walker(), get_matching_location(), parseCheckAggregates(), ParseFuncOrColumn(), parser_coercion_errposition(), resolve_unique_index_expr(), select_common_type(), transformAExprOf(), transformAggregateCall(), transformArrayExpr(), transformArraySubscripts(), transformAssignedExpr(), transformDistinctClause(), transformDistinctOnClause(), transformFromClauseItem(), transformGroupClause(), transformGroupClauseExpr(), transformGroupingSet(), transformIndirection(), transformInsertRow(), transformInsertStmt(), transformMultiAssignRef(), transformOnConflictArbiter(), transformPartitionBound(), transformRangeFunction(), transformReturningList(), transformSelectStmt(), transformSetOperationStmt(), transformSetOperationTree(), and transformValuesClause().

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

Definition at line 991 of file nodeFuncs.c.

References arg, ARRAY_SUBLINK, Assert, castNode, DEFAULT_COLLATION_OID, elog, ERROR, EXPR_SUBLINK, exprCollation(), InvalidOid, IS_XMLSERIALIZE, IsA, linitial, 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_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().

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

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

1141 {
1142  switch (nodeTag(expr))
1143  {
1144  case T_Aggref:
1145  ((Aggref *) expr)->inputcollid = inputcollation;
1146  break;
1147  case T_WindowFunc:
1148  ((WindowFunc *) expr)->inputcollid = inputcollation;
1149  break;
1150  case T_FuncExpr:
1151  ((FuncExpr *) expr)->inputcollid = inputcollation;
1152  break;
1153  case T_OpExpr:
1154  ((OpExpr *) expr)->inputcollid = inputcollation;
1155  break;
1156  case T_DistinctExpr:
1157  ((DistinctExpr *) expr)->inputcollid = inputcollation;
1158  break;
1159  case T_NullIfExpr:
1160  ((NullIfExpr *) expr)->inputcollid = inputcollation;
1161  break;
1162  case T_ScalarArrayOpExpr:
1163  ((ScalarArrayOpExpr *) expr)->inputcollid = inputcollation;
1164  break;
1165  case T_MinMaxExpr:
1166  ((MinMaxExpr *) expr)->inputcollid = inputcollation;
1167  break;
1168  default:
1169  break;
1170  }
1171 }
#define nodeTag(nodeptr)
Definition: nodes.h:513
Oid exprType ( const Node expr)

Definition at line 42 of file nodeFuncs.c.

References arg, ARRAY_SUBLINK, Assert, BOOLOID, castNode, 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, 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_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, and XMLOID.

Referenced by addTargetToGroupList(), addTargetToSortList(), analyzeCTE(), analyzeCTETargetList(), appendAggOrderBy(), assign_collations_walker(), assign_hypothetical_collations(), assign_nestloop_param_placeholdervar(), ATExecAlterColumnType(), ATPrepAlterColumnType(), 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(), 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_simple_recheck_plan(), ExecCheckPlanOutput(), ExecEvalConvertRowtype(), ExecEvalXml(), ExecInitExpr(), ExecInitIndexScan(), ExecMakeTableFunctionResult(), ExecTypeFromExprList(), ExecTypeFromTLInternal(), ExecWindowAgg(), expandRecordVariable(), ExpandRowReference(), expandRTE(), exprType(), exprTypmod(), 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_type(), get_first_col_type(), get_fn_expr_rettype(), get_func_expr(), get_name_for_var_field(), get_oper_expr(), get_rte_attribute_type(), get_rule_expr(), 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(), transformPartitionBound(), 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 = castNode(TargetEntry, linitial(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_InferenceElem:
250  {
251  const InferenceElem *n = (const InferenceElem *) expr;
252 
253  type = exprType((Node *) n->expr);
254  }
255  break;
256  case T_PlaceHolderVar:
257  type = exprType((Node *) ((const PlaceHolderVar *) expr)->phexpr);
258  break;
259  default:
260  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
261  type = InvalidOid; /* keep compiler quiet */
262  break;
263  }
264  return type;
265 }
Oid firstColType
Definition: primnodes.h:670
Expr * refassgnexpr
Definition: primnodes.h:387
#define IsA(nodeptr, _type_)
Definition: nodes.h:559
#define castNode(_type_, nodeptr)
Definition: nodes.h:577
#define TEXTOID
Definition: pg_type.h:324
SubLinkType subLinkType
Definition: primnodes.h:661
#define INT4OID
Definition: pg_type.h:316
Definition: nodes.h:508
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:141
#define OidIsValid(objectId)
Definition: c.h:534
List * targetList
Definition: parsenodes.h:131
#define linitial(l)
Definition: pg_list.h:110
#define ERROR
Definition: elog.h:43
#define XMLOID
Definition: pg_type.h:359
List * reflowerindexpr
Definition: primnodes.h:383
#define RECORDOID
Definition: pg_type.h:668
#define ereport(elevel, rest)
Definition: elog.h:122
Definition: nodes.h:140
Definition: nodes.h:139
Oid get_promoted_array_type(Oid typid)
Definition: lsyscache.c:2504
Oid refelemtype
Definition: primnodes.h:378
#define InvalidOid
Definition: postgres_ext.h:36
#define Assert(condition)
Definition: c.h:671
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
#define BOOLOID
Definition: pg_type.h:288
#define nodeTag(nodeptr)
Definition: nodes.h:513
Oid refarraytype
Definition: primnodes.h:377
int errmsg(const char *fmt,...)
Definition: elog.c:797
void * arg
#define elog
Definition: elog.h:219
Definition: nodes.h:141
int32 exprTypmod ( const Node expr)

Definition at line 273 of file nodeFuncs.c.

References arg, OpExpr::args, CaseExpr::args, CoalesceExpr::args, MinMaxExpr::args, ARRAY_SUBLINK, ArrayExpr::array_typeid, Assert, CaseExpr::casetype, castNode, CoalesceExpr::coalescetype, CaseExpr::defresult, ArrayExpr::element_typeid, ArrayExpr::elements, elog, ERROR, EXPR_SUBLINK, exprIsLengthCoercion(), exprType(), exprTypmod(), SubPlan::firstColTypmod, for_each_cell, IsA, lfirst, linitial, 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_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_simple_recheck_plan(), ExecTypeFromExprList(), ExecTypeFromTLInternal(), expandRecordVariable(), ExpandRowReference(), expandRTE(), exprTypmod(), find_placeholder_info(), generate_append_tlist(), generate_setop_tlist(), generate_subquery_params(), get_agg_clause_costs_walker(), get_first_col_type(), get_name_for_var_field(), get_rte_attribute_type(), get_rule_expr(), 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(), transformMultiAssignRef(), transformSetOperationTree(), transformSubLink(), transformValuesClause(), varbit_transform(), and varchar_transform().

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

Definition at line 1591 of file nodeFuncs.c.

References fix_opfuncids_walker(), and NULL.

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

1592 {
1593  /* This tree walk requires no special setup, so away we go... */
1594  fix_opfuncids_walker(node, NULL);
1595 }
static bool fix_opfuncids_walker(Node *node, void *context)
Definition: nodeFuncs.c:1598
#define NULL
Definition: c.h:226
static bool fix_opfuncids_walker ( Node node,
void *  context 
)
static

Definition at line 1598 of file nodeFuncs.c.

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

Referenced by fix_opfuncids().

1599 {
1600  if (node == NULL)
1601  return false;
1602  if (IsA(node, OpExpr))
1603  set_opfuncid((OpExpr *) node);
1604  else if (IsA(node, DistinctExpr))
1605  set_opfuncid((OpExpr *) node); /* rely on struct equivalence */
1606  else if (IsA(node, NullIfExpr))
1607  set_opfuncid((OpExpr *) node); /* rely on struct equivalence */
1608  else if (IsA(node, ScalarArrayOpExpr))
1610  return expression_tree_walker(node, fix_opfuncids_walker, context);
1611 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:559
static bool fix_opfuncids_walker(Node *node, void *context)
Definition: nodeFuncs.c:1598
#define NULL
Definition: c.h:226
bool expression_tree_walker(Node *node, bool(*walker)(), void *context)
Definition: nodeFuncs.c:1852
void set_opfuncid(OpExpr *opexpr)
Definition: nodeFuncs.c:1622
void set_sa_opfuncid(ScalarArrayOpExpr *opexpr)
Definition: nodeFuncs.c:1633
static int leftmostLoc ( int  loc1,
int  loc2 
)
static

Definition at line 1570 of file nodeFuncs.c.

References Min.

Referenced by exprLocation().

1571 {
1572  if (loc1 < 0)
1573  return loc2;
1574  else if (loc2 < 0)
1575  return loc1;
1576  else
1577  return Min(loc1, loc2);
1578 }
#define Min(x, y)
Definition: c.h:802
bool planstate_tree_walker ( PlanState planstate,
bool(*)()  walker,
void *  context 
)

Definition at line 3639 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(), ExecParallelReportInstrumentation(), ExecParallelRetrieveInstrumentation(), ExecShutdownNode(), and ExplainPreScanNode().

3642 {
3643  Plan *plan = planstate->plan;
3644  ListCell *lc;
3645 
3646  /* initPlan-s */
3647  if (planstate_walk_subplans(planstate->initPlan, walker, context))
3648  return true;
3649 
3650  /* lefttree */
3651  if (outerPlanState(planstate))
3652  {
3653  if (walker(outerPlanState(planstate), context))
3654  return true;
3655  }
3656 
3657  /* righttree */
3658  if (innerPlanState(planstate))
3659  {
3660  if (walker(innerPlanState(planstate), context))
3661  return true;
3662  }
3663 
3664  /* special child plans */
3665  switch (nodeTag(plan))
3666  {
3667  case T_ModifyTable:
3668  if (planstate_walk_members(((ModifyTable *) plan)->plans,
3669  ((ModifyTableState *) planstate)->mt_plans,
3670  walker, context))
3671  return true;
3672  break;
3673  case T_Append:
3674  if (planstate_walk_members(((Append *) plan)->appendplans,
3675  ((AppendState *) planstate)->appendplans,
3676  walker, context))
3677  return true;
3678  break;
3679  case T_MergeAppend:
3680  if (planstate_walk_members(((MergeAppend *) plan)->mergeplans,
3681  ((MergeAppendState *) planstate)->mergeplans,
3682  walker, context))
3683  return true;
3684  break;
3685  case T_BitmapAnd:
3686  if (planstate_walk_members(((BitmapAnd *) plan)->bitmapplans,
3687  ((BitmapAndState *) planstate)->bitmapplans,
3688  walker, context))
3689  return true;
3690  break;
3691  case T_BitmapOr:
3692  if (planstate_walk_members(((BitmapOr *) plan)->bitmapplans,
3693  ((BitmapOrState *) planstate)->bitmapplans,
3694  walker, context))
3695  return true;
3696  break;
3697  case T_SubqueryScan:
3698  if (walker(((SubqueryScanState *) planstate)->subplan, context))
3699  return true;
3700  break;
3701  case T_CustomScan:
3702  foreach(lc, ((CustomScanState *) planstate)->custom_ps)
3703  {
3704  if (walker((PlanState *) lfirst(lc), context))
3705  return true;
3706  }
3707  break;
3708  default:
3709  break;
3710  }
3711 
3712  /* subPlan-s */
3713  if (planstate_walk_subplans(planstate->subPlan, walker, context))
3714  return true;
3715 
3716  return false;
3717 }
List * initPlan
Definition: execnodes.h:1065
List * subPlan
Definition: execnodes.h:1067
Definition: nodes.h:48
#define outerPlanState(node)
Definition: execnodes.h:1090
static bool planstate_walk_subplans(List *plans, bool(*walker)(), void *context)
Definition: nodeFuncs.c:3723
Plan * plan
Definition: execnodes.h:1047
#define lfirst(lc)
Definition: pg_list.h:106
#define nodeTag(nodeptr)
Definition: nodes.h:513
static bool planstate_walk_members(List *plans, PlanState **planstates, bool(*walker)(), void *context)
Definition: nodeFuncs.c:3748
#define innerPlanState(node)
Definition: execnodes.h:1089
static bool planstate_walk_members ( List plans,
PlanState **  planstates,
bool(*)()  walker,
void *  context 
)
static

Definition at line 3748 of file nodeFuncs.c.

References list_length().

Referenced by planstate_tree_walker().

3750 {
3751  int nplans = list_length(plans);
3752  int j;
3753 
3754  for (j = 0; j < nplans; j++)
3755  {
3756  if (walker(planstates[j], context))
3757  return true;
3758  }
3759 
3760  return false;
3761 }
static int list_length(const List *l)
Definition: pg_list.h:89
static bool planstate_walk_subplans ( List plans,
bool(*)()  walker,
void *  context 
)
static

Definition at line 3723 of file nodeFuncs.c.

References castNode, lfirst, and SubPlanState::planstate.

Referenced by planstate_tree_walker().

3726 {
3727  ListCell *lc;
3728 
3729  foreach(lc, plans)
3730  {
3732 
3733  if (walker(sps->planstate, context))
3734  return true;
3735  }
3736 
3737  return false;
3738 }
#define castNode(_type_, nodeptr)
Definition: nodes.h:577
struct PlanState * planstate
Definition: execnodes.h:786
#define lfirst(lc)
Definition: pg_list.h:106
Node* query_or_expression_tree_mutator ( Node node,
Node *(*)()  mutator,
void *  context,
int  flags 
)

Definition at line 3169 of file nodeFuncs.c.

References IsA, and query_tree_mutator().

Referenced by map_variable_attnos(), and replace_rte_variables().

3173 {
3174  if (node && IsA(node, Query))
3175  return (Node *) query_tree_mutator((Query *) node,
3176  mutator,
3177  context,
3178  flags);
3179  else
3180  return mutator(node, context);
3181 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:559
Definition: nodes.h:508
Query * query_tree_mutator(Query *query, Node *(*mutator)(), void *context, int flags)
Definition: nodeFuncs.c:3040
bool query_or_expression_tree_walker ( Node node,
bool(*)()  walker,
void *  context,
int  flags 
)

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

3150 {
3151  if (node && IsA(node, Query))
3152  return query_tree_walker((Query *) node,
3153  walker,
3154  context,
3155  flags);
3156  else
3157  return walker(node, context);
3158 }
bool query_tree_walker(Query *query, bool(*walker)(), void *context, int flags)
Definition: nodeFuncs.c:2238
#define IsA(nodeptr, _type_)
Definition: nodes.h:559
Query* query_tree_mutator ( Query query,
Node *(*)()  mutator,
void *  context,
int  flags 
)

Definition at line 3040 of file nodeFuncs.c.

References Assert, copyObject(), Query::cteList, FLATCOPY, Query::havingQual, IsA, Query::jointree, Query::limitCount, Query::limitOffset, MUTATE, NULL, 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().

3044 {
3045  Assert(query != NULL && IsA(query, Query));
3046 
3047  if (!(flags & QTW_DONT_COPY_QUERY))
3048  {
3049  Query *newquery;
3050 
3051  FLATCOPY(newquery, query, Query);
3052  query = newquery;
3053  }
3054 
3055  MUTATE(query->targetList, query->targetList, List *);
3056  MUTATE(query->withCheckOptions, query->withCheckOptions, List *);
3057  MUTATE(query->onConflict, query->onConflict, OnConflictExpr *);
3058  MUTATE(query->returningList, query->returningList, List *);
3059  MUTATE(query->jointree, query->jointree, FromExpr *);
3060  MUTATE(query->setOperations, query->setOperations, Node *);
3061  MUTATE(query->havingQual, query->havingQual, Node *);
3062  MUTATE(query->limitOffset, query->limitOffset, Node *);
3063  MUTATE(query->limitCount, query->limitCount, Node *);
3064  if (!(flags & QTW_IGNORE_CTE_SUBQUERIES))
3065  MUTATE(query->cteList, query->cteList, List *);
3066  else /* else copy CTE list as-is */
3067  query->cteList = copyObject(query->cteList);
3068  query->rtable = range_table_mutator(query->rtable,
3069  mutator, context, flags);
3070  return query;
3071 }
Node * limitOffset
Definition: parsenodes.h:149
#define IsA(nodeptr, _type_)
Definition: nodes.h:559
FromExpr * jointree
Definition: parsenodes.h:129
OnConflictExpr * onConflict
Definition: parsenodes.h:133
List * withCheckOptions
Definition: parsenodes.h:160
Definition: nodes.h:508
#define QTW_DONT_COPY_QUERY
Definition: nodeFuncs.h:26
List * targetList
Definition: parsenodes.h:131
void * copyObject(const void *from)
Definition: copyfuncs.c:4475
#define QTW_IGNORE_CTE_SUBQUERIES
Definition: nodeFuncs.h:21
List * rtable
Definition: parsenodes.h:128
Node * limitCount
Definition: parsenodes.h:150
List * returningList
Definition: parsenodes.h:135
#define FLATCOPY(newnode, node, nodetype)
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
List * cteList
Definition: parsenodes.h:126
Node * setOperations
Definition: parsenodes.h:154
List * range_table_mutator(List *rtable, Node *(*mutator)(), void *context, int flags)
Definition: nodeFuncs.c:3079
Node * havingQual
Definition: parsenodes.h:141
Definition: pg_list.h:45
#define MUTATE(newfield, oldfield, fieldtype)
bool query_tree_walker ( Query query,
bool(*)()  walker,
void *  context,
int  flags 
)

Definition at line 2238 of file nodeFuncs.c.

References Assert, Query::cteList, Query::havingQual, IsA, Query::jointree, Query::limitCount, Query::limitOffset, NULL, 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().

2242 {
2243  Assert(query != NULL && IsA(query, Query));
2244 
2245  if (walker((Node *) query->targetList, context))
2246  return true;
2247  if (walker((Node *) query->withCheckOptions, context))
2248  return true;
2249  if (walker((Node *) query->onConflict, context))
2250  return true;
2251  if (walker((Node *) query->returningList, context))
2252  return true;
2253  if (walker((Node *) query->jointree, context))
2254  return true;
2255  if (walker(query->setOperations, context))
2256  return true;
2257  if (walker(query->havingQual, context))
2258  return true;
2259  if (walker(query->limitOffset, context))
2260  return true;
2261  if (walker(query->limitCount, context))
2262  return true;
2263  if (!(flags & QTW_IGNORE_CTE_SUBQUERIES))
2264  {
2265  if (walker((Node *) query->cteList, context))
2266  return true;
2267  }
2268  if (!(flags & QTW_IGNORE_RANGE_TABLE))
2269  {
2270  if (range_table_walker(query->rtable, walker, context, flags))
2271  return true;
2272  }
2273  return false;
2274 }
Node * limitOffset
Definition: parsenodes.h:149
#define IsA(nodeptr, _type_)
Definition: nodes.h:559
FromExpr * jointree
Definition: parsenodes.h:129
OnConflictExpr * onConflict
Definition: parsenodes.h:133
List * withCheckOptions
Definition: parsenodes.h:160
Definition: nodes.h:508
List * targetList
Definition: parsenodes.h:131
#define QTW_IGNORE_CTE_SUBQUERIES
Definition: nodeFuncs.h:21
List * rtable
Definition: parsenodes.h:128
Node * limitCount
Definition: parsenodes.h:150
List * returningList
Definition: parsenodes.h:135
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
bool range_table_walker(List *rtable, bool(*walker)(), void *context, int flags)
Definition: nodeFuncs.c:2282
List * cteList
Definition: parsenodes.h:126
Node * setOperations
Definition: parsenodes.h:154
#define QTW_IGNORE_RANGE_TABLE
Definition: nodeFuncs.h:24
Node * havingQual
Definition: parsenodes.h:141
List* range_table_mutator ( List rtable,
Node *(*)()  mutator,
void *  context,
int  flags 
)

Definition at line 3079 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_RELATION, RTE_SUBQUERY, RTE_VALUES, RangeTblEntry::rtekind, RangeTblEntry::securityQuals, RangeTblEntry::subquery, RangeTblEntry::tablesample, and RangeTblEntry::values_lists.

Referenced by query_tree_mutator().

3083 {
3084  List *newrt = NIL;
3085  ListCell *rt;
3086 
3087  foreach(rt, rtable)
3088  {
3089  RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
3090  RangeTblEntry *newrte;
3091 
3092  FLATCOPY(newrte, rte, RangeTblEntry);
3093  switch (rte->rtekind)
3094  {
3095  case RTE_RELATION:
3096  MUTATE(newrte->tablesample, rte->tablesample,
3097  TableSampleClause *);
3098  /* we don't bother to copy eref, aliases, etc; OK? */
3099  break;
3100  case RTE_CTE:
3101  /* nothing to do */
3102  break;
3103  case RTE_SUBQUERY:
3104  if (!(flags & QTW_IGNORE_RT_SUBQUERIES))
3105  {
3106  CHECKFLATCOPY(newrte->subquery, rte->subquery, Query);
3107  MUTATE(newrte->subquery, newrte->subquery, Query *);
3108  }
3109  else
3110  {
3111  /* else, copy RT subqueries as-is */
3112  newrte->subquery = copyObject(rte->subquery);
3113  }
3114  break;
3115  case RTE_JOIN:
3116  if (!(flags & QTW_IGNORE_JOINALIASES))
3117  MUTATE(newrte->joinaliasvars, rte->joinaliasvars, List *);
3118  else
3119  {
3120  /* else, copy join aliases as-is */
3121  newrte->joinaliasvars = copyObject(rte->joinaliasvars);
3122  }
3123  break;
3124  case RTE_FUNCTION:
3125  MUTATE(newrte->functions, rte->functions, List *);
3126  break;
3127  case RTE_VALUES:
3128  MUTATE(newrte->values_lists, rte->values_lists, List *);
3129  break;
3130  }
3131  MUTATE(newrte->securityQuals, rte->securityQuals, List *);
3132  newrt = lappend(newrt, newrte);
3133  }
3134  return newrt;
3135 }
#define NIL
Definition: pg_list.h:69
List * joinaliasvars
Definition: parsenodes.h:921
#define CHECKFLATCOPY(newnode, node, nodetype)
List * securityQuals
Definition: parsenodes.h:970
List * values_lists
Definition: parsenodes.h:937
void * copyObject(const void *from)
Definition: copyfuncs.c:4475
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:931
RTEKind rtekind
Definition: parsenodes.h:882
#define QTW_IGNORE_RT_SUBQUERIES
Definition: nodeFuncs.h:20
Query * subquery
Definition: parsenodes.h:900
Definition: pg_list.h:45
struct TableSampleClause * tablesample
Definition: parsenodes.h:895
#define MUTATE(newfield, oldfield, fieldtype)
#define QTW_IGNORE_JOINALIASES
Definition: nodeFuncs.h:23
bool range_table_walker ( List rtable,
bool(*)()  walker,
void *  context,
int  flags 
)

Definition at line 2282 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_RELATION, RTE_SUBQUERY, RTE_VALUES, RangeTblEntry::rtekind, RangeTblEntry::securityQuals, RangeTblEntry::subquery, RangeTblEntry::tablesample, and RangeTblEntry::values_lists.

Referenced by IncrementVarSublevelsUp_rtable(), and query_tree_walker().

2286 {
2287  ListCell *rt;
2288 
2289  foreach(rt, rtable)
2290  {
2291  RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
2292 
2293  /* For historical reasons, visiting RTEs is not the default */
2294  if (flags & QTW_EXAMINE_RTES)
2295  if (walker(rte, context))
2296  return true;
2297 
2298  switch (rte->rtekind)