summaryrefslogtreecommitdiff
path: root/src/backend/nodes
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/nodes')
-rw-r--r--src/backend/nodes/copyfuncs.c36
-rw-r--r--src/backend/nodes/equalfuncs.c28
-rw-r--r--src/backend/nodes/makefuncs.c46
-rw-r--r--src/backend/nodes/nodeFuncs.c24
-rw-r--r--src/backend/nodes/outfuncs.c34
-rw-r--r--src/backend/nodes/readfuncs.c26
6 files changed, 132 insertions, 62 deletions
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 1733da633a..e3edcf6f74 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -504,11 +504,7 @@ _copyFunctionScan(const FunctionScan *from)
/*
* copy remainder of node
*/
- COPY_NODE_FIELD(funcexpr);
- COPY_NODE_FIELD(funccolnames);
- COPY_NODE_FIELD(funccoltypes);
- COPY_NODE_FIELD(funccoltypmods);
- COPY_NODE_FIELD(funccolcollations);
+ COPY_NODE_FIELD(functions);
COPY_SCALAR_FIELD(funcordinality);
return newnode;
@@ -1981,10 +1977,7 @@ _copyRangeTblEntry(const RangeTblEntry *from)
COPY_SCALAR_FIELD(security_barrier);
COPY_SCALAR_FIELD(jointype);
COPY_NODE_FIELD(joinaliasvars);
- COPY_NODE_FIELD(funcexpr);
- COPY_NODE_FIELD(funccoltypes);
- COPY_NODE_FIELD(funccoltypmods);
- COPY_NODE_FIELD(funccolcollations);
+ COPY_NODE_FIELD(functions);
COPY_SCALAR_FIELD(funcordinality);
COPY_NODE_FIELD(values_lists);
COPY_NODE_FIELD(values_collations);
@@ -2007,6 +2000,22 @@ _copyRangeTblEntry(const RangeTblEntry *from)
return newnode;
}
+static RangeTblFunction *
+_copyRangeTblFunction(const RangeTblFunction *from)
+{
+ RangeTblFunction *newnode = makeNode(RangeTblFunction);
+
+ COPY_NODE_FIELD(funcexpr);
+ COPY_SCALAR_FIELD(funccolcount);
+ COPY_NODE_FIELD(funccolnames);
+ COPY_NODE_FIELD(funccoltypes);
+ COPY_NODE_FIELD(funccoltypmods);
+ COPY_NODE_FIELD(funccolcollations);
+ COPY_BITMAPSET_FIELD(funcparams);
+
+ return newnode;
+}
+
static WithCheckOption *
_copyWithCheckOption(const WithCheckOption *from)
{
@@ -2299,9 +2308,10 @@ _copyRangeFunction(const RangeFunction *from)
{
RangeFunction *newnode = makeNode(RangeFunction);
- COPY_SCALAR_FIELD(ordinality);
COPY_SCALAR_FIELD(lateral);
- COPY_NODE_FIELD(funccallnode);
+ COPY_SCALAR_FIELD(ordinality);
+ COPY_SCALAR_FIELD(is_table);
+ COPY_NODE_FIELD(functions);
COPY_NODE_FIELD(alias);
COPY_NODE_FIELD(coldeflist);
@@ -2366,6 +2376,7 @@ _copyColumnDef(const ColumnDef *from)
COPY_SCALAR_FIELD(collOid);
COPY_NODE_FIELD(constraints);
COPY_NODE_FIELD(fdwoptions);
+ COPY_LOCATION_FIELD(location);
return newnode;
}
@@ -4550,6 +4561,9 @@ copyObject(const void *from)
case T_RangeTblEntry:
retval = _copyRangeTblEntry(from);
break;
+ case T_RangeTblFunction:
+ retval = _copyRangeTblFunction(from);
+ break;
case T_WithCheckOption:
retval = _copyWithCheckOption(from);
break;
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 7b29812b69..1f9b5d70f5 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -2140,9 +2140,10 @@ _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_SCALAR_FIELD(ordinality);
+ COMPARE_SCALAR_FIELD(is_table);
+ COMPARE_NODE_FIELD(functions);
COMPARE_NODE_FIELD(alias);
COMPARE_NODE_FIELD(coldeflist);
@@ -2179,6 +2180,7 @@ _equalColumnDef(const ColumnDef *a, const ColumnDef *b)
COMPARE_SCALAR_FIELD(collOid);
COMPARE_NODE_FIELD(constraints);
COMPARE_NODE_FIELD(fdwoptions);
+ COMPARE_LOCATION_FIELD(location);
return true;
}
@@ -2245,10 +2247,7 @@ _equalRangeTblEntry(const RangeTblEntry *a, const RangeTblEntry *b)
COMPARE_SCALAR_FIELD(security_barrier);
COMPARE_SCALAR_FIELD(jointype);
COMPARE_NODE_FIELD(joinaliasvars);
- COMPARE_NODE_FIELD(funcexpr);
- COMPARE_NODE_FIELD(funccoltypes);
- COMPARE_NODE_FIELD(funccoltypmods);
- COMPARE_NODE_FIELD(funccolcollations);
+ COMPARE_NODE_FIELD(functions);
COMPARE_SCALAR_FIELD(funcordinality);
COMPARE_NODE_FIELD(values_lists);
COMPARE_NODE_FIELD(values_collations);
@@ -2272,6 +2271,20 @@ _equalRangeTblEntry(const RangeTblEntry *a, const RangeTblEntry *b)
}
static bool
+_equalRangeTblFunction(const RangeTblFunction *a, const RangeTblFunction *b)
+{
+ COMPARE_NODE_FIELD(funcexpr);
+ COMPARE_SCALAR_FIELD(funccolcount);
+ COMPARE_NODE_FIELD(funccolnames);
+ COMPARE_NODE_FIELD(funccoltypes);
+ COMPARE_NODE_FIELD(funccoltypmods);
+ COMPARE_NODE_FIELD(funccolcollations);
+ COMPARE_BITMAPSET_FIELD(funcparams);
+
+ return true;
+}
+
+static bool
_equalWithCheckOption(const WithCheckOption *a, const WithCheckOption *b)
{
COMPARE_STRING_FIELD(viewname);
@@ -3018,6 +3031,9 @@ equal(const void *a, const void *b)
case T_RangeTblEntry:
retval = _equalRangeTblEntry(a, b);
break;
+ case T_RangeTblFunction:
+ retval = _equalRangeTblFunction(a, b);
+ break;
case T_WithCheckOption:
retval = _equalWithCheckOption(a, b);
break;
diff --git a/src/backend/nodes/makefuncs.c b/src/backend/nodes/makefuncs.c
index 4a7e793ae0..d3ed4fe98b 100644
--- a/src/backend/nodes/makefuncs.c
+++ b/src/backend/nodes/makefuncs.c
@@ -122,14 +122,10 @@ makeVarFromTargetEntry(Index varno,
* a rowtype; either a named composite type, or RECORD. This function
* encapsulates the logic for determining the correct rowtype OID to use.
*
- * If allowScalar is true, then for the case where the RTE is a function
+ * If allowScalar is true, then for the case where the RTE is a single function
* 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,
@@ -139,6 +135,7 @@ makeWholeRowVar(RangeTblEntry *rte,
{
Var *result;
Oid toid;
+ Node *fexpr;
switch (rte->rtekind)
{
@@ -157,31 +154,27 @@ makeWholeRowVar(RangeTblEntry *rte,
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.
+ * If there's more than one function, or ordinality is requested,
+ * force a RECORD result, since there's certainly more than one
+ * column involved and it can't be a known named type.
*/
- toid = exprType(rte->funcexpr);
-
- if (rte->funcordinality)
+ if (rte->funcordinality || list_length(rte->functions) != 1)
{
- /* ORDINALITY always produces an anonymous RECORD result */
+ /* always produces an anonymous RECORD result */
result = makeVar(varno,
InvalidAttrNumber,
RECORDOID,
-1,
InvalidOid,
varlevelsup);
+ break;
}
- else if (type_is_rowtype(toid))
+
+ fexpr = ((RangeTblFunction *) linitial(rte->functions))->funcexpr;
+ toid = exprType(fexpr);
+ if (type_is_rowtype(toid))
{
/* func returns composite; same as relation case */
result = makeVar(varno,
@@ -198,7 +191,7 @@ makeWholeRowVar(RangeTblEntry *rte,
1,
toid,
-1,
- exprCollation(rte->funcexpr),
+ exprCollation(fexpr),
varlevelsup);
}
else
@@ -214,6 +207,7 @@ makeWholeRowVar(RangeTblEntry *rte,
break;
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
@@ -541,23 +535,21 @@ makeDefElemExtended(char *nameSpace, char *name, Node *arg,
* makeFuncCall -
*
* Initialize a FuncCall struct with the information every caller must
- * supply. Any non-default parameters have to be handled by the
- * caller.
- *
+ * supply. Any non-default parameters have to be inserted by the caller.
*/
-
FuncCall *
makeFuncCall(List *name, List *args, int location)
{
- FuncCall *n = makeNode(FuncCall);
+ FuncCall *n = makeNode(FuncCall);
+
n->funcname = name;
n->args = args;
- n->location = location;
n->agg_order = NIL;
n->agg_filter = NULL;
n->agg_star = FALSE;
n->agg_distinct = FALSE;
n->func_variadic = FALSE;
n->over = NULL;
+ n->location = location;
return n;
}
diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c
index 908f397d50..d7db67dc9e 100644
--- a/src/backend/nodes/nodeFuncs.c
+++ b/src/backend/nodes/nodeFuncs.c
@@ -1447,6 +1447,9 @@ exprLocation(const Node *expr)
case T_TypeName:
loc = ((const TypeName *) expr)->location;
break;
+ case T_ColumnDef:
+ loc = ((const ColumnDef *) expr)->location;
+ break;
case T_Constraint:
loc = ((const Constraint *) expr)->location;
break;
@@ -1901,6 +1904,8 @@ expression_tree_walker(Node *node,
break;
case T_PlaceHolderInfo:
return walker(((PlaceHolderInfo *) node)->ph_var, context);
+ case T_RangeTblFunction:
+ return walker(((RangeTblFunction *) node)->funcexpr, context);
default:
elog(ERROR, "unrecognized node type: %d",
(int) nodeTag(node));
@@ -2000,7 +2005,7 @@ range_table_walker(List *rtable,
return true;
break;
case RTE_FUNCTION:
- if (walker(rte->funcexpr, context))
+ if (walker(rte->functions, context))
return true;
break;
case RTE_VALUES:
@@ -2615,6 +2620,17 @@ expression_tree_mutator(Node *node,
return (Node *) newnode;
}
break;
+ case T_RangeTblFunction:
+ {
+ RangeTblFunction *rtfunc = (RangeTblFunction *) node;
+ RangeTblFunction *newnode;
+
+ FLATCOPY(newnode, rtfunc, RangeTblFunction);
+ MUTATE(newnode->funcexpr, rtfunc->funcexpr, Node *);
+ /* Assume we need not copy the coldef info lists */
+ return (Node *) newnode;
+ }
+ break;
default:
elog(ERROR, "unrecognized node type: %d",
(int) nodeTag(node));
@@ -2725,7 +2741,7 @@ range_table_mutator(List *rtable,
}
break;
case RTE_FUNCTION:
- MUTATE(newrte->funcexpr, rte->funcexpr, Node *);
+ MUTATE(newrte->functions, rte->functions, List *);
break;
case RTE_VALUES:
MUTATE(newrte->values_lists, rte->values_lists, List *);
@@ -3113,10 +3129,12 @@ raw_expression_tree_walker(Node *node,
{
RangeFunction *rf = (RangeFunction *) node;
- if (walker(rf->funccallnode, context))
+ if (walker(rf->functions, context))
return true;
if (walker(rf->alias, context))
return true;
+ if (walker(rf->coldeflist, context))
+ return true;
}
break;
case T_TypeName:
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index b39927e025..4c7505e334 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -516,11 +516,7 @@ _outFunctionScan(StringInfo str, const FunctionScan *node)
_outScanInfo(str, (const Scan *) node);
- WRITE_NODE_FIELD(funcexpr);
- WRITE_NODE_FIELD(funccolnames);
- WRITE_NODE_FIELD(funccoltypes);
- WRITE_NODE_FIELD(funccoltypmods);
- WRITE_NODE_FIELD(funccolcollations);
+ WRITE_NODE_FIELD(functions);
WRITE_BOOL_FIELD(funcordinality);
}
@@ -2154,6 +2150,7 @@ _outColumnDef(StringInfo str, const ColumnDef *node)
WRITE_OID_FIELD(collOid);
WRITE_NODE_FIELD(constraints);
WRITE_NODE_FIELD(fdwoptions);
+ WRITE_LOCATION_FIELD(location);
}
static void
@@ -2382,10 +2379,7 @@ _outRangeTblEntry(StringInfo str, const RangeTblEntry *node)
WRITE_NODE_FIELD(joinaliasvars);
break;
case RTE_FUNCTION:
- WRITE_NODE_FIELD(funcexpr);
- WRITE_NODE_FIELD(funccoltypes);
- WRITE_NODE_FIELD(funccoltypmods);
- WRITE_NODE_FIELD(funccolcollations);
+ WRITE_NODE_FIELD(functions);
WRITE_BOOL_FIELD(funcordinality);
break;
case RTE_VALUES:
@@ -2415,6 +2409,20 @@ _outRangeTblEntry(StringInfo str, const RangeTblEntry *node)
}
static void
+_outRangeTblFunction(StringInfo str, const RangeTblFunction *node)
+{
+ WRITE_NODE_TYPE("RANGETBLFUNCTION");
+
+ WRITE_NODE_FIELD(funcexpr);
+ WRITE_INT_FIELD(funccolcount);
+ WRITE_NODE_FIELD(funccolnames);
+ WRITE_NODE_FIELD(funccoltypes);
+ WRITE_NODE_FIELD(funccoltypmods);
+ WRITE_NODE_FIELD(funccolcollations);
+ WRITE_BITMAPSET_FIELD(funcparams);
+}
+
+static void
_outAExpr(StringInfo str, const A_Expr *node)
{
WRITE_NODE_TYPE("AEXPR");
@@ -2619,9 +2627,10 @@ _outRangeFunction(StringInfo str, const RangeFunction *node)
{
WRITE_NODE_TYPE("RANGEFUNCTION");
- WRITE_BOOL_FIELD(ordinality);
WRITE_BOOL_FIELD(lateral);
- WRITE_NODE_FIELD(funccallnode);
+ WRITE_BOOL_FIELD(ordinality);
+ WRITE_BOOL_FIELD(is_table);
+ WRITE_NODE_FIELD(functions);
WRITE_NODE_FIELD(alias);
WRITE_NODE_FIELD(coldeflist);
}
@@ -3156,6 +3165,9 @@ _outNode(StringInfo str, const void *obj)
case T_RangeTblEntry:
_outRangeTblEntry(str, obj);
break;
+ case T_RangeTblFunction:
+ _outRangeTblFunction(str, obj);
+ break;
case T_A_Expr:
_outAExpr(str, obj);
break;
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index d325bb3212..2e2cfa7af6 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -1220,10 +1220,7 @@ _readRangeTblEntry(void)
READ_NODE_FIELD(joinaliasvars);
break;
case RTE_FUNCTION:
- READ_NODE_FIELD(funcexpr);
- READ_NODE_FIELD(funccoltypes);
- READ_NODE_FIELD(funccoltypmods);
- READ_NODE_FIELD(funccolcollations);
+ READ_NODE_FIELD(functions);
READ_BOOL_FIELD(funcordinality);
break;
case RTE_VALUES:
@@ -1255,6 +1252,25 @@ _readRangeTblEntry(void)
READ_DONE();
}
+/*
+ * _readRangeTblFunction
+ */
+static RangeTblFunction *
+_readRangeTblFunction(void)
+{
+ READ_LOCALS(RangeTblFunction);
+
+ READ_NODE_FIELD(funcexpr);
+ READ_INT_FIELD(funccolcount);
+ READ_NODE_FIELD(funccolnames);
+ READ_NODE_FIELD(funccoltypes);
+ READ_NODE_FIELD(funccoltypmods);
+ READ_NODE_FIELD(funccolcollations);
+ READ_BITMAPSET_FIELD(funcparams);
+
+ READ_DONE();
+}
+
/*
* parseNodeString
@@ -1378,6 +1394,8 @@ parseNodeString(void)
return_value = _readFromExpr();
else if (MATCH("RTE", 3))
return_value = _readRangeTblEntry();
+ else if (MATCH("RANGETBLFUNCTION", 16))
+ return_value = _readRangeTblFunction();
else if (MATCH("NOTIFY", 6))
return_value = _readNotifyStmt();
else if (MATCH("DECLARECURSOR", 13))