On Thu, Jan 24, 2013 at 09:12:41PM -0800, David Fetter wrote: > On Thu, Jan 24, 2013 at 09:51:46AM -0800, David Fetter wrote: > > Folks, > > > > Andrew Gierth asked me to send this out as his email is in a parlous > > state at the moment. My comments will follow in replies. Without > > further ado: > > [snip] > > > > As I see it, the current options are: > > > > 1. Do nothing, and insist on non-standard use of the LATERAL keyword. > > > > 2. Add UNNEST to the grammar (or parse analysis) as a special case, making > > it implicitly LATERAL. > > > > (This would make implementing S301 easier, but special cases are ugly.) > > > > 3. Make all cases of SRFs in the FROM-clause implicitly LATERAL. > > > > (As far as I can tell, those cases whose behaviour would be changed by > > this actually produce errors in versions prior to 9.3, so no working > > code should be affected.) > > > > Since LATERAL is new in 9.3, I think the pros and cons of these choices > > should be considered now, rather than being allowed to slide by unexamined. > > Please find attached a patch which implements approach 3. The vast > majority of it is changes to the regression tests. The removed > regression tests in join.{sql,out} are no longer errors, although some > of them are pretty standard DoS attacks, hence they're all removed. > > Cheers, > David.
Oops. Misspelled rtekind in the previous patch. Here's a corrected one, much shorter. Cheers, David. -- David Fetter <da...@fetter.org> http://fetter.org/ Phone: +1 415 235 3778 AIM: dfetter666 Yahoo!: dfetter Skype: davidfetter XMPP: david.fet...@gmail.com iCal: webcal://www.tripit.com/feed/ical/people/david74/tripit.ics Remember to vote! Consider donating to Postgres: http://www.postgresql.org/about/donate
*** 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 ----
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers