aboutsummaryrefslogtreecommitdiff
path: root/src/include/nodes/parsenodes.h
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2013-11-21 19:37:02 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2013-11-21 19:37:20 -0500
commit784e762e886e6f72f548da86a27cd2ead87dbd1c (patch)
tree9c21fc1545c96a655ec4591e1ba3c8d99cdfccf8 /src/include/nodes/parsenodes.h
parent38f432898131270e5b64245786cb67f322538bae (diff)
downloadpostgresql-784e762e886e6f72f548da86a27cd2ead87dbd1c.tar.gz
postgresql-784e762e886e6f72f548da86a27cd2ead87dbd1c.zip
Support multi-argument UNNEST(), and TABLE() syntax for multiple functions.
This patch adds the ability to write TABLE( function1(), function2(), ...) as a single FROM-clause entry. The result is the concatenation of the first row from each function, followed by the second row from each function, etc; with NULLs inserted if any function produces fewer rows than others. This is believed to be a much more useful behavior than what Postgres currently does with multiple SRFs in a SELECT list. This syntax also provides a reasonable way to combine use of column definition lists with WITH ORDINALITY: put the column definition list inside TABLE(), where it's clear that it doesn't control the ordinality column as well. Also implement SQL-compliant multiple-argument UNNEST(), by turning UNNEST(a,b,c) into TABLE(unnest(a), unnest(b), unnest(c)). The SQL standard specifies TABLE() with only a single function, not multiple functions, and it seems to require an implicit UNNEST() which is not what this patch does. There may be something wrong with that reading of the spec, though, because if it's right then the spec's TABLE() is just a pointless alternative spelling of UNNEST(). After further review of that, we might choose to adopt a different syntax for what this patch does, but in any case this functionality seems clearly worthwhile. Andrew Gierth, reviewed by Zoltán Böszörményi and Heikki Linnakangas, and significantly revised by me
Diffstat (limited to 'src/include/nodes/parsenodes.h')
-rw-r--r--src/include/nodes/parsenodes.h83
1 files changed, 56 insertions, 27 deletions
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 55524b468ab..6a5555f918d 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -288,10 +288,8 @@ typedef struct CollateClause
* aggregate or some other kind of function. However, if FILTER or OVER is
* present it had better be an aggregate or window function.
*
- * Normally, you'd initialize this via makeFuncCall() and then only
- * change the parts of the struct its defaults don't match afterwards
- * if needed.
- *
+ * Normally, you'd initialize this via makeFuncCall() and then only change the
+ * parts of the struct its defaults don't match afterwards, as needed.
*/
typedef struct FuncCall
{
@@ -466,13 +464,25 @@ typedef struct RangeSubselect
/*
* RangeFunction - function call appearing in a FROM clause
+ *
+ * functions is a List because we use this to represent the construct
+ * TABLE(func1(...), func2(...), ...). Each element of this list is a
+ * two-element sublist, the first element being the untransformed function
+ * call tree, and the second element being a possibly-empty list of ColumnDef
+ * nodes representing any columndef list attached to that function within the
+ * TABLE() syntax.
+ *
+ * alias and coldeflist represent any alias and/or columndef list attached
+ * at the top level. (We disallow coldeflist appearing both here and
+ * per-function, but that's checked in parse analysis, not by the grammar.)
*/
typedef struct RangeFunction
{
NodeTag type;
bool lateral; /* does it have LATERAL prefix? */
bool ordinality; /* does it have WITH ORDINALITY suffix? */
- Node *funccallnode; /* untransformed function call tree */
+ bool is_table; /* is result of TABLE() syntax? */
+ List *functions; /* per-function information, see above */
Alias *alias; /* table alias & optional column aliases */
List *coldeflist; /* list of ColumnDef nodes to describe result
* of function returning RECORD */
@@ -512,6 +522,7 @@ typedef struct ColumnDef
Oid collOid; /* collation OID (InvalidOid if not set) */
List *constraints; /* other constraints on column */
List *fdwoptions; /* per-column FDW options */
+ int location; /* parse location, or -1 if none/unknown */
} ColumnDef;
/*
@@ -652,13 +663,8 @@ typedef struct XmlSerialize
* dropped columns. Note however that a stored rule may have nonempty
* colnames for columns dropped since the rule was created (and for that
* matter the colnames might be out of date due to column renamings).
- *
- * The same comments apply to FUNCTION RTEs when the function's return type
- * is a named composite type. In addition, for all return types, FUNCTION
- * RTEs with ORDINALITY must always have the last colname entry being the
- * one for the ordinal column; this is enforced when constructing the RTE.
- * Thus when ORDINALITY is used, there will be exactly one more colname
- * than would have been present otherwise.
+ * The same comments apply to FUNCTION RTEs when a function's return type
+ * is a named composite type.
*
* In JOIN RTEs, the colnames in both alias and eref are one-to-one with
* joinaliasvars entries. A JOIN RTE will omit columns of its inputs when
@@ -755,23 +761,15 @@ typedef struct RangeTblEntry
List *joinaliasvars; /* list of alias-var expansions */
/*
- * Fields valid for a function RTE (else NULL):
- *
- * If the function returns an otherwise-unspecified RECORD, funccoltypes
- * lists the column types declared in the RTE's column type specification,
- * funccoltypmods lists their declared typmods, funccolcollations their
- * collations. Note that in this case, ORDINALITY is not permitted, so
- * there is no extra ordinal column to be allowed for.
+ * Fields valid for a function RTE (else NIL/zero):
*
- * Otherwise, those fields are NIL, and the result column types must be
- * derived from the funcexpr while treating the ordinal column, if
- * present, as a special case. (see get_rte_attribute_*)
+ * When funcordinality is true, the eref->colnames list includes an alias
+ * for the ordinality column. The ordinality column is otherwise
+ * implicit, and must be accounted for "by hand" in places such as
+ * expandRTE().
*/
- Node *funcexpr; /* expression tree for func call */
- List *funccoltypes; /* OID list of column type OIDs */
- List *funccoltypmods; /* integer list of column typmods */
- List *funccolcollations; /* OID list of column collation OIDs */
- bool funcordinality; /* is this called WITH ORDINALITY? */
+ List *functions; /* list of RangeTblFunction nodes */
+ bool funcordinality; /* is this called WITH ORDINALITY? */
/*
* Fields valid for a values RTE (else NIL):
@@ -804,6 +802,37 @@ typedef struct RangeTblEntry
} RangeTblEntry;
/*
+ * RangeTblFunction -
+ * RangeTblEntry subsidiary data for one function in a FUNCTION RTE.
+ *
+ * If the function had a column definition list (required for an
+ * otherwise-unspecified RECORD result), funccolnames lists the names given
+ * in the definition list, funccoltypes lists their declared column types,
+ * funccoltypmods lists their typmods, funccolcollations their collations.
+ * Otherwise, those fields are NIL.
+ *
+ * Notice we don't attempt to store info about the results of functions
+ * returning named composite types, because those can change from time to
+ * time. We do however remember how many columns we thought the type had
+ * (including dropped columns!), so that we can successfully ignore any
+ * columns added after the query was parsed.
+ */
+typedef struct RangeTblFunction
+{
+ NodeTag type;
+
+ Node *funcexpr; /* expression tree for func call */
+ int funccolcount; /* number of columns it contributes to RTE */
+ /* These fields record the contents of a column definition list, if any: */
+ List *funccolnames; /* column names (list of String) */
+ List *funccoltypes; /* OID list of column type OIDs */
+ List *funccoltypmods; /* integer list of column typmods */
+ List *funccolcollations; /* OID list of column collation OIDs */
+ /* This is set during planning for use by the executor: */
+ Bitmapset *funcparams; /* PARAM_EXEC Param IDs affecting this func */
+} RangeTblFunction;
+
+/*
* WithCheckOption -
* representation of WITH CHECK OPTION checks to be applied to new tuples
* when inserting/updating an auto-updatable view.