mirror of
https://github.com/postgres/postgres.git
synced 2025-09-03 15:22:11 +03:00
Add SQL Standard WITH ORDINALITY support for UNNEST (and any other SRF)
Author: Andrew Gierth, David Fetter Reviewers: Dean Rasheed, Jeevan Chalke, Stephen Frost
This commit is contained in:
@@ -509,6 +509,7 @@ _copyFunctionScan(const FunctionScan *from)
|
||||
COPY_NODE_FIELD(funccoltypes);
|
||||
COPY_NODE_FIELD(funccoltypmods);
|
||||
COPY_NODE_FIELD(funccolcollations);
|
||||
COPY_SCALAR_FIELD(funcordinality);
|
||||
|
||||
return newnode;
|
||||
}
|
||||
@@ -1983,6 +1984,7 @@ _copyRangeTblEntry(const RangeTblEntry *from)
|
||||
COPY_NODE_FIELD(funccoltypes);
|
||||
COPY_NODE_FIELD(funccoltypmods);
|
||||
COPY_NODE_FIELD(funccolcollations);
|
||||
COPY_SCALAR_FIELD(funcordinality);
|
||||
COPY_NODE_FIELD(values_lists);
|
||||
COPY_NODE_FIELD(values_collations);
|
||||
COPY_STRING_FIELD(ctename);
|
||||
@@ -2296,6 +2298,7 @@ _copyRangeFunction(const RangeFunction *from)
|
||||
{
|
||||
RangeFunction *newnode = makeNode(RangeFunction);
|
||||
|
||||
COPY_SCALAR_FIELD(ordinality);
|
||||
COPY_SCALAR_FIELD(lateral);
|
||||
COPY_NODE_FIELD(funccallnode);
|
||||
COPY_NODE_FIELD(alias);
|
||||
|
@@ -2126,6 +2126,7 @@ _equalRangeSubselect(const RangeSubselect *a, const RangeSubselect *b)
|
||||
static bool
|
||||
_equalRangeFunction(const RangeFunction *a, const RangeFunction *b)
|
||||
{
|
||||
COMPARE_SCALAR_FIELD(ordinality);
|
||||
COMPARE_SCALAR_FIELD(lateral);
|
||||
COMPARE_NODE_FIELD(funccallnode);
|
||||
COMPARE_NODE_FIELD(alias);
|
||||
@@ -2234,6 +2235,7 @@ _equalRangeTblEntry(const RangeTblEntry *a, const RangeTblEntry *b)
|
||||
COMPARE_NODE_FIELD(funccoltypes);
|
||||
COMPARE_NODE_FIELD(funccoltypmods);
|
||||
COMPARE_NODE_FIELD(funccolcollations);
|
||||
COMPARE_SCALAR_FIELD(funcordinality);
|
||||
COMPARE_NODE_FIELD(values_lists);
|
||||
COMPARE_NODE_FIELD(values_collations);
|
||||
COMPARE_STRING_FIELD(ctename);
|
||||
|
@@ -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
|
||||
|
@@ -521,6 +521,7 @@ _outFunctionScan(StringInfo str, const FunctionScan *node)
|
||||
WRITE_NODE_FIELD(funccoltypes);
|
||||
WRITE_NODE_FIELD(funccoltypmods);
|
||||
WRITE_NODE_FIELD(funccolcollations);
|
||||
WRITE_BOOL_FIELD(funcordinality);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2382,6 +2383,7 @@ _outRangeTblEntry(StringInfo str, const RangeTblEntry *node)
|
||||
WRITE_NODE_FIELD(funccoltypes);
|
||||
WRITE_NODE_FIELD(funccoltypmods);
|
||||
WRITE_NODE_FIELD(funccolcollations);
|
||||
WRITE_BOOL_FIELD(funcordinality);
|
||||
break;
|
||||
case RTE_VALUES:
|
||||
WRITE_NODE_FIELD(values_lists);
|
||||
@@ -2614,6 +2616,7 @@ _outRangeFunction(StringInfo str, const RangeFunction *node)
|
||||
{
|
||||
WRITE_NODE_TYPE("RANGEFUNCTION");
|
||||
|
||||
WRITE_BOOL_FIELD(ordinality);
|
||||
WRITE_BOOL_FIELD(lateral);
|
||||
WRITE_NODE_FIELD(funccallnode);
|
||||
WRITE_NODE_FIELD(alias);
|
||||
|
@@ -1223,6 +1223,7 @@ _readRangeTblEntry(void)
|
||||
READ_NODE_FIELD(funccoltypes);
|
||||
READ_NODE_FIELD(funccoltypmods);
|
||||
READ_NODE_FIELD(funccolcollations);
|
||||
READ_BOOL_FIELD(funcordinality);
|
||||
break;
|
||||
case RTE_VALUES:
|
||||
READ_NODE_FIELD(values_lists);
|
||||
|
Reference in New Issue
Block a user