-C Experimental\simplementation\sof\sLATERAL\sJOIN.
-D 2024-07-20T01:19:18.644
+C "LATERAL"\smay\snot\sbe\sa\skeyword,\sas\sthat\swould\scause\sproblems\sfor\slegacy\ndatabases\sthat\shave\stables\snamed\s"lateral".\s\sIt\shas\sto\sbe\sparsed\sas\san\nidentifier.
+D 2024-07-20T03:19:40.623
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c b08600ebf0db90b6d1e9b8b6577c6fa3877cbe1a100bd0b2899e4c6e9adad4b3
F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a
-F src/parse.y 4be218b2b28316145aae99695ccec0bd08d1b9f1088304a72e5e526bb9bbb083
+F src/parse.y c681bcadfb08325e425c3798a6fa0fb374426ffa2db943cf4e7e97b6545e09fb
F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484
F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5
F src/pcache1.c 49516ad7718a3626f28f710fa7448ef1fce3c07fd169acbb4817341950264319
F test/joinE.test d5d182f3812771e2c0d97c9dcf5dbe4c41c8e21c82560e59358731c4a3981d6b
F test/joinF.test 53dd66158806823ea680dd7543b5406af151b5aafa5cd06a7f3231cd94938127
F test/joinH.test 55f69e64da74d4eca2235237f3acb657aef181e22e45daa228e35bba865e0255
-F test/joinL.test 42f319f9fc60a3dddb248a71f4d8ace80741772c8a8606f4ce878e96311822ee
+F test/joinL.test d18dc1f85a8254b260ef5d0e1d3695dca65309f20f04b79e0b1cb754fdef9334
F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497
F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4
F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e
F tool/mkautoconfamal.sh cbdcf993fa83dccbef7fb77b39cdeb31ef9f77d9d88c9e343b58d35ca3898a6a
F tool/mkccode.tcl 86463e68ce9c15d3041610fedd285ce32a5cf7a58fc88b3202b8b76837650dbe x
F tool/mkctimec.tcl 060e9785e9503bf51f8b1b11b542bdeef90fd0ceb0738154f6762acec0c61e5f x
-F tool/mkkeywordhash.c 10f6a1eb691b17d4a87b0a9bf809420c5cfb806273d3e5101add1544b223f9d4
+F tool/mkkeywordhash.c b9faa0ae7e14e4dbbcd951cddd786bf46b8a65bb07b129ba8c0cfade723aaffd
F tool/mkmsvcmin.tcl 8897d515ef7f94772322db95a3b6fce6c614d84fe0bdd06ba5a1c786351d5a1d
F tool/mkopcodec.tcl 33d20791e191df43209b77d37f0ff0904620b28465cca6990cf8d60da61a07ef
F tool/mkopcodeh.tcl 2b4e6967a670ef21bf53a164964c35c6163277d002a4c6f56fa231d68c88d023
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P bf54b26092ded2e6acc779acfb960364f05c665c7626c38ffae61caae5636184
-R fd0426e8bf5d734a1d48d710a5bc9a8a
-T *branch * lateral-join
-T *sym-lateral-join *
-T -sym-trunk *
+P 3c045a96bc65713e5544af82b8547cdcdf93fa20f9b7b0851d77f8c090cc650b
+R f090a6ec615c741ecafebf974126b522
U drh
-Z 0351f62d422552d2d5b55232d6520d93
+Z ff3d32fb657fae9cfdb48424d2f017eb
# Remove this line to create a well-formed Fossil manifest.
-3c045a96bc65713e5544af82b8547cdcdf93fa20f9b7b0851d77f8c090cc650b
+8217bddaf8c0697799c7518746996665bbd1f5a327315d18091a6ab3250f1112
ABORT ACTION AFTER ANALYZE ASC ATTACH BEFORE BEGIN BY CASCADE CAST COLUMNKW
CONFLICT DATABASE DEFERRED DESC DETACH DO
EACH END EXCLUSIVE EXPLAIN FAIL FOR
- IGNORE IMMEDIATE INITIALLY INSTEAD LATERAL LIKE_KW MATCH NO PLAN
+ IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH NO PLAN
QUERY KEY OF OFFSET PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW ROWS
ROLLBACK SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL WITH WITHOUT
NULLS FIRST LAST
seltablist(A) ::= stl_prefix(A) LP select(S) RP as(Z) on_using(N). {
A = sqlite3SrcListAppendFromTerm(pParse,A,0,0,&Z,S,&N);
}
- seltablist(A) ::= stl_prefix(A) LATERAL LP select(S) RP as(Z) on_using(N). {
- SrcList *pSrc;
+ seltablist(A) ::= stl_prefix(A) nm(Y) dbnm(D) LP select(S) RP as(Z) on_using(N). {
+ // \___________/
+ // |
+ // This must be a single identifier token "LATERAL". We cannot make
+ // LATERAL a keyword, since there might be legacy databases that
+ // use "lateral" as a table name and a table name is valid syntax
+ // in this position.
+ SrcList *pSrc = A;
+ if( Y.n!=7 || sqlite3StrNICmp(Y.z,"lateral",7)!=0 || D.z!=0 ){
+ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &Y);
+ pParse->db->errByteOffset = (int)(Y.z - pParse->zTail);
+ }else
+ if( pSrc
+ && ALWAYS(pSrc->nSrc>0)
+ && (pSrc->a[pSrc->nSrc-1].fg.jointype & JT_RIGHT)!=0
+ ){
+ sqlite3ErrorMsg(pParse, "join must be INNER or LEFT for a LATERAL reference");
+ pParse->db->errByteOffset = (int)(Y.z - pParse->zTail);
+ }
pSrc = A = sqlite3SrcListAppendFromTerm(pParse,A,0,0,&Z,S,&N);
if( pSrc && pSrc->nSrc>1 ){
pSrc->a[pSrc->nSrc-1].fg.isLateral = 1;
3 cindy 15.0 2 5.28 banana
}
+
+do_catchsql_test 1.2 {
+ SELECT *
+ FROM wishlist AS w RIGHT JOIN LATERAL (
+ SELECT * FROM product AS p
+ WHERE p.price < w.desired_price
+ ORDER BY p.price DESC LIMIT 3
+ ) AS x ON true
+ ORDER BY wishlist_id, price DESC;
+} {1 {join must be INNER or LEFT for a LATERAL reference}}
+do_catchsql_test 1.3 {
+ SELECT *
+ FROM wishlist AS w FULL OUTER JOIN LATERAL (
+ SELECT * FROM product AS p
+ WHERE p.price < w.desired_price
+ ORDER BY p.price DESC LIMIT 3
+ ) AS x ON true
+ ORDER BY wishlist_id, price DESC;
+} {1 {join must be INNER or LEFT for a LATERAL reference}}
+do_catchsql_test 1.4 {
+ SELECT *
+ FROM wishlist AS w FULL OUTER JOIN LATERALx (
+ SELECT * FROM product AS p
+ WHERE p.price < w.desired_price
+ ORDER BY p.price DESC LIMIT 3
+ ) AS x ON true
+ ORDER BY wishlist_id, price DESC;
+} {1 {near "LATERALx": syntax error}}
+do_catchsql_test 1.5 {
+ SELECT *
+ FROM wishlist AS w FULL OUTER JOIN LATERAL.xyz (
+ SELECT * FROM product AS p
+ WHERE p.price < w.desired_price
+ ORDER BY p.price DESC LIMIT 3
+ ) AS x ON true
+ ORDER BY wishlist_id, price DESC;
+} {1 {near "LATERAL": syntax error}}
+
do_execsql_test 2.0 {
CREATE TABLE orders(id INTEGER PRIMARY KEY, user_id INT, created_at TEXT);
INSERT INTO orders VALUES
2 2024-07-20T01:35:07 NULL NULL
3 2024-07-20T01:35:10 2024-07-20T01:58:17 5
}
+do_execsql_test 2.1 {
+ SELECT user_id, first_order_time, next_order_time, id FROM
+ LATERAL (SELECT user_id, min(created_at) AS first_order_time
+ FROM orders GROUP BY user_id) AS o1
+ LEFT JOIN LATERAL
+ (SELECT id, created_at AS next_order_time
+ FROM orders
+ WHERE user_id = o1.user_id AND created_at > o1.first_order_time
+ ORDER BY created_at ASC LIMIT 1) AS o2
+ ON true;
+} {
+ 1 2024-07-20T01:35:03 2024-07-20T01:58:10 4
+ 2 2024-07-20T01:35:07 NULL NULL
+ 3 2024-07-20T01:35:10 2024-07-20T01:58:17 5
+}
+# "LATERAL" is a not actually a keyword. It can be used as an indentifier for
+# historical compatibility.
+#
+do_execsql_test 3.0 {
+ CREATE TABLE lateral(a,lateral lateral);
+ INSERT INTO lateral VALUES(1,2);
+ SELECT * FROM lateral;
+ ATTACH ':memory:' AS lateral;
+ CREATE TABLE lateral.t2(x,y);
+ INSERT INTO t2 VALUES(98,99);
+ SELECT * FROM t2;
+} {1 2 98 99}
finish_test
{ "JOIN", "TK_JOIN", ALWAYS, 5 },
{ "KEY", "TK_KEY", ALWAYS, 1 },
{ "LAST", "TK_LAST", ALWAYS, 4 },
- { "LATERAL", "TK_LATERAL", ALWAYS, 7 },
{ "LEFT", "TK_JOIN_KW", ALWAYS, 5 },
{ "LIKE", "TK_LIKE_KW", ALWAYS, 5 },
{ "LIMIT", "TK_LIMIT", ALWAYS, 3 },