lateral_srf_in_from_002.patch

text/plain

Filename: lateral_srf_in_from_002.patch
Type: text/plain
Part: 0
Message: Re: LATERAL, UNNEST and spec compliance

Patch

Format: context
File+
src/backend/parser/gram.y 1 0
src/backend/utils/adt/ruleutils.c 1 0
src/test/regress/expected/join.out 0 0
src/test/regress/expected/rangefuncs.out 7 0
src/test/regress/sql/join.sql 0 0
*** a/src/backend/parser/gram.y
--- b/src/backend/parser/gram.y
***************
*** 9391,9397 **** table_ref:	relation_expr opt_alias_clause
  			| func_table func_alias_clause
  				{
  					RangeFunction *n = makeNode(RangeFunction);
! 					n->lateral = false;
  					n->funccallnode = $1;
  					n->alias = linitial($2);
  					n->coldeflist = lsecond($2);
--- 9391,9397 ----
  			| func_table func_alias_clause
  				{
  					RangeFunction *n = makeNode(RangeFunction);
! 					n->lateral = true;
  					n->funccallnode = $1;
  					n->alias = linitial($2);
  					n->coldeflist = lsecond($2);
*** a/src/backend/utils/adt/ruleutils.c
--- b/src/backend/utils/adt/ruleutils.c
***************
*** 7928,7934 **** get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
  		deparse_columns *colinfo = deparse_columns_fetch(varno, dpns);
  		bool		printalias;
  
! 		if (rte->lateral)
  			appendStringInfoString(buf, "LATERAL ");
  
  		/* Print the FROM item proper */
--- 7928,7934 ----
  		deparse_columns *colinfo = deparse_columns_fetch(varno, dpns);
  		bool		printalias;
  
! 		if (rte->lateral && rte->rtekind != RTE_FUNCTION)
  			appendStringInfoString(buf, "LATERAL ");
  
  		/* Print the FROM item proper */
*** a/src/test/regress/expected/join.out
--- b/src/test/regress/expected/join.out
***************
*** 3577,3603 **** select * from
           Output: (COALESCE((COALESCE(b.q2, 42::bigint)), d.q2))
  (26 rows)
  
- -- test some error cases where LATERAL should have been used but wasn't
- select f1,g from int4_tbl a, generate_series(0, f1) g;
- ERROR:  column "f1" does not exist
- LINE 1: select f1,g from int4_tbl a, generate_series(0, f1) g;
-                                                         ^
- HINT:  There is a column named "f1" in table "a", but it cannot be referenced from this part of the query.
- select f1,g from int4_tbl a, generate_series(0, a.f1) g;
- ERROR:  invalid reference to FROM-clause entry for table "a"
- LINE 1: select f1,g from int4_tbl a, generate_series(0, a.f1) g;
-                                                         ^
- HINT:  There is an entry for table "a", but it cannot be referenced from this part of the query.
- select f1,g from int4_tbl a cross join generate_series(0, f1) g;
- ERROR:  column "f1" does not exist
- LINE 1: ...ct f1,g from int4_tbl a cross join generate_series(0, f1) g;
-                                                                  ^
- HINT:  There is a column named "f1" in table "a", but it cannot be referenced from this part of the query.
- select f1,g from int4_tbl a cross join generate_series(0, a.f1) g;
- ERROR:  invalid reference to FROM-clause entry for table "a"
- LINE 1: ... f1,g from int4_tbl a cross join generate_series(0, a.f1) g;
-                                                                ^
- HINT:  There is an entry for table "a", but it cannot be referenced from this part of the query.
  -- SQL:2008 says the left table is in scope but illegal to access here
  select f1,g from int4_tbl a right join lateral generate_series(0, a.f1) g on true;
  ERROR:  invalid reference to FROM-clause entry for table "a"
--- 3577,3582 ----
*** a/src/test/regress/expected/rangefuncs.out
--- b/src/test/regress/expected/rangefuncs.out
***************
*** 21,30 **** INSERT INTO foo2 VALUES(1, 111);
  CREATE FUNCTION foot(int) returns setof foo2 as 'SELECT * FROM foo2 WHERE fooid = $1;' LANGUAGE SQL;
  -- supposed to fail with ERROR
  select * from foo2, foot(foo2.fooid) z where foo2.f2 = z.f2;
! ERROR:  invalid reference to FROM-clause entry for table "foo2"
! LINE 1: select * from foo2, foot(foo2.fooid) z where foo2.f2 = z.f2;
!                                  ^
! HINT:  There is an entry for table "foo2", but it cannot be referenced from this part of the query.
  -- function in subselect
  select * from foo2 where f2 in (select f2 from foot(foo2.fooid) z where z.fooid = foo2.fooid) ORDER BY 1,2;
   fooid | f2  
--- 21,33 ----
  CREATE FUNCTION foot(int) returns setof foo2 as 'SELECT * FROM foo2 WHERE fooid = $1;' LANGUAGE SQL;
  -- supposed to fail with ERROR
  select * from foo2, foot(foo2.fooid) z where foo2.f2 = z.f2;
!  fooid | f2  | fooid | f2  
! -------+-----+-------+-----
!      1 |  11 |     1 |  11
!      2 |  22 |     2 |  22
!      1 | 111 |     1 | 111
! (3 rows)
! 
  -- function in subselect
  select * from foo2 where f2 in (select f2 from foot(foo2.fooid) z where z.fooid = foo2.fooid) ORDER BY 1,2;
   fooid | f2  
*** a/src/test/regress/sql/join.sql
--- b/src/test/regress/sql/join.sql
***************
*** 986,996 **** select * from
    ) on c.q2 = ss2.q1,
    lateral (select ss2.y) ss3;
  
- -- test some error cases where LATERAL should have been used but wasn't
- select f1,g from int4_tbl a, generate_series(0, f1) g;
- select f1,g from int4_tbl a, generate_series(0, a.f1) g;
- select f1,g from int4_tbl a cross join generate_series(0, f1) g;
- select f1,g from int4_tbl a cross join generate_series(0, a.f1) g;
  -- SQL:2008 says the left table is in scope but illegal to access here
  select f1,g from int4_tbl a right join lateral generate_series(0, a.f1) g on true;
  select f1,g from int4_tbl a full join lateral generate_series(0, a.f1) g on true;
--- 986,991 ----