in src/backend/nodes/nodeFuncs.c [30:280]
static bool planstate_walk_subplans(List *plans, bool (*walker) (),
void *context);
static bool planstate_walk_members(PlanState **planstates, int nplans,
bool (*walker) (), void *context);
static Node *
range_table_entry_mutator(RangeTblEntry *rte, Node *(*mutator)(), void *context, int flags);
/*
* exprType -
* returns the Oid of the type of the expression's result.
*/
Oid
exprType(const Node *expr)
{
Oid type;
if (!expr)
return InvalidOid;
switch (nodeTag(expr))
{
case T_Var:
type = ((const Var *) expr)->vartype;
break;
case T_Const:
type = ((const Const *) expr)->consttype;
break;
case T_Param:
type = ((const Param *) expr)->paramtype;
break;
case T_Aggref:
type = ((const Aggref *) expr)->aggtype;
break;
case T_GroupingFunc:
type = INT4OID;
break;
case T_GroupId:
type = INT4OID;
break;
case T_GroupingSetId:
type = INT4OID;
break;
case T_WindowFunc:
type = ((const WindowFunc *) expr)->wintype;
break;
case T_SubscriptingRef:
type = ((const SubscriptingRef *) expr)->refrestype;
break;
case T_FuncExpr:
type = ((const FuncExpr *) expr)->funcresulttype;
break;
case T_NamedArgExpr:
type = exprType((Node *) ((const NamedArgExpr *) expr)->arg);
break;
case T_OpExpr:
type = ((const OpExpr *) expr)->opresulttype;
break;
case T_DistinctExpr:
type = ((const DistinctExpr *) expr)->opresulttype;
break;
case T_NullIfExpr:
type = ((const NullIfExpr *) expr)->opresulttype;
break;
case T_ScalarArrayOpExpr:
type = BOOLOID;
break;
case T_BoolExpr:
type = BOOLOID;
break;
case T_SubLink:
{
const SubLink *sublink = (const SubLink *) expr;
if (sublink->subLinkType == EXPR_SUBLINK ||
sublink->subLinkType == ARRAY_SUBLINK)
{
/* get the type of the subselect's first target column */
Query *qtree = (Query *) sublink->subselect;
TargetEntry *tent;
if (!qtree || !IsA(qtree, Query))
elog(ERROR, "cannot get type for untransformed sublink");
tent = linitial_node(TargetEntry, qtree->targetList);
Assert(!tent->resjunk);
type = exprType((Node *) tent->expr);
if (sublink->subLinkType == ARRAY_SUBLINK)
{
type = get_promoted_array_type(type);
if (!OidIsValid(type))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("could not find array type for data type %s",
format_type_be(exprType((Node *) tent->expr)))));
}
}
else if (sublink->subLinkType == MULTIEXPR_SUBLINK)
{
/* MULTIEXPR is always considered to return RECORD */
type = RECORDOID;
}
else
{
/* for all other sublink types, result is boolean */
type = BOOLOID;
}
}
break;
case T_SubPlan:
{
const SubPlan *subplan = (const SubPlan *) expr;
if (subplan->subLinkType == EXPR_SUBLINK ||
subplan->subLinkType == ARRAY_SUBLINK)
{
/* get the type of the subselect's first target column */
type = subplan->firstColType;
if (subplan->subLinkType == ARRAY_SUBLINK)
{
type = get_promoted_array_type(type);
if (!OidIsValid(type))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("could not find array type for data type %s",
format_type_be(subplan->firstColType))));
}
}
else if (subplan->subLinkType == MULTIEXPR_SUBLINK)
{
/* MULTIEXPR is always considered to return RECORD */
type = RECORDOID;
}
else
{
/* for all other subplan types, result is boolean */
type = BOOLOID;
}
}
break;
case T_AlternativeSubPlan:
{
const AlternativeSubPlan *asplan = (const AlternativeSubPlan *) expr;
/* subplans should all return the same thing */
type = exprType((Node *) linitial(asplan->subplans));
}
break;
case T_FieldSelect:
type = ((const FieldSelect *) expr)->resulttype;
break;
case T_FieldStore:
type = ((const FieldStore *) expr)->resulttype;
break;
case T_RelabelType:
type = ((const RelabelType *) expr)->resulttype;
break;
case T_CoerceViaIO:
type = ((const CoerceViaIO *) expr)->resulttype;
break;
case T_ArrayCoerceExpr:
type = ((const ArrayCoerceExpr *) expr)->resulttype;
break;
case T_ConvertRowtypeExpr:
type = ((const ConvertRowtypeExpr *) expr)->resulttype;
break;
case T_CollateExpr:
type = exprType((Node *) ((const CollateExpr *) expr)->arg);
break;
case T_CaseExpr:
type = ((const CaseExpr *) expr)->casetype;
break;
case T_CaseTestExpr:
type = ((const CaseTestExpr *) expr)->typeId;
break;
case T_ArrayExpr:
type = ((const ArrayExpr *) expr)->array_typeid;
break;
case T_RowExpr:
type = ((const RowExpr *) expr)->row_typeid;
break;
case T_TableValueExpr:
type = ANYTABLEOID; /* MULTISET values are a special pseudotype */
break;
case T_RowCompareExpr:
type = BOOLOID;
break;
case T_CoalesceExpr:
type = ((const CoalesceExpr *) expr)->coalescetype;
break;
case T_MinMaxExpr:
type = ((const MinMaxExpr *) expr)->minmaxtype;
break;
case T_SQLValueFunction:
type = ((const SQLValueFunction *) expr)->type;
break;
case T_XmlExpr:
if (((const XmlExpr *) expr)->op == IS_DOCUMENT)
type = BOOLOID;
else if (((const XmlExpr *) expr)->op == IS_XMLSERIALIZE)
type = TEXTOID;
else
type = XMLOID;
break;
case T_NullTest:
type = BOOLOID;
break;
case T_BooleanTest:
type = BOOLOID;
break;
case T_CoerceToDomain:
type = ((const CoerceToDomain *) expr)->resulttype;
break;
case T_CoerceToDomainValue:
type = ((const CoerceToDomainValue *) expr)->typeId;
break;
case T_SetToDefault:
type = ((const SetToDefault *) expr)->typeId;
break;
case T_CurrentOfExpr:
type = BOOLOID;
break;
case T_NextValueExpr:
type = ((const NextValueExpr *) expr)->typeId;
break;
case T_InferenceElem:
{
const InferenceElem *n = (const InferenceElem *) expr;
type = exprType((Node *) n->expr);
}
break;
case T_PlaceHolderVar:
type = exprType((Node *) ((const PlaceHolderVar *) expr)->phexpr);
break;
case T_DMLActionExpr:
type = INT4OID;
break;
case T_AggExprId:
type = INT4OID;
break;
case T_RowIdExpr:
type = INT8OID;
break;
default:
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr));
type = InvalidOid; /* keep compiler quiet */
break;
}
return type;
}