1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-19 13:42:17 +03:00

Rename TABLE() to ROWS FROM().

SQL-standard TABLE() is a subset of UNNEST(); they deal with arrays and
other collection types.  This feature, however, deals with set-returning
functions.  Use a different syntax for this feature to keep open the
possibility of implementing the standard TABLE().
This commit is contained in:
Noah Misch
2013-12-10 09:34:37 -05:00
parent 01cc1fecfd
commit 53685d7981
11 changed files with 123 additions and 123 deletions

View File

@@ -2310,7 +2310,7 @@ _copyRangeFunction(const RangeFunction *from)
COPY_SCALAR_FIELD(lateral);
COPY_SCALAR_FIELD(ordinality);
COPY_SCALAR_FIELD(is_table);
COPY_SCALAR_FIELD(is_rowsfrom);
COPY_NODE_FIELD(functions);
COPY_NODE_FIELD(alias);
COPY_NODE_FIELD(coldeflist);

View File

@@ -2142,7 +2142,7 @@ _equalRangeFunction(const RangeFunction *a, const RangeFunction *b)
{
COMPARE_SCALAR_FIELD(lateral);
COMPARE_SCALAR_FIELD(ordinality);
COMPARE_SCALAR_FIELD(is_table);
COMPARE_SCALAR_FIELD(is_rowsfrom);
COMPARE_NODE_FIELD(functions);
COMPARE_NODE_FIELD(alias);
COMPARE_NODE_FIELD(coldeflist);

View File

@@ -2629,7 +2629,7 @@ _outRangeFunction(StringInfo str, const RangeFunction *node)
WRITE_BOOL_FIELD(lateral);
WRITE_BOOL_FIELD(ordinality);
WRITE_BOOL_FIELD(is_table);
WRITE_BOOL_FIELD(is_rowsfrom);
WRITE_NODE_FIELD(functions);
WRITE_NODE_FIELD(alias);
WRITE_NODE_FIELD(coldeflist);

View File

@@ -406,7 +406,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
a_expr b_expr c_expr AexprConst indirection_el
columnref in_expr having_clause func_table array_expr
ExclusionWhereClause
%type <list> func_table_item func_table_list opt_col_def_list
%type <list> rowsfrom_item rowsfrom_list opt_col_def_list
%type <boolean> opt_ordinality
%type <list> ExclusionConstraintList ExclusionConstraintElem
%type <list> func_arg_list
@@ -9980,13 +9980,13 @@ relation_expr_opt_alias: relation_expr %prec UMINUS
/*
* func_table represents a function invocation in a FROM list. It can be
* a plain function call, like "foo(...)", or a TABLE expression with
* one or more function calls, "TABLE (foo(...), bar(...))",
* a plain function call, like "foo(...)", or a ROWS FROM expression with
* one or more function calls, "ROWS FROM (foo(...), bar(...))",
* optionally with WITH ORDINALITY attached.
* In the TABLE syntax, a column definition list can be given for each
* In the ROWS FROM syntax, a column definition list can be given for each
* function, for example:
* TABLE (foo() AS (foo_res_a text, foo_res_b text),
* bar() AS (bar_res_a text, bar_res_b text))
* ROWS FROM (foo() AS (foo_res_a text, foo_res_b text),
* bar() AS (bar_res_a text, bar_res_b text))
* It's also possible to attach a column definition list to the RangeFunction
* as a whole, but that's handled by the table_ref production.
*/
@@ -9995,29 +9995,30 @@ func_table: func_expr_windowless opt_ordinality
RangeFunction *n = makeNode(RangeFunction);
n->lateral = false;
n->ordinality = $2;
n->is_table = false;
n->is_rowsfrom = false;
n->functions = list_make1(list_make2($1, NIL));
/* alias and coldeflist are set by table_ref production */
$$ = (Node *) n;
}
| TABLE '(' func_table_list ')' opt_ordinality
| ROWS FROM '(' rowsfrom_list ')' opt_ordinality
{
RangeFunction *n = makeNode(RangeFunction);
n->lateral = false;
n->ordinality = $5;
n->is_table = true;
n->functions = $3;
n->ordinality = $6;
n->is_rowsfrom = true;
n->functions = $4;
/* alias and coldeflist are set by table_ref production */
$$ = (Node *) n;
}
;
func_table_item: func_expr_windowless opt_col_def_list
rowsfrom_item: func_expr_windowless opt_col_def_list
{ $$ = list_make2($1, $2); }
;
func_table_list: func_table_item { $$ = list_make1($1); }
| func_table_list ',' func_table_item { $$ = lappend($1, $3); }
rowsfrom_list:
rowsfrom_item { $$ = list_make1($1); }
| rowsfrom_list ',' rowsfrom_item { $$ = lappend($1, $3); }
;
opt_col_def_list: AS '(' TableFuncElementList ')' { $$ = $3; }

View File

@@ -655,25 +655,25 @@ transformRangeFunction(ParseState *pstate, RangeFunction *r)
* expansion) and no WITH ORDINALITY. The reason for the latter
* restriction is that it's not real clear whether the ordinality column
* should be in the coldeflist, and users are too likely to make mistakes
* in one direction or the other. Putting the coldeflist inside TABLE()
* is much clearer in this case.
* in one direction or the other. Putting the coldeflist inside ROWS
* FROM() is much clearer in this case.
*/
if (r->coldeflist)
{
if (list_length(funcexprs) != 1)
{
if (r->is_table)
if (r->is_rowsfrom)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("TABLE() with multiple functions cannot have a column definition list"),
errhint("Put a separate column definition list for each function inside TABLE()."),
errmsg("ROWS FROM() with multiple functions cannot have a column definition list"),
errhint("Put a separate column definition list for each function inside ROWS FROM()."),
parser_errposition(pstate,
exprLocation((Node *) r->coldeflist))));
else
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("UNNEST() with multiple arguments cannot have a column definition list"),
errhint("Use separate UNNEST() calls inside TABLE(), and attach a column definition list to each one."),
errhint("Use separate UNNEST() calls inside ROWS FROM(), and attach a column definition list to each one."),
parser_errposition(pstate,
exprLocation((Node *) r->coldeflist))));
}
@@ -681,7 +681,7 @@ transformRangeFunction(ParseState *pstate, RangeFunction *r)
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("WITH ORDINALITY cannot be used with a column definition list"),
errhint("Put the column definition list inside TABLE()."),
errhint("Put the column definition list inside ROWS FROM()."),
parser_errposition(pstate,
exprLocation((Node *) r->coldeflist))));

View File

@@ -8125,10 +8125,10 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
rtfunc1 = (RangeTblFunction *) linitial(rte->functions);
/*
* Omit TABLE() syntax if there's just one function, unless it
* Omit ROWS FROM() syntax for just one function, unless it
* has both a coldeflist and WITH ORDINALITY. If it has both,
* we must use TABLE() syntax to avoid ambiguity about whether
* the coldeflist includes the ordinality column.
* we must use ROWS FROM() syntax to avoid ambiguity about
* whether the coldeflist includes the ordinality column.
*/
if (list_length(rte->functions) == 1 &&
(rtfunc1->funccolnames == NIL || !rte->funcordinality))
@@ -8151,8 +8151,8 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
* XXX This is pretty ugly, since it makes not-terribly-
* future-proof assumptions about what the parser would do
* with the output; but the alternative is to emit our
* nonstandard extended TABLE() notation for what might
* have been a perfectly spec-compliant multi-argument
* nonstandard ROWS FROM() notation for what might have
* been a perfectly spec-compliant multi-argument
* UNNEST().
*/
all_unnest = true;
@@ -8189,7 +8189,7 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
{
int funcno = 0;
appendStringInfoString(buf, "TABLE(");
appendStringInfoString(buf, "ROWS FROM(");
foreach(lc, rte->functions)
{
RangeTblFunction *rtfunc = (RangeTblFunction *) lfirst(lc);
@@ -8422,7 +8422,7 @@ get_column_alias_list(deparse_columns *colinfo, deparse_context *context)
*
* When printing a top-level coldeflist (which is syntactically also the
* relation's column alias list), use column names from colinfo. But when
* printing a coldeflist embedded inside TABLE(), we prefer to use the
* printing a coldeflist embedded inside ROWS FROM(), we prefer to use the
* original coldeflist's names, which are available in rtfunc->funccolnames.
* Pass NULL for colinfo to select the latter behavior.
*

View File

@@ -466,11 +466,11 @@ 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
* ROWS FROM(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.
* ROWS FROM() syntax.
*
* alias and coldeflist represent any alias and/or columndef list attached
* at the top level. (We disallow coldeflist appearing both here and
@@ -481,7 +481,7 @@ typedef struct RangeFunction
NodeTag type;
bool lateral; /* does it have LATERAL prefix? */
bool ordinality; /* does it have WITH ORDINALITY suffix? */
bool is_table; /* is result of TABLE() syntax? */
bool is_rowsfrom; /* is result of ROWS FROM() syntax? */
List *functions; /* per-function information, see above */
Alias *alias; /* table alias & optional column aliases */
List *coldeflist; /* list of ColumnDef nodes to describe result

View File

@@ -97,14 +97,14 @@ select definition from pg_views where viewname='vw_ord';
drop view vw_ord;
-- multiple functions
select * from table(foot(1),foot(2)) with ordinality as z(a,b,c,d,ord);
select * from rows from(foot(1),foot(2)) with ordinality as z(a,b,c,d,ord);
a | b | c | d | ord
---+-----+---+----+-----
1 | 11 | 2 | 22 | 1
1 | 111 | | | 2
(2 rows)
create temporary view vw_ord as select * from (values (1)) v(n) join table(foot(1),foot(2)) with ordinality as z(a,b,c,d,ord) on (n=ord);
create temporary view vw_ord as select * from (values (1)) v(n) join rows from(foot(1),foot(2)) with ordinality as z(a,b,c,d,ord) on (n=ord);
select * from vw_ord;
n | a | b | c | d | ord
---+---+----+---+----+-----
@@ -112,16 +112,16 @@ select * from vw_ord;
(1 row)
select definition from pg_views where viewname='vw_ord';
definition
-----------------------------------------------------------------------------------------
SELECT v.n, +
z.a, +
z.b, +
z.c, +
z.d, +
z.ord +
FROM (( VALUES (1)) v(n) +
JOIN TABLE(foot(1), foot(2)) WITH ORDINALITY z(a, b, c, d, ord) ON ((v.n = z.ord)));
definition
---------------------------------------------------------------------------------------------
SELECT v.n, +
z.a, +
z.b, +
z.c, +
z.d, +
z.ord +
FROM (( VALUES (1)) v(n) +
JOIN ROWS FROM(foot(1), foot(2)) WITH ORDINALITY z(a, b, c, d, ord) ON ((v.n = z.ord)));
(1 row)
drop view vw_ord;
@@ -140,14 +140,14 @@ select * from unnest(array[10,20],array['foo','bar'],array[1.0]) with ordinality
20 | bar | | 2
(2 rows)
select * from table(unnest(array[10,20],array['foo','bar'],array[1.0])) with ordinality as z(a,b,c,ord);
select * from rows from(unnest(array[10,20],array['foo','bar'],array[1.0])) with ordinality as z(a,b,c,ord);
a | b | c | ord
----+-----+-----+-----
10 | foo | 1.0 | 1
20 | bar | | 2
(2 rows)
select * from table(unnest(array[10,20],array['foo','bar']), generate_series(101,102)) with ordinality as z(a,b,c,ord);
select * from rows from(unnest(array[10,20],array['foo','bar']), generate_series(101,102)) with ordinality as z(a,b,c,ord);
a | b | c | ord
----+-----+-----+-----
10 | foo | 101 | 1
@@ -172,7 +172,7 @@ select definition from pg_views where viewname='vw_ord';
(1 row)
drop view vw_ord;
create temporary view vw_ord as select * from table(unnest(array[10,20],array['foo','bar'],array[1.0])) as z(a,b,c);
create temporary view vw_ord as select * from rows from(unnest(array[10,20],array['foo','bar'],array[1.0])) as z(a,b,c);
select * from vw_ord;
a | b | c
----+-----+-----
@@ -190,7 +190,7 @@ select definition from pg_views where viewname='vw_ord';
(1 row)
drop view vw_ord;
create temporary view vw_ord as select * from table(unnest(array[10,20],array['foo','bar']), generate_series(1,2)) as z(a,b,c);
create temporary view vw_ord as select * from rows from(unnest(array[10,20],array['foo','bar']), generate_series(1,2)) as z(a,b,c);
select * from vw_ord;
a | b | c
----+-----+---
@@ -199,18 +199,18 @@ select * from vw_ord;
(2 rows)
select definition from pg_views where viewname='vw_ord';
definition
------------------------------------------------------------------------------------------------------------------
SELECT z.a, +
z.b, +
z.c +
FROM TABLE(unnest(ARRAY[10, 20]), unnest(ARRAY['foo'::text, 'bar'::text]), generate_series(1, 2)) z(a, b, c);
definition
----------------------------------------------------------------------------------------------------------------------
SELECT z.a, +
z.b, +
z.c +
FROM ROWS FROM(unnest(ARRAY[10, 20]), unnest(ARRAY['foo'::text, 'bar'::text]), generate_series(1, 2)) z(a, b, c);
(1 row)
drop view vw_ord;
-- ordinality and multiple functions vs. rewind and reverse scan
begin;
declare foo scroll cursor for select * from table(generate_series(1,5),generate_series(1,2)) with ordinality as g(i,j,o);
declare foo scroll cursor for select * from rows from(generate_series(1,5),generate_series(1,2)) with ordinality as g(i,j,o);
fetch all from foo;
i | j | o
---+---+---
@@ -525,7 +525,7 @@ SELECT * FROM getfoo6(1) AS t1(fooid int, foosubid int, fooname text);
1 | 1 | Joe
(1 row)
SELECT * FROM TABLE( getfoo6(1) AS (fooid int, foosubid int, fooname text) ) WITH ORDINALITY;
SELECT * FROM ROWS FROM( getfoo6(1) AS (fooid int, foosubid int, fooname text) ) WITH ORDINALITY;
fooid | foosubid | fooname | ordinality
-------+----------+---------+------------
1 | 1 | Joe | 1
@@ -541,7 +541,7 @@ SELECT * FROM vw_getfoo;
DROP VIEW vw_getfoo;
CREATE VIEW vw_getfoo AS
SELECT * FROM TABLE( getfoo6(1) AS (fooid int, foosubid int, fooname text) )
SELECT * FROM ROWS FROM( getfoo6(1) AS (fooid int, foosubid int, fooname text) )
WITH ORDINALITY;
SELECT * FROM vw_getfoo;
fooid | foosubid | fooname | ordinality
@@ -559,7 +559,7 @@ SELECT * FROM getfoo7(1) AS t1(fooid int, foosubid int, fooname text);
1 | 2 | Ed
(2 rows)
SELECT * FROM TABLE( getfoo7(1) AS (fooid int, foosubid int, fooname text) ) WITH ORDINALITY;
SELECT * FROM ROWS FROM( getfoo7(1) AS (fooid int, foosubid int, fooname text) ) WITH ORDINALITY;
fooid | foosubid | fooname | ordinality
-------+----------+---------+------------
1 | 1 | Joe | 1
@@ -577,7 +577,7 @@ SELECT * FROM vw_getfoo;
DROP VIEW vw_getfoo;
CREATE VIEW vw_getfoo AS
SELECT * FROM TABLE( getfoo7(1) AS (fooid int, foosubid int, fooname text) )
SELECT * FROM ROWS FROM( getfoo7(1) AS (fooid int, foosubid int, fooname text) )
WITH ORDINALITY;
SELECT * FROM vw_getfoo;
fooid | foosubid | fooname | ordinality
@@ -648,7 +648,7 @@ SELECT * FROM vw_getfoo;
DROP VIEW vw_getfoo;
-- mix 'n match kinds, to exercise expandRTE and related logic
select * from table(getfoo1(1),getfoo2(1),getfoo3(1),getfoo4(1),getfoo5(1),
select * from rows from(getfoo1(1),getfoo2(1),getfoo3(1),getfoo4(1),getfoo5(1),
getfoo6(1) AS (fooid int, foosubid int, fooname text),
getfoo7(1) AS (fooid int, foosubid int, fooname text),
getfoo8(1),getfoo9(1))
@@ -659,7 +659,7 @@ select * from table(getfoo1(1),getfoo2(1),getfoo3(1),getfoo4(1),getfoo5(1),
| 1 | Ed | | | | 1 | 2 | Ed | | | | 1 | 2 | Ed | | | | | 2
(2 rows)
select * from table(getfoo9(1),getfoo8(1),
select * from rows from(getfoo9(1),getfoo8(1),
getfoo7(1) AS (fooid int, foosubid int, fooname text),
getfoo6(1) AS (fooid int, foosubid int, fooname text),
getfoo5(1),getfoo4(1),getfoo3(1),getfoo2(1),getfoo1(1))
@@ -671,7 +671,7 @@ select * from table(getfoo9(1),getfoo8(1),
(2 rows)
create temporary view vw_foo as
select * from table(getfoo9(1),
select * from rows from(getfoo9(1),
getfoo7(1) AS (fooid int, foosubid int, fooname text),
getfoo1(1))
with ordinality as t1(a,b,c,d,e,f,g,n);
@@ -683,17 +683,17 @@ select * from vw_foo;
(2 rows)
select pg_get_viewdef('vw_foo');
pg_get_viewdef
--------------------------------------------------------------------------------------------------------------------------------------------------
SELECT t1.a, +
t1.b, +
t1.c, +
t1.d, +
t1.e, +
t1.f, +
t1.g, +
t1.n +
FROM TABLE(getfoo9(1), getfoo7(1) AS (fooid integer, foosubid integer, fooname text), getfoo1(1)) WITH ORDINALITY t1(a, b, c, d, e, f, g, n);
pg_get_viewdef
------------------------------------------------------------------------------------------------------------------------------------------------------
SELECT t1.a, +
t1.b, +
t1.c, +
t1.d, +
t1.e, +
t1.f, +
t1.g, +
t1.n +
FROM ROWS FROM(getfoo9(1), getfoo7(1) AS (fooid integer, foosubid integer, fooname text), getfoo1(1)) WITH ORDINALITY t1(a, b, c, d, e, f, g, n);
(1 row)
drop view vw_foo;
@@ -805,7 +805,7 @@ SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
1 | 1
(1 row)
SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN TABLE( foo_sql(11,13), foo_mat(11,13) ) WITH ORDINALITY AS f(i1,s1,i2,s2,o) ON (r+i1+i2)<100;
SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN ROWS FROM( foo_sql(11,13), foo_mat(11,13) ) WITH ORDINALITY AS f(i1,s1,i2,s2,o) ON (r+i1+i2)<100;
r | i1 | s1 | i2 | s2 | o
---+----+----+----+----+---
1 | 11 | 1 | 11 | 1 | 1
@@ -1103,7 +1103,7 @@ SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
1 | 1
(1 row)
SELECT * FROM (VALUES (1),(2),(3)) v(r), TABLE( foo_sql(11,11), foo_mat(10+r,13) );
SELECT * FROM (VALUES (1),(2),(3)) v(r), ROWS FROM( foo_sql(11,11), foo_mat(10+r,13) );
r | i | s | i | s
---+----+---+----+---
1 | 11 | 1 | 11 | 1
@@ -1120,7 +1120,7 @@ SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
1 | 1
(1 row)
SELECT * FROM (VALUES (1),(2),(3)) v(r), TABLE( foo_sql(10+r,13), foo_mat(11,11) );
SELECT * FROM (VALUES (1),(2),(3)) v(r), ROWS FROM( foo_sql(10+r,13), foo_mat(11,11) );
r | i | s | i | s
---+----+---+----+---
1 | 11 | 1 | 11 | 1
@@ -1137,7 +1137,7 @@ SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
1 | 1
(1 row)
SELECT * FROM (VALUES (1),(2),(3)) v(r), TABLE( foo_sql(10+r,13), foo_mat(10+r,13) );
SELECT * FROM (VALUES (1),(2),(3)) v(r), ROWS FROM( foo_sql(10+r,13), foo_mat(10+r,13) );
r | i | s | i | s
---+----+---+----+---
1 | 11 | 1 | 11 | 1
@@ -1154,7 +1154,7 @@ SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
1 | 1
(1 row)
SELECT * FROM generate_series(1,2) r1, generate_series(r1,3) r2, TABLE( foo_sql(10+r1,13), foo_mat(10+r2,13) );
SELECT * FROM generate_series(1,2) r1, generate_series(r1,3) r2, ROWS FROM( foo_sql(10+r1,13), foo_mat(10+r2,13) );
r1 | r2 | i | s | i | s
----+----+----+----+----+---
1 | 1 | 11 | 1 | 11 | 1
@@ -1905,14 +1905,14 @@ SELECT * FROM get_users() WITH ORDINALITY; -- make sure ordinality copes
(2 rows)
-- multiple functions vs. dropped columns
SELECT * FROM TABLE(generate_series(10,11), get_users()) WITH ORDINALITY;
SELECT * FROM ROWS FROM(generate_series(10,11), get_users()) WITH ORDINALITY;
generate_series | userid | seq | email | moredrop | enabled | ordinality
-----------------+--------+-----+--------+----------+---------+------------
10 | id | 1 | email | 11 | t | 1
11 | id2 | 2 | email2 | 12 | t | 2
(2 rows)
SELECT * FROM TABLE(get_users(), generate_series(10,11)) WITH ORDINALITY;
SELECT * FROM ROWS FROM(get_users(), generate_series(10,11)) WITH ORDINALITY;
userid | seq | email | moredrop | enabled | generate_series | ordinality
--------+-----+--------+----------+---------+-----------------+------------
id | 1 | email | 11 | t | 10 | 1
@@ -1921,7 +1921,7 @@ SELECT * FROM TABLE(get_users(), generate_series(10,11)) WITH ORDINALITY;
-- check that we can cope with post-parsing changes in rowtypes
create temp view usersview as
SELECT * FROM TABLE(get_users(), generate_series(10,11)) WITH ORDINALITY;
SELECT * FROM ROWS FROM(get_users(), generate_series(10,11)) WITH ORDINALITY;
select * from usersview;
userid | seq | email | moredrop | enabled | generate_series | ordinality
--------+-----+--------+----------+---------+-----------------+------------

View File

@@ -24,8 +24,8 @@ select definition from pg_views where viewname='vw_ord';
drop view vw_ord;
-- multiple functions
select * from table(foot(1),foot(2)) with ordinality as z(a,b,c,d,ord);
create temporary view vw_ord as select * from (values (1)) v(n) join table(foot(1),foot(2)) with ordinality as z(a,b,c,d,ord) on (n=ord);
select * from rows from(foot(1),foot(2)) with ordinality as z(a,b,c,d,ord);
create temporary view vw_ord as select * from (values (1)) v(n) join rows from(foot(1),foot(2)) with ordinality as z(a,b,c,d,ord) on (n=ord);
select * from vw_ord;
select definition from pg_views where viewname='vw_ord';
drop view vw_ord;
@@ -33,24 +33,24 @@ drop view vw_ord;
-- expansions of unnest()
select * from unnest(array[10,20],array['foo','bar'],array[1.0]);
select * from unnest(array[10,20],array['foo','bar'],array[1.0]) with ordinality as z(a,b,c,ord);
select * from table(unnest(array[10,20],array['foo','bar'],array[1.0])) with ordinality as z(a,b,c,ord);
select * from table(unnest(array[10,20],array['foo','bar']), generate_series(101,102)) with ordinality as z(a,b,c,ord);
select * from rows from(unnest(array[10,20],array['foo','bar'],array[1.0])) with ordinality as z(a,b,c,ord);
select * from rows from(unnest(array[10,20],array['foo','bar']), generate_series(101,102)) with ordinality as z(a,b,c,ord);
create temporary view vw_ord as select * from unnest(array[10,20],array['foo','bar'],array[1.0]) as z(a,b,c);
select * from vw_ord;
select definition from pg_views where viewname='vw_ord';
drop view vw_ord;
create temporary view vw_ord as select * from table(unnest(array[10,20],array['foo','bar'],array[1.0])) as z(a,b,c);
create temporary view vw_ord as select * from rows from(unnest(array[10,20],array['foo','bar'],array[1.0])) as z(a,b,c);
select * from vw_ord;
select definition from pg_views where viewname='vw_ord';
drop view vw_ord;
create temporary view vw_ord as select * from table(unnest(array[10,20],array['foo','bar']), generate_series(1,2)) as z(a,b,c);
create temporary view vw_ord as select * from rows from(unnest(array[10,20],array['foo','bar']), generate_series(1,2)) as z(a,b,c);
select * from vw_ord;
select definition from pg_views where viewname='vw_ord';
drop view vw_ord;
-- ordinality and multiple functions vs. rewind and reverse scan
begin;
declare foo scroll cursor for select * from table(generate_series(1,5),generate_series(1,2)) with ordinality as g(i,j,o);
declare foo scroll cursor for select * from rows from(generate_series(1,5),generate_series(1,2)) with ordinality as g(i,j,o);
fetch all from foo;
fetch backward all from foo;
fetch all from foo;
@@ -147,13 +147,13 @@ DROP VIEW vw_getfoo;
-- sql, proretset = f, prorettype = record
CREATE FUNCTION getfoo6(int) RETURNS RECORD AS 'SELECT * FROM foo WHERE fooid = $1;' LANGUAGE SQL;
SELECT * FROM getfoo6(1) AS t1(fooid int, foosubid int, fooname text);
SELECT * FROM TABLE( getfoo6(1) AS (fooid int, foosubid int, fooname text) ) WITH ORDINALITY;
SELECT * FROM ROWS FROM( getfoo6(1) AS (fooid int, foosubid int, fooname text) ) WITH ORDINALITY;
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo6(1) AS
(fooid int, foosubid int, fooname text);
SELECT * FROM vw_getfoo;
DROP VIEW vw_getfoo;
CREATE VIEW vw_getfoo AS
SELECT * FROM TABLE( getfoo6(1) AS (fooid int, foosubid int, fooname text) )
SELECT * FROM ROWS FROM( getfoo6(1) AS (fooid int, foosubid int, fooname text) )
WITH ORDINALITY;
SELECT * FROM vw_getfoo;
DROP VIEW vw_getfoo;
@@ -161,13 +161,13 @@ DROP VIEW vw_getfoo;
-- sql, proretset = t, prorettype = record
CREATE FUNCTION getfoo7(int) RETURNS setof record AS 'SELECT * FROM foo WHERE fooid = $1;' LANGUAGE SQL;
SELECT * FROM getfoo7(1) AS t1(fooid int, foosubid int, fooname text);
SELECT * FROM TABLE( getfoo7(1) AS (fooid int, foosubid int, fooname text) ) WITH ORDINALITY;
SELECT * FROM ROWS FROM( getfoo7(1) AS (fooid int, foosubid int, fooname text) ) WITH ORDINALITY;
CREATE VIEW vw_getfoo AS SELECT * FROM getfoo7(1) AS
(fooid int, foosubid int, fooname text);
SELECT * FROM vw_getfoo;
DROP VIEW vw_getfoo;
CREATE VIEW vw_getfoo AS
SELECT * FROM TABLE( getfoo7(1) AS (fooid int, foosubid int, fooname text) )
SELECT * FROM ROWS FROM( getfoo7(1) AS (fooid int, foosubid int, fooname text) )
WITH ORDINALITY;
SELECT * FROM vw_getfoo;
DROP VIEW vw_getfoo;
@@ -196,19 +196,19 @@ DROP VIEW vw_getfoo;
-- mix 'n match kinds, to exercise expandRTE and related logic
select * from table(getfoo1(1),getfoo2(1),getfoo3(1),getfoo4(1),getfoo5(1),
select * from rows from(getfoo1(1),getfoo2(1),getfoo3(1),getfoo4(1),getfoo5(1),
getfoo6(1) AS (fooid int, foosubid int, fooname text),
getfoo7(1) AS (fooid int, foosubid int, fooname text),
getfoo8(1),getfoo9(1))
with ordinality as t1(a,b,c,d,e,f,g,h,i,j,k,l,m,o,p,q,r,s,t,u);
select * from table(getfoo9(1),getfoo8(1),
select * from rows from(getfoo9(1),getfoo8(1),
getfoo7(1) AS (fooid int, foosubid int, fooname text),
getfoo6(1) AS (fooid int, foosubid int, fooname text),
getfoo5(1),getfoo4(1),getfoo3(1),getfoo2(1),getfoo1(1))
with ordinality as t1(a,b,c,d,e,f,g,h,i,j,k,l,m,o,p,q,r,s,t,u);
create temporary view vw_foo as
select * from table(getfoo9(1),
select * from rows from(getfoo9(1),
getfoo7(1) AS (fooid int, foosubid int, fooname text),
getfoo1(1))
with ordinality as t1(a,b,c,d,e,f,g,n);
@@ -252,7 +252,7 @@ SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN foo_mat(11,13) ON (r+i)<100;
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN foo_mat(11,13) WITH ORDINALITY AS f(i,s,o) ON (r+i)<100;
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN TABLE( foo_sql(11,13), foo_mat(11,13) ) WITH ORDINALITY AS f(i1,s1,i2,s2,o) ON (r+i1+i2)<100;
SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN ROWS FROM( foo_sql(11,13), foo_mat(11,13) ) WITH ORDINALITY AS f(i1,s1,i2,s2,o) ON (r+i1+i2)<100;
SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN generate_series(11,13) f(i) ON (r+i)<100;
SELECT * FROM (VALUES (1),(2),(3)) v(r) LEFT JOIN generate_series(11,13) WITH ORDINALITY AS f(i,o) ON (r+i)<100;
@@ -291,14 +291,14 @@ SELECT * FROM (VALUES (11,12),(13,15),(16,20)) v(r1,r2), foo_mat(r1,r2) WITH ORD
-- selective rescan of multiple functions:
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r), TABLE( foo_sql(11,11), foo_mat(10+r,13) );
SELECT * FROM (VALUES (1),(2),(3)) v(r), ROWS FROM( foo_sql(11,11), foo_mat(10+r,13) );
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r), TABLE( foo_sql(10+r,13), foo_mat(11,11) );
SELECT * FROM (VALUES (1),(2),(3)) v(r), ROWS FROM( foo_sql(10+r,13), foo_mat(11,11) );
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT * FROM (VALUES (1),(2),(3)) v(r), TABLE( foo_sql(10+r,13), foo_mat(10+r,13) );
SELECT * FROM (VALUES (1),(2),(3)) v(r), ROWS FROM( foo_sql(10+r,13), foo_mat(10+r,13) );
SELECT setval('foo_rescan_seq1',1,false),setval('foo_rescan_seq2',1,false);
SELECT * FROM generate_series(1,2) r1, generate_series(r1,3) r2, TABLE( foo_sql(10+r1,13), foo_mat(10+r2,13) );
SELECT * FROM generate_series(1,2) r1, generate_series(r1,3) r2, ROWS FROM( foo_sql(10+r1,13), foo_mat(10+r2,13) );
SELECT * FROM (VALUES (1),(2),(3)) v(r), generate_series(10+r,20-r) f(i);
SELECT * FROM (VALUES (1),(2),(3)) v(r), generate_series(10+r,20-r) WITH ORDINALITY AS f(i,o);
@@ -550,12 +550,12 @@ SELECT * FROM get_users();
SELECT * FROM get_users() WITH ORDINALITY; -- make sure ordinality copes
-- multiple functions vs. dropped columns
SELECT * FROM TABLE(generate_series(10,11), get_users()) WITH ORDINALITY;
SELECT * FROM TABLE(get_users(), generate_series(10,11)) WITH ORDINALITY;
SELECT * FROM ROWS FROM(generate_series(10,11), get_users()) WITH ORDINALITY;
SELECT * FROM ROWS FROM(get_users(), generate_series(10,11)) WITH ORDINALITY;
-- check that we can cope with post-parsing changes in rowtypes
create temp view usersview as
SELECT * FROM TABLE(get_users(), generate_series(10,11)) WITH ORDINALITY;
SELECT * FROM ROWS FROM(get_users(), generate_series(10,11)) WITH ORDINALITY;
select * from usersview;
alter table users drop column moredrop;