diff options
Diffstat (limited to 'src/backend/nodes/makefuncs.c')
-rw-r--r-- | src/backend/nodes/makefuncs.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c index ee15695b914..4b268f3c6b3 100644 --- a/src/backend/nodes/makefuncs.c +++ b/src/backend/nodes/makefuncs.c @@ -108,6 +108,93 @@ makeVarFromTargetEntry(Index varno, } /* + * makeWholeRowVar - + * creates a Var node representing a whole row of the specified RTE + * + * A whole-row reference is a Var with varno set to the correct range + * table entry, and varattno == 0 to signal that it references the whole + * tuple. (Use of zero here is unclean, since it could easily be confused + * with error cases, but it's not worth changing now.) The vartype indicates + * a rowtype; either a named composite type, or RECORD. This function + * encapsulates the logic for determining the correct rowtype OID to use. + */ +Var * +makeWholeRowVar(RangeTblEntry *rte, + Index varno, + Index varlevelsup) +{ + Var *result; + Oid toid; + + switch (rte->rtekind) + { + case RTE_RELATION: + /* relation: the rowtype is a named composite type */ + toid = get_rel_type_id(rte->relid); + if (!OidIsValid(toid)) + elog(ERROR, "could not find type OID for relation %u", + rte->relid); + result = makeVar(varno, + InvalidAttrNumber, + toid, + -1, + varlevelsup); + break; + case RTE_FUNCTION: + toid = exprType(rte->funcexpr); + if (type_is_rowtype(toid)) + { + /* func returns composite; same as relation case */ + result = makeVar(varno, + InvalidAttrNumber, + toid, + -1, + varlevelsup); + } + else + { + /* + * func returns scalar; instead of making a whole-row Var, + * just reference the function's scalar output. (XXX this + * seems a tad inconsistent, especially if "f.*" was + * explicitly written ...) + */ + result = makeVar(varno, + 1, + toid, + -1, + varlevelsup); + } + break; + case RTE_VALUES: + toid = RECORDOID; + /* returns composite; same as relation case */ + result = makeVar(varno, + InvalidAttrNumber, + toid, + -1, + varlevelsup); + break; + default: + + /* + * RTE is a join or subselect. We represent this as a whole-row + * Var of RECORD type. (Note that in most cases the Var will be + * expanded to a RowExpr during planning, but that is not our + * concern here.) + */ + result = makeVar(varno, + InvalidAttrNumber, + RECORDOID, + -1, + varlevelsup); + break; + } + + return result; +} + +/* * makeTargetEntry - * creates a TargetEntry node */ |