diff --git a/ext/rtree/rtree1.test b/ext/rtree/rtree1.test index e5b55a28e4..034155341b 100644 --- a/ext/rtree/rtree1.test +++ b/ext/rtree/rtree1.test @@ -741,10 +741,19 @@ do_execsql_test 20.0 { CREATE TABLE t0(a INT); CREATE TABLE t1(b INT); INSERT INTO rt0 VALUES(0, 0, 0); +} +do_catchsql_test 20.1 { SELECT * FROM t1 JOIN t0 ON x0>a RIGHT JOIN rt0 ON true WHERE +x0 = 0; -} {} -do_execsql_test 20.1 { +} {1 {ON clause references tables to its right}} +do_catchsql_test 20.2 { SELECT * FROM t1 JOIN t0 ON x0>a RIGHT JOIN rt0 ON true WHERE x0 = 0; -} {} +} {1 {ON clause references tables to its right}} +db null - +do_execsql_test 20.3 { + SELECT * FROM t1 JOIN t0 ON true RIGHT JOIN rt0 ON x0>a WHERE +x0 = 0; +} {- - 0 0.0 0.0} +do_execsql_test 20.4 { + SELECT * FROM t1 JOIN t0 ON true RIGHT JOIN rt0 ON x0>a WHERE x0 = 0; +} {- - 0 0.0 0.0} finish_test diff --git a/manifest b/manifest index 5496a6747d..a9812cacf6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sfix\sat\s[cab9b4cccd13bf0a]\swas\sincomplete,\sas\sdemonstrated\sby\n[forum:/forumpost/57bdf2217d|forum\spost\s57bdf2217d].\s\sThis\scheck-in\nshould\scomplete\sthe\sfix. -D 2022-06-20T12:42:28.345 +C Do\snot\sallow\san\sON\sclause\sto\sreferences\stables\sto\sits\sright\sif\sthere\sis\sa\nRIGHT\sor\sLEFT\sjoin\sanywhere\sin\sthe\squery.\s\sOther\sRDBMSes\sprohibit\sthis\salways,\nbut\sSQLite\smust\sallow\sON\sclauses\sto\sreference\stables\sto\stheir\sright\sfor\slegacy\ncompatibility,\sunless\sthere\sis\sa\sRIGHT\sor\sLEFT\sjoin\ssomeplace\sin\sthe\squery,\nin\swhich\scase\sthere\sis\sno\slegacy\sto\ssupport. +D 2022-06-20T17:04:44.141 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -416,7 +416,7 @@ F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 F ext/rtree/geopoly.c cc3f89c11abcf114fa60d74709ae8b5bc1eae5a261b30bc1bb7085089c03bfab F ext/rtree/rtree.c d7b4b8b81d8d54376a7f81de5be85ec58b37c11604bcf42984a8418b34158d93 F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412 -F ext/rtree/rtree1.test 70c092dcf34716b64edc9dbab171790322aa87b89a48f7437b8b4c7b466449c4 +F ext/rtree/rtree1.test d47f58832145fcfed9067bc457ca8664962196c4566c17a1ebd679367db55d11 F ext/rtree/rtree2.test 9d9deddbb16fd0c30c36e6b4fdc3ee3132d765567f0f9432ee71e1303d32603d F ext/rtree/rtree3.test 4ee5d7df86040efe3d8d84f141f2962a7745452200a7cba1db06f86d97050499 F ext/rtree/rtree4.test 304de65d484540111b896827e4261815e5dca4ce28eeecd58be648cd73452c4b @@ -570,7 +570,7 @@ F src/printf.c 6166a30417b05c5b2f82e1f183f75faa2926ad60531c0b688a57dbc951441a20 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c a4eb3c617027fd049b07432f3b942ea7151fa793a332a11a7d0f58c9539e104f F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c e3181898cc05e8a78195f1792f170760df49262d6267dcaa834160900aab7d37 +F src/select.c baadb1b3fd0e87f82f0c416b68a5b8d90d8f4ffb3568c9a86f84a2be7d40261f F src/shell.c.in 08e59f1cb9d9b1180aba52861aaada0c95f6ddd210488719684e160a0724c806 F src/sqlite.h.in 172528c287399a34f188154017b7268bf82c6d5b780902e361958d2318c4e37c F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -660,7 +660,7 @@ F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b F src/where.c 2db3d41a1fd3b93d86680b4f33530d1f96ce9941771ebee80effba071d9d1e38 F src/whereInt.h b48ca529ffe293c18cbfa8326af18a09e39910de66fb3e96ef788c7cbf8ef3a7 F src/wherecode.c 0b09abfcb88c61c6a6984a3e065786631ff35495e9bdf865e6b74ab0a1299c5b -F src/whereexpr.c 20255cf03e0b765b742301197d165511ff99e95da0d7ee9c8a2ebc1e888dd049 +F src/whereexpr.c 3b5f9f6f9fc07039b242ecf7a66e87392e9c49d62923b3c593c904090bd9345c F src/window.c fff1b51757438c664e471d5184634e48dcdf8ea34b640f3b1b0810b1e06de18c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 @@ -1168,7 +1168,7 @@ F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test d22b6cba8fb59ab3f1c82701434c360705eb12d4ce200c449f37b018fc47681a F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c F test/join7.test 2268dcbb54b724391dda3748ea95c60d960607ffeed67885675998e7117697f6 -F test/join8.test c839d7cd4704b600468fd4d82d92bfe3eac67623c41dbfb99f804cdad7a3846e +F test/join8.test 6d063ef3fa580ff9e50015107b0e6caf51e7055731749ba6391b8f11c1e00e3f F test/join9.test 9056ddd3b0c0f4f9d658f4521038d9a37dc23ead8ca9a505d0b0db2b6a471e05 F test/joinA.test 7eab225dc1c1ab258a5e62513a4ed7cabbd3db971d59d5d92f4fb6fa14c12f6a F test/joinB.test 1b2ba3fc8568b49411787fccbf540570c148e9b6a53a30f80691cb6268098ded @@ -1978,8 +1978,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 11162446f12ae3af6e4a63bb5c374129b2505f6006f91d4028c7165f05fe9651 -R e2f301053cf79999e11ddef561e846ed +P fb0a23b6789da8e934562ce9ebd9d58ea13a10fd10dee5cbfc7ac8f394e1aeec +R 9a31acf363f55129767709f03c1bfdcf U drh -Z 238d98417a47860062f9a4d41505b756 +Z ae2f170f0ee7cf50c320a853890db816 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b75dd0fdc6..bd8414421c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fb0a23b6789da8e934562ce9ebd9d58ea13a10fd10dee5cbfc7ac8f394e1aeec \ No newline at end of file +e615dbe02ca949252d1526ed5c48f8ce08159773ea2008ce666484379d0d9854 \ No newline at end of file diff --git a/src/select.c b/src/select.c index f062d2f4df..5c73c6bf63 100644 --- a/src/select.c +++ b/src/select.c @@ -424,11 +424,13 @@ void sqlite3SetJoinExpr(Expr *p, int iTable, u32 joinFlag){ } } -/* Undo the work of sqlite3SetJoinExpr(). In the expression p, convert every -** term that is marked with EP_OuterON and w.iJoin==iTable into -** an ordinary term that omits the EP_OuterON mark. +/* Undo the work of sqlite3SetJoinExpr(). This is used when a LEFT JOIN +** is simplified into an ordinary JOIN, and when an ON expression is +** "pushed down" into the WHERE clause of a subquery. ** -** This happens when a LEFT JOIN is simplified into an ordinary JOIN. +** Convert every term that is marked with EP_OuterON and w.iJoin==iTable into +** an ordinary term that omits the EP_OuterON mark. Or if iTable<0, then +** just clear every EP_OuterON and EP_InnerON mark from the expression tree. ** ** If nullable is true, that means that Expr p might evaluate to NULL even ** if it is a reference to a NOT NULL column. This can happen, for example, @@ -438,10 +440,9 @@ void sqlite3SetJoinExpr(Expr *p, int iTable, u32 joinFlag){ */ static void unsetJoinExpr(Expr *p, int iTable, int nullable){ while( p ){ - if( ExprHasProperty(p, EP_OuterON) - && (iTable<0 || p->w.iJoin==iTable) ){ - ExprClearProperty(p, EP_OuterON); - ExprSetProperty(p, EP_InnerON); + if( iTable<0 || (ExprHasProperty(p, EP_OuterON) && p->w.iJoin==iTable) ){ + ExprClearProperty(p, EP_OuterON|EP_InnerON); + if( iTable>=0 ) ExprSetProperty(p, EP_InnerON); } if( p->op==TK_COLUMN && p->iTable==iTable && !nullable ){ ExprClearProperty(p, EP_CanBeNull); @@ -6771,6 +6772,7 @@ int sqlite3Select( SELECTTRACE(0x100,pParse,p, ("LEFT-JOIN simplifies to JOIN on term %d\n",i)); pItem->fg.jointype &= ~(JT_LEFT|JT_OUTER); + assert( pItem->iCursor>=0 ); unsetJoinExpr(p->pWhere, pItem->iCursor, pTabList->a[0].fg.jointype & JT_LTORJ); } diff --git a/src/whereexpr.c b/src/whereexpr.c index 878e69f633..52da05ddde 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1121,9 +1121,15 @@ static void exprAnalyze( } }else if( (prereqAll>>1)>=x ){ /* The ON clause of an INNER JOIN references a table to its right. - ** Most other SQL database engines raise an error. But all versions - ** of SQLite going back to 3.0.0 have just put the ON clause constraint - ** into the WHERE clause and carried on. */ + ** Most other SQL database engines raise an error. But SQLite versions + ** 3.0 through 3.38 just put the ON clause constraint into the WHERE + ** clause and carried on. Beginning with 3.39, raise an error only + ** if there is a RIGHT or LEFT JOIN in the query. This makes SQLite + ** more like other systems, and also preserves legacy. */ + if( pSrc->nSrc>0 && (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ + sqlite3ErrorMsg(pParse, "ON clause references tables to its right"); + return; + } ExprClearProperty(pExpr, EP_InnerON); } } diff --git a/test/join8.test b/test/join8.test index c39b773d18..46bf38aa6d 100644 --- a/test/join8.test +++ b/test/join8.test @@ -684,11 +684,13 @@ do_execsql_test join8-22030 { CREATE TABLE t3(c INTEGER PRIMARY KEY, d INT); CREATE INDEX t3d ON t3(d); INSERT INTO t3 VALUES(0, 0); +} +do_catchsql_test join8-22031 { SELECT * FROM t1 JOIN t2 ON d>b RIGHT JOIN t3 ON true WHERE +d = 0; -} {} -do_execsql_test join8-22040 { +} {1 {ON clause references tables to its right}} +do_catchsql_test join8-22040 { SELECT * FROM t1 JOIN t2 ON d>b RIGHT JOIN t3 ON true WHERE d = 0; -} {} +} {1 {ON clause references tables to its right}} # 2022-06-10