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:560
#define AssertMacro(condition)
Definition: c.h:676
void * palloc(Size size)
Definition: mcxt.c:849

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:849

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 1672 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().

1674 {
1675  switch (nodeTag(node))
1676  {
1677  case T_Aggref:
1678  {
1679  Aggref *expr = (Aggref *) node;
1680 
1681  if (checker(expr->aggfnoid, context))
1682  return true;
1683  }
1684  break;
1685  case T_WindowFunc:
1686  {
1687  WindowFunc *expr = (WindowFunc *) node;
1688 
1689  if (checker(expr->winfnoid, context))
1690  return true;
1691  }
1692  break;
1693  case T_FuncExpr:
1694  {
1695  FuncExpr *expr = (FuncExpr *) node;
1696 
1697  if (checker(expr->funcid, context))
1698  return true;
1699  }
1700  break;
1701  case T_OpExpr:
1702  case T_DistinctExpr: /* struct-equivalent to OpExpr */
1703  case T_NullIfExpr: /* struct-equivalent to OpExpr */
1704  {
1705  OpExpr *expr = (OpExpr *) node;
1706 
1707  /* Set opfuncid if it wasn't set already */
1708  set_opfuncid(expr);
1709  if (checker(expr->opfuncid, context))
1710  return true;
1711  }
1712  break;
1713  case T_ScalarArrayOpExpr:
1714  {
1715  ScalarArrayOpExpr *expr = (ScalarArrayOpExpr *) node;
1716 
1717  set_sa_opfuncid(expr);
1718  if (checker(expr->opfuncid, context))
1719  return true;
1720  }
1721  break;
1722  case T_CoerceViaIO:
1723  {
1724  CoerceViaIO *expr = (CoerceViaIO *) node;
1725  Oid iofunc;
1726  Oid typioparam;
1727  bool typisvarlena;
1728 
1729  /* check the result type's input function */
1731  &iofunc, &typioparam);
1732  if (checker(iofunc, context))
1733  return true;
1734  /* check the input type's output function */
1735  getTypeOutputInfo(exprType((Node *) expr->arg),
1736  &iofunc, &typisvarlena);
1737  if (checker(iofunc, context))
1738  return true;
1739  }
1740  break;
1741  case T_ArrayCoerceExpr:
1742  {
1743  ArrayCoerceExpr *expr = (ArrayCoerceExpr *) node;
1744 
1745  if (OidIsValid(expr->elemfuncid) &&
1746  checker(expr->elemfuncid, context))
1747  return true;
1748  }
1749  break;
1750  case T_RowCompareExpr:
1751  {
1752  RowCompareExpr *rcexpr = (RowCompareExpr *) node;
1753  ListCell *opid;
1754 
1755  foreach(opid, rcexpr->opnos)
1756  {
1757  Oid opfuncid = get_opcode(lfirst_oid(opid));
1758 
1759  if (checker(opfuncid, context))
1760  return true;
1761  }
1762  }
1763  break;
1764  default:
1765  break;
1766  }
1767  return false;
1768 }
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
Definition: lsyscache.c:2632
Oid resulttype
Definition: primnodes.h:811
Definition: nodes.h:509
unsigned int Oid
Definition: postgres_ext.h:31
#define OidIsValid(objectId)
Definition: c.h:538
Oid funcid
Definition: primnodes.h:448
Oid winfnoid
Definition: primnodes.h:355
Expr * arg
Definition: primnodes.h:810
void getTypeInputInfo(Oid type, Oid *typInput, Oid *typIOParam)
Definition: lsyscache.c:2599
Oid opfuncid
Definition: primnodes.h:496
RegProcedure get_opcode(Oid opno)
Definition: lsyscache.c:1094
Oid aggfnoid
Definition: primnodes.h:294
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
#define nodeTag(nodeptr)
Definition: nodes.h:514
void set_opfuncid(OpExpr *opexpr)
Definition: nodeFuncs.c:1634
void set_sa_opfuncid(ScalarArrayOpExpr *opexpr)
Definition: nodeFuncs.c:1645
#define lfirst_oid(lc)
Definition: pg_list.h:108
Oid exprCollation ( const Node expr)

Definition at line 748 of file nodeFuncs.c.

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

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

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

Definition at line 676 of file nodeFuncs.c.

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

Referenced by expression_returns_set().

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

Definition at line 2431 of file nodeFuncs.c.

References Aggref::aggargtypes, Aggref::aggdirectargs, Aggref::aggdistinct, Aggref::aggfilter, WindowFunc::aggfilter, Aggref::aggorder, OnConflictExpr::arbiterElems, OnConflictExpr::arbiterWhere, NamedArgExpr::arg, FieldSelect::arg, FieldStore::arg, RelabelType::arg, CoerceViaIO::arg, ArrayCoerceExpr::arg, ConvertRowtypeExpr::arg, CollateExpr::arg, CaseExpr::arg, NullTest::arg, BooleanTest::arg, CoerceToDomain::arg, Aggref::args, GroupingFunc::args, WindowFunc::args, FuncExpr::args, OpExpr::args, ScalarArrayOpExpr::args, BoolExpr::args, SubPlan::args, CaseExpr::args, RowExpr::args, CoalesceExpr::args, MinMaxExpr::args, TableSampleClause::args, XmlExpr::args, check_stack_depth(), TableFunc::coldefexprs, TableFunc::colexprs, GroupingFunc::cols, copyObject, CommonTableExpr::ctequery, CaseExpr::defresult, TableFunc::docexpr, ArrayExpr::elements, elog, WindowClause::endOffset, ERROR, OnConflictExpr::exclRelTlist, CaseWhen::expr, InferenceElem::expr, TargetEntry::expr, FieldStore::fieldnums, FLATCOPY, FromExpr::fromlist, RangeTblFunction::funcexpr, lappend(), JoinExpr::larg, SetOperationStmt::larg, RowCompareExpr::largs, lfirst, list_copy(), MUTATE, XmlExpr::named_args, FieldStore::newvals, NIL, nodeTag, TableFunc::ns_uris, 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, TableFunc::rowexpr, WindowClause::startOffset, AlternativeSubPlan::subplans, SubLink::subselect, T_Aggref, T_AlternativeSubPlan, T_AppendRelInfo, T_ArrayCoerceExpr, T_ArrayExpr, T_ArrayRef, T_BooleanTest, T_BoolExpr, T_CaseExpr, T_CaseTestExpr, T_CaseWhen, T_CoalesceExpr, T_CoerceToDomain, T_CoerceToDomainValue, T_CoerceViaIO, T_CollateExpr, T_CommonTableExpr, T_Const, T_ConvertRowtypeExpr, T_CurrentOfExpr, T_DistinctExpr, T_FieldSelect, T_FieldStore, T_FromExpr, T_FuncExpr, T_GroupingFunc, T_InferenceElem, T_JoinExpr, T_List, T_MinMaxExpr, T_NamedArgExpr, T_NextValueExpr, T_NullIfExpr, T_NullTest, T_OnConflictExpr, T_OpExpr, T_Param, T_PlaceHolderInfo, T_PlaceHolderVar, T_Query, T_RangeTblFunction, T_RangeTblRef, T_RelabelType, T_RowCompareExpr, T_RowExpr, T_ScalarArrayOpExpr, T_SetOperationStmt, T_SetToDefault, T_SortGroupClause, T_SQLValueFunction, T_SubLink, T_SubPlan, T_TableFunc, T_TableSampleClause, T_TargetEntry, T_Var, T_WindowClause, T_WindowFunc, T_WithCheckOption, T_XmlExpr, SubLink::testexpr, SubPlan::testexpr, and AppendRelInfo::translated_vars.

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

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

Definition at line 1864 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, check_stack_depth(), TableFunc::coldefexprs, TableFunc::colexprs, CommonTableExpr::ctequery, CaseExpr::defresult, TableFunc::docexpr, elog, WindowClause::endOffset, ERROR, OnConflictExpr::exclRelTlist, CaseWhen::expr, expression_tree_walker(), FromExpr::fromlist, JoinExpr::larg, SetOperationStmt::larg, RowCompareExpr::largs, lfirst, lfirst_node, XmlExpr::named_args, FieldStore::newvals, nodeTag, TableFunc::ns_uris, 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, TableFunc::rowexpr, WindowClause::startOffset, SubLink::subselect, T_Aggref, T_AlternativeSubPlan, T_AppendRelInfo, T_ArrayCoerceExpr, T_ArrayExpr, T_ArrayRef, T_BooleanTest, T_BoolExpr, T_CaseExpr, T_CaseTestExpr, T_CoalesceExpr, T_CoerceToDomain, T_CoerceToDomainValue, T_CoerceViaIO, T_CollateExpr, T_CommonTableExpr, T_Const, T_ConvertRowtypeExpr, T_CurrentOfExpr, T_DistinctExpr, T_FieldSelect, T_FieldStore, T_FromExpr, T_FuncExpr, T_GroupingFunc, T_InferenceElem, T_JoinExpr, T_List, T_MinMaxExpr, T_NamedArgExpr, T_NextValueExpr, T_NullIfExpr, T_NullTest, T_OnConflictExpr, T_OpExpr, T_Param, T_PlaceHolderInfo, T_PlaceHolderVar, T_Query, T_RangeTblFunction, T_RangeTblRef, T_RelabelType, T_RowCompareExpr, T_RowExpr, T_ScalarArrayOpExpr, T_SetOperationStmt, T_SetToDefault, T_SortGroupClause, T_SQLValueFunction, T_SubLink, T_SubPlan, T_TableFunc, T_TableSampleClause, T_TargetEntry, T_Var, T_WindowClause, T_WindowFunc, T_WithCheckOption, T_XmlExpr, SubLink::testexpr, SubPlan::testexpr, and AppendRelInfo::translated_vars.

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

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

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

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

Definition at line 513 of file nodeFuncs.c.

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

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

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

Definition at line 1213 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_TableFunc, T_TargetEntry, T_TypeCast, T_TypeName, T_Var, T_WindowDef, T_WindowFunc, T_WithClause, T_XmlExpr, T_XmlSerialize, SubLink::testexpr, and TypeCast::typeName.

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

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

Definition at line 997 of file nodeFuncs.c.

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

Referenced by assign_collations_walker().

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

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

1150 {
1151  switch (nodeTag(expr))
1152  {
1153  case T_Aggref:
1154  ((Aggref *) expr)->inputcollid = inputcollation;
1155  break;
1156  case T_WindowFunc:
1157  ((WindowFunc *) expr)->inputcollid = inputcollation;
1158  break;
1159  case T_FuncExpr:
1160  ((FuncExpr *) expr)->inputcollid = inputcollation;
1161  break;
1162  case T_OpExpr:
1163  ((OpExpr *) expr)->inputcollid = inputcollation;
1164  break;
1165  case T_DistinctExpr:
1166  ((DistinctExpr *) expr)->inputcollid = inputcollation;
1167  break;
1168  case T_NullIfExpr:
1169  ((NullIfExpr *) expr)->inputcollid = inputcollation;
1170  break;
1171  case T_ScalarArrayOpExpr:
1172  ((ScalarArrayOpExpr *) expr)->inputcollid = inputcollation;
1173  break;
1174  case T_MinMaxExpr:
1175  ((MinMaxExpr *) expr)->inputcollid = inputcollation;
1176  break;
1177  default:
1178  break;
1179  }
1180 }
#define nodeTag(nodeptr)
Definition: nodes.h:514
Oid exprType ( const Node expr)

Definition at line 42 of file nodeFuncs.c.

References arg, ARRAY_SUBLINK, Assert, BOOLOID, elog, ereport, errcode(), errmsg(), ERROR, InferenceElem::expr, EXPR_SUBLINK, exprType(), SubPlan::firstColType, format_type_be(), get_promoted_array_type(), INT4OID, InvalidOid, IS_DOCUMENT, IS_XMLSERIALIZE, IsA, linitial, linitial_node, MULTIEXPR_SUBLINK, nodeTag, OidIsValid, RECORDOID, ArrayRef::refarraytype, ArrayRef::refassgnexpr, ArrayRef::refelemtype, ArrayRef::reflowerindexpr, SubLink::subLinkType, SubPlan::subLinkType, AlternativeSubPlan::subplans, SubLink::subselect, T_Aggref, T_AlternativeSubPlan, T_ArrayCoerceExpr, T_ArrayExpr, T_ArrayRef, T_BooleanTest, T_BoolExpr, T_CaseExpr, T_CaseTestExpr, T_CoalesceExpr, T_CoerceToDomain, T_CoerceToDomainValue, T_CoerceViaIO, T_CollateExpr, T_Const, T_ConvertRowtypeExpr, T_CurrentOfExpr, T_DistinctExpr, T_FieldSelect, T_FieldStore, T_FuncExpr, T_GroupingFunc, T_InferenceElem, T_MinMaxExpr, T_NamedArgExpr, T_NextValueExpr, T_NullIfExpr, T_NullTest, T_OpExpr, T_Param, T_PlaceHolderVar, T_RelabelType, T_RowCompareExpr, T_RowExpr, T_ScalarArrayOpExpr, T_SetToDefault, T_SQLValueFunction, T_SubLink, T_SubPlan, T_Var, T_WindowFunc, T_XmlExpr, Query::targetList, TEXTOID, 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_typmod(), compare_tlist_datatypes(), compute_semijoin_info(), ComputeIndexAttrs(), ComputePartitionAttrs(), ConstructTupleDescriptor(), convert_EXISTS_to_ANY(), cookDefault(), cost_qual_eval_walker(), create_ctas_nodata(), create_indexscan_plan(), DefineVirtualRelation(), deparseNullTest(), estimate_num_groups(), eval_const_expressions_mutator(), EvaluateParams(), examine_attribute(), examine_variable(), exec_simple_recheck_plan(), ExecBuildProjectionInfo(), ExecCheckPlanOutput(), ExecEvalConvertRowtype(), ExecEvalXmlExpr(), ExecInitExprRec(), 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 = linitial_node(TargetEntry, qtree->targetList);
115  Assert(!tent->resjunk);
116  type = exprType((Node *) tent->expr);
117  if (sublink->subLinkType == ARRAY_SUBLINK)
118  {
119  type = get_promoted_array_type(type);
120  if (!OidIsValid(type))
121  ereport(ERROR,
122  (errcode(ERRCODE_UNDEFINED_OBJECT),
123  errmsg("could not find array type for data type %s",
124  format_type_be(exprType((Node *) tent->expr)))));
125  }
126  }
127  else if (sublink->subLinkType == MULTIEXPR_SUBLINK)
128  {
129  /* MULTIEXPR is always considered to return RECORD */
130  type = RECORDOID;
131  }
132  else
133  {
134  /* for all other sublink types, result is boolean */
135  type = BOOLOID;
136  }
137  }
138  break;
139  case T_SubPlan:
140  {
141  const SubPlan *subplan = (const SubPlan *) expr;
142 
143  if (subplan->subLinkType == EXPR_SUBLINK ||
144  subplan->subLinkType == ARRAY_SUBLINK)
145  {
146  /* get the type of the subselect's first target column */
147  type = subplan->firstColType;
148  if (subplan->subLinkType == ARRAY_SUBLINK)
149  {
150  type = get_promoted_array_type(type);
151  if (!OidIsValid(type))
152  ereport(ERROR,
153  (errcode(ERRCODE_UNDEFINED_OBJECT),
154  errmsg("could not find array type for data type %s",
155  format_type_be(subplan->firstColType))));
156  }
157  }
158  else if (subplan->subLinkType == MULTIEXPR_SUBLINK)
159  {
160  /* MULTIEXPR is always considered to return RECORD */
161  type = RECORDOID;
162  }
163  else
164  {
165  /* for all other subplan types, result is boolean */
166  type = BOOLOID;
167  }
168  }
169  break;
171  {
172  const AlternativeSubPlan *asplan = (const AlternativeSubPlan *) expr;
173 
174  /* subplans should all return the same thing */
175  type = exprType((Node *) linitial(asplan->subplans));
176  }
177  break;
178  case T_FieldSelect:
179  type = ((const FieldSelect *) expr)->resulttype;
180  break;
181  case T_FieldStore:
182  type = ((const FieldStore *) expr)->resulttype;
183  break;
184  case T_RelabelType:
185  type = ((const RelabelType *) expr)->resulttype;
186  break;
187  case T_CoerceViaIO:
188  type = ((const CoerceViaIO *) expr)->resulttype;
189  break;
190  case T_ArrayCoerceExpr:
191  type = ((const ArrayCoerceExpr *) expr)->resulttype;
192  break;
194  type = ((const ConvertRowtypeExpr *) expr)->resulttype;
195  break;
196  case T_CollateExpr:
197  type = exprType((Node *) ((const CollateExpr *) expr)->arg);
198  break;
199  case T_CaseExpr:
200  type = ((const CaseExpr *) expr)->casetype;
201  break;
202  case T_CaseTestExpr:
203  type = ((const CaseTestExpr *) expr)->typeId;
204  break;
205  case T_ArrayExpr:
206  type = ((const ArrayExpr *) expr)->array_typeid;
207  break;
208  case T_RowExpr:
209  type = ((const RowExpr *) expr)->row_typeid;
210  break;
211  case T_RowCompareExpr:
212  type = BOOLOID;
213  break;
214  case T_CoalesceExpr:
215  type = ((const CoalesceExpr *) expr)->coalescetype;
216  break;
217  case T_MinMaxExpr:
218  type = ((const MinMaxExpr *) expr)->minmaxtype;
219  break;
220  case T_SQLValueFunction:
221  type = ((const SQLValueFunction *) expr)->type;
222  break;
223  case T_XmlExpr:
224  if (((const XmlExpr *) expr)->op == IS_DOCUMENT)
225  type = BOOLOID;
226  else if (((const XmlExpr *) expr)->op == IS_XMLSERIALIZE)
227  type = TEXTOID;
228  else
229  type = XMLOID;
230  break;
231  case T_NullTest:
232  type = BOOLOID;
233  break;
234  case T_BooleanTest:
235  type = BOOLOID;
236  break;
237  case T_CoerceToDomain:
238  type = ((const CoerceToDomain *) expr)->resulttype;
239  break;
241  type = ((const CoerceToDomainValue *) expr)->typeId;
242  break;
243  case T_SetToDefault:
244  type = ((const SetToDefault *) expr)->typeId;
245  break;
246  case T_CurrentOfExpr:
247  type = BOOLOID;
248  break;
249  case T_NextValueExpr:
250  type = ((const NextValueExpr *) expr)->typeId;
251  break;
252  case T_InferenceElem:
253  {
254  const InferenceElem *n = (const InferenceElem *) expr;
255 
256  type = exprType((Node *) n->expr);
257  }
258  break;
259  case T_PlaceHolderVar:
260  type = exprType((Node *) ((const PlaceHolderVar *) expr)->phexpr);
261  break;
262  default:
263  elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
264  type = InvalidOid; /* keep compiler quiet */
265  break;
266  }
267  return type;
268 }
Oid firstColType
Definition: primnodes.h:692
Expr * refassgnexpr
Definition: primnodes.h:409
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
#define TEXTOID
Definition: pg_type.h:324
SubLinkType subLinkType
Definition: primnodes.h:683
#define INT4OID
Definition: pg_type.h:316
Definition: nodes.h:509
int errcode(int sqlerrcode)
Definition: elog.c:575
char * format_type_be(Oid type_oid)
Definition: format_type.c:94
unsigned int Oid
Definition: postgres_ext.h:31
Definition: primnodes.h:163
#define linitial_node(type, l)
Definition: pg_list.h:114
#define OidIsValid(objectId)
Definition: c.h:538
List * targetList
Definition: parsenodes.h:138
#define linitial(l)
Definition: pg_list.h:111
#define ERROR
Definition: elog.h:43
#define XMLOID
Definition: pg_type.h:359
List * reflowerindexpr
Definition: primnodes.h:405
#define RECORDOID
Definition: pg_type.h:680
#define ereport(elevel, rest)
Definition: elog.h:122
Definition: nodes.h:147
Definition: nodes.h:146
Oid get_promoted_array_type(Oid typid)
Definition: lsyscache.c:2536
Oid refelemtype
Definition: primnodes.h:400
#define InvalidOid
Definition: postgres_ext.h:36
#define Assert(condition)
Definition: c.h:675
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
#define BOOLOID
Definition: pg_type.h:288
#define nodeTag(nodeptr)
Definition: nodes.h:514
Oid refarraytype
Definition: primnodes.h:399
int errmsg(const char *fmt,...)
Definition: elog.c:797
void * arg
#define elog
Definition: elog.h:219
Definition: nodes.h:148
int32 exprTypmod ( const Node expr)

Definition at line 276 of file nodeFuncs.c.

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

Referenced by analyzeCTE(), analyzeCTETargetList(), assign_hypothetical_collations(), assign_nestloop_param_placeholdervar(), build_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().

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

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

1604 {
1605  /* This tree walk requires no special setup, so away we go... */
1606  fix_opfuncids_walker(node, NULL);
1607 }
static bool fix_opfuncids_walker(Node *node, void *context)
Definition: nodeFuncs.c:1610
#define NULL
Definition: c.h:229
static bool fix_opfuncids_walker ( Node node,
void *  context 
)
static

Definition at line 1610 of file nodeFuncs.c.

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

Referenced by fix_opfuncids().

1611 {
1612  if (node == NULL)
1613  return false;
1614  if (IsA(node, OpExpr))
1615  set_opfuncid((OpExpr *) node);
1616  else if (IsA(node, DistinctExpr))
1617  set_opfuncid((OpExpr *) node); /* rely on struct equivalence */
1618  else if (IsA(node, NullIfExpr))
1619  set_opfuncid((OpExpr *) node); /* rely on struct equivalence */
1620  else if (IsA(node, ScalarArrayOpExpr))
1622  return expression_tree_walker(node, fix_opfuncids_walker, context);
1623 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
static bool fix_opfuncids_walker(Node *node, void *context)
Definition: nodeFuncs.c:1610
#define NULL
Definition: c.h:229
bool expression_tree_walker(Node *node, bool(*walker)(), void *context)
Definition: nodeFuncs.c:1864
void set_opfuncid(OpExpr *opexpr)
Definition: nodeFuncs.c:1634
void set_sa_opfuncid(ScalarArrayOpExpr *opexpr)
Definition: nodeFuncs.c:1645
static int leftmostLoc ( int  loc1,
int  loc2 
)
static

Definition at line 1582 of file nodeFuncs.c.

References Min.

Referenced by exprLocation().

1583 {
1584  if (loc1 < 0)
1585  return loc2;
1586  else if (loc2 < 0)
1587  return loc1;
1588  else
1589  return Min(loc1, loc2);
1590 }
#define Min(x, y)
Definition: c.h:806
bool planstate_tree_walker ( PlanState planstate,
bool(*)()  walker,
void *  context 
)

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

3721 {
3722  Plan *plan = planstate->plan;
3723  ListCell *lc;
3724 
3725  /* initPlan-s */
3726  if (planstate_walk_subplans(planstate->initPlan, walker, context))
3727  return true;
3728 
3729  /* lefttree */
3730  if (outerPlanState(planstate))
3731  {
3732  if (walker(outerPlanState(planstate), context))
3733  return true;
3734  }
3735 
3736  /* righttree */
3737  if (innerPlanState(planstate))
3738  {
3739  if (walker(innerPlanState(planstate), context))
3740  return true;
3741  }
3742 
3743  /* special child plans */
3744  switch (nodeTag(plan))
3745  {
3746  case T_ModifyTable:
3747  if (planstate_walk_members(((ModifyTable *) plan)->plans,
3748  ((ModifyTableState *) planstate)->mt_plans,
3749  walker, context))
3750  return true;
3751  break;
3752  case T_Append:
3753  if (planstate_walk_members(((Append *) plan)->appendplans,
3754  ((AppendState *) planstate)->appendplans,
3755  walker, context))
3756  return true;
3757  break;
3758  case T_MergeAppend:
3759  if (planstate_walk_members(((MergeAppend *) plan)->mergeplans,
3760  ((MergeAppendState *) planstate)->mergeplans,
3761  walker, context))
3762  return true;
3763  break;
3764  case T_BitmapAnd:
3765  if (planstate_walk_members(((BitmapAnd *) plan)->bitmapplans,
3766  ((BitmapAndState *) planstate)->bitmapplans,
3767  walker, context))
3768  return true;
3769  break;
3770  case T_BitmapOr:
3771  if (planstate_walk_members(((BitmapOr *) plan)->bitmapplans,
3772  ((BitmapOrState *) planstate)->bitmapplans,
3773  walker, context))
3774  return true;
3775  break;
3776  case T_SubqueryScan:
3777  if (walker(((SubqueryScanState *) planstate)->subplan, context))
3778  return true;
3779  break;
3780  case T_CustomScan:
3781  foreach(lc, ((CustomScanState *) planstate)->custom_ps)
3782  {
3783  if (walker((PlanState *) lfirst(lc), context))
3784  return true;
3785  }
3786  break;
3787  default:
3788  break;
3789  }
3790 
3791  /* subPlan-s */
3792  if (planstate_walk_subplans(planstate->subPlan, walker, context))
3793  return true;
3794 
3795  return false;
3796 }
List * initPlan
Definition: execnodes.h:820
List * subPlan
Definition: execnodes.h:822
Definition: nodes.h:48
#define outerPlanState(node)
Definition: execnodes.h:845
static bool planstate_walk_subplans(List *plans, bool(*walker)(), void *context)
Definition: nodeFuncs.c:3802
Plan * plan
Definition: execnodes.h:803
#define lfirst(lc)
Definition: pg_list.h:106
#define nodeTag(nodeptr)
Definition: nodes.h:514
static bool planstate_walk_members(List *plans, PlanState **planstates, bool(*walker)(), void *context)
Definition: nodeFuncs.c:3827
#define innerPlanState(node)
Definition: execnodes.h:844
static bool planstate_walk_members ( List plans,
PlanState **  planstates,
bool(*)()  walker,
void *  context 
)
static

Definition at line 3827 of file nodeFuncs.c.

References list_length().

Referenced by planstate_tree_walker().

3829 {
3830  int nplans = list_length(plans);
3831  int j;
3832 
3833  for (j = 0; j < nplans; j++)
3834  {
3835  if (walker(planstates[j], context))
3836  return true;
3837  }
3838 
3839  return false;
3840 }
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 3802 of file nodeFuncs.c.

References lfirst_node, and SubPlanState::planstate.

Referenced by planstate_tree_walker().

3805 {
3806  ListCell *lc;
3807 
3808  foreach(lc, plans)
3809  {
3811 
3812  if (walker(sps->planstate, context))
3813  return true;
3814  }
3815 
3816  return false;
3817 }
struct PlanState * planstate
Definition: execnodes.h:726
#define lfirst_node(type, lc)
Definition: pg_list.h:109
Node* query_or_expression_tree_mutator ( Node node,
Node *(*)()  mutator,
void *  context,
int  flags 
)

Definition at line 3222 of file nodeFuncs.c.

References IsA, and query_tree_mutator().

Referenced by map_variable_attnos(), and replace_rte_variables().

3226 {
3227  if (node && IsA(node, Query))
3228  return (Node *) query_tree_mutator((Query *) node,
3229  mutator,
3230  context,
3231  flags);
3232  else
3233  return mutator(node, context);
3234 }
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
Definition: nodes.h:509
Query * query_tree_mutator(Query *query, Node *(*mutator)(), void *context, int flags)
Definition: nodeFuncs.c:3089
bool query_or_expression_tree_walker ( Node node,
bool(*)()  walker,
void *  context,
int  flags 
)

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

3203 {
3204  if (node && IsA(node, Query))
3205  return query_tree_walker((Query *) node,
3206  walker,
3207  context,
3208  flags);
3209  else
3210  return walker(node, context);
3211 }
bool query_tree_walker(Query *query, bool(*walker)(), void *context, int flags)
Definition: nodeFuncs.c:2267
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
Query* query_tree_mutator ( Query query,
Node *(*)()  mutator,
void *  context,
int  flags 
)

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

3093 {
3094  Assert(query != NULL && IsA(query, Query));
3095 
3096  if (!(flags & QTW_DONT_COPY_QUERY))
3097  {
3098  Query *newquery;
3099 
3100  FLATCOPY(newquery, query, Query);
3101  query = newquery;
3102  }
3103 
3104  MUTATE(query->targetList, query->targetList, List *);
3105  MUTATE(query->withCheckOptions, query->withCheckOptions, List *);
3106  MUTATE(query->onConflict, query->onConflict, OnConflictExpr *);
3107  MUTATE(query->returningList, query->returningList, List *);
3108  MUTATE(query->jointree, query->jointree, FromExpr *);
3109  MUTATE(query->setOperations, query->setOperations, Node *);
3110  MUTATE(query->havingQual, query->havingQual, Node *);
3111  MUTATE(query->limitOffset, query->limitOffset, Node *);
3112  MUTATE(query->limitCount, query->limitCount, Node *);
3113  if (!(flags & QTW_IGNORE_CTE_SUBQUERIES))
3114  MUTATE(query->cteList, query->cteList, List *);
3115  else /* else copy CTE list as-is */
3116  query->cteList = copyObject(query->cteList);
3117  query->rtable = range_table_mutator(query->rtable,
3118  mutator, context, flags);
3119  return query;
3120 }
Node * limitOffset
Definition: parsenodes.h:158
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
FromExpr * jointree
Definition: parsenodes.h:136
OnConflictExpr * onConflict
Definition: parsenodes.h:142
List * withCheckOptions
Definition: parsenodes.h:169
Definition: nodes.h:509
#define QTW_DONT_COPY_QUERY
Definition: nodeFuncs.h:26
List * targetList
Definition: parsenodes.h:138
#define QTW_IGNORE_CTE_SUBQUERIES
Definition: nodeFuncs.h:21
List * rtable
Definition: parsenodes.h:135
Node * limitCount
Definition: parsenodes.h:159
List * returningList
Definition: parsenodes.h:144
#define FLATCOPY(newnode, node, nodetype)
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
List * cteList
Definition: parsenodes.h:133
Node * setOperations
Definition: parsenodes.h:163
List * range_table_mutator(List *rtable, Node *(*mutator)(), void *context, int flags)
Definition: nodeFuncs.c:3128
#define copyObject(obj)
Definition: nodes.h:621
Node * havingQual
Definition: parsenodes.h:150
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 2267 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().

2271 {
2272  Assert(query != NULL && IsA(query, Query));
2273 
2274  if (walker((Node *) query->targetList, context))
2275  return true;
2276  if (walker((Node *) query->withCheckOptions, context))
2277  return true;
2278  if (walker((Node *) query->onConflict, context))
2279  return true;
2280  if (walker((Node *) query->returningList, context))
2281  return true;
2282  if (walker((Node *) query->jointree, context))
2283  return true;
2284  if (walker(query->setOperations, context))
2285  return true;
2286  if (walker(query->havingQual, context))
2287  return true;
2288  if (walker(query->limitOffset, context))
2289  return true;
2290  if (walker(query->limitCount, context))
2291  return true;
2292  if (!(flags & QTW_IGNORE_CTE_SUBQUERIES))
2293  {
2294  if (walker((Node *) query->cteList, context))
2295  return true;
2296  }
2297  if (!(flags & QTW_IGNORE_RANGE_TABLE))
2298  {
2299  if (range_table_walker(query->rtable, walker, context, flags))
2300  return true;
2301  }
2302  return false;
2303 }
Node * limitOffset
Definition: parsenodes.h:158
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
FromExpr * jointree
Definition: parsenodes.h:136
OnConflictExpr * onConflict
Definition: parsenodes.h:142
List * withCheckOptions
Definition: parsenodes.h:169
Definition: nodes.h:509
List * targetList
Definition: parsenodes.h:138
#define QTW_IGNORE_CTE_SUBQUERIES
Definition: nodeFuncs.h:21
List * rtable
Definition: parsenodes.h:135
Node * limitCount
Definition: parsenodes.h:159
List * returningList
Definition: parsenodes.h:144
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
bool range_table_walker(List *rtable, bool(*walker)(), void *context, int flags)
Definition: nodeFuncs.c:2311
List * cteList
Definition: parsenodes.h:133
Node * setOperations
Definition: parsenodes.h:163
#define QTW_IGNORE_RANGE_TABLE
Definition: nodeFuncs.h:24
Node * havingQual
Definition: parsenodes.h:150
List* range_table_mutator ( List rtable,
Node *(*)()  mutator,
void *  context,
int  flags 
)

Definition at line 3128 of file nodeFuncs.c.

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

Referenced by query_tree_mutator().

3132 {
3133  List *newrt = NIL;
3134  ListCell *rt;
3135 
3136  foreach(rt, rtable)
3137  {
3138  RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
3139  RangeTblEntry *newrte;
3140 
3141  FLATCOPY(newrte, rte, RangeTblEntry);
3142  switch (rte->rtekind)
3143  {
3144  case RTE_RELATION:
3145  MUTATE(newrte->tablesample, rte->tablesample,
3146  TableSampleClause *);
3147  /* we don't bother to copy eref, aliases, etc; OK? */
3148  break;
3149  case RTE_CTE:
3150  case RTE_NAMEDTUPLESTORE:
3151  /* nothing to do */
3152  break;
3153  case RTE_SUBQUERY:
3154  if (!(flags & QTW_IGNORE_RT_SUBQUERIES))
3155  {
3156  CHECKFLATCOPY(newrte->subquery, rte->subquery, Query);
3157  MUTATE(newrte->subquery, newrte->subquery, Query *);
3158  }
3159  else
3160  {
3161  /* else, copy RT subqueries as-is */
3162  newrte->subquery = copyObject(rte->