aboutsummaryrefslogtreecommitdiff
path: root/src/backend/nodes/makefuncs.c
diff options
context:
space:
mode:
authorGreg Stark <stark@mit.edu>2013-07-29 16:38:01 +0100
committerGreg Stark <stark@mit.edu>2013-07-29 16:38:01 +0100
commitc62736cc37f6812d1ebb41ea5a86ffe60564a1f0 (patch)
tree3cb1654476a7e45620d9a3320a002495d000380e /src/backend/nodes/makefuncs.c
parent55cbfa5366b78d93cd1ff8c4c622b552985344f6 (diff)
downloadpostgresql-c62736cc37f6812d1ebb41ea5a86ffe60564a1f0.tar.gz
postgresql-c62736cc37f6812d1ebb41ea5a86ffe60564a1f0.zip
Add SQL Standard WITH ORDINALITY support for UNNEST (and any other SRF)
Author: Andrew Gierth, David Fetter Reviewers: Dean Rasheed, Jeevan Chalke, Stephen Frost
Diffstat (limited to 'src/backend/nodes/makefuncs.c')
-rw-r--r--src/backend/nodes/makefuncs.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c
index 0f8a282ec81..b742ec95324 100644
--- a/src/backend/nodes/makefuncs.c
+++ b/src/backend/nodes/makefuncs.c
@@ -126,6 +126,10 @@ makeVarFromTargetEntry(Index varno,
* returning a non-composite result type, we produce a normal Var referencing
* the function's result directly, instead of the single-column composite
* value that the whole-row notation might otherwise suggest.
+ *
+ * We also handle the specific case of function RTEs with ordinality,
+ * where the additional column has to be added. This forces the result
+ * to be composite and RECORD type.
*/
Var *
makeWholeRowVar(RangeTblEntry *rte,
@@ -151,9 +155,33 @@ makeWholeRowVar(RangeTblEntry *rte,
InvalidOid,
varlevelsup);
break;
+
case RTE_FUNCTION:
+ /*
+ * RTE is a function with or without ordinality. We map the
+ * cases as follows:
+ *
+ * If ordinality is set, we return a composite var even if
+ * the function is a scalar. This var is always of RECORD type.
+ *
+ * If ordinality is not set but the function returns a row,
+ * we keep the function's return type.
+ *
+ * If the function is a scalar, we do what allowScalar requests.
+ */
toid = exprType(rte->funcexpr);
- if (type_is_rowtype(toid))
+
+ if (rte->funcordinality)
+ {
+ /* ORDINALITY always produces an anonymous RECORD result */
+ result = makeVar(varno,
+ InvalidAttrNumber,
+ RECORDOID,
+ -1,
+ InvalidOid,
+ varlevelsup);
+ }
+ else if (type_is_rowtype(toid))
{
/* func returns composite; same as relation case */
result = makeVar(varno,
@@ -184,8 +212,8 @@ makeWholeRowVar(RangeTblEntry *rte,
varlevelsup);
}
break;
- default:
+ default:
/*
* RTE is a join, subselect, or VALUES. We represent this as a
* whole-row Var of RECORD type. (Note that in most cases the Var