From 90402d4d541e80a8e12cc75e41029b2cbcc555d0 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 14 Mar 2022 16:54:05 +0000 Subject: [PATCH 001/259] Foreign key constraint failures should return SQLITE_CONSTRAINT_FOREIGNKEY even if there is a RETURNING clause. See [forum:/forumpost/e6be6e82c86aa59b|forum thread e6be6e82c86aa59b]. FossilOrigin-Name: 3f9887d4a58cbfdbabf2a37e975c81ba660f373414058920b379f3a81e6e1c2c --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 32242ebdcf..705d7b502f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\scomment\slinking\sa\spart\sof\sthe\sUPDATE\sconstraint\schecking\scode\sto\none\sof\sthe\scorresponding\sTH3\stest\scases. -D 2022-03-11T15:42:05.493 +C Foreign\skey\sconstraint\sfailures\sshould\sreturn\sSQLITE_CONSTRAINT_FOREIGNKEY\neven\sif\sthere\sis\sa\sRETURNING\sclause.\s\sSee\n[forum:/forumpost/e6be6e82c86aa59b|forum\sthread\se6be6e82c86aa59b]. +D 2022-03-14T16:54:05.621 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -628,7 +628,7 @@ F src/vdbe.c b1830c6daf744473a732257652b6431ac18032f508a3e30ff3a1466fe5978559 F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e F src/vdbeInt.h 8dd91427155a38ec06e9ecbde07e33f21bc02e101625191e7613f883e379a363 F src/vdbeapi.c 1c80efbe51118bbecc7279023e75d18edcfa4b3dc441287e1718ee70ad594f58 -F src/vdbeaux.c 2870683ec4a50276a32ebbe32300732dbfc47c3207662bd767c8d612620a9d78 +F src/vdbeaux.c 33c61dc3dbe920f262371ad2ba3e10277d27d8e35ee86075e2aef74113eae251 F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 57fceb4ed6aac960e9517c963dc0668189e8b7c8e6216d257030a2f5e9a583df F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 @@ -1944,8 +1944,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 5d739aff96c47146dba72fd76fed62d4e43ded09b32246fdde13d5467f713135 -R fe298d8fac60be400e4a8c74276154d9 +P 0606e8e93edb5de4d154f377dbf91f15295d25ca9013c0f1612ae6d63a0139ea +R 2439bf04cf15e67a5b6dba1b18f0930e U drh -Z 318438bd874dd4bc6c146383b35f409b +Z abecf5a0440cfbfb9a09cffcb215231b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5a00a628e2..098c158d06 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0606e8e93edb5de4d154f377dbf91f15295d25ca9013c0f1612ae6d63a0139ea \ No newline at end of file +3f9887d4a58cbfdbabf2a37e975c81ba660f373414058920b379f3a81e6e1c2c \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index aea932125c..be6406cffc 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2994,7 +2994,7 @@ int sqlite3VdbeCheckFk(Vdbe *p, int deferred){ p->rc = SQLITE_CONSTRAINT_FOREIGNKEY; p->errorAction = OE_Abort; sqlite3VdbeError(p, "FOREIGN KEY constraint failed"); - return SQLITE_ERROR; + return SQLITE_CONSTRAINT_FOREIGNKEY; } return SQLITE_OK; } From 1a25be1a9a3adb30f7d7c48928827e73ceffc616 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 14 Mar 2022 20:31:57 +0000 Subject: [PATCH 002/259] Disable trigger coding while running sqlite3_declare_vtab(). dbsqlfuzz 97e1865771b4226f29e6e482411c1cae14133f50 FossilOrigin-Name: 387ab17b8a0a4b87903aab52abc7da79098b882aff2ab687a554d5794e9d183e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vtab.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 705d7b502f..0a0d559dcb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Foreign\skey\sconstraint\sfailures\sshould\sreturn\sSQLITE_CONSTRAINT_FOREIGNKEY\neven\sif\sthere\sis\sa\sRETURNING\sclause.\s\sSee\n[forum:/forumpost/e6be6e82c86aa59b|forum\sthread\se6be6e82c86aa59b]. -D 2022-03-14T16:54:05.621 +C Disable\strigger\scoding\swhile\srunning\ssqlite3_declare_vtab().\ndbsqlfuzz\s97e1865771b4226f29e6e482411c1cae14133f50 +D 2022-03-14T20:31:57.700 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -634,7 +634,7 @@ F src/vdbemem.c 57fceb4ed6aac960e9517c963dc0668189e8b7c8e6216d257030a2f5e9a583df F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823 F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c -F src/vtab.c e0eaf5b8f7f8929088485a76bea2ff6124adb12e0eb5c0997287ff5e0e4c0517 +F src/vtab.c 3d72c780d1ea08906a198e4f033921a658a54590e3ed72c544995d84f3f9464a F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a @@ -1944,8 +1944,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 0606e8e93edb5de4d154f377dbf91f15295d25ca9013c0f1612ae6d63a0139ea -R 2439bf04cf15e67a5b6dba1b18f0930e +P 3f9887d4a58cbfdbabf2a37e975c81ba660f373414058920b379f3a81e6e1c2c +R 4ff2c1250d0d520623244bd080f43fa8 U drh -Z abecf5a0440cfbfb9a09cffcb215231b +Z 30a6fade432910c6c17981de0d6b942d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 098c158d06..bc213ff69f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3f9887d4a58cbfdbabf2a37e975c81ba660f373414058920b379f3a81e6e1c2c \ No newline at end of file +387ab17b8a0a4b87903aab52abc7da79098b882aff2ab687a554d5794e9d183e \ No newline at end of file diff --git a/src/vtab.c b/src/vtab.c index 11c076e4e6..b50ccd24a6 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -827,6 +827,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ sqlite3ParseObjectInit(&sParse, db); sParse.eParseMode = PARSE_MODE_DECLARE_VTAB; + sParse.disableTriggers = 1; /* We should never be able to reach this point while loading the ** schema. Nevertheless, defend against that (turn off db->init.busy) ** in case a bug arises. */ From d024eca323a4d5fce35c834342aa30013d24e2fe Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 14 Mar 2022 22:58:04 +0000 Subject: [PATCH 003/259] Fix an assert() statement in the covering index optimization for the corner case of dealing with an sqlite_offset() SQL function call. FossilOrigin-Name: 3950b7d006add571579158c751247a9435801e53eafd84b43dd3046e01da8ee6 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 3 +++ test/func6.test | 9 +++++++++ 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 0a0d559dcb..4ef61a7bdb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disable\strigger\scoding\swhile\srunning\ssqlite3_declare_vtab().\ndbsqlfuzz\s97e1865771b4226f29e6e482411c1cae14133f50 -D 2022-03-14T20:31:57.700 +C Fix\san\sassert()\sstatement\sin\sthe\scovering\sindex\soptimization\sfor\sthe\scorner\ncase\sof\sdealing\swith\san\ssqlite_offset()\sSQL\sfunction\scall. +D 2022-03-14T22:58:04.421 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -639,7 +639,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c baec5c64db111227b6c7f07f65d91706a51d9f8c72d3f3ec7e65c39450b592d0 +F src/where.c 7f7e6b5f0c017997a3a47988781de9481f9fa685febdaea779a9fd79ab17a43c F src/whereInt.h 15d2975c3b4c193c78c26674400a840da8647fe1777ae3b026e2d15937b38a03 F src/wherecode.c 555f598a9ddad81761f084710fdb4f8733fe31bc14cd6b19f8ca4274a7eaa04c F src/whereexpr.c 2a71f5491798460c9590317329234d332d9eb1717cba4f3403122189a75c465e @@ -1055,7 +1055,7 @@ F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f F test/func3.test 600a632c305a88f3946d38f9a51efe145c989b2e13bd2b2a488db47fe76bab6a F test/func4.test 2285fb5792d593fef442358763f0fd9de806eda47dbc7a5934df57ffdc484c31 F test/func5.test 863e6d1bd0013d09c17236f8a13ea34008dd857d87d85a13a673960e4c25d82a -F test/func6.test 90e42b64c4f9fb6f04f44cb8a1da586c8542502e926b19c76504fe74ff2a9b7c +F test/func6.test 9cc9b1f43b435af34fe1416eb1e318c8920448ea7a6962f2121972f5215cb9b0 F test/func7.test b9e2a1a30a8562b00841b4a21a5d2d81754fa3ab99275fd71fd5279287b44b1c F test/fuzz-oss1.test 514dcabb24687818ea949fa6760229eaacad74ca70157743ef36d35bbe01ffb0 F test/fuzz.test 4608c1310cff4c3014a84bcced6278139743e080046e5f6784b0de7b069371d8 @@ -1944,8 +1944,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 3f9887d4a58cbfdbabf2a37e975c81ba660f373414058920b379f3a81e6e1c2c -R 4ff2c1250d0d520623244bd080f43fa8 +P 387ab17b8a0a4b87903aab52abc7da79098b882aff2ab687a554d5794e9d183e +R e5ff5d7df3817a5b139cd165c41f1bb2 U drh -Z 30a6fade432910c6c17981de0d6b942d +Z bda3d12cdd079bd3275d1232b7b49db5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index bc213ff69f..174918fc01 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -387ab17b8a0a4b87903aab52abc7da79098b882aff2ab687a554d5794e9d183e \ No newline at end of file +3950b7d006add571579158c751247a9435801e53eafd84b43dd3046e01da8ee6 \ No newline at end of file diff --git a/src/where.c b/src/where.c index ca4ce3d805..8dcea0fa05 100644 --- a/src/where.c +++ b/src/where.c @@ -6165,6 +6165,9 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ OpcodeRewriteTrace(db, k, pOp); } assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0 +#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC + || pOp->opcode==OP_Offset +#endif || pWInfo->eOnePass ); }else if( pOp->opcode==OP_Rowid ){ pOp->p1 = pLevel->iIdxCur; diff --git a/test/func6.test b/test/func6.test index 1e16a7ca38..fe90a755d7 100644 --- a/test/func6.test +++ b/test/func6.test @@ -171,4 +171,13 @@ do_execsql_test func6-200 { SELECT offrec( sqlite_offset(y), x, y ) FROM t2 ORDER BY x } $z100 +# 2022-03-14 dbsqlfuzz 474499f3977d95fdf2dbcd99c50be1d0082e4c92 +reset_db +do_execsql_test func6-300 { + CREATE TABLE t2(a INT, b INT PRIMARY KEY) WITHOUT ROWID; + CREATE INDEX x3 ON t2(b); + CREATE TABLE t1(a INT PRIMARY KEY, b TEXT); + SELECT * FROM t1 WHERE a IN (SELECT sqlite_offset(b) FROM t2); +} {} + finish_test From 836652952f7d2bdefe67c8ec730d986826eb9ca9 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 14 Mar 2022 23:50:38 +0000 Subject: [PATCH 004/259] Calling sqlite3_value_dup() on a pointer value results in an ordinary NULL. [forum:/forumpost/ae8592cc73|Forum post ae8592cc73]. Test cases in TH3. FossilOrigin-Name: fff1243b594c190d15f14b7ca4e60d23519cd15134f275991c685966fcc24145 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqlite.h.in | 3 ++- src/vdbeapi.c | 3 +++ 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 4ef61a7bdb..ef45129a67 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sassert()\sstatement\sin\sthe\scovering\sindex\soptimization\sfor\sthe\scorner\ncase\sof\sdealing\swith\san\ssqlite_offset()\sSQL\sfunction\scall. -D 2022-03-14T22:58:04.421 +C Calling\ssqlite3_value_dup()\son\sa\spointer\svalue\sresults\sin\san\sordinary\nNULL.\s\s[forum:/forumpost/ae8592cc73|Forum\spost\sae8592cc73].\s\sTest\scases\nin\sTH3. +D 2022-03-14T23:50:38.525 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -554,7 +554,7 @@ F src/resolve.c ea935b87d6fb36c78b70cdc7b28561dc8f33f2ef37048389549c7b5ef9b0ba5e F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 4890a3cfee0bc60ff231c3a44db37968859ab0be156983dbcc0c096109832cdd F src/shell.c.in 69d1e59da4881f096ab47fbd3e6d99794f3e4a43f41fd9e4d2e845c9b8d20fd5 -F src/sqlite.h.in b93deee892f1bc4030e5c8712df9e21d786a1bf8e921ab8dc987eaf1e44c676f +F src/sqlite.h.in 5845213799feca09cd69d18ff841a85fe0df31021f46aaa1797e703e80dc1d70 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h a95cb9ed106e3d39e2118e4dcc15a14faec3fa50d0093425083d340d9dfd96e6 F src/sqliteInt.h 2ce7d868630ccd70ffd4b15d46b59ccf7daf89198993b62ed6e4a165d3511280 @@ -627,7 +627,7 @@ F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 F src/vdbe.c b1830c6daf744473a732257652b6431ac18032f508a3e30ff3a1466fe5978559 F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e F src/vdbeInt.h 8dd91427155a38ec06e9ecbde07e33f21bc02e101625191e7613f883e379a363 -F src/vdbeapi.c 1c80efbe51118bbecc7279023e75d18edcfa4b3dc441287e1718ee70ad594f58 +F src/vdbeapi.c bc3812dff7c9e6497c87ae86962818a51f66f8d7a873e7ec02a22aa115b84799 F src/vdbeaux.c 33c61dc3dbe920f262371ad2ba3e10277d27d8e35ee86075e2aef74113eae251 F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 57fceb4ed6aac960e9517c963dc0668189e8b7c8e6216d257030a2f5e9a583df @@ -1944,8 +1944,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 387ab17b8a0a4b87903aab52abc7da79098b882aff2ab687a554d5794e9d183e -R e5ff5d7df3817a5b139cd165c41f1bb2 +P 3950b7d006add571579158c751247a9435801e53eafd84b43dd3046e01da8ee6 +R 11f87de954262d4e3fb38fcc559280a1 U drh -Z bda3d12cdd079bd3275d1232b7b49db5 +Z 30a1d3694c96fe3b7193b4f79a3605d9 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 174918fc01..33d14d16e8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3950b7d006add571579158c751247a9435801e53eafd84b43dd3046e01da8ee6 \ No newline at end of file +fff1243b594c190d15f14b7ca4e60d23519cd15134f275991c685966fcc24145 \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 6062f79c22..9f77e01c69 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -5593,7 +5593,8 @@ unsigned int sqlite3_value_subtype(sqlite3_value*); ** object D and returns a pointer to that copy. ^The [sqlite3_value] returned ** is a [protected sqlite3_value] object even if the input is not. ** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a -** memory allocation fails. +** memory allocation fails. ^If V is a [pointer value], then the result +** of sqlite3_value_dup(V) is a NULL value. ** ** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object ** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 83f7b0fd65..af1e94487c 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -345,6 +345,9 @@ sqlite3_value *sqlite3_value_dup(const sqlite3_value *pOrig){ sqlite3ValueFree(pNew); pNew = 0; } + }else if( pNew->flags & MEM_Null ){ + /* Do not duplicate pointer values */ + pNew->flags &= ~(MEM_Term|MEM_Subtype); } return pNew; } From c6e2f2e64d0e4c7502f05f979e2bd99a6b39ef55 Mon Sep 17 00:00:00 2001 From: larrybr Date: Tue, 15 Mar 2022 17:57:42 +0000 Subject: [PATCH 005/259] Make CLI complain about incomplete input at EOF. Fix for regression reported at https://sqlite.org/forum/forumpost/718f489a43be3197 FossilOrigin-Name: 72029cf7cdb266703cc8716102dbba8e6f2666e1f47409f42c39528795757b73 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/shell.c.in | 3 ++- test/shell2.test | 9 +++++++++ 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index ef45129a67..bb70984547 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Calling\ssqlite3_value_dup()\son\sa\spointer\svalue\sresults\sin\san\sordinary\nNULL.\s\s[forum:/forumpost/ae8592cc73|Forum\spost\sae8592cc73].\s\sTest\scases\nin\sTH3. -D 2022-03-14T23:50:38.525 +C Make\sCLI\scomplain\sabout\sincomplete\sinput\sat\sEOF.\sFix\sfor\sregression\sreported\sat\shttps://sqlite.org/forum/forumpost/718f489a43be3197 +D 2022-03-15T17:57:42.959 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -553,7 +553,7 @@ F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c ea935b87d6fb36c78b70cdc7b28561dc8f33f2ef37048389549c7b5ef9b0ba5e F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 4890a3cfee0bc60ff231c3a44db37968859ab0be156983dbcc0c096109832cdd -F src/shell.c.in 69d1e59da4881f096ab47fbd3e6d99794f3e4a43f41fd9e4d2e845c9b8d20fd5 +F src/shell.c.in ec4b952f7d9c02919e8e8394be16bcbff55c105fd080895602d10fc8fa5328b8 F src/sqlite.h.in 5845213799feca09cd69d18ff841a85fe0df31021f46aaa1797e703e80dc1d70 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h a95cb9ed106e3d39e2118e4dcc15a14faec3fa50d0093425083d340d9dfd96e6 @@ -1389,7 +1389,7 @@ F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 F test/shell1.test b224e0793c5f48aa3749e65d8c64b93a30731bd206f2e41e6c5f1bee1bdb16c6 -F test/shell2.test 89e4b2db062d52baed75022227b462d085cff495809de1699652779d8e0257d6 +F test/shell2.test 7a3a23a9f57b99453f1679b1fe8072cb30e382a622874c0c4d97695fadb0a787 F test/shell3.test a50628ab1d78d90889d9d3f32fb2c084ee15674771e96afe954aaa0accd1de3c F test/shell4.test 8f6c0fce4abed19a8a7f7262517149812a04caa905d01bdc8f5e92573504b759 F test/shell5.test 0a9920d81fae28c45cd5dbd1deb809487a23c5f4b422a49f9d31c85f926d4a9c @@ -1944,8 +1944,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 3950b7d006add571579158c751247a9435801e53eafd84b43dd3046e01da8ee6 -R 11f87de954262d4e3fb38fcc559280a1 -U drh -Z 30a1d3694c96fe3b7193b4f79a3605d9 +P fff1243b594c190d15f14b7ca4e60d23519cd15134f275991c685966fcc24145 +R 419d7db42dfecc265d3cd4cb01355313 +U larrybr +Z e6c264c989ed1b7dd7a09ef4a9447bb1 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 33d14d16e8..a0ac00e2f8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fff1243b594c190d15f14b7ca4e60d23519cd15134f275991c685966fcc24145 \ No newline at end of file +72029cf7cdb266703cc8716102dbba8e6f2666e1f47409f42c39528795757b73 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 45cbb436e0..c0b5898e6e 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -11560,7 +11560,8 @@ static int process_input(ShellState *p){ qss = QSS_Start; } } - if( nSql && QSS_PLAINDARK(qss) ){ + if( nSql ){ + /* This may be incomplete. Let the SQL parser deal with that. */ errCnt += runOneSqlLine(p, zSql, p->in, startline); } free(zSql); diff --git a/test/shell2.test b/test/shell2.test index db8cd96ab8..29712c7f07 100644 --- a/test/shell2.test +++ b/test/shell2.test @@ -188,4 +188,13 @@ b 2 }} +# Test for rejection of incomplete input at EOF. +# Reported at https://sqlite.org/forum/forumpost/718f489a43be3197 +do_test shell2-1.4.7 { + catchcmd ":memory:" { + SELECT 'unclosed;} +} {1 {Parse error near line 2: unrecognized token: "'unclosed;" + SELECT 'unclosed; + ^--- error here}} + finish_test From ece092e728e91a6cba1a4e6cd81606a38e4b2b12 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 16 Mar 2022 12:06:00 +0000 Subject: [PATCH 006/259] Experimental change to have sqlite3_vtab_distinct() return 3 to indicate that results should sorted and duplicates may be removed. FossilOrigin-Name: 11f4508895c0a46d8623ca2f4f37b4f1b54b6d9022765f6124a9d42132f7d633 --- manifest | 20 ++++---- manifest.uuid | 2 +- src/select.c | 6 ++- src/where.c | 18 +++++--- test/bestindex9.test | 108 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 137 insertions(+), 17 deletions(-) create mode 100644 test/bestindex9.test diff --git a/manifest b/manifest index bb70984547..c6cb2c5124 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sCLI\scomplain\sabout\sincomplete\sinput\sat\sEOF.\sFix\sfor\sregression\sreported\sat\shttps://sqlite.org/forum/forumpost/718f489a43be3197 -D 2022-03-15T17:57:42.959 +C Experimental\schange\sto\shave\ssqlite3_vtab_distinct()\sreturn\s3\sto\sindicate\sthat\sresults\sshould\ssorted\sand\sduplicates\smay\sbe\sremoved. +D 2022-03-16T12:06:00.492 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -552,7 +552,7 @@ F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c ea935b87d6fb36c78b70cdc7b28561dc8f33f2ef37048389549c7b5ef9b0ba5e F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 4890a3cfee0bc60ff231c3a44db37968859ab0be156983dbcc0c096109832cdd +F src/select.c 16453eff42da7b9705f0e3e3cdf4a7251b27b7b88620d0697c15e4f656ff3e77 F src/shell.c.in ec4b952f7d9c02919e8e8394be16bcbff55c105fd080895602d10fc8fa5328b8 F src/sqlite.h.in 5845213799feca09cd69d18ff841a85fe0df31021f46aaa1797e703e80dc1d70 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -639,7 +639,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c 7f7e6b5f0c017997a3a47988781de9481f9fa685febdaea779a9fd79ab17a43c +F src/where.c 615ac2c6ea64baf48b023f27b33fa5b6f8f2bbd75d86d16c43ce7b0a2aa7a4fa F src/whereInt.h 15d2975c3b4c193c78c26674400a840da8647fe1777ae3b026e2d15937b38a03 F src/wherecode.c 555f598a9ddad81761f084710fdb4f8733fe31bc14cd6b19f8ca4274a7eaa04c F src/whereexpr.c 2a71f5491798460c9590317329234d332d9eb1717cba4f3403122189a75c465e @@ -732,6 +732,7 @@ F test/bestindex5.test a0c90b2dad7836e80a01379e200e5f8ec9476d49b349af02c0dbff2fb F test/bestindex6.test 16942535b551273f3ad9df8d7cc4b7f22b1fcd8882714358859eb049a6f99dd4 F test/bestindex7.test f094c669a6400777f4d2ddc3ed28e39169f1adb5be3d59b55f22ccf8c414b71e F test/bestindex8.test abd0016fc04f19dc382976750b06df5463d2757e11e78a8ba7d7dc50671f3337 +F test/bestindex9.test bf2eb8556e8d5c00ef3ee18c521751cd03c1b55454b6e7683b4c6742e3131b23 F test/between.test b9a65fb065391980119e8a781a7409d3fcf059d89968279c750e190a9a1d5263 F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59 F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc @@ -1944,8 +1945,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P fff1243b594c190d15f14b7ca4e60d23519cd15134f275991c685966fcc24145 -R 419d7db42dfecc265d3cd4cb01355313 -U larrybr -Z e6c264c989ed1b7dd7a09ef4a9447bb1 +P 72029cf7cdb266703cc8716102dbba8e6f2666e1f47409f42c39528795757b73 +R 091535e0d89f14f4e262c52c3edd5ea6 +T *branch * vtab-distinct-ordered +T *sym-vtab-distinct-ordered * +T -sym-trunk * +U dan +Z e66666d32a77ed9604cb92699aaf4a49 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a0ac00e2f8..d7cf2e0bb5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -72029cf7cdb266703cc8716102dbba8e6f2666e1f47409f42c39528795757b73 \ No newline at end of file +11f4508895c0a46d8623ca2f4f37b4f1b54b6d9022765f6124a9d42132f7d633 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 0c5ce55715..a7c9cdeba9 100644 --- a/src/select.c +++ b/src/select.c @@ -6821,6 +6821,7 @@ int sqlite3Select( ** the sDistinct.isTnct is still set. Hence, isTnct represents the ** original setting of the SF_Distinct flag, not the current setting */ assert( sDistinct.isTnct ); + sDistinct.isTnct = 2; #if SELECTTRACE_ENABLED if( sqlite3SelectTrace & 0x400 ){ @@ -7164,7 +7165,8 @@ int sqlite3Select( sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); SELECTTRACE(1,pParse,p,("WhereBegin\n")); pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, pDistinct, - 0, (WHERE_GROUPBY|(orderByGrp ? WHERE_SORTBYGROUP : 0)|distFlag), 0 + 0, (sDistinct.isTnct==2 ? WHERE_DISTINCTBY : WHERE_GROUPBY) + | (orderByGrp ? WHERE_SORTBYGROUP : 0) | distFlag, 0 ); if( pWInfo==0 ){ sqlite3ExprListDelete(db, pDistinct); @@ -7346,7 +7348,7 @@ int sqlite3Select( VdbeComment((v, "indicate accumulator empty")); sqlite3VdbeAddOp1(v, OP_Return, regReset); - if( eDist!=WHERE_DISTINCT_NOOP ){ + if( distFlag!=0 && eDist!=WHERE_DISTINCT_NOOP ){ struct AggInfo_func *pF = &pAggInfo->aFunc[0]; fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr); } diff --git a/src/where.c b/src/where.c index 8dcea0fa05..8ede0d89c0 100644 --- a/src/where.c +++ b/src/where.c @@ -1212,8 +1212,10 @@ static sqlite3_index_info *allocateIndexInfo( } if( i==n ){ nOrderBy = n; - if( (pWInfo->wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY)) ){ - eDistinct = 1 + ((pWInfo->wctrlFlags & WHERE_DISTINCTBY)!=0); + if( (pWInfo->wctrlFlags & WHERE_DISTINCTBY) ){ + eDistinct = 2 + ((pWInfo->wctrlFlags & WHERE_SORTBYGROUP)!=0); + }else if( pWInfo->wctrlFlags & WHERE_GROUPBY ){ + eDistinct = 1; } } } @@ -3771,7 +3773,9 @@ int sqlite3_vtab_distinct(sqlite3_index_info *pIdxInfo){ HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; assert( pHidden->eDistinct==0 || pHidden->eDistinct==1 - || pHidden->eDistinct==2 ); + || pHidden->eDistinct==2 + || pHidden->eDistinct==3 + ); return pHidden->eDistinct; } @@ -4230,7 +4234,9 @@ static i8 wherePathSatisfiesOrderBy( pLoop = pLast; } if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){ - if( pLoop->u.vtab.isOrdered && (wctrlFlags & WHERE_DISTINCTBY)==0 ){ + if( pLoop->u.vtab.isOrdered + && ((wctrlFlags&(WHERE_DISTINCTBY|WHERE_SORTBYGROUP))!=WHERE_DISTINCTBY) + ){ obSat = obDone; } break; @@ -4497,7 +4503,7 @@ static i8 wherePathSatisfiesOrderBy( ** SELECT * FROM t1 GROUP BY y,x ORDER BY y,x; -- IsSorted()==0 */ int sqlite3WhereIsSorted(WhereInfo *pWInfo){ - assert( pWInfo->wctrlFlags & WHERE_GROUPBY ); + assert( pWInfo->wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY) ); assert( pWInfo->wctrlFlags & WHERE_SORTBYGROUP ); return pWInfo->sorted; } @@ -4898,12 +4904,12 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ } pWInfo->bOrderedInnerLoop = 0; if( pWInfo->pOrderBy ){ + pWInfo->nOBSat = pFrom->isOrdered; if( pWInfo->wctrlFlags & WHERE_DISTINCTBY ){ if( pFrom->isOrdered==pWInfo->pOrderBy->nExpr ){ pWInfo->eDistinct = WHERE_DISTINCT_ORDERED; } }else{ - pWInfo->nOBSat = pFrom->isOrdered; pWInfo->revMask = pFrom->revLoop; if( pWInfo->nOBSat<=0 ){ pWInfo->nOBSat = 0; diff --git a/test/bestindex9.test b/test/bestindex9.test new file mode 100644 index 0000000000..94b9da0d38 --- /dev/null +++ b/test/bestindex9.test @@ -0,0 +1,108 @@ +# 2020-01-29 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix bestindex9 + +ifcapable !vtab { + finish_test + return +} + + +proc vtab_command {method args} { + switch -- $method { + xConnect { + return $::create_table + } + + xBestIndex { + set hdl [lindex $args 0] + set ::vtab_orderby [$hdl orderby] + set ::vtab_distinct [$hdl distinct] + + return [list orderby 1] + } + + xFilter { + return "" + } + } + + return {} +} + +proc do_bestindex9_test {tn create select orderby distinct} { + forcedelete test.db2 + sqlite3 dbtest test.db2 + register_tcl_module dbtest + + set ::create_table $create + dbtest eval { CREATE VIRTUAL TABLE t1 USING tcl(vtab_command); } + dbtest eval $select + + do_test $tn.orderby [list set {} $::vtab_orderby] $orderby + do_test $tn.distinct [list set {} $::vtab_distinct] $distinct + + dbtest close +} + +#------------------------------------------------------------------------- +# +do_bestindex9_test 1.0 { + CREATE TABLE x(k1, k2, v1, PRIMARY KEY(k1, k2)) +} { + SELECT DISTINCT k1, k2 FROM t1 +} {{column 0 desc 0} {column 1 desc 0}} 2 + +do_bestindex9_test 1.1 { + CREATE TABLE x(k1, k2, v1, PRIMARY KEY(k1, k2)) WITHOUT ROWID +} { + SELECT DISTINCT k1, k2 FROM t1 +} {} 0 + +do_bestindex9_test 1.2 { + CREATE TABLE x(k1 NOT NULL, k2 NOT NULL, v1, PRIMARY KEY(k1, k2)) +} { + SELECT DISTINCT k1, k2 FROM t1 +} {} 0 + +#------------------------------------------------------------------------- +# +do_bestindex9_test 2 { + CREATE TABLE x(c1, c2, c3); +} { + SELECT DISTINCT c1 FROM t1 ORDER BY c1 +} {{column 0 desc 0}} 3 + +#------------------------------------------------------------------------- +# +do_bestindex9_test 3 { + CREATE TABLE x(c1, c2, c3); +} { + SELECT DISTINCT c1 FROM t1 GROUP BY c1 +} {{column 0 desc 0}} 1 + +do_bestindex9_test 4 { + CREATE TABLE x(c1, c2, c3); +} { + CREATE TABLE t2(balls); + SELECT DISTINCT c1 FROM t1, t2 +} {{column 0 desc 0}} 2 + + +finish_test + + + + From 2f3e34624a34fcae8295c3958f1c6d54fda9d126 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 16 Mar 2022 14:51:35 +0000 Subject: [PATCH 007/259] Update the sqlite3_vtab_distinct() documentation. FossilOrigin-Name: 88929d85e2ae81c51634ddb65ebec439958b63581016f9ccb4f5388715b3fe3f --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/sqlite.h.in | 11 +++++++++-- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index c6cb2c5124..0010b6f478 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Experimental\schange\sto\shave\ssqlite3_vtab_distinct()\sreturn\s3\sto\sindicate\sthat\sresults\sshould\ssorted\sand\sduplicates\smay\sbe\sremoved. -D 2022-03-16T12:06:00.492 +C Update\sthe\ssqlite3_vtab_distinct()\sdocumentation. +D 2022-03-16T14:51:35.141 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -554,7 +554,7 @@ F src/resolve.c ea935b87d6fb36c78b70cdc7b28561dc8f33f2ef37048389549c7b5ef9b0ba5e F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 16453eff42da7b9705f0e3e3cdf4a7251b27b7b88620d0697c15e4f656ff3e77 F src/shell.c.in ec4b952f7d9c02919e8e8394be16bcbff55c105fd080895602d10fc8fa5328b8 -F src/sqlite.h.in 5845213799feca09cd69d18ff841a85fe0df31021f46aaa1797e703e80dc1d70 +F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h a95cb9ed106e3d39e2118e4dcc15a14faec3fa50d0093425083d340d9dfd96e6 F src/sqliteInt.h 2ce7d868630ccd70ffd4b15d46b59ccf7daf89198993b62ed6e4a165d3511280 @@ -1945,11 +1945,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 72029cf7cdb266703cc8716102dbba8e6f2666e1f47409f42c39528795757b73 -R 091535e0d89f14f4e262c52c3edd5ea6 -T *branch * vtab-distinct-ordered -T *sym-vtab-distinct-ordered * -T -sym-trunk * -U dan -Z e66666d32a77ed9604cb92699aaf4a49 +P 11f4508895c0a46d8623ca2f4f37b4f1b54b6d9022765f6124a9d42132f7d633 +R d6e5b04ecfceb5b1d41e97b1931549ce +U drh +Z b7abd501d6e35f76ed5404c5b9be3a3f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d7cf2e0bb5..e6cab2ac9b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -11f4508895c0a46d8623ca2f4f37b4f1b54b6d9022765f6124a9d42132f7d633 \ No newline at end of file +88929d85e2ae81c51634ddb65ebec439958b63581016f9ccb4f5388715b3fe3f \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 9f77e01c69..9c4df2292d 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -9555,8 +9555,8 @@ SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int); ** of a [virtual table] implementation. The result of calling this ** interface from outside of xBestIndex() is undefined and probably harmful. ** -** ^The sqlite3_vtab_distinct() interface returns an integer that is -** either 0, 1, or 2. The integer returned by sqlite3_vtab_distinct() +** ^The sqlite3_vtab_distinct() interface returns an integer between 0 and +** 3. The integer returned by sqlite3_vtab_distinct() ** gives the virtual table additional information about how the query ** planner wants the output to be ordered. As long as the virtual table ** can meet the ordering requirements of the query planner, it may set @@ -9588,6 +9588,13 @@ SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int); ** that have the same value for all columns identified by "aOrderBy". ** ^However omitting the extra rows is optional. ** This mode is used for a DISTINCT query. +**
  • +** ^(If the sqlite3_vtab_distinct() interface returns 3, that means +** that the query planner needs only distinct rows but it does need the +** rows to be sorted.)^ ^The virtual table implementation is free to omit +** rows that are identical in all aOrderBy columns, if it wants to, but +** it is not required to omit any rows. This mode is used for queries +** that have both DISTINCT and ORDER BY clauses. ** ** ** ^For the purposes of comparing virtual table output values to see if the From 247d09462e39b5a1e34aaadf16556d90855369d4 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 16 Mar 2022 19:28:18 +0000 Subject: [PATCH 008/259] Add extra test cases. FossilOrigin-Name: 0a922d141749cf3ef672f56449001e03f1a7e31822b66dcaf8550bb6e1b88cd3 --- manifest | 16 +++++++-------- manifest.uuid | 2 +- test/bestindex8.test | 2 +- test/distinct.test | 48 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 0010b6f478..e7949f810c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthe\ssqlite3_vtab_distinct()\sdocumentation. -D 2022-03-16T14:51:35.141 +C Add\sextra\stest\scases. +D 2022-03-16T19:28:18.285 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -731,7 +731,7 @@ F test/bestindex4.test 3039894f2dad50f3a68443dffad1b44c9b067ac03870102df1ce3d9a4 F test/bestindex5.test a0c90b2dad7836e80a01379e200e5f8ec9476d49b349af02c0dbff2fb75dc98d F test/bestindex6.test 16942535b551273f3ad9df8d7cc4b7f22b1fcd8882714358859eb049a6f99dd4 F test/bestindex7.test f094c669a6400777f4d2ddc3ed28e39169f1adb5be3d59b55f22ccf8c414b71e -F test/bestindex8.test abd0016fc04f19dc382976750b06df5463d2757e11e78a8ba7d7dc50671f3337 +F test/bestindex8.test 333ad8c6a554b885a49b68c019166eda92b05f493a92b36b0acdf7f766d04dad F test/bestindex9.test bf2eb8556e8d5c00ef3ee18c521751cd03c1b55454b6e7683b4c6742e3131b23 F test/between.test b9a65fb065391980119e8a781a7409d3fcf059d89968279c750e190a9a1d5263 F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59 @@ -860,7 +860,7 @@ F test/descidx1.test edc8adee58d491b06c7157c50364eaf1c3605c9c19f8093cb1ea2b6184f F test/descidx2.test a0ba347037ff3b811f4c6ceca5fd0f9d5d72e74e59f2d9de346a9d2f6ad78298 F test/descidx3.test 953c831df7ea219c73826dfbf2f6ee02d95040725aa88ccb4fa43d1a1999b926 F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e -F test/distinct.test 3e4210ef9cd1985aeec44939ad912c4621fbea9bb4a9c565696cebfe184b2ec5 +F test/distinct.test a7687c2fb50c93f6a486936c51439a93221c6e1188f9bc7b27b3ec26f9c58b1e F test/distinct2.test cd1d15a4a2abf579298f7161e821ed50c0119136fe0424db85c52cf0adc230d1 F test/distinctagg.test d76ef2e91fe810630c176d6bd0a58c14d5851c3125f0a1d977db87ba76359639 F test/e_blobbytes.test 4c01dfe4f12087b92b20705a3fdfded45dc4ed16d5a211fed4e1d2786ba68a52 @@ -1945,8 +1945,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 11f4508895c0a46d8623ca2f4f37b4f1b54b6d9022765f6124a9d42132f7d633 -R d6e5b04ecfceb5b1d41e97b1931549ce -U drh -Z b7abd501d6e35f76ed5404c5b9be3a3f +P 88929d85e2ae81c51634ddb65ebec439958b63581016f9ccb4f5388715b3fe3f +R 5ec914a37329cec4637eeb50f0e157e7 +U dan +Z 3e7c56f5527a371257fd32df3810ad3c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e6cab2ac9b..428d3e5fee 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -88929d85e2ae81c51634ddb65ebec439958b63581016f9ccb4f5388715b3fe3f \ No newline at end of file +0a922d141749cf3ef672f56449001e03f1a7e31822b66dcaf8550bb6e1b88cd3 \ No newline at end of file diff --git a/test/bestindex8.test b/test/bestindex8.test index 6816400771..e95c3c6dc2 100644 --- a/test/bestindex8.test +++ b/test/bestindex8.test @@ -85,7 +85,7 @@ foreach {tn sql bDistinct idxinsert bConsumed res} { 4 "SELECT DISTINCT b FROM vt1" 2 1 0 {b d} 5 "SELECT DISTINCT b FROM vt1 ORDER BY a" 0 1 1 {b d} 6 "SELECT DISTINCT t0.c0 FROM vt1, t0 ORDER BY vt1.a" 0 1 1 {1 0} - 7 "SELECT DISTINCT a, b FROM vt1 ORDER BY a, b" 1 0 1 {a b c d} + 7 "SELECT DISTINCT a, b FROM vt1 ORDER BY a, b" 3 0 1 {a b c d} 8 "SELECT DISTINCT a, b FROM vt1 ORDER BY a" 0 1 1 {a b c d} 9 "SELECT DISTINCT a FROM vt1 ORDER BY a, b" 0 1 1 {a c} diff --git a/test/distinct.test b/test/distinct.test index a3cb1afc8a..446f85bb8e 100644 --- a/test/distinct.test +++ b/test/distinct.test @@ -301,4 +301,52 @@ do_execsql_test 8.0 { SELECT DISTINCT pid FROM person where pid = 10; } {10} +#------------------------------------------------------------------------- +reset_db +do_execsql_test 9.0 { + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES('a', 'a'); + INSERT INTO t1 VALUES('a', 'b'); + INSERT INTO t1 VALUES('a', 'c'); + + INSERT INTO t1 VALUES('b', 'a'); + INSERT INTO t1 VALUES('b', 'b'); + INSERT INTO t1 VALUES('b', 'c'); + + INSERT INTO t1 VALUES('a', 'a'); + INSERT INTO t1 VALUES('b', 'b'); + + INSERT INTO t1 VALUES('A', 'A'); + INSERT INTO t1 VALUES('B', 'B'); +} + +foreach {tn idx} { + 1 { } + 2 { CREATE INDEX i1 ON t1(a, b); } + 3 { CREATE INDEX i1 ON t1(b, a); } + 4 { CREATE INDEX i1 ON t1(a COLLATE nocase, b COLLATE nocase); } + 5 { CREATE INDEX i1 ON t1(b COLLATE nocase, a COLLATE nocase); } +} { + + execsql { DROP INDEX IF EXISTS i1 } + execsql $idx + + do_execsql_test 9.$tn.1 { + SELECT DISTINCT a, b FROM t1 ORDER BY a, b + } { + A A B B + a a a b a c + b a b b b c + } + + do_execsql_test 9.$tn.1 { + SELECT DISTINCT a COLLATE nocase, b COLLATE nocase FROM t1 + ORDER BY a COLLATE nocase, b COLLATE nocase + } { + a a a b a c + b a b b b c + } +} + + finish_test From 494317ad57353c3872922337a0dffd738808d1f8 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 17 Mar 2022 11:23:13 +0000 Subject: [PATCH 009/259] Another fix for a corner-case in sqlite_offset() - this one having to do with computed virtual columns in a WITHOUT ROWID table. FossilOrigin-Name: 84ddd19bcec99f04b43b1a823477457758a2d93ea9beda43598e1234ea07776c --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 9 +++++---- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index bb70984547..511b9b2276 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sCLI\scomplain\sabout\sincomplete\sinput\sat\sEOF.\sFix\sfor\sregression\sreported\sat\shttps://sqlite.org/forum/forumpost/718f489a43be3197 -D 2022-03-15T17:57:42.959 +C Another\sfix\sfor\sa\scorner-case\sin\ssqlite_offset()\s-\sthis\sone\shaving\sto\ndo\swith\scomputed\svirtual\scolumns\sin\sa\sWITHOUT\sROWID\stable. +D 2022-03-17T11:23:13.924 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -639,7 +639,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c 7f7e6b5f0c017997a3a47988781de9481f9fa685febdaea779a9fd79ab17a43c +F src/where.c 3f6926af089c0070dd627bef9e16f6890262b43341d5627097bc26fa121d0e12 F src/whereInt.h 15d2975c3b4c193c78c26674400a840da8647fe1777ae3b026e2d15937b38a03 F src/wherecode.c 555f598a9ddad81761f084710fdb4f8733fe31bc14cd6b19f8ca4274a7eaa04c F src/whereexpr.c 2a71f5491798460c9590317329234d332d9eb1717cba4f3403122189a75c465e @@ -1944,8 +1944,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 fff1243b594c190d15f14b7ca4e60d23519cd15134f275991c685966fcc24145 -R 419d7db42dfecc265d3cd4cb01355313 -U larrybr -Z e6c264c989ed1b7dd7a09ef4a9447bb1 +P 72029cf7cdb266703cc8716102dbba8e6f2666e1f47409f42c39528795757b73 +R daa2513edd6111fe3d506fefc3f7ebd4 +U drh +Z 44502c04520a4cca4d14e85f770454ce # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a0ac00e2f8..da3c3c2eca 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -72029cf7cdb266703cc8716102dbba8e6f2666e1f47409f42c39528795757b73 \ No newline at end of file +84ddd19bcec99f04b43b1a823477457758a2d93ea9beda43598e1234ea07776c \ No newline at end of file diff --git a/src/where.c b/src/where.c index 8dcea0fa05..83bd63fc30 100644 --- a/src/where.c +++ b/src/where.c @@ -6146,14 +6146,15 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ ){ int x = pOp->p2; assert( pIdx->pTable==pTab ); +#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC + if( pOp->opcode==OP_Offset ){ + /* Do not need to translate the column number */ + }else +#endif if( !HasRowid(pTab) ){ Index *pPk = sqlite3PrimaryKeyIndex(pTab); x = pPk->aiColumn[x]; assert( x>=0 ); -#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC - }else if( pOp->opcode==OP_Offset ){ - /* Do not need to translate the column number */ -#endif }else{ testcase( x!=sqlite3StorageColumnToTable(pTab,x) ); x = sqlite3StorageColumnToTable(pTab,x); From d6df8550b255ca74886fd9fba43c8f91111e6ebc Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 17 Mar 2022 18:03:08 +0000 Subject: [PATCH 010/259] Updates a comment and an assert(). FossilOrigin-Name: 0c5be14aac07222b9cd2404ae485b6587f8cb2899e776bc45f1f1117bdd7e9b7 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/select.c | 2 +- src/where.c | 6 +----- 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index e7949f810c..85f16ee750 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sextra\stest\scases. -D 2022-03-16T19:28:18.285 +C Updates\sa\scomment\sand\san\sassert(). +D 2022-03-17T18:03:08.225 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -552,7 +552,7 @@ F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c ea935b87d6fb36c78b70cdc7b28561dc8f33f2ef37048389549c7b5ef9b0ba5e F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 16453eff42da7b9705f0e3e3cdf4a7251b27b7b88620d0697c15e4f656ff3e77 +F src/select.c c366c05e48e836ea04f8ecefb9c1225745dc250c3f01bdb39e9cbb0dc25e3610 F src/shell.c.in ec4b952f7d9c02919e8e8394be16bcbff55c105fd080895602d10fc8fa5328b8 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -639,7 +639,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c 615ac2c6ea64baf48b023f27b33fa5b6f8f2bbd75d86d16c43ce7b0a2aa7a4fa +F src/where.c bea45cd6ad295044fd2682ebc9c415acc9d83771809926cb0fa20f39df3376a4 F src/whereInt.h 15d2975c3b4c193c78c26674400a840da8647fe1777ae3b026e2d15937b38a03 F src/wherecode.c 555f598a9ddad81761f084710fdb4f8733fe31bc14cd6b19f8ca4274a7eaa04c F src/whereexpr.c 2a71f5491798460c9590317329234d332d9eb1717cba4f3403122189a75c465e @@ -1945,8 +1945,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 88929d85e2ae81c51634ddb65ebec439958b63581016f9ccb4f5388715b3fe3f -R 5ec914a37329cec4637eeb50f0e157e7 -U dan -Z 3e7c56f5527a371257fd32df3810ad3c +P 0a922d141749cf3ef672f56449001e03f1a7e31822b66dcaf8550bb6e1b88cd3 +R 4575407b1b9d18654c677ea1217fbbaa +U drh +Z deec1c56a09d8f545a4f4b9f8cb9eb99 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 428d3e5fee..c420d300f2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0a922d141749cf3ef672f56449001e03f1a7e31822b66dcaf8550bb6e1b88cd3 \ No newline at end of file +0c5be14aac07222b9cd2404ae485b6587f8cb2899e776bc45f1f1117bdd7e9b7 \ No newline at end of file diff --git a/src/select.c b/src/select.c index a7c9cdeba9..5165d6f600 100644 --- a/src/select.c +++ b/src/select.c @@ -21,7 +21,7 @@ */ typedef struct DistinctCtx DistinctCtx; struct DistinctCtx { - u8 isTnct; /* True if the DISTINCT keyword is present */ + u8 isTnct; /* 0: Not distinct. 1: DISTICT 2: DISTINCT and ORDER BY */ u8 eTnctType; /* One of the WHERE_DISTINCT_* operators */ int tabTnct; /* Ephemeral table used for DISTINCT processing */ int addrTnct; /* Address of OP_OpenEphemeral opcode for tabTnct */ diff --git a/src/where.c b/src/where.c index 8ede0d89c0..54a63459af 100644 --- a/src/where.c +++ b/src/where.c @@ -3771,11 +3771,7 @@ int sqlite3_vtab_rhs_value( */ int sqlite3_vtab_distinct(sqlite3_index_info *pIdxInfo){ HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; - assert( pHidden->eDistinct==0 - || pHidden->eDistinct==1 - || pHidden->eDistinct==2 - || pHidden->eDistinct==3 - ); + assert( pHidden->eDistinct>=0 && pHidden->eDistinct<=3 ); return pHidden->eDistinct; } From 389e056bfe1486a6003e1798043fb5c639f86451 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 17 Mar 2022 23:49:58 +0000 Subject: [PATCH 011/259] Change a conditional into an assert() due to the change in [387ab17b8a0a4b87]. FossilOrigin-Name: 13b584869f40ea6aa2190dbac64709695ee8d72b27bc5afb8b39ab3763b9c46a --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/trigger.c | 5 ++--- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index ea5c01f737..bc0354deee 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\s4th\soutput\scode\s(value\s3)\sfrom\sthe\ssqlite3_vtab_distinct()\sinterface\nthat\sindicates\sthat\sSQLite\swants\sdistinct\sresults\sthat\sare\ssorted. -D 2022-03-17T22:09:17.044 +C Change\sa\sconditional\sinto\san\sassert()\sdue\sto\sthe\schange\sin\n[387ab17b8a0a4b87]. +D 2022-03-17T23:49:58.567 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -618,7 +618,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c 6661a9fa660ecbd3ac0df1acd2ec788b3a8122b4316022bcdaf476ea6754a8de F src/treeview.c 3fac35b0835998f34bc940cb07282c5c485caa1645135435fca07ba828c48463 -F src/trigger.c 5fc3cde35cc4de510be68bb2db4dcff0ce0e1625f43e28a0920be9a6f010cd3f +F src/trigger.c 8caa0baf1b18522863cf0fd611ef483962cfa50155ca82ad43e63b20f863a683 F src/update.c f875b0d59da5c3055a0b2ac20560e1650229c6787e78de5e9836267b5cbb8359 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 @@ -1945,9 +1945,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 84ddd19bcec99f04b43b1a823477457758a2d93ea9beda43598e1234ea07776c 0c5be14aac07222b9cd2404ae485b6587f8cb2899e776bc45f1f1117bdd7e9b7 -R 3a06f6b09e46e5d74ffd1d941c48374e -T +closed 0c5be14aac07222b9cd2404ae485b6587f8cb2899e776bc45f1f1117bdd7e9b7 +P 135d8b97b01f9b5204f486f828c274c2d779c17723e79171ca61f738746adf8e +R 804c8964f2fbb5642c5ee5c7164de09a U drh -Z b60aa89107b858dfaa16ff6d69f84def +Z e27c445db2b5c5196ccb2b18d76e60e4 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index db4a1daef9..081bbca379 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -135d8b97b01f9b5204f486f828c274c2d779c17723e79171ca61f738746adf8e \ No newline at end of file +13b584869f40ea6aa2190dbac64709695ee8d72b27bc5afb8b39ab3763b9c46a \ No newline at end of file diff --git a/src/trigger.c b/src/trigger.c index 5df6b0c0bc..c30454519a 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -67,11 +67,10 @@ Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){ ){ pTrig->pNext = pList; pList = pTrig; - }else if( pTrig->op==TK_RETURNING + }else if( pTrig->op==TK_RETURNING ){ #ifndef SQLITE_OMIT_VIRTUALTABLE - && pParse->db->pVtabCtx==0 + assert( pParse->db->pVtabCtx==0 ); #endif - ){ assert( pParse->bReturning ); assert( &(pParse->u1.pReturning->retTrig) == pTrig ); pTrig->table = pTab->zName; From d5c35f6d69525d961033c2249f55848d62ef3d84 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 19 Mar 2022 12:48:14 +0000 Subject: [PATCH 012/259] Fix the zipfile extension so that it knows that a zero-length BLOB returns a NULL pointer. [forum:/forumpost/ae86934905|Forum post ae86934905]. FossilOrigin-Name: 5f6d56737caefa78e542a7af2f95646e3a818e0ecdd8e838f3c2978500ce960c --- ext/misc/zipfile.c | 5 +++++ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/ext/misc/zipfile.c b/ext/misc/zipfile.c index d3259fbf41..f818fbc11c 100644 --- a/ext/misc/zipfile.c +++ b/ext/misc/zipfile.c @@ -1262,9 +1262,14 @@ static int zipfileFilter( zipfileCursorErr(pCsr, "zipfile() function requires an argument"); return SQLITE_ERROR; }else if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){ + static const u8 aEmptyBlob = 0; const u8 *aBlob = (const u8*)sqlite3_value_blob(argv[0]); int nBlob = sqlite3_value_bytes(argv[0]); assert( pTab->pFirstEntry==0 ); + if( aBlob==0 ){ + aBlob = &aEmptyBlob; + nBlob = 0; + } rc = zipfileLoadDirectory(pTab, aBlob, nBlob); pCsr->pFreeEntry = pTab->pFirstEntry; pTab->pFirstEntry = pTab->pLastEntry = 0; diff --git a/manifest b/manifest index bc0354deee..6bd029dd2e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sa\sconditional\sinto\san\sassert()\sdue\sto\sthe\schange\sin\n[387ab17b8a0a4b87]. -D 2022-03-17T23:49:58.567 +C Fix\sthe\szipfile\sextension\sso\sthat\sit\sknows\sthat\sa\szero-length\sBLOB\sreturns\na\sNULL\spointer.\n[forum:/forumpost/ae86934905|Forum\spost\sae86934905]. +D 2022-03-19T12:48:14.721 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -339,7 +339,7 @@ F ext/misc/vfsstat.c 474d08efc697b8eba300082cb1eb74a5f0f3df31ed257db1cb07e72ab0e F ext/misc/vtablog.c 5538acd0c8ddaae372331bee11608d76973436b77d6a91e8635cfc9432fba5ae F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd F ext/misc/wholenumber.c a838d1bea913c514ff316c69695efbb49ea3b8cb37d22afc57f73b6b010b4546 -F ext/misc/zipfile.c c4e2d12b3544a380ce171a143dc2fdfe2fc76ae424ed4cf43ba4f74c6d0db444 +F ext/misc/zipfile.c 22afe121d1a5e318453b7cdbc0f5492161d2fd4fce548ff3605da05e89be7140 F ext/misc/zorder.c b0ff58fa643afa1d846786d51ea8d5c4b6b35aa0254ab5a82617db92f3adda64 F ext/rbu/rbu.c 801450b24eaf14440d8fd20385aacc751d5c9d6123398df41b1b5aa804bf4ce8 F ext/rbu/rbu1.test c62904bd9526dcdc3496a21199aaf14ae191bbadbf67f076bf16be6b3f2115c2 @@ -1945,8 +1945,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 135d8b97b01f9b5204f486f828c274c2d779c17723e79171ca61f738746adf8e -R 804c8964f2fbb5642c5ee5c7164de09a +P 13b584869f40ea6aa2190dbac64709695ee8d72b27bc5afb8b39ab3763b9c46a +R f08299960d4b1603006c98552917b7fb U drh -Z e27c445db2b5c5196ccb2b18d76e60e4 +Z 86a529adb93c7cd292392a9b7c1968ce # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 081bbca379..579a78914f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -13b584869f40ea6aa2190dbac64709695ee8d72b27bc5afb8b39ab3763b9c46a \ No newline at end of file +5f6d56737caefa78e542a7af2f95646e3a818e0ecdd8e838f3c2978500ce960c \ No newline at end of file From 9198f5afacc9ab4b41b9d39fd767130497547dff Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 19 Mar 2022 15:19:35 +0000 Subject: [PATCH 013/259] In the CLI, disable the zipfile and sqlar extensions in --safe mode. FossilOrigin-Name: d8b65a2dab97392ff81bcc33ff707b4e626a10d84a258c6452e45f90cd2c7f45 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c.in | 6 ++++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 6bd029dd2e..c620e40048 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\szipfile\sextension\sso\sthat\sit\sknows\sthat\sa\szero-length\sBLOB\sreturns\na\sNULL\spointer.\n[forum:/forumpost/ae86934905|Forum\spost\sae86934905]. -D 2022-03-19T12:48:14.721 +C In\sthe\sCLI,\sdisable\sthe\szipfile\sand\ssqlar\sextensions\sin\s--safe\smode. +D 2022-03-19T15:19:35.831 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -553,7 +553,7 @@ F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c ea935b87d6fb36c78b70cdc7b28561dc8f33f2ef37048389549c7b5ef9b0ba5e F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c c366c05e48e836ea04f8ecefb9c1225745dc250c3f01bdb39e9cbb0dc25e3610 -F src/shell.c.in ec4b952f7d9c02919e8e8394be16bcbff55c105fd080895602d10fc8fa5328b8 +F src/shell.c.in a292c6f78b4dd0302adeea03929f2dffec14ab39b364e98f707de942af2b9ac2 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h a95cb9ed106e3d39e2118e4dcc15a14faec3fa50d0093425083d340d9dfd96e6 @@ -1945,8 +1945,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 13b584869f40ea6aa2190dbac64709695ee8d72b27bc5afb8b39ab3763b9c46a -R f08299960d4b1603006c98552917b7fb +P 5f6d56737caefa78e542a7af2f95646e3a818e0ecdd8e838f3c2978500ce960c +R 351703dbbae8170966ef28712efda463 U drh -Z 86a529adb93c7cd292392a9b7c1968ce +Z 115f5affaaf1a7b376be313e0bf919f0 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 579a78914f..eb7850725c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5f6d56737caefa78e542a7af2f95646e3a818e0ecdd8e838f3c2978500ce960c \ No newline at end of file +d8b65a2dab97392ff81bcc33ff707b4e626a10d84a258c6452e45f90cd2c7f45 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index c0b5898e6e..2758a73443 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -4997,8 +4997,10 @@ static void open_db(ShellState *p, int openFlags){ sqlite3_dbdata_init(p->db, 0, 0); #endif #ifdef SQLITE_HAVE_ZLIB - sqlite3_zipfile_init(p->db, 0, 0); - sqlite3_sqlar_init(p->db, 0, 0); + if( !p->bSafeModePersist ){ + sqlite3_zipfile_init(p->db, 0, 0); + sqlite3_sqlar_init(p->db, 0, 0); + } #endif sqlite3_create_function(p->db, "shell_add_schema", 3, SQLITE_UTF8, 0, shellAddSchemaName, 0, 0); From ef07f96fafcbfea99507cdd88950c66e459f54d8 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 21 Mar 2022 11:32:45 +0000 Subject: [PATCH 014/259] Fix an assert() in sqlite3TableAffinity() that might have been false if there was a prior syntax error in the query. FossilOrigin-Name: 23fdb169ca1622369cd44fd641946c37fef09071625838b3b9c86c31244ed205 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/insert.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index c620e40048..2e31721b89 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\sCLI,\sdisable\sthe\szipfile\sand\ssqlar\sextensions\sin\s--safe\smode. -D 2022-03-19T15:19:35.831 +C Fix\san\sassert()\sin\ssqlite3TableAffinity()\sthat\smight\shave\sbeen\sfalse\sif\sthere\nwas\sa\sprior\ssyntax\serror\sin\sthe\squery. +D 2022-03-21T11:32:45.255 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -512,7 +512,7 @@ F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51 F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c d9fd15b2bd030cb9bd3119b301dbdb2912f16fff76c6e3797296cfd1500faaf4 +F src/insert.c c4fc48e6f38cc415262652407949771ce4e6f8f0c7330f872e44a0677f3ad602 F src/json.c 24fcd7f5f9080b04b89722c343010d390f85e55b2ab560046cb567c9dd640f62 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c aa919a6a7884f8b34d7b791841b24d14b1b0ab43f45b3940f4851043b2855c0c @@ -1945,8 +1945,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 5f6d56737caefa78e542a7af2f95646e3a818e0ecdd8e838f3c2978500ce960c -R 351703dbbae8170966ef28712efda463 +P d8b65a2dab97392ff81bcc33ff707b4e626a10d84a258c6452e45f90cd2c7f45 +R b0e701a49b12b11d39ad32ac91f5b559 U drh -Z 115f5affaaf1a7b376be313e0bf919f0 +Z f3540f142b57b02386753768c9b41bc5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index eb7850725c..da524222b3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d8b65a2dab97392ff81bcc33ff707b4e626a10d84a258c6452e45f90cd2c7f45 \ No newline at end of file +23fdb169ca1622369cd44fd641946c37fef09071625838b3b9c86c31244ed205 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 9b4f0b2201..dde685e302 100644 --- a/src/insert.c +++ b/src/insert.c @@ -181,7 +181,7 @@ void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){ } for(i=j=0; inCol; i++){ - assert( pTab->aCol[i].affinity!=0 ); + assert( pTab->aCol[i].affinity!=0 || sqlite3VdbeParser(v)->nErr>0 ); if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){ zColAff[j++] = pTab->aCol[i].affinity; } From 75c493f76789b3fa0fc44d56a276ceef8d2dfb4d Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 21 Mar 2022 13:47:15 +0000 Subject: [PATCH 015/259] Fix the assert() that attempts to verify that the table-reference to index-reference translator finds all required translations. [forum:/forumpost/929168fdd6|Forum post 929168fdd6]. FossilOrigin-Name: fa9bd1fce47e8db1cfc4cd8efd2c09f8711ea917ce7d116dc7226c575cb9a6d4 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 33 ++++++++++++++++++++++++++++----- test/upfrom2.test | 20 ++++++++++++++++++++ 4 files changed, 56 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 2e31721b89..5acc5b6e83 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sassert()\sin\ssqlite3TableAffinity()\sthat\smight\shave\sbeen\sfalse\sif\sthere\nwas\sa\sprior\ssyntax\serror\sin\sthe\squery. -D 2022-03-21T11:32:45.255 +C Fix\sthe\sassert()\sthat\sattempts\sto\sverify\sthat\sthe\stable-reference\sto\nindex-reference\stranslator\sfinds\sall\srequired\stranslations.\n[forum:/forumpost/929168fdd6|Forum\spost\s929168fdd6]. +D 2022-03-21T13:47:15.347 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -639,7 +639,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c f661a49e6f100b03619eccc715d5d8b57a0564a96c8d1fa8597805bf9119316f +F src/where.c afb9fcb03016e277d65e4d679d8533b0e132d3d683ced9d37735d0423160d480 F src/whereInt.h 15d2975c3b4c193c78c26674400a840da8647fe1777ae3b026e2d15937b38a03 F src/wherecode.c 555f598a9ddad81761f084710fdb4f8733fe31bc14cd6b19f8ca4274a7eaa04c F src/whereexpr.c 2a71f5491798460c9590317329234d332d9eb1717cba4f3403122189a75c465e @@ -1681,7 +1681,7 @@ F test/update.test eb7f4eb172ce270e51bb67d7867521f33a63635bb671e261bbafccaef3bd6 F test/update2.test 67455bc61fcbcf96923c45b3bc4f87bc72be7d67575ad35f134906148c7b06d3 F test/upfrom1.tcl 8859d9d437f03b44174c4524a7a734a391fd4526fcff65be08285dafc9dc9041 F test/upfrom1.test 8cb06689e99cd707d884faa16da0e8eb26ff658bb01c47ddf72fadade666e6e1 -F test/upfrom2.test 88d39cb755db5789541e645d4e2764abc697a56958f28a3f8451a0e9342bbd6b +F test/upfrom2.test 66f3ebf721b3cebd922faee5c386bf244f816d416b57c000753ff51af62328a1 F test/upfrom3.test 6130f24ebf97f5ea865e5d2a14a2d543fe5428a62e87cc60f62d875e45c1f5f0 F test/upfromfault.test 3a10075a0043f0c4fad6614b2c371f88a8ba5a4acab68b907438413865d6a8d6 F test/upsert1.test b0ae2f58680c5205b4bc1cdeed3c3d444057c506f6c44494fa3eac60731d68a2 @@ -1945,8 +1945,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 d8b65a2dab97392ff81bcc33ff707b4e626a10d84a258c6452e45f90cd2c7f45 -R b0e701a49b12b11d39ad32ac91f5b559 +P 23fdb169ca1622369cd44fd641946c37fef09071625838b3b9c86c31244ed205 +R 4c2caf4c6925c27f263ef9f6fe474f74 U drh -Z f3540f142b57b02386753768c9b41bc5 +Z 8e55e0e30dab82e26d51680d64fa738f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index da524222b3..d2b24cee2e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -23fdb169ca1622369cd44fd641946c37fef09071625838b3b9c86c31244ed205 \ No newline at end of file +fa9bd1fce47e8db1cfc4cd8efd2c09f8711ea917ce7d116dc7226c575cb9a6d4 \ No newline at end of file diff --git a/src/where.c b/src/where.c index bfe9980a18..afa0d3038d 100644 --- a/src/where.c +++ b/src/where.c @@ -5896,6 +5896,26 @@ whereBeginError: } #endif +#ifdef SQLITE_DEBUG +/* +** Return true if cursor iCur is opened by instruction k of the +** bytecode. Used inside of assert() only. +*/ +static int cursorIsOpen(Vdbe *v, int iCur, int k){ + while( k>=0 ){ + VdbeOp *pOp = sqlite3VdbeGetOp(v,k--); + if( pOp->p1!=iCur ) continue; + if( pOp->opcode==OP_Close ) return 0; + if( pOp->opcode==OP_OpenRead ) return 1; + if( pOp->opcode==OP_OpenWrite ) return 1; + if( pOp->opcode==OP_OpenDup ) return 1; + if( pOp->opcode==OP_OpenAutoindex ) return 1; + if( pOp->opcode==OP_OpenEphemeral ) return 1; + } + return 0; +} +#endif /* SQLITE_DEBUG */ + /* ** Generate the end of the WHERE loop. See comments on ** sqlite3WhereBegin() for additional information. @@ -6166,12 +6186,15 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ pOp->p2 = x; pOp->p1 = pLevel->iIdxCur; OpcodeRewriteTrace(db, k, pOp); + }else{ + /* Unable to translate the table reference into an index + ** reference. Verify that this is harmless - that the + ** table being referenced really is open. + */ + assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 + || cursorIsOpen(v,pOp->p1,k) + ); } - assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0 -#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC - || pOp->opcode==OP_Offset -#endif - || pWInfo->eOnePass ); }else if( pOp->opcode==OP_Rowid ){ pOp->p1 = pLevel->iIdxCur; pOp->opcode = OP_IdxRowid; diff --git a/test/upfrom2.test b/test/upfrom2.test index a1f00953e6..600fa05e4b 100644 --- a/test/upfrom2.test +++ b/test/upfrom2.test @@ -382,4 +382,24 @@ do_execsql_test 6.2 { ) } {} +# 2022-03-21 +# https://sqlite.org/forum/forumpost/929168fdd6 +# +reset_db +do_execsql_test 7.0 { + CREATE TABLE t1(a); + INSERT INTO t1(a) VALUES(11),(22),(33),(44),(55); + CREATE VIEW t2(b,c) AS SELECT a, COUNT(*) OVER () FROM t1; + CREATE TABLE t3(x,y); + CREATE TRIGGER t2r1 INSTEAD OF UPDATE ON t2 BEGIN + INSERT INTO t3(x,y) VALUES(new.b,new.c); + END; + SELECT * FROM t2; +} {11 5 22 5 33 5 44 5 55 5} +do_execsql_test 7.1 { + UPDATE t2 SET c=t1.a FROM t1 WHERE t2.b=t1.a; + SELECT * FROM t3; +} {11 11 22 22 33 33 44 44 55 55} + + finish_test From 67aa2318c1637fff7a5fdcc8183e958a143795b3 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 21 Mar 2022 15:42:42 +0000 Subject: [PATCH 016/259] The previous assert() fix was not correct when building with -DSQLITE_ENABLE_OFFSET_SQL_FUNC. This is the fix. FossilOrigin-Name: c0a4767fef27cfe4fdc1d8a29342998095894769a63d84e37ec47ced7ce4e5f7 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 3 +++ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 5acc5b6e83..a21751cf67 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sassert()\sthat\sattempts\sto\sverify\sthat\sthe\stable-reference\sto\nindex-reference\stranslator\sfinds\sall\srequired\stranslations.\n[forum:/forumpost/929168fdd6|Forum\spost\s929168fdd6]. -D 2022-03-21T13:47:15.347 +C The\sprevious\sassert()\sfix\swas\snot\scorrect\swhen\sbuilding\swith\n-DSQLITE_ENABLE_OFFSET_SQL_FUNC.\s\sThis\sis\sthe\sfix. +D 2022-03-21T15:42:42.783 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -639,7 +639,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c afb9fcb03016e277d65e4d679d8533b0e132d3d683ced9d37735d0423160d480 +F src/where.c b071160c771d396c82b7d37e901834b5b58544811200cdbf14fffc8f982c4224 F src/whereInt.h 15d2975c3b4c193c78c26674400a840da8647fe1777ae3b026e2d15937b38a03 F src/wherecode.c 555f598a9ddad81761f084710fdb4f8733fe31bc14cd6b19f8ca4274a7eaa04c F src/whereexpr.c 2a71f5491798460c9590317329234d332d9eb1717cba4f3403122189a75c465e @@ -1945,8 +1945,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 23fdb169ca1622369cd44fd641946c37fef09071625838b3b9c86c31244ed205 -R 4c2caf4c6925c27f263ef9f6fe474f74 +P fa9bd1fce47e8db1cfc4cd8efd2c09f8711ea917ce7d116dc7226c575cb9a6d4 +R fc8ee44bd759c8bce21e1507c043ba2f U drh -Z 8e55e0e30dab82e26d51680d64fa738f +Z 03ce4b7e2beed66af6c911c254018f05 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d2b24cee2e..33d9d5649f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fa9bd1fce47e8db1cfc4cd8efd2c09f8711ea917ce7d116dc7226c575cb9a6d4 \ No newline at end of file +c0a4767fef27cfe4fdc1d8a29342998095894769a63d84e37ec47ced7ce4e5f7 \ No newline at end of file diff --git a/src/where.c b/src/where.c index afa0d3038d..97eaac8ba5 100644 --- a/src/where.c +++ b/src/where.c @@ -6193,6 +6193,9 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ */ assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || cursorIsOpen(v,pOp->p1,k) +#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC + || pOp->opcode==OP_Offset +#endif ); } }else if( pOp->opcode==OP_Rowid ){ From bd5fb3a88814c06f52562e7678210566207bc9b3 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 21 Mar 2022 18:17:09 +0000 Subject: [PATCH 017/259] Strengthen the defenses against corrupt databases in the sqlite3BtreeInsert() function of the btree module. [forum:/forumpost/c7ec29905f|Forum post c7ec29905f]. FossilOrigin-Name: 4df301c8610c4c36b4eb360d49ccaef873c63ea719ccb14b357754ff0b3ea5ef --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 39 +++++++++++++++++++-------------------- 3 files changed, 26 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index a21751cf67..47ab5f7c3e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sprevious\sassert()\sfix\swas\snot\scorrect\swhen\sbuilding\swith\n-DSQLITE_ENABLE_OFFSET_SQL_FUNC.\s\sThis\sis\sthe\sfix. -D 2022-03-21T15:42:42.783 +C Strengthen\sthe\sdefenses\sagainst\scorrupt\sdatabases\sin\sthe\nsqlite3BtreeInsert()\sfunction\sof\sthe\sbtree\smodule.\n[forum:/forumpost/c7ec29905f|Forum\spost\sc7ec29905f]. +D 2022-03-21T18:17:09.573 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -492,7 +492,7 @@ F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf F src/backup.c a2891172438e385fdbe97c11c9745676bec54f518d4447090af97189fd8e52d7 F src/bitvec.c 7c849aac407230278445cb069bebc5f89bf2ddd87c5ed9459b070a9175707b3d F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c ddc3cec12a39675e10066c008aac7925b26c74f78c46b849b2416ca45701a313 +F src/btree.c 3362779aa933ef3a66f97110cf25a2acea06fbea74c95364b86401ad0a774a5c F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482e F src/build.c a0cc68fe8172c0a31b54576f9c6c0fe6f7c82b1b5e1387afdd6a5a13132bc131 @@ -1945,8 +1945,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 fa9bd1fce47e8db1cfc4cd8efd2c09f8711ea917ce7d116dc7226c575cb9a6d4 -R fc8ee44bd759c8bce21e1507c043ba2f +P c0a4767fef27cfe4fdc1d8a29342998095894769a63d84e37ec47ced7ce4e5f7 +R f0ffb8e52619d6c660df8acbda2d48c1 U drh -Z 03ce4b7e2beed66af6c911c254018f05 +Z c7aaa48c41ee3a7af14aecc83b976bcc # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 33d9d5649f..9237fe6bf3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c0a4767fef27cfe4fdc1d8a29342998095894769a63d84e37ec47ced7ce4e5f7 \ No newline at end of file +4df301c8610c4c36b4eb360d49ccaef873c63ea719ccb14b357754ff0b3ea5ef \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 2e87707072..5b84604f58 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9007,24 +9007,6 @@ int sqlite3BtreeInsert( assert( (flags & (BTREE_SAVEPOSITION|BTREE_APPEND|BTREE_PREFORMAT))==flags ); assert( (flags & BTREE_PREFORMAT)==0 || seekResult || pCur->pKeyInfo==0 ); - if( pCur->eState==CURSOR_FAULT ){ - assert( pCur->skipNext!=SQLITE_OK ); - return pCur->skipNext; - } - - assert( cursorOwnsBtShared(pCur) ); - assert( (pCur->curFlags & BTCF_WriteFlag)!=0 - && pBt->inTransaction==TRANS_WRITE - && (pBt->btsFlags & BTS_READ_ONLY)==0 ); - assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); - - /* Assert that the caller has been consistent. If this cursor was opened - ** expecting an index b-tree, then the caller should be inserting blob - ** keys with no associated data. If the cursor was opened expecting an - ** intkey table, the caller should be inserting integer keys with a - ** blob of associated data. */ - assert( (flags & BTREE_PREFORMAT) || (pX->pKey==0)==(pCur->pKeyInfo==0) ); - /* Save the positions of any other cursors open on this table. ** ** In some cases, the call to btreeMoveto() below is a no-op. For @@ -9049,6 +9031,24 @@ int sqlite3BtreeInsert( } } + if( pCur->eState>=CURSOR_REQUIRESEEK ){ + rc = moveToRoot(pCur); + if( rc && rc!=SQLITE_EMPTY ) return rc; + } + + assert( cursorOwnsBtShared(pCur) ); + assert( (pCur->curFlags & BTCF_WriteFlag)!=0 + && pBt->inTransaction==TRANS_WRITE + && (pBt->btsFlags & BTS_READ_ONLY)==0 ); + assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); + + /* Assert that the caller has been consistent. If this cursor was opened + ** expecting an index b-tree, then the caller should be inserting blob + ** keys with no associated data. If the cursor was opened expecting an + ** intkey table, the caller should be inserting integer keys with a + ** blob of associated data. */ + assert( (flags & BTREE_PREFORMAT) || (pX->pKey==0)==(pCur->pKeyInfo==0) ); + if( pCur->pKeyInfo==0 ){ assert( pX->pKey==0 ); /* If this is an insert into a table b-tree, invalidate any incrblob @@ -9137,8 +9137,7 @@ int sqlite3BtreeInsert( } } assert( pCur->eState==CURSOR_VALID - || (pCur->eState==CURSOR_INVALID && loc) - || CORRUPT_DB ); + || (pCur->eState==CURSOR_INVALID && loc) ); pPage = pCur->pPage; assert( pPage->intKey || pX->nKey>=0 || (flags & BTREE_PREFORMAT) ); From c63e40956b346035aca581378572dbbf7834c3ab Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 21 Mar 2022 18:48:31 +0000 Subject: [PATCH 018/259] Some branches are no longer reachable after the previous change. Mark them accordingly. Also improve comments. FossilOrigin-Name: 88d69f60cceb22bde42cfe43c23259c7bad47b8e06f918a79bd089a77b480d46 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/btree.c | 8 +++++++- src/pcache.c | 3 +-- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 47ab5f7c3e..537f0203c5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Strengthen\sthe\sdefenses\sagainst\scorrupt\sdatabases\sin\sthe\nsqlite3BtreeInsert()\sfunction\sof\sthe\sbtree\smodule.\n[forum:/forumpost/c7ec29905f|Forum\spost\sc7ec29905f]. -D 2022-03-21T18:17:09.573 +C Some\sbranches\sare\sno\slonger\sreachable\safter\sthe\sprevious\schange.\s\sMark\sthem\naccordingly.\s\sAlso\simprove\scomments. +D 2022-03-21T18:48:31.068 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -492,7 +492,7 @@ F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf F src/backup.c a2891172438e385fdbe97c11c9745676bec54f518d4447090af97189fd8e52d7 F src/bitvec.c 7c849aac407230278445cb069bebc5f89bf2ddd87c5ed9459b070a9175707b3d F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c 3362779aa933ef3a66f97110cf25a2acea06fbea74c95364b86401ad0a774a5c +F src/btree.c dd4d780d2382551c4876b67d8716360a0df44ecbb3ca6b538877bc4109bf4215 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482e F src/build.c a0cc68fe8172c0a31b54576f9c6c0fe6f7c82b1b5e1387afdd6a5a13132bc131 @@ -542,7 +542,7 @@ F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 42120492784fc9bcd9082b5c9b5e329b7318c357f9f3574a1bbfcf7418910356 F src/pager.h f82e9844166e1585f5786837ddc7709966138ced17f568c16af7ccf946c2baa3 F src/parse.y 0f02b27cdaa334441463153fff3ceb780fea006ab53ffd6ef566d4468f93e924 -F src/pcache.c 0aab73936341fad83d107cf62c6a7bc2d2d5fb9aaec8c3ce61e19fc18e4560fc +F src/pcache.c 084e638432c610f95aea72b8509f0845d2791293f39d1b82f0c0a7e089c3bb6b F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 54881292a9a5db202b2c0ac541c5e3ef9a5e8c4f1c1383adb2601d5499a60e65 F src/pragma.c 9047ffb003d9434810ee81d7b1722d0093821622eb3217c962c3407bad949ce2 @@ -1945,8 +1945,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 c0a4767fef27cfe4fdc1d8a29342998095894769a63d84e37ec47ced7ce4e5f7 -R f0ffb8e52619d6c660df8acbda2d48c1 +P 4df301c8610c4c36b4eb360d49ccaef873c63ea719ccb14b357754ff0b3ea5ef +R 89c086814dc175a63802ec978ba098bf U drh -Z c7aaa48c41ee3a7af14aecc83b976bcc +Z 6be762314610127124940dc99f0ea403 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9237fe6bf3..840a6d92b9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4df301c8610c4c36b4eb360d49ccaef873c63ea719ccb14b357754ff0b3ea5ef \ No newline at end of file +88d69f60cceb22bde42cfe43c23259c7bad47b8e06f918a79bd089a77b480d46 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 5b84604f58..41087825ba 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9031,7 +9031,12 @@ int sqlite3BtreeInsert( } } + /* Ensure that the cursor is not in the CURSOR_FAULT state and that it + ** points to a valid cell. + */ if( pCur->eState>=CURSOR_REQUIRESEEK ){ + testcase( pCur->eState==CURSOR_REQUIRESEEK ); + testcase( pCur->eState==CURSOR_FAULT ); rc = moveToRoot(pCur); if( rc && rc!=SQLITE_EMPTY ) return rc; } @@ -9143,7 +9148,8 @@ int sqlite3BtreeInsert( assert( pPage->intKey || pX->nKey>=0 || (flags & BTREE_PREFORMAT) ); assert( pPage->leaf || !pPage->intKey ); if( pPage->nFree<0 ){ - if( pCur->eState>CURSOR_INVALID ){ + if( NEVER(pCur->eState>CURSOR_INVALID) ){ + /* ^^^^^--- due to the moveToRoot() call above */ rc = SQLITE_CORRUPT_BKPT; }else{ rc = btreeComputeFreeSpace(pPage); diff --git a/src/pcache.c b/src/pcache.c index 76cc4bb7a9..14d1e7cde0 100644 --- a/src/pcache.c +++ b/src/pcache.c @@ -551,8 +551,7 @@ void sqlite3PcacheDrop(PgHdr *p){ ** make it so. */ void sqlite3PcacheMakeDirty(PgHdr *p){ - assert( p->nRef>0 || p->pCache->bPurgeable==0 ); - testcase( p->nRef==0 ); + assert( p->nRef>0 ); assert( sqlite3PcachePageSanity(p) ); if( p->flags & (PGHDR_CLEAN|PGHDR_DONT_WRITE) ){ /*OPTIMIZATION-IF-FALSE*/ p->flags &= ~PGHDR_DONT_WRITE; From a753a3a2be4a1008bfc7246781d3c32c0695d58d Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 21 Mar 2022 20:08:13 +0000 Subject: [PATCH 019/259] Do not allow an #ifdef inside of an assert(), as gcc tells us that is not portable. FossilOrigin-Name: c7a2047e93df36c172be0be773f9a04150dafe7ba1773269d74016418d262fc4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 8 ++++++-- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 537f0203c5..e1b5f85deb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Some\sbranches\sare\sno\slonger\sreachable\safter\sthe\sprevious\schange.\s\sMark\sthem\naccordingly.\s\sAlso\simprove\scomments. -D 2022-03-21T18:48:31.068 +C Do\snot\sallow\san\s#ifdef\sinside\sof\san\sassert(),\sas\sgcc\stells\sus\sthat\sis\nnot\sportable. +D 2022-03-21T20:08:13.044 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -639,7 +639,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c b071160c771d396c82b7d37e901834b5b58544811200cdbf14fffc8f982c4224 +F src/where.c 9cba7b9e58d4d07f08bb0cb5b9b982d359c8051050df9114ee927cf6798e5509 F src/whereInt.h 15d2975c3b4c193c78c26674400a840da8647fe1777ae3b026e2d15937b38a03 F src/wherecode.c 555f598a9ddad81761f084710fdb4f8733fe31bc14cd6b19f8ca4274a7eaa04c F src/whereexpr.c 2a71f5491798460c9590317329234d332d9eb1717cba4f3403122189a75c465e @@ -1945,8 +1945,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 4df301c8610c4c36b4eb360d49ccaef873c63ea719ccb14b357754ff0b3ea5ef -R 89c086814dc175a63802ec978ba098bf +P 88d69f60cceb22bde42cfe43c23259c7bad47b8e06f918a79bd089a77b480d46 +R e549179e194537a8c238e9efdda7fdd8 U drh -Z 6be762314610127124940dc99f0ea403 +Z 1df73c54c069d2ae3e739535fe1bd6f4 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 840a6d92b9..f0af174ea7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -88d69f60cceb22bde42cfe43c23259c7bad47b8e06f918a79bd089a77b480d46 \ No newline at end of file +c7a2047e93df36c172be0be773f9a04150dafe7ba1773269d74016418d262fc4 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 97eaac8ba5..bec77cc45d 100644 --- a/src/where.c +++ b/src/where.c @@ -6191,12 +6191,16 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ ** reference. Verify that this is harmless - that the ** table being referenced really is open. */ +#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || cursorIsOpen(v,pOp->p1,k) -#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC || pOp->opcode==OP_Offset -#endif ); +#else + assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 + || cursorIsOpen(v,pOp->p1,k) + ); +#endif } }else if( pOp->opcode==OP_Rowid ){ pOp->p1 = pLevel->iIdxCur; From cb0854a380bef57b6ed0227e29d880a4be9e6acd Mon Sep 17 00:00:00 2001 From: larrybr Date: Tue, 22 Mar 2022 02:53:34 +0000 Subject: [PATCH 020/259] Create new branch named "extapi-serializing" FossilOrigin-Name: a1220a2170a09075a42d1d6c4b502ffa7cc92856779b9eb2ecb9e05c09ccedac --- manifest | 13 ++++++++----- manifest.uuid | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/manifest b/manifest index e1b5f85deb..e4877c1f89 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sallow\san\s#ifdef\sinside\sof\san\sassert(),\sas\sgcc\stells\sus\sthat\sis\nnot\sportable. -D 2022-03-21T20:08:13.044 +C Create\snew\sbranch\snamed\s"extapi-serializing" +D 2022-03-22T02:53:34.923 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1945,8 +1945,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 88d69f60cceb22bde42cfe43c23259c7bad47b8e06f918a79bd089a77b480d46 +P c7a2047e93df36c172be0be773f9a04150dafe7ba1773269d74016418d262fc4 R e549179e194537a8c238e9efdda7fdd8 -U drh -Z 1df73c54c069d2ae3e739535fe1bd6f4 +T *branch * extapi-serializing +T *sym-extapi-serializing * +T -sym-trunk * +U larrybr +Z f0119c9607692a68a3b40efe179fd906 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f0af174ea7..306ab7cba3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c7a2047e93df36c172be0be773f9a04150dafe7ba1773269d74016418d262fc4 \ No newline at end of file +a1220a2170a09075a42d1d6c4b502ffa7cc92856779b9eb2ecb9e05c09ccedac \ No newline at end of file From b5bb769c2713bc85134143bac971ffa513b4d4a7 Mon Sep 17 00:00:00 2001 From: larrybr Date: Tue, 22 Mar 2022 03:03:13 +0000 Subject: [PATCH 021/259] expose sqlite3_{deserialize,serialize}() in sqlite3ext.h FossilOrigin-Name: da874180d35aacdeb9c06f5b425e8909d833e2765179c4337854d56b8a624fd5 --- manifest | 17 +++++++---------- manifest.uuid | 2 +- src/loadext.c | 10 +++++++++- src/sqlite3ext.h | 9 +++++++++ 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index e4877c1f89..d615a0f523 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Create\snew\sbranch\snamed\s"extapi-serializing" -D 2022-03-22T02:53:34.923 +C expose\ssqlite3_{deserialize,serialize}()\sin\ssqlite3ext.h +D 2022-03-22T03:03:13.557 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -515,7 +515,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c c4fc48e6f38cc415262652407949771ce4e6f8f0c7330f872e44a0677f3ad602 F src/json.c 24fcd7f5f9080b04b89722c343010d390f85e55b2ab560046cb567c9dd640f62 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa -F src/loadext.c aa919a6a7884f8b34d7b791841b24d14b1b0ab43f45b3940f4851043b2855c0c +F src/loadext.c 2ecb1441f9b1c22e9e022ee0776e67d259facf34b56ba892b206f0a294ee6f8c F src/main.c 89dfd569b4fbcab65281b3c6d636b887b2cb23cbaa16f8c6b67062862144c927 F src/malloc.c fec841aa0a0400a6f7d20706178a5d8e8219a6bf562b6fe712c17f6c26813266 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 @@ -556,7 +556,7 @@ F src/select.c c366c05e48e836ea04f8ecefb9c1225745dc250c3f01bdb39e9cbb0dc25e3610 F src/shell.c.in a292c6f78b4dd0302adeea03929f2dffec14ab39b364e98f707de942af2b9ac2 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 -F src/sqlite3ext.h a95cb9ed106e3d39e2118e4dcc15a14faec3fa50d0093425083d340d9dfd96e6 +F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e F src/sqliteInt.h 2ce7d868630ccd70ffd4b15d46b59ccf7daf89198993b62ed6e4a165d3511280 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 @@ -1945,11 +1945,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 c7a2047e93df36c172be0be773f9a04150dafe7ba1773269d74016418d262fc4 -R e549179e194537a8c238e9efdda7fdd8 -T *branch * extapi-serializing -T *sym-extapi-serializing * -T -sym-trunk * +P a1220a2170a09075a42d1d6c4b502ffa7cc92856779b9eb2ecb9e05c09ccedac +R bf3c838ea5a83946446e0f353de9bf76 U larrybr -Z f0119c9607692a68a3b40efe179fd906 +Z 47187b657b7053b4c6d0a1936928ef2c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 306ab7cba3..e938c3d8cc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a1220a2170a09075a42d1d6c4b502ffa7cc92856779b9eb2ecb9e05c09ccedac \ No newline at end of file +da874180d35aacdeb9c06f5b425e8909d833e2765179c4337854d56b8a624fd5 \ No newline at end of file diff --git a/src/loadext.c b/src/loadext.c index 603516e18a..cefe2eb94c 100644 --- a/src/loadext.c +++ b/src/loadext.c @@ -491,7 +491,15 @@ static const sqlite3_api_routines sqlite3Apis = { sqlite3_vtab_distinct, sqlite3_vtab_in, sqlite3_vtab_in_first, - sqlite3_vtab_in_next + sqlite3_vtab_in_next, + /* Version 3.39.0 and later */ +#ifndef SQLITE_OMIT_DESERIALIZE + sqlite3_deserialize, + sqlite3_serialize +#else + 0, + 0 +#endif }; /* True if x is the directory separator character diff --git a/src/sqlite3ext.h b/src/sqlite3ext.h index 2eac4f3f05..a75dd496e7 100644 --- a/src/sqlite3ext.h +++ b/src/sqlite3ext.h @@ -351,6 +351,11 @@ struct sqlite3_api_routines { int (*vtab_in)(sqlite3_index_info*,int,int); int (*vtab_in_first)(sqlite3_value*,sqlite3_value**); int (*vtab_in_next)(sqlite3_value*,sqlite3_value**); + /* Version 3.39.0 and later */ + int (*deserialize)(sqlite3*,const char*,unsigned char*, + sqlite3_int64,sqlite3_int64,unsigned); + unsigned char *(*serialize)(sqlite3*,const char *,sqlite3_int64*, + unsigned int); }; /* @@ -669,6 +674,10 @@ typedef int (*sqlite3_loadext_entry)( #define sqlite3_vtab_in sqlite3_api->vtab_in #define sqlite3_vtab_in_first sqlite3_api->vtab_in_first #define sqlite3_vtab_in_next sqlite3_api->vtab_in_next +#ifndef SQLITE_OMIT_DESERIALIZE +#define sqlite3_deserialize sqlite3_api->deserialize +#define sqlite3_serialize sqlite3_api->serialize +#endif #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) From 56d88aad299a57368408a69c7357963a9ddd8f89 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 22 Mar 2022 19:41:55 +0000 Subject: [PATCH 022/259] Harden the xShmLock method of both the unix and Windows VFSes so that they are robust against being invoked when the SHM file is not open. FossilOrigin-Name: 67d8b434f628d44c4a90ce8ff5ab2e381f500bb42bdbfab9a17d21925a2ec6cd --- manifest | 15 +++++++-------- manifest.uuid | 2 +- src/os_unix.c | 12 +++++++++--- src/os_win.c | 6 +++++- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 8de26e80b2..e8a0b85d78 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sthe\ssqlite3_serialize()\sand\ssqlite3_deserialize()\sinterfaces\saccessible\nto\sloadable\sextensions. -D 2022-03-22T11:22:55.530 +C Harden\sthe\sxShmLock\smethod\sof\sboth\sthe\sunix\sand\sWindows\sVFSes\sso\sthat\sthey\nare\srobust\sagainst\sbeing\sinvoked\swhen\sthe\sSHM\sfile\sis\snot\sopen. +D 2022-03-22T19:41:55.891 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -536,8 +536,8 @@ F src/os.c b1c4f2d485961e9a5b6b648c36687d25047c252222e9660b7cc25a6e1ea436ab F src/os.h 26890f540b475598cd9881dcc68931377b8d429d3ea3e2eeb64470cde64199f8 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 -F src/os_unix.c f0dc85d439ece53120c4071c98876758ec24e6f713b67af3711af033c897091e -F src/os_win.c 77d39873836f1831a9b0b91894fec45ab0e9ca8e067dc8c549e1d1eca1566fe9 +F src/os_unix.c 1f71ec8c87621f75c9c5ea973f5e8ce2f1d23fe760c01ed2814fe4b98b639825 +F src/os_win.c a8ea80037e81127ca01959daa87387cc135f325c88dc745376c4f760de852a10 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 42120492784fc9bcd9082b5c9b5e329b7318c357f9f3574a1bbfcf7418910356 F src/pager.h f82e9844166e1585f5786837ddc7709966138ced17f568c16af7ccf946c2baa3 @@ -1945,9 +1945,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 c7a2047e93df36c172be0be773f9a04150dafe7ba1773269d74016418d262fc4 da874180d35aacdeb9c06f5b425e8909d833e2765179c4337854d56b8a624fd5 -R bf3c838ea5a83946446e0f353de9bf76 -T +closed da874180d35aacdeb9c06f5b425e8909d833e2765179c4337854d56b8a624fd5 +P 81f8746bc65828fb91e170393f22f1f4e9c587a8938e8c11b72315fcd6131403 +R d298ad7f59290d0a6efedfc24438d25c U drh -Z 464016fe3bfc08f8aed0a703c852c5bf +Z 4cb272d1327d5bb30f85a15fc2446351 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 56691d0ab3..4c5bd46b09 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -81f8746bc65828fb91e170393f22f1f4e9c587a8938e8c11b72315fcd6131403 \ No newline at end of file +67d8b434f628d44c4a90ce8ff5ab2e381f500bb42bdbfab9a17d21925a2ec6cd \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index f4e5421469..03ac3e46c9 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -4910,11 +4910,17 @@ static int unixShmLock( int flags /* What to do with the lock */ ){ unixFile *pDbFd = (unixFile*)fd; /* Connection holding shared memory */ - unixShm *p = pDbFd->pShm; /* The shared memory being locked */ - unixShmNode *pShmNode = p->pShmNode; /* The underlying file iNode */ + unixShm *p; /* The shared memory being locked */ + unixShmNode *pShmNode; /* The underlying file iNode */ int rc = SQLITE_OK; /* Result code */ u16 mask; /* Mask of locks to take or release */ - int *aLock = pShmNode->aLock; + int *aLock; + + p = pDbFd->pShm; + if( p==0 ) return SQLITE_IOERR_SHMLOCK; + pShmNode = p->pShmNode; + if( NEVER(pShmNode==0) ) return SQLITE_IOERR_SHMLOCK; + aLock = pShmNode->aLock; assert( pShmNode==pDbFd->pInode->pShmNode ); assert( pShmNode->pInode==pDbFd->pInode ); diff --git a/src/os_win.c b/src/os_win.c index d7c436eff9..8832c8012a 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -4070,10 +4070,14 @@ static int winShmLock( winFile *pDbFd = (winFile*)fd; /* Connection holding shared memory */ winShm *p = pDbFd->pShm; /* The shared memory being locked */ winShm *pX; /* For looping over all siblings */ - winShmNode *pShmNode = p->pShmNode; + winShmNode *pShmNode; int rc = SQLITE_OK; /* Result code */ u16 mask; /* Mask of locks to take or release */ + if( p==0 ) return SQLITE_IOERR_SHMLOCK; + pShmNode = p->pShmNode; + if( NEVER(pShmNode==0) ) return SQLITE_IOERR_SHMLOCK; + assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK ); assert( n>=1 ); assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED) From 500d7e542ce30c37a6427ffc20df16e942ea0820 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 22 Mar 2022 23:33:20 +0000 Subject: [PATCH 023/259] Ensure that database corruption does not cause the cursor passed into sqlite3BtreeDelete() to be invalid. dbsqlfuzz 209bf3de9ee11ae440848ab9bc9c13858f9be2e4. FossilOrigin-Name: a85126f96614c53b030c6e6c43ff239eae458048597a10e9a0361fcec8628ecf --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 17 +++++++++++------ 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index e8a0b85d78..8a9aac75fc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Harden\sthe\sxShmLock\smethod\sof\sboth\sthe\sunix\sand\sWindows\sVFSes\sso\sthat\sthey\nare\srobust\sagainst\sbeing\sinvoked\swhen\sthe\sSHM\sfile\sis\snot\sopen. -D 2022-03-22T19:41:55.891 +C Ensure\sthat\sdatabase\scorruption\sdoes\snot\scause\sthe\scursor\spassed\sinto\nsqlite3BtreeDelete()\sto\sbe\sinvalid.\ndbsqlfuzz\s209bf3de9ee11ae440848ab9bc9c13858f9be2e4. +D 2022-03-22T23:33:20.814 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -492,7 +492,7 @@ F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf F src/backup.c a2891172438e385fdbe97c11c9745676bec54f518d4447090af97189fd8e52d7 F src/bitvec.c 7c849aac407230278445cb069bebc5f89bf2ddd87c5ed9459b070a9175707b3d F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c dd4d780d2382551c4876b67d8716360a0df44ecbb3ca6b538877bc4109bf4215 +F src/btree.c 11a4719bbae5dc1da6d0e1e892302589420c054ad24ca523c10a66a39a123d06 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482e F src/build.c a0cc68fe8172c0a31b54576f9c6c0fe6f7c82b1b5e1387afdd6a5a13132bc131 @@ -1945,8 +1945,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 81f8746bc65828fb91e170393f22f1f4e9c587a8938e8c11b72315fcd6131403 -R d298ad7f59290d0a6efedfc24438d25c +P 67d8b434f628d44c4a90ce8ff5ab2e381f500bb42bdbfab9a17d21925a2ec6cd +R e6b2a5be1ca94fee0075c0fb950011d0 U drh -Z 4cb272d1327d5bb30f85a15fc2446351 +Z 7ec50fc10da9dc3290e1ed4062490cc2 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 4c5bd46b09..06cb848392 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -67d8b434f628d44c4a90ce8ff5ab2e381f500bb42bdbfab9a17d21925a2ec6cd \ No newline at end of file +a85126f96614c53b030c6e6c43ff239eae458048597a10e9a0361fcec8628ecf \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 41087825ba..d31d30c5ed 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9430,12 +9430,16 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); assert( !hasReadConflicts(p, pCur->pgnoRoot) ); assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 ); - if( pCur->eState==CURSOR_REQUIRESEEK ){ - rc = btreeRestoreCursorPosition(pCur); - assert( rc!=SQLITE_OK || CORRUPT_DB || pCur->eState==CURSOR_VALID ); - if( rc || pCur->eState!=CURSOR_VALID ) return rc; + if( pCur->eState!=CURSOR_VALID ){ + if( pCur->eState>=CURSOR_REQUIRESEEK ){ + rc = btreeRestoreCursorPosition(pCur); + assert( rc!=SQLITE_OK || CORRUPT_DB || pCur->eState==CURSOR_VALID ); + if( rc || pCur->eState!=CURSOR_VALID ) return rc; + }else{ + return SQLITE_CORRUPT_BKPT; + } } - assert( CORRUPT_DB || pCur->eState==CURSOR_VALID ); + assert( pCur->eState==CURSOR_VALID ); iCellDepth = pCur->iPage; iCellIdx = pCur->ix; @@ -9467,7 +9471,8 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ bPreserve = (flags & BTREE_SAVEPOSITION)!=0; if( bPreserve ){ if( !pPage->leaf - || (pPage->nFree+pPage->xCellSize(pPage,pCell)+2)>(int)(pBt->usableSize*2/3) + || (pPage->nFree+pPage->xCellSize(pPage,pCell)+2) > + (int)(pBt->usableSize*2/3) || pPage->nCell==1 /* See dbfuzz001.test for a test case */ ){ /* A b-tree rebalance will be required after deleting this entry. From 8ad3c4325793c053c2f23168e38f5cacd255d823 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 23 Mar 2022 10:04:52 +0000 Subject: [PATCH 024/259] Use trickery to code the UTF-8 BOM for the --bom option on .output, .once, and .excel in the CLI, to work around a warning in some Microsoft compilers. [https://fossil-scm.org/forum/forumpost/bd0844268f0fab71|Fossil forum post bd0844268f0fab71]. FossilOrigin-Name: 43143ad131f17734fd2eff849e0a1bc2e26daf6a28c7e07d697d38732e6af5fc --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c.in | 14 +++++++++----- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 8a9aac75fc..48ebdf8a82 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sdatabase\scorruption\sdoes\snot\scause\sthe\scursor\spassed\sinto\nsqlite3BtreeDelete()\sto\sbe\sinvalid.\ndbsqlfuzz\s209bf3de9ee11ae440848ab9bc9c13858f9be2e4. -D 2022-03-22T23:33:20.814 +C Use\strickery\sto\scode\sthe\sUTF-8\sBOM\sfor\sthe\s--bom\soption\son\s.output,\s.once,\nand\s.excel\sin\sthe\sCLI,\sto\swork\saround\sa\swarning\sin\ssome\sMicrosoft\scompilers.\n[https://fossil-scm.org/forum/forumpost/bd0844268f0fab71|Fossil\sforum\spost\sbd0844268f0fab71]. +D 2022-03-23T10:04:52.573 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -553,7 +553,7 @@ F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c ea935b87d6fb36c78b70cdc7b28561dc8f33f2ef37048389549c7b5ef9b0ba5e F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c c366c05e48e836ea04f8ecefb9c1225745dc250c3f01bdb39e9cbb0dc25e3610 -F src/shell.c.in a292c6f78b4dd0302adeea03929f2dffec14ab39b364e98f707de942af2b9ac2 +F src/shell.c.in 24d1082d275db252379629c2b3694dbfa0f8886530b0f6f9896d52e456afe510 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e @@ -1945,8 +1945,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 67d8b434f628d44c4a90ce8ff5ab2e381f500bb42bdbfab9a17d21925a2ec6cd -R e6b2a5be1ca94fee0075c0fb950011d0 +P a85126f96614c53b030c6e6c43ff239eae458048597a10e9a0361fcec8628ecf +R c0d21f3a897da32dc231cb9a9071f457 U drh -Z 7ec50fc10da9dc3290e1ed4062490cc2 +Z 59c54a229953561c06d50ca7a8ed1998 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 06cb848392..d9afa6af5b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a85126f96614c53b030c6e6c43ff239eae458048597a10e9a0361fcec8628ecf \ No newline at end of file +43143ad131f17734fd2eff849e0a1bc2e26daf6a28c7e07d697d38732e6af5fc \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 2758a73443..e5c546bd74 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -9591,9 +9591,10 @@ static int do_meta_command(char *zLine, ShellState *p){ int bTxtMode = 0; int i; int eMode = 0; - int bBOM = 0; - int bOnce = 0; /* 0: .output, 1: .once, 2: .excel */ + int bOnce = 0; /* 0: .output, 1: .once, 2: .excel */ + unsigned char zBOM[4]; /* Byte-order mark to using if --bom is present */ + zBOM[0] = 0; failIfSafeMode(p, "cannot run .%s in safe mode", azArg[0]); if( c=='e' ){ eMode = 'x'; @@ -9606,7 +9607,10 @@ static int do_meta_command(char *zLine, ShellState *p){ if( z[0]=='-' ){ if( z[1]=='-' ) z++; if( strcmp(z,"-bom")==0 ){ - bBOM = 1; + zBOM[0] = 0xef; + zBOM[1] = 0xbb; + zBOM[2] = 0xbf; + zBOM[3] = 0; }else if( c!='e' && strcmp(z,"-x")==0 ){ eMode = 'x'; /* spreadsheet */ }else if( c!='e' && strcmp(z,"-e")==0 ){ @@ -9675,7 +9679,7 @@ static int do_meta_command(char *zLine, ShellState *p){ p->out = stdout; rc = 1; }else{ - if( bBOM ) fprintf(p->out,"\357\273\277"); + if( zBOM[0] ) fwrite(zBOM, 1, 3, p->out); sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile); } #endif @@ -9688,7 +9692,7 @@ static int do_meta_command(char *zLine, ShellState *p){ p->out = stdout; rc = 1; } else { - if( bBOM ) fprintf(p->out,"\357\273\277"); + if( zBOM[0] ) fwrite(zBOM, 1, 3, p->out); sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile); } } From 5705b41fb80137aa0e63cbfaddf6ce63e7ea6d4d Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 24 Mar 2022 14:01:55 +0000 Subject: [PATCH 025/259] The "PRAGMA writable_schema=ON" flag should not allow OOM errors to pass while parsing the schema. dbsqlfuzz 9cc49e1a53e1cef8e3a1496a88c683aa20483163. FossilOrigin-Name: a7abb725c7c783331e73837597917e25e5ff692aac8ec97a0a8c0e30db62d68b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/prepare.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 48ebdf8a82..5606959056 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\strickery\sto\scode\sthe\sUTF-8\sBOM\sfor\sthe\s--bom\soption\son\s.output,\s.once,\nand\s.excel\sin\sthe\sCLI,\sto\swork\saround\sa\swarning\sin\ssome\sMicrosoft\scompilers.\n[https://fossil-scm.org/forum/forumpost/bd0844268f0fab71|Fossil\sforum\spost\sbd0844268f0fab71]. -D 2022-03-23T10:04:52.573 +C The\s"PRAGMA\swritable_schema=ON"\sflag\sshould\snot\sallow\sOOM\serrors\sto\spass\nwhile\sparsing\sthe\sschema.\ndbsqlfuzz\s9cc49e1a53e1cef8e3a1496a88c683aa20483163. +D 2022-03-24T14:01:55.718 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -547,7 +547,7 @@ F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 54881292a9a5db202b2c0ac541c5e3ef9a5e8c4f1c1383adb2601d5499a60e65 F src/pragma.c 9047ffb003d9434810ee81d7b1722d0093821622eb3217c962c3407bad949ce2 F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 -F src/prepare.c a187dade741c1f09ae118fcbbf0302511807bfc0355880927d7152eb75b8260d +F src/prepare.c fd940149c691684e7c1073c3787a7170e44852b02d1275d2e30a5b58e89cfcaf F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c ea935b87d6fb36c78b70cdc7b28561dc8f33f2ef37048389549c7b5ef9b0ba5e @@ -1945,8 +1945,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 a85126f96614c53b030c6e6c43ff239eae458048597a10e9a0361fcec8628ecf -R c0d21f3a897da32dc231cb9a9071f457 +P 43143ad131f17734fd2eff849e0a1bc2e26daf6a28c7e07d697d38732e6af5fc +R c6ecdf0c09fcfac1e33c997c57a43f56 U drh -Z 59c54a229953561c06d50ca7a8ed1998 +Z 9ff38d7c1e3943096d040996e86f8218 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d9afa6af5b..515843110e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -43143ad131f17734fd2eff849e0a1bc2e26daf6a28c7e07d697d38732e6af5fc \ No newline at end of file +a7abb725c7c783331e73837597917e25e5ff692aac8ec97a0a8c0e30db62d68b \ No newline at end of file diff --git a/src/prepare.c b/src/prepare.c index 7e08a5a674..d402da4a3a 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -389,7 +389,7 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){ sqlite3ResetAllSchemasOfConnection(db); pDb = &db->aDb[iDb]; }else - if( rc==SQLITE_OK || (db->flags&SQLITE_NoSchemaError)){ + if( rc==SQLITE_OK || ((db->flags&SQLITE_NoSchemaError) && rc!=SQLITE_NOMEM)){ /* Hack: If the SQLITE_NoSchemaError flag is set, then consider ** the schema loaded, even if errors (other than OOM) occurred. In ** this situation the current sqlite3_prepare() operation will fail, From be341502dbb10ca5941f41ce65df11c2d52290e3 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 25 Mar 2022 01:23:37 +0000 Subject: [PATCH 026/259] Fix the Bloom-filter optimization so that it does not use IS NULL or IS NOT NULL constraints from the WHERE clause when operating on a LEFT JOIN. [forum:/forumpost/031e262a89b6a9d2|Forum thread 031e262a89b6a9d2]. FossilOrigin-Name: 1a6328f2a5b4973094e5f85787145d652119822c86ec01a61f3f985c9d2903f2 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 13 +++++++++++-- test/join5.test | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 53 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 5606959056..9769465203 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\s"PRAGMA\swritable_schema=ON"\sflag\sshould\snot\sallow\sOOM\serrors\sto\spass\nwhile\sparsing\sthe\sschema.\ndbsqlfuzz\s9cc49e1a53e1cef8e3a1496a88c683aa20483163. -D 2022-03-24T14:01:55.718 +C Fix\sthe\sBloom-filter\soptimization\sso\sthat\sit\sdoes\snot\suse\sIS\sNULL\sor\nIS\sNOT\sNULL\sconstraints\sfrom\sthe\sWHERE\sclause\swhen\soperating\son\sa\sLEFT\sJOIN.\n[forum:/forumpost/031e262a89b6a9d2|Forum\sthread\s031e262a89b6a9d2]. +D 2022-03-25T01:23:37.631 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -639,7 +639,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c 9cba7b9e58d4d07f08bb0cb5b9b982d359c8051050df9114ee927cf6798e5509 +F src/where.c 7c2c5feb3600d02b827effece817adda0cc1d96ddb9ebe7494c990d53dc26180 F src/whereInt.h 15d2975c3b4c193c78c26674400a840da8647fe1777ae3b026e2d15937b38a03 F src/wherecode.c 555f598a9ddad81761f084710fdb4f8733fe31bc14cd6b19f8ca4274a7eaa04c F src/whereexpr.c 2a71f5491798460c9590317329234d332d9eb1717cba4f3403122189a75c465e @@ -1144,7 +1144,7 @@ F test/join.test 25cf0ac11c3b81fedfd166f9062166bdb39dea92f5a7c16cacbf6dc1f7f6702 F test/join2.test 9bdc615841b91c97a16d68bad9508aea11fa0c6b34e5689847bcc4dac70e4990 F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 -F test/join5.test 3d51c4ae5f1f373a03164ca3c88d438f64bed7a2c01cf69810e2ca3d0e9071c8 +F test/join5.test 0d63c7e43b3160b9d4b93f196ef83b6efc7751b9edd0d18c53a46fbec7a49cfc F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 @@ -1945,8 +1945,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 43143ad131f17734fd2eff849e0a1bc2e26daf6a28c7e07d697d38732e6af5fc -R c6ecdf0c09fcfac1e33c997c57a43f56 +P a7abb725c7c783331e73837597917e25e5ff692aac8ec97a0a8c0e30db62d68b +R 7df72da8b94385b7c430ac7b857fb766 U drh -Z 9ff38d7c1e3943096d040996e86f8218 +Z f44c9fa4c137748740188f91b08447a0 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 515843110e..2c894bd6bf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a7abb725c7c783331e73837597917e25e5ff692aac8ec97a0a8c0e30db62d68b \ No newline at end of file +1a6328f2a5b4973094e5f85787145d652119822c86ec01a61f3f985c9d2903f2 \ No newline at end of file diff --git a/src/where.c b/src/where.c index bec77cc45d..c8a3cba2ec 100644 --- a/src/where.c +++ b/src/where.c @@ -2596,8 +2596,17 @@ static void whereLoopOutputAdjust( /* If there are extra terms in the WHERE clause not used by an index ** that depend only on the table being scanned, and that will tend to ** cause many rows to be omitted, then mark that table as - ** "self-culling". */ - pLoop->wsFlags |= WHERE_SELFCULL; + ** "self-culling". + ** + ** 2022-03-24: Self-culling only applies if either the extra terms + ** are straight comparison operators that are non-true with NULL + ** operand, or if the loop is not a LEFT JOIN. + */ + if( (pTerm->eOperator & 0x3f)!=0 + || (pWC->pWInfo->pTabList->a[pLoop->iTab].fg.jointype & JT_LEFT)==0 + ){ + pLoop->wsFlags |= WHERE_SELFCULL; + } } if( pTerm->truthProb<=0 ){ /* If a truth probability is specified using the likelihood() hints, diff --git a/test/join5.test b/test/join5.test index 518fab7a92..a5cedd8cb2 100644 --- a/test/join5.test +++ b/test/join5.test @@ -300,6 +300,13 @@ do_execsql_test 7.3 { do_eqp_test 7.4 { SELECT * FROM t3 LEFT JOIN t4 ON (t4.x = t3.x) WHERE (t4.y = ? OR t4.z = ?); +} { + QUERY PLAN + |--SCAN t3 + `--SEARCH t4 USING INDEX t4xz (x=?) +} +do_eqp_test 7.4b { + SELECT * FROM t3 CROSS JOIN t4 ON (t4.x = t3.x) WHERE (+t4.y = ? OR t4.z = ?); } { QUERY PLAN |--SCAN t3 @@ -360,5 +367,32 @@ do_execsql_test 10.1 { SELECT x FROM v3; } {0} +# 2022-03-24 https://sqlite.org/forum/forumpost/031e262a89b6a9d2 +# Bloom-filter on a LEFT JOIN with NULL-based WHERE constraints. +# +reset_db +do_execsql_test 11.1 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT); + CREATE TABLE t2(c INTEGER PRIMARY KEY, d INT); + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<8) + INSERT INTO t1(a,b) SELECT x, 10*x FROM c; + INSERT INTO t2(c,d) SELECT b*2, 100*a FROM t1; + ANALYZE; + DELETE FROM sqlite_stat1; + INSERT INTO sqlite_stat1(tbl,idx,stat) VALUES + ('t1',NULL,150105),('t2',NULL,98747); + ANALYZE sqlite_schema; +} {} +do_execsql_test 11.2 { + SELECT count(*) FROM t1 LEFT JOIN t2 ON c=b WHERE d IS NULL; +} {4} +do_execsql_test 11.3 { + SELECT count(*) FROM t1 LEFT JOIN t2 ON c=b WHERE d=100; +} {1} +do_execsql_test 11.4 { + SELECT count(*) FROM t1 LEFT JOIN t2 ON c=b WHERE d>=300; +} {2} + + finish_test From f5a8386c328122402f5bc30bb8a4cf59cd8e28a2 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 28 Mar 2022 13:22:54 +0000 Subject: [PATCH 027/259] Performance optimization in the memsys5 memory allocator. FossilOrigin-Name: 949133231f8f751aa86518d0d3f6f03d7827fec085bfef3929fa3d57369d0216 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/mem5.c | 9 +++++++-- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 9769465203..72da5c29d6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sBloom-filter\soptimization\sso\sthat\sit\sdoes\snot\suse\sIS\sNULL\sor\nIS\sNOT\sNULL\sconstraints\sfrom\sthe\sWHERE\sclause\swhen\soperating\son\sa\sLEFT\sJOIN.\n[forum:/forumpost/031e262a89b6a9d2|Forum\sthread\s031e262a89b6a9d2]. -D 2022-03-25T01:23:37.631 +C Performance\soptimization\sin\sthe\smemsys5\smemory\sallocator. +D 2022-03-28T13:22:54.383 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -522,7 +522,7 @@ F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de F src/mem2.c c8bfc9446fd0798bddd495eb5d9dbafa7d4b7287d8c22d50a83ac9daa26d8a75 F src/mem3.c 30301196cace2a085cbedee1326a49f4b26deff0af68774ca82c1f7c06fda4f6 -F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944 +F src/mem5.c 5a3dbd8ac8a6501152a4fc1fcae9b0900c2d7eb0589c4ec7456fdde15725a26c F src/memdb.c c2dc88f97c410eb68a24468344b65526685e18354ddfd15906750c1eaf9dc2dd F src/memjournal.c 8bd50ae6d9c6d34b3a96cc3b4f567f9935dc358444d872ab48901a8c11ad82a6 F src/msvc.h 3a15918220367a8876be3fa4f2abe423a861491e84b864fb2b7426bf022a28f8 @@ -1945,8 +1945,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 a7abb725c7c783331e73837597917e25e5ff692aac8ec97a0a8c0e30db62d68b -R 7df72da8b94385b7c430ac7b857fb766 +P 1a6328f2a5b4973094e5f85787145d652119822c86ec01a61f3f985c9d2903f2 +R 075c473a8f2a578df0cfd2b3c1673c63 U drh -Z f44c9fa4c137748740188f91b08447a0 +Z 68a9fe4db4958adfd158cca3b2637b20 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2c894bd6bf..3c17d65bca 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1a6328f2a5b4973094e5f85787145d652119822c86ec01a61f3f985c9d2903f2 \ No newline at end of file +949133231f8f751aa86518d0d3f6f03d7827fec085bfef3929fa3d57369d0216 \ No newline at end of file diff --git a/src/mem5.c b/src/mem5.c index c194a6b778..b61b93e112 100644 --- a/src/mem5.c +++ b/src/mem5.c @@ -420,8 +420,13 @@ static void *memsys5Realloc(void *pPrior, int nBytes){ */ static int memsys5Roundup(int n){ int iFullSz; - if( n > 0x40000000 ) return 0; - for(iFullSz=mem5.szAtom; iFullSz0x40000000 ) return 0; + for(iFullSz=mem5.szAtom*8; iFullSz=n ) return iFullSz/2; return iFullSz; } From da3ec15f3c9651b0f7e439fccd256a3a1a4792f4 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 28 Mar 2022 14:18:03 +0000 Subject: [PATCH 028/259] Use sqlite3DbFreeNN() instead of sqlite3DbFree() in a few hot spots for better performance. FossilOrigin-Name: b12de0ecc78a4f654c8e7b2b17cc2201688808a4f516908e9563a216677e655c --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/tokenize.c | 2 +- src/vdbeaux.c | 10 ++++++---- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 72da5c29d6..dbf6485433 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimization\sin\sthe\smemsys5\smemory\sallocator. -D 2022-03-28T13:22:54.383 +C Use\ssqlite3DbFreeNN()\sinstead\sof\ssqlite3DbFree()\sin\sa\sfew\shot\sspots\sfor\nbetter\sperformance. +D 2022-03-28T14:18:03.634 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -616,7 +616,7 @@ F src/test_windirent.h 90dfbe95442c9762357fe128dc7ae3dc199d006de93eb33ba3972e0a9 F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394ba3f F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c -F src/tokenize.c 6661a9fa660ecbd3ac0df1acd2ec788b3a8122b4316022bcdaf476ea6754a8de +F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98 F src/treeview.c 3fac35b0835998f34bc940cb07282c5c485caa1645135435fca07ba828c48463 F src/trigger.c 8caa0baf1b18522863cf0fd611ef483962cfa50155ca82ad43e63b20f863a683 F src/update.c f875b0d59da5c3055a0b2ac20560e1650229c6787e78de5e9836267b5cbb8359 @@ -628,7 +628,7 @@ F src/vdbe.c b1830c6daf744473a732257652b6431ac18032f508a3e30ff3a1466fe5978559 F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e F src/vdbeInt.h 8dd91427155a38ec06e9ecbde07e33f21bc02e101625191e7613f883e379a363 F src/vdbeapi.c bc3812dff7c9e6497c87ae86962818a51f66f8d7a873e7ec02a22aa115b84799 -F src/vdbeaux.c 33c61dc3dbe920f262371ad2ba3e10277d27d8e35ee86075e2aef74113eae251 +F src/vdbeaux.c 1a718a2baef76f2e6fcf7fe12d60e4a2a3b5ccb84b0733ab3f8d1fbe312dce19 F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 57fceb4ed6aac960e9517c963dc0668189e8b7c8e6216d257030a2f5e9a583df F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 @@ -1945,8 +1945,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 1a6328f2a5b4973094e5f85787145d652119822c86ec01a61f3f985c9d2903f2 -R 075c473a8f2a578df0cfd2b3c1673c63 +P 949133231f8f751aa86518d0d3f6f03d7827fec085bfef3929fa3d57369d0216 +R 8bb789d6e9ef98c61a24ee7a63b36635 U drh -Z 68a9fe4db4958adfd158cca3b2637b20 +Z 93250572ce0f63983b330a7fac8a4441 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3c17d65bca..a0ed9f22bc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -949133231f8f751aa86518d0d3f6f03d7827fec085bfef3929fa3d57369d0216 \ No newline at end of file +b12de0ecc78a4f654c8e7b2b17cc2201688808a4f516908e9563a216677e655c \ No newline at end of file diff --git a/src/tokenize.c b/src/tokenize.c index a727078ba7..f0c0cc1910 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -710,7 +710,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql){ if( pParse->pNewTrigger && !IN_RENAME_OBJECT ){ sqlite3DeleteTrigger(db, pParse->pNewTrigger); } - sqlite3DbFree(db, pParse->pVList); + if( pParse->pVList ) sqlite3DbFreeNN(db, pParse->pVList); db->pParse = pParentParse; assert( nErr==0 || pParse->rc!=SQLITE_OK ); return nErr; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index be6406cffc..d48909b614 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3439,7 +3439,10 @@ void sqlite3VdbeDeleteAuxData(sqlite3 *db, AuxData **pp, int iOp, int mask){ void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ SubProgram *pSub, *pNext; assert( p->db==0 || p->db==db ); - releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); + if( p->aColName ){ + releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); + sqlite3DbFreeNN(db, p->aColName); + } for(pSub=p->pProgram; pSub; pSub=pNext){ pNext = pSub->pNext; vdbeFreeOpArray(db, pSub->aOp, pSub->nOp); @@ -3447,11 +3450,10 @@ void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ } if( p->iVdbeMagic!=VDBE_MAGIC_INIT ){ releaseMemArray(p->aVar, p->nVar); - sqlite3DbFree(db, p->pVList); - sqlite3DbFree(db, p->pFree); + if( p->pVList ) sqlite3DbFreeNN(db, p->pVList); + if( p->pFree ) sqlite3DbFreeNN(db, p->pFree); } vdbeFreeOpArray(db, p->aOp, p->nOp); - sqlite3DbFree(db, p->aColName); sqlite3DbFree(db, p->zSql); #ifdef SQLITE_ENABLE_NORMALIZE sqlite3DbFree(db, p->zNormSql); From cea170ec96aeee0042ba716251d18a057e2d5287 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 28 Mar 2022 14:56:47 +0000 Subject: [PATCH 029/259] Another small performance gain by using sqlite3DbFreeNN(). FossilOrigin-Name: daa924af987253345bdb1c71b13378681bd252521e94d01f5d4629601232c352 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 6 ++++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index dbf6485433..a5a4107b3b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\ssqlite3DbFreeNN()\sinstead\sof\ssqlite3DbFree()\sin\sa\sfew\shot\sspots\sfor\nbetter\sperformance. -D 2022-03-28T14:18:03.634 +C Another\ssmall\sperformance\sgain\sby\susing\ssqlite3DbFreeNN(). +D 2022-03-28T14:56:47.340 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -628,7 +628,7 @@ F src/vdbe.c b1830c6daf744473a732257652b6431ac18032f508a3e30ff3a1466fe5978559 F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e F src/vdbeInt.h 8dd91427155a38ec06e9ecbde07e33f21bc02e101625191e7613f883e379a363 F src/vdbeapi.c bc3812dff7c9e6497c87ae86962818a51f66f8d7a873e7ec02a22aa115b84799 -F src/vdbeaux.c 1a718a2baef76f2e6fcf7fe12d60e4a2a3b5ccb84b0733ab3f8d1fbe312dce19 +F src/vdbeaux.c eb7e1379abdd414b8585510e137a7061196c6d55a0d5a4c9e9c60b7d45bcb414 F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 57fceb4ed6aac960e9517c963dc0668189e8b7c8e6216d257030a2f5e9a583df F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 @@ -1945,8 +1945,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 949133231f8f751aa86518d0d3f6f03d7827fec085bfef3929fa3d57369d0216 -R 8bb789d6e9ef98c61a24ee7a63b36635 +P b12de0ecc78a4f654c8e7b2b17cc2201688808a4f516908e9563a216677e655c +R 240acd8eb9a53671ac46c1b4413159b7 U drh -Z 93250572ce0f63983b330a7fac8a4441 +Z 55979c13a79d18f654ea77f2201d732c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a0ed9f22bc..9b1468fc0d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b12de0ecc78a4f654c8e7b2b17cc2201688808a4f516908e9563a216677e655c \ No newline at end of file +daa924af987253345bdb1c71b13378681bd252521e94d01f5d4629601232c352 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index d48909b614..ad26075d47 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -863,8 +863,10 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ if( pOp==p->aOp ) break; pOp--; } - sqlite3DbFree(p->db, pParse->aLabel); - pParse->aLabel = 0; + if( aLabel ){ + sqlite3DbFreeNN(p->db, pParse->aLabel); + pParse->aLabel = 0; + } pParse->nLabel = 0; *pMaxFuncArgs = nMaxArgs; assert( p->bIsReader!=0 || DbMaskAllZero(p->btreeMask) ); From 60a512d923d3351cba2131d0ab9031cbb8c59741 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 28 Mar 2022 15:06:36 +0000 Subject: [PATCH 030/259] Performance increase in the loop that frees an opcode array. FossilOrigin-Name: 4ccebb86aae178dbce905d782f04d98211f8fce9aacd71c12b8694c92a4f5c40 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 7 +++++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index a5a4107b3b..bfa5d8e376 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Another\ssmall\sperformance\sgain\sby\susing\ssqlite3DbFreeNN(). -D 2022-03-28T14:56:47.340 +C Performance\sincrease\sin\sthe\sloop\sthat\sfrees\san\sopcode\sarray. +D 2022-03-28T15:06:36.675 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -628,7 +628,7 @@ F src/vdbe.c b1830c6daf744473a732257652b6431ac18032f508a3e30ff3a1466fe5978559 F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e F src/vdbeInt.h 8dd91427155a38ec06e9ecbde07e33f21bc02e101625191e7613f883e379a363 F src/vdbeapi.c bc3812dff7c9e6497c87ae86962818a51f66f8d7a873e7ec02a22aa115b84799 -F src/vdbeaux.c eb7e1379abdd414b8585510e137a7061196c6d55a0d5a4c9e9c60b7d45bcb414 +F src/vdbeaux.c 1de06d17a1af1bf5cc776e60afcc01c49438df90863fc4db0a0516060e7b959a F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 57fceb4ed6aac960e9517c963dc0668189e8b7c8e6216d257030a2f5e9a583df F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 @@ -1945,8 +1945,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 b12de0ecc78a4f654c8e7b2b17cc2201688808a4f516908e9563a216677e655c -R 240acd8eb9a53671ac46c1b4413159b7 +P daa924af987253345bdb1c71b13378681bd252521e94d01f5d4629601232c352 +R 3f80c1c90cf9e3dfa7b095bf09b6a361 U drh -Z 55979c13a79d18f654ea77f2201d732c +Z b8e292382fc35254c1fc18d26e049666 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9b1468fc0d..c22cb673ca 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -daa924af987253345bdb1c71b13378681bd252521e94d01f5d4629601232c352 \ No newline at end of file +4ccebb86aae178dbce905d782f04d98211f8fce9aacd71c12b8694c92a4f5c40 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index ad26075d47..56b433ef62 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1152,13 +1152,16 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){ ** nOp entries. */ static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){ + assert( nOp>=0 ); if( aOp ){ - Op *pOp; - for(pOp=&aOp[nOp-1]; pOp>=aOp; pOp--){ + Op *pOp = &aOp[nOp-1]; + while(1){ /* Exit via break */ if( pOp->p4type <= P4_FREE_IF_LE ) freeP4(db, pOp->p4type, pOp->p4.p); #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS sqlite3DbFree(db, pOp->zComment); #endif + if( pOp==aOp ) break; + pOp--; } sqlite3DbFreeNN(db, aOp); } From f4dd18ea36ca6fd0468d9e2ab49d8df9214f9ebf Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 28 Mar 2022 17:34:46 +0000 Subject: [PATCH 031/259] Slightly smaller and faster sqlite3VdbeMemSetStr(). FossilOrigin-Name: 06928e745c7bcb26ec46a17989f30efe3536fd48a74c8a1cd423cc9ff6feccb5 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbemem.c | 13 +++++++++++-- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index bfa5d8e376..b3b35b83e2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\sincrease\sin\sthe\sloop\sthat\sfrees\san\sopcode\sarray. -D 2022-03-28T15:06:36.675 +C Slightly\ssmaller\sand\sfaster\ssqlite3VdbeMemSetStr(). +D 2022-03-28T17:34:46.798 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -630,7 +630,7 @@ F src/vdbeInt.h 8dd91427155a38ec06e9ecbde07e33f21bc02e101625191e7613f883e379a363 F src/vdbeapi.c bc3812dff7c9e6497c87ae86962818a51f66f8d7a873e7ec02a22aa115b84799 F src/vdbeaux.c 1de06d17a1af1bf5cc776e60afcc01c49438df90863fc4db0a0516060e7b959a F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd -F src/vdbemem.c 57fceb4ed6aac960e9517c963dc0668189e8b7c8e6216d257030a2f5e9a583df +F src/vdbemem.c 4fdef7b1dadb7073ea6c20f366f84cce5e01f8795317d4fd55cf2c9d6e5febf4 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823 F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c @@ -1945,8 +1945,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 daa924af987253345bdb1c71b13378681bd252521e94d01f5d4629601232c352 -R 3f80c1c90cf9e3dfa7b095bf09b6a361 +P 4ccebb86aae178dbce905d782f04d98211f8fce9aacd71c12b8694c92a4f5c40 +R d5c1e4092f171ba4e7d9a62fbfe55090 U drh -Z b8e292382fc35254c1fc18d26e049666 +Z 6eb24c52f69c2c05bf470575314084b5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c22cb673ca..33159274fb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4ccebb86aae178dbce905d782f04d98211f8fce9aacd71c12b8694c92a4f5c40 \ No newline at end of file +06928e745c7bcb26ec46a17989f30efe3536fd48a74c8a1cd423cc9ff6feccb5 \ No newline at end of file diff --git a/src/vdbemem.c b/src/vdbemem.c index 516a06b71e..b41b13e2f5 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1107,6 +1107,13 @@ void sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){ ** stored without allocating memory, then it is. If a memory allocation ** is required to store the string, then value of pMem is unchanged. In ** either case, SQLITE_TOOBIG is returned. +** +** The "enc" parameter is the text encoding for the string, or zero +** to store a blob. +** +** If n is negative, then the string consists of all bytes up to but +** excluding the first zero character. The n parameter must be +** non-negative for blobs. */ int sqlite3VdbeMemSetStr( Mem *pMem, /* Memory cell to set to string value */ @@ -1122,6 +1129,7 @@ int sqlite3VdbeMemSetStr( assert( pMem!=0 ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( !sqlite3VdbeMemIsRowSet(pMem) ); + assert( enc!=0 || n>=0 ); /* If z is a NULL pointer, set pMem to contain an SQL NULL. */ if( !z ){ @@ -1134,7 +1142,6 @@ int sqlite3VdbeMemSetStr( }else{ iLimit = SQLITE_MAX_LENGTH; } - flags = (enc==0?MEM_Blob:MEM_Str); if( nByte<0 ){ assert( enc!=0 ); if( enc==SQLITE_UTF8 ){ @@ -1142,7 +1149,9 @@ int sqlite3VdbeMemSetStr( }else{ for(nByte=0; nByte<=iLimit && (z[nByte] | z[nByte+1]); nByte+=2){} } - flags |= MEM_Term; + flags|= MEM_Str|MEM_Term; + }else{ + flags = (enc==0?MEM_Blob:MEM_Str); } /* The following block sets the new values of Mem.z and Mem.xDel. It From bcedbb2781e2fc9acca1ea926e52525e255e279e Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 28 Mar 2022 18:34:40 +0000 Subject: [PATCH 032/259] Further size and performance optimizations for sqlite3VdbeMemSetStr(). FossilOrigin-Name: 310a3e102d8eedf92ee63ffffb48621abfb1e2736b96bd2a676d63cca0f40598 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbemem.c | 46 ++++++++++++++++++++++++++-------------------- 3 files changed, 33 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index b3b35b83e2..d6dc655417 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Slightly\ssmaller\sand\sfaster\ssqlite3VdbeMemSetStr(). -D 2022-03-28T17:34:46.798 +C Further\ssize\sand\sperformance\soptimizations\sfor\ssqlite3VdbeMemSetStr(). +D 2022-03-28T18:34:40.795 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -630,7 +630,7 @@ F src/vdbeInt.h 8dd91427155a38ec06e9ecbde07e33f21bc02e101625191e7613f883e379a363 F src/vdbeapi.c bc3812dff7c9e6497c87ae86962818a51f66f8d7a873e7ec02a22aa115b84799 F src/vdbeaux.c 1de06d17a1af1bf5cc776e60afcc01c49438df90863fc4db0a0516060e7b959a F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd -F src/vdbemem.c 4fdef7b1dadb7073ea6c20f366f84cce5e01f8795317d4fd55cf2c9d6e5febf4 +F src/vdbemem.c dc02c6b8d51bcfc50f02266cb7003395d2989b72a9df6be561fcecdf16040784 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823 F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c @@ -1945,8 +1945,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 4ccebb86aae178dbce905d782f04d98211f8fce9aacd71c12b8694c92a4f5c40 -R d5c1e4092f171ba4e7d9a62fbfe55090 +P 06928e745c7bcb26ec46a17989f30efe3536fd48a74c8a1cd423cc9ff6feccb5 +R e5b296feee8b6ff8861e4cf66944c654 U drh -Z 6eb24c52f69c2c05bf470575314084b5 +Z 8d86ba5638b23b699bb683c424e71903 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 33159274fb..17903a1e91 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -06928e745c7bcb26ec46a17989f30efe3536fd48a74c8a1cd423cc9ff6feccb5 \ No newline at end of file +310a3e102d8eedf92ee63ffffb48621abfb1e2736b96bd2a676d63cca0f40598 \ No newline at end of file diff --git a/src/vdbemem.c b/src/vdbemem.c index b41b13e2f5..524280e0df 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1124,7 +1124,7 @@ int sqlite3VdbeMemSetStr( ){ i64 nByte = n; /* New value for pMem->n */ int iLimit; /* Maximum allowed string or blob size */ - u16 flags = 0; /* New value for pMem->flags */ + u16 flags; /* New value for pMem->flags */ assert( pMem!=0 ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); @@ -1149,9 +1149,27 @@ int sqlite3VdbeMemSetStr( }else{ for(nByte=0; nByte<=iLimit && (z[nByte] | z[nByte+1]); nByte+=2){} } - flags|= MEM_Str|MEM_Term; + flags= MEM_Str|MEM_Term; + }else if( enc==0 ){ + flags = MEM_Blob; +#ifdef SQLITE_ENABLE_SESSION + enc = pMem->db ? ENC(pMem->db) : SQLITE_UTF8; +#else + assert( pMem->db!=0 ); + enc = ENC(pMem->db); +#endif }else{ - flags = (enc==0?MEM_Blob:MEM_Str); + flags = MEM_Str; + } + if( nByte>iLimit ){ + if( xDel && xDel!=SQLITE_TRANSIENT ){ + if( xDel==SQLITE_DYNAMIC ){ + sqlite3DbFree(pMem->db, (void*)z); + }else{ + xDel((void*)z); + } + } + return sqlite3ErrorToParser(pMem->db, SQLITE_TOOBIG); } /* The following block sets the new values of Mem.z and Mem.xDel. It @@ -1163,9 +1181,6 @@ int sqlite3VdbeMemSetStr( if( flags&MEM_Term ){ nAlloc += (enc==SQLITE_UTF8?1:2); } - if( nByte>iLimit ){ - return sqlite3ErrorToParser(pMem->db, SQLITE_TOOBIG); - } testcase( nAlloc==0 ); testcase( nAlloc==31 ); testcase( nAlloc==32 ); @@ -1187,26 +1202,17 @@ int sqlite3VdbeMemSetStr( pMem->n = (int)(nByte & 0x7fffffff); pMem->flags = flags; - if( enc ){ - pMem->enc = enc; -#ifdef SQLITE_ENABLE_SESSION - }else if( pMem->db==0 ){ - pMem->enc = SQLITE_UTF8; -#endif - }else{ - assert( pMem->db!=0 ); - pMem->enc = ENC(pMem->db); - } + pMem->enc = enc; #ifndef SQLITE_OMIT_UTF16 - if( enc>SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){ + if( enc>SQLITE_UTF8 + && (flags & MEM_Blob)==0 + && sqlite3VdbeMemHandleBom(pMem) + ){ return SQLITE_NOMEM_BKPT; } #endif - if( nByte>iLimit ){ - return sqlite3ErrorToParser(pMem->db, SQLITE_TOOBIG); - } return SQLITE_OK; } From fb92e071861384455519a718706d217c4e91a7d6 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 29 Mar 2022 01:43:09 +0000 Subject: [PATCH 033/259] Fix the sqlite3_result_xxxxx() routines so that they all check for and perform any necessary text encoding conversions and check for oversize strings and BLOBs. Thus those checks can be done where they are most efficient and avoided in cases like OP_Function where they are more expensive. FossilOrigin-Name: d50b162b2f2e320af0889b931351f9443580465a933f6657fa98f437b6579277 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/vdbe.c | 15 ++++----------- src/vdbeapi.c | 25 +++++++++++++++++++------ src/vdbemem.c | 18 +++++++----------- 5 files changed, 39 insertions(+), 37 deletions(-) diff --git a/manifest b/manifest index d6dc655417..c7638368d1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\ssize\sand\sperformance\soptimizations\sfor\ssqlite3VdbeMemSetStr(). -D 2022-03-28T18:34:40.795 +C Fix\sthe\ssqlite3_result_xxxxx()\sroutines\sso\sthat\sthey\sall\scheck\sfor\sand\nperform\sany\snecessary\stext\sencoding\sconversions\sand\scheck\sfor\soversize\nstrings\sand\sBLOBs.\s\sThus\sthose\schecks\scan\sbe\sdone\swhere\sthey\sare\smost\nefficient\sand\savoided\sin\scases\slike\sOP_Function\swhere\sthey\sare\smore\nexpensive. +D 2022-03-29T01:43:09.917 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -624,13 +624,13 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c b1830c6daf744473a732257652b6431ac18032f508a3e30ff3a1466fe5978559 +F src/vdbe.c af4a5e9d64dbcc484be1fa4609b655577f81ee2cd40b61e96bece6d43718ae91 F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e F src/vdbeInt.h 8dd91427155a38ec06e9ecbde07e33f21bc02e101625191e7613f883e379a363 -F src/vdbeapi.c bc3812dff7c9e6497c87ae86962818a51f66f8d7a873e7ec02a22aa115b84799 +F src/vdbeapi.c 299da88f2788ac50b83890bbcfcfbfd09f5863604ad66f6165010cd897d087b5 F src/vdbeaux.c 1de06d17a1af1bf5cc776e60afcc01c49438df90863fc4db0a0516060e7b959a F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd -F src/vdbemem.c dc02c6b8d51bcfc50f02266cb7003395d2989b72a9df6be561fcecdf16040784 +F src/vdbemem.c d6add1f60a255bd513b2b66a4139e810a8060bfe3d0639c34a0b80923d00ef35 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823 F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c @@ -1945,8 +1945,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 06928e745c7bcb26ec46a17989f30efe3536fd48a74c8a1cd423cc9ff6feccb5 -R e5b296feee8b6ff8861e4cf66944c654 +P 310a3e102d8eedf92ee63ffffb48621abfb1e2736b96bd2a676d63cca0f40598 +R 36f3f4bc3d4f57fe3c73eaa6653f4db1 U drh -Z 8d86ba5638b23b699bb683c424e71903 +Z faba0725b64437f0f9101d235cb21291 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 17903a1e91..ddcd1c1d29 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -310a3e102d8eedf92ee63ffffb48621abfb1e2736b96bd2a676d63cca0f40598 \ No newline at end of file +d50b162b2f2e320af0889b931351f9443580465a933f6657fa98f437b6579277 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index cf6137ab0a..ec227f884a 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -7378,9 +7378,6 @@ case OP_AggFinal: { } sqlite3VdbeChangeEncoding(pMem, encoding); UPDATE_MAX_BLOBSIZE(pMem); - if( sqlite3VdbeMemTooBig(pMem) ){ - goto too_big; - } break; } @@ -7919,9 +7916,6 @@ case OP_VColumn: { REGISTER_TRACE(pOp->p3, pDest); UPDATE_MAX_BLOBSIZE(pDest); - if( sqlite3VdbeMemTooBig(pDest) ){ - goto too_big; - } if( rc ) goto abort_due_to_error; break; } @@ -8214,11 +8208,10 @@ case OP_Function: { /* group */ if( rc ) goto abort_due_to_error; } - /* Copy the result of the function into register P3 */ - if( pOut->flags & (MEM_Str|MEM_Blob) ){ - sqlite3VdbeChangeEncoding(pOut, encoding); - if( sqlite3VdbeMemTooBig(pOut) ) goto too_big; - } + assert( (pOut->flags&MEM_Str)==0 + || pOut->enc==encoding + || db->mallocFailed ); + assert( !sqlite3VdbeMemTooBig(pOut) ); REGISTER_TRACE(pOp->p3, pOut); UPDATE_MAX_BLOBSIZE(pOut); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index af1e94487c..48487694b2 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -378,7 +378,8 @@ static void setResultStrOrError( u8 enc, /* Encoding of z. 0 for BLOBs */ void (*xDel)(void*) /* Destructor function */ ){ - int rc = sqlite3VdbeMemSetStr(pCtx->pOut, z, n, enc, xDel); + Mem *pOut = pCtx->pOut; + int rc = sqlite3VdbeMemSetStr(pOut, z, n, enc, xDel); if( rc ){ if( rc==SQLITE_TOOBIG ){ sqlite3_result_error_toobig(pCtx); @@ -388,6 +389,13 @@ static void setResultStrOrError( assert( rc==SQLITE_NOMEM ); sqlite3_result_error_nomem(pCtx); } + return; + } + if( pOut->enc!=ENC(pOut->db) ){ + sqlite3VdbeChangeEncoding(pOut, ENC(pOut->db)); + if( sqlite3VdbeMemTooBig(pOut) ){ + sqlite3_result_error_toobig(pCtx); + } } } static int invokeValueDestructor( @@ -531,17 +539,22 @@ void sqlite3_result_text16le( } #endif /* SQLITE_OMIT_UTF16 */ void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){ + Mem *pOut = pCtx->pOut; assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - sqlite3VdbeMemCopy(pCtx->pOut, pValue); + sqlite3VdbeMemCopy(pOut, pValue); + sqlite3VdbeChangeEncoding(pOut, ENC(pOut->db)); + if( sqlite3VdbeMemTooBig(pOut) ){ + sqlite3_result_error_toobig(pCtx); + } } void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){ - assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); - sqlite3VdbeMemSetZeroBlob(pCtx->pOut, n); + sqlite3_result_zeroblob64(pCtx, n>0 ? n : 0); } int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){ Mem *pOut = pCtx->pOut; assert( sqlite3_mutex_held(pOut->db->mutex) ); if( n>(u64)pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){ + sqlite3_result_error_toobig(pCtx); return SQLITE_TOOBIG; } #ifndef SQLITE_OMIT_INCRBLOB @@ -557,8 +570,8 @@ void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode; #endif if( pCtx->pOut->flags & MEM_Null ){ - sqlite3VdbeMemSetStr(pCtx->pOut, sqlite3ErrStr(errCode), -1, - SQLITE_UTF8, SQLITE_STATIC); + setResultStrOrError(pCtx, sqlite3ErrStr(errCode), -1, SQLITE_UTF8, + SQLITE_STATIC); } } diff --git a/src/vdbemem.c b/src/vdbemem.c index 524280e0df..7a736fc21b 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -204,7 +204,11 @@ int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){ assert( !sqlite3VdbeMemIsRowSet(pMem) ); assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE || desiredEnc==SQLITE_UTF16BE ); - if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){ + if( pMem->enc==desiredEnc ){ + return SQLITE_OK; + } + if( !(pMem->flags&MEM_Str) ){ + pMem->enc = desiredEnc; return SQLITE_OK; } assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); @@ -1152,12 +1156,7 @@ int sqlite3VdbeMemSetStr( flags= MEM_Str|MEM_Term; }else if( enc==0 ){ flags = MEM_Blob; -#ifdef SQLITE_ENABLE_SESSION - enc = pMem->db ? ENC(pMem->db) : SQLITE_UTF8; -#else - assert( pMem->db!=0 ); - enc = ENC(pMem->db); -#endif + enc = SQLITE_UTF8; }else{ flags = MEM_Str; } @@ -1205,10 +1204,7 @@ int sqlite3VdbeMemSetStr( pMem->enc = enc; #ifndef SQLITE_OMIT_UTF16 - if( enc>SQLITE_UTF8 - && (flags & MEM_Blob)==0 - && sqlite3VdbeMemHandleBom(pMem) - ){ + if( enc>SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){ return SQLITE_NOMEM_BKPT; } #endif From de9484858e8cbf66bf86e27f2e4a31cfde641d35 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 29 Mar 2022 13:16:32 +0000 Subject: [PATCH 034/259] Avoid unnecessary calls to balance() from sqlite3BtreeDelete(). FossilOrigin-Name: d0966d1bdd474e27cb048884d340184f0e81a4fab65eb6b74682b20630caddf8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 17 ++++++++++++++--- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index c7638368d1..e0411f4dc8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\ssqlite3_result_xxxxx()\sroutines\sso\sthat\sthey\sall\scheck\sfor\sand\nperform\sany\snecessary\stext\sencoding\sconversions\sand\scheck\sfor\soversize\nstrings\sand\sBLOBs.\s\sThus\sthose\schecks\scan\sbe\sdone\swhere\sthey\sare\smost\nefficient\sand\savoided\sin\scases\slike\sOP_Function\swhere\sthey\sare\smore\nexpensive. -D 2022-03-29T01:43:09.917 +C Avoid\sunnecessary\scalls\sto\sbalance()\sfrom\ssqlite3BtreeDelete(). +D 2022-03-29T13:16:32.297 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -492,7 +492,7 @@ F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf F src/backup.c a2891172438e385fdbe97c11c9745676bec54f518d4447090af97189fd8e52d7 F src/bitvec.c 7c849aac407230278445cb069bebc5f89bf2ddd87c5ed9459b070a9175707b3d F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c 11a4719bbae5dc1da6d0e1e892302589420c054ad24ca523c10a66a39a123d06 +F src/btree.c 485157b77a8d841c16bff713380d2ce1375c2167f6824202e56f2715bf51c982 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482e F src/build.c a0cc68fe8172c0a31b54576f9c6c0fe6f7c82b1b5e1387afdd6a5a13132bc131 @@ -1945,8 +1945,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 310a3e102d8eedf92ee63ffffb48621abfb1e2736b96bd2a676d63cca0f40598 -R 36f3f4bc3d4f57fe3c73eaa6653f4db1 +P d50b162b2f2e320af0889b931351f9443580465a933f6657fa98f437b6579277 +R 760b6e4d465397c3b2d89a9054754f29 U drh -Z faba0725b64437f0f9101d235cb21291 +Z 254ff3a6f1f20ba9be417b9b988b6588 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index ddcd1c1d29..73ad7122bc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d50b162b2f2e320af0889b931351f9443580465a933f6657fa98f437b6579277 \ No newline at end of file +d0966d1bdd474e27cb048884d340184f0e81a4fab65eb6b74682b20630caddf8 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index d31d30c5ed..d4cd0d0207 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8742,7 +8742,6 @@ static int anotherValidCursor(BtCursor *pCur){ */ static int balance(BtCursor *pCur){ int rc = SQLITE_OK; - const int nMin = pCur->pBt->usableSize * 2 / 3; u8 aBalanceQuickSpace[13]; u8 *pFree = 0; @@ -8754,7 +8753,11 @@ static int balance(BtCursor *pCur){ MemPage *pPage = pCur->pPage; if( NEVER(pPage->nFree<0) && btreeComputeFreeSpace(pPage) ) break; - if( pPage->nOverflow==0 && pPage->nFree<=nMin ){ + if( pPage->nOverflow==0 && pPage->nFree*3<=pCur->pBt->usableSize*2 ){ + /* No rebalance required as long as: + ** (1) There are no overflow cells + ** (2) The amount of free space on the page is less than 2/3rds of + ** the total usable space on the page. */ break; }else if( (iPage = pCur->iPage)==0 ){ if( pPage->nOverflow && (rc = anotherValidCursor(pCur))==SQLITE_OK ){ @@ -9568,7 +9571,15 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ ** been corrected, so be it. Otherwise, after balancing the leaf node, ** walk the cursor up the tree to the internal node and balance it as ** well. */ - rc = balance(pCur); + assert( pCur->pPage->nOverflow==0 ); + assert( pCur->pPage->nFree>=0 ); + if( pCur->pPage->nFree*3<=pCur->pBt->usableSize*2 ){ + /* Optimization: If the free space is less than 2/3rds of the page, + ** then balance() will always be a no-op. No need to invoke it. */ + rc = SQLITE_OK; + }else{ + rc = balance(pCur); + } if( rc==SQLITE_OK && pCur->iPage>iCellDepth ){ releasePageNotNull(pCur->pPage); pCur->iPage--; From 555db979f68ed2efffd080d22c3ae5c3ea7740b2 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 29 Mar 2022 19:19:23 +0000 Subject: [PATCH 035/259] Reverse the order of two tests to stop a harmless initialized value warning from MSAN - reported by OSSFuzz. FossilOrigin-Name: 800b8fdad73b67105e416b4b5c6a5c5ded7d6a43b4eacd6b67d690cab7584b0b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbemem.c | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index e0411f4dc8..39902b1ae8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sunnecessary\scalls\sto\sbalance()\sfrom\ssqlite3BtreeDelete(). -D 2022-03-29T13:16:32.297 +C Reverse\sthe\sorder\sof\stwo\stests\sto\sstop\sa\sharmless\sinitialized\svalue\nwarning\sfrom\sMSAN\s-\sreported\sby\sOSSFuzz. +D 2022-03-29T19:19:23.454 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -630,7 +630,7 @@ F src/vdbeInt.h 8dd91427155a38ec06e9ecbde07e33f21bc02e101625191e7613f883e379a363 F src/vdbeapi.c 299da88f2788ac50b83890bbcfcfbfd09f5863604ad66f6165010cd897d087b5 F src/vdbeaux.c 1de06d17a1af1bf5cc776e60afcc01c49438df90863fc4db0a0516060e7b959a F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd -F src/vdbemem.c d6add1f60a255bd513b2b66a4139e810a8060bfe3d0639c34a0b80923d00ef35 +F src/vdbemem.c 6538bcef73730a060e7240981b6cc6c7efeef45337da38cb491657d0112a8831 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823 F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c @@ -1945,8 +1945,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 d50b162b2f2e320af0889b931351f9443580465a933f6657fa98f437b6579277 -R 760b6e4d465397c3b2d89a9054754f29 +P d0966d1bdd474e27cb048884d340184f0e81a4fab65eb6b74682b20630caddf8 +R 362fb85ce36e696bb625349ebeaa586d U drh -Z 254ff3a6f1f20ba9be417b9b988b6588 +Z 1ae32a58ccc3cd421b61027296aeaf05 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 73ad7122bc..a79633940c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d0966d1bdd474e27cb048884d340184f0e81a4fab65eb6b74682b20630caddf8 \ No newline at end of file +800b8fdad73b67105e416b4b5c6a5c5ded7d6a43b4eacd6b67d690cab7584b0b \ No newline at end of file diff --git a/src/vdbemem.c b/src/vdbemem.c index 7a736fc21b..cb44f3ab26 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -204,13 +204,13 @@ int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){ assert( !sqlite3VdbeMemIsRowSet(pMem) ); assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE || desiredEnc==SQLITE_UTF16BE ); - if( pMem->enc==desiredEnc ){ - return SQLITE_OK; - } if( !(pMem->flags&MEM_Str) ){ pMem->enc = desiredEnc; return SQLITE_OK; } + if( pMem->enc==desiredEnc ){ + return SQLITE_OK; + } assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); #ifdef SQLITE_OMIT_UTF16 return SQLITE_ERROR; From 4cb32b70ed9fad380c99a7af34373d1f952b1f9e Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 29 Mar 2022 20:50:20 +0000 Subject: [PATCH 036/259] Ensure that sqlite3VdbeMemSetStr() always leaves the value in a consistent state even if there is an error. FossilOrigin-Name: c86ab289ec31ce9ae0abaf103a829b8d1e5ed632f493456f1f40607aeb91b41c --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbemem.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 39902b1ae8..ea110e4ef5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Reverse\sthe\sorder\sof\stwo\stests\sto\sstop\sa\sharmless\sinitialized\svalue\nwarning\sfrom\sMSAN\s-\sreported\sby\sOSSFuzz. -D 2022-03-29T19:19:23.454 +C Ensure\sthat\ssqlite3VdbeMemSetStr()\salways\sleaves\sthe\svalue\sin\sa\sconsistent\nstate\seven\sif\sthere\sis\san\serror. +D 2022-03-29T20:50:20.630 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -630,7 +630,7 @@ F src/vdbeInt.h 8dd91427155a38ec06e9ecbde07e33f21bc02e101625191e7613f883e379a363 F src/vdbeapi.c 299da88f2788ac50b83890bbcfcfbfd09f5863604ad66f6165010cd897d087b5 F src/vdbeaux.c 1de06d17a1af1bf5cc776e60afcc01c49438df90863fc4db0a0516060e7b959a F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd -F src/vdbemem.c 6538bcef73730a060e7240981b6cc6c7efeef45337da38cb491657d0112a8831 +F src/vdbemem.c 512499e51eb7cbe1d886031f19ab6f3e05655a0b25655991af01b61a631a78f7 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823 F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c @@ -1945,8 +1945,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 d0966d1bdd474e27cb048884d340184f0e81a4fab65eb6b74682b20630caddf8 -R 362fb85ce36e696bb625349ebeaa586d +P 800b8fdad73b67105e416b4b5c6a5c5ded7d6a43b4eacd6b67d690cab7584b0b +R 2b3031ad1bef73c7bb072d8d8c375b8b U drh -Z 1ae32a58ccc3cd421b61027296aeaf05 +Z 768c379b4a042ffc9bb001e63cb4eaa8 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a79633940c..07c7c14b1b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -800b8fdad73b67105e416b4b5c6a5c5ded7d6a43b4eacd6b67d690cab7584b0b \ No newline at end of file +c86ab289ec31ce9ae0abaf103a829b8d1e5ed632f493456f1f40607aeb91b41c \ No newline at end of file diff --git a/src/vdbemem.c b/src/vdbemem.c index cb44f3ab26..82d79a580a 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1168,6 +1168,7 @@ int sqlite3VdbeMemSetStr( xDel((void*)z); } } + sqlite3VdbeMemSetNull(pMem); return sqlite3ErrorToParser(pMem->db, SQLITE_TOOBIG); } From c55b62d4cba51b583cbb6fe5f65e415a356f36d6 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 29 Mar 2022 22:57:00 +0000 Subject: [PATCH 037/259] In setResultStrOrError(), if the input string pointer is NULL and hence the value gets set to an SQL NULL, then the Mem.enc field is uninitialized. So do not read it. This is a harmless OSSFuzz/ASAN found problem. FossilOrigin-Name: 47d0b1c4cfc3d2d8f57a02079276bb70a205ffd0f18007dd39c92f813d4c87f5 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeapi.c | 8 +++----- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index ea110e4ef5..12bcce5e63 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\ssqlite3VdbeMemSetStr()\salways\sleaves\sthe\svalue\sin\sa\sconsistent\nstate\seven\sif\sthere\sis\san\serror. -D 2022-03-29T20:50:20.630 +C In\ssetResultStrOrError(),\sif\sthe\sinput\sstring\spointer\sis\sNULL\sand\shence\sthe\nvalue\sgets\sset\sto\san\sSQL\sNULL,\sthen\sthe\sMem.enc\sfield\sis\suninitialized.\s\sSo\ndo\snot\sread\sit.\s\sThis\sis\sa\sharmless\sOSSFuzz/ASAN\sfound\sproblem. +D 2022-03-29T22:57:00.956 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -627,7 +627,7 @@ F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 F src/vdbe.c af4a5e9d64dbcc484be1fa4609b655577f81ee2cd40b61e96bece6d43718ae91 F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e F src/vdbeInt.h 8dd91427155a38ec06e9ecbde07e33f21bc02e101625191e7613f883e379a363 -F src/vdbeapi.c 299da88f2788ac50b83890bbcfcfbfd09f5863604ad66f6165010cd897d087b5 +F src/vdbeapi.c 2571824e8eb961e528428ae31e2a993acc586330a32e26d03d918f0bdbdfc5f7 F src/vdbeaux.c 1de06d17a1af1bf5cc776e60afcc01c49438df90863fc4db0a0516060e7b959a F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 512499e51eb7cbe1d886031f19ab6f3e05655a0b25655991af01b61a631a78f7 @@ -1945,8 +1945,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 800b8fdad73b67105e416b4b5c6a5c5ded7d6a43b4eacd6b67d690cab7584b0b -R 2b3031ad1bef73c7bb072d8d8c375b8b +P c86ab289ec31ce9ae0abaf103a829b8d1e5ed632f493456f1f40607aeb91b41c +R 52ea0d5515c388b9056669df44e0e84b U drh -Z 768c379b4a042ffc9bb001e63cb4eaa8 +Z b8d3abe3b2948e70e31147c55397470d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 07c7c14b1b..e8b84357bb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c86ab289ec31ce9ae0abaf103a829b8d1e5ed632f493456f1f40607aeb91b41c \ No newline at end of file +47d0b1c4cfc3d2d8f57a02079276bb70a205ffd0f18007dd39c92f813d4c87f5 \ No newline at end of file diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 48487694b2..f47ece2396 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -391,11 +391,9 @@ static void setResultStrOrError( } return; } - if( pOut->enc!=ENC(pOut->db) ){ - sqlite3VdbeChangeEncoding(pOut, ENC(pOut->db)); - if( sqlite3VdbeMemTooBig(pOut) ){ - sqlite3_result_error_toobig(pCtx); - } + sqlite3VdbeChangeEncoding(pOut, ENC(pOut->db)); + if( sqlite3VdbeMemTooBig(pOut) ){ + sqlite3_result_error_toobig(pCtx); } } static int invokeValueDestructor( From 66f58bf38d581e9738b7a6b4a5f9b30aafeecdbe Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 30 Mar 2022 17:36:40 +0000 Subject: [PATCH 038/259] Small size reduction and performance increase in sqlite3FinishCoding(). FossilOrigin-Name: 9248ce50f57fb9c4ba67949fdf9c9567c3e626cd9dd1b41b71c602d29c77c43e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/build.c | 6 ++++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 12bcce5e63..f042fd080d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\ssetResultStrOrError(),\sif\sthe\sinput\sstring\spointer\sis\sNULL\sand\shence\sthe\nvalue\sgets\sset\sto\san\sSQL\sNULL,\sthen\sthe\sMem.enc\sfield\sis\suninitialized.\s\sSo\ndo\snot\sread\sit.\s\sThis\sis\sa\sharmless\sOSSFuzz/ASAN\sfound\sproblem. -D 2022-03-29T22:57:00.956 +C Small\ssize\sreduction\sand\sperformance\sincrease\sin\ssqlite3FinishCoding(). +D 2022-03-30T17:36:40.718 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -495,7 +495,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 485157b77a8d841c16bff713380d2ce1375c2167f6824202e56f2715bf51c982 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482e -F src/build.c a0cc68fe8172c0a31b54576f9c6c0fe6f7c82b1b5e1387afdd6a5a13132bc131 +F src/build.c 4a265d49342cefc95ae739982a6197eae04a9258151f8e0bbe3ff8ab56aab801 F src/callback.c 4c19af69835787bfe790ac560f3071a824eb629f34e41f97b52ce5235c77de1c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 2cce39df1a13e05b7633e6d21b651f21492471f991dd7b323a4ee4e7b7f0b7f1 @@ -1945,8 +1945,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 c86ab289ec31ce9ae0abaf103a829b8d1e5ed632f493456f1f40607aeb91b41c -R 52ea0d5515c388b9056669df44e0e84b +P 47d0b1c4cfc3d2d8f57a02079276bb70a205ffd0f18007dd39c92f813d4c87f5 +R bfff41b69f3c58b7003f472b201fd884 U drh -Z b8d3abe3b2948e70e31147c55397470d +Z 561c127ed7f0a8dbf7f5fadac7f3d58b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e8b84357bb..4929d91704 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -47d0b1c4cfc3d2d8f57a02079276bb70a205ffd0f18007dd39c92f813d4c87f5 \ No newline at end of file +9248ce50f57fb9c4ba67949fdf9c9567c3e626cd9dd1b41b71c602d29c77c43e \ No newline at end of file diff --git a/src/build.c b/src/build.c index f7614af625..35f1ea3639 100644 --- a/src/build.c +++ b/src/build.c @@ -214,7 +214,9 @@ void sqlite3FinishCoding(Parse *pParse){ int iDb, i; assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init ); sqlite3VdbeJumpHere(v, 0); - for(iDb=0; iDbnDb; iDb++){ + assert( db->nDb>0 ); + iDb = 0; + do{ Schema *pSchema; if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue; sqlite3VdbeUsesBtree(v, iDb); @@ -229,7 +231,7 @@ void sqlite3FinishCoding(Parse *pParse){ if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1); VdbeComment((v, "usesStmtJournal=%d", pParse->mayAbort && pParse->isMultiWrite)); - } + }while( ++iDbnDb ); #ifndef SQLITE_OMIT_VIRTUALTABLE for(i=0; inVtabLock; i++){ char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]); From 7e62146b13efe237c2b2d08c9841ecfb9eef7b77 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 30 Mar 2022 17:56:27 +0000 Subject: [PATCH 039/259] Faster and slightly smaller implementation of sqlite3Step(). FossilOrigin-Name: c6901a8c78838228f8135c9346b214e638b72086fd85367b9ff482273e62ece6 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeapi.c | 7 ++++++- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index f042fd080d..ca0e84f92f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\ssize\sreduction\sand\sperformance\sincrease\sin\ssqlite3FinishCoding(). -D 2022-03-30T17:36:40.718 +C Faster\sand\sslightly\ssmaller\simplementation\sof\ssqlite3Step(). +D 2022-03-30T17:56:27.350 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -627,7 +627,7 @@ F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 F src/vdbe.c af4a5e9d64dbcc484be1fa4609b655577f81ee2cd40b61e96bece6d43718ae91 F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e F src/vdbeInt.h 8dd91427155a38ec06e9ecbde07e33f21bc02e101625191e7613f883e379a363 -F src/vdbeapi.c 2571824e8eb961e528428ae31e2a993acc586330a32e26d03d918f0bdbdfc5f7 +F src/vdbeapi.c d41dedcf05f4b0ee3f0a2ce4f8316631fef5391c2d5705b4a0b48156b8061c0b F src/vdbeaux.c 1de06d17a1af1bf5cc776e60afcc01c49438df90863fc4db0a0516060e7b959a F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 512499e51eb7cbe1d886031f19ab6f3e05655a0b25655991af01b61a631a78f7 @@ -1945,8 +1945,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 47d0b1c4cfc3d2d8f57a02079276bb70a205ffd0f18007dd39c92f813d4c87f5 -R bfff41b69f3c58b7003f472b201fd884 +P 9248ce50f57fb9c4ba67949fdf9c9567c3e626cd9dd1b41b71c602d29c77c43e +R d211f80e25abf1520d1ba8916168f07f U drh -Z 561c127ed7f0a8dbf7f5fadac7f3d58b +Z 7ecb30a0193ebe95381527545dca992e # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 4929d91704..535bfdf1f0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9248ce50f57fb9c4ba67949fdf9c9567c3e626cd9dd1b41b71c602d29c77c43e \ No newline at end of file +c6901a8c78838228f8135c9346b214e638b72086fd85367b9ff482273e62ece6 \ No newline at end of file diff --git a/src/vdbeapi.c b/src/vdbeapi.c index f47ece2396..7567b89945 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -731,7 +731,12 @@ static int sqlite3Step(Vdbe *p){ db->nVdbeExec--; } - if( rc!=SQLITE_ROW ){ + if( rc==SQLITE_ROW ){ + assert( p->rc==SQLITE_OK ); + assert( db->mallocFailed==0 ); + db->errCode = SQLITE_ROW; + return SQLITE_ROW; + }else{ #ifndef SQLITE_OMIT_TRACE /* If the statement completed successfully, invoke the profile callback */ checkProfileCallback(db, p); From 89cf958c00b79d9f4590e024618afd47b241ea43 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 31 Mar 2022 11:12:56 +0000 Subject: [PATCH 040/259] Refinement to [3f9887d4a58cbfdb]: The SQLITE_CONSTRAINT error should only be returned if the prepared statement came from sqlite3_prepare_v2(). The legacy sqlite3_prepare() is documented to return only SQLITE_ERROR. FossilOrigin-Name: f2d9262e4427ab37ba26c004fc7a4790c86c1856d695a6b4ec3e72732ea54c09 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index ca0e84f92f..8046b9e446 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Faster\sand\sslightly\ssmaller\simplementation\sof\ssqlite3Step(). -D 2022-03-30T17:56:27.350 +C Refinement\sto\s[3f9887d4a58cbfdb]:\s\sThe\sSQLITE_CONSTRAINT\serror\sshould\sonly\nbe\sreturned\sif\sthe\sprepared\sstatement\scame\sfrom\ssqlite3_prepare_v2().\s\sThe\nlegacy\ssqlite3_prepare()\sis\sdocumented\sto\sreturn\sonly\sSQLITE_ERROR. +D 2022-03-31T11:12:56.506 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -628,7 +628,7 @@ F src/vdbe.c af4a5e9d64dbcc484be1fa4609b655577f81ee2cd40b61e96bece6d43718ae91 F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e F src/vdbeInt.h 8dd91427155a38ec06e9ecbde07e33f21bc02e101625191e7613f883e379a363 F src/vdbeapi.c d41dedcf05f4b0ee3f0a2ce4f8316631fef5391c2d5705b4a0b48156b8061c0b -F src/vdbeaux.c 1de06d17a1af1bf5cc776e60afcc01c49438df90863fc4db0a0516060e7b959a +F src/vdbeaux.c c3818106ffdb09e8c8cce4edad4fdb1e741bc56c94edca03a8cfd21981087831 F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 512499e51eb7cbe1d886031f19ab6f3e05655a0b25655991af01b61a631a78f7 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 @@ -1945,8 +1945,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 9248ce50f57fb9c4ba67949fdf9c9567c3e626cd9dd1b41b71c602d29c77c43e -R d211f80e25abf1520d1ba8916168f07f +P c6901a8c78838228f8135c9346b214e638b72086fd85367b9ff482273e62ece6 +R 4dff1665eca1a56c0e1c4858159903e1 U drh -Z 7ecb30a0193ebe95381527545dca992e +Z ac3ad774d954660a814205deffa61713 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 535bfdf1f0..d68f633351 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c6901a8c78838228f8135c9346b214e638b72086fd85367b9ff482273e62ece6 \ No newline at end of file +f2d9262e4427ab37ba26c004fc7a4790c86c1856d695a6b4ec3e72732ea54c09 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 56b433ef62..21b2578188 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2999,6 +2999,7 @@ int sqlite3VdbeCheckFk(Vdbe *p, int deferred){ p->rc = SQLITE_CONSTRAINT_FOREIGNKEY; p->errorAction = OE_Abort; sqlite3VdbeError(p, "FOREIGN KEY constraint failed"); + if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)==0 ) return SQLITE_ERROR; return SQLITE_CONSTRAINT_FOREIGNKEY; } return SQLITE_OK; From c4c0ff86643edcd3f87d14f41e92f967af8a84c8 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 31 Mar 2022 16:09:13 +0000 Subject: [PATCH 041/259] Fix harmless compiler warnings. FossilOrigin-Name: b916087aacba53530d2bd19eef2a4fd7a253bf7fa87b49e0df17f7987d7164ae --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/btree.c | 4 ++-- src/vdbeaux.c | 2 ++ 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 8046b9e446..a443d0fbce 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Refinement\sto\s[3f9887d4a58cbfdb]:\s\sThe\sSQLITE_CONSTRAINT\serror\sshould\sonly\nbe\sreturned\sif\sthe\sprepared\sstatement\scame\sfrom\ssqlite3_prepare_v2().\s\sThe\nlegacy\ssqlite3_prepare()\sis\sdocumented\sto\sreturn\sonly\sSQLITE_ERROR. -D 2022-03-31T11:12:56.506 +C Fix\sharmless\scompiler\swarnings. +D 2022-03-31T16:09:13.558 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -492,7 +492,7 @@ F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf F src/backup.c a2891172438e385fdbe97c11c9745676bec54f518d4447090af97189fd8e52d7 F src/bitvec.c 7c849aac407230278445cb069bebc5f89bf2ddd87c5ed9459b070a9175707b3d F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c 485157b77a8d841c16bff713380d2ce1375c2167f6824202e56f2715bf51c982 +F src/btree.c d705859e23fbd7b3c6cd5874f973b5c4fa083eab861398aac95bea7de9a7ed07 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482e F src/build.c 4a265d49342cefc95ae739982a6197eae04a9258151f8e0bbe3ff8ab56aab801 @@ -628,7 +628,7 @@ F src/vdbe.c af4a5e9d64dbcc484be1fa4609b655577f81ee2cd40b61e96bece6d43718ae91 F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e F src/vdbeInt.h 8dd91427155a38ec06e9ecbde07e33f21bc02e101625191e7613f883e379a363 F src/vdbeapi.c d41dedcf05f4b0ee3f0a2ce4f8316631fef5391c2d5705b4a0b48156b8061c0b -F src/vdbeaux.c c3818106ffdb09e8c8cce4edad4fdb1e741bc56c94edca03a8cfd21981087831 +F src/vdbeaux.c 45a94316496a200a1d3a29b014fbbc7fc44860c026f768b2d0fcc108e92536d4 F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 512499e51eb7cbe1d886031f19ab6f3e05655a0b25655991af01b61a631a78f7 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 @@ -1945,8 +1945,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 c6901a8c78838228f8135c9346b214e638b72086fd85367b9ff482273e62ece6 -R 4dff1665eca1a56c0e1c4858159903e1 +P f2d9262e4427ab37ba26c004fc7a4790c86c1856d695a6b4ec3e72732ea54c09 +R d2182f02ef1334fdc5f699b0ef49ddd5 U drh -Z ac3ad774d954660a814205deffa61713 +Z 8f84c3af05b1ca72966bc5e0edb8cacb # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d68f633351..5456276fa0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f2d9262e4427ab37ba26c004fc7a4790c86c1856d695a6b4ec3e72732ea54c09 \ No newline at end of file +b916087aacba53530d2bd19eef2a4fd7a253bf7fa87b49e0df17f7987d7164ae \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index d4cd0d0207..eb3dbb0a3c 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8753,7 +8753,7 @@ static int balance(BtCursor *pCur){ MemPage *pPage = pCur->pPage; if( NEVER(pPage->nFree<0) && btreeComputeFreeSpace(pPage) ) break; - if( pPage->nOverflow==0 && pPage->nFree*3<=pCur->pBt->usableSize*2 ){ + if( pPage->nOverflow==0 && pPage->nFree*3<=(int)pCur->pBt->usableSize*2 ){ /* No rebalance required as long as: ** (1) There are no overflow cells ** (2) The amount of free space on the page is less than 2/3rds of @@ -9573,7 +9573,7 @@ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ ** well. */ assert( pCur->pPage->nOverflow==0 ); assert( pCur->pPage->nFree>=0 ); - if( pCur->pPage->nFree*3<=pCur->pBt->usableSize*2 ){ + if( pCur->pPage->nFree*3<=(int)pCur->pBt->usableSize*2 ){ /* Optimization: If the free space is less than 2/3rds of the page, ** then balance() will always be a no-op. No need to invoke it. */ rc = SQLITE_OK; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 21b2578188..c5024efb13 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -699,6 +699,8 @@ int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){ int hasInitCoroutine = 0; Op *pOp; VdbeOpIter sIter; + + if( v==0 ) return 0; memset(&sIter, 0, sizeof(sIter)); sIter.v = v; From 66181ce2b8504d5a11e4222e1c87beccb2c1799b Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 31 Mar 2022 20:04:49 +0000 Subject: [PATCH 042/259] Rename Vdbe.iVdbeMagic to eVdbeState. Remove unnecessary states. This is a preliminary step toward splitting RUN_STATE out into several other states. FossilOrigin-Name: ff91191d232305d44ae6c0fbca2542a749422dc716fa1fd5d54f58c7d6052c14 --- manifest | 21 ++++++++++++--------- manifest.uuid | 2 +- src/vdbe.c | 2 +- src/vdbeInt.h | 13 ++++++------- src/vdbeapi.c | 6 +++--- src/vdbeaux.c | 38 +++++++++++++++++--------------------- 6 files changed, 40 insertions(+), 42 deletions(-) diff --git a/manifest b/manifest index a443d0fbce..d3dfb5782a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings. -D 2022-03-31T16:09:13.558 +C Rename\sVdbe.iVdbeMagic\sto\seVdbeState.\s\sRemove\sunnecessary\sstates.\s\sThis\sis\na\spreliminary\sstep\stoward\ssplitting\sRUN_STATE\sout\sinto\sseveral\sother\sstates. +D 2022-03-31T20:04:49.855 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -624,11 +624,11 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c af4a5e9d64dbcc484be1fa4609b655577f81ee2cd40b61e96bece6d43718ae91 +F src/vdbe.c c7982c468cf39e3ad690da427aa72d43744debc32cea943849b688c17dfe2bff F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e -F src/vdbeInt.h 8dd91427155a38ec06e9ecbde07e33f21bc02e101625191e7613f883e379a363 -F src/vdbeapi.c d41dedcf05f4b0ee3f0a2ce4f8316631fef5391c2d5705b4a0b48156b8061c0b -F src/vdbeaux.c 45a94316496a200a1d3a29b014fbbc7fc44860c026f768b2d0fcc108e92536d4 +F src/vdbeInt.h fe6987d90048eee26bf0e9a2498ff3f2c5d4149b0d6e78b9fcc6bce13274faae +F src/vdbeapi.c 0bfeb0ebfb2b064b97bcb389a92f9f819bacc2ae70c819c6976157616f48c31c +F src/vdbeaux.c 4260b1016c9e47a20c75f7d311c4bf1fe5b0efa9dafa2f72f7959fcb0517792b F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 512499e51eb7cbe1d886031f19ab6f3e05655a0b25655991af01b61a631a78f7 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 @@ -1945,8 +1945,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f2d9262e4427ab37ba26c004fc7a4790c86c1856d695a6b4ec3e72732ea54c09 -R d2182f02ef1334fdc5f699b0ef49ddd5 +P b916087aacba53530d2bd19eef2a4fd7a253bf7fa87b49e0df17f7987d7164ae +R 3c60b6ccbc6ab91e39cbf56c4038bfa8 +T *branch * vdbe-state-refactor +T *sym-vdbe-state-refactor * +T -sym-trunk * U drh -Z 8f84c3af05b1ca72966bc5e0edb8cacb +Z 839815ce9594c9953a4b8872bf63aa11 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5456276fa0..8b300102c5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b916087aacba53530d2bd19eef2a4fd7a253bf7fa87b49e0df17f7987d7164ae \ No newline at end of file +ff91191d232305d44ae6c0fbca2542a749422dc716fa1fd5d54f58c7d6052c14 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index ec227f884a..44a60e2bbf 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -740,7 +740,7 @@ int sqlite3VdbeExec( #endif /*** INSERT STACK UNION HERE ***/ - assert( p->iVdbeMagic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */ + assert( p->eVdbeState==VDBE_RUN_STATE ); /* sqlite3_step() verifies this */ sqlite3VdbeEnter(p); #ifndef SQLITE_OMIT_PROGRESS_CALLBACK if( db->xProgress ){ diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 45720b6a55..aba378f397 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -417,7 +417,6 @@ struct Vdbe { Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */ Parse *pParse; /* Parsing context used to create this Vdbe */ ynVar nVar; /* Number of entries in aVar[] */ - u32 iVdbeMagic; /* Magic number defining state of the SQL statement */ int nMem; /* Number of memory locations currently allocated */ int nCursor; /* Number of slots in apCsr[] */ u32 cacheCtr; /* VdbeCursor row cache generation counter */ @@ -456,6 +455,7 @@ struct Vdbe { u8 minWriteFileFormat; /* Minimum file format for writable database files */ u8 prepFlags; /* SQLITE_PREPARE_* flags */ u8 doingRerun; /* True if rerunning after an auto-reprepare */ + u8 eVdbeState; /* On of the VDBE_*_STATE values */ bft expired:2; /* 1: recompile VM immediately 2: when convenient */ bft explain:2; /* True if EXPLAIN present on SQL command */ bft changeCntOn:1; /* True to update the change-counter */ @@ -486,13 +486,12 @@ struct Vdbe { }; /* -** The following are allowed values for Vdbe.magic +** The following are allowed values for Vdbe.eVdbeState */ -#define VDBE_MAGIC_INIT 0x16bceaa5 /* Building a VDBE program */ -#define VDBE_MAGIC_RUN 0x2df20da3 /* VDBE is ready to execute */ -#define VDBE_MAGIC_HALT 0x319c2973 /* VDBE has completed execution */ -#define VDBE_MAGIC_RESET 0x48fa9f76 /* Reset and ready to run again */ -#define VDBE_MAGIC_DEAD 0x5606c3c8 /* The VDBE has been deallocated */ +#define VDBE_INIT_STATE 0 /* Prepared statement under construction */ +#define VDBE_READY_STATE 1 /* Ready to run but not yet started */ +#define VDBE_RUN_STATE 2 /* Run in progress */ +#define VDBE_HALT_STATE 3 /* Finished. Need reset() or finalize() */ /* ** Structure used to store the context required by the diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 7567b89945..49d9a1d57c 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -643,7 +643,7 @@ static int sqlite3Step(Vdbe *p){ int rc; assert(p); - if( p->iVdbeMagic!=VDBE_MAGIC_RUN ){ + if( p->eVdbeState!=VDBE_RUN_STATE ){ /* We used to require that sqlite3_reset() be called before retrying ** sqlite3_step() after any error or after SQLITE_DONE. But beginning ** with version 3.7.0, we changed this so that sqlite3_reset() would @@ -1428,7 +1428,7 @@ static int vdbeUnbind(Vdbe *p, int i){ return SQLITE_MISUSE_BKPT; } sqlite3_mutex_enter(p->db->mutex); - if( p->iVdbeMagic!=VDBE_MAGIC_RUN || p->pc>=0 ){ + if( p->eVdbeState!=VDBE_RUN_STATE || p->pc>=0 ){ sqlite3Error(p->db, SQLITE_MISUSE); sqlite3_mutex_leave(p->db->mutex); sqlite3_log(SQLITE_MISUSE, @@ -1781,7 +1781,7 @@ int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt){ */ int sqlite3_stmt_busy(sqlite3_stmt *pStmt){ Vdbe *v = (Vdbe*)pStmt; - return v!=0 && v->iVdbeMagic==VDBE_MAGIC_RUN && v->pc>=0; + return v!=0 && v->eVdbeState==VDBE_RUN_STATE && v->pc>=0; } /* diff --git a/src/vdbeaux.c b/src/vdbeaux.c index c5024efb13..1ce4c14ace 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -35,7 +35,7 @@ Vdbe *sqlite3VdbeCreate(Parse *pParse){ p->pNext = db->pVdbe; p->pPrev = 0; db->pVdbe = p; - p->iVdbeMagic = VDBE_MAGIC_INIT; + assert( p->eVdbeState==VDBE_INIT_STATE ); p->pParse = pParse; pParse->pVdbe = p; assert( pParse->aLabel==0 ); @@ -236,7 +236,7 @@ int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ VdbeOp *pOp; i = p->nOp; - assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); + assert( p->eVdbeState==VDBE_INIT_STATE ); assert( op>=0 && op<0xff ); if( p->nOpAlloc<=i ){ return growOp3(p, op, p1, p2, p3); @@ -568,7 +568,7 @@ static SQLITE_NOINLINE void resizeResolveLabel(Parse *p, Vdbe *v, int j){ void sqlite3VdbeResolveLabel(Vdbe *v, int x){ Parse *p = v->pParse; int j = ADDR(x); - assert( v->iVdbeMagic==VDBE_MAGIC_INIT ); + assert( v->eVdbeState==VDBE_INIT_STATE ); assert( j<-p->nLabel ); assert( j>=0 ); #ifdef SQLITE_DEBUG @@ -878,7 +878,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ ** Return the address of the next instruction to be inserted. */ int sqlite3VdbeCurrentAddr(Vdbe *p){ - assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); + assert( p->eVdbeState==VDBE_INIT_STATE ); return p->nOp; } @@ -963,7 +963,7 @@ VdbeOp *sqlite3VdbeAddOpList( int i; VdbeOp *pOut, *pFirst; assert( nOp>0 ); - assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); + assert( p->eVdbeState==VDBE_INIT_STATE ); if( p->nOp + nOp > p->nOpAlloc && growOpArray(p, nOp) ){ return 0; } @@ -1289,7 +1289,7 @@ void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){ sqlite3 *db; assert( p!=0 ); db = p->db; - assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); + assert( p->eVdbeState==VDBE_INIT_STATE ); assert( p->aOp!=0 || db->mallocFailed ); if( db->mallocFailed ){ if( n!=P4_VTAB ) freeP4(db, n, (void*)*(char**)&zP4); @@ -1417,7 +1417,7 @@ VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){ /* C89 specifies that the constant "dummy" will be initialized to all ** zeros, which is correct. MSVC generates a warning, nevertheless. */ static VdbeOp dummy; /* Ignore the MSVC warning about no initializer */ - assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); + assert( p->eVdbeState==VDBE_INIT_STATE ); if( addr<0 ){ addr = p->nOp - 1; } @@ -2119,7 +2119,7 @@ int sqlite3VdbeList( Op *pOp; /* Current opcode */ assert( p->explain ); - assert( p->iVdbeMagic==VDBE_MAGIC_RUN ); + assert( p->eVdbeState==VDBE_RUN_STATE ); assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || p->rc==SQLITE_NOMEM ); /* Even though this opcode does not use dynamic strings for @@ -2299,14 +2299,13 @@ void sqlite3VdbeRewind(Vdbe *p){ int i; #endif assert( p!=0 ); - assert( p->iVdbeMagic==VDBE_MAGIC_INIT || p->iVdbeMagic==VDBE_MAGIC_RESET ); + assert( p->eVdbeState==VDBE_INIT_STATE || p->eVdbeState==VDBE_HALT_STATE ); /* There should be at least one opcode. */ assert( p->nOp>0 ); - /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. */ - p->iVdbeMagic = VDBE_MAGIC_RUN; + p->eVdbeState = VDBE_RUN_STATE; #ifdef SQLITE_DEBUG for(i=0; inMem; i++){ @@ -2362,7 +2361,7 @@ void sqlite3VdbeMakeReady( assert( p!=0 ); assert( p->nOp>0 ); assert( pParse!=0 ); - assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); + assert( p->eVdbeState==VDBE_INIT_STATE ); assert( pParse==p->pParse ); p->pVList = pParse->pVList; pParse->pVList = 0; @@ -3041,7 +3040,7 @@ int sqlite3VdbeHalt(Vdbe *p){ ** one, or the complete transaction if there is no statement transaction. */ - if( p->iVdbeMagic!=VDBE_MAGIC_RUN ){ + if( p->eVdbeState!=VDBE_RUN_STATE ){ return SQLITE_OK; } if( db->mallocFailed ){ @@ -3208,7 +3207,7 @@ int sqlite3VdbeHalt(Vdbe *p){ assert( db->nVdbeRead>=db->nVdbeWrite ); assert( db->nVdbeWrite>=0 ); } - p->iVdbeMagic = VDBE_MAGIC_HALT; + p->eVdbeState = VDBE_HALT_STATE; checkActiveVdbeCnt(db); if( db->mallocFailed ){ p->rc = SQLITE_NOMEM_BKPT; @@ -3290,8 +3289,8 @@ static void vdbeInvokeSqllog(Vdbe *v){ ** again. ** ** To look at it another way, this routine resets the state of the -** virtual machine from VDBE_MAGIC_RUN or VDBE_MAGIC_HALT back to -** VDBE_MAGIC_INIT. +** virtual machine from VDBE_RUN_STATE or VDBE_HALT_STATE back to +** VDBE_READY_STATE. */ int sqlite3VdbeReset(Vdbe *p){ #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) @@ -3382,7 +3381,6 @@ int sqlite3VdbeReset(Vdbe *p){ } } #endif - p->iVdbeMagic = VDBE_MAGIC_RESET; return p->rc & db->errMask; } @@ -3392,7 +3390,7 @@ int sqlite3VdbeReset(Vdbe *p){ */ int sqlite3VdbeFinalize(Vdbe *p){ int rc = SQLITE_OK; - if( p->iVdbeMagic==VDBE_MAGIC_RUN || p->iVdbeMagic==VDBE_MAGIC_HALT ){ + if( p->eVdbeState==VDBE_RUN_STATE || p->eVdbeState==VDBE_HALT_STATE ){ rc = sqlite3VdbeReset(p); assert( (rc & p->db->errMask)==rc ); } @@ -3456,7 +3454,7 @@ void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ vdbeFreeOpArray(db, pSub->aOp, pSub->nOp); sqlite3DbFree(db, pSub); } - if( p->iVdbeMagic!=VDBE_MAGIC_INIT ){ + if( p->eVdbeState!=VDBE_INIT_STATE ){ releaseMemArray(p->aVar, p->nVar); if( p->pVList ) sqlite3DbFreeNN(db, p->pVList); if( p->pFree ) sqlite3DbFreeNN(db, p->pFree); @@ -3503,8 +3501,6 @@ void sqlite3VdbeDelete(Vdbe *p){ if( p->pNext ){ p->pNext->pPrev = p->pPrev; } - p->iVdbeMagic = VDBE_MAGIC_DEAD; - p->db = 0; sqlite3DbFreeNN(db, p); } From 99a218282c42057ada2c187dc28f47442ce78751 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 31 Mar 2022 21:15:09 +0000 Subject: [PATCH 043/259] Split out the RUN state into separate READY and RUN states. FossilOrigin-Name: d698826b08b88e227eb83f84b3cdb19f17306b532eccfa162090abccdf3c63d8 --- manifest | 17 +++---- manifest.uuid | 2 +- src/vdbeapi.c | 137 +++++++++++++++++++++++++++----------------------- src/vdbeaux.c | 31 ++++++------ 4 files changed, 97 insertions(+), 90 deletions(-) diff --git a/manifest b/manifest index d3dfb5782a..ac0d69c54e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rename\sVdbe.iVdbeMagic\sto\seVdbeState.\s\sRemove\sunnecessary\sstates.\s\sThis\sis\na\spreliminary\sstep\stoward\ssplitting\sRUN_STATE\sout\sinto\sseveral\sother\sstates. -D 2022-03-31T20:04:49.855 +C Split\sout\sthe\sRUN\sstate\sinto\sseparate\sREADY\sand\sRUN\sstates. +D 2022-03-31T21:15:09.341 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -627,8 +627,8 @@ F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 F src/vdbe.c c7982c468cf39e3ad690da427aa72d43744debc32cea943849b688c17dfe2bff F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e F src/vdbeInt.h fe6987d90048eee26bf0e9a2498ff3f2c5d4149b0d6e78b9fcc6bce13274faae -F src/vdbeapi.c 0bfeb0ebfb2b064b97bcb389a92f9f819bacc2ae70c819c6976157616f48c31c -F src/vdbeaux.c 4260b1016c9e47a20c75f7d311c4bf1fe5b0efa9dafa2f72f7959fcb0517792b +F src/vdbeapi.c bdc977e721fbadb9b075f8f4eb5f4ac5289eb2bffc0786ffae303e915580484a +F src/vdbeaux.c 6c76956b969cdb65b52fe120e1e5424868ec4473f454dd81039e5b07a2b44ee4 F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 512499e51eb7cbe1d886031f19ab6f3e05655a0b25655991af01b61a631a78f7 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 @@ -1945,11 +1945,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 b916087aacba53530d2bd19eef2a4fd7a253bf7fa87b49e0df17f7987d7164ae -R 3c60b6ccbc6ab91e39cbf56c4038bfa8 -T *branch * vdbe-state-refactor -T *sym-vdbe-state-refactor * -T -sym-trunk * +P ff91191d232305d44ae6c0fbca2542a749422dc716fa1fd5d54f58c7d6052c14 +R ec623ff49fd7a3945e7e6cf4e06ba68c U drh -Z 839815ce9594c9953a4b8872bf63aa11 +Z 2cbaf76e3cc43bc83d2f6fc2647ea3ec # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8b300102c5..06fb3a929c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ff91191d232305d44ae6c0fbca2542a749422dc716fa1fd5d54f58c7d6052c14 \ No newline at end of file +d698826b08b88e227eb83f84b3cdb19f17306b532eccfa162090abccdf3c63d8 \ No newline at end of file diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 49d9a1d57c..4c8078be3f 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -642,35 +642,6 @@ static int sqlite3Step(Vdbe *p){ sqlite3 *db; int rc; - assert(p); - if( p->eVdbeState!=VDBE_RUN_STATE ){ - /* We used to require that sqlite3_reset() be called before retrying - ** sqlite3_step() after any error or after SQLITE_DONE. But beginning - ** with version 3.7.0, we changed this so that sqlite3_reset() would - ** be called automatically instead of throwing the SQLITE_MISUSE error. - ** This "automatic-reset" change is not technically an incompatibility, - ** since any application that receives an SQLITE_MISUSE is broken by - ** definition. - ** - ** Nevertheless, some published applications that were originally written - ** for version 3.6.23 or earlier do in fact depend on SQLITE_MISUSE - ** returns, and those were broken by the automatic-reset change. As a - ** a work-around, the SQLITE_OMIT_AUTORESET compile-time restores the - ** legacy behavior of returning SQLITE_MISUSE for cases where the - ** previous sqlite3_step() returned something other than a SQLITE_LOCKED - ** or SQLITE_BUSY error. - */ -#ifdef SQLITE_OMIT_AUTORESET - if( (rc = p->rc&0xff)==SQLITE_BUSY || rc==SQLITE_LOCKED ){ - sqlite3_reset((sqlite3_stmt*)p); - }else{ - return SQLITE_MISUSE_BKPT; - } -#else - sqlite3_reset((sqlite3_stmt*)p); -#endif - } - /* Check that malloc() has not failed. If it has, return early. */ db = p->db; if( db->mallocFailed ){ @@ -678,45 +649,83 @@ static int sqlite3Step(Vdbe *p){ return SQLITE_NOMEM_BKPT; } - if( p->pc<0 && p->expired ){ - p->rc = SQLITE_SCHEMA; - rc = SQLITE_ERROR; - if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 ){ - /* If this statement was prepared using saved SQL and an - ** error has occurred, then return the error code in p->rc to the - ** caller. Set the error code in the database handle to the same value. - */ - rc = sqlite3VdbeTransferError(p); - } - goto end_of_step; - } - if( p->pc<0 ){ - /* If there are no other statements currently running, then - ** reset the interrupt flag. This prevents a call to sqlite3_interrupt - ** from interrupting a statement that has not yet started. - */ - if( db->nVdbeActive==0 ){ - AtomicStore(&db->u1.isInterrupted, 0); - } + assert(p); + if( p->eVdbeState!=VDBE_RUN_STATE ){ + restart_step: + if( p->eVdbeState==VDBE_READY_STATE ){ + if( p->expired ){ + p->rc = SQLITE_SCHEMA; + rc = SQLITE_ERROR; + if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 ){ + /* If this statement was prepared using saved SQL and an + ** error has occurred, then return the error code in p->rc to the + ** caller. Set the error code in the database handle to the same + ** value. + */ + rc = sqlite3VdbeTransferError(p); + } + goto end_of_step; + } - assert( db->nVdbeWrite>0 || db->autoCommit==0 - || (db->nDeferredCons==0 && db->nDeferredImmCons==0) - ); + /* If there are no other statements currently running, then + ** reset the interrupt flag. This prevents a call to sqlite3_interrupt + ** from interrupting a statement that has not yet started. + */ + if( db->nVdbeActive==0 ){ + AtomicStore(&db->u1.isInterrupted, 0); + } + + assert( db->nVdbeWrite>0 || db->autoCommit==0 + || (db->nDeferredCons==0 && db->nDeferredImmCons==0) + ); #ifndef SQLITE_OMIT_TRACE - if( (db->mTrace & (SQLITE_TRACE_PROFILE|SQLITE_TRACE_XPROFILE))!=0 - && !db->init.busy && p->zSql ){ - sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime); - }else{ - assert( p->startTime==0 ); - } + if( (db->mTrace & (SQLITE_TRACE_PROFILE|SQLITE_TRACE_XPROFILE))!=0 + && !db->init.busy && p->zSql ){ + sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime); + }else{ + assert( p->startTime==0 ); + } #endif - db->nVdbeActive++; - if( p->readOnly==0 ) db->nVdbeWrite++; - if( p->bIsReader ) db->nVdbeRead++; - p->pc = 0; + db->nVdbeActive++; + if( p->readOnly==0 ) db->nVdbeWrite++; + if( p->bIsReader ) db->nVdbeRead++; + p->pc = 0; + p->eVdbeState = VDBE_RUN_STATE; + }else + + if( p->eVdbeState==VDBE_HALT_STATE ){ + /* We used to require that sqlite3_reset() be called before retrying + ** sqlite3_step() after any error or after SQLITE_DONE. But beginning + ** with version 3.7.0, we changed this so that sqlite3_reset() would + ** be called automatically instead of throwing the SQLITE_MISUSE error. + ** This "automatic-reset" change is not technically an incompatibility, + ** since any application that receives an SQLITE_MISUSE is broken by + ** definition. + ** + ** Nevertheless, some published applications that were originally written + ** for version 3.6.23 or earlier do in fact depend on SQLITE_MISUSE + ** returns, and those were broken by the automatic-reset change. As a + ** a work-around, the SQLITE_OMIT_AUTORESET compile-time restores the + ** legacy behavior of returning SQLITE_MISUSE for cases where the + ** previous sqlite3_step() returned something other than a SQLITE_LOCKED + ** or SQLITE_BUSY error. + */ +#ifdef SQLITE_OMIT_AUTORESET + if( (rc = p->rc&0xff)==SQLITE_BUSY || rc==SQLITE_LOCKED ){ + sqlite3_reset((sqlite3_stmt*)p); + }else{ + return SQLITE_MISUSE_BKPT; + } +#else + sqlite3_reset((sqlite3_stmt*)p); +#endif + assert( p->eVdbeState==VDBE_READY_STATE ); + goto restart_step; + } } + #ifdef SQLITE_DEBUG p->rcApp = SQLITE_OK; #endif @@ -1428,7 +1437,7 @@ static int vdbeUnbind(Vdbe *p, int i){ return SQLITE_MISUSE_BKPT; } sqlite3_mutex_enter(p->db->mutex); - if( p->eVdbeState!=VDBE_RUN_STATE || p->pc>=0 ){ + if( p->eVdbeState!=VDBE_READY_STATE ){ sqlite3Error(p->db, SQLITE_MISUSE); sqlite3_mutex_leave(p->db->mutex); sqlite3_log(SQLITE_MISUSE, @@ -1781,7 +1790,7 @@ int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt){ */ int sqlite3_stmt_busy(sqlite3_stmt *pStmt){ Vdbe *v = (Vdbe*)pStmt; - return v!=0 && v->eVdbeState==VDBE_RUN_STATE && v->pc>=0; + return v!=0 && v->eVdbeState==VDBE_RUN_STATE; } /* diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 1ce4c14ace..ce92999cdf 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2299,13 +2299,15 @@ void sqlite3VdbeRewind(Vdbe *p){ int i; #endif assert( p!=0 ); - assert( p->eVdbeState==VDBE_INIT_STATE || p->eVdbeState==VDBE_HALT_STATE ); + assert( p->eVdbeState==VDBE_INIT_STATE + || p->eVdbeState==VDBE_READY_STATE + || p->eVdbeState==VDBE_HALT_STATE ); /* There should be at least one opcode. */ assert( p->nOp>0 ); - p->eVdbeState = VDBE_RUN_STATE; + p->eVdbeState = VDBE_READY_STATE; #ifdef SQLITE_DEBUG for(i=0; inMem; i++){ @@ -2558,9 +2560,7 @@ static void closeAllCursors(Vdbe *p){ } assert( p->nFrame==0 ); closeCursorsInFrame(p); - if( p->aMem ){ - releaseMemArray(p->aMem, p->nMem); - } + releaseMemArray(p->aMem, p->nMem); while( p->pDelFrame ){ VdbeFrame *pDel = p->pDelFrame; p->pDelFrame = pDel->pParent; @@ -3051,7 +3051,7 @@ int sqlite3VdbeHalt(Vdbe *p){ /* No commit or rollback needed if the program never started or if the ** SQL statement does not read or write a database file. */ - if( p->pc>=0 && p->bIsReader ){ + if( p->bIsReader ){ int mrc; /* Primary error code from p->rc */ int eStatementOp = 0; int isSpecialError; /* Set to true if a 'special' error */ @@ -3199,14 +3199,12 @@ int sqlite3VdbeHalt(Vdbe *p){ } /* We have successfully halted and closed the VM. Record this fact. */ - if( p->pc>=0 ){ - db->nVdbeActive--; - if( !p->readOnly ) db->nVdbeWrite--; - if( p->bIsReader ) db->nVdbeRead--; - assert( db->nVdbeActive>=db->nVdbeRead ); - assert( db->nVdbeRead>=db->nVdbeWrite ); - assert( db->nVdbeWrite>=0 ); - } + db->nVdbeActive--; + if( !p->readOnly ) db->nVdbeWrite--; + if( p->bIsReader ) db->nVdbeRead--; + assert( db->nVdbeActive>=db->nVdbeRead ); + assert( db->nVdbeRead>=db->nVdbeWrite ); + assert( db->nVdbeWrite>=0 ); p->eVdbeState = VDBE_HALT_STATE; checkActiveVdbeCnt(db); if( db->mallocFailed ){ @@ -3390,7 +3388,10 @@ int sqlite3VdbeReset(Vdbe *p){ */ int sqlite3VdbeFinalize(Vdbe *p){ int rc = SQLITE_OK; - if( p->eVdbeState==VDBE_RUN_STATE || p->eVdbeState==VDBE_HALT_STATE ){ + assert( VDBE_RUN_STATE>VDBE_READY_STATE ); + assert( VDBE_HALT_STATE>VDBE_READY_STATE ); + assert( VDBE_INIT_STATEeVdbeState>=VDBE_READY_STATE ){ rc = sqlite3VdbeReset(p); assert( (rc & p->db->errMask)==rc ); } From 659fdb4da87b3eed2e5b5ec6369f63c34f682e2a Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 1 Apr 2022 15:31:58 +0000 Subject: [PATCH 044/259] Have the sqlite3_context object carry the encoding for the prepared statement that it represents, so that sqlite3_result() and similar can set the encoding according to the prepared statement, even if the database encoding has changed. dbsqlfuzz c409b10d0a6bccf78ab00f47e1d29d42ee5b3565 FossilOrigin-Name: d4e19314f564126e180e091f9135c7bc55a10442edb46fbd3a4cfad21201dfa6 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/vdbe.c | 3 +++ src/vdbeInt.h | 1 + src/vdbeapi.c | 4 ++-- src/vdbemem.c | 3 +++ 6 files changed, 19 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index a443d0fbce..926ed99065 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings. -D 2022-03-31T16:09:13.558 +C Have\sthe\ssqlite3_context\sobject\scarry\sthe\sencoding\sfor\sthe\sprepared\sstatement\nthat\sit\srepresents,\sso\sthat\ssqlite3_result()\sand\ssimilar\scan\sset\sthe\sencoding\naccording\sto\sthe\sprepared\sstatement,\seven\sif\sthe\sdatabase\sencoding\shas\nchanged.\ndbsqlfuzz\sc409b10d0a6bccf78ab00f47e1d29d42ee5b3565 +D 2022-04-01T15:31:58.643 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -624,13 +624,13 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c af4a5e9d64dbcc484be1fa4609b655577f81ee2cd40b61e96bece6d43718ae91 +F src/vdbe.c 0245de62bdf0fb22605b8d093738890b3fa788604ee37b6cde3c36312c982dd5 F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e -F src/vdbeInt.h 8dd91427155a38ec06e9ecbde07e33f21bc02e101625191e7613f883e379a363 -F src/vdbeapi.c d41dedcf05f4b0ee3f0a2ce4f8316631fef5391c2d5705b4a0b48156b8061c0b +F src/vdbeInt.h 75421e3c0f139b008c95f1e9c36815aa40f4d07d2bdd1e0499c2c5a1bcf43fd3 +F src/vdbeapi.c fe789d29ce9edab0f5413836ab535d4a1518aca3a6a75e2f8ff6cd1af8092384 F src/vdbeaux.c 45a94316496a200a1d3a29b014fbbc7fc44860c026f768b2d0fcc108e92536d4 F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd -F src/vdbemem.c 512499e51eb7cbe1d886031f19ab6f3e05655a0b25655991af01b61a631a78f7 +F src/vdbemem.c 062cd58c54f887dc2eeb865686251c17237f791f0e6394e9c6f7a6f3c1a7e206 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823 F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c @@ -1945,8 +1945,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 f2d9262e4427ab37ba26c004fc7a4790c86c1856d695a6b4ec3e72732ea54c09 -R d2182f02ef1334fdc5f699b0ef49ddd5 +P b916087aacba53530d2bd19eef2a4fd7a253bf7fa87b49e0df17f7987d7164ae +R 1ee66aee9bdc56655db1d4233ec1d6dd U drh -Z 8f84c3af05b1ca72966bc5e0edb8cacb +Z 211cab8b8131b21a3be9680b8e8f8562 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5456276fa0..9351fe3040 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b916087aacba53530d2bd19eef2a4fd7a253bf7fa87b49e0df17f7987d7164ae \ No newline at end of file +d4e19314f564126e180e091f9135c7bc55a10442edb46fbd3a4cfad21201dfa6 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index ec227f884a..138210943b 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -7249,6 +7249,7 @@ case OP_AggStep: { pCtx->pVdbe = p; pCtx->skipFlag = 0; pCtx->isError = 0; + pCtx->enc = encoding; pCtx->argc = n; pOp->p4type = P4_FUNCCTX; pOp->p4.pCtx = pCtx; @@ -7898,6 +7899,7 @@ case OP_VColumn: { assert( pModule->xColumn ); memset(&sContext, 0, sizeof(sContext)); sContext.pOut = pDest; + sContext.enc = encoding; assert( pOp->p5==OPFLAG_NOCHNG || pOp->p5==0 ); if( pOp->p5 & OPFLAG_NOCHNG ){ sqlite3VdbeMemSetNull(pDest); @@ -8182,6 +8184,7 @@ case OP_Function: { /* group */ if( pCtx->pOut != pOut ){ pCtx->pVdbe = p; pCtx->pOut = pOut; + pCtx->enc = encoding; for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i]; } assert( pCtx->pVdbe==p ); diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 45720b6a55..32c341eb8d 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -369,6 +369,7 @@ struct sqlite3_context { Vdbe *pVdbe; /* The VM that owns this context */ int iOp; /* Instruction number of OP_Function */ int isError; /* Error code returned by the function. */ + u8 enc; /* Encoding to use for results */ u8 skipFlag; /* Skip accumulator loading if true */ u8 argc; /* Number of arguments */ sqlite3_value *argv[1]; /* Argument set */ diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 7567b89945..c23dd0e0c8 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -391,7 +391,7 @@ static void setResultStrOrError( } return; } - sqlite3VdbeChangeEncoding(pOut, ENC(pOut->db)); + sqlite3VdbeChangeEncoding(pOut, pCtx->enc); if( sqlite3VdbeMemTooBig(pOut) ){ sqlite3_result_error_toobig(pCtx); } @@ -540,7 +540,7 @@ void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){ Mem *pOut = pCtx->pOut; assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemCopy(pOut, pValue); - sqlite3VdbeChangeEncoding(pOut, ENC(pOut->db)); + sqlite3VdbeChangeEncoding(pOut, pCtx->enc); if( sqlite3VdbeMemTooBig(pOut) ){ sqlite3_result_error_toobig(pCtx); } diff --git a/src/vdbemem.c b/src/vdbemem.c index 82d79a580a..5eac7cf712 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -467,6 +467,7 @@ int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ ctx.pOut = &t; ctx.pMem = pMem; ctx.pFunc = pFunc; + ctx.enc = ENC(t.db); pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */ assert( (pMem->flags & MEM_Dyn)==0 ); if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc); @@ -494,6 +495,7 @@ int sqlite3VdbeMemAggValue(Mem *pAccum, Mem *pOut, FuncDef *pFunc){ ctx.pOut = pOut; ctx.pMem = pAccum; ctx.pFunc = pFunc; + ctx.enc = ENC(pAccum->db); pFunc->xValue(&ctx); return ctx.isError; } @@ -1491,6 +1493,7 @@ static int valueFromFunction( memset(&ctx, 0, sizeof(ctx)); ctx.pOut = pVal; ctx.pFunc = pFunc; + ctx.enc = ENC(db); pFunc->xSFunc(&ctx, nVal, apVal); if( ctx.isError ){ rc = ctx.isError; From 00946d79535aa1c11d859ea2e944068c953faf48 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 1 Apr 2022 16:22:41 +0000 Subject: [PATCH 045/259] Avoid a harmless uninitialized variable warning in PRAGMA incremental_vacuum. FossilOrigin-Name: 6d976f90dfe4886c3f4c062151af5c5ca7454d34b71172401b8c67acd2d663a0 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/pragma.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 926ed99065..662771b0da 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Have\sthe\ssqlite3_context\sobject\scarry\sthe\sencoding\sfor\sthe\sprepared\sstatement\nthat\sit\srepresents,\sso\sthat\ssqlite3_result()\sand\ssimilar\scan\sset\sthe\sencoding\naccording\sto\sthe\sprepared\sstatement,\seven\sif\sthe\sdatabase\sencoding\shas\nchanged.\ndbsqlfuzz\sc409b10d0a6bccf78ab00f47e1d29d42ee5b3565 -D 2022-04-01T15:31:58.643 +C Avoid\sa\sharmless\suninitialized\svariable\swarning\sin\sPRAGMA\sincremental_vacuum. +D 2022-04-01T16:22:41.680 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -545,7 +545,7 @@ F src/parse.y 0f02b27cdaa334441463153fff3ceb780fea006ab53ffd6ef566d4468f93e924 F src/pcache.c 084e638432c610f95aea72b8509f0845d2791293f39d1b82f0c0a7e089c3bb6b F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 54881292a9a5db202b2c0ac541c5e3ef9a5e8c4f1c1383adb2601d5499a60e65 -F src/pragma.c 9047ffb003d9434810ee81d7b1722d0093821622eb3217c962c3407bad949ce2 +F src/pragma.c a29c54aa5230819ab34293e3563836318dc8b87f5aeb68ca64f9734011a8b00e F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c fd940149c691684e7c1073c3787a7170e44852b02d1275d2e30a5b58e89cfcaf F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 @@ -1945,8 +1945,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 b916087aacba53530d2bd19eef2a4fd7a253bf7fa87b49e0df17f7987d7164ae -R 1ee66aee9bdc56655db1d4233ec1d6dd +P d4e19314f564126e180e091f9135c7bc55a10442edb46fbd3a4cfad21201dfa6 +R 0ec367734a93a75663b3abea5e03bf19 U drh -Z 211cab8b8131b21a3be9680b8e8f8562 +Z 9dcfea7aa3dabdeb03cfb5d58440b56a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9351fe3040..d0b89733cc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d4e19314f564126e180e091f9135c7bc55a10442edb46fbd3a4cfad21201dfa6 \ No newline at end of file +6d976f90dfe4886c3f4c062151af5c5ca7454d34b71172401b8c67acd2d663a0 \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index a95b9ee3d1..f4908813cc 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -808,7 +808,7 @@ void sqlite3Pragma( */ #ifndef SQLITE_OMIT_AUTOVACUUM case PragTyp_INCREMENTAL_VACUUM: { - int iLimit, addr; + int iLimit = 0, addr; if( zRight==0 || !sqlite3GetInt32(zRight, &iLimit) || iLimit<=0 ){ iLimit = 0x7fffffff; } From 2fb448f2c865955a5fafe7c6562123f41b0ecb34 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 1 Apr 2022 17:23:17 +0000 Subject: [PATCH 046/259] Remove an unnecessary branch from sqlite3VdbeReset(). FossilOrigin-Name: a7d79560a0efd6221ba59ce84bcb4fa94024a901ac4a45e192ddecc6e1b5c78c --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/vdbeaux.c | 6 ------ 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index e9f33763f3..e133f7b103 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Refactor\sthe\sVdbe.iVdbeMagic\sfield\sinto\sVdbe.eVdbeState.\s\sSplit\sthe\sRUNNING\nstate\sinto\sseparate\sRUNNING\sand\sREADY.\s\sThis\sgives\sa\ssize\sreduction\sand\nperformance\sincrease. -D 2022-04-01T17:01:57.201 +C Remove\san\sunnecessary\sbranch\sfrom\ssqlite3VdbeReset(). +D 2022-04-01T17:23:17.177 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -628,7 +628,7 @@ F src/vdbe.c aa8751fbca2aae36ea0a4753636d4e257363a39c67af6b52ebdaecea83de2859 F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e F src/vdbeInt.h a2f535ae607e441104d22617a30cb6290264fa1820702a7956a10c6f795b1344 F src/vdbeapi.c 17474f2122c1f54c93dcdb7b845e68e207bbebab6a040c65ed374c4aec049d34 -F src/vdbeaux.c 12fd47127081042706c318590f4dbc90233e22ca12742462f85703f4f4fc6658 +F src/vdbeaux.c 58e52186c8589c027cbd641a712bff32d065ed9979dceee075f149fbd9741a48 F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 062cd58c54f887dc2eeb865686251c17237f791f0e6394e9c6f7a6f3c1a7e206 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 @@ -1945,9 +1945,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 6d976f90dfe4886c3f4c062151af5c5ca7454d34b71172401b8c67acd2d663a0 d698826b08b88e227eb83f84b3cdb19f17306b532eccfa162090abccdf3c63d8 -R 97a4d2d9fb07a14d2a76d85d2d1743dd -T +closed d698826b08b88e227eb83f84b3cdb19f17306b532eccfa162090abccdf3c63d8 +P 5a50a42fde9477868fad31099f5fe976437825fac44f8b3a4cf6c739c7667bbb +R c8b23c8076d7301b5325ea561823bba4 U drh -Z b98f2a477a3e4e8aef60cc1790477902 +Z 3fa3c8a11056de64fa803d36c3f3eb49 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b55eb61a13..b9f9ec1753 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5a50a42fde9477868fad31099f5fe976437825fac44f8b3a4cf6c739c7667bbb \ No newline at end of file +a7d79560a0efd6221ba59ce84bcb4fa94024a901ac4a45e192ddecc6e1b5c78c \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 6573efcf2e..09c11b73d3 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3315,12 +3315,6 @@ int sqlite3VdbeReset(Vdbe *p){ db->errCode = p->rc; } if( p->runOnlyOnce ) p->expired = 1; - }else if( p->rc && p->expired ){ - /* The expired flag was set on the VDBE before the first call - ** to sqlite3_step(). For consistency (since sqlite3_step() was - ** called), set the database error in this case as well. - */ - sqlite3ErrorWithMsg(db, p->rc, p->zErrMsg ? "%s" : 0, p->zErrMsg); } /* Reset register contents and reclaim error message memory. From 473571b083e6387da0a0268ab396bf1243a15491 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 1 Apr 2022 18:19:04 +0000 Subject: [PATCH 047/259] Provide and use a version of sqlite3VdbeFreeCursor() that guarantees the cursor pointer is not NULL. This saves a few bytes of code space and a few CPU cycles. FossilOrigin-Name: cb5e6f8e265c91221227e5f15b95798c688773262407dd138d414103184702f6 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/vdbe.c | 2 +- src/vdbeInt.h | 1 + src/vdbeaux.c | 10 +++++----- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index e133f7b103..e91b22a10f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunnecessary\sbranch\sfrom\ssqlite3VdbeReset(). -D 2022-04-01T17:23:17.177 +C Provide\sand\suse\sa\sversion\sof\ssqlite3VdbeFreeCursor()\sthat\sguarantees\sthe\ncursor\spointer\sis\snot\sNULL.\s\sThis\ssaves\sa\sfew\sbytes\sof\scode\sspace\sand\sa\nfew\sCPU\scycles. +D 2022-04-01T18:19:04.619 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -624,11 +624,11 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c aa8751fbca2aae36ea0a4753636d4e257363a39c67af6b52ebdaecea83de2859 +F src/vdbe.c 0ea2adc2b42e9e3ec8c30fd46818c9715f6359334618153ed2192b4c19e328f8 F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e -F src/vdbeInt.h a2f535ae607e441104d22617a30cb6290264fa1820702a7956a10c6f795b1344 +F src/vdbeInt.h 81172c6b828b546d9fa1ce3e2cbeba90d56e39a6fbef87c46813611090d41f07 F src/vdbeapi.c 17474f2122c1f54c93dcdb7b845e68e207bbebab6a040c65ed374c4aec049d34 -F src/vdbeaux.c 58e52186c8589c027cbd641a712bff32d065ed9979dceee075f149fbd9741a48 +F src/vdbeaux.c 7a98ce924c634ced8d083d130a06e7f2883743dc53f4636957971d623c5517bf F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 062cd58c54f887dc2eeb865686251c17237f791f0e6394e9c6f7a6f3c1a7e206 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 @@ -1945,8 +1945,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 5a50a42fde9477868fad31099f5fe976437825fac44f8b3a4cf6c739c7667bbb -R c8b23c8076d7301b5325ea561823bba4 +P a7d79560a0efd6221ba59ce84bcb4fa94024a901ac4a45e192ddecc6e1b5c78c +R 4a60eaae011c259c4305c79c1c111fac U drh -Z 3fa3c8a11056de64fa803d36c3f3eb49 +Z 4a9d92a66022269a482333bbfdb033cb # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b9f9ec1753..6bfe5a83a1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a7d79560a0efd6221ba59ce84bcb4fa94024a901ac4a45e192ddecc6e1b5c78c \ No newline at end of file +cb5e6f8e265c91221227e5f15b95798c688773262407dd138d414103184702f6 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index ed781a96e5..4eee7b03e4 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -271,7 +271,7 @@ static VdbeCursor *allocateCursor( assert( iCur>=0 && iCurnCursor ); if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/ - sqlite3VdbeFreeCursor(p, p->apCsr[iCur]); + sqlite3VdbeFreeCursorNN(p, p->apCsr[iCur]); p->apCsr[iCur] = 0; } diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 9247b41c3b..342b56ccbc 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -538,6 +538,7 @@ struct ValueList { */ void sqlite3VdbeError(Vdbe*, const char *, ...); void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*); +void sqlite3VdbeFreeCursorNN(Vdbe*,VdbeCursor*); void sqliteVdbePopStack(Vdbe*,int); int SQLITE_NOINLINE sqlite3VdbeHandleMovedCursor(VdbeCursor *p); int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor*); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 09c11b73d3..e64bff1c21 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2080,7 +2080,7 @@ void sqlite3VdbeFrameDelete(VdbeFrame *p){ VdbeCursor **apCsr = (VdbeCursor **)&aMem[p->nChildMem]; assert( sqlite3VdbeFrameIsValid(p) ); for(i=0; inChildCsr; i++){ - sqlite3VdbeFreeCursor(p->v, apCsr[i]); + if( apCsr[i] ) sqlite3VdbeFreeCursorNN(p->v, apCsr[i]); } releaseMemArray(aMem, p->nChildMem); sqlite3VdbeDeleteAuxData(p->v->db, &p->pAuxData, -1, 0); @@ -2474,9 +2474,9 @@ void sqlite3VdbeMakeReady( ** happens to hold. */ void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){ - if( pCx==0 ){ - return; - } + if( pCx ) sqlite3VdbeFreeCursorNN(p,pCx); +} +void sqlite3VdbeFreeCursorNN(Vdbe *p, VdbeCursor *pCx){ switch( pCx->eCurType ){ case CURTYPE_SORTER: { sqlite3VdbeSorterClose(p->db, pCx); @@ -2508,7 +2508,7 @@ static void closeCursorsInFrame(Vdbe *p){ for(i=0; inCursor; i++){ VdbeCursor *pC = p->apCsr[i]; if( pC ){ - sqlite3VdbeFreeCursor(p, pC); + sqlite3VdbeFreeCursorNN(p, pC); p->apCsr[i] = 0; } } From cf6e3fd787fdcc3eb2e5edf2ea80146a195ac874 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 1 Apr 2022 18:45:11 +0000 Subject: [PATCH 048/259] New macro ROUND8P() which works like ROUND8() but assumes that the input is already a multiple of the size of a pointer. It becomes a no-op for 64-bit machines, giving a small size reduction and speed boost. FossilOrigin-Name: d126f304cde66ebfe21a4967c22dcba0bac27cbce56318b14bd50051e49c978c --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/sqliteInt.h | 11 +++++++++++ src/vdbe.c | 4 ++-- src/vdbeaux.c | 10 +++++----- src/where.c | 2 +- 6 files changed, 29 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index e91b22a10f..06f6e0fba4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Provide\sand\suse\sa\sversion\sof\ssqlite3VdbeFreeCursor()\sthat\sguarantees\sthe\ncursor\spointer\sis\snot\sNULL.\s\sThis\ssaves\sa\sfew\sbytes\sof\scode\sspace\sand\sa\nfew\sCPU\scycles. -D 2022-04-01T18:19:04.619 +C New\smacro\sROUND8P()\swhich\sworks\slike\sROUND8()\sbut\sassumes\sthat\sthe\sinput\sis\nalready\sa\smultiple\sof\sthe\ssize\sof\sa\spointer.\s\sIt\sbecomes\sa\sno-op\sfor\n64-bit\smachines,\sgiving\sa\ssmall\ssize\sreduction\sand\sspeed\sboost. +D 2022-04-01T18:45:11.641 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -557,7 +557,7 @@ F src/shell.c.in 24d1082d275db252379629c2b3694dbfa0f8886530b0f6f9896d52e456afe51 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h 2ce7d868630ccd70ffd4b15d46b59ccf7daf89198993b62ed6e4a165d3511280 +F src/sqliteInt.h 5a7867196379868a3f91c8ae172209622de2b5fabf7a5e20aa021ec44174eead F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -624,11 +624,11 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c 0ea2adc2b42e9e3ec8c30fd46818c9715f6359334618153ed2192b4c19e328f8 +F src/vdbe.c 297ff0e5cb7873c177c92627a314e91a21e905323efbd907a50bc3d34d3418d6 F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e F src/vdbeInt.h 81172c6b828b546d9fa1ce3e2cbeba90d56e39a6fbef87c46813611090d41f07 F src/vdbeapi.c 17474f2122c1f54c93dcdb7b845e68e207bbebab6a040c65ed374c4aec049d34 -F src/vdbeaux.c 7a98ce924c634ced8d083d130a06e7f2883743dc53f4636957971d623c5517bf +F src/vdbeaux.c 7be57b47c60e348c32048d2e33c719b3d918a2aef36b30c6da571033c489dd58 F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 062cd58c54f887dc2eeb865686251c17237f791f0e6394e9c6f7a6f3c1a7e206 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 @@ -639,7 +639,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c 7c2c5feb3600d02b827effece817adda0cc1d96ddb9ebe7494c990d53dc26180 +F src/where.c a2483d4fe7cde88638cd3140dd5d6ee3dc0c80d3b3fe20322a8d08dc451f97ae F src/whereInt.h 15d2975c3b4c193c78c26674400a840da8647fe1777ae3b026e2d15937b38a03 F src/wherecode.c 555f598a9ddad81761f084710fdb4f8733fe31bc14cd6b19f8ca4274a7eaa04c F src/whereexpr.c 2a71f5491798460c9590317329234d332d9eb1717cba4f3403122189a75c465e @@ -1945,8 +1945,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 a7d79560a0efd6221ba59ce84bcb4fa94024a901ac4a45e192ddecc6e1b5c78c -R 4a60eaae011c259c4305c79c1c111fac +P cb5e6f8e265c91221227e5f15b95798c688773262407dd138d414103184702f6 +R d734309bfa3d7179546c9735303c8516 U drh -Z 4a9d92a66022269a482333bbfdb033cb +Z 952158b32ce23df022f8a24df89bf845 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 6bfe5a83a1..0dcdfb94a5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cb5e6f8e265c91221227e5f15b95798c688773262407dd138d414103184702f6 \ No newline at end of file +d126f304cde66ebfe21a4967c22dcba0bac27cbce56318b14bd50051e49c978c \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 0f4077aae8..6b08281fed 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -939,8 +939,19 @@ typedef INT16_TYPE LogEst; /* ** Round up a number to the next larger multiple of 8. This is used ** to force 8-byte alignment on 64-bit architectures. +** +** ROUND8() always does the rounding, for any argument. +** +** ROUND8P() assumes that the argument is already an integer number of +** pointers in size, and so it is a no-op on systems where the pointer +** size is 8. */ #define ROUND8(x) (((x)+7)&~7) +#if SQLITE_PTRSIZE==8 +# define ROUND8P(x) (x) +#else +# define ROUND8P(x) (((x)+7)&~7) +#endif /* ** Round down to the nearest multiple of 8 diff --git a/src/vdbe.c b/src/vdbe.c index 4eee7b03e4..5f8543e08a 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -266,7 +266,7 @@ static VdbeCursor *allocateCursor( int nByte; VdbeCursor *pCx = 0; nByte = - ROUND8(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField + + ROUND8P(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField + (eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0); assert( iCur>=0 && iCurnCursor ); @@ -301,7 +301,7 @@ static VdbeCursor *allocateCursor( pCx->aOffset = &pCx->aType[nField]; if( eCurType==CURTYPE_BTREE ){ pCx->uc.pCursor = (BtCursor*) - &pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField]; + &pMem->z[ROUND8P(sizeof(VdbeCursor))+2*sizeof(u32)*nField]; sqlite3BtreeCursorZero(pCx->uc.pCursor); } return pCx; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index e64bff1c21..ecdd50f700 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2274,11 +2274,11 @@ struct ReusableSpace { static void *allocSpace( struct ReusableSpace *p, /* Bulk memory available for allocation */ void *pBuf, /* Pointer to a prior allocation */ - sqlite3_int64 nByte /* Bytes of memory needed */ + sqlite3_int64 nByte /* Bytes of memory needed. */ ){ assert( EIGHT_BYTE_ALIGNMENT(p->pSpace) ); if( pBuf==0 ){ - nByte = ROUND8(nByte); + nByte = ROUND8P(nByte); if( nByte <= p->nFree ){ p->nFree -= nByte; pBuf = &p->pSpace[p->nFree]; @@ -2386,7 +2386,7 @@ void sqlite3VdbeMakeReady( ** opcode array. This extra memory will be reallocated for other elements ** of the prepared statement. */ - n = ROUND8(sizeof(Op)*p->nOp); /* Bytes of opcode memory used */ + n = ROUND8P(sizeof(Op)*p->nOp); /* Bytes of opcode memory used */ x.pSpace = &((u8*)p->aOp)[n]; /* Unused opcode memory */ assert( EIGHT_BYTE_ALIGNMENT(x.pSpace) ); x.nFree = ROUNDDOWN8(pParse->szOpAlloc - n); /* Bytes of unused memory */ @@ -3969,10 +3969,10 @@ UnpackedRecord *sqlite3VdbeAllocUnpackedRecord( ){ UnpackedRecord *p; /* Unpacked record to return */ int nByte; /* Number of bytes required for *p */ - nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1); + nByte = ROUND8P(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1); p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte); if( !p ) return 0; - p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))]; + p->aMem = (Mem*)&((char*)p)[ROUND8P(sizeof(UnpackedRecord))]; assert( pKeyInfo->aSortFlags!=0 ); p->pKeyInfo = pKeyInfo; p->nField = pKeyInfo->nKeyField + 1; diff --git a/src/where.c b/src/where.c index c8a3cba2ec..f9f42d5285 100644 --- a/src/where.c +++ b/src/where.c @@ -5408,7 +5408,7 @@ WhereInfo *sqlite3WhereBegin( ** field (type Bitmask) it must be aligned on an 8-byte boundary on ** some architectures. Hence the ROUND8() below. */ - nByteWInfo = ROUND8(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel)); + nByteWInfo = ROUND8P(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel)); pWInfo = sqlite3DbMallocRawNN(db, nByteWInfo + sizeof(WhereLoop)); if( db->mallocFailed ){ sqlite3DbFree(db, pWInfo); From a24832b7b2ca8e10705448d04d4d0ca38e41a0bd Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 1 Apr 2022 19:04:13 +0000 Subject: [PATCH 049/259] Omit the Vdbe.doingRerun field for a slight size reduction and performance gain. FossilOrigin-Name: e93297a9d775688e6274c54ba75b19fc1fe8b29b73b9b5e7f94f3f2ca37f045f --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/vdbe.c | 2 +- src/vdbeInt.h | 1 - src/vdbeapi.c | 9 +++++++-- 5 files changed, 17 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 06f6e0fba4..a1b43ba589 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\smacro\sROUND8P()\swhich\sworks\slike\sROUND8()\sbut\sassumes\sthat\sthe\sinput\sis\nalready\sa\smultiple\sof\sthe\ssize\sof\sa\spointer.\s\sIt\sbecomes\sa\sno-op\sfor\n64-bit\smachines,\sgiving\sa\ssmall\ssize\sreduction\sand\sspeed\sboost. -D 2022-04-01T18:45:11.641 +C Omit\sthe\sVdbe.doingRerun\sfield\sfor\sa\sslight\ssize\sreduction\sand\sperformance\sgain. +D 2022-04-01T19:04:13.644 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -624,10 +624,10 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c 297ff0e5cb7873c177c92627a314e91a21e905323efbd907a50bc3d34d3418d6 +F src/vdbe.c 8f8373466beab434b7d1991fafec68a13318adf10ccf345a14ed178873c66632 F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e -F src/vdbeInt.h 81172c6b828b546d9fa1ce3e2cbeba90d56e39a6fbef87c46813611090d41f07 -F src/vdbeapi.c 17474f2122c1f54c93dcdb7b845e68e207bbebab6a040c65ed374c4aec049d34 +F src/vdbeInt.h 22babf1e585ae7e5c49f2e6442969b88f07bdcc3d154164346d25ef4efa3ebf3 +F src/vdbeapi.c 76024c6f5af4ca00490b00caa4fb1fb6e016bded19f3b901c255686455d0ef31 F src/vdbeaux.c 7be57b47c60e348c32048d2e33c719b3d918a2aef36b30c6da571033c489dd58 F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 062cd58c54f887dc2eeb865686251c17237f791f0e6394e9c6f7a6f3c1a7e206 @@ -1945,8 +1945,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 cb5e6f8e265c91221227e5f15b95798c688773262407dd138d414103184702f6 -R d734309bfa3d7179546c9735303c8516 +P d126f304cde66ebfe21a4967c22dcba0bac27cbce56318b14bd50051e49c978c +R e63b5f59e7e4b2f0f7f707ce12aa7775 U drh -Z 952158b32ce23df022f8a24df89bf845 +Z 4a5439f66922b2e5d0302346fbe72c1a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0dcdfb94a5..fd47478bc3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d126f304cde66ebfe21a4967c22dcba0bac27cbce56318b14bd50051e49c978c \ No newline at end of file +e93297a9d775688e6274c54ba75b19fc1fe8b29b73b9b5e7f94f3f2ca37f045f \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 5f8543e08a..ffae6a3957 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -8340,7 +8340,7 @@ case OP_Init: { /* jump */ #ifndef SQLITE_OMIT_TRACE if( (db->mTrace & (SQLITE_TRACE_STMT|SQLITE_TRACE_LEGACY))!=0 - && !p->doingRerun + && p->minWriteFileFormat!=254 /* tag-20220401a */ && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 ){ #ifndef SQLITE_OMIT_DEPRECATED diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 342b56ccbc..792ead7b5f 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -455,7 +455,6 @@ struct Vdbe { u8 errorAction; /* Recovery action to do in case of an error */ u8 minWriteFileFormat; /* Minimum file format for writable database files */ u8 prepFlags; /* SQLITE_PREPARE_* flags */ - u8 doingRerun; /* True if rerunning after an auto-reprepare */ u8 eVdbeState; /* On of the VDBE_*_STATE values */ bft expired:2; /* 1: recompile VM immediately 2: when convenient */ bft explain:2; /* True if EXPLAIN present on SQL command */ diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 40821c1145..b07211177a 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -797,7 +797,6 @@ int sqlite3_step(sqlite3_stmt *pStmt){ } db = v->db; sqlite3_mutex_enter(db->mutex); - v->doingRerun = 0; while( (rc = sqlite3Step(v))==SQLITE_SCHEMA && cnt++ < SQLITE_MAX_SCHEMA_RETRY ){ int savedPc = v->pc; @@ -823,7 +822,13 @@ int sqlite3_step(sqlite3_stmt *pStmt){ break; } sqlite3_reset(pStmt); - if( savedPc>=0 ) v->doingRerun = 1; + if( savedPc>=0 ){ + /* Setting minWriteFileFormat to 254 is a signal to the OP_Init and + ** OP_Trace opcodes to *not* perform SQLITE_TRACE_STMT because one + ** should output has already occurred due to SQLITE_SCHEMA. + ** tag-20220401a */ + v->minWriteFileFormat = 254; + } assert( v->expired==0 ); } sqlite3_mutex_leave(db->mutex); From 35e9e350cac291b64023e93b3fc886abc112c758 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 1 Apr 2022 19:13:39 +0000 Subject: [PATCH 050/259] There is no need for sqlite3_step() to check for an OOM condition prior to starting up. FossilOrigin-Name: 44be7f46ba89289683ed0e123169ca9adb1018de03071d66de480c910a23d074 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeapi.c | 8 +------- 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index a1b43ba589..09acfe15c2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Omit\sthe\sVdbe.doingRerun\sfield\sfor\sa\sslight\ssize\sreduction\sand\sperformance\sgain. -D 2022-04-01T19:04:13.644 +C There\sis\sno\sneed\sfor\ssqlite3_step()\sto\scheck\sfor\san\sOOM\scondition\sprior\nto\sstarting\sup. +D 2022-04-01T19:13:39.542 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -627,7 +627,7 @@ F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 F src/vdbe.c 8f8373466beab434b7d1991fafec68a13318adf10ccf345a14ed178873c66632 F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e F src/vdbeInt.h 22babf1e585ae7e5c49f2e6442969b88f07bdcc3d154164346d25ef4efa3ebf3 -F src/vdbeapi.c 76024c6f5af4ca00490b00caa4fb1fb6e016bded19f3b901c255686455d0ef31 +F src/vdbeapi.c 5c498998c99667f16cac2519f2fa439fe46acf99a332b0caa73637fc2ab35c22 F src/vdbeaux.c 7be57b47c60e348c32048d2e33c719b3d918a2aef36b30c6da571033c489dd58 F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 062cd58c54f887dc2eeb865686251c17237f791f0e6394e9c6f7a6f3c1a7e206 @@ -1945,8 +1945,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 d126f304cde66ebfe21a4967c22dcba0bac27cbce56318b14bd50051e49c978c -R e63b5f59e7e4b2f0f7f707ce12aa7775 +P e93297a9d775688e6274c54ba75b19fc1fe8b29b73b9b5e7f94f3f2ca37f045f +R 3bf981a3a67361db5af62d95568eb001 U drh -Z 4a5439f66922b2e5d0302346fbe72c1a +Z f0feb45320505d1785603ccc6d16bf9d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index fd47478bc3..3c06fa0e20 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e93297a9d775688e6274c54ba75b19fc1fe8b29b73b9b5e7f94f3f2ca37f045f \ No newline at end of file +44be7f46ba89289683ed0e123169ca9adb1018de03071d66de480c910a23d074 \ No newline at end of file diff --git a/src/vdbeapi.c b/src/vdbeapi.c index b07211177a..9a5d01682a 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -642,14 +642,8 @@ static int sqlite3Step(Vdbe *p){ sqlite3 *db; int rc; - /* Check that malloc() has not failed. If it has, return early. */ - db = p->db; - if( db->mallocFailed ){ - p->rc = SQLITE_NOMEM; - return SQLITE_NOMEM_BKPT; - } - assert(p); + db = p->db; if( p->eVdbeState!=VDBE_RUN_STATE ){ restart_step: if( p->eVdbeState==VDBE_READY_STATE ){ From 3b8b5be3b7340a3c94d549d51c55721cdd1ca3f3 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 1 Apr 2022 20:19:36 +0000 Subject: [PATCH 051/259] It is not necessary to de-ephermeralize the output registers in the OP_ResultRow opcode. Omit that step for a size reduction and performance increase. FossilOrigin-Name: 8a07745aed1d0a4eead55d43f1923597b12371f307ecf5bc19c5a1db9a107a50 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 43 +++++++++++++++---------------------------- 3 files changed, 22 insertions(+), 35 deletions(-) diff --git a/manifest b/manifest index 09acfe15c2..090b7eeb5f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C There\sis\sno\sneed\sfor\ssqlite3_step()\sto\scheck\sfor\san\sOOM\scondition\sprior\nto\sstarting\sup. -D 2022-04-01T19:13:39.542 +C It\sis\snot\snecessary\sto\sde-ephermeralize\sthe\soutput\sregisters\sin\sthe\nOP_ResultRow\sopcode.\s\sOmit\sthat\sstep\sfor\sa\ssize\sreduction\sand\sperformance\nincrease. +D 2022-04-01T20:19:36.366 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -624,7 +624,7 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c 8f8373466beab434b7d1991fafec68a13318adf10ccf345a14ed178873c66632 +F src/vdbe.c c8f0fc516a54aa9c696ca0cd4f54b550ea86ab08bcee70b8982f5e3b0305ab8b F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e F src/vdbeInt.h 22babf1e585ae7e5c49f2e6442969b88f07bdcc3d154164346d25ef4efa3ebf3 F src/vdbeapi.c 5c498998c99667f16cac2519f2fa439fe46acf99a332b0caa73637fc2ab35c22 @@ -1945,8 +1945,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 e93297a9d775688e6274c54ba75b19fc1fe8b29b73b9b5e7f94f3f2ca37f045f -R 3bf981a3a67361db5af62d95568eb001 +P 44be7f46ba89289683ed0e123169ca9adb1018de03071d66de480c910a23d074 +R e4956d08253d673d906bef0462c4e505 U drh -Z f0feb45320505d1785603ccc6d16bf9d +Z 404f89fed3d9a2adc89e028bcb714881 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3c06fa0e20..9df36ca5df 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -44be7f46ba89289683ed0e123169ca9adb1018de03071d66de480c910a23d074 \ No newline at end of file +8a07745aed1d0a4eead55d43f1923597b12371f307ecf5bc19c5a1db9a107a50 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index ffae6a3957..c3894560cc 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1549,45 +1549,32 @@ case OP_FkCheck: { ** the result row. */ case OP_ResultRow: { - Mem *pMem; - int i; assert( p->nResColumn==pOp->p2 ); assert( pOp->p1>0 || CORRUPT_DB ); assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 ); - /* Invalidate all ephemeral cursor row caches */ p->cacheCtr = (p->cacheCtr + 2)|1; - - /* Make sure the results of the current row are \000 terminated - ** and have an assigned type. The results are de-ephemeralized as - ** a side effect. - */ - pMem = p->pResultSet = &aMem[pOp->p1]; - for(i=0; ip2; i++){ - assert( memIsValid(&pMem[i]) ); - Deephemeralize(&pMem[i]); - assert( (pMem[i].flags & MEM_Ephem)==0 - || (pMem[i].flags & (MEM_Str|MEM_Blob))==0 ); - sqlite3VdbeMemNulTerminate(&pMem[i]); - REGISTER_TRACE(pOp->p1+i, &pMem[i]); + p->pResultSet = &aMem[pOp->p1]; #ifdef SQLITE_DEBUG - /* The registers in the result will not be used again when the - ** prepared statement restarts. This is because sqlite3_column() - ** APIs might have caused type conversions of made other changes to - ** the register values. Therefore, we can go ahead and break any - ** OP_SCopy dependencies. */ - pMem[i].pScopyFrom = 0; -#endif + { + Mem *pMem = p->pResultSet; + int i; + for(i=0; ip2; i++){ + assert( memIsValid(&pMem[i]) ); + REGISTER_TRACE(pOp->p1+i, &pMem[i]); + /* The registers in the result will not be used again when the + ** prepared statement restarts. This is because sqlite3_column() + ** APIs might have caused type conversions of made other changes to + ** the register values. Therefore, we can go ahead and break any + ** OP_SCopy dependencies. */ + pMem[i].pScopyFrom = 0; + } } +#endif if( db->mallocFailed ) goto no_mem; - if( db->mTrace & SQLITE_TRACE_ROW ){ db->trace.xV2(SQLITE_TRACE_ROW, db->pTraceArg, p, 0); } - - - /* Return SQLITE_ROW - */ p->pc = (int)(pOp - aOp) + 1; rc = SQLITE_ROW; goto vdbe_return; From 759e507ce5fdbc9790e916409d111eb199ab1e89 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 1 Apr 2022 20:39:40 +0000 Subject: [PATCH 052/259] Loop optimization in the OP_MakeRecord opcode. FossilOrigin-Name: 47a61fbd63928021098fbe492283f1afda7c293b3b2706c001192ae4ff1b2cbe --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 6 ++++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 090b7eeb5f..fd9b504655 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C It\sis\snot\snecessary\sto\sde-ephermeralize\sthe\soutput\sregisters\sin\sthe\nOP_ResultRow\sopcode.\s\sOmit\sthat\sstep\sfor\sa\ssize\sreduction\sand\sperformance\nincrease. -D 2022-04-01T20:19:36.366 +C Loop\soptimization\sin\sthe\sOP_MakeRecord\sopcode. +D 2022-04-01T20:39:40.291 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -624,7 +624,7 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c c8f0fc516a54aa9c696ca0cd4f54b550ea86ab08bcee70b8982f5e3b0305ab8b +F src/vdbe.c 0e54be9acfe26e68b94d946cbaf0c8dfe94435e8a506f22ad5550ae4db1d7a0c F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e F src/vdbeInt.h 22babf1e585ae7e5c49f2e6442969b88f07bdcc3d154164346d25ef4efa3ebf3 F src/vdbeapi.c 5c498998c99667f16cac2519f2fa439fe46acf99a332b0caa73637fc2ab35c22 @@ -1945,8 +1945,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 44be7f46ba89289683ed0e123169ca9adb1018de03071d66de480c910a23d074 -R e4956d08253d673d906bef0462c4e505 +P 8a07745aed1d0a4eead55d43f1923597b12371f307ecf5bc19c5a1db9a107a50 +R 8f846dfb58734bb88c205139ba75a9df U drh -Z 404f89fed3d9a2adc89e028bcb714881 +Z 0a0d680f496f86b11293db3c46b2ee9c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9df36ca5df..246b8f5a89 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8a07745aed1d0a4eead55d43f1923597b12371f307ecf5bc19c5a1db9a107a50 \ No newline at end of file +47a61fbd63928021098fbe492283f1afda7c293b3b2706c001192ae4ff1b2cbe \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index c3894560cc..8ad6cd19f6 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3377,7 +3377,7 @@ case OP_MakeRecord: { zHdr += putVarint32(zHdr, nHdr); assert( pData0<=pLast ); pRec = pData0; - do{ + while( 1 /*exit-by-break*/ ){ serial_type = pRec->uTemp; /* EVIDENCE-OF: R-06529-47362 Following the size varint are one or more ** additional varints, one per column. */ @@ -3385,7 +3385,9 @@ case OP_MakeRecord: { /* EVIDENCE-OF: R-64536-51728 The values for each column in the record ** immediately follow the header. */ zPayload += sqlite3VdbeSerialPut(zPayload, pRec, serial_type); /* content */ - }while( (++pRec)<=pLast ); + if( pRec==pLast ) break; + pRec++; + } assert( nHdr==(int)(zHdr - (u8*)pOut->z) ); assert( nByte==(int)(zPayload - (u8*)pOut->z) ); From b47b1f67dca06317908c5c512f0b2352394836f0 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 1 Apr 2022 21:01:37 +0000 Subject: [PATCH 053/259] The putVarint32() macro does not optimize well. So expand it into in-line code in places were performance is an issue. FossilOrigin-Name: 390c239e53cf936a97b268dce8171f0b17050542ae64735ca8ef375fec2c9544 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/btree.c | 6 +++++- src/vdbe.c | 12 ++++++++++-- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index fd9b504655..1aaae798d6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Loop\soptimization\sin\sthe\sOP_MakeRecord\sopcode. -D 2022-04-01T20:39:40.291 +C The\sputVarint32()\smacro\sdoes\snot\soptimize\swell.\s\sSo\sexpand\sit\sinto\sin-line\ncode\sin\splaces\swere\sperformance\sis\san\sissue. +D 2022-04-01T21:01:37.702 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -492,7 +492,7 @@ F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf F src/backup.c a2891172438e385fdbe97c11c9745676bec54f518d4447090af97189fd8e52d7 F src/bitvec.c 7c849aac407230278445cb069bebc5f89bf2ddd87c5ed9459b070a9175707b3d F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c d705859e23fbd7b3c6cd5874f973b5c4fa083eab861398aac95bea7de9a7ed07 +F src/btree.c 45161c2d5c9527b9c9bbfd7478daf3e0a619cf4bbe3278378aaea3d4b4e4f5b5 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482e F src/build.c 4a265d49342cefc95ae739982a6197eae04a9258151f8e0bbe3ff8ab56aab801 @@ -624,7 +624,7 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c 0e54be9acfe26e68b94d946cbaf0c8dfe94435e8a506f22ad5550ae4db1d7a0c +F src/vdbe.c ced0c7b4b872bd30b25f40be70c0ecae095b1dafd9510912ed24369b7efef335 F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e F src/vdbeInt.h 22babf1e585ae7e5c49f2e6442969b88f07bdcc3d154164346d25ef4efa3ebf3 F src/vdbeapi.c 5c498998c99667f16cac2519f2fa439fe46acf99a332b0caa73637fc2ab35c22 @@ -1945,8 +1945,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 8a07745aed1d0a4eead55d43f1923597b12371f307ecf5bc19c5a1db9a107a50 -R 8f846dfb58734bb88c205139ba75a9df +P 47a61fbd63928021098fbe492283f1afda7c293b3b2706c001192ae4ff1b2cbe +R ade274038cb2118d099723f504530cb1 U drh -Z 0a0d680f496f86b11293db3c46b2ee9c +Z 4ae04a2d928465896e499e8a40353d10 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 246b8f5a89..8c666935af 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -47a61fbd63928021098fbe492283f1afda7c293b3b2706c001192ae4ff1b2cbe \ No newline at end of file +390c239e53cf936a97b268dce8171f0b17050542ae64735ca8ef375fec2c9544 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index eb3dbb0a3c..9e721ee5af 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9314,7 +9314,11 @@ int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 iKey){ u32 nRem; /* Bytes of data still to copy */ getCellInfo(pSrc); - aOut += putVarint32(aOut, pSrc->info.nPayload); + if( pSrc->info.nPayload<0x80 ){ + *(aOut++) = pSrc->info.nPayload; + }else{ + aOut += sqlite3PutVarint(aOut, pSrc->info.nPayload); + } if( pDest->pKeyInfo==0 ) aOut += putVarint(aOut, iKey); nIn = pSrc->info.nLocal; aIn = pSrc->info.pPayload; diff --git a/src/vdbe.c b/src/vdbe.c index 8ad6cd19f6..07dfc63258 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3374,14 +3374,22 @@ case OP_MakeRecord: { zPayload = zHdr + nHdr; /* Write the record */ - zHdr += putVarint32(zHdr, nHdr); + if( nHdr<0x80 ){ + *(zHdr++) = nHdr; + }else{ + zHdr += sqlite3PutVarint(zHdr,nHdr); + } assert( pData0<=pLast ); pRec = pData0; while( 1 /*exit-by-break*/ ){ serial_type = pRec->uTemp; /* EVIDENCE-OF: R-06529-47362 Following the size varint are one or more ** additional varints, one per column. */ - zHdr += putVarint32(zHdr, serial_type); /* serial type */ + if( serial_type<0x80 ){ + *(zHdr++) = serial_type; + }else{ + zHdr += sqlite3PutVarint(zHdr, serial_type); + } /* EVIDENCE-OF: R-64536-51728 The values for each column in the record ** immediately follow the header. */ zPayload += sqlite3VdbeSerialPut(zPayload, pRec, serial_type); /* content */ From d859dc2b25c55ab10f70979f76470bdba9f53165 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 2 Apr 2022 14:30:58 +0000 Subject: [PATCH 054/259] In-line the sqlite3VdbeSerialPut() routine into the OP_MakeRecord opcode. This allows some duplicate comparisons to be omitted, resulting in a size reduction and performance increase. FossilOrigin-Name: 6f4d6f212a3558c27be6e9dcf71cec43c424d445e5889c6e91dde84a19c5a2c1 --- manifest | 16 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 37 +++++++++++++++++++++++++++----- src/vdbeInt.h | 9 +++++++- src/vdbeaux.c | 59 ++++----------------------------------------------- 5 files changed, 53 insertions(+), 70 deletions(-) diff --git a/manifest b/manifest index 1aaae798d6..c5af0b4f6d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sputVarint32()\smacro\sdoes\snot\soptimize\swell.\s\sSo\sexpand\sit\sinto\sin-line\ncode\sin\splaces\swere\sperformance\sis\san\sissue. -D 2022-04-01T21:01:37.702 +C In-line\sthe\ssqlite3VdbeSerialPut()\sroutine\sinto\sthe\sOP_MakeRecord\sopcode.\nThis\sallows\ssome\sduplicate\scomparisons\sto\sbe\somitted,\sresulting\sin\sa\ssize\nreduction\sand\sperformance\sincrease. +D 2022-04-02T14:30:58.141 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -624,11 +624,11 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c ced0c7b4b872bd30b25f40be70c0ecae095b1dafd9510912ed24369b7efef335 +F src/vdbe.c 3500a7ebd2121765ce422b971bf65ab5f4d3d177b7ed2c04270423fb77f45b35 F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e -F src/vdbeInt.h 22babf1e585ae7e5c49f2e6442969b88f07bdcc3d154164346d25ef4efa3ebf3 +F src/vdbeInt.h 106930790a7619bc6e851be698e6e35c6b2b2e9e66c2f464d597d6b75b919679 F src/vdbeapi.c 5c498998c99667f16cac2519f2fa439fe46acf99a332b0caa73637fc2ab35c22 -F src/vdbeaux.c 7be57b47c60e348c32048d2e33c719b3d918a2aef36b30c6da571033c489dd58 +F src/vdbeaux.c 7a9df2e5700351221a152775e05d0b4ce9aa73b0d04bcfabeb85ab2229052bac F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 062cd58c54f887dc2eeb865686251c17237f791f0e6394e9c6f7a6f3c1a7e206 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 @@ -1945,8 +1945,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 47a61fbd63928021098fbe492283f1afda7c293b3b2706c001192ae4ff1b2cbe -R ade274038cb2118d099723f504530cb1 +P 390c239e53cf936a97b268dce8171f0b17050542ae64735ca8ef375fec2c9544 +R b3527f8e2f58b460cb9579ec710b98c3 U drh -Z 4ae04a2d928465896e499e8a40353d10 +Z dbc3ad7d55ca1ccbb3a168f87a1e7a5d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8c666935af..901d9eb8a8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -390c239e53cf936a97b268dce8171f0b17050542ae64735ca8ef375fec2c9544 \ No newline at end of file +6f4d6f212a3558c27be6e9dcf71cec43c424d445e5889c6e91dde84a19c5a2c1 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 07dfc63258..0c7447e8a8 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3384,15 +3384,42 @@ case OP_MakeRecord: { while( 1 /*exit-by-break*/ ){ serial_type = pRec->uTemp; /* EVIDENCE-OF: R-06529-47362 Following the size varint are one or more - ** additional varints, one per column. */ - if( serial_type<0x80 ){ + ** additional varints, one per column. + ** EVIDENCE-OF: R-64536-51728 The values for each column in the record + ** immediately follow the header. */ + if( serial_type<=7 ){ *(zHdr++) = serial_type; + if( serial_type==0 ){ + /* NULL value. No change in zPayload */ + }else{ + u64 v; + u32 i, len; + if( serial_type==7 ){ + assert( sizeof(v)==sizeof(pRec->u.r) ); + memcpy(&v, &pRec->u.r, sizeof(v)); + swapMixedEndianFloat(v); + }else{ + v = pRec->u.i; + } + len = i = sqlite3SmallTypeSizes[serial_type]; + assert( i>0 ); + do{ + zPayload[--i] = (u8)(v&0xFF); + v >>= 8; + }while( i ); + zPayload += len; + } + }else if( serial_type<0x80 ){ + *(zHdr++) = serial_type; + if( serial_type>=14 ){ + memcpy(zPayload, pRec->z, pRec->n); + zPayload += pRec->n; + } }else{ zHdr += sqlite3PutVarint(zHdr, serial_type); + memcpy(zPayload, pRec->z, pRec->n); + zPayload += pRec->n; } - /* EVIDENCE-OF: R-64536-51728 The values for each column in the record - ** immediately follow the header. */ - zPayload += sqlite3VdbeSerialPut(zPayload, pRec, serial_type); /* content */ if( pRec==pLast ) break; pRec++; } diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 792ead7b5f..968500b322 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -532,6 +532,8 @@ struct ValueList { sqlite3_value *pOut; /* Register to hold each decoded output value */ }; +const u8 sqlite3SmallTypeSizes[128]; + /* ** Function prototypes */ @@ -544,7 +546,12 @@ int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor*); int sqlite3VdbeCursorRestore(VdbeCursor*); u32 sqlite3VdbeSerialTypeLen(u32); u8 sqlite3VdbeOneByteSerialTypeLen(u8); -u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32); +#ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT + u64 sqlite3FloatSwap(u64 in); +# define swapMixedEndianFloat(X) X = sqlite3FloatSwap(X) +#else +# define swapMixedEndianFloat(X) +#endif void sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); void sqlite3VdbeDeleteAuxData(sqlite3*, AuxData**, int, int); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index ecdd50f700..aa45cae54c 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3557,7 +3557,7 @@ int sqlite3VdbeCursorRestore(VdbeCursor *p){ ** sqlite3VdbeSerialType() ** sqlite3VdbeSerialTypeLen() ** sqlite3VdbeSerialLen() -** sqlite3VdbeSerialPut() +** sqlite3VdbeSerialPut() <--- in-lined into OP_MakeRecord as of 2022-04-02 ** sqlite3VdbeSerialGet() ** ** encapsulate the code that serializes values for storage in SQLite @@ -3669,7 +3669,7 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){ /* ** The sizes for serial types less than 128 */ -static const u8 sqlite3SmallTypeSizes[] = { +const u8 sqlite3SmallTypeSizes[128] = { /* 0 1 2 3 4 5 6 7 8 9 */ /* 0 */ 0, 1, 2, 3, 4, 6, 8, 8, 0, 0, /* 10 */ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, @@ -3738,7 +3738,7 @@ u8 sqlite3VdbeOneByteSerialTypeLen(u8 serial_type){ ** so we trust him. */ #ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT -static u64 floatSwap(u64 in){ +u64 sqlite3FloatSwap(u64 in){ union { u64 r; u32 i[2]; @@ -3751,59 +3751,8 @@ static u64 floatSwap(u64 in){ u.i[1] = t; return u.r; } -# define swapMixedEndianFloat(X) X = floatSwap(X) -#else -# define swapMixedEndianFloat(X) -#endif +#endif /* SQLITE_MIXED_ENDIAN_64BIT_FLOAT */ -/* -** Write the serialized data blob for the value stored in pMem into -** buf. It is assumed that the caller has allocated sufficient space. -** Return the number of bytes written. -** -** nBuf is the amount of space left in buf[]. The caller is responsible -** for allocating enough space to buf[] to hold the entire field, exclusive -** of the pMem->u.nZero bytes for a MEM_Zero value. -** -** Return the number of bytes actually written into buf[]. The number -** of bytes in the zero-filled tail is included in the return value only -** if those bytes were zeroed in buf[]. -*/ -u32 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type){ - u32 len; - - /* Integer and Real */ - if( serial_type<=7 && serial_type>0 ){ - u64 v; - u32 i; - if( serial_type==7 ){ - assert( sizeof(v)==sizeof(pMem->u.r) ); - memcpy(&v, &pMem->u.r, sizeof(v)); - swapMixedEndianFloat(v); - }else{ - v = pMem->u.i; - } - len = i = sqlite3SmallTypeSizes[serial_type]; - assert( i>0 ); - do{ - buf[--i] = (u8)(v&0xFF); - v >>= 8; - }while( i ); - return len; - } - - /* String or blob */ - if( serial_type>=12 ){ - assert( pMem->n + ((pMem->flags & MEM_Zero)?pMem->u.nZero:0) - == (int)sqlite3VdbeSerialTypeLen(serial_type) ); - len = pMem->n; - if( len>0 ) memcpy(buf, pMem->z, len); - return len; - } - - /* NULL or constants 0 or 1 */ - return 0; -} /* Input "x" is a sequence of unsigned characters that represent a ** big-endian integer. Return the equivalent native integer From 2c144b0f63bd1410e6f03c4c211d87f7860f7b3b Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 2 Apr 2022 15:19:02 +0000 Subject: [PATCH 055/259] Minor loop optimization in OP_MakeRecord. FossilOrigin-Name: 4350983b37879d3280432d90fef04f5cc4be1b3110b5435123d897e31b34db8a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 5 +++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index c5af0b4f6d..e0d4246e1f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In-line\sthe\ssqlite3VdbeSerialPut()\sroutine\sinto\sthe\sOP_MakeRecord\sopcode.\nThis\sallows\ssome\sduplicate\scomparisons\sto\sbe\somitted,\sresulting\sin\sa\ssize\nreduction\sand\sperformance\sincrease. -D 2022-04-02T14:30:58.141 +C Minor\sloop\soptimization\sin\sOP_MakeRecord. +D 2022-04-02T15:19:02.206 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -624,7 +624,7 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c 3500a7ebd2121765ce422b971bf65ab5f4d3d177b7ed2c04270423fb77f45b35 +F src/vdbe.c 9dca2919060c79df77a9e2db6440461592f8230aa379102e45c3988604794fa1 F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e F src/vdbeInt.h 106930790a7619bc6e851be698e6e35c6b2b2e9e66c2f464d597d6b75b919679 F src/vdbeapi.c 5c498998c99667f16cac2519f2fa439fe46acf99a332b0caa73637fc2ab35c22 @@ -1945,8 +1945,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 390c239e53cf936a97b268dce8171f0b17050542ae64735ca8ef375fec2c9544 -R b3527f8e2f58b460cb9579ec710b98c3 +P 6f4d6f212a3558c27be6e9dcf71cec43c424d445e5889c6e91dde84a19c5a2c1 +R b4168a297f2f907dda7ae8fb734939e5 U drh -Z dbc3ad7d55ca1ccbb3a168f87a1e7a5d +Z a1b1f1e17a6d5742ec380e2ab7594ab3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 901d9eb8a8..8f966a5043 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6f4d6f212a3558c27be6e9dcf71cec43c424d445e5889c6e91dde84a19c5a2c1 \ No newline at end of file +4350983b37879d3280432d90fef04f5cc4be1b3110b5435123d897e31b34db8a \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 0c7447e8a8..7b13037d01 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3403,10 +3403,11 @@ case OP_MakeRecord: { } len = i = sqlite3SmallTypeSizes[serial_type]; assert( i>0 ); - do{ + while( 1 /*exit-by-break*/ ){ zPayload[--i] = (u8)(v&0xFF); + if( i==0 ) break; v >>= 8; - }while( i ); + } zPayload += len; } }else if( serial_type<0x80 ){ From d13527daedcf9871c80afd35a7a47a123116618e Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 2 Apr 2022 19:21:58 +0000 Subject: [PATCH 056/259] Ensure that a zero-blob does not cause in invocation of memcpy() with a zero length and a NULL source pointer. FossilOrigin-Name: 35441eb5e1447e01f2031837a4ede705bce34f87be27912278cc730abce6cf05 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 10 +++++++--- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index e0d4246e1f..e5d3e4dd51 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\sloop\soptimization\sin\sOP_MakeRecord. -D 2022-04-02T15:19:02.206 +C Ensure\sthat\sa\szero-blob\sdoes\snot\scause\sin\sinvocation\sof\smemcpy()\swith\sa\nzero\slength\sand\sa\sNULL\ssource\spointer. +D 2022-04-02T19:21:58.840 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -624,7 +624,7 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c 9dca2919060c79df77a9e2db6440461592f8230aa379102e45c3988604794fa1 +F src/vdbe.c 7154f67e5317d3e62a7582c0fc6922570f816f669646e135187190152619cb57 F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e F src/vdbeInt.h 106930790a7619bc6e851be698e6e35c6b2b2e9e66c2f464d597d6b75b919679 F src/vdbeapi.c 5c498998c99667f16cac2519f2fa439fe46acf99a332b0caa73637fc2ab35c22 @@ -1945,8 +1945,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 6f4d6f212a3558c27be6e9dcf71cec43c424d445e5889c6e91dde84a19c5a2c1 -R b4168a297f2f907dda7ae8fb734939e5 +P 4350983b37879d3280432d90fef04f5cc4be1b3110b5435123d897e31b34db8a +R 41e1f7708441585a94d754911a9cc8e1 U drh -Z a1b1f1e17a6d5742ec380e2ab7594ab3 +Z 0c7a0f0fdc1ef54b004e1c62fd235a57 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8f966a5043..3cf338d569 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4350983b37879d3280432d90fef04f5cc4be1b3110b5435123d897e31b34db8a \ No newline at end of file +35441eb5e1447e01f2031837a4ede705bce34f87be27912278cc730abce6cf05 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 7b13037d01..0092946d3f 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3412,14 +3412,18 @@ case OP_MakeRecord: { } }else if( serial_type<0x80 ){ *(zHdr++) = serial_type; - if( serial_type>=14 ){ + if( serial_type>=14 && pRec->n>0 ){ + assert( pRec->z!=0 ); memcpy(zPayload, pRec->z, pRec->n); zPayload += pRec->n; } }else{ zHdr += sqlite3PutVarint(zHdr, serial_type); - memcpy(zPayload, pRec->z, pRec->n); - zPayload += pRec->n; + if( pRec->n ){ + assert( pRec->z!=0 ); + memcpy(zPayload, pRec->z, pRec->n); + zPayload += pRec->n; + } } if( pRec==pLast ) break; pRec++; From 1f416db2926d5c41e04db2537f6343959b7bb09e Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 2 Apr 2022 20:08:48 +0000 Subject: [PATCH 057/259] Fix harmless compiler warnings. FossilOrigin-Name: 8a3a3486358d076c34e515ac92663a04f0c7ff10f405094cb5b6ada0d5f05cdc --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 2 +- src/vdbeInt.h | 7 ++++++- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index e5d3e4dd51..d8da92f2f3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sa\szero-blob\sdoes\snot\scause\sin\sinvocation\sof\smemcpy()\swith\sa\nzero\slength\sand\sa\sNULL\ssource\spointer. -D 2022-04-02T19:21:58.840 +C Fix\sharmless\scompiler\swarnings. +D 2022-04-02T20:08:48.365 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -624,9 +624,9 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c 7154f67e5317d3e62a7582c0fc6922570f816f669646e135187190152619cb57 +F src/vdbe.c dbe88250144988bf8481aa5c98714cb5f0ce355213dcc4a458a3d2062ccc54c6 F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e -F src/vdbeInt.h 106930790a7619bc6e851be698e6e35c6b2b2e9e66c2f464d597d6b75b919679 +F src/vdbeInt.h 88c11169ac35488764e6275017610ddbaaa0e51acd260ea61638f9ccce578d7c F src/vdbeapi.c 5c498998c99667f16cac2519f2fa439fe46acf99a332b0caa73637fc2ab35c22 F src/vdbeaux.c 7a9df2e5700351221a152775e05d0b4ce9aa73b0d04bcfabeb85ab2229052bac F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd @@ -1945,8 +1945,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 4350983b37879d3280432d90fef04f5cc4be1b3110b5435123d897e31b34db8a -R 41e1f7708441585a94d754911a9cc8e1 +P 35441eb5e1447e01f2031837a4ede705bce34f87be27912278cc730abce6cf05 +R 0de4cbf018f5e69209b41b7da65c596e U drh -Z 0c7a0f0fdc1ef54b004e1c62fd235a57 +Z ddceb08a72931a4b051462e72474673d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3cf338d569..d87692bdba 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -35441eb5e1447e01f2031837a4ede705bce34f87be27912278cc730abce6cf05 \ No newline at end of file +8a3a3486358d076c34e515ac92663a04f0c7ff10f405094cb5b6ada0d5f05cdc \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 0092946d3f..c66680220b 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3393,7 +3393,7 @@ case OP_MakeRecord: { /* NULL value. No change in zPayload */ }else{ u64 v; - u32 i, len; + u32 i; if( serial_type==7 ){ assert( sizeof(v)==sizeof(pRec->u.r) ); memcpy(&v, &pRec->u.r, sizeof(v)); diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 968500b322..4a80cf926b 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -532,7 +532,12 @@ struct ValueList { sqlite3_value *pOut; /* Register to hold each decoded output value */ }; -const u8 sqlite3SmallTypeSizes[128]; +/* Size of content associated with serial types that fit into a +** single-byte varint. +*/ +#ifndef SQLITE_AMALGAMATION +extern const u8 sqlite3SmallTypeSizes[]; +#endif /* ** Function prototypes From c2808f39d1b9f13d362a465ee3687022b51f6b40 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 2 Apr 2022 22:47:47 +0000 Subject: [PATCH 058/259] Expand the getVarint32() macro in a few places, as the C-compiler seems to be able to optimize better when that macro is expanded manually. FossilOrigin-Name: cd4fe34b98bf5ce26f3596c717edb73932f3b46ad6e9b4934d06b7b3c176a0d6 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 6 +++++- src/vdbeaux.c | 14 +++++++++++--- 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index d8da92f2f3..f05cad7f40 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings. -D 2022-04-02T20:08:48.365 +C Expand\sthe\sgetVarint32()\smacro\sin\sa\sfew\splaces,\sas\sthe\sC-compiler\sseems\sto\nbe\sable\sto\soptimize\sbetter\swhen\sthat\smacro\sis\sexpanded\smanually. +D 2022-04-02T22:47:47.656 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -624,11 +624,11 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c dbe88250144988bf8481aa5c98714cb5f0ce355213dcc4a458a3d2062ccc54c6 +F src/vdbe.c 52b9afb8df338c7a392332ecfe71c748817b72abfcc1bb90c61d10264aa6db53 F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e F src/vdbeInt.h 88c11169ac35488764e6275017610ddbaaa0e51acd260ea61638f9ccce578d7c F src/vdbeapi.c 5c498998c99667f16cac2519f2fa439fe46acf99a332b0caa73637fc2ab35c22 -F src/vdbeaux.c 7a9df2e5700351221a152775e05d0b4ce9aa73b0d04bcfabeb85ab2229052bac +F src/vdbeaux.c d928cca15c31da201e0198b10fe29ffc001a0d1dfcffdcee6c6acce2360f0053 F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 062cd58c54f887dc2eeb865686251c17237f791f0e6394e9c6f7a6f3c1a7e206 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 @@ -1945,8 +1945,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 35441eb5e1447e01f2031837a4ede705bce34f87be27912278cc730abce6cf05 -R 0de4cbf018f5e69209b41b7da65c596e +P 8a3a3486358d076c34e515ac92663a04f0c7ff10f405094cb5b6ada0d5f05cdc +R a6b1bae040909e67200132c66e5ed3d0 U drh -Z ddceb08a72931a4b051462e72474673d +Z b06751a34dfdacfa9d4b7d6e9de9abea # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d87692bdba..364727c8d1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8a3a3486358d076c34e515ac92663a04f0c7ff10f405094cb5b6ada0d5f05cdc \ No newline at end of file +cd4fe34b98bf5ce26f3596c717edb73932f3b46ad6e9b4934d06b7b3c176a0d6 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index c66680220b..bb23757d69 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2739,7 +2739,11 @@ op_column_restart: assert( pC->szRow<=65536 ); /* Maximum page size is 64KiB */ } pC->cacheStatus = p->cacheCtr; - pC->iHdrOffset = getVarint32(pC->aRow, aOffset[0]); + if( (aOffset[0] = pC->aRow[0])<0x80 ){ + pC->iHdrOffset = 1; + }else{ + pC->iHdrOffset = sqlite3GetVarint32(pC->aRow, aOffset); + } pC->nHdrParsed = 0; if( pC->szRow Date: Sun, 3 Apr 2022 10:42:06 +0000 Subject: [PATCH 059/259] Performance optimization and slight size reduction in the OP_Transaction opcode. FossilOrigin-Name: 7bee8c195f3fc27aaab13e493ad446a4f19201de3ac064ed6d8a3cbda7c69ee1 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 7 ++++--- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index f05cad7f40..01d4999df4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Expand\sthe\sgetVarint32()\smacro\sin\sa\sfew\splaces,\sas\sthe\sC-compiler\sseems\sto\nbe\sable\sto\soptimize\sbetter\swhen\sthat\smacro\sis\sexpanded\smanually. -D 2022-04-02T22:47:47.656 +C Performance\soptimization\sand\sslight\ssize\sreduction\sin\sthe\sOP_Transaction\nopcode. +D 2022-04-03T10:42:06.846 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -624,7 +624,7 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c 52b9afb8df338c7a392332ecfe71c748817b72abfcc1bb90c61d10264aa6db53 +F src/vdbe.c 17c49fe3d853ca458dbf681ea462f8095b4cab86beaca57be3483f8aa0394ca4 F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e F src/vdbeInt.h 88c11169ac35488764e6275017610ddbaaa0e51acd260ea61638f9ccce578d7c F src/vdbeapi.c 5c498998c99667f16cac2519f2fa439fe46acf99a332b0caa73637fc2ab35c22 @@ -1945,8 +1945,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 8a3a3486358d076c34e515ac92663a04f0c7ff10f405094cb5b6ada0d5f05cdc -R a6b1bae040909e67200132c66e5ed3d0 +P cd4fe34b98bf5ce26f3596c717edb73932f3b46ad6e9b4934d06b7b3c176a0d6 +R cceae0bcc38787bdf816e721690684a9 U drh -Z b06751a34dfdacfa9d4b7d6e9de9abea +Z 9618a426f045ebdd433022eacdc71e54 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 364727c8d1..9a3bb1ac23 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cd4fe34b98bf5ce26f3596c717edb73932f3b46ad6e9b4934d06b7b3c176a0d6 \ No newline at end of file +7bee8c195f3fc27aaab13e493ad446a4f19201de3ac064ed6d8a3cbda7c69ee1 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index bb23757d69..4c7a3a72c8 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3754,6 +3754,7 @@ case OP_AutoCommit: { */ case OP_Transaction: { Btree *pBt; + Db *pDb; int iMeta = 0; assert( p->bIsReader ); @@ -3773,7 +3774,8 @@ case OP_Transaction: { } goto abort_due_to_error; } - pBt = db->aDb[pOp->p1].pBt; + pDb = &db->aDb[pOp->p1]; + pBt = pDb->pBt; if( pBt ){ rc = sqlite3BtreeBeginTrans(pBt, pOp->p2, &iMeta); @@ -3814,8 +3816,7 @@ case OP_Transaction: { assert( pOp->p5==0 || pOp->p4type==P4_INT32 ); if( rc==SQLITE_OK && pOp->p5 - && (iMeta!=pOp->p3 - || db->aDb[pOp->p1].pSchema->iGeneration!=pOp->p4.i) + && (iMeta!=pOp->p3 || pDb->pSchema->iGeneration!=pOp->p4.i) ){ /* ** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema From 18bcfb999ace3a981a5069a4fe6a7814b5cc6fc3 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 3 Apr 2022 19:13:40 +0000 Subject: [PATCH 060/259] Omit the Vdbe.runOnlyOnce flag (simplifying the prepared statement implementation) and accomplish the same result by adding an "OP_Expire 1 1" opcode to prepared statements that would normally have runOnlyOnce set. FossilOrigin-Name: 6e20e1c46d17ac6aba21e02b57649af51cfa415d83d0c001b30677d2fd1f1dc1 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbeInt.h | 1 - src/vdbeaux.c | 11 ++++++++--- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 01d4999df4..f0f98c5b05 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimization\sand\sslight\ssize\sreduction\sin\sthe\sOP_Transaction\nopcode. -D 2022-04-03T10:42:06.846 +C Omit\sthe\sVdbe.runOnlyOnce\sflag\s(simplifying\sthe\sprepared\sstatement\nimplementation)\sand\saccomplish\sthe\ssame\sresult\sby\sadding\san\s"OP_Expire\s1\s1"\nopcode\sto\sprepared\sstatements\sthat\swould\snormally\shave\srunOnlyOnce\sset. +D 2022-04-03T19:13:40.130 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -626,9 +626,9 @@ F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 F src/vdbe.c 17c49fe3d853ca458dbf681ea462f8095b4cab86beaca57be3483f8aa0394ca4 F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e -F src/vdbeInt.h 88c11169ac35488764e6275017610ddbaaa0e51acd260ea61638f9ccce578d7c +F src/vdbeInt.h 5f3d0abcf30c2b7a6672ad4386f18be0fca9c9b2cefe18f85a2e3df74f2613bf F src/vdbeapi.c 5c498998c99667f16cac2519f2fa439fe46acf99a332b0caa73637fc2ab35c22 -F src/vdbeaux.c d928cca15c31da201e0198b10fe29ffc001a0d1dfcffdcee6c6acce2360f0053 +F src/vdbeaux.c 7769be4cff457f8d52732c7b1c7772100dace9cb8aff070c74cd6b956a1a94e2 F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 062cd58c54f887dc2eeb865686251c17237f791f0e6394e9c6f7a6f3c1a7e206 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 @@ -1945,8 +1945,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 cd4fe34b98bf5ce26f3596c717edb73932f3b46ad6e9b4934d06b7b3c176a0d6 -R cceae0bcc38787bdf816e721690684a9 +P 7bee8c195f3fc27aaab13e493ad446a4f19201de3ac064ed6d8a3cbda7c69ee1 +R 15ed6d8a2e61bcb1b52a461e4c596e08 U drh -Z 9618a426f045ebdd433022eacdc71e54 +Z c2f5051216c01ebf5c6b4028b126912b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9a3bb1ac23..25906a8e25 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7bee8c195f3fc27aaab13e493ad446a4f19201de3ac064ed6d8a3cbda7c69ee1 \ No newline at end of file +6e20e1c46d17ac6aba21e02b57649af51cfa415d83d0c001b30677d2fd1f1dc1 \ No newline at end of file diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 4a80cf926b..b07aee0c05 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -459,7 +459,6 @@ struct Vdbe { bft expired:2; /* 1: recompile VM immediately 2: when convenient */ bft explain:2; /* True if EXPLAIN present on SQL command */ bft changeCntOn:1; /* True to update the change-counter */ - bft runOnlyOnce:1; /* Automatically expire on reset */ bft usesStmtJournal:1; /* True if uses a statement journal */ bft readOnly:1; /* True for statements that do not write */ bft bIsReader:1; /* True for statements that read */ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 8fdd85abb8..a1908edf35 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -588,14 +588,20 @@ void sqlite3VdbeResolveLabel(Vdbe *v, int x){ ** Mark the VDBE as one that can only be run one time. */ void sqlite3VdbeRunOnlyOnce(Vdbe *p){ - p->runOnlyOnce = 1; + sqlite3VdbeAddOp2(p, OP_Expire, 1, 1); } /* ** Mark the VDBE as one that can only be run multiple times. */ void sqlite3VdbeReusable(Vdbe *p){ - p->runOnlyOnce = 0; + int i; + for(i=1; ALWAYS(inOp); i++){ + if( p->aOp[i].opcode==OP_Expire ){ + p->aOp[1].opcode = OP_Noop; + break; + } + } } #ifdef SQLITE_DEBUG /* sqlite3AssertMayAbort() logic */ @@ -3314,7 +3320,6 @@ int sqlite3VdbeReset(Vdbe *p){ }else{ db->errCode = p->rc; } - if( p->runOnlyOnce ) p->expired = 1; } /* Reset register contents and reclaim error message memory. From 8bb93daca0004d8c882fd7d46a4bdf2a5979ad88 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 3 Apr 2022 20:39:48 +0000 Subject: [PATCH 061/259] Performance optimization and size reduction in the OP_Halt opcode. FossilOrigin-Name: 21948e6e1ccd2ce128742415d21759604ecb8902226ec4707dbd75585450f208 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 5 ++--- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index f0f98c5b05..244b07b907 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Omit\sthe\sVdbe.runOnlyOnce\sflag\s(simplifying\sthe\sprepared\sstatement\nimplementation)\sand\saccomplish\sthe\ssame\sresult\sby\sadding\san\s"OP_Expire\s1\s1"\nopcode\sto\sprepared\sstatements\sthat\swould\snormally\shave\srunOnlyOnce\sset. -D 2022-04-03T19:13:40.130 +C Performance\soptimization\sand\ssize\sreduction\sin\sthe\sOP_Halt\sopcode. +D 2022-04-03T20:39:48.118 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -624,7 +624,7 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c 17c49fe3d853ca458dbf681ea462f8095b4cab86beaca57be3483f8aa0394ca4 +F src/vdbe.c 1d839d17db758a6c3a06cc2018880395f9b0f11ff81945d55cf90c4ae6c901c3 F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e F src/vdbeInt.h 5f3d0abcf30c2b7a6672ad4386f18be0fca9c9b2cefe18f85a2e3df74f2613bf F src/vdbeapi.c 5c498998c99667f16cac2519f2fa439fe46acf99a332b0caa73637fc2ab35c22 @@ -1945,8 +1945,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 7bee8c195f3fc27aaab13e493ad446a4f19201de3ac064ed6d8a3cbda7c69ee1 -R 15ed6d8a2e61bcb1b52a461e4c596e08 +P 6e20e1c46d17ac6aba21e02b57649af51cfa415d83d0c001b30677d2fd1f1dc1 +R d64478804f8f45705fcb95b743cf8c6f U drh -Z c2f5051216c01ebf5c6b4028b126912b +Z 82c6988106584643e5a2e0ab2496c5d2 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 25906a8e25..50c5b7148b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6e20e1c46d17ac6aba21e02b57649af51cfa415d83d0c001b30677d2fd1f1dc1 \ No newline at end of file +21948e6e1ccd2ce128742415d21759604ecb8902226ec4707dbd75585450f208 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 4c7a3a72c8..a4177ae2ea 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1129,11 +1129,10 @@ case OP_Halt: { VdbeFrame *pFrame; int pcx; - pcx = (int)(pOp - aOp); #ifdef SQLITE_DEBUG if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); } #endif - if( pOp->p1==SQLITE_OK && p->pFrame ){ + if( p->pFrame && pOp->p1==SQLITE_OK ){ /* Halt the sub-program. Return control to the parent frame. */ pFrame = p->pFrame; p->pFrame = pFrame->pParent; @@ -1155,7 +1154,6 @@ case OP_Halt: { } p->rc = pOp->p1; p->errorAction = (u8)pOp->p2; - p->pc = pcx; assert( pOp->p5<=4 ); if( p->rc ){ if( pOp->p5 ){ @@ -1172,6 +1170,7 @@ case OP_Halt: { }else{ sqlite3VdbeError(p, "%s", pOp->p4.z); } + pcx = (int)(pOp - aOp); sqlite3_log(pOp->p1, "abort at %d in [%s]: %s", pcx, p->zSql, p->zErrMsg); } rc = sqlite3VdbeHalt(p); From 8703edd3e9c10a687e1bf9f95901bca24c3a6881 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 3 Apr 2022 22:35:13 +0000 Subject: [PATCH 062/259] Performance optimization in the sqlite3VdbeHalt() routine. FossilOrigin-Name: 9564d72a0820dbcb38f905fcd42ed4c858ea8fb5f648b189ceb65380a14a785b --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 7 +++++-- src/vdbeaux.c | 6 ++---- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 244b07b907..6383d48064 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimization\sand\ssize\sreduction\sin\sthe\sOP_Halt\sopcode. -D 2022-04-03T20:39:48.118 +C Performance\soptimization\sin\sthe\ssqlite3VdbeHalt()\sroutine. +D 2022-04-03T22:35:13.221 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -624,11 +624,11 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c 1d839d17db758a6c3a06cc2018880395f9b0f11ff81945d55cf90c4ae6c901c3 +F src/vdbe.c b34327e7ea940885db12df0ae7f751b53106a4eb7047c9a2bfb7efe26e39fc62 F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e F src/vdbeInt.h 5f3d0abcf30c2b7a6672ad4386f18be0fca9c9b2cefe18f85a2e3df74f2613bf F src/vdbeapi.c 5c498998c99667f16cac2519f2fa439fe46acf99a332b0caa73637fc2ab35c22 -F src/vdbeaux.c 7769be4cff457f8d52732c7b1c7772100dace9cb8aff070c74cd6b956a1a94e2 +F src/vdbeaux.c 17ab5a927e22c0f8454e15b6fc03ca5be72e04fb1f455ce7fb10dc52d2153955 F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 062cd58c54f887dc2eeb865686251c17237f791f0e6394e9c6f7a6f3c1a7e206 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 @@ -1945,8 +1945,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 6e20e1c46d17ac6aba21e02b57649af51cfa415d83d0c001b30677d2fd1f1dc1 -R d64478804f8f45705fcb95b743cf8c6f +P 21948e6e1ccd2ce128742415d21759604ecb8902226ec4707dbd75585450f208 +R 4745fb554ab36f43731027bbab700d2d U drh -Z 82c6988106584643e5a2e0ab2496c5d2 +Z 869d9bdd409ceb08c178610bb5fbeb99 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 50c5b7148b..eea4d469a2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -21948e6e1ccd2ce128742415d21759604ecb8902226ec4707dbd75585450f208 \ No newline at end of file +9564d72a0820dbcb38f905fcd42ed4c858ea8fb5f648b189ceb65380a14a785b \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index a4177ae2ea..3f7dd44478 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -3649,7 +3649,10 @@ case OP_Savepoint: { } } if( rc ) goto abort_due_to_error; - + if( p->eVdbeState==VDBE_HALT_STATE ){ + rc = SQLITE_DONE; + goto vdbe_return; + } break; } @@ -8602,7 +8605,7 @@ abort_due_to_error: testcase( sqlite3GlobalConfig.xLog!=0 ); sqlite3_log(rc, "statement aborts at %d: [%s] %s", (int)(pOp - aOp), p->zSql, p->zErrMsg); - sqlite3VdbeHalt(p); + if( p->eVdbeState==VDBE_RUN_STATE ) sqlite3VdbeHalt(p); if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db); if( rc==SQLITE_CORRUPT && db->autoCommit==0 ){ db->flags |= SQLITE_CorruptRdOnly; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index a1908edf35..6e6e240cd5 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3044,9 +3044,7 @@ int sqlite3VdbeHalt(Vdbe *p){ ** one, or the complete transaction if there is no statement transaction. */ - if( p->eVdbeState!=VDBE_RUN_STATE ){ - return SQLITE_OK; - } + assert( p->eVdbeState==VDBE_RUN_STATE ); if( db->mallocFailed ){ p->rc = SQLITE_NOMEM_BKPT; } @@ -3306,7 +3304,7 @@ int sqlite3VdbeReset(Vdbe *p){ ** error, then it might not have been halted properly. So halt ** it now. */ - sqlite3VdbeHalt(p); + if( p->eVdbeState==VDBE_RUN_STATE ) sqlite3VdbeHalt(p); /* If the VDBE has been run even partially, then transfer the error code ** and error message from the VDBE into the main database structure. But From 1c8486301f53137c73b19b83f1cb0def51f198ab Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 4 Apr 2022 01:12:11 +0000 Subject: [PATCH 063/259] Only invoke sqlite3VdbeClearObject() from a single location, so that the compiler is more likely to in-line the code. Performance increase and size reduction. FossilOrigin-Name: c6947a96e61f71aa61ca3d70d9e2612d784ab04d60fa88852b03cfce86b1bf2b --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/status.c | 3 +-- src/vdbe.h | 1 - src/vdbeapi.c | 3 +-- src/vdbeaux.c | 20 +++++++++++--------- 6 files changed, 23 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index 6383d48064..bf99d99766 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimization\sin\sthe\ssqlite3VdbeHalt()\sroutine. -D 2022-04-03T22:35:13.221 +C Only\sinvoke\ssqlite3VdbeClearObject()\sfrom\sa\ssingle\slocation,\sso\sthat\sthe\ncompiler\sis\smore\slikely\sto\sin-line\sthe\scode.\s\sPerformance\sincrease\sand\nsize\sreduction. +D 2022-04-04T01:12:11.426 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -559,7 +559,7 @@ F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e F src/sqliteInt.h 5a7867196379868a3f91c8ae172209622de2b5fabf7a5e20aa021ec44174eead F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 -F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 +F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 F src/tclsqlite.c 1f6673991147bc2cecc08a40d22f9803b84c805b24b499fe727f392256f73474 F src/test1.c 87fda59eea3ac1eba1baef37c1967565cb1b8d6d264649f2e57f252ca5989914 @@ -625,10 +625,10 @@ F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 F src/vdbe.c b34327e7ea940885db12df0ae7f751b53106a4eb7047c9a2bfb7efe26e39fc62 -F src/vdbe.h a1d0e3b934e835e73edd146f2e7c4eadb711b5c9875c18159a57483fd78e550e +F src/vdbe.h 89f5edb1422c8783a0b29db836e409876f2b3e847f78e2b21b1fbcc48a93f85f F src/vdbeInt.h 5f3d0abcf30c2b7a6672ad4386f18be0fca9c9b2cefe18f85a2e3df74f2613bf -F src/vdbeapi.c 5c498998c99667f16cac2519f2fa439fe46acf99a332b0caa73637fc2ab35c22 -F src/vdbeaux.c 17ab5a927e22c0f8454e15b6fc03ca5be72e04fb1f455ce7fb10dc52d2153955 +F src/vdbeapi.c 354c893f1500cf524cc45c32879b9c68893a28b77e3442c24668d6afe4236217 +F src/vdbeaux.c 19cd7117723ef31ca31ffffb12cd0298c1b24e4a7b2d920c19f1615bb0023b6d F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 062cd58c54f887dc2eeb865686251c17237f791f0e6394e9c6f7a6f3c1a7e206 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 @@ -1945,8 +1945,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 21948e6e1ccd2ce128742415d21759604ecb8902226ec4707dbd75585450f208 -R 4745fb554ab36f43731027bbab700d2d +P 9564d72a0820dbcb38f905fcd42ed4c858ea8fb5f648b189ceb65380a14a785b +R dab150b94935a23a5a1bd7213e910e23 U drh -Z 869d9bdd409ceb08c178610bb5fbeb99 +Z 70183e42a4b74b2de8511fa6905065a2 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index eea4d469a2..22bd606275 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9564d72a0820dbcb38f905fcd42ed4c858ea8fb5f648b189ceb65380a14a785b \ No newline at end of file +c6947a96e61f71aa61ca3d70d9e2612d784ab04d60fa88852b03cfce86b1bf2b \ No newline at end of file diff --git a/src/status.c b/src/status.c index f0e307c2dd..e7f2158446 100644 --- a/src/status.c +++ b/src/status.c @@ -334,8 +334,7 @@ int sqlite3_db_status( db->pnBytesFreed = &nByte; for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){ - sqlite3VdbeClearObject(db, pVdbe); - sqlite3DbFree(db, pVdbe); + sqlite3VdbeDelete(pVdbe); } db->pnBytesFreed = 0; diff --git a/src/vdbe.h b/src/vdbe.h index fb383e3ed2..e251dd666e 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -244,7 +244,6 @@ int sqlite3VdbeMakeLabel(Parse*); void sqlite3VdbeRunOnlyOnce(Vdbe*); void sqlite3VdbeReusable(Vdbe*); void sqlite3VdbeDelete(Vdbe*); -void sqlite3VdbeClearObject(sqlite3*,Vdbe*); void sqlite3VdbeMakeReady(Vdbe*,Parse*); int sqlite3VdbeFinalize(Vdbe*); void sqlite3VdbeResolveLabel(Vdbe*, int); diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 9a5d01682a..39d73288ce 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -1835,8 +1835,7 @@ int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){ sqlite3_mutex_enter(db->mutex); v = 0; db->pnBytesFreed = (int*)&v; - sqlite3VdbeClearObject(db, pVdbe); - sqlite3DbFree(db, pVdbe); + sqlite3VdbeDelete(pVdbe); db->pnBytesFreed = 0; sqlite3_mutex_leave(db->mutex); }else{ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 6e6e240cd5..d9a5236f32 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3438,7 +3438,7 @@ void sqlite3VdbeDeleteAuxData(sqlite3 *db, AuxData **pp, int iOp, int mask){ ** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with ** the database connection and frees the object itself. */ -void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ +static void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ SubProgram *pSub, *pNext; assert( p->db==0 || p->db==db ); if( p->aColName ){ @@ -3488,14 +3488,16 @@ void sqlite3VdbeDelete(Vdbe *p){ db = p->db; assert( sqlite3_mutex_held(db->mutex) ); sqlite3VdbeClearObject(db, p); - if( p->pPrev ){ - p->pPrev->pNext = p->pNext; - }else{ - assert( db->pVdbe==p ); - db->pVdbe = p->pNext; - } - if( p->pNext ){ - p->pNext->pPrev = p->pPrev; + if( db->pnBytesFreed==0 ){ + if( p->pPrev ){ + p->pPrev->pNext = p->pNext; + }else{ + assert( db->pVdbe==p ); + db->pVdbe = p->pNext; + } + if( p->pNext ){ + p->pNext->pPrev = p->pPrev; + } } sqlite3DbFreeNN(db, p); } From a81a9f78fdb1b017c341c54d4602c1dee75c1a23 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 4 Apr 2022 11:38:49 +0000 Subject: [PATCH 064/259] Performance optimization and stronger assert()s in the comparison opcodes. FossilOrigin-Name: e0305e640b9078c7eed9ab0bcc14f4515b54e7cd9ade3306bc2d1660f05b2725 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 19 ++++++++++++------- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index bf99d99766..225a47a011 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Only\sinvoke\ssqlite3VdbeClearObject()\sfrom\sa\ssingle\slocation,\sso\sthat\sthe\ncompiler\sis\smore\slikely\sto\sin-line\sthe\scode.\s\sPerformance\sincrease\sand\nsize\sreduction. -D 2022-04-04T01:12:11.426 +C Performance\soptimization\sand\sstronger\sassert()s\sin\sthe\scomparison\sopcodes. +D 2022-04-04T11:38:49.588 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -624,7 +624,7 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c b34327e7ea940885db12df0ae7f751b53106a4eb7047c9a2bfb7efe26e39fc62 +F src/vdbe.c c6e546c9d1ade8e253f54476263d669b2f9af2f57c9de113b1a1096575cfa36e F src/vdbe.h 89f5edb1422c8783a0b29db836e409876f2b3e847f78e2b21b1fbcc48a93f85f F src/vdbeInt.h 5f3d0abcf30c2b7a6672ad4386f18be0fca9c9b2cefe18f85a2e3df74f2613bf F src/vdbeapi.c 354c893f1500cf524cc45c32879b9c68893a28b77e3442c24668d6afe4236217 @@ -1945,8 +1945,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 9564d72a0820dbcb38f905fcd42ed4c858ea8fb5f648b189ceb65380a14a785b -R dab150b94935a23a5a1bd7213e910e23 +P c6947a96e61f71aa61ca3d70d9e2612d784ab04d60fa88852b03cfce86b1bf2b +R d512c70bc3a60e0984463bf1a9685f54 U drh -Z 70183e42a4b74b2de8511fa6905065a2 +Z 355946a7b8f5d0c9dd9f26b391a9102c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 22bd606275..e6b956b6cf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c6947a96e61f71aa61ca3d70d9e2612d784ab04d60fa88852b03cfce86b1bf2b \ No newline at end of file +e0305e640b9078c7eed9ab0bcc14f4515b54e7cd9ade3306bc2d1660f05b2725 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 3f7dd44478..e7343e8207 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2087,23 +2087,23 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ assert( (pOp->p5 & SQLITE_AFF_MASK)!=SQLITE_AFF_TEXT || CORRUPT_DB ); /* Common case of comparison of two integers */ if( pIn3->u.i > pIn1->u.i ){ - iCompare = +1; if( sqlite3aGTb[pOp->opcode] ){ VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3); goto jump_to_p2; } + iCompare = +1; }else if( pIn3->u.i < pIn1->u.i ){ - iCompare = -1; if( sqlite3aLTb[pOp->opcode] ){ VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3); goto jump_to_p2; } + iCompare = -1; }else{ - iCompare = 0; if( sqlite3aEQb[pOp->opcode] ){ VdbeBranchTaken(1, (pOp->p5 & SQLITE_NULLEQ)?2:3); goto jump_to_p2; } + iCompare = 0; } VdbeBranchTaken(0, (pOp->p5 & SQLITE_NULLEQ)?2:3); break; @@ -2130,11 +2130,11 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ ** then the result is always NULL. ** The jump is taken if the SQLITE_JUMPIFNULL bit is set. */ - iCompare = 1; /* Operands are not equal */ VdbeBranchTaken(2,3); if( pOp->p5 & SQLITE_JUMPIFNULL ){ goto jump_to_p2; } + iCompare = 1; /* Operands are not equal */ break; } }else{ @@ -2240,9 +2240,8 @@ case OP_ElseEq: { /* same as TK_ESCAPE, jump */ ** Set the permutation used by the OP_Compare operator in the next ** instruction. The permutation is stored in the P4 operand. ** -** The permutation is only valid until the next OP_Compare that has -** the OPFLAG_PERMUTE bit set in P5. Typically the OP_Permutation should -** occur immediately prior to the OP_Compare. +** The permutation is only valid for the next opcode which must be +** an OP_Compare that has the OPFLAG_PERMUTE bit set in P5. ** ** The first integer in the P4 integer array is the length of the array ** and does not become part of the permutation. @@ -2274,6 +2273,8 @@ case OP_Permutation: { ** The comparison is a sort comparison, so NULLs compare equal, ** NULLs are less than numbers, numbers are less than strings, ** and strings are less than blobs. +** +** This opcode must be immediately followed by an OP_Jump opcode. */ case OP_Compare: { int n; @@ -2332,6 +2333,7 @@ case OP_Compare: { break; } } + assert( pOp[1].opcode==OP_Jump ); break; } @@ -2340,8 +2342,11 @@ case OP_Compare: { ** Jump to the instruction at address P1, P2, or P3 depending on whether ** in the most recent OP_Compare instruction the P1 vector was less than ** equal to, or greater than the P2 vector, respectively. +** +** This opcode must immediately follow an OP_Compare opcode. */ case OP_Jump: { /* jump */ + assert( pOp>aOp && pOp[-1].opcode==OP_Compare ); if( iCompare<0 ){ VdbeBranchTaken(0,4); pOp = &aOp[pOp->p1 - 1]; }else if( iCompare==0 ){ From b07fb4f1c27609c40b8d1d417f9c8db3e5f7f402 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 4 Apr 2022 14:24:14 +0000 Subject: [PATCH 065/259] Fix the JSON Path parser so that it will accept zero-length object labels. [forum/forumpost/c082aeab43|Forum thread c082aeab43]. FossilOrigin-Name: 84fe95d2a5b4d232d657e3b8110027a698a9bcd597f205cc535cfa97bc299f21 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/json.c | 9 +++++---- test/json101.test | 17 +++++++++++++++++ 4 files changed, 30 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 225a47a011..e988ff78ef 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Performance\soptimization\sand\sstronger\sassert()s\sin\sthe\scomparison\sopcodes. -D 2022-04-04T11:38:49.588 +C Fix\sthe\sJSON\sPath\sparser\sso\sthat\sit\swill\saccept\szero-length\sobject\slabels.\n[forum/forumpost/c082aeab43|Forum\sthread\sc082aeab43]. +D 2022-04-04T14:24:14.310 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -513,7 +513,7 @@ F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51 F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c c4fc48e6f38cc415262652407949771ce4e6f8f0c7330f872e44a0677f3ad602 -F src/json.c 24fcd7f5f9080b04b89722c343010d390f85e55b2ab560046cb567c9dd640f62 +F src/json.c 37d4b68b52440653e9a8ffab13e9d5c282f01d4d6c1ba763aaa36c72671d9988 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 2ecb1441f9b1c22e9e022ee0776e67d259facf34b56ba892b206f0a294ee6f8c F src/main.c 89dfd569b4fbcab65281b3c6d636b887b2cb23cbaa16f8c6b67062862144c927 @@ -1152,7 +1152,7 @@ F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ff F test/jrnlmode.test 9b5bc01dac22223cb60ec2d5f97acf568d73820794386de5634dcadbea9e1946 F test/jrnlmode2.test 8759a1d4657c064637f8b079592651530db738419e1d649c6df7048cd724363d F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa -F test/json101.test d7c84854acafaf80f883e183ac4248ea2742615086c94a61a46ad7d7382ce123 +F test/json101.test 9d46b8e254c4e23306da175dd226d5c4f164db6b294bcea98e5dcd891ba48c91 F test/json102.test 327e77275f338c028faefa2da5164daf6b142a165e3015ff2a6e4251ddc6a0ac F test/json103.test 53df87f83a4e5fa0c0a56eb29ff6c94055c6eb919f33316d62161a8880112dbe F test/json104.test a502dc01853aada95d721b3b275afbe2dc18fffdac1fea6e96fb20c13586bbb5 @@ -1945,8 +1945,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 c6947a96e61f71aa61ca3d70d9e2612d784ab04d60fa88852b03cfce86b1bf2b -R d512c70bc3a60e0984463bf1a9685f54 +P e0305e640b9078c7eed9ab0bcc14f4515b54e7cd9ade3306bc2d1660f05b2725 +R b7b1f674d3bb83fa7d01b3c971c6fb98 U drh -Z 355946a7b8f5d0c9dd9f26b391a9102c +Z 9f0444d3701a4ee2277aeb80cbb65f96 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e6b956b6cf..e4dd017579 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e0305e640b9078c7eed9ab0bcc14f4515b54e7cd9ade3306bc2d1660f05b2725 \ No newline at end of file +84fe95d2a5b4d232d657e3b8110027a698a9bcd597f205cc535cfa97bc299f21 \ No newline at end of file diff --git a/src/json.c b/src/json.c index 243afd5dd4..81111fff15 100644 --- a/src/json.c +++ b/src/json.c @@ -1119,14 +1119,15 @@ static JsonNode *jsonLookupStep( *pzErr = zPath; return 0; } + testcase( nKey==0 ); }else{ zKey = zPath; for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){} nKey = i; - } - if( nKey==0 ){ - *pzErr = zPath; - return 0; + if( nKey==0 ){ + *pzErr = zPath; + return 0; + } } j = 1; for(;;){ diff --git a/test/json101.test b/test/json101.test index 1845279179..b84846d888 100644 --- a/test/json101.test +++ b/test/json101.test @@ -850,4 +850,21 @@ do_execsql_test json-17.1 { SELECT * FROM t1 LEFT JOIN t2 ON (SELECT b FROM json_each ORDER BY 1); } {} +# 2022-04-04 forum post https://sqlite.org/forum/forumpost/c082aeab43 +do_execsql_test json-18.1 { + SELECT json_valid('{"":5}'); +} {1} +do_execsql_test json-18.2 { + SELECT json_extract('{"":5}', '$.""'); +} {5} +do_execsql_test json-18.3 { + SELECT json_extract('[3,{"a":4,"":[5,{"hi":6},7]},8]', '$[1].""[1].hi'); +} {6} +do_execsql_test json-18.4 { + SELECT json_extract('[3,{"a":4,"":[5,{"hi":6},7]},8]', '$[1].""[1]."hi"'); +} {6} +do_catchsql_test json-18.5 { + SELECT json_extract('{"":8}', '$.'); +} {1 {JSON path error near ''}} + finish_test From 0de10ac11cb9f5e0e1bed4c56c20b118a20dae3a Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 4 Apr 2022 15:15:45 +0000 Subject: [PATCH 066/259] When constructing the JSON Path for the "fullpath" column of the json_tree() and json_each() table-valued functions, be sure to quote object labels where necessary. FossilOrigin-Name: 0fbbe7881cadf0b3c211653c7a0797e0a90c7c24da78ecc8a27140c05f89f2ed --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/json.c | 35 +++++++++++++++++++++++++++++------ 3 files changed, 36 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index e988ff78ef..1195949c62 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sJSON\sPath\sparser\sso\sthat\sit\swill\saccept\szero-length\sobject\slabels.\n[forum/forumpost/c082aeab43|Forum\sthread\sc082aeab43]. -D 2022-04-04T14:24:14.310 +C When\sconstructing\sthe\sJSON\sPath\sfor\sthe\s"fullpath"\scolumn\sof\sthe\njson_tree()\sand\sjson_each()\stable-valued\sfunctions,\sbe\ssure\sto\squote\nobject\slabels\swhere\snecessary. +D 2022-04-04T15:15:45.616 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -513,7 +513,7 @@ F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51 F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c c4fc48e6f38cc415262652407949771ce4e6f8f0c7330f872e44a0677f3ad602 -F src/json.c 37d4b68b52440653e9a8ffab13e9d5c282f01d4d6c1ba763aaa36c72671d9988 +F src/json.c 7749b98c62f691697c7ee536b570c744c0583cab4a89200fdd0fc2aa8cc8cbd6 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 2ecb1441f9b1c22e9e022ee0776e67d259facf34b56ba892b206f0a294ee6f8c F src/main.c 89dfd569b4fbcab65281b3c6d636b887b2cb23cbaa16f8c6b67062862144c927 @@ -1945,8 +1945,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 e0305e640b9078c7eed9ab0bcc14f4515b54e7cd9ade3306bc2d1660f05b2725 -R b7b1f674d3bb83fa7d01b3c971c6fb98 +P 84fe95d2a5b4d232d657e3b8110027a698a9bcd597f205cc535cfa97bc299f21 +R 970c08a76dac53f29009856eb6ab9f31 U drh -Z 9f0444d3701a4ee2277aeb80cbb65f96 +Z feea099ba66960be6a93d634e84b651a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e4dd017579..308ea25f3a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -84fe95d2a5b4d232d657e3b8110027a698a9bcd597f205cc535cfa97bc299f21 \ No newline at end of file +0fbbe7881cadf0b3c211653c7a0797e0a90c7c24da78ecc8a27140c05f89f2ed \ No newline at end of file diff --git a/src/json.c b/src/json.c index 81111fff15..3636d36655 100644 --- a/src/json.c +++ b/src/json.c @@ -2275,6 +2275,33 @@ static int jsonEachNext(sqlite3_vtab_cursor *cur){ return SQLITE_OK; } +/* Append an object label to the JSON Path being constructed +** in pStr. +*/ +static void jsonAppendObjectPathElement( + JsonString *pStr, + JsonNode *pNode +){ + int jj, nn; + const char *z; + assert( pNode->eType==JSON_STRING ); + assert( pNode->jnFlags & JNODE_LABEL ); + assert( pNode->eU==1 ); + z = pNode->u.zJContent; + nn = pNode->n; + assert( nn>=2 ); + assert( z[0]=='"' ); + assert( z[nn-1]=='"' ); + if( nn>2 && sqlite3Isalpha(z[1]) ){ + for(jj=2; jjeType==JSON_OBJECT ); if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--; - assert( pNode->eType==JSON_STRING ); - assert( pNode->jnFlags & JNODE_LABEL ); - assert( pNode->eU==1 ); - jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1); + jsonAppendObjectPathElement(pStr, pNode); } } @@ -2373,8 +2397,7 @@ static int jsonEachColumn( if( p->eType==JSON_ARRAY ){ jsonPrintf(30, &x, "[%d]", p->iRowid); }else if( p->eType==JSON_OBJECT ){ - assert( pThis->eU==1 ); - jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1); + jsonAppendObjectPathElement(&x, pThis); } } jsonResult(&x); From 36d2d09023b68299e27528cda0e74071a670ffef Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 4 Apr 2022 18:17:59 +0000 Subject: [PATCH 067/259] Use unpacked keys for OP_Found in foreign key processing. FossilOrigin-Name: 328dc76657eb5317f0201859d2b3abe6918103b894f7beaed0aca3058a9f2b64 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/fkey.c | 10 ++++------ src/pragma.c | 6 ++---- 4 files changed, 14 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 1195949c62..6c7b5741fe 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sconstructing\sthe\sJSON\sPath\sfor\sthe\s"fullpath"\scolumn\sof\sthe\njson_tree()\sand\sjson_each()\stable-valued\sfunctions,\sbe\ssure\sto\squote\nobject\slabels\swhere\snecessary. -D 2022-04-04T15:15:45.616 +C Use\sunpacked\skeys\sfor\sOP_Found\sin\sforeign\skey\sprocessing. +D 2022-04-04T18:17:59.858 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -505,7 +505,7 @@ F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d F src/delete.c b5f1716b4d723db48254ee0f896e362cd029e865e05414139ea7f539f3884e1d F src/expr.c 3cdb00b6c15f815c94836e7b4474b675155d1279e64804f6ab5816188a9b05b6 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 -F src/fkey.c 06e4ac33031b02dde7130c12e79cddf4dc5cfa72b23d8e63a3c26878fc9c1d3c +F src/fkey.c 94927f9b46d72a9cb858c208febf04ceb0a3270c5fa5fd0b7f436cf16e09f72a F src/func.c a3407a6fbb0d4088d8d502e46f0ace63e0aeae7467ae23a9ca9815bbf9239761 F src/global.c 75deb064a71e1db60c8972a660a84f4e6d805c8f0463299a18e30ea527f4a650 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 @@ -545,7 +545,7 @@ F src/parse.y 0f02b27cdaa334441463153fff3ceb780fea006ab53ffd6ef566d4468f93e924 F src/pcache.c 084e638432c610f95aea72b8509f0845d2791293f39d1b82f0c0a7e089c3bb6b F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 54881292a9a5db202b2c0ac541c5e3ef9a5e8c4f1c1383adb2601d5499a60e65 -F src/pragma.c a29c54aa5230819ab34293e3563836318dc8b87f5aeb68ca64f9734011a8b00e +F src/pragma.c d1aead03e8418ff586c7cfca344c50a914b8eb06abd841e8e91a982d823671da F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c fd940149c691684e7c1073c3787a7170e44852b02d1275d2e30a5b58e89cfcaf F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 @@ -1945,8 +1945,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 84fe95d2a5b4d232d657e3b8110027a698a9bcd597f205cc535cfa97bc299f21 -R 970c08a76dac53f29009856eb6ab9f31 +P 0fbbe7881cadf0b3c211653c7a0797e0a90c7c24da78ecc8a27140c05f89f2ed +R 98b3d21b59eb71e092a0c493cf5ae5c8 U drh -Z feea099ba66960be6a93d634e84b651a +Z fe844f2684caa7d8abe26eb99432eaf4 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 308ea25f3a..a2be004566 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0fbbe7881cadf0b3c211653c7a0797e0a90c7c24da78ecc8a27140c05f89f2ed \ No newline at end of file +328dc76657eb5317f0201859d2b3abe6918103b894f7beaed0aca3058a9f2b64 \ No newline at end of file diff --git a/src/fkey.c b/src/fkey.c index b464743c78..bae9b11ac3 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -390,7 +390,6 @@ static void fkLookupParent( }else{ int nCol = pFKey->nCol; int regTemp = sqlite3GetTempRange(pParse, nCol); - int regRec = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb); sqlite3VdbeSetP4KeyInfo(pParse, pIdx); @@ -429,12 +428,11 @@ static void fkLookupParent( } sqlite3VdbeGoto(v, iOk); } - - sqlite3VdbeAddOp4(v, OP_MakeRecord, regTemp, nCol, regRec, + + sqlite3VdbeAddOp4(v, OP_Affinity, regTemp, nCol, 0, sqlite3IndexAffinityStr(pParse->db,pIdx), nCol); - sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0); VdbeCoverage(v); - - sqlite3ReleaseTempReg(pParse, regRec); + sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regTemp, nCol); + VdbeCoverage(v); sqlite3ReleaseTempRange(pParse, regTemp, nCol); } } diff --git a/src/pragma.c b/src/pragma.c index f4908813cc..9860da86d7 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1496,7 +1496,6 @@ void sqlite3Pragma( HashElem *k; /* Loop counter: Next table in schema */ int x; /* result variable */ int regResult; /* 3 registers to hold a result row */ - int regKey; /* Register to hold key for checking the FK */ int regRow; /* Registers to hold a row from pTab */ int addrTop; /* Top of a loop checking foreign keys */ int addrOk; /* Jump here if the key is OK */ @@ -1504,7 +1503,6 @@ void sqlite3Pragma( regResult = pParse->nMem+1; pParse->nMem += 4; - regKey = ++pParse->nMem; regRow = ++pParse->nMem; k = sqliteHashFirst(&db->aDb[iDb].pSchema->tblHash); while( k ){ @@ -1571,9 +1569,9 @@ void sqlite3Pragma( /* Generate code to query the parent index for a matching parent ** key. If a match is found, jump to addrOk. */ if( pIdx ){ - sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey, + sqlite3VdbeAddOp4(v, OP_Affinity, regRow, pFK->nCol, 0, sqlite3IndexAffinityStr(db,pIdx), pFK->nCol); - sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0); + sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regRow, pFK->nCol); VdbeCoverage(v); }else if( pParent ){ int jmp = sqlite3VdbeCurrentAddr(v)+2; From b834e0de59d5e37b0d90e1a13298e0ebb7b45e6d Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 4 Apr 2022 19:43:57 +0000 Subject: [PATCH 068/259] Optimizations to the OP_Found opcode save about 600K cycles in speedtest1. FossilOrigin-Name: 5c3357ad62843fe982b9c2d31dbf02018f2948ceab2c85dac917cd9ce1e97dd6 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 53 ++++++++++++++++++++++++++++----------------------- 3 files changed, 36 insertions(+), 31 deletions(-) diff --git a/manifest b/manifest index 6c7b5741fe..911821ee8f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Use\sunpacked\skeys\sfor\sOP_Found\sin\sforeign\skey\sprocessing. -D 2022-04-04T18:17:59.858 +C Optimizations\sto\sthe\sOP_Found\sopcode\ssave\sabout\s600K\scycles\sin\sspeedtest1. +D 2022-04-04T19:43:57.944 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -624,7 +624,7 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c c6e546c9d1ade8e253f54476263d669b2f9af2f57c9de113b1a1096575cfa36e +F src/vdbe.c 61ff67a29b89214c928631be206af9cb5f820ed46b8cec3e58308fea205123e4 F src/vdbe.h 89f5edb1422c8783a0b29db836e409876f2b3e847f78e2b21b1fbcc48a93f85f F src/vdbeInt.h 5f3d0abcf30c2b7a6672ad4386f18be0fca9c9b2cefe18f85a2e3df74f2613bf F src/vdbeapi.c 354c893f1500cf524cc45c32879b9c68893a28b77e3442c24668d6afe4236217 @@ -1945,8 +1945,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 0fbbe7881cadf0b3c211653c7a0797e0a90c7c24da78ecc8a27140c05f89f2ed -R 98b3d21b59eb71e092a0c493cf5ae5c8 +P 328dc76657eb5317f0201859d2b3abe6918103b894f7beaed0aca3058a9f2b64 +R ac8b3e120e5046f4e8f53f05766d7e6a U drh -Z fe844f2684caa7d8abe26eb99432eaf4 +Z 8545e3f2f52a7362bf82a3c0cf610720 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a2be004566..a05f745f93 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -328dc76657eb5317f0201859d2b3abe6918103b894f7beaed0aca3058a9f2b64 \ No newline at end of file +5c3357ad62843fe982b9c2d31dbf02018f2948ceab2c85dac917cd9ce1e97dd6 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index e7343e8207..c29198f747 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4966,11 +4966,9 @@ case OP_NoConflict: /* jump, in3 */ case OP_NotFound: /* jump, in3 */ case OP_Found: { /* jump, in3 */ int alreadyExists; - int takeJump; int ii; VdbeCursor *pC; int res; - UnpackedRecord *pFree; UnpackedRecord *pIdxKey; UnpackedRecord r; @@ -4990,9 +4988,11 @@ case OP_Found: { /* jump, in3 */ assert( pC->uc.pCursor!=0 ); assert( pC->isTable==0 ); if( pOp->p4.i>0 ){ - r.pKeyInfo = pC->pKeyInfo; + /* Key values in an array of registers */ r.nField = (u16)pOp->p4.i; + r.pKeyInfo = pC->pKeyInfo; r.aMem = pIn3; + r.default_rc = 0; #ifdef SQLITE_DEBUG for(ii=0; iip3+ii, &r.aMem[ii]); } #endif - pIdxKey = &r; - pFree = 0; + rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, &r, &res); }else{ + /* Composite key generated by OP_MakeRecord */ assert( pIn3->flags & MEM_Blob ); + assert( pOp->opcode!=OP_NoConflict ); rc = ExpandBlob(pIn3); assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); if( rc ) goto no_mem; - pFree = pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo); + pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo); if( pIdxKey==0 ) goto no_mem; sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey); + pIdxKey->default_rc = 0; + rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, pIdxKey, &res); + sqlite3DbFreeNN(db, pIdxKey); } - pIdxKey->default_rc = 0; - takeJump = 0; - if( pOp->opcode==OP_NoConflict ){ - /* For the OP_NoConflict opcode, take the jump if any of the - ** input fields are NULL, since any key with a NULL will not - ** conflict */ - for(ii=0; iinField; ii++){ - if( pIdxKey->aMem[ii].flags & MEM_Null ){ - takeJump = 1; - break; - } - } - } - rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, pIdxKey, &res); - if( pFree ) sqlite3DbFreeNN(db, pFree); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } @@ -5038,9 +5027,25 @@ case OP_Found: { /* jump, in3 */ VdbeBranchTaken(alreadyExists!=0,2); if( alreadyExists ) goto jump_to_p2; }else{ - VdbeBranchTaken(takeJump||alreadyExists==0,2); - if( takeJump || !alreadyExists ) goto jump_to_p2; - if( pOp->opcode==OP_IfNoHope ) pC->seekHit = pOp->p4.i; + if( !alreadyExists ){ + VdbeBranchTaken(1,2); + goto jump_to_p2; + } + if( pOp->opcode==OP_NoConflict ){ + /* For the OP_NoConflict opcode, take the jump if any of the + ** input fields are NULL, since any key with a NULL will not + ** conflict */ + for(ii=0; iiopcode==OP_IfNoHope ){ + pC->seekHit = pOp->p4.i; + } } break; } From 50f22d17a826c6141a17258ac15d98aefe445195 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 4 Apr 2022 19:58:55 +0000 Subject: [PATCH 069/259] Tag an always-taken branch using ALWAYS(). FossilOrigin-Name: ad8bc3d7443ff57ce5a8756428e717ac42ec0295191a9b4d7ae44846d8fa03a2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 911821ee8f..24a5d04278 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Optimizations\sto\sthe\sOP_Found\sopcode\ssave\sabout\s600K\scycles\sin\sspeedtest1. -D 2022-04-04T19:43:57.944 +C Tag\san\salways-taken\sbranch\susing\sALWAYS(). +D 2022-04-04T19:58:55.827 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -628,7 +628,7 @@ F src/vdbe.c 61ff67a29b89214c928631be206af9cb5f820ed46b8cec3e58308fea205123e4 F src/vdbe.h 89f5edb1422c8783a0b29db836e409876f2b3e847f78e2b21b1fbcc48a93f85f F src/vdbeInt.h 5f3d0abcf30c2b7a6672ad4386f18be0fca9c9b2cefe18f85a2e3df74f2613bf F src/vdbeapi.c 354c893f1500cf524cc45c32879b9c68893a28b77e3442c24668d6afe4236217 -F src/vdbeaux.c 19cd7117723ef31ca31ffffb12cd0298c1b24e4a7b2d920c19f1615bb0023b6d +F src/vdbeaux.c 567ddcdd5d875161201e9752144834d1519e7e856e2da410619d88a9cfefe70d F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 062cd58c54f887dc2eeb865686251c17237f791f0e6394e9c6f7a6f3c1a7e206 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 @@ -1945,8 +1945,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 328dc76657eb5317f0201859d2b3abe6918103b894f7beaed0aca3058a9f2b64 -R ac8b3e120e5046f4e8f53f05766d7e6a +P 5c3357ad62843fe982b9c2d31dbf02018f2948ceab2c85dac917cd9ce1e97dd6 +R e1baec0a4623bc482b84ffca80620d79 U drh -Z 8545e3f2f52a7362bf82a3c0cf610720 +Z 85eb1104cf0cb5341f01b52e5988e935 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a05f745f93..72687ca8ac 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5c3357ad62843fe982b9c2d31dbf02018f2948ceab2c85dac917cd9ce1e97dd6 \ No newline at end of file +ad8bc3d7443ff57ce5a8756428e717ac42ec0295191a9b4d7ae44846d8fa03a2 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index d9a5236f32..551236226b 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -597,7 +597,7 @@ void sqlite3VdbeRunOnlyOnce(Vdbe *p){ void sqlite3VdbeReusable(Vdbe *p){ int i; for(i=1; ALWAYS(inOp); i++){ - if( p->aOp[i].opcode==OP_Expire ){ + if( ALWAYS(p->aOp[i].opcode==OP_Expire) ){ p->aOp[1].opcode = OP_Noop; break; } From ec534e6a23f305b571f448480b4bfed2de8f0c16 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 4 Apr 2022 20:20:22 +0000 Subject: [PATCH 070/259] Small performance and size improvement to OP_Found. FossilOrigin-Name: 81587a18b7c0516628453000172a0c58e74ee173c15f655d035799d84d4e2d81 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 8 +++----- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 24a5d04278..1c8de88e1e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Tag\san\salways-taken\sbranch\susing\sALWAYS(). -D 2022-04-04T19:58:55.827 +C Small\sperformance\sand\ssize\simprovement\sto\sOP_Found. +D 2022-04-04T20:20:22.930 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -624,7 +624,7 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c 61ff67a29b89214c928631be206af9cb5f820ed46b8cec3e58308fea205123e4 +F src/vdbe.c 4d8f5b013e1ad47240e9822217a4ac76041afd2667dcbefd26f598fe45f729a5 F src/vdbe.h 89f5edb1422c8783a0b29db836e409876f2b3e847f78e2b21b1fbcc48a93f85f F src/vdbeInt.h 5f3d0abcf30c2b7a6672ad4386f18be0fca9c9b2cefe18f85a2e3df74f2613bf F src/vdbeapi.c 354c893f1500cf524cc45c32879b9c68893a28b77e3442c24668d6afe4236217 @@ -1945,8 +1945,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 5c3357ad62843fe982b9c2d31dbf02018f2948ceab2c85dac917cd9ce1e97dd6 -R e1baec0a4623bc482b84ffca80620d79 +P ad8bc3d7443ff57ce5a8756428e717ac42ec0295191a9b4d7ae44846d8fa03a2 +R f24c2291256936df51ada2b187bd8ef3 U drh -Z 85eb1104cf0cb5341f01b52e5988e935 +Z 8dca514d63cc68731f709c5c7575f708 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 72687ca8ac..b114205a3a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ad8bc3d7443ff57ce5a8756428e717ac42ec0295191a9b4d7ae44846d8fa03a2 \ No newline at end of file +81587a18b7c0516628453000172a0c58e74ee173c15f655d035799d84d4e2d81 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index c29198f747..02d0988f10 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4968,7 +4968,6 @@ case OP_Found: { /* jump, in3 */ int alreadyExists; int ii; VdbeCursor *pC; - int res; UnpackedRecord *pIdxKey; UnpackedRecord r; @@ -5000,7 +4999,7 @@ case OP_Found: { /* jump, in3 */ if( ii ) REGISTER_TRACE(pOp->p3+ii, &r.aMem[ii]); } #endif - rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, &r, &res); + rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, &r, &pC->seekResult); }else{ /* Composite key generated by OP_MakeRecord */ assert( pIn3->flags & MEM_Blob ); @@ -5012,14 +5011,13 @@ case OP_Found: { /* jump, in3 */ if( pIdxKey==0 ) goto no_mem; sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey); pIdxKey->default_rc = 0; - rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, pIdxKey, &res); + rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, pIdxKey, &pC->seekResult); sqlite3DbFreeNN(db, pIdxKey); } if( rc!=SQLITE_OK ){ goto abort_due_to_error; } - pC->seekResult = res; - alreadyExists = (res==0); + alreadyExists = (pC->seekResult==0); pC->nullRow = 1-alreadyExists; pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; From 7d2c1d24b0a331590ec2c8fd53bc9bf569b54300 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 6 Apr 2022 00:29:21 +0000 Subject: [PATCH 071/259] Add new diagnostic "sqlite3TreeView" routines for IdList, Upsert, and for INSERT statements. This is all debugging code. There are no changes to release builds. FossilOrigin-Name: f3084122039bcb30c8617f5f432009a49be8b488235850a1f10ef862c91560b2 --- manifest | 16 +++---- manifest.uuid | 2 +- src/insert.c | 7 +++ src/sqliteInt.h | 6 +++ src/treeview.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 146 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 1c8de88e1e..7332bfaa55 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\sperformance\sand\ssize\simprovement\sto\sOP_Found. -D 2022-04-04T20:20:22.930 +C Add\snew\sdiagnostic\s"sqlite3TreeView"\sroutines\sfor\sIdList,\sUpsert,\sand\sfor\nINSERT\sstatements.\s\sThis\sis\sall\sdebugging\scode.\s\sThere\sare\sno\schanges\sto\nrelease\sbuilds. +D 2022-04-06T00:29:21.828 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -512,7 +512,7 @@ F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51 F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c c4fc48e6f38cc415262652407949771ce4e6f8f0c7330f872e44a0677f3ad602 +F src/insert.c 1ae2427a4432735a938dc078466a1ac01207889b3ce6d4677328917675feff37 F src/json.c 7749b98c62f691697c7ee536b570c744c0583cab4a89200fdd0fc2aa8cc8cbd6 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 2ecb1441f9b1c22e9e022ee0776e67d259facf34b56ba892b206f0a294ee6f8c @@ -557,7 +557,7 @@ F src/shell.c.in 24d1082d275db252379629c2b3694dbfa0f8886530b0f6f9896d52e456afe51 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h 5a7867196379868a3f91c8ae172209622de2b5fabf7a5e20aa021ec44174eead +F src/sqliteInt.h 0d08bc66b1c0019532ec9d7e63bf1fe36a9271790afed16bde73aa648b0bea09 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -617,7 +617,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98 -F src/treeview.c 3fac35b0835998f34bc940cb07282c5c485caa1645135435fca07ba828c48463 +F src/treeview.c 46d5a45387c1d32ab452bb378bd06e1604354e93e094eb44a9e7b4c358c5ce92 F src/trigger.c 8caa0baf1b18522863cf0fd611ef483962cfa50155ca82ad43e63b20f863a683 F src/update.c f875b0d59da5c3055a0b2ac20560e1650229c6787e78de5e9836267b5cbb8359 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 @@ -1945,8 +1945,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 ad8bc3d7443ff57ce5a8756428e717ac42ec0295191a9b4d7ae44846d8fa03a2 -R f24c2291256936df51ada2b187bd8ef3 +P 81587a18b7c0516628453000172a0c58e74ee173c15f655d035799d84d4e2d81 +R cd74e6843bcbfaa69e0d22d5e8c51092 U drh -Z 8dca514d63cc68731f709c5c7575f708 +Z a9d6094f1c40af3b59087c028de538e7 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b114205a3a..cc50486ead 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -81587a18b7c0516628453000172a0c58e74ee173c15f655d035799d84d4e2d81 \ No newline at end of file +f3084122039bcb30c8617f5f432009a49be8b488235850a1f10ef862c91560b2 \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index dde685e302..8a022df07c 100644 --- a/src/insert.c +++ b/src/insert.c @@ -722,6 +722,13 @@ void sqlite3Insert( assert( db->mallocFailed==0 ); dest.iSDParm = 0; /* Suppress a harmless compiler warning */ +#if SELECTTRACE_ENABLED + if( sqlite3SelectTrace & 0x100 ){ + sqlite3TreeViewInsert(0, pParse->pWith, pTabList, pColumn, pSelect, + onError, pUpsert); + } +#endif + /* If the Select object is really just a simple VALUES() list with a ** single row (the common case) then keep that one row of values ** and discard the other (unused) parts of the pSelect object diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 6b08281fed..9662508da5 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4415,9 +4415,15 @@ char *sqlite3VMPrintf(sqlite3*,const char*, va_list); void sqlite3TreeViewExpr(TreeView*, const Expr*, u8); void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, const char*); void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*); + void sqlite3TreeViewBareIdList(TreeView*, const IdList*, const char*); + void sqlite3TreeViewIdList(TreeView*, const IdList*, u8, const char*); void sqlite3TreeViewSrcList(TreeView*, const SrcList*); void sqlite3TreeViewSelect(TreeView*, const Select*, u8); void sqlite3TreeViewWith(TreeView*, const With*, u8); + void sqlite3TreeViewUpsert(TreeView*, const Upsert*, u8); + void sqlite3TreeViewInsert(TreeView*, const With*, const SrcList*, + const IdList*, const Select*, int, + const Upsert*); #ifndef SQLITE_OMIT_WINDOWFUNC void sqlite3TreeViewWindow(TreeView*, const Window*, u8); void sqlite3TreeViewWinFunc(TreeView*, const Window*, u8); diff --git a/src/treeview.c b/src/treeview.c index b547c96c57..a2ae320690 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -95,7 +95,7 @@ void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){ sqlite3TreeViewLine(pView, "WITH (0x%p)", pWith); } if( pWith->nCte>0 ){ - pView = sqlite3TreeViewPush(pView, 1); + pView = sqlite3TreeViewPush(pView, moreToFollow); for(i=0; inCte; i++){ StrAccum x; char zLine[1000]; @@ -814,4 +814,127 @@ void sqlite3TreeViewExprList( sqlite3TreeViewPop(pView); } +/* +** Generate a human-readable explanation of an id-list. +*/ +void sqlite3TreeViewBareIdList( + TreeView *pView, + const IdList *pList, + const char *zLabel +){ + if( zLabel==0 || zLabel[0]==0 ) zLabel = "LIST"; + if( pList==0 ){ + sqlite3TreeViewLine(pView, "%s (empty)", zLabel); + }else{ + int i; + sqlite3TreeViewLine(pView, "%s", zLabel); + for(i=0; inId; i++){ + char *zName = pList->a[i].zName; + int moreToFollow = inId - 1; + if( zName==0 ) zName = "(null)"; + sqlite3TreeViewPush(pView, moreToFollow); + moreToFollow = 0; + sqlite3TreeViewLine(pView, 0); + fprintf(stdout, "%s (%d)\n", zName, pList->a[i].idx); + sqlite3TreeViewPop(pView); + } + } +} +void sqlite3TreeViewIdList( + TreeView *pView, + const IdList *pList, + u8 moreToFollow, + const char *zLabel +){ + pView = sqlite3TreeViewPush(pView, moreToFollow); + sqlite3TreeViewBareIdList(pView, pList, zLabel); + sqlite3TreeViewPop(pView); +} + +/* +** Generate a human-readable explanation of a list of Upsert objects +*/ +void sqlite3TreeViewUpsert( + TreeView *pView, + const Upsert *pUpsert, + u8 moreToFollow +){ + if( pUpsert==0 ) return; + pView = sqlite3TreeViewPush(pView, moreToFollow); + while( pUpsert ){ + int n; + sqlite3TreeViewPush(pView, pUpsert->pNextUpsert!=0 || moreToFollow); + sqlite3TreeViewLine(pView, "ON CONFLICT DO %s", + pUpsert->isDoUpdate ? "UPDATE" : "NOTHING"); + n = (pUpsert->pUpsertSet!=0) + (pUpsert->pUpsertWhere!=0); + sqlite3TreeViewExprList(pView, pUpsert->pUpsertTarget, (n--)>0, "TARGET"); + sqlite3TreeViewExprList(pView, pUpsert->pUpsertSet, (n--)>0, "SET"); + if( pUpsert->pUpsertWhere ){ + sqlite3TreeViewItem(pView, "WHERE", (n--)>0); + sqlite3TreeViewExpr(pView, pUpsert->pUpsertWhere, 0); + sqlite3TreeViewPop(pView); + } + sqlite3TreeViewPop(pView); + pUpsert = pUpsert->pNextUpsert; + } + sqlite3TreeViewPop(pView); +} + +/* +** Generate a human-readable diagram of the data structure that go +** into generating an INSERT statement. +*/ +void sqlite3TreeViewInsert( + TreeView *pView, + const With *pWith, + const SrcList *pTabList, + const IdList *pColumnList, + const Select *pSelect, + int onError, + const Upsert *pUpsert +){ + int n = 0; + const char *zLabel = "INSERT"; + switch( onError ){ + case OE_Replace: zLabel = "REPLACE"; break; + case OE_Ignore: zLabel = "INSERT OR IGNORE"; break; + case OE_Rollback: zLabel = "INSERT OR ROLLBACK"; break; + case OE_Abort: zLabel = "INSERT OR ABORT"; break; + case OE_Fail: zLabel = "INSERT OR FAIL"; break; + } + sqlite3TreeViewLine(pView, zLabel); + pView = sqlite3TreeViewPush(pView, 0); + if( pWith ) n++; + if( pTabList ) n++; + if( pColumnList ) n++; + if( pSelect ) n++; + if( pUpsert ) n++; + if( pWith ){ + pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewWith(pView, pWith, 0); + sqlite3TreeViewPop(pView); + } + if( pTabList ){ + pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewLine(pView, "INTO"); + sqlite3TreeViewSrcList(pView, pTabList); + sqlite3TreeViewPop(pView); + } + if( pColumnList ){ + sqlite3TreeViewIdList(pView, pColumnList, (--n)>0, "COLUMNS"); + } + if( pSelect ){ + pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewLine(pView, "DATA-SOURCE"); + sqlite3TreeViewSelect(pView, pSelect, 0); + sqlite3TreeViewPop(pView); + } + if( pUpsert ){ + pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewLine(pView, "UPSERT"); + sqlite3TreeViewUpsert(pView, pUpsert, 0); + sqlite3TreeViewPop(pView); + } +} + #endif /* SQLITE_DEBUG */ From f8ef2dbd7be8df555ce63e8dc8edbb680d6f0e70 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 6 Apr 2022 10:37:44 +0000 Subject: [PATCH 072/259] Add additional tree display routines for DELETE and UPDATE. No changes to deliverable code. FossilOrigin-Name: fbd288ff3d4ea47cd324b5952e7754a465901844f2d950f0860d4488d5b6eb9f --- manifest | 20 ++++---- manifest.uuid | 2 +- src/delete.c | 6 +++ src/insert.c | 2 +- src/sqliteInt.h | 5 ++ src/treeview.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++ src/update.c | 7 +++ 7 files changed, 148 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 7332bfaa55..b62b8aafc3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\snew\sdiagnostic\s"sqlite3TreeView"\sroutines\sfor\sIdList,\sUpsert,\sand\sfor\nINSERT\sstatements.\s\sThis\sis\sall\sdebugging\scode.\s\sThere\sare\sno\schanges\sto\nrelease\sbuilds. -D 2022-04-06T00:29:21.828 +C Add\sadditional\stree\sdisplay\sroutines\sfor\sDELETE\sand\sUPDATE.\s\sNo\schanges\nto\sdeliverable\scode. +D 2022-04-06T10:37:44.925 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -502,7 +502,7 @@ F src/ctime.c 2cce39df1a13e05b7633e6d21b651f21492471f991dd7b323a4ee4e7b7f0b7f1 F src/date.c 15082566229d4b1e5f24fdb490bf9bcc68824b911d70e3573ef075a1b9e2d26f F src/dbpage.c a70be9a4879ac5392673a1050d526a72b8b2f9938df7049f65348566a2637db3 F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d -F src/delete.c b5f1716b4d723db48254ee0f896e362cd029e865e05414139ea7f539f3884e1d +F src/delete.c 0052a340726b2521fedf05e0944a3d36110d82c66b33618068ce962bb8004a38 F src/expr.c 3cdb00b6c15f815c94836e7b4474b675155d1279e64804f6ab5816188a9b05b6 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 94927f9b46d72a9cb858c208febf04ceb0a3270c5fa5fd0b7f436cf16e09f72a @@ -512,7 +512,7 @@ F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51 F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 1ae2427a4432735a938dc078466a1ac01207889b3ce6d4677328917675feff37 +F src/insert.c f2793e5a2b1484472c025fc80a5a2d97d5098498c150157f25aea0672763cab0 F src/json.c 7749b98c62f691697c7ee536b570c744c0583cab4a89200fdd0fc2aa8cc8cbd6 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 2ecb1441f9b1c22e9e022ee0776e67d259facf34b56ba892b206f0a294ee6f8c @@ -557,7 +557,7 @@ F src/shell.c.in 24d1082d275db252379629c2b3694dbfa0f8886530b0f6f9896d52e456afe51 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h 0d08bc66b1c0019532ec9d7e63bf1fe36a9271790afed16bde73aa648b0bea09 +F src/sqliteInt.h 1edf4da9aa846479e9217a154cd94d3aeef49b8bcc813c0e573681c648c28aca F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -617,9 +617,9 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98 -F src/treeview.c 46d5a45387c1d32ab452bb378bd06e1604354e93e094eb44a9e7b4c358c5ce92 +F src/treeview.c 7e95d0dcf5e3a29272c1f1f84a86cb90f0acc1e7b927d53ac80af7b120d1da15 F src/trigger.c 8caa0baf1b18522863cf0fd611ef483962cfa50155ca82ad43e63b20f863a683 -F src/update.c f875b0d59da5c3055a0b2ac20560e1650229c6787e78de5e9836267b5cbb8359 +F src/update.c 92f3801f9561c41dcc07df990aaba383759d14122fd7c53db016370d061362c1 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 @@ -1945,8 +1945,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 81587a18b7c0516628453000172a0c58e74ee173c15f655d035799d84d4e2d81 -R cd74e6843bcbfaa69e0d22d5e8c51092 +P f3084122039bcb30c8617f5f432009a49be8b488235850a1f10ef862c91560b2 +R 6bd4728818ef5c3b838d1c52b662f0fa U drh -Z a9d6094f1c40af3b59087c028de538e7 +Z 0924497f59dfb282d02a01f160c46ce4 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index cc50486ead..abfd17b89b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f3084122039bcb30c8617f5f432009a49be8b488235850a1f10ef862c91560b2 \ No newline at end of file +fbd288ff3d4ea47cd324b5952e7754a465901844f2d950f0860d4488d5b6eb9f \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index 7b769e6a18..8990e10a0c 100644 --- a/src/delete.c +++ b/src/delete.c @@ -300,6 +300,12 @@ void sqlite3DeleteFrom( assert( db->mallocFailed==0 ); assert( pTabList->nSrc==1 ); +#if SELECTTRACE_ENABLED + if( sqlite3SelectTrace & 0x10000 ){ + sqlite3TreeViewDelete(0, pParse->pWith, pTabList, pWhere, + pOrderBy, pLimit); + } +#endif /* Locate the table which we want to delete. This table has to be ** put in an SrcList structure because some of the subroutines we diff --git a/src/insert.c b/src/insert.c index 8a022df07c..72d4b7df32 100644 --- a/src/insert.c +++ b/src/insert.c @@ -723,7 +723,7 @@ void sqlite3Insert( dest.iSDParm = 0; /* Suppress a harmless compiler warning */ #if SELECTTRACE_ENABLED - if( sqlite3SelectTrace & 0x100 ){ + if( sqlite3SelectTrace & 0x10000 ){ sqlite3TreeViewInsert(0, pParse->pWith, pTabList, pColumn, pSelect, onError, pUpsert); } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 9662508da5..6d403f4f1e 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4421,9 +4421,14 @@ char *sqlite3VMPrintf(sqlite3*,const char*, va_list); void sqlite3TreeViewSelect(TreeView*, const Select*, u8); void sqlite3TreeViewWith(TreeView*, const With*, u8); void sqlite3TreeViewUpsert(TreeView*, const Upsert*, u8); + void sqlite3TreeViewDelete(TreeView*, const With*, const SrcList*, + const Expr*,const ExprList*,const Expr*); void sqlite3TreeViewInsert(TreeView*, const With*, const SrcList*, const IdList*, const Select*, int, const Upsert*); + void sqlite3TreeViewUpdate(TreeView*, const With*, const SrcList*, + const ExprList*, const Expr*, int, + const ExprList*, const Expr*, const Upsert*); #ifndef SQLITE_OMIT_WINDOWFUNC void sqlite3TreeViewWindow(TreeView*, const Window*, u8); void sqlite3TreeViewWinFunc(TreeView*, const Window*, u8); diff --git a/src/treeview.c b/src/treeview.c index a2ae320690..bb7187ee65 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -880,6 +880,54 @@ void sqlite3TreeViewUpsert( sqlite3TreeViewPop(pView); } +/* +** Generate a human-readable diagram of the data structure that go +** into generating an DELETE statement. +*/ +void sqlite3TreeViewDelete( + TreeView *pView, + const With *pWith, + const SrcList *pTabList, + const Expr *pWhere, + const ExprList *pOrderBy, + const Expr *pLimit +){ + int n = 0; + sqlite3TreeViewLine(pView, "DELETE"); + pView = sqlite3TreeViewPush(pView, 0); + if( pWith ) n++; + if( pTabList ) n++; + if( pWhere ) n++; + if( pOrderBy ) n++; + if( pLimit ) n++; + if( pWith ){ + pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewWith(pView, pWith, 0); + sqlite3TreeViewPop(pView); + } + if( pTabList ){ + pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewLine(pView, "FROM"); + sqlite3TreeViewSrcList(pView, pTabList); + sqlite3TreeViewPop(pView); + } + if( pWhere ){ + pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewLine(pView, "WHERE"); + sqlite3TreeViewExpr(pView, pWhere, 0); + sqlite3TreeViewPop(pView); + } + if( pOrderBy ){ + sqlite3TreeViewExprList(pView, pOrderBy, (--n)>0, "ORDER-BY"); + } + if( pLimit ){ + pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewLine(pView, "LIMIT"); + sqlite3TreeViewExpr(pView, pLimit, 0); + sqlite3TreeViewPop(pView); + } +} + /* ** Generate a human-readable diagram of the data structure that go ** into generating an INSERT statement. @@ -937,4 +985,74 @@ void sqlite3TreeViewInsert( } } +/* +** Generate a human-readable diagram of the data structure that go +** into generating an UPDATE statement. +*/ +void sqlite3TreeViewUpdate( + TreeView *pView, + const With *pWith, + const SrcList *pTabList, + const ExprList *pChanges, + const Expr *pWhere, + int onError, + const ExprList *pOrderBy, + const Expr *pLimit, + const Upsert *pUpsert +){ + int n = 0; + const char *zLabel = "UPDATE"; + switch( onError ){ + case OE_Replace: zLabel = "UPDATE OR REPLACE"; break; + case OE_Ignore: zLabel = "UPDATE OR IGNORE"; break; + case OE_Rollback: zLabel = "UPDATE OR ROLLBACK"; break; + case OE_Abort: zLabel = "UPDATE OR ABORT"; break; + case OE_Fail: zLabel = "UPDATE OR FAIL"; break; + } + sqlite3TreeViewLine(pView, zLabel); + pView = sqlite3TreeViewPush(pView, 0); + if( pWith ) n++; + if( pTabList ) n++; + if( pChanges ) n++; + if( pWhere ) n++; + if( pOrderBy ) n++; + if( pLimit ) n++; + if( pUpsert ) n++; + if( pWith ){ + pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewWith(pView, pWith, 0); + sqlite3TreeViewPop(pView); + } + if( pTabList ){ + pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewLine(pView, "FROM"); + sqlite3TreeViewSrcList(pView, pTabList); + sqlite3TreeViewPop(pView); + } + if( pChanges ){ + sqlite3TreeViewExprList(pView, pChanges, (--n)>0, "SET"); + } + if( pWhere ){ + pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewLine(pView, "WHERE"); + sqlite3TreeViewExpr(pView, pWhere, 0); + sqlite3TreeViewPop(pView); + } + if( pOrderBy ){ + sqlite3TreeViewExprList(pView, pOrderBy, (--n)>0, "ORDER-BY"); + } + if( pLimit ){ + pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewLine(pView, "LIMIT"); + sqlite3TreeViewExpr(pView, pLimit, 0); + sqlite3TreeViewPop(pView); + } + if( pUpsert ){ + pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewLine(pView, "UPSERT"); + sqlite3TreeViewUpsert(pView, pUpsert, 0); + sqlite3TreeViewPop(pView); + } +} + #endif /* SQLITE_DEBUG */ diff --git a/src/update.c b/src/update.c index a43d0eac53..49f3618618 100644 --- a/src/update.c +++ b/src/update.c @@ -353,6 +353,13 @@ void sqlite3Update( } assert( db->mallocFailed==0 ); +#if SELECTTRACE_ENABLED + if( sqlite3SelectTrace & 0x10000 ){ + sqlite3TreeViewUpdate(0, pParse->pWith, pTabList, pChanges, pWhere, + onError, pOrderBy, pLimit, pUpsert); + } +#endif + /* Locate the table which we want to update. */ pTab = sqlite3SrcListLookup(pParse, pTabList); From 5e431bead8008f52337213a90860fe3f2481c66c Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 6 Apr 2022 11:08:38 +0000 Subject: [PATCH 073/259] Rename debugging defines and variables from SELECTTRACE to TREETRACE (and similar) since the functionality has how expanded to include data structures beyond SELECT statements. Should not affect deliverable builds. FossilOrigin-Name: 393fa32e188a017f431372b54037cb31e885030542f00d0bfd59da9d9db5c014 --- manifest | 28 ++++++++++++------------- manifest.uuid | 2 +- src/delete.c | 4 ++-- src/global.c | 2 +- src/insert.c | 4 ++-- src/main.c | 12 +++++------ src/select.c | 56 ++++++++++++++++++++++++------------------------- src/shell.c.in | 6 ++++-- src/sqliteInt.h | 15 ++++++------- src/test1.c | 6 +++--- src/update.c | 4 ++-- 11 files changed, 71 insertions(+), 68 deletions(-) diff --git a/manifest b/manifest index b62b8aafc3..380f6d6775 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sadditional\stree\sdisplay\sroutines\sfor\sDELETE\sand\sUPDATE.\s\sNo\schanges\nto\sdeliverable\scode. -D 2022-04-06T10:37:44.925 +C Rename\sdebugging\sdefines\sand\svariables\sfrom\sSELECTTRACE\sto\sTREETRACE\s(and\nsimilar)\ssince\sthe\sfunctionality\shas\show\sexpanded\sto\sinclude\sdata\sstructures\nbeyond\sSELECT\sstatements.\s\sShould\snot\saffect\sdeliverable\sbuilds. +D 2022-04-06T11:08:38.679 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -502,21 +502,21 @@ F src/ctime.c 2cce39df1a13e05b7633e6d21b651f21492471f991dd7b323a4ee4e7b7f0b7f1 F src/date.c 15082566229d4b1e5f24fdb490bf9bcc68824b911d70e3573ef075a1b9e2d26f F src/dbpage.c a70be9a4879ac5392673a1050d526a72b8b2f9938df7049f65348566a2637db3 F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d -F src/delete.c 0052a340726b2521fedf05e0944a3d36110d82c66b33618068ce962bb8004a38 +F src/delete.c f9e765869d4eb1bb639df0d77a8eda36bf064e83d21777b1ea772cac66786df5 F src/expr.c 3cdb00b6c15f815c94836e7b4474b675155d1279e64804f6ab5816188a9b05b6 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 94927f9b46d72a9cb858c208febf04ceb0a3270c5fa5fd0b7f436cf16e09f72a F src/func.c a3407a6fbb0d4088d8d502e46f0ace63e0aeae7467ae23a9ca9815bbf9239761 -F src/global.c 75deb064a71e1db60c8972a660a84f4e6d805c8f0463299a18e30ea527f4a650 +F src/global.c e83ee571b79ee3adc32e380cf554cf1254bc43763d23786c71721fbcdfbbb965 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51 F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c f2793e5a2b1484472c025fc80a5a2d97d5098498c150157f25aea0672763cab0 +F src/insert.c 1e76792fef634bc84dfc79080e632fe5bf833fadb0777510785c6a8fc13e5e8c F src/json.c 7749b98c62f691697c7ee536b570c744c0583cab4a89200fdd0fc2aa8cc8cbd6 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 2ecb1441f9b1c22e9e022ee0776e67d259facf34b56ba892b206f0a294ee6f8c -F src/main.c 89dfd569b4fbcab65281b3c6d636b887b2cb23cbaa16f8c6b67062862144c927 +F src/main.c db08e3ebd5e1802ab4d4cac5dfa6ae0a12058c51345a90126146dd6010b32593 F src/malloc.c fec841aa0a0400a6f7d20706178a5d8e8219a6bf562b6fe712c17f6c26813266 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -552,17 +552,17 @@ F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c ea935b87d6fb36c78b70cdc7b28561dc8f33f2ef37048389549c7b5ef9b0ba5e F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c c366c05e48e836ea04f8ecefb9c1225745dc250c3f01bdb39e9cbb0dc25e3610 -F src/shell.c.in 24d1082d275db252379629c2b3694dbfa0f8886530b0f6f9896d52e456afe510 +F src/select.c bf46b8fb1f095651ba26e5a4a63b0fab51367794169ba3c802c002f919117e6c +F src/shell.c.in 18832612e74c92bbd25d88e1f92685f66589262f68cca1001d2a43bd6dd0ed60 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h 1edf4da9aa846479e9217a154cd94d3aeef49b8bcc813c0e573681c648c28aca +F src/sqliteInt.h eaecce0fe9ab773594281c61dfeb4b6f561c23d8e79778cc89b40b0a6f862750 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 F src/tclsqlite.c 1f6673991147bc2cecc08a40d22f9803b84c805b24b499fe727f392256f73474 -F src/test1.c 87fda59eea3ac1eba1baef37c1967565cb1b8d6d264649f2e57f252ca5989914 +F src/test1.c 1356984e97bff07e4a8cc3863e892f05b3348678a74783bb6f350b76316736f1 F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644 F src/test4.c 7c4420e01c577b5c4add2cb03119743b1a357543d347773b9e717195ea967159 @@ -619,7 +619,7 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98 F src/treeview.c 7e95d0dcf5e3a29272c1f1f84a86cb90f0acc1e7b927d53ac80af7b120d1da15 F src/trigger.c 8caa0baf1b18522863cf0fd611ef483962cfa50155ca82ad43e63b20f863a683 -F src/update.c 92f3801f9561c41dcc07df990aaba383759d14122fd7c53db016370d061362c1 +F src/update.c c79e4ba491dbce7e0bd8995aeccbbf453843c763a0670c7a3414094610b0d71f F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 @@ -1945,8 +1945,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 f3084122039bcb30c8617f5f432009a49be8b488235850a1f10ef862c91560b2 -R 6bd4728818ef5c3b838d1c52b662f0fa +P fbd288ff3d4ea47cd324b5952e7754a465901844f2d950f0860d4488d5b6eb9f +R a8535a7f26ac80cc50df61020309f93a U drh -Z 0924497f59dfb282d02a01f160c46ce4 +Z c92d34f20cea24a5723ef3e12b37f708 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index abfd17b89b..77dc1ec430 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fbd288ff3d4ea47cd324b5952e7754a465901844f2d950f0860d4488d5b6eb9f \ No newline at end of file +393fa32e188a017f431372b54037cb31e885030542f00d0bfd59da9d9db5c014 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index 8990e10a0c..ca3705f552 100644 --- a/src/delete.c +++ b/src/delete.c @@ -300,8 +300,8 @@ void sqlite3DeleteFrom( assert( db->mallocFailed==0 ); assert( pTabList->nSrc==1 ); -#if SELECTTRACE_ENABLED - if( sqlite3SelectTrace & 0x10000 ){ +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x10000 ){ sqlite3TreeViewDelete(0, pParse->pWith, pTabList, pWhere, pOrderBy, pLimit); } diff --git a/src/global.c b/src/global.c index c77d0cc201..9e3c07a515 100644 --- a/src/global.c +++ b/src/global.c @@ -347,7 +347,7 @@ int sqlite3PendingByte = 0x40000000; /* ** Tracing flags set by SQLITE_TESTCTRL_TRACEFLAGS. */ -u32 sqlite3SelectTrace = 0; +u32 sqlite3TreeTrace = 0; u32 sqlite3WhereTrace = 0; #include "opcodes.h" diff --git a/src/insert.c b/src/insert.c index 72d4b7df32..9acddd4070 100644 --- a/src/insert.c +++ b/src/insert.c @@ -722,8 +722,8 @@ void sqlite3Insert( assert( db->mallocFailed==0 ); dest.iSDParm = 0; /* Suppress a harmless compiler warning */ -#if SELECTTRACE_ENABLED - if( sqlite3SelectTrace & 0x10000 ){ +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x10000 ){ sqlite3TreeViewInsert(0, pParse->pWith, pTabList, pColumn, pSelect, onError, pUpsert); } diff --git a/src/main.c b/src/main.c index 4aac64da3e..c17e1b89f9 100644 --- a/src/main.c +++ b/src/main.c @@ -4358,8 +4358,8 @@ int sqlite3_test_control(int op, ...){ ** ** "ptr" is a pointer to a u32. ** - ** op==0 Store the current sqlite3SelectTrace in *ptr - ** op==1 Set sqlite3SelectTrace to the value *ptr + ** op==0 Store the current sqlite3TreeTrace in *ptr + ** op==1 Set sqlite3TreeTrace to the value *ptr ** op==3 Store the current sqlite3WhereTrace in *ptr ** op==3 Set sqlite3WhereTrace to the value *ptr */ @@ -4367,10 +4367,10 @@ int sqlite3_test_control(int op, ...){ int opTrace = va_arg(ap, int); u32 *ptr = va_arg(ap, u32*); switch( opTrace ){ - case 0: *ptr = sqlite3SelectTrace; break; - case 1: sqlite3SelectTrace = *ptr; break; - case 2: *ptr = sqlite3WhereTrace; break; - case 3: sqlite3WhereTrace = *ptr; break; + case 0: *ptr = sqlite3TreeTrace; break; + case 1: sqlite3TreeTrace = *ptr; break; + case 2: *ptr = sqlite3WhereTrace; break; + case 3: sqlite3WhereTrace = *ptr; break; } break; } diff --git a/src/select.c b/src/select.c index 5165d6f600..d9348dc583 100644 --- a/src/select.c +++ b/src/select.c @@ -4457,8 +4457,8 @@ static int flattenSubquery( sqlite3WalkSelect(&w,pSub1); sqlite3SelectDelete(db, pSub1); -#if SELECTTRACE_ENABLED - if( sqlite3SelectTrace & 0x100 ){ +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x100 ){ SELECTTRACE(0x100,pParse,p,("After flattening:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -6157,8 +6157,8 @@ static void havingToWhere(Parse *pParse, Select *p){ sWalker.xExprCallback = havingToWhereExprCb; sWalker.u.pSelect = p; sqlite3WalkExpr(&sWalker, p->pHaving); -#if SELECTTRACE_ENABLED - if( sWalker.eCode && (sqlite3SelectTrace & 0x100)!=0 ){ +#if TREETRACE_ENABLED + if( sWalker.eCode && (sqlite3TreeTrace & 0x100)!=0 ){ SELECTTRACE(0x100,pParse,p,("Move HAVING terms into WHERE:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -6290,8 +6290,8 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ p->pEList->a[0].pExpr = pExpr; p->selFlags &= ~SF_Aggregate; -#if SELECTTRACE_ENABLED - if( sqlite3SelectTrace & 0x400 ){ +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x400 ){ SELECTTRACE(0x400,pParse,p,("After count-of-view optimization:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -6344,9 +6344,9 @@ int sqlite3Select( } assert( db->mallocFailed==0 ); if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; -#if SELECTTRACE_ENABLED +#if TREETRACE_ENABLED SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain)); - if( sqlite3SelectTrace & 0x100 ){ + if( sqlite3TreeTrace & 0x100 ){ sqlite3TreeViewSelect(0, p, 0); } #endif @@ -6361,9 +6361,9 @@ int sqlite3Select( pDest->eDest==SRT_DistQueue || pDest->eDest==SRT_DistFifo ); /* All of these destinations are also able to ignore the ORDER BY clause */ if( p->pOrderBy ){ -#if SELECTTRACE_ENABLED +#if TREETRACE_ENABLED SELECTTRACE(1,pParse,p, ("dropping superfluous ORDER BY:\n")); - if( sqlite3SelectTrace & 0x100 ){ + if( sqlite3TreeTrace & 0x100 ){ sqlite3TreeViewExprList(0, p->pOrderBy, 0, "ORDERBY"); } #endif @@ -6382,8 +6382,8 @@ int sqlite3Select( } assert( db->mallocFailed==0 ); assert( p->pEList!=0 ); -#if SELECTTRACE_ENABLED - if( sqlite3SelectTrace & 0x104 ){ +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x104 ){ SELECTTRACE(0x104,pParse,p, ("after name resolution:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -6427,8 +6427,8 @@ int sqlite3Select( assert( pParse->nErr ); goto select_end; } -#if SELECTTRACE_ENABLED - if( p->pWin && (sqlite3SelectTrace & 0x108)!=0 ){ +#if TREETRACE_ENABLED + if( p->pWin && (sqlite3TreeTrace & 0x108)!=0 ){ SELECTTRACE(0x104,pParse,p, ("after window rewrite:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -6566,9 +6566,9 @@ int sqlite3Select( */ if( p->pPrior ){ rc = multiSelect(pParse, p, pDest); -#if SELECTTRACE_ENABLED +#if TREETRACE_ENABLED SELECTTRACE(0x1,pParse,p,("end compound-select processing\n")); - if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ + if( (sqlite3TreeTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ sqlite3TreeViewSelect(0, p, 0); } #endif @@ -6587,8 +6587,8 @@ int sqlite3Select( && OptimizationEnabled(db, SQLITE_PropagateConst) && propagateConstants(pParse, p) ){ -#if SELECTTRACE_ENABLED - if( sqlite3SelectTrace & 0x100 ){ +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x100 ){ SELECTTRACE(0x100,pParse,p,("After constant propagation:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -6667,8 +6667,8 @@ int sqlite3Select( && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor, (pItem->fg.jointype & JT_OUTER)!=0) ){ -#if SELECTTRACE_ENABLED - if( sqlite3SelectTrace & 0x100 ){ +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x100 ){ SELECTTRACE(0x100,pParse,p, ("After WHERE-clause push-down into subquery %d:\n", pSub->selId)); sqlite3TreeViewSelect(0, p, 0); @@ -6786,8 +6786,8 @@ int sqlite3Select( pHaving = p->pHaving; sDistinct.isTnct = (p->selFlags & SF_Distinct)!=0; -#if SELECTTRACE_ENABLED - if( sqlite3SelectTrace & 0x400 ){ +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x400 ){ SELECTTRACE(0x400,pParse,p,("After all FROM-clause analysis:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -6823,8 +6823,8 @@ int sqlite3Select( assert( sDistinct.isTnct ); sDistinct.isTnct = 2; -#if SELECTTRACE_ENABLED - if( sqlite3SelectTrace & 0x400 ){ +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x400 ){ SELECTTRACE(0x400,pParse,p,("Transform DISTINCT into GROUP BY:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -7076,8 +7076,8 @@ int sqlite3Select( } pAggInfo->mxReg = pParse->nMem; if( db->mallocFailed ) goto select_end; -#if SELECTTRACE_ENABLED - if( sqlite3SelectTrace & 0x400 ){ +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x400 ){ int ii; SELECTTRACE(0x400,pParse,p,("After aggregate analysis %p:\n", pAggInfo)); sqlite3TreeViewSelect(0, p, 0); @@ -7540,9 +7540,9 @@ select_end: } #endif -#if SELECTTRACE_ENABLED +#if TREETRACE_ENABLED SELECTTRACE(0x1,pParse,p,("end processing\n")); - if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ + if( (sqlite3TreeTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ sqlite3TreeViewSelect(0, p, 0); } #endif diff --git a/src/shell.c.in b/src/shell.c.in index e5c546bd74..9e6198f517 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -3042,7 +3042,7 @@ static void explain_data_delete(ShellState *p){ } /* -** Disable and restore .wheretrace and .selecttrace settings. +** Disable and restore .wheretrace and .treetrace/.selecttrace settings. */ static unsigned int savedSelectTrace; static unsigned int savedWhereTrace; @@ -10113,7 +10113,9 @@ static int do_meta_command(char *zLine, ShellState *p){ } }else - if( c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0 ){ + if( (c=='s' && n==11 && strncmp(azArg[0], "selecttrace", n)==0) + || (c=='t' && n==9 && strncmp(azArg[0], "treetrace", n)==0) + ){ unsigned int x = nArg>=2 ? (unsigned int)integerValue(azArg[1]) : 0xffffffff; sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &x); }else diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 6d403f4f1e..3a1cc85548 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1014,22 +1014,23 @@ typedef INT16_TYPE LogEst; #endif /* -** SELECTTRACE_ENABLED will be either 1 or 0 depending on whether or not -** the Select query generator tracing logic is turned on. +** TREETRACE_ENABLED will be either 1 or 0 depending on whether or not +** the Abstract Syntax Tree tracing logic is turned on. */ #if !defined(SQLITE_AMALGAMATION) -extern u32 sqlite3SelectTrace; +extern u32 sqlite3TreeTrace; #endif #if defined(SQLITE_DEBUG) \ - && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_SELECTTRACE)) -# define SELECTTRACE_ENABLED 1 + && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_SELECTTRACE) \ + || defined(SQLITE_ENABLE_TREETRACE)) +# define TREETRACE_ENABLED 1 # define SELECTTRACE(K,P,S,X) \ - if(sqlite3SelectTrace&(K)) \ + if(sqlite3TreeTrace&(K)) \ sqlite3DebugPrintf("%u/%d/%p: ",(S)->selId,(P)->addrExplain,(S)),\ sqlite3DebugPrintf X #else # define SELECTTRACE(K,P,S,X) -# define SELECTTRACE_ENABLED 0 +# define TREETRACE_ENABLED 0 #endif /* diff --git a/src/test1.c b/src/test1.c index 455c4b2579..6ccd4512f5 100644 --- a/src/test1.c +++ b/src/test1.c @@ -8908,9 +8908,9 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ (char*)&sqlite3_sync_count, TCL_LINK_INT); Tcl_LinkVar(interp, "sqlite_fullsync_count", (char*)&sqlite3_fullsync_count, TCL_LINK_INT); -#if defined(SQLITE_ENABLE_SELECTTRACE) - Tcl_LinkVar(interp, "sqlite3_unsupported_selecttrace", - (char*)&sqlite3SelectTrace, TCL_LINK_INT); +#if defined(SQLITE_ENABLE_TREETRACE) + Tcl_LinkVar(interp, "sqlite3_unsupported_treetrace", + (char*)&sqlite3TreeTrace, TCL_LINK_INT); #endif #if defined(SQLITE_ENABLE_FTS3) && defined(SQLITE_TEST) Tcl_LinkVar(interp, "sqlite_fts3_enable_parentheses", diff --git a/src/update.c b/src/update.c index 49f3618618..908fc3ad6d 100644 --- a/src/update.c +++ b/src/update.c @@ -353,8 +353,8 @@ void sqlite3Update( } assert( db->mallocFailed==0 ); -#if SELECTTRACE_ENABLED - if( sqlite3SelectTrace & 0x10000 ){ +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x10000 ){ sqlite3TreeViewUpdate(0, pParse->pWith, pTabList, pChanges, pWhere, onError, pOrderBy, pLimit, pUpsert); } From 8f1eb6f5e4e3eb577faeab5db40e04c595639270 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 6 Apr 2022 12:25:04 +0000 Subject: [PATCH 074/259] Add the sqlite3Show() family of debugging interfaces under SQLITE_DEBUG. No changes to deliverable builds. Rename SQLITE_ENABLE_SELECTTRACE to SQLITE_ENABLE_TREETRACE in ctime.c. FossilOrigin-Name: bc33168cf1f48caf848c2dc5c3ae15e4efff8c0378f944eb5398a245139a2b35 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/ctime.c | 6 +++--- src/sqliteInt.h | 12 +++++++++++- src/treeview.c | 22 ++++++++++++++++++++++ tool/mkctimec.tcl | 2 +- tool/mksqlite3c.tcl | 3 ++- 7 files changed, 50 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 380f6d6775..900bed8717 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rename\sdebugging\sdefines\sand\svariables\sfrom\sSELECTTRACE\sto\sTREETRACE\s(and\nsimilar)\ssince\sthe\sfunctionality\shas\show\sexpanded\sto\sinclude\sdata\sstructures\nbeyond\sSELECT\sstatements.\s\sShould\snot\saffect\sdeliverable\sbuilds. -D 2022-04-06T11:08:38.679 +C Add\sthe\ssqlite3Show()\sfamily\sof\sdebugging\sinterfaces\sunder\sSQLITE_DEBUG.\nNo\schanges\sto\sdeliverable\sbuilds.\s\sRename\sSQLITE_ENABLE_SELECTTRACE\sto\nSQLITE_ENABLE_TREETRACE\sin\sctime.c. +D 2022-04-06T12:25:04.844 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -498,7 +498,7 @@ F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482 F src/build.c 4a265d49342cefc95ae739982a6197eae04a9258151f8e0bbe3ff8ab56aab801 F src/callback.c 4c19af69835787bfe790ac560f3071a824eb629f34e41f97b52ce5235c77de1c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e -F src/ctime.c 2cce39df1a13e05b7633e6d21b651f21492471f991dd7b323a4ee4e7b7f0b7f1 +F src/ctime.c 026dbdcdbd8c3cde98a88483ee88310ff43150ab164ad768f12cc700a11495ad F src/date.c 15082566229d4b1e5f24fdb490bf9bcc68824b911d70e3573ef075a1b9e2d26f F src/dbpage.c a70be9a4879ac5392673a1050d526a72b8b2f9938df7049f65348566a2637db3 F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d @@ -557,7 +557,7 @@ F src/shell.c.in 18832612e74c92bbd25d88e1f92685f66589262f68cca1001d2a43bd6dd0ed6 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h eaecce0fe9ab773594281c61dfeb4b6f561c23d8e79778cc89b40b0a6f862750 +F src/sqliteInt.h 811d8defe1dff439db365e18129216140204462665d19c23be14b78affea3e18 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -617,7 +617,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98 -F src/treeview.c 7e95d0dcf5e3a29272c1f1f84a86cb90f0acc1e7b927d53ac80af7b120d1da15 +F src/treeview.c 9f867920ef5a39659d034fc2e62c737240d9751a833b0a2b71058ee0304224bc F src/trigger.c 8caa0baf1b18522863cf0fd611ef483962cfa50155ca82ad43e63b20f863a683 F src/update.c c79e4ba491dbce7e0bd8995aeccbbf453843c763a0670c7a3414094610b0d71f F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 @@ -1872,7 +1872,7 @@ F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439 F tool/merge-test.tcl de76b62f2de2a92d4c1ca4f976bce0aea6899e0229e250479b229b2a1914b176 F tool/mkautoconfamal.sh f62353eb6c06ab264da027fd4507d09914433dbdcab9cb011cdc18016f1ab3b8 F tool/mkccode.tcl 86463e68ce9c15d3041610fedd285ce32a5cf7a58fc88b3202b8b76837650dbe x -F tool/mkctimec.tcl 3147e9dfc4ad774e94f80084789ebaada9da9b6e66ddab16438cfc07999b6047 x +F tool/mkctimec.tcl ac96a74f5e6d9dac672d5229f79c583d3357a50e7d098e473e6b2ce2f8ae1704 x F tool/mkkeywordhash.c 35bfc41adacc4aa6ef6fca7fd0c63e0ec0534b78daf4d0cfdebe398216bbffc3 F tool/mkmsvcmin.tcl 6ecab9fe22c2c8de4d82d4c46797bda3d2deac8e763885f5a38d0c44a895ab33 F tool/mkopcodec.tcl 33d20791e191df43209b77d37f0ff0904620b28465cca6990cf8d60da61a07ef @@ -1883,7 +1883,7 @@ F tool/mkshellc.tcl df5d249617f9cc94d5c48eb0401673eb3f31f383ecbc54e8a13ca3dd97e8 F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b079b9 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6d0274f584a7f -F tool/mksqlite3c.tcl 6f9e05facb51e906a1a7ef9f95274ef2ec91bf88b96732a9aed40647c605f419 +F tool/mksqlite3c.tcl eee7e9d9c58abb1045f6ed74ad95ad26e8d22be29fdc431deea5267fb3fa049c F tool/mksqlite3h.tcl 1f5e4a1dbbbc43c83cc6e74fe32c6c620502240b66c7c0f33a51378e78fc4edf F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5 @@ -1945,8 +1945,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 fbd288ff3d4ea47cd324b5952e7754a465901844f2d950f0860d4488d5b6eb9f -R a8535a7f26ac80cc50df61020309f93a +P 393fa32e188a017f431372b54037cb31e885030542f00d0bfd59da9d9db5c014 +R 816f74a7ffe21c8ebedcd180ac5b3970 U drh -Z c92d34f20cea24a5723ef3e12b37f708 +Z 533350b01dcc82c38ad1e7fcaa045f9f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 77dc1ec430..95f849d5cd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -393fa32e188a017f431372b54037cb31e885030542f00d0bfd59da9d9db5c014 \ No newline at end of file +bc33168cf1f48caf848c2dc5c3ae15e4efff8c0378f944eb5398a245139a2b35 \ No newline at end of file diff --git a/src/ctime.c b/src/ctime.c index 1463e4f552..a9391213d7 100644 --- a/src/ctime.c +++ b/src/ctime.c @@ -307,9 +307,6 @@ static const char * const sqlite3azCompileOpt[] = { #ifdef SQLITE_ENABLE_RTREE "ENABLE_RTREE", #endif -#ifdef SQLITE_ENABLE_SELECTTRACE - "ENABLE_SELECTTRACE", -#endif #ifdef SQLITE_ENABLE_SESSION "ENABLE_SESSION", #endif @@ -331,6 +328,9 @@ static const char * const sqlite3azCompileOpt[] = { #ifdef SQLITE_ENABLE_STMT_SCANSTATUS "ENABLE_STMT_SCANSTATUS", #endif +#ifdef SQLITE_ENABLE_TREETRACE + "ENABLE_TREETRACE", +#endif #ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION "ENABLE_UNKNOWN_SQL_FUNCTION", #endif diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 3a1cc85548..357e0f985d 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4433,9 +4433,19 @@ char *sqlite3VMPrintf(sqlite3*,const char*, va_list); #ifndef SQLITE_OMIT_WINDOWFUNC void sqlite3TreeViewWindow(TreeView*, const Window*, u8); void sqlite3TreeViewWinFunc(TreeView*, const Window*, u8); +#endif + void sqlite3ShowExpr(const Expr*); + void sqlite3ShowExprList(const ExprList*); + void sqlite3ShowIdList(const IdList*); + void sqlite3ShowSrcList(const SrcList*); + void sqlite3ShowSelect(const Select*); + void sqlite3ShowWith(const With*); + void sqlite3ShowUpsert(const Upsert*); +#ifndef SQLITE_OMIT_WINDOWFUNC + void sqlite3ShowWindow(const Window*); + void sqlite3ShowWinFunc(const Window*); #endif #endif - void sqlite3SetString(char **, sqlite3*, const char*); void sqlite3ErrorMsg(Parse*, const char*, ...); diff --git a/src/treeview.c b/src/treeview.c index bb7187ee65..e935c5bfa6 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -1055,4 +1055,26 @@ void sqlite3TreeViewUpdate( } } +/* +** These simplified versions of the tree-view routines omit unnecessary +** parameters. These variants are intended to be used from a symbolic +** debugger, such as "gdb", during interactive debugging sessions. +** +** This routines are given external linkage so that they will always be +** accessible to the debugging, and to avoid warnings about unused +** functions. But these routines only exist in debugging builds, so they +** do not contaminate the interface. +*/ +void sqlite3ShowExpr(const Expr *p){ sqlite3TreeViewExpr(0,p,0); } +void sqlite3ShowExprList(const ExprList *p){ sqlite3TreeViewExprList(0,p,0,0);} +void sqlite3ShowIdList(const IdList *p){ sqlite3TreeViewIdList(0,p,0,0); } +void sqlite3ShowSrcList(const SrcList *p){ sqlite3TreeViewSrcList(0,p); } +void sqlite3ShowSelect(const Select *p){ sqlite3TreeViewSelect(0,p,0); } +void sqlite3ShowWith(const With *p){ sqlite3TreeViewWith(0,p,0); } +void sqlite3ShowUpsert(const Upsert *p){ sqlite3TreeViewUpsert(0,p,0); } +#ifndef SQLITE_OMIT_WINDOWFUNC +void sqlite3ShowWindow(const Window *p){ sqlite3TreeViewWindow(0,p,0); } +void sqlite3ShowWinFunc(const Window *p){ sqlite3TreeViewWinFunc(0,p,0); } +#endif + #endif /* SQLITE_DEBUG */ diff --git a/tool/mkctimec.tcl b/tool/mkctimec.tcl index 745a59a229..bc723f4561 100755 --- a/tool/mkctimec.tcl +++ b/tool/mkctimec.tcl @@ -158,7 +158,6 @@ set boolean_defnil_options { SQLITE_ENABLE_QPSG SQLITE_ENABLE_RBU SQLITE_ENABLE_RTREE - SQLITE_ENABLE_SELECTTRACE SQLITE_ENABLE_SESSION SQLITE_ENABLE_SNAPSHOT SQLITE_ENABLE_SORTER_REFERENCES @@ -166,6 +165,7 @@ set boolean_defnil_options { SQLITE_ENABLE_STAT4 SQLITE_ENABLE_STMT_SCANSTATUS SQLITE_ENABLE_STMTVTAB + SQLITE_ENABLE_TREETRACE SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION SQLITE_ENABLE_UNLOCK_NOTIFY SQLITE_ENABLE_UPDATE_DELETE_LIMIT diff --git a/tool/mksqlite3c.tcl b/tool/mksqlite3c.tcl index 1a35fc0ea3..595fc4c602 100644 --- a/tool/mksqlite3c.tcl +++ b/tool/mksqlite3c.tcl @@ -291,7 +291,8 @@ proc copy_file {filename} { # Add the SQLITE_PRIVATE before variable declarations or # definitions for internal use regsub {^SQLITE_API } $line {} line - if {![regexp {^sqlite3_} $varname]} { + if {![regexp {^sqlite3_} $varname] + && ![regexp {^sqlite3Show[A-Z]} $varname]} { regsub {^extern } $line {} line puts $out "SQLITE_PRIVATE $line" } else { From c16a5686fe4860b86a30a8357314ed2171f75d40 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 6 Apr 2022 12:54:41 +0000 Subject: [PATCH 075/259] Corrections and updates to the header comment describing the TriggerStep object. No changes to code. FossilOrigin-Name: abb34c0830a49d4f4e277ddd17e710529e87cba7061f3546079dbba2f82b020e --- manifest | 12 +++--- manifest.uuid | 2 +- src/sqliteInt.h | 107 +++++++++++++++++++++++++----------------------- 3 files changed, 63 insertions(+), 58 deletions(-) diff --git a/manifest b/manifest index 900bed8717..7e989d04ad 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssqlite3Show()\sfamily\sof\sdebugging\sinterfaces\sunder\sSQLITE_DEBUG.\nNo\schanges\sto\sdeliverable\sbuilds.\s\sRename\sSQLITE_ENABLE_SELECTTRACE\sto\nSQLITE_ENABLE_TREETRACE\sin\sctime.c. -D 2022-04-06T12:25:04.844 +C Corrections\sand\supdates\sto\sthe\sheader\scomment\sdescribing\sthe\nTriggerStep\sobject.\s\sNo\schanges\sto\scode. +D 2022-04-06T12:54:41.675 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -557,7 +557,7 @@ F src/shell.c.in 18832612e74c92bbd25d88e1f92685f66589262f68cca1001d2a43bd6dd0ed6 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h 811d8defe1dff439db365e18129216140204462665d19c23be14b78affea3e18 +F src/sqliteInt.h 2cd3008975523038cf01ce77d3ec61c190466c5879aa3856fa79c2cb00e5240d F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -1945,8 +1945,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 393fa32e188a017f431372b54037cb31e885030542f00d0bfd59da9d9db5c014 -R 816f74a7ffe21c8ebedcd180ac5b3970 +P bc33168cf1f48caf848c2dc5c3ae15e4efff8c0378f944eb5398a245139a2b35 +R 2e653a42f648804346ba4eb540aa80b7 U drh -Z 533350b01dcc82c38ad1e7fcaa045f9f +Z 6f432e2a1d80c3ecd80c5f978baed379 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 95f849d5cd..2d05530aef 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bc33168cf1f48caf848c2dc5c3ae15e4efff8c0378f944eb5398a245139a2b35 \ No newline at end of file +abb34c0830a49d4f4e277ddd17e710529e87cba7061f3546079dbba2f82b020e \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 357e0f985d..63d7c3286c 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3727,20 +3727,20 @@ struct AuthContext { #define OPFLAG_PREFORMAT 0x80 /* OP_Insert uses preformatted cell */ /* - * Each trigger present in the database schema is stored as an instance of - * struct Trigger. - * - * Pointers to instances of struct Trigger are stored in two ways. - * 1. In the "trigHash" hash table (part of the sqlite3* that represents the - * database). This allows Trigger structures to be retrieved by name. - * 2. All triggers associated with a single table form a linked list, using the - * pNext member of struct Trigger. A pointer to the first element of the - * linked list is stored as the "pTrigger" member of the associated - * struct Table. - * - * The "step_list" member points to the first element of a linked list - * containing the SQL statements specified as the trigger program. - */ +** Each trigger present in the database schema is stored as an instance of +** struct Trigger. +** +** Pointers to instances of struct Trigger are stored in two ways. +** 1. In the "trigHash" hash table (part of the sqlite3* that represents the +** database). This allows Trigger structures to be retrieved by name. +** 2. All triggers associated with a single table form a linked list, using the +** pNext member of struct Trigger. A pointer to the first element of the +** linked list is stored as the "pTrigger" member of the associated +** struct Table. +** +** The "step_list" member points to the first element of a linked list +** containing the SQL statements specified as the trigger program. +*/ struct Trigger { char *zName; /* The name of the trigger */ char *table; /* The table or view to which the trigger applies */ @@ -3767,43 +3767,48 @@ struct Trigger { #define TRIGGER_AFTER 2 /* - * An instance of struct TriggerStep is used to store a single SQL statement - * that is a part of a trigger-program. - * - * Instances of struct TriggerStep are stored in a singly linked list (linked - * using the "pNext" member) referenced by the "step_list" member of the - * associated struct Trigger instance. The first element of the linked list is - * the first step of the trigger-program. - * - * The "op" member indicates whether this is a "DELETE", "INSERT", "UPDATE" or - * "SELECT" statement. The meanings of the other members is determined by the - * value of "op" as follows: - * - * (op == TK_INSERT) - * orconf -> stores the ON CONFLICT algorithm - * pSelect -> If this is an INSERT INTO ... SELECT ... statement, then - * this stores a pointer to the SELECT statement. Otherwise NULL. - * zTarget -> Dequoted name of the table to insert into. - * pExprList -> If this is an INSERT INTO ... VALUES ... statement, then - * this stores values to be inserted. Otherwise NULL. - * pIdList -> If this is an INSERT INTO ... () VALUES ... - * statement, then this stores the column-names to be - * inserted into. - * - * (op == TK_DELETE) - * zTarget -> Dequoted name of the table to delete from. - * pWhere -> The WHERE clause of the DELETE statement if one is specified. - * Otherwise NULL. - * - * (op == TK_UPDATE) - * zTarget -> Dequoted name of the table to update. - * pWhere -> The WHERE clause of the UPDATE statement if one is specified. - * Otherwise NULL. - * pExprList -> A list of the columns to update and the expressions to update - * them to. See sqlite3Update() documentation of "pChanges" - * argument. - * - */ +** An instance of struct TriggerStep is used to store a single SQL statement +** that is a part of a trigger-program. +** +** Instances of struct TriggerStep are stored in a singly linked list (linked +** using the "pNext" member) referenced by the "step_list" member of the +** associated struct Trigger instance. The first element of the linked list is +** the first step of the trigger-program. +** +** The "op" member indicates whether this is a "DELETE", "INSERT", "UPDATE" or +** "SELECT" statement. The meanings of the other members is determined by the +** value of "op" as follows: +** +** (op == TK_INSERT) +** orconf -> stores the ON CONFLICT algorithm +** pSelect -> The content to be inserted - either a SELECT statement or +** a VALUES clause. +** zTarget -> Dequoted name of the table to insert into. +** pIdList -> If this is an INSERT INTO ... () VALUES ... +** statement, then this stores the column-names to be +** inserted into. +** pUpsert -> The ON CONFLICT clauses for an Upsert +** +** (op == TK_DELETE) +** zTarget -> Dequoted name of the table to delete from. +** pWhere -> The WHERE clause of the DELETE statement if one is specified. +** Otherwise NULL. +** +** (op == TK_UPDATE) +** zTarget -> Dequoted name of the table to update. +** pWhere -> The WHERE clause of the UPDATE statement if one is specified. +** Otherwise NULL. +** pExprList -> A list of the columns to update and the expressions to update +** them to. See sqlite3Update() documentation of "pChanges" +** argument. +** +** (op == TK_SELECT) +** pSelect -> The SELECT statement +** +** (op == TK_RETURNING) +** pExprList -> The list of expressions that follow the RETURNING keyword. +** +*/ struct TriggerStep { u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT, ** or TK_RETURNING */ From 2a7dcbfbb0e6fcd255fda917d0f28a10588b7dd0 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 6 Apr 2022 15:41:53 +0000 Subject: [PATCH 076/259] Attempt to show triggers in the TreeView output from DELETE, INSERT, and UPDATE statements. FossilOrigin-Name: b0939d6f4d94b45dce53ace6295508a67d574cc72bd6977623bf77065b3c4e64 --- manifest | 20 ++-- manifest.uuid | 2 +- src/delete.c | 15 +-- src/insert.c | 15 +-- src/sqliteInt.h | 25 +++-- src/treeview.c | 264 +++++++++++++++++++++++++++++++----------------- src/update.c | 15 +-- 7 files changed, 227 insertions(+), 129 deletions(-) diff --git a/manifest b/manifest index 7e989d04ad..233a3a04fd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Corrections\sand\supdates\sto\sthe\sheader\scomment\sdescribing\sthe\nTriggerStep\sobject.\s\sNo\schanges\sto\scode. -D 2022-04-06T12:54:41.675 +C Attempt\sto\sshow\striggers\sin\sthe\sTreeView\soutput\sfrom\sDELETE,\sINSERT,\sand\nUPDATE\sstatements. +D 2022-04-06T15:41:53.521 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -502,7 +502,7 @@ F src/ctime.c 026dbdcdbd8c3cde98a88483ee88310ff43150ab164ad768f12cc700a11495ad F src/date.c 15082566229d4b1e5f24fdb490bf9bcc68824b911d70e3573ef075a1b9e2d26f F src/dbpage.c a70be9a4879ac5392673a1050d526a72b8b2f9938df7049f65348566a2637db3 F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d -F src/delete.c f9e765869d4eb1bb639df0d77a8eda36bf064e83d21777b1ea772cac66786df5 +F src/delete.c dafdc71a097f84fbbf66164d8842ebcb9bacf74e069658001fd70b62ee0acbdb F src/expr.c 3cdb00b6c15f815c94836e7b4474b675155d1279e64804f6ab5816188a9b05b6 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 94927f9b46d72a9cb858c208febf04ceb0a3270c5fa5fd0b7f436cf16e09f72a @@ -512,7 +512,7 @@ F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51 F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 1e76792fef634bc84dfc79080e632fe5bf833fadb0777510785c6a8fc13e5e8c +F src/insert.c d97fc6f1824297bc3da8e54daa902d6a458cb941b17aaff891564ffa34845e4a F src/json.c 7749b98c62f691697c7ee536b570c744c0583cab4a89200fdd0fc2aa8cc8cbd6 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 2ecb1441f9b1c22e9e022ee0776e67d259facf34b56ba892b206f0a294ee6f8c @@ -557,7 +557,7 @@ F src/shell.c.in 18832612e74c92bbd25d88e1f92685f66589262f68cca1001d2a43bd6dd0ed6 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h 2cd3008975523038cf01ce77d3ec61c190466c5879aa3856fa79c2cb00e5240d +F src/sqliteInt.h e7b2a0a394629bb8d005bb1b64f5d34737ab4659f894cb1be0a322a2199873e3 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -617,9 +617,9 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98 -F src/treeview.c 9f867920ef5a39659d034fc2e62c737240d9751a833b0a2b71058ee0304224bc +F src/treeview.c 4ed907fc341bbab963a31ffccd803e13af99eb89376de5cbd0418b1fba0c9ebf F src/trigger.c 8caa0baf1b18522863cf0fd611ef483962cfa50155ca82ad43e63b20f863a683 -F src/update.c c79e4ba491dbce7e0bd8995aeccbbf453843c763a0670c7a3414094610b0d71f +F src/update.c 2cfaded82ca80ff56afb8c3ae5e88284e0824bfd86119827cc22481959f96f92 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 @@ -1945,8 +1945,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 bc33168cf1f48caf848c2dc5c3ae15e4efff8c0378f944eb5398a245139a2b35 -R 2e653a42f648804346ba4eb540aa80b7 +P abb34c0830a49d4f4e277ddd17e710529e87cba7061f3546079dbba2f82b020e +R 3b68aded646af44203f4f0b172b58b76 U drh -Z 6f432e2a1d80c3ecd80c5f978baed379 +Z c0df658f2ef079af39e2552d24158d31 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2d05530aef..bb2179135e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -abb34c0830a49d4f4e277ddd17e710529e87cba7061f3546079dbba2f82b020e \ No newline at end of file +b0939d6f4d94b45dce53ace6295508a67d574cc72bd6977623bf77065b3c4e64 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index ca3705f552..a4c5d53c58 100644 --- a/src/delete.c +++ b/src/delete.c @@ -300,13 +300,6 @@ void sqlite3DeleteFrom( assert( db->mallocFailed==0 ); assert( pTabList->nSrc==1 ); -#if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x10000 ){ - sqlite3TreeViewDelete(0, pParse->pWith, pTabList, pWhere, - pOrderBy, pLimit); - } -#endif - /* Locate the table which we want to delete. This table has to be ** put in an SrcList structure because some of the subroutines we ** will be calling are designed to work with multiple tables and expect @@ -331,6 +324,14 @@ void sqlite3DeleteFrom( # define isView 0 #endif +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x10000 ){ + sqlite3TreeViewLine(0, "In sqlite3Delete() at %s:%d", __FILE__, __LINE__); + sqlite3TreeViewDelete(pParse->pWith, pTabList, pWhere, + pOrderBy, pLimit, pTrigger); + } +#endif + #ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT if( !isView ){ pWhere = sqlite3LimitWhere( diff --git a/src/insert.c b/src/insert.c index 9acddd4070..e56d037194 100644 --- a/src/insert.c +++ b/src/insert.c @@ -722,13 +722,6 @@ void sqlite3Insert( assert( db->mallocFailed==0 ); dest.iSDParm = 0; /* Suppress a harmless compiler warning */ -#if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x10000 ){ - sqlite3TreeViewInsert(0, pParse->pWith, pTabList, pColumn, pSelect, - onError, pUpsert); - } -#endif - /* If the Select object is really just a simple VALUES() list with a ** single row (the common case) then keep that one row of values ** and discard the other (unused) parts of the pSelect object @@ -772,6 +765,14 @@ void sqlite3Insert( #endif assert( (pTrigger && tmask) || (pTrigger==0 && tmask==0) ); +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x10000 ){ + sqlite3TreeViewLine(0, "In sqlite3Insert() at %s:%d", __FILE__, __LINE__); + sqlite3TreeViewInsert(pParse->pWith, pTabList, pColumn, pSelect, + onError, pUpsert, pTrigger); + } +#endif + /* If pTab is really a view, make sure it has been initialized. ** ViewGetColumnNames() is a no-op if pTab is not a view. */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 63d7c3286c..ef28573456 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4418,6 +4418,7 @@ char *sqlite3VMPrintf(sqlite3*,const char*, va_list); #endif #if defined(SQLITE_DEBUG) + void sqlite3TreeViewLine(TreeView*, const char *zFormat, ...); void sqlite3TreeViewExpr(TreeView*, const Expr*, u8); void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, const char*); void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*); @@ -4427,14 +4428,18 @@ char *sqlite3VMPrintf(sqlite3*,const char*, va_list); void sqlite3TreeViewSelect(TreeView*, const Select*, u8); void sqlite3TreeViewWith(TreeView*, const With*, u8); void sqlite3TreeViewUpsert(TreeView*, const Upsert*, u8); - void sqlite3TreeViewDelete(TreeView*, const With*, const SrcList*, - const Expr*,const ExprList*,const Expr*); - void sqlite3TreeViewInsert(TreeView*, const With*, const SrcList*, + void sqlite3TreeViewDelete(const With*, const SrcList*, const Expr*, + const ExprList*,const Expr*, const Trigger*); + void sqlite3TreeViewInsert(const With*, const SrcList*, const IdList*, const Select*, int, - const Upsert*); - void sqlite3TreeViewUpdate(TreeView*, const With*, const SrcList*, - const ExprList*, const Expr*, int, - const ExprList*, const Expr*, const Upsert*); + const Upsert*, const Trigger*); + void sqlite3TreeViewUpdate(const With*, const SrcList*, const ExprList*, + const Expr*, int, const ExprList*, const Expr*, + const Upsert*, const Trigger*); +#ifndef SQLITE_OMIT_TRIGGER + void sqlite3TreeViewTriggerStep(TreeView*, const TriggerStep*, u8, u8); + void sqlite3TreeViewTrigger(TreeView*, const Trigger*, u8, u8); +#endif #ifndef SQLITE_OMIT_WINDOWFUNC void sqlite3TreeViewWindow(TreeView*, const Window*, u8); void sqlite3TreeViewWinFunc(TreeView*, const Window*, u8); @@ -4446,6 +4451,12 @@ char *sqlite3VMPrintf(sqlite3*,const char*, va_list); void sqlite3ShowSelect(const Select*); void sqlite3ShowWith(const With*); void sqlite3ShowUpsert(const Upsert*); +#ifndef SQLITE_OMIT_TRIGGER + void sqlite3ShowTriggerStep(const TriggerStep*); + void sqlite3ShowTriggerStepList(const TriggerStep*); + void sqlite3ShowTrigger(const Trigger*); + void sqlite3ShowTriggerList(const Trigger*); +#endif #ifndef SQLITE_OMIT_WINDOWFUNC void sqlite3ShowWindow(const Window*); void sqlite3ShowWinFunc(const Window*); diff --git a/src/treeview.c b/src/treeview.c index e935c5bfa6..a63f94bfd5 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -24,33 +24,37 @@ ** Add a new subitem to the tree. The moreToFollow flag indicates that this ** is not the last item in the tree. */ -static TreeView *sqlite3TreeViewPush(TreeView *p, u8 moreToFollow){ +static void sqlite3TreeViewPush(TreeView **pp, u8 moreToFollow){ + TreeView *p = *pp; if( p==0 ){ - p = sqlite3_malloc64( sizeof(*p) ); - if( p==0 ) return 0; + *pp = p = sqlite3_malloc64( sizeof(*p) ); + if( p==0 ) return; memset(p, 0, sizeof(*p)); }else{ p->iLevel++; } assert( moreToFollow==0 || moreToFollow==1 ); if( p->iLevel<(int)sizeof(p->bLine) ) p->bLine[p->iLevel] = moreToFollow; - return p; } /* ** Finished with one layer of the tree */ -static void sqlite3TreeViewPop(TreeView *p){ +static void sqlite3TreeViewPop(TreeView **pp){ + TreeView *p = *pp; if( p==0 ) return; p->iLevel--; - if( p->iLevel<0 ) sqlite3_free(p); + if( p->iLevel<0 ){ + sqlite3_free(p); + *pp = 0; + } } /* ** Generate a single line of output for the tree, with a prefix that contains ** all the appropriate tree lines */ -static void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){ +void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){ va_list ap; int i; StrAccum acc; @@ -78,7 +82,7 @@ static void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){ ** Shorthand for starting a new tree item that consists of a single label */ static void sqlite3TreeViewItem(TreeView *p, const char *zLabel,u8 moreFollows){ - p = sqlite3TreeViewPush(p, moreFollows); + sqlite3TreeViewPush(&p, moreFollows); sqlite3TreeViewLine(p, "%s", zLabel); } @@ -95,7 +99,7 @@ void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){ sqlite3TreeViewLine(pView, "WITH (0x%p)", pWith); } if( pWith->nCte>0 ){ - pView = sqlite3TreeViewPush(pView, moreToFollow); + sqlite3TreeViewPush(&pView, moreToFollow); for(i=0; inCte; i++){ StrAccum x; char zLine[1000]; @@ -118,9 +122,9 @@ void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){ sqlite3StrAccumFinish(&x); sqlite3TreeViewItem(pView, zLine, inCte-1); sqlite3TreeViewSelect(pView, pCte->pSelect, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } } @@ -159,7 +163,7 @@ void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ if( pItem->fg.isTabFunc ){ sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:"); } - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } } @@ -173,11 +177,11 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ sqlite3TreeViewLine(pView, "nil-SELECT"); return; } - pView = sqlite3TreeViewPush(pView, moreToFollow); + sqlite3TreeViewPush(&pView, moreToFollow); if( p->pWith ){ sqlite3TreeViewWith(pView, p->pWith, 1); cnt = 1; - sqlite3TreeViewPush(pView, 1); + sqlite3TreeViewPush(&pView, 1); } do{ if( p->selFlags & SF_WhereBegin ){ @@ -191,7 +195,7 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ (int)p->nSelectRow ); } - if( cnt++ ) sqlite3TreeViewPop(pView); + if( cnt++ ) sqlite3TreeViewPop(&pView); if( p->pPrior ){ n = 1000; }else{ @@ -214,24 +218,24 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ #ifndef SQLITE_OMIT_WINDOWFUNC if( p->pWin ){ Window *pX; - pView = sqlite3TreeViewPush(pView, (n--)>0); + sqlite3TreeViewPush(&pView, (n--)>0); sqlite3TreeViewLine(pView, "window-functions"); for(pX=p->pWin; pX; pX=pX->pNextWin){ sqlite3TreeViewWinFunc(pView, pX, pX->pNextWin!=0); } - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } #endif if( p->pSrc && p->pSrc->nSrc ){ - pView = sqlite3TreeViewPush(pView, (n--)>0); + sqlite3TreeViewPush(&pView, (n--)>0); sqlite3TreeViewLine(pView, "FROM"); sqlite3TreeViewSrcList(pView, p->pSrc); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } if( p->pWhere ){ sqlite3TreeViewItem(pView, "WHERE", (n--)>0); sqlite3TreeViewExpr(pView, p->pWhere, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } if( p->pGroupBy ){ sqlite3TreeViewExprList(pView, p->pGroupBy, (n--)>0, "GROUPBY"); @@ -239,7 +243,7 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ if( p->pHaving ){ sqlite3TreeViewItem(pView, "HAVING", (n--)>0); sqlite3TreeViewExpr(pView, p->pHaving, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } #ifndef SQLITE_OMIT_WINDOWFUNC if( p->pWinDefn ){ @@ -248,7 +252,7 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ for(pX=p->pWinDefn; pX; pX=pX->pNextWin){ sqlite3TreeViewWindow(pView, pX, pX->pNextWin!=0); } - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } #endif if( p->pOrderBy ){ @@ -260,9 +264,9 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ if( p->pLimit->pRight ){ sqlite3TreeViewItem(pView, "OFFSET", (n--)>0); sqlite3TreeViewExpr(pView, p->pLimit->pRight, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } if( p->pPrior ){ const char *zOp = "UNION"; @@ -275,7 +279,7 @@ void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ } p = p->pPrior; }while( p!=0 ); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } #ifndef SQLITE_OMIT_WINDOWFUNC @@ -291,24 +295,24 @@ void sqlite3TreeViewBound( switch( eBound ){ case TK_UNBOUNDED: { sqlite3TreeViewItem(pView, "UNBOUNDED", moreToFollow); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); break; } case TK_CURRENT: { sqlite3TreeViewItem(pView, "CURRENT", moreToFollow); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); break; } case TK_PRECEDING: { sqlite3TreeViewItem(pView, "PRECEDING", moreToFollow); sqlite3TreeViewExpr(pView, pExpr, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); break; } case TK_FOLLOWING: { sqlite3TreeViewItem(pView, "FOLLOWING", moreToFollow); sqlite3TreeViewExpr(pView, pExpr, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); break; } } @@ -324,9 +328,9 @@ void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){ if( pWin->pFilter ){ sqlite3TreeViewItem(pView, "FILTER", 1); sqlite3TreeViewExpr(pView, pWin->pFilter, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } - pView = sqlite3TreeViewPush(pView, more); + sqlite3TreeViewPush(&pView, more); if( pWin->zName ){ sqlite3TreeViewLine(pView, "OVER %s (%p)", pWin->zName, pWin); }else{ @@ -337,9 +341,9 @@ void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){ if( pWin->eFrmType ) nElement++; if( pWin->eExclude ) nElement++; if( pWin->zBase ){ - sqlite3TreeViewPush(pView, (--nElement)>0); + sqlite3TreeViewPush(&pView, (--nElement)>0); sqlite3TreeViewLine(pView, "window: %s", pWin->zBase); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } if( pWin->pPartition ){ sqlite3TreeViewExprList(pView, pWin->pPartition, nElement>0,"PARTITION-BY"); @@ -357,7 +361,7 @@ void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){ sqlite3TreeViewItem(pView, zBuf, (--nElement)>0); sqlite3TreeViewBound(pView, pWin->eStart, pWin->pStart, 1); sqlite3TreeViewBound(pView, pWin->eEnd, pWin->pEnd, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } if( pWin->eExclude ){ char zBuf[30]; @@ -372,11 +376,11 @@ void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){ zExclude = zBuf; break; } - sqlite3TreeViewPush(pView, 0); + sqlite3TreeViewPush(&pView, 0); sqlite3TreeViewLine(pView, "EXCLUDE %s", zExclude); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } #endif /* SQLITE_OMIT_WINDOWFUNC */ @@ -385,11 +389,11 @@ void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){ ** Generate a human-readable explanation for a Window Function object */ void sqlite3TreeViewWinFunc(TreeView *pView, const Window *pWin, u8 more){ - pView = sqlite3TreeViewPush(pView, more); + sqlite3TreeViewPush(&pView, more); sqlite3TreeViewLine(pView, "WINFUNC %s(%d)", pWin->pWFunc->zName, pWin->pWFunc->nArg); sqlite3TreeViewWindow(pView, pWin, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } #endif /* SQLITE_OMIT_WINDOWFUNC */ @@ -400,10 +404,10 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ const char *zBinOp = 0; /* Binary operator */ const char *zUniOp = 0; /* Unary operator */ char zFlgs[200]; - pView = sqlite3TreeViewPush(pView, moreToFollow); + sqlite3TreeViewPush(&pView, moreToFollow); if( pExpr==0 ){ sqlite3TreeViewLine(pView, "nil"); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); return; } if( pExpr->flags || pExpr->affExpr || pExpr->vvaFlags ){ @@ -760,7 +764,7 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ sqlite3TreeViewLine(pView, "%s%s", zUniOp, zFlgs); sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); } - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } @@ -784,7 +788,7 @@ void sqlite3TreeViewBareExprList( int moreToFollow = inExpr - 1; if( pList->a[i].eEName!=ENAME_NAME ) zName = 0; if( j || zName ){ - sqlite3TreeViewPush(pView, moreToFollow); + sqlite3TreeViewPush(&pView, moreToFollow); moreToFollow = 0; sqlite3TreeViewLine(pView, 0); if( zName ){ @@ -798,7 +802,7 @@ void sqlite3TreeViewBareExprList( } sqlite3TreeViewExpr(pView, pList->a[i].pExpr, moreToFollow); if( j || zName ){ - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } } } @@ -809,9 +813,9 @@ void sqlite3TreeViewExprList( u8 moreToFollow, const char *zLabel ){ - pView = sqlite3TreeViewPush(pView, moreToFollow); + sqlite3TreeViewPush(&pView, moreToFollow); sqlite3TreeViewBareExprList(pView, pList, zLabel); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } /* @@ -832,11 +836,11 @@ void sqlite3TreeViewBareIdList( char *zName = pList->a[i].zName; int moreToFollow = inId - 1; if( zName==0 ) zName = "(null)"; - sqlite3TreeViewPush(pView, moreToFollow); + sqlite3TreeViewPush(&pView, moreToFollow); moreToFollow = 0; sqlite3TreeViewLine(pView, 0); fprintf(stdout, "%s (%d)\n", zName, pList->a[i].idx); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } } } @@ -846,9 +850,9 @@ void sqlite3TreeViewIdList( u8 moreToFollow, const char *zLabel ){ - pView = sqlite3TreeViewPush(pView, moreToFollow); + sqlite3TreeViewPush(&pView, moreToFollow); sqlite3TreeViewBareIdList(pView, pList, zLabel); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } /* @@ -860,10 +864,10 @@ void sqlite3TreeViewUpsert( u8 moreToFollow ){ if( pUpsert==0 ) return; - pView = sqlite3TreeViewPush(pView, moreToFollow); + sqlite3TreeViewPush(&pView, moreToFollow); while( pUpsert ){ int n; - sqlite3TreeViewPush(pView, pUpsert->pNextUpsert!=0 || moreToFollow); + sqlite3TreeViewPush(&pView, pUpsert->pNextUpsert!=0 || moreToFollow); sqlite3TreeViewLine(pView, "ON CONFLICT DO %s", pUpsert->isDoUpdate ? "UPDATE" : "NOTHING"); n = (pUpsert->pUpsertSet!=0) + (pUpsert->pUpsertWhere!=0); @@ -872,12 +876,12 @@ void sqlite3TreeViewUpsert( if( pUpsert->pUpsertWhere ){ sqlite3TreeViewItem(pView, "WHERE", (n--)>0); sqlite3TreeViewExpr(pView, pUpsert->pUpsertWhere, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); pUpsert = pUpsert->pNextUpsert; } - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } /* @@ -885,47 +889,53 @@ void sqlite3TreeViewUpsert( ** into generating an DELETE statement. */ void sqlite3TreeViewDelete( - TreeView *pView, const With *pWith, const SrcList *pTabList, const Expr *pWhere, const ExprList *pOrderBy, - const Expr *pLimit + const Expr *pLimit, + const Trigger *pTrigger ){ int n = 0; + TreeView *pView = 0; + sqlite3TreeViewPush(&pView, 0); sqlite3TreeViewLine(pView, "DELETE"); - pView = sqlite3TreeViewPush(pView, 0); if( pWith ) n++; if( pTabList ) n++; if( pWhere ) n++; if( pOrderBy ) n++; if( pLimit ) n++; + if( pTrigger ) n++; if( pWith ){ - pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewPush(&pView, (--n)>0); sqlite3TreeViewWith(pView, pWith, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } if( pTabList ){ - pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewPush(&pView, (--n)>0); sqlite3TreeViewLine(pView, "FROM"); sqlite3TreeViewSrcList(pView, pTabList); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } if( pWhere ){ - pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewPush(&pView, (--n)>0); sqlite3TreeViewLine(pView, "WHERE"); sqlite3TreeViewExpr(pView, pWhere, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } if( pOrderBy ){ sqlite3TreeViewExprList(pView, pOrderBy, (--n)>0, "ORDER-BY"); } if( pLimit ){ - pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewPush(&pView, (--n)>0); sqlite3TreeViewLine(pView, "LIMIT"); sqlite3TreeViewExpr(pView, pLimit, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } + if( pTrigger ){ + sqlite3TreeViewTrigger(pView, pTrigger, (--n)>0, 1); + } + sqlite3TreeViewPop(&pView); } /* @@ -933,14 +943,15 @@ void sqlite3TreeViewDelete( ** into generating an INSERT statement. */ void sqlite3TreeViewInsert( - TreeView *pView, const With *pWith, const SrcList *pTabList, const IdList *pColumnList, const Select *pSelect, int onError, - const Upsert *pUpsert + const Upsert *pUpsert, + const Trigger *pTrigger ){ + TreeView *pView = 0; int n = 0; const char *zLabel = "INSERT"; switch( onError ){ @@ -950,39 +961,44 @@ void sqlite3TreeViewInsert( case OE_Abort: zLabel = "INSERT OR ABORT"; break; case OE_Fail: zLabel = "INSERT OR FAIL"; break; } + sqlite3TreeViewPush(&pView, 0); sqlite3TreeViewLine(pView, zLabel); - pView = sqlite3TreeViewPush(pView, 0); if( pWith ) n++; if( pTabList ) n++; if( pColumnList ) n++; if( pSelect ) n++; if( pUpsert ) n++; + if( pTrigger ) n++; if( pWith ){ - pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewPush(&pView, (--n)>0); sqlite3TreeViewWith(pView, pWith, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } if( pTabList ){ - pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewPush(&pView, (--n)>0); sqlite3TreeViewLine(pView, "INTO"); sqlite3TreeViewSrcList(pView, pTabList); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } if( pColumnList ){ sqlite3TreeViewIdList(pView, pColumnList, (--n)>0, "COLUMNS"); } if( pSelect ){ - pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewPush(&pView, (--n)>0); sqlite3TreeViewLine(pView, "DATA-SOURCE"); sqlite3TreeViewSelect(pView, pSelect, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } if( pUpsert ){ - pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewPush(&pView, (--n)>0); sqlite3TreeViewLine(pView, "UPSERT"); sqlite3TreeViewUpsert(pView, pUpsert, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } + if( pTrigger ){ + sqlite3TreeViewTrigger(pView, pTrigger, (--n)>0, 1); + } + sqlite3TreeViewPop(&pView); } /* @@ -990,7 +1006,6 @@ void sqlite3TreeViewInsert( ** into generating an UPDATE statement. */ void sqlite3TreeViewUpdate( - TreeView *pView, const With *pWith, const SrcList *pTabList, const ExprList *pChanges, @@ -998,9 +1013,11 @@ void sqlite3TreeViewUpdate( int onError, const ExprList *pOrderBy, const Expr *pLimit, - const Upsert *pUpsert + const Upsert *pUpsert, + const Trigger *pTrigger ){ int n = 0; + TreeView *pView = 0; const char *zLabel = "UPDATE"; switch( onError ){ case OE_Replace: zLabel = "UPDATE OR REPLACE"; break; @@ -1009,8 +1026,8 @@ void sqlite3TreeViewUpdate( case OE_Abort: zLabel = "UPDATE OR ABORT"; break; case OE_Fail: zLabel = "UPDATE OR FAIL"; break; } + sqlite3TreeViewPush(&pView, 0); sqlite3TreeViewLine(pView, zLabel); - pView = sqlite3TreeViewPush(pView, 0); if( pWith ) n++; if( pTabList ) n++; if( pChanges ) n++; @@ -1018,43 +1035,100 @@ void sqlite3TreeViewUpdate( if( pOrderBy ) n++; if( pLimit ) n++; if( pUpsert ) n++; + if( pTrigger ) n++; if( pWith ){ - pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewPush(&pView, (--n)>0); sqlite3TreeViewWith(pView, pWith, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } if( pTabList ){ - pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewPush(&pView, (--n)>0); sqlite3TreeViewLine(pView, "FROM"); sqlite3TreeViewSrcList(pView, pTabList); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } if( pChanges ){ sqlite3TreeViewExprList(pView, pChanges, (--n)>0, "SET"); } if( pWhere ){ - pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewPush(&pView, (--n)>0); sqlite3TreeViewLine(pView, "WHERE"); sqlite3TreeViewExpr(pView, pWhere, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } if( pOrderBy ){ sqlite3TreeViewExprList(pView, pOrderBy, (--n)>0, "ORDER-BY"); } if( pLimit ){ - pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewPush(&pView, (--n)>0); sqlite3TreeViewLine(pView, "LIMIT"); sqlite3TreeViewExpr(pView, pLimit, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } if( pUpsert ){ - pView = sqlite3TreeViewPush(pView, (--n)>0); + sqlite3TreeViewPush(&pView, (--n)>0); sqlite3TreeViewLine(pView, "UPSERT"); sqlite3TreeViewUpsert(pView, pUpsert, 0); - sqlite3TreeViewPop(pView); + sqlite3TreeViewPop(&pView); } + if( pTrigger ){ + sqlite3TreeViewTrigger(pView, pTrigger, (--n)>0, 1); + } + sqlite3TreeViewPop(&pView); } +#ifndef SQLITE_OMIT_TRIGGER +/* +** Show a human-readable graph of a TriggerStep +*/ +void sqlite3TreeViewTriggerStep( + TreeView *pView, + const TriggerStep *pStep, + u8 moreToFollow, + u8 showFullList +){ + int cnt = 0; + if( pStep==0 ) return; + sqlite3TreeViewPush(&pView, + moreToFollow || (showFullList && pStep->pNext!=0)); + do{ + if( cnt++ && pStep->pNext==0 ){ + sqlite3TreeViewPop(&pView); + sqlite3TreeViewPush(&pView, 0); + } + sqlite3TreeViewLine(pView, "%s", pStep->zSpan ? pStep->zSpan : "RETURNING"); + }while( showFullList && (pStep = pStep->pNext)!=0 ); + sqlite3TreeViewPop(&pView); +} + +/* +** Show a human-readable graph of a Trigger +*/ +void sqlite3TreeViewTrigger( + TreeView *pView, + const Trigger *pTrigger, + u8 moreToFollow, + u8 showFullList +){ + int cnt = 0; + if( pTrigger==0 ) return; + sqlite3TreeViewPush(&pView, + moreToFollow || (showFullList && pTrigger->pNext!=0)); + do{ + if( cnt++ && pTrigger->pNext==0 ){ + sqlite3TreeViewPop(&pView); + sqlite3TreeViewPush(&pView, 0); + } + sqlite3TreeViewLine(pView, "TRIGGER %s", pTrigger->zName); + sqlite3TreeViewPush(&pView, 0); + sqlite3TreeViewTriggerStep(pView, pTrigger->step_list, 0, 1); + sqlite3TreeViewPop(&pView); + }while( showFullList && (pTrigger = pTrigger->pNext)!=0 ); + sqlite3TreeViewPop(&pView); +} +#endif /* SQLITE_OMIT_TRIGGER */ + + /* ** These simplified versions of the tree-view routines omit unnecessary ** parameters. These variants are intended to be used from a symbolic @@ -1072,6 +1146,16 @@ void sqlite3ShowSrcList(const SrcList *p){ sqlite3TreeViewSrcList(0,p); } void sqlite3ShowSelect(const Select *p){ sqlite3TreeViewSelect(0,p,0); } void sqlite3ShowWith(const With *p){ sqlite3TreeViewWith(0,p,0); } void sqlite3ShowUpsert(const Upsert *p){ sqlite3TreeViewUpsert(0,p,0); } +#ifndef SQLITE_OMIT_TRIGGER +void sqlite3ShowTriggerStep(const TriggerStep *p){ + sqlite3TreeViewTriggerStep(0,p,0,0); +} +void sqlite3ShowTriggerStepList(const TriggerStep *p){ + sqlite3TreeViewTriggerStep(0,p,0,1); +} +void sqlite3ShowTrigger(const Trigger *p){ sqlite3TreeViewTrigger(0,p,0,0); } +void sqlite3ShowTriggerList(const Trigger *p){ sqlite3TreeViewTrigger(0,p,0,1);} +#endif #ifndef SQLITE_OMIT_WINDOWFUNC void sqlite3ShowWindow(const Window *p){ sqlite3TreeViewWindow(0,p,0); } void sqlite3ShowWinFunc(const Window *p){ sqlite3TreeViewWinFunc(0,p,0); } diff --git a/src/update.c b/src/update.c index 908fc3ad6d..6547041472 100644 --- a/src/update.c +++ b/src/update.c @@ -353,13 +353,6 @@ void sqlite3Update( } assert( db->mallocFailed==0 ); -#if TREETRACE_ENABLED - if( sqlite3TreeTrace & 0x10000 ){ - sqlite3TreeViewUpdate(0, pParse->pWith, pTabList, pChanges, pWhere, - onError, pOrderBy, pLimit, pUpsert); - } -#endif - /* Locate the table which we want to update. */ pTab = sqlite3SrcListLookup(pParse, pTabList); @@ -383,6 +376,14 @@ void sqlite3Update( # define isView 0 #endif +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x10000 ){ + sqlite3TreeViewLine(0, "In sqlite3Update() at %s:%d", __FILE__, __LINE__); + sqlite3TreeViewUpdate(pParse->pWith, pTabList, pChanges, pWhere, + onError, pOrderBy, pLimit, pUpsert, pTrigger); + } +#endif + /* If there was a FROM clause, set nChangeFrom to the number of expressions ** in the change-list. Otherwise, set it to 0. There cannot be a FROM ** clause if this function is being called to generate code for part of From c2d0df95ba5312b420d7aa786ab805a5daeb1cc0 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 6 Apr 2022 18:30:17 +0000 Subject: [PATCH 077/259] Improvements to the display of AST for DML statements. FossilOrigin-Name: 84c239a071cfaf8af107646f01ef269e2915fd2384e95927d484f2e408ba6bbf --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/insert.c | 2 +- src/select.c | 8 ++++++-- src/sqliteInt.h | 4 ++-- src/treeview.c | 5 +++++ 6 files changed, 24 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 233a3a04fd..068906c346 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Attempt\sto\sshow\striggers\sin\sthe\sTreeView\soutput\sfrom\sDELETE,\sINSERT,\sand\nUPDATE\sstatements. -D 2022-04-06T15:41:53.521 +C Improvements\sto\sthe\sdisplay\sof\sAST\sfor\sDML\sstatements. +D 2022-04-06T18:30:17.017 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -512,7 +512,7 @@ F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51 F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c d97fc6f1824297bc3da8e54daa902d6a458cb941b17aaff891564ffa34845e4a +F src/insert.c 221ae0496a53fcf74321d6dcdd7fa2d3c17ede1c17fa1d9020e2465da4a4505a F src/json.c 7749b98c62f691697c7ee536b570c744c0583cab4a89200fdd0fc2aa8cc8cbd6 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 2ecb1441f9b1c22e9e022ee0776e67d259facf34b56ba892b206f0a294ee6f8c @@ -552,12 +552,12 @@ F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c ea935b87d6fb36c78b70cdc7b28561dc8f33f2ef37048389549c7b5ef9b0ba5e F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c bf46b8fb1f095651ba26e5a4a63b0fab51367794169ba3c802c002f919117e6c +F src/select.c c3dab5fb5d25934bc384b0ffcbc1ab576ad8ce4a494a5eed3e1367c79c1416b1 F src/shell.c.in 18832612e74c92bbd25d88e1f92685f66589262f68cca1001d2a43bd6dd0ed60 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h e7b2a0a394629bb8d005bb1b64f5d34737ab4659f894cb1be0a322a2199873e3 +F src/sqliteInt.h f9484b03c663a20ac998627a416d8ef368950596e52e1186c5188ee93b695285 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -617,7 +617,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98 -F src/treeview.c 4ed907fc341bbab963a31ffccd803e13af99eb89376de5cbd0418b1fba0c9ebf +F src/treeview.c 433434c230263faeab7c47e601239d43d05b955f59c78add18a43856da9564f5 F src/trigger.c 8caa0baf1b18522863cf0fd611ef483962cfa50155ca82ad43e63b20f863a683 F src/update.c 2cfaded82ca80ff56afb8c3ae5e88284e0824bfd86119827cc22481959f96f92 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 @@ -1945,8 +1945,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 abb34c0830a49d4f4e277ddd17e710529e87cba7061f3546079dbba2f82b020e -R 3b68aded646af44203f4f0b172b58b76 +P b0939d6f4d94b45dce53ace6295508a67d574cc72bd6977623bf77065b3c4e64 +R 872e7cb0a41ffc82d4d587b9b5d48fbd U drh -Z c0df658f2ef079af39e2552d24158d31 +Z 7e160e4a9e1d6cdfe648435dccc34431 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index bb2179135e..3466d2e241 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b0939d6f4d94b45dce53ace6295508a67d574cc72bd6977623bf77065b3c4e64 \ No newline at end of file +84c239a071cfaf8af107646f01ef269e2915fd2384e95927d484f2e408ba6bbf \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index e56d037194..2593f353b3 100644 --- a/src/insert.c +++ b/src/insert.c @@ -768,7 +768,7 @@ void sqlite3Insert( #if TREETRACE_ENABLED if( sqlite3TreeTrace & 0x10000 ){ sqlite3TreeViewLine(0, "In sqlite3Insert() at %s:%d", __FILE__, __LINE__); - sqlite3TreeViewInsert(pParse->pWith, pTabList, pColumn, pSelect, + sqlite3TreeViewInsert(pParse->pWith, pTabList, pColumn, pSelect, pList, onError, pUpsert, pTrigger); } #endif diff --git a/src/select.c b/src/select.c index d9348dc583..a0d94c0c8d 100644 --- a/src/select.c +++ b/src/select.c @@ -6346,8 +6346,12 @@ int sqlite3Select( if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; #if TREETRACE_ENABLED SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain)); - if( sqlite3TreeTrace & 0x100 ){ - sqlite3TreeViewSelect(0, p, 0); + if( sqlite3TreeTrace & 0x10100 ){ + if( (sqlite3TreeTrace & 0x10001)==0x10000 ){ + sqlite3TreeViewLine(0, "In sqlite3Select() at %s:%d", + __FILE__, __LINE__); + } + sqlite3ShowSelect(p); } #endif diff --git a/src/sqliteInt.h b/src/sqliteInt.h index ef28573456..a77df1d8b8 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4431,8 +4431,8 @@ char *sqlite3VMPrintf(sqlite3*,const char*, va_list); void sqlite3TreeViewDelete(const With*, const SrcList*, const Expr*, const ExprList*,const Expr*, const Trigger*); void sqlite3TreeViewInsert(const With*, const SrcList*, - const IdList*, const Select*, int, - const Upsert*, const Trigger*); + const IdList*, const Select*, const ExprList*, + int, const Upsert*, const Trigger*); void sqlite3TreeViewUpdate(const With*, const SrcList*, const ExprList*, const Expr*, int, const ExprList*, const Expr*, const Upsert*, const Trigger*); diff --git a/src/treeview.c b/src/treeview.c index a63f94bfd5..7e15424637 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -947,6 +947,7 @@ void sqlite3TreeViewInsert( const SrcList *pTabList, const IdList *pColumnList, const Select *pSelect, + const ExprList *pExprList, int onError, const Upsert *pUpsert, const Trigger *pTrigger @@ -967,6 +968,7 @@ void sqlite3TreeViewInsert( if( pTabList ) n++; if( pColumnList ) n++; if( pSelect ) n++; + if( pExprList ) n++; if( pUpsert ) n++; if( pTrigger ) n++; if( pWith ){ @@ -989,6 +991,9 @@ void sqlite3TreeViewInsert( sqlite3TreeViewSelect(pView, pSelect, 0); sqlite3TreeViewPop(&pView); } + if( pExprList ){ + sqlite3TreeViewExprList(pView, pExprList, (--n)>0, "VALUES"); + } if( pUpsert ){ sqlite3TreeViewPush(&pView, (--n)>0); sqlite3TreeViewLine(pView, "UPSERT"); From 200adc9e75fdc08beaf70536d3983b3434e45ded Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 6 Apr 2022 19:46:20 +0000 Subject: [PATCH 078/259] Faster parsing of the FROM clause in joins for the common case where there is no INDEXED BY clause. FossilOrigin-Name: 848b7a0ea99ddc52091b78313f018c07d00a0e28aa6da8c1cae709c1d03468fe --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/parse.y | 11 ++++++++--- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 068906c346..3290802af4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sthe\sdisplay\sof\sAST\sfor\sDML\sstatements. -D 2022-04-06T18:30:17.017 +C Faster\sparsing\sof\sthe\sFROM\sclause\sin\sjoins\sfor\sthe\scommon\scase\swhere\sthere\nis\sno\sINDEXED\sBY\sclause. +D 2022-04-06T19:46:20.282 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -541,7 +541,7 @@ F src/os_win.c a8ea80037e81127ca01959daa87387cc135f325c88dc745376c4f760de852a10 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 42120492784fc9bcd9082b5c9b5e329b7318c357f9f3574a1bbfcf7418910356 F src/pager.h f82e9844166e1585f5786837ddc7709966138ced17f568c16af7ccf946c2baa3 -F src/parse.y 0f02b27cdaa334441463153fff3ceb780fea006ab53ffd6ef566d4468f93e924 +F src/parse.y a2786e72c5ce8a91df7dbad8306616d822ba7093f87cfa0d09fe351b83fa5828 F src/pcache.c 084e638432c610f95aea72b8509f0845d2791293f39d1b82f0c0a7e089c3bb6b F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 54881292a9a5db202b2c0ac541c5e3ef9a5e8c4f1c1383adb2601d5499a60e65 @@ -1945,8 +1945,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 b0939d6f4d94b45dce53ace6295508a67d574cc72bd6977623bf77065b3c4e64 -R 872e7cb0a41ffc82d4d587b9b5d48fbd +P 84c239a071cfaf8af107646f01ef269e2915fd2384e95927d484f2e408ba6bbf +R c85c19380822b3766b7352b207ade832 U drh -Z 7e160e4a9e1d6cdfe648435dccc34431 +Z f7c9c9fec330149ee82e748d50b754aa # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3466d2e241..6856212ee1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -84c239a071cfaf8af107646f01ef269e2915fd2384e95927d484f2e408ba6bbf \ No newline at end of file +848b7a0ea99ddc52091b78313f018c07d00a0e28aa6da8c1cae709c1d03468fe \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index 2680e640a0..e413739ff7 100644 --- a/src/parse.y +++ b/src/parse.y @@ -695,7 +695,10 @@ stl_prefix(A) ::= seltablist(A) joinop(Y). { if( ALWAYS(A && A->nSrc>0) ) A->a[A->nSrc-1].fg.jointype = (u8)Y; } stl_prefix(A) ::= . {A = 0;} -seltablist(A) ::= stl_prefix(A) nm(Y) dbnm(D) as(Z) indexed_opt(I) +seltablist(A) ::= stl_prefix(A) nm(Y) dbnm(D) as(Z) on_opt(N) using_opt(U). { + A = sqlite3SrcListAppendFromTerm(pParse,A,&Y,&D,&Z,0,N,U); +} +seltablist(A) ::= stl_prefix(A) nm(Y) dbnm(D) as(Z) indexed_by(I) on_opt(N) using_opt(U). { A = sqlite3SrcListAppendFromTerm(pParse,A,&Y,&D,&Z,0,N,U); sqlite3SrcListIndexedBy(pParse, A, &I); @@ -813,9 +816,11 @@ on_opt(N) ::= . [OR] {N = 0;} // recognizes and interprets this as a special case. // %type indexed_opt {Token} +%type indexed_by {Token} indexed_opt(A) ::= . {A.z=0; A.n=0;} -indexed_opt(A) ::= INDEXED BY nm(X). {A = X;} -indexed_opt(A) ::= NOT INDEXED. {A.z=0; A.n=1;} +indexed_opt(A) ::= indexed_by(A). +indexed_by(A) ::= INDEXED BY nm(X). {A = X;} +indexed_by(A) ::= NOT INDEXED. {A.z=0; A.n=1;} %type using_opt {IdList*} %destructor using_opt {sqlite3IdListDelete(pParse->db, $$);} From d44f8b2385eeb97d799fe5172c7514972c6f3359 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 7 Apr 2022 01:11:13 +0000 Subject: [PATCH 079/259] Improved technique for parsing the ON and USING clauses of a join is faster and uses less memory. FossilOrigin-Name: 158156a3e3d50042cafc75dea3aaaa68b1f2efb9c3d178518ea6e68e32e0d21c --- manifest | 38 ++++++++++++++++++------------------ manifest.uuid | 2 +- src/alter.c | 16 +++++++++------- src/attach.c | 6 +++++- src/build.c | 31 +++++++++++++++++++----------- src/delete.c | 4 ++-- src/expr.c | 20 +++++++++++++++++-- src/parse.y | 47 ++++++++++++++++++--------------------------- src/resolve.c | 15 +++++++++------ src/select.c | 48 +++++++++++++++++++++------------------------- src/sqliteInt.h | 20 ++++++++++++++++--- src/whereexpr.c | 4 +++- test/e_select.test | 2 +- test/join.test | 2 +- test/tkt3935.test | 6 +++--- test/vtab6.test | 2 +- 16 files changed, 150 insertions(+), 113 deletions(-) diff --git a/manifest b/manifest index 3290802af4..18e886918b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Faster\sparsing\sof\sthe\sFROM\sclause\sin\sjoins\sfor\sthe\scommon\scase\swhere\sthere\nis\sno\sINDEXED\sBY\sclause. -D 2022-04-06T19:46:20.282 +C Improved\stechnique\sfor\sparsing\sthe\sON\sand\sUSING\sclauses\sof\sa\sjoin\sis\sfaster\nand\suses\sless\smemory. +D 2022-04-07T01:11:13.364 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -485,9 +485,9 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c 006325f8844c65d885b3ba469b4c08d9dd0cd3e9ec481d5bcff621f224cb2302 +F src/alter.c 9395ece9850ad57c6fbb453aeb5185be4bae3b159c4b37611425c565124ee849 F src/analyze.c 3a119baeb03053c154029877454d41bb8fd79d4d1eb583392f2289b3554a75bc -F src/attach.c f26d400f3ffe2cdca01406bca70e5f58c5488bf165b4fc37c228136dfcf1b583 +F src/attach.c 4431f82f0247bf3aaf91589acafdff77d1882235c95407b36da1585c765fbbc8 F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf F src/backup.c a2891172438e385fdbe97c11c9745676bec54f518d4447090af97189fd8e52d7 F src/bitvec.c 7c849aac407230278445cb069bebc5f89bf2ddd87c5ed9459b070a9175707b3d @@ -495,15 +495,15 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 45161c2d5c9527b9c9bbfd7478daf3e0a619cf4bbe3278378aaea3d4b4e4f5b5 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482e -F src/build.c 4a265d49342cefc95ae739982a6197eae04a9258151f8e0bbe3ff8ab56aab801 +F src/build.c ff119be98394a65bc8be7afc39d4a791a66f03a778d396de3ec456f5dfaf39e8 F src/callback.c 4c19af69835787bfe790ac560f3071a824eb629f34e41f97b52ce5235c77de1c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 026dbdcdbd8c3cde98a88483ee88310ff43150ab164ad768f12cc700a11495ad F src/date.c 15082566229d4b1e5f24fdb490bf9bcc68824b911d70e3573ef075a1b9e2d26f F src/dbpage.c a70be9a4879ac5392673a1050d526a72b8b2f9938df7049f65348566a2637db3 F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d -F src/delete.c dafdc71a097f84fbbf66164d8842ebcb9bacf74e069658001fd70b62ee0acbdb -F src/expr.c 3cdb00b6c15f815c94836e7b4474b675155d1279e64804f6ab5816188a9b05b6 +F src/delete.c a8e844af211a48b13b5b358be77a12c860c6a557c21990ad51a548e2536500ce +F src/expr.c 5e247a8dfabb92e9fd10b78a675dc5d25430433dfd9e316471b4447b548635ba F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 94927f9b46d72a9cb858c208febf04ceb0a3270c5fa5fd0b7f436cf16e09f72a F src/func.c a3407a6fbb0d4088d8d502e46f0ace63e0aeae7467ae23a9ca9815bbf9239761 @@ -541,7 +541,7 @@ F src/os_win.c a8ea80037e81127ca01959daa87387cc135f325c88dc745376c4f760de852a10 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 42120492784fc9bcd9082b5c9b5e329b7318c357f9f3574a1bbfcf7418910356 F src/pager.h f82e9844166e1585f5786837ddc7709966138ced17f568c16af7ccf946c2baa3 -F src/parse.y a2786e72c5ce8a91df7dbad8306616d822ba7093f87cfa0d09fe351b83fa5828 +F src/parse.y afae75ce87abc2d87a8277ed811bc09d04da4b1760ace3e845cb1553f3a3dd0a F src/pcache.c 084e638432c610f95aea72b8509f0845d2791293f39d1b82f0c0a7e089c3bb6b F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 54881292a9a5db202b2c0ac541c5e3ef9a5e8c4f1c1383adb2601d5499a60e65 @@ -550,14 +550,14 @@ F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c fd940149c691684e7c1073c3787a7170e44852b02d1275d2e30a5b58e89cfcaf F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c -F src/resolve.c ea935b87d6fb36c78b70cdc7b28561dc8f33f2ef37048389549c7b5ef9b0ba5e +F src/resolve.c 18d99e7146852d6064559561769fcca0743eb32b14a97da6dbed373a30ee0e76 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c c3dab5fb5d25934bc384b0ffcbc1ab576ad8ce4a494a5eed3e1367c79c1416b1 +F src/select.c d6c04eb93395024af80f61a8c278a33c2a0333aeb7d57bb6aa737a6f1c4af4b8 F src/shell.c.in 18832612e74c92bbd25d88e1f92685f66589262f68cca1001d2a43bd6dd0ed60 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h f9484b03c663a20ac998627a416d8ef368950596e52e1186c5188ee93b695285 +F src/sqliteInt.h dbd5537c36a6b01fd67890487c3f7da468f16845500c115886f20adec06869ca F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -642,7 +642,7 @@ F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b F src/where.c a2483d4fe7cde88638cd3140dd5d6ee3dc0c80d3b3fe20322a8d08dc451f97ae F src/whereInt.h 15d2975c3b4c193c78c26674400a840da8647fe1777ae3b026e2d15937b38a03 F src/wherecode.c 555f598a9ddad81761f084710fdb4f8733fe31bc14cd6b19f8ca4274a7eaa04c -F src/whereexpr.c 2a71f5491798460c9590317329234d332d9eb1717cba4f3403122189a75c465e +F src/whereexpr.c 612f58f5f6e3e3bb94d10e2c56672ade8bbf94d4a928d3edb4e84e2ed3c00dca F src/window.c 42a71595263dbd8ef8248218e4fc7d4b5ddccece52146ad48e079342d93f6f8f F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 @@ -878,7 +878,7 @@ F test/e_fts3.test 17ba7c373aba4d4f5696ba147ee23fd1a1ef70782af050e03e262ca187c5e F test/e_insert.test f02f7f17852b2163732c6611d193f84fc67bc641fb4882c77a464076e5eba80e F test/e_reindex.test 2b0e29344497d9a8a999453a003cb476b6b1d2eef2d6c120f83c2d3a429f3164 F test/e_resolve.test a61751c368b109db73df0f20fc75fb47e166b1d8 -F test/e_select.test c5425a423da06d0494119db8361ebfc6de302929f7546ca596d56224137e0360 +F test/e_select.test 9b7ca08975c5444844b35ee60e09f973787a9f3317719715e8e6669abdf6aba2 F test/e_select2.test aceb80ab927d46fba5ce7586ebabf23e2bb0604f F test/e_totalchanges.test c927f7499dc3aa28b9b556b7d6d115a2f0fe41f012b128d16bf1f3b30e9b41e4 F test/e_update.test f46c2554d915c9197548681e8d8c33a267e84528 @@ -1140,7 +1140,7 @@ F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4 F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b F test/istrue.test e7f285bb70282625c258e866ce6337d4c762922f5a300e1b50f958aef6e7d9c9 -F test/join.test 25cf0ac11c3b81fedfd166f9062166bdb39dea92f5a7c16cacbf6dc1f7f67020 +F test/join.test 85e9c88bf4700b45a48a6362cd47e0c0aefc572629827c31aa58a5978cabdfc5 F test/join2.test 9bdc615841b91c97a16d68bad9508aea11fa0c6b34e5689847bcc4dac70e4990 F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 @@ -1628,7 +1628,7 @@ F test/tkt3911.test 74cd324f3ba653040cc6d94cc4857b290d12d633 F test/tkt3918.test ea78bf164e4d55cbde0d83c671ef6fbe930a0032 F test/tkt3922.test f26be40ab4fe6c00795629bd2006d96e270d9b1a F test/tkt3929.test cdf67acf5aa936ec4ffead81db87f8a71fe40e59 -F test/tkt3935.test e15261fedb9e30a4305a311da614a5d8e693c767 +F test/tkt3935.test 1ffcfffc148df51c8a01d1b3efae2d6c44cbeb0af1e0c5b88f4afe9a86d4ddb6 F test/tkt3992.test f3e7d548ac26f763b47bc0f750da3d03c81071da F test/tkt3997.test a335fa41ca3985660a139df7b734a26ef53284bd F test/tkt4018.test 18dbc6617f7a4b90e938d1bd6d26ad18daafaf08 @@ -1711,7 +1711,7 @@ F test/vtab2.test 14d4ab26cee13ba6cf5c5601b158e4f57552d3b055cdd9406cf7f711e9c840 F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e F test/vtab4.test 8e73ed268f3d596bc3590f45fc948fb40f28e9c3 F test/vtab5.test 889f444970393c73f1e077e2bdc5d845e157a391 -F test/vtab6.test 82d5bb8fd3c0643102c1209e9ea353b168b7eb9c8db4406ab2ee2cbbdaead62c +F test/vtab6.test 7167e8e526bc2e719e7818e18b2fd7bb8c455fa018b74e611943a86782e10125 F test/vtab7.test 70c6f4a1d6177144a8236e4172d5fba92e683440374664ad1f04851fbb335d3c F test/vtab8.test e19fa4a538fcd1bb66c22825fa8f71618fb13583 F test/vtab9.test ea58d2b95d61955f87226381716b2d0b1d4e4f9b @@ -1945,8 +1945,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 84c239a071cfaf8af107646f01ef269e2915fd2384e95927d484f2e408ba6bbf -R c85c19380822b3766b7352b207ade832 +P 848b7a0ea99ddc52091b78313f018c07d00a0e28aa6da8c1cae709c1d03468fe +R f48eedde1f7cf0c2cbb2f0efc2fa0619 U drh -Z f7c9c9fec330149ee82e748d50b754aa +Z 3a4c374a49d27fcf334d19f314ba8d15 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 6856212ee1..7245377486 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -848b7a0ea99ddc52091b78313f018c07d00a0e28aa6da8c1cae709c1d03468fe \ No newline at end of file +158156a3e3d50042cafc75dea3aaaa68b1f2efb9c3d178518ea6e68e32e0d21c \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 1ec74cdcc7..62075df759 100644 --- a/src/alter.c +++ b/src/alter.c @@ -858,11 +858,10 @@ static void unmapColumnIdlistNames( Parse *pParse, const IdList *pIdList ){ - if( pIdList ){ - int ii; - for(ii=0; iinId; ii++){ - sqlite3RenameTokenRemap(pParse, 0, (const void*)pIdList->a[ii].zName); - } + int ii; + assert( pIdList!=0 ); + for(ii=0; iinId; ii++){ + sqlite3RenameTokenRemap(pParse, 0, (const void*)pIdList->a[ii].zName); } } @@ -890,8 +889,11 @@ static int renameUnmapSelectCb(Walker *pWalker, Select *p){ SrcList *pSrc = p->pSrc; for(i=0; inSrc; i++){ sqlite3RenameTokenRemap(pParse, 0, (void*)pSrc->a[i].zName); - sqlite3WalkExpr(pWalker, pSrc->a[i].pOn); - unmapColumnIdlistNames(pParse, pSrc->a[i].pUsing); + if( pSrc->a[i].fg.isUsing==0 ){ + sqlite3WalkExpr(pWalker, pSrc->a[i].u3.pOn); + }else{ + unmapColumnIdlistNames(pParse, pSrc->a[i].u3.pUsing); + } } } diff --git a/src/attach.c b/src/attach.c index e587f6cc5e..1732be27bf 100644 --- a/src/attach.c +++ b/src/attach.c @@ -480,7 +480,11 @@ static int fixSelectCb(Walker *p, Select *pSelect){ pItem->fg.fromDDL = 1; } #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) - if( sqlite3WalkExpr(&pFix->w, pList->a[i].pOn) ) return WRC_Abort; + if( pList->a[i].fg.isUsing==0 + && sqlite3WalkExpr(&pFix->w, pList->a[i].u3.pOn) + ){ + return WRC_Abort; + } #endif } if( pSelect->pWith ){ diff --git a/src/build.c b/src/build.c index 35f1ea3639..da862fa707 100644 --- a/src/build.c +++ b/src/build.c @@ -4710,7 +4710,7 @@ void sqlite3IdListDelete(sqlite3 *db, IdList *pList){ */ int sqlite3IdListIndex(IdList *pList, const char *zName){ int i; - if( pList==0 ) return -1; + assert( pList!=0 ); for(i=0; inId; i++){ if( sqlite3StrICmp(pList->a[i].zName, zName)==0 ) return i; } @@ -4913,8 +4913,11 @@ void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg); sqlite3DeleteTable(db, pItem->pTab); if( pItem->pSelect ) sqlite3SelectDelete(db, pItem->pSelect); - if( pItem->pOn ) sqlite3ExprDelete(db, pItem->pOn); - if( pItem->pUsing ) sqlite3IdListDelete(db, pItem->pUsing); + if( pItem->fg.isUsing ){ + sqlite3IdListDelete(db, pItem->u3.pUsing); + }else if( pItem->u3.pOn ){ + sqlite3ExprDelete(db, pItem->u3.pOn); + } } sqlite3DbFreeNN(db, pList); } @@ -4942,14 +4945,13 @@ SrcList *sqlite3SrcListAppendFromTerm( Token *pDatabase, /* Name of the database containing pTable */ Token *pAlias, /* The right-hand side of the AS subexpression */ Select *pSubquery, /* A subquery used in place of a table name */ - Expr *pOn, /* The ON clause of a join */ - IdList *pUsing /* The USING clause of a join */ + OnOrUsing *pOnUsing /* Either the ON clause or the USING clause */ ){ SrcItem *pItem; sqlite3 *db = pParse->db; - if( !p && (pOn || pUsing) ){ + if( !p && pOnUsing!=0 && (pOnUsing->pOn || pOnUsing->pUsing) ){ sqlite3ErrorMsg(pParse, "a JOIN clause is required before %s", - (pOn ? "ON" : "USING") + (pOnUsing->pOn ? "ON" : "USING") ); goto append_from_error; } @@ -4970,14 +4972,21 @@ SrcList *sqlite3SrcListAppendFromTerm( pItem->zAlias = sqlite3NameFromToken(db, pAlias); } pItem->pSelect = pSubquery; - pItem->pOn = pOn; - pItem->pUsing = pUsing; + assert( pOnUsing==0 || pOnUsing->pOn==0 || pOnUsing->pUsing==0 ); + assert( pItem->fg.isUsing==0 ); + if( pOnUsing==0 ){ + pItem->u3.pOn = 0; + }else if( pOnUsing->pUsing ){ + pItem->fg.isUsing = 1; + pItem->u3.pUsing = pOnUsing->pUsing; + }else{ + pItem->u3.pOn = pOnUsing->pOn; + } return p; append_from_error: assert( p==0 ); - sqlite3ExprDelete(db, pOn); - sqlite3IdListDelete(db, pUsing); + sqlite3ClearOnOrUsing(db, pOnUsing); sqlite3SelectDelete(db, pSubquery); return 0; } diff --git a/src/delete.c b/src/delete.c index a4c5d53c58..df378d2d58 100644 --- a/src/delete.c +++ b/src/delete.c @@ -128,8 +128,8 @@ void sqlite3MaterializeView( assert( pFrom->nSrc==1 ); pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName); pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); - assert( pFrom->a[0].pOn==0 ); - assert( pFrom->a[0].pUsing==0 ); + assert( pFrom->a[0].fg.isUsing==0 ); + assert( pFrom->a[0].u3.pOn==0 ); } pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, pOrderBy, SF_IncludeHidden, pLimit); diff --git a/src/expr.c b/src/expr.c index 79889bdd75..2c00bb498d 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1249,6 +1249,18 @@ void sqlite3ExprDelete(sqlite3 *db, Expr *p){ if( p ) sqlite3ExprDeleteNN(db, p); } +/* +** Clear both elements of an OnOrUsing object +*/ +void sqlite3ClearOnOrUsing(sqlite3 *db, OnOrUsing *p){ + if( p==0 ){ + /* Nothing to clear */ + }else if( p->pOn ){ + sqlite3ExprDeleteNN(db, p->pOn); + }else if( p->pUsing ){ + sqlite3IdListDelete(db, p->pUsing); + } +} /* ** Arrange to cause pExpr to be deleted when the pParse is deleted. @@ -1671,8 +1683,12 @@ SrcList *sqlite3SrcListDup(sqlite3 *db, const SrcList *p, int flags){ pTab->nTabRef++; } pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect, flags); - pNewItem->pOn = sqlite3ExprDup(db, pOldItem->pOn, flags); - pNewItem->pUsing = sqlite3IdListDup(db, pOldItem->pUsing); + if( pOldItem->fg.isUsing ){ + assert( pNewItem->fg.isUsing ); + pNewItem->u3.pUsing = sqlite3IdListDup(db, pOldItem->u3.pUsing); + }else{ + pNewItem->u3.pOn = sqlite3ExprDup(db, pOldItem->u3.pOn, flags); + } pNewItem->colUsed = pOldItem->colUsed; } return pNew; diff --git a/src/parse.y b/src/parse.y index e413739ff7..7b3af1f1c2 100644 --- a/src/parse.y +++ b/src/parse.y @@ -570,7 +570,7 @@ selectnowith(A) ::= selectnowith(A) multiselect_op(Y) oneselect(Z). { Token x; x.n = 0; parserDoubleLinkSelect(pParse, pRhs); - pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0); + pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0); pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0); } if( pRhs ){ @@ -695,30 +695,26 @@ stl_prefix(A) ::= seltablist(A) joinop(Y). { if( ALWAYS(A && A->nSrc>0) ) A->a[A->nSrc-1].fg.jointype = (u8)Y; } stl_prefix(A) ::= . {A = 0;} -seltablist(A) ::= stl_prefix(A) nm(Y) dbnm(D) as(Z) on_opt(N) using_opt(U). { - A = sqlite3SrcListAppendFromTerm(pParse,A,&Y,&D,&Z,0,N,U); +seltablist(A) ::= stl_prefix(A) nm(Y) dbnm(D) as(Z) on_using(N). { + A = sqlite3SrcListAppendFromTerm(pParse,A,&Y,&D,&Z,0,&N); } -seltablist(A) ::= stl_prefix(A) nm(Y) dbnm(D) as(Z) indexed_by(I) - on_opt(N) using_opt(U). { - A = sqlite3SrcListAppendFromTerm(pParse,A,&Y,&D,&Z,0,N,U); +seltablist(A) ::= stl_prefix(A) nm(Y) dbnm(D) as(Z) indexed_by(I) on_using(N). { + A = sqlite3SrcListAppendFromTerm(pParse,A,&Y,&D,&Z,0,&N); sqlite3SrcListIndexedBy(pParse, A, &I); } -seltablist(A) ::= stl_prefix(A) nm(Y) dbnm(D) LP exprlist(E) RP as(Z) - on_opt(N) using_opt(U). { - A = sqlite3SrcListAppendFromTerm(pParse,A,&Y,&D,&Z,0,N,U); +seltablist(A) ::= stl_prefix(A) nm(Y) dbnm(D) LP exprlist(E) RP as(Z) on_using(N). { + A = sqlite3SrcListAppendFromTerm(pParse,A,&Y,&D,&Z,0,&N); sqlite3SrcListFuncArgs(pParse, A, E); } %ifndef SQLITE_OMIT_SUBQUERY - seltablist(A) ::= stl_prefix(A) LP select(S) RP - as(Z) on_opt(N) using_opt(U). { - A = sqlite3SrcListAppendFromTerm(pParse,A,0,0,&Z,S,N,U); + 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) LP seltablist(F) RP - as(Z) on_opt(N) using_opt(U). { - if( A==0 && Z.n==0 && N==0 && U==0 ){ + seltablist(A) ::= stl_prefix(A) LP seltablist(F) RP as(Z) on_using(N). { + if( A==0 && Z.n==0 && N.pOn==0 && N.pUsing==0 ){ A = F; }else if( F->nSrc==1 ){ - A = sqlite3SrcListAppendFromTerm(pParse,A,0,0,&Z,0,N,U); + A = sqlite3SrcListAppendFromTerm(pParse,A,0,0,&Z,0,&N); if( A ){ SrcItem *pNew = &A->a[A->nSrc-1]; SrcItem *pOld = F->a; @@ -739,7 +735,7 @@ seltablist(A) ::= stl_prefix(A) nm(Y) dbnm(D) LP exprlist(E) RP as(Z) Select *pSubquery; sqlite3SrcListShiftJoinType(F); pSubquery = sqlite3SelectNew(pParse,0,F,0,0,0,0,SF_NestedFrom,0); - A = sqlite3SrcListAppendFromTerm(pParse,A,0,0,&Z,pSubquery,N,U); + A = sqlite3SrcListAppendFromTerm(pParse,A,0,0,&Z,pSubquery,&N); } } %endif SQLITE_OMIT_SUBQUERY @@ -797,13 +793,14 @@ joinop(X) ::= JOIN_KW(A) nm(B) nm(C) JOIN. // // INSERT INTO tab SELECT * FROM aaa JOIN bbb WHERE true ON CONFLICT ... // -// The [AND] and [OR] precedence marks in the rules for on_opt cause the +// The [AND] and [OR] precedence marks in the rules for on_using cause the // ON in this context to always be interpreted as belonging to the JOIN. // -%type on_opt {Expr*} -%destructor on_opt {sqlite3ExprDelete(pParse->db, $$);} -on_opt(N) ::= ON expr(E). {N = E;} -on_opt(N) ::= . [OR] {N = 0;} +%type on_using {OnOrUsing} +//%destructor on_using {sqlite3ClearOnOrUsing(pParse->db, &$$);} +on_using(N) ::= ON expr(E). {N.pOn = E; N.pUsing = 0;} +on_using(N) ::= USING LP idlist(L) RP. {N.pOn = 0; N.pUsing = L;} +on_using(N) ::= . [OR] {N.pOn = 0; N.pUsing = 0;} // Note that this block abuses the Token type just a little. If there is // no "INDEXED BY" clause, the returned token is empty (z==0 && n==0). If @@ -822,12 +819,6 @@ indexed_opt(A) ::= indexed_by(A). indexed_by(A) ::= INDEXED BY nm(X). {A = X;} indexed_by(A) ::= NOT INDEXED. {A.z=0; A.n=1;} -%type using_opt {IdList*} -%destructor using_opt {sqlite3IdListDelete(pParse->db, $$);} -using_opt(U) ::= USING LP idlist(L) RP. {U = L;} -using_opt(U) ::= . {U = 0;} - - %type orderby_opt {ExprList*} %destructor orderby_opt {sqlite3ExprListDelete(pParse->db, $$);} diff --git a/src/resolve.c b/src/resolve.c index 480694f6f5..30785ca706 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -123,11 +123,10 @@ static void resolveAlias( ** zCol. */ static int nameInUsingClause(IdList *pUsing, const char *zCol){ - if( pUsing ){ - int k; - for(k=0; knId; k++){ - if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ) return 1; - } + int k; + assert( pUsing!=0 ); + for(k=0; knId; k++){ + if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ) return 1; } return 0; } @@ -346,7 +345,11 @@ static int lookupName( */ if( cnt==1 ){ if( pItem->fg.jointype & JT_NATURAL ) continue; - if( nameInUsingClause(pItem->pUsing, zCol) ) continue; + if( pItem->fg.isUsing + && nameInUsingClause(pItem->u3.pUsing, zCol) + ){ + continue; + } } cnt++; pMatch = pItem; diff --git a/src/select.c b/src/select.c index a0d94c0c8d..989446af61 100644 --- a/src/select.c +++ b/src/select.c @@ -468,7 +468,7 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ ** every column that the two tables have in common. */ if( pRight->fg.jointype & JT_NATURAL ){ - if( pRight->pOn || pRight->pUsing ){ + if( pRight->fg.isUsing || pRight->u3.pOn ){ sqlite3ErrorMsg(pParse, "a NATURAL join may not have " "an ON or USING clause", 0); return 1; @@ -487,23 +487,6 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ } } - /* Disallow both ON and USING clauses in the same join - */ - if( pRight->pOn && pRight->pUsing ){ - sqlite3ErrorMsg(pParse, "cannot have both ON and USING " - "clauses in the same join"); - return 1; - } - - /* Add the ON clause to the end of the WHERE clause, connected by - ** an AND operator. - */ - if( pRight->pOn ){ - if( isOuter ) sqlite3SetJoinExpr(pRight->pOn, pRight->iCursor); - p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pRight->pOn); - pRight->pOn = 0; - } - /* Create extra terms on the WHERE clause for each column named ** in the USING clause. Example: If the two tables to be joined are ** A and B and the USING clause names X, Y, and Z, then add this @@ -511,8 +494,9 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ ** Report an error if any column mentioned in the USING clause is ** not contained in both tables to be joined. */ - if( pRight->pUsing ){ - IdList *pList = pRight->pUsing; + if( pRight->fg.isUsing ){ + IdList *pList = pRight->u3.pUsing; + assert( pList!=0 ); for(j=0; jnId; j++){ char *zName; /* Name of the term in the USING clause */ int iLeft; /* Table on the left with matching column name */ @@ -532,6 +516,15 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ isOuter, &p->pWhere); } } + + /* Add the ON clause to the end of the WHERE clause, connected by + ** an AND operator. + */ + else if( pRight->u3.pOn ){ + if( isOuter ) sqlite3SetJoinExpr(pRight->u3.pOn, pRight->iCursor); + p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pRight->u3.pOn); + pRight->u3.pOn = 0; + } } return 0; } @@ -4222,7 +4215,7 @@ static int flattenSubquery( pSubitem->zName = 0; pSubitem->zAlias = 0; pSubitem->pSelect = 0; - assert( pSubitem->pOn==0 ); + assert( pSubitem->fg.isUsing!=0 || pSubitem->u3.pOn==0 ); /* If the sub-query is a compound SELECT statement, then (by restrictions ** 17 and 18 above) it must be a UNION ALL and the parent query must @@ -4366,9 +4359,10 @@ static int flattenSubquery( ** outer query. */ for(i=0; ia[i+iFrom].pUsing); - assert( pSrc->a[i+iFrom].fg.isTabFunc==0 ); - pSrc->a[i+iFrom] = pSubSrc->a[i]; + SrcItem *pItem = &pSrc->a[i+iFrom]; + if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing); + assert( pItem->fg.isTabFunc==0 ); + *pItem = pSubSrc->a[i]; iNewParent = pSubSrc->a[i].iCursor; memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i])); } @@ -5092,7 +5086,7 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){ pNew = sqlite3DbMallocZero(db, sizeof(*pNew) ); if( pNew==0 ) return WRC_Abort; memset(&dummy, 0, sizeof(dummy)); - pNewSrc = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&dummy,pNew,0,0); + pNewSrc = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&dummy,pNew,0); if( pNewSrc==0 ) return WRC_Abort; *pNew = *p; p->pSrc = pNewSrc; @@ -5703,7 +5697,9 @@ static int selectExpander(Walker *pWalker, Select *p){ ** table to the right of the join */ continue; } - if( sqlite3IdListIndex(pFrom->pUsing, zName)>=0 ){ + if( pFrom->fg.isUsing + && sqlite3IdListIndex(pFrom->u3.pUsing, zName)>=0 + ){ /* In a join with a USING clause, omit columns in the ** using clause from the table on the right. */ continue; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index a77df1d8b8..9f95ec8a9d 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1191,6 +1191,7 @@ typedef struct Lookaside Lookaside; typedef struct LookasideSlot LookasideSlot; typedef struct Module Module; typedef struct NameContext NameContext; +typedef struct OnOrUsing OnOrUsing; typedef struct Parse Parse; typedef struct ParseCleanup ParseCleanup; typedef struct PreUpdate PreUpdate; @@ -3075,10 +3076,13 @@ struct SrcItem { unsigned fromDDL :1; /* Comes from sqlite_schema */ unsigned isCte :1; /* This is a CTE */ unsigned notCte :1; /* This item may not match a CTE */ + unsigned isUsing :1; /* u3.pUsing is valid */ } fg; int iCursor; /* The VDBE cursor number used to access this table */ - Expr *pOn; /* The ON clause of a join */ - IdList *pUsing; /* The USING clause of a join */ + union { + Expr *pOn; /* fg.isUsing==0 => The ON clause of a join */ + IdList *pUsing; /* fg.isUsing==1 => The USING clause of a join */ + } u3; Bitmask colUsed; /* Bit N (1<" clause */ @@ -3090,6 +3094,15 @@ struct SrcItem { } u2; }; +/* +** The OnOrUsing object represents either an ON clause or a USING clause. +** It can never be both at the same time, but it can be neither. +*/ +struct OnOrUsing { + Expr *pOn; /* The ON clause of a join */ + IdList *pUsing; /* The USING clause of a join */ +}; + /* ** The following structure describes the FROM clause of a SELECT statement. ** Each table or subquery in the FROM clause is a separate element of @@ -4610,13 +4623,14 @@ SrcList *sqlite3SrcListEnlarge(Parse*, SrcList*, int, int); SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2); SrcList *sqlite3SrcListAppend(Parse*, SrcList*, Token*, Token*); SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*, - Token*, Select*, Expr*, IdList*); + Token*, Select*, OnOrUsing*); void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *); void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*); int sqlite3IndexedByLookup(Parse *, SrcItem *); void sqlite3SrcListShiftJoinType(SrcList*); void sqlite3SrcListAssignCursors(Parse*, SrcList*); void sqlite3IdListDelete(sqlite3*, IdList*); +void sqlite3ClearOnOrUsing(sqlite3*, OnOrUsing*); void sqlite3SrcListDelete(sqlite3*, SrcList*); Index *sqlite3AllocateIndexObject(sqlite3*,i16,int,char**); void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*, diff --git a/src/whereexpr.c b/src/whereexpr.c index 19dd886de5..26a521fffd 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -951,7 +951,9 @@ static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){ int i; for(i=0; inSrc; i++){ mask |= exprSelectUsage(pMaskSet, pSrc->a[i].pSelect); - mask |= sqlite3WhereExprUsage(pMaskSet, pSrc->a[i].pOn); + if( pSrc->a[i].fg.isUsing==0 ){ + mask |= sqlite3WhereExprUsage(pMaskSet, pSrc->a[i].u3.pOn); + } if( pSrc->a[i].fg.isTabFunc ){ mask |= sqlite3WhereExprListUsage(pMaskSet, pSrc->a[i].u1.pFuncArg); } diff --git a/test/e_select.test b/test/e_select.test index a4e74d30e1..1ffd4021b6 100644 --- a/test/e_select.test +++ b/test/e_select.test @@ -96,7 +96,7 @@ do_join_test e_select-0.1.3 { } {9} do_catchsql_test e_select-0.1.4 { SELECT count(*) FROM t1, t2 ON (t1.a=t2.a) USING (a) -} {1 {cannot have both ON and USING clauses in the same join}} +} {1 {near "USING": syntax error}} do_catchsql_test e_select-0.1.5 { SELECT count(*) FROM t1, t2 USING (a) ON (t1.a=t2.a) } {1 {near "ON": syntax error}} diff --git a/test/join.test b/test/join.test index 221dbdd098..f48a1a149d 100644 --- a/test/join.test +++ b/test/join.test @@ -307,7 +307,7 @@ do_test join-3.3 { catchsql { SELECT * FROM t1 JOIN t2 ON t1.a=t2.b USING(b); } -} {1 {cannot have both ON and USING clauses in the same join}} +} {1 {near "USING": syntax error}} do_test join-3.4.1 { catchsql { SELECT * FROM t1 JOIN t2 USING(a); diff --git a/test/tkt3935.test b/test/tkt3935.test index abbeb3f866..a4f1f61dad 100644 --- a/test/tkt3935.test +++ b/test/tkt3935.test @@ -34,13 +34,13 @@ do_test tkt3935.3 { do_test tkt3935.4 { catchsql { SELECT a FROM (t1) AS t ON b USING(a) } -} {1 {a JOIN clause is required before ON}} +} {1 {near "USING": syntax error}} do_test tkt3935.5 { catchsql { SELECT a FROM (t1) AS t ON b } } {1 {a JOIN clause is required before ON}} do_test tkt3935.6 { catchsql { SELECT a FROM (SELECT * FROM t1) AS t ON b USING(a) } -} {1 {a JOIN clause is required before ON}} +} {1 {near "USING": syntax error}} do_test tkt3935.7 { catchsql { SELECT a FROM (SELECT * FROM t1) AS t ON b } } {1 {a JOIN clause is required before ON}} @@ -49,7 +49,7 @@ do_test tkt3935.8 { } {1 {a JOIN clause is required before ON}} do_test tkt3935.9 { catchsql { SELECT a FROM t1 AS t ON b USING(a) } -} {1 {a JOIN clause is required before ON}} +} {1 {near "USING": syntax error}} do_test tkt3935.10 { catchsql { SELECT a FROM t1 AS t USING(a) } } {1 {a JOIN clause is required before USING}} diff --git a/test/vtab6.test b/test/vtab6.test index ffbe430c6e..ab52c9f15c 100644 --- a/test/vtab6.test +++ b/test/vtab6.test @@ -263,7 +263,7 @@ do_test vtab6-3.3 { catchsql { SELECT * FROM t1 JOIN t2 ON t1.a=t2.b USING(b); } -} {1 {cannot have both ON and USING clauses in the same join}} +} {1 {near "USING": syntax error}} do_test vtab6-3.4 { catchsql { SELECT * FROM t1 JOIN t2 USING(a); From c381056e6d721e5243b84efb734a4ed2a763bac8 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 7 Apr 2022 10:11:35 +0000 Subject: [PATCH 080/259] Fix harmless compiler warnings. FossilOrigin-Name: 61095b5bcb5c30d29f03efa5b4809e3a0b780ed57e35227c292aab9dd1cfe3f6 --- ext/fts5/fts5_expr.c | 3 +++ manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/treeview.c | 1 - src/vdbemem.c | 6 ++++-- 5 files changed, 16 insertions(+), 12 deletions(-) diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index d9c1dd0fd9..66bd304d42 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -1627,6 +1627,9 @@ Fts5ExprNearset *sqlite3Fts5ParseNearset( }else{ if( pRet->nPhrase>0 ){ Fts5ExprPhrase *pLast = pRet->apPhrase[pRet->nPhrase-1]; + assert( pParse!=0 ); + assert( pParse->apPhrase!=0 ); + assert( pParse->nPhrase>=2 ); assert( pLast==pParse->apPhrase[pParse->nPhrase-2] ); if( pPhrase->nTerm==0 ){ fts5ExprPhraseFree(pPhrase); diff --git a/manifest b/manifest index 18e886918b..42c5bbf72f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\stechnique\sfor\sparsing\sthe\sON\sand\sUSING\sclauses\sof\sa\sjoin\sis\sfaster\nand\suses\sless\smemory. -D 2022-04-07T01:11:13.364 +C Fix\sharmless\scompiler\swarnings. +D 2022-04-07T10:11:35.114 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -117,7 +117,7 @@ F ext/fts5/fts5Int.h 36fd4a05e6e6307e3bac359a589d5f090b903afe0e7ae15db84f0ff90c7 F ext/fts5/fts5_aux.c f558e1fb9f0f86a4f7489e258c162e1f947de5ff2709087fbb465fddb7092f98 F ext/fts5/fts5_buffer.c 3001fbabb585d6de52947b44b455235072b741038391f830d6b729225eeaf6a5 F ext/fts5/fts5_config.c 501e7d3566bc92766b0e11c0109a7c5a6146bc41144195459af5422f6c2078aa -F ext/fts5/fts5_expr.c fcd0770d53028c2b53a15d0f53bf6d0e01b1bf3dd97630b9fedf0801f03aa3ec +F ext/fts5/fts5_expr.c 40174a64829d30cc86e8266306ad24980f6911edd5ca0b8c1ce7821ea1341b88 F ext/fts5/fts5_hash.c d4fb70940359f2120ccd1de7ffe64cc3efe65de9e8995b822cd536ff64c96982 F ext/fts5/fts5_index.c fdfbc8a62827ec1d1b6f207a1e59c1c4986c3ce245592b5128ffe738867cfcd1 F ext/fts5/fts5_main.c 6078ae86d3b813753a4f1201054550aff21a3f660e97b30f200d2b1472874151 @@ -617,7 +617,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98 -F src/treeview.c 433434c230263faeab7c47e601239d43d05b955f59c78add18a43856da9564f5 +F src/treeview.c 80a3d70bbc112399aa3cc7e777acc5d07c452e44c652630fc158d4594d86afd1 F src/trigger.c 8caa0baf1b18522863cf0fd611ef483962cfa50155ca82ad43e63b20f863a683 F src/update.c 2cfaded82ca80ff56afb8c3ae5e88284e0824bfd86119827cc22481959f96f92 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 @@ -630,7 +630,7 @@ F src/vdbeInt.h 5f3d0abcf30c2b7a6672ad4386f18be0fca9c9b2cefe18f85a2e3df74f2613bf F src/vdbeapi.c 354c893f1500cf524cc45c32879b9c68893a28b77e3442c24668d6afe4236217 F src/vdbeaux.c 567ddcdd5d875161201e9752144834d1519e7e856e2da410619d88a9cfefe70d F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd -F src/vdbemem.c 062cd58c54f887dc2eeb865686251c17237f791f0e6394e9c6f7a6f3c1a7e206 +F src/vdbemem.c 7189090b72baa025f945a1ac8c61ee420c645254476e8a191d555db76dfea5d4 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823 F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c @@ -1945,8 +1945,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 848b7a0ea99ddc52091b78313f018c07d00a0e28aa6da8c1cae709c1d03468fe -R f48eedde1f7cf0c2cbb2f0efc2fa0619 +P 158156a3e3d50042cafc75dea3aaaa68b1f2efb9c3d178518ea6e68e32e0d21c +R ddc4a547b7cd9ea461a0814ceeb710d6 U drh -Z 3a4c374a49d27fcf334d19f314ba8d15 +Z 47d2237d442f3e332877057086e92ecb # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7245377486..c3995ce24f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -158156a3e3d50042cafc75dea3aaaa68b1f2efb9c3d178518ea6e68e32e0d21c \ No newline at end of file +61095b5bcb5c30d29f03efa5b4809e3a0b780ed57e35227c292aab9dd1cfe3f6 \ No newline at end of file diff --git a/src/treeview.c b/src/treeview.c index 7e15424637..91aff8ddf1 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -837,7 +837,6 @@ void sqlite3TreeViewBareIdList( int moreToFollow = inId - 1; if( zName==0 ) zName = "(null)"; sqlite3TreeViewPush(&pView, moreToFollow); - moreToFollow = 0; sqlite3TreeViewLine(pView, 0); fprintf(stdout, "%s (%d)\n", zName, pList->a[i].idx); sqlite3TreeViewPop(&pView); diff --git a/src/vdbemem.c b/src/vdbemem.c index 5eac7cf712..faa35f0ac9 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -457,9 +457,10 @@ int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ Mem t; assert( pFunc!=0 ); assert( pMem!=0 ); + assert( pMem->db!=0 ); assert( pFunc->xFinalize!=0 ); assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef ); - assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + assert( sqlite3_mutex_held(pMem->db->mutex) ); memset(&ctx, 0, sizeof(ctx)); memset(&t, 0, sizeof(t)); t.flags = MEM_Null; @@ -489,7 +490,8 @@ int sqlite3VdbeMemAggValue(Mem *pAccum, Mem *pOut, FuncDef *pFunc){ assert( pFunc!=0 ); assert( pFunc->xValue!=0 ); assert( (pAccum->flags & MEM_Null)!=0 || pFunc==pAccum->u.pDef ); - assert( pAccum->db==0 || sqlite3_mutex_held(pAccum->db->mutex) ); + assert( pAccum->db!=0 ); + assert( sqlite3_mutex_held(pAccum->db->mutex) ); memset(&ctx, 0, sizeof(ctx)); sqlite3VdbeMemSetNull(pOut); ctx.pOut = pOut; From 9c949b1c46870ef10fef6a09441cf1c0f3ac0472 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 7 Apr 2022 12:10:00 +0000 Subject: [PATCH 081/259] Omit an unnecessary initialization in tokenExpr(). FossilOrigin-Name: 8f6ae686019c61a03fe70eb78d2b529b1cf126215b45513a97cfdf7086f82f54 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/parse.y | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 42c5bbf72f..a6f8dcf81c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings. -D 2022-04-07T10:11:35.114 +C Omit\san\sunnecessary\sinitialization\sin\stokenExpr(). +D 2022-04-07T12:10:00.281 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -541,7 +541,7 @@ F src/os_win.c a8ea80037e81127ca01959daa87387cc135f325c88dc745376c4f760de852a10 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 42120492784fc9bcd9082b5c9b5e329b7318c357f9f3574a1bbfcf7418910356 F src/pager.h f82e9844166e1585f5786837ddc7709966138ced17f568c16af7ccf946c2baa3 -F src/parse.y afae75ce87abc2d87a8277ed811bc09d04da4b1760ace3e845cb1553f3a3dd0a +F src/parse.y 9130a936927658e7c574e97e5d4f0a747a3f6b9a42bc5c63e455c8e40cc74216 F src/pcache.c 084e638432c610f95aea72b8509f0845d2791293f39d1b82f0c0a7e089c3bb6b F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 54881292a9a5db202b2c0ac541c5e3ef9a5e8c4f1c1383adb2601d5499a60e65 @@ -1945,8 +1945,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 158156a3e3d50042cafc75dea3aaaa68b1f2efb9c3d178518ea6e68e32e0d21c -R ddc4a547b7cd9ea461a0814ceeb710d6 +P 61095b5bcb5c30d29f03efa5b4809e3a0b780ed57e35227c292aab9dd1cfe3f6 +R d10cb8dc7a06987894bb442f89af796a U drh -Z 47d2237d442f3e332877057086e92ecb +Z 9cd1781a9da7842a2690f24190d28f26 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c3995ce24f..f5caace469 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -61095b5bcb5c30d29f03efa5b4809e3a0b780ed57e35227c292aab9dd1cfe3f6 \ No newline at end of file +8f6ae686019c61a03fe70eb78d2b529b1cf126215b45513a97cfdf7086f82f54 \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index 7b3af1f1c2..4deae14b4c 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1030,7 +1030,7 @@ idlist(A) ::= nm(Y). p->affExpr = 0; p->flags = EP_Leaf; ExprClearVVAProperties(p); - p->iAgg = -1; + /* p->iAgg = -1; // Not required */ p->pLeft = p->pRight = 0; p->pAggInfo = 0; memset(&p->x, 0, sizeof(p->x)); From 4cd8296f396e2df95cd3b693c6da7469968c8e44 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 7 Apr 2022 13:48:34 +0000 Subject: [PATCH 082/259] Avoid compiler warnings about the new sqlite3Show() debugging routines begin "defined but not used". FossilOrigin-Name: 47ddc26974fbad8233c953d435e79d4f5dd5e09fbd684ea5f4ad32f4cae6cae6 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/main.c | 19 +++++++++++++++++++ 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index a6f8dcf81c..6127d4ba54 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Omit\san\sunnecessary\sinitialization\sin\stokenExpr(). -D 2022-04-07T12:10:00.281 +C Avoid\scompiler\swarnings\sabout\sthe\snew\ssqlite3Show()\sdebugging\sroutines\nbegin\s"defined\sbut\snot\sused". +D 2022-04-07T13:48:34.525 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -516,7 +516,7 @@ F src/insert.c 221ae0496a53fcf74321d6dcdd7fa2d3c17ede1c17fa1d9020e2465da4a4505a F src/json.c 7749b98c62f691697c7ee536b570c744c0583cab4a89200fdd0fc2aa8cc8cbd6 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 2ecb1441f9b1c22e9e022ee0776e67d259facf34b56ba892b206f0a294ee6f8c -F src/main.c db08e3ebd5e1802ab4d4cac5dfa6ae0a12058c51345a90126146dd6010b32593 +F src/main.c 135858d2ede0b83d779e71b07ede9c1d6b6eaab7b77bc2a85729584152769faf F src/malloc.c fec841aa0a0400a6f7d20706178a5d8e8219a6bf562b6fe712c17f6c26813266 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -1945,8 +1945,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 61095b5bcb5c30d29f03efa5b4809e3a0b780ed57e35227c292aab9dd1cfe3f6 -R d10cb8dc7a06987894bb442f89af796a +P 8f6ae686019c61a03fe70eb78d2b529b1cf126215b45513a97cfdf7086f82f54 +R 380084301cb6b00c02dcf97f512da662 U drh -Z 9cd1781a9da7842a2690f24190d28f26 +Z cfb664e1b06ecfbc84035c3ba38b1870 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f5caace469..03780d765c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8f6ae686019c61a03fe70eb78d2b529b1cf126215b45513a97cfdf7086f82f54 \ No newline at end of file +47ddc26974fbad8233c953d435e79d4f5dd5e09fbd684ea5f4ad32f4cae6cae6 \ No newline at end of file diff --git a/src/main.c b/src/main.c index c17e1b89f9..c40b3162ab 100644 --- a/src/main.c +++ b/src/main.c @@ -4097,6 +4097,25 @@ int sqlite3_test_control(int op, ...){ volatile int x = 0; assert( /*side-effects-ok*/ (x = va_arg(ap,int))!=0 ); rc = x; +#if defined(SQLITE_DEBUG) + /* Invoke these debugging routines so that the compiler does not + ** issue "defined but not used" warnings. */ + if( x==9999 ){ + sqlite3ShowExpr(0); + sqlite3ShowExpr(0); + sqlite3ShowExprList(0); + sqlite3ShowIdList(0); + sqlite3ShowSrcList(0); + sqlite3ShowWith(0); + sqlite3ShowUpsert(0); + sqlite3ShowTriggerStep(0); + sqlite3ShowTriggerStepList(0); + sqlite3ShowTrigger(0); + sqlite3ShowTriggerList(0); + sqlite3ShowWindow(0); + sqlite3ShowWinFunc(0); + } +#endif break; } From a744167956cbe170a4b3e6edc1a3206f75c81fbb Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 7 Apr 2022 14:03:07 +0000 Subject: [PATCH 083/259] Optimization to sqlite3TriggersExist() saves over 700K CPU cycles. FossilOrigin-Name: 5043a3507e0781878e0e1bea5095a33273958820baead4af8fc2929e9d7c07ee --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/trigger.c | 27 ++++++++++++++++++++++++++- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 6127d4ba54..4d7ead95e3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\scompiler\swarnings\sabout\sthe\snew\ssqlite3Show()\sdebugging\sroutines\nbegin\s"defined\sbut\snot\sused". -D 2022-04-07T13:48:34.525 +C Optimization\sto\ssqlite3TriggersExist()\ssaves\sover\s700K\sCPU\scycles. +D 2022-04-07T14:03:07.800 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -618,7 +618,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98 F src/treeview.c 80a3d70bbc112399aa3cc7e777acc5d07c452e44c652630fc158d4594d86afd1 -F src/trigger.c 8caa0baf1b18522863cf0fd611ef483962cfa50155ca82ad43e63b20f863a683 +F src/trigger.c 4cdfe612037f10a42b32a59ba2a356105d27f51fd245d448375b947fb34db9a4 F src/update.c 2cfaded82ca80ff56afb8c3ae5e88284e0824bfd86119827cc22481959f96f92 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 @@ -1945,8 +1945,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 8f6ae686019c61a03fe70eb78d2b529b1cf126215b45513a97cfdf7086f82f54 -R 380084301cb6b00c02dcf97f512da662 +P 47ddc26974fbad8233c953d435e79d4f5dd5e09fbd684ea5f4ad32f4cae6cae6 +R 313704a91e0bd8ca9890cadf31801b34 U drh -Z cfb664e1b06ecfbc84035c3ba38b1870 +Z d452943e9c0d2e6a5130deca0f1583c4 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 03780d765c..651bd878e2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -47ddc26974fbad8233c953d435e79d4f5dd5e09fbd684ea5f4ad32f4cae6cae6 \ No newline at end of file +5043a3507e0781878e0e1bea5095a33273958820baead4af8fc2929e9d7c07ee \ No newline at end of file diff --git a/src/trigger.c b/src/trigger.c index c30454519a..3ff2ebc91b 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -729,13 +729,22 @@ static int checkColumnOverlap(IdList *pIdList, ExprList *pEList){ return 0; } +/* +** Return true if any TEMP triggers exist +*/ +static int tempTriggersExist(sqlite3 *db){ + if( db->aDb[1].pSchema==0 ) return 0; + if( sqliteHashFirst(&db->aDb[1].pSchema->trigHash)==0 ) return 0; + return 1; +} + /* ** Return a list of all triggers on table pTab if there exists at least ** one trigger that must be fired when an operation of type 'op' is ** performed on the table, and, if that operation is an UPDATE, if at ** least one of the columns in pChanges is being modified. */ -Trigger *sqlite3TriggersExist( +static SQLITE_NOINLINE Trigger *triggersReallyExist( Parse *pParse, /* Parse context */ Table *pTab, /* The table the contains the triggers */ int op, /* one of TK_DELETE, TK_INSERT, TK_UPDATE */ @@ -798,6 +807,22 @@ exit_triggers_exist: } return (mask ? pList : 0); } +Trigger *sqlite3TriggersExist( + Parse *pParse, /* Parse context */ + Table *pTab, /* The table the contains the triggers */ + int op, /* one of TK_DELETE, TK_INSERT, TK_UPDATE */ + ExprList *pChanges, /* Columns that change in an UPDATE statement */ + int *pMask /* OUT: Mask of TRIGGER_BEFORE|TRIGGER_AFTER */ +){ + assert( pTab!=0 ); + if( (pTab->pTrigger==0 && !tempTriggersExist(pParse->db)) + || pParse->disableTriggers + ){ + if( pMask ) *pMask = 0; + return 0; + } + return triggersReallyExist(pParse,pTab,op,pChanges,pMask); +} /* ** Convert the pStep->zTarget string into a SrcList and return a pointer From db08a6d13c7b868eb42b53d4fac8738ad3d7b477 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 7 Apr 2022 14:13:32 +0000 Subject: [PATCH 084/259] Fix the parsing of C-style comments in Lemon, as reported by [forum:/forumpost/b6edc69548|forum post b6edc69548]. This has no affect on SQLite itself. FossilOrigin-Name: 201569e09b000919ccb463bd581fb2ecd5320e7f584fdb1bc2aaba111061d5c3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/lemon.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 4d7ead95e3..3a5afaeadc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Optimization\sto\ssqlite3TriggersExist()\ssaves\sover\s700K\sCPU\scycles. -D 2022-04-07T14:03:07.800 +C Fix\sthe\sparsing\sof\sC-style\scomments\sin\sLemon,\sas\sreported\sby\n[forum:/forumpost/b6edc69548|forum\spost\sb6edc69548].\s\sThis\shas\sno\saffect\non\sSQLite\sitself. +D 2022-04-07T14:13:32.478 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1863,7 +1863,7 @@ F tool/genfkey.test b6afd7b825d797a1e1274f519ab5695373552ecad5cd373530c63533638a F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/index_usage.c f62a0c701b2c7ff2f3e21d206f093c123f222dbf07136a10ffd1ca15a5c706c5 F tool/kvtest-speed.sh 4761a9c4b3530907562314d7757995787f7aef8f -F tool/lemon.c 1c5a14f6044193e42864c36de48359026fa2cdcf205a43cc1a31116101e27258 +F tool/lemon.c ea5c8589c7749e9bd32ba10432aeeed3c16e215de72a12ada2bc707884837149 F tool/lempar.c 57478ea48420da05faa873c6d1616321caa5464644588c97fbe8e0ea04450748 F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 @@ -1945,8 +1945,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 47ddc26974fbad8233c953d435e79d4f5dd5e09fbd684ea5f4ad32f4cae6cae6 -R 313704a91e0bd8ca9890cadf31801b34 +P 5043a3507e0781878e0e1bea5095a33273958820baead4af8fc2929e9d7c07ee +R 3aa1ea2fb3309b52d9b9b355614ccef2 U drh -Z d452943e9c0d2e6a5130deca0f1583c4 +Z a9f6250e4b921e7cc5eba2670fe5b4ea # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 651bd878e2..604ab9337a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5043a3507e0781878e0e1bea5095a33273958820baead4af8fc2929e9d7c07ee \ No newline at end of file +201569e09b000919ccb463bd581fb2ecd5320e7f584fdb1bc2aaba111061d5c3 \ No newline at end of file diff --git a/tool/lemon.c b/tool/lemon.c index 11e25c8a1c..fb81292d4d 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -3015,6 +3015,7 @@ void Parse(struct lemon *gp) } if( c=='/' && cp[1]=='*' ){ /* Skip C style comments */ cp+=2; + if( (*cp)=='/' ) cp++; while( (c= *cp)!=0 && (c!='/' || cp[-1]!='*') ){ if( c=='\n' ) lineno++; cp++; From da4c7ccc075f84dd0f91d6bc6d60e9acebf78292 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 7 Apr 2022 18:17:56 +0000 Subject: [PATCH 085/259] The ".testctrl optimizations 0x400000" command disables the generation of OP_ReleaseReg opcodes. OP_ReleaseReg opcodes are usually only generated for SQLITE_DEBUG builds and are used to verify that registers are descoped propertly. But they can get in the way of code understanding when studying bytecode dumps. So this new optimization setting is provided to temporarily turn OP_ReleaseReg opcodes off. FossilOrigin-Name: fa5276725f246cef9d58b27c1e617ee3f873f7a9b88284a4e8fc453ebda338bc --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/sqliteInt.h | 1 + src/vdbeaux.c | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 3a5afaeadc..d1b23d0aac 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sparsing\sof\sC-style\scomments\sin\sLemon,\sas\sreported\sby\n[forum:/forumpost/b6edc69548|forum\spost\sb6edc69548].\s\sThis\shas\sno\saffect\non\sSQLite\sitself. -D 2022-04-07T14:13:32.478 +C The\s".testctrl\soptimizations\s0x400000"\scommand\sdisables\sthe\sgeneration\sof\nOP_ReleaseReg\sopcodes.\s\sOP_ReleaseReg\sopcodes\sare\susually\sonly\sgenerated\sfor\nSQLITE_DEBUG\sbuilds\sand\sare\sused\sto\sverify\sthat\sregisters\sare\sdescoped\npropertly.\s\sBut\sthey\scan\sget\sin\sthe\sway\sof\scode\sunderstanding\swhen\sstudying\nbytecode\sdumps.\s\sSo\sthis\snew\soptimization\ssetting\sis\sprovided\sto\ntemporarily\sturn\sOP_ReleaseReg\sopcodes\soff. +D 2022-04-07T18:17:56.434 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -557,7 +557,7 @@ F src/shell.c.in 18832612e74c92bbd25d88e1f92685f66589262f68cca1001d2a43bd6dd0ed6 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h dbd5537c36a6b01fd67890487c3f7da468f16845500c115886f20adec06869ca +F src/sqliteInt.h 8262a5a484ffc0c0899537c9d99fff381f2d76061e256592a342bc098860a6ec F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -628,7 +628,7 @@ F src/vdbe.c 4d8f5b013e1ad47240e9822217a4ac76041afd2667dcbefd26f598fe45f729a5 F src/vdbe.h 89f5edb1422c8783a0b29db836e409876f2b3e847f78e2b21b1fbcc48a93f85f F src/vdbeInt.h 5f3d0abcf30c2b7a6672ad4386f18be0fca9c9b2cefe18f85a2e3df74f2613bf F src/vdbeapi.c 354c893f1500cf524cc45c32879b9c68893a28b77e3442c24668d6afe4236217 -F src/vdbeaux.c 567ddcdd5d875161201e9752144834d1519e7e856e2da410619d88a9cfefe70d +F src/vdbeaux.c baafd56664ccca4cf361a48b912f7ff37f95ee19aaf7cada420ce2ca73396833 F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 7189090b72baa025f945a1ac8c61ee420c645254476e8a191d555db76dfea5d4 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 @@ -1945,8 +1945,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 5043a3507e0781878e0e1bea5095a33273958820baead4af8fc2929e9d7c07ee -R 3aa1ea2fb3309b52d9b9b355614ccef2 +P 201569e09b000919ccb463bd581fb2ecd5320e7f584fdb1bc2aaba111061d5c3 +R 3b3b7a8904349e1fc968ddd3854c9c21 U drh -Z a9f6250e4b921e7cc5eba2670fe5b4ea +Z 053f375f9db373c4b27ef764e92f78d7 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 604ab9337a..70d47c032f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -201569e09b000919ccb463bd581fb2ecd5320e7f584fdb1bc2aaba111061d5c3 \ No newline at end of file +fa5276725f246cef9d58b27c1e617ee3f873f7a9b88284a4e8fc453ebda338bc \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 9f95ec8a9d..a9f3121c7c 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1779,6 +1779,7 @@ struct sqlite3 { #define SQLITE_BloomFilter 0x00080000 /* Use a Bloom filter on searches */ #define SQLITE_BloomPulldown 0x00100000 /* Run Bloom filters early */ #define SQLITE_BalancedMerge 0x00200000 /* Balance multi-way merges */ +#define SQLITE_ReleaseReg 0x00400000 /* Use OP_ReleaseReg for testing */ #define SQLITE_AllOpts 0xffffffff /* All optimizations */ /* diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 551236226b..cb2433c2cd 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1231,7 +1231,7 @@ void sqlite3VdbeReleaseRegisters( u32 mask, /* Mask of registers to NOT release */ int bUndefine /* If true, mark registers as undefined */ ){ - if( N==0 ) return; + if( N==0 || OptimizationDisabled(pParse->db, SQLITE_ReleaseReg) ) return; assert( pParse->pVdbe ); assert( iFirst>=1 ); assert( iFirst+N-1<=pParse->nMem ); From e603ab00eee7002704ace0cafe072b91d909d37e Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 7 Apr 2022 19:06:31 +0000 Subject: [PATCH 086/259] Enhance the EXPLAIN output formatting in the CLI so that the subroutine that implements the loop body for the multi-index OR optimization is indented. FossilOrigin-Name: c2965fea9df7076b235d3eadaf84f0a36242476d0329030b0e57557b66e2540c --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/shell.c.in | 8 ++++++-- src/vdbe.c | 10 +++++++++- src/wherecode.c | 8 ++++++++ 5 files changed, 32 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index d1b23d0aac..66ed4df0ca 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\s".testctrl\soptimizations\s0x400000"\scommand\sdisables\sthe\sgeneration\sof\nOP_ReleaseReg\sopcodes.\s\sOP_ReleaseReg\sopcodes\sare\susually\sonly\sgenerated\sfor\nSQLITE_DEBUG\sbuilds\sand\sare\sused\sto\sverify\sthat\sregisters\sare\sdescoped\npropertly.\s\sBut\sthey\scan\sget\sin\sthe\sway\sof\scode\sunderstanding\swhen\sstudying\nbytecode\sdumps.\s\sSo\sthis\snew\soptimization\ssetting\sis\sprovided\sto\ntemporarily\sturn\sOP_ReleaseReg\sopcodes\soff. -D 2022-04-07T18:17:56.434 +C Enhance\sthe\sEXPLAIN\soutput\sformatting\sin\sthe\sCLI\sso\sthat\sthe\ssubroutine\sthat\nimplements\sthe\sloop\sbody\sfor\sthe\smulti-index\sOR\soptimization\sis\sindented. +D 2022-04-07T19:06:31.719 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -553,7 +553,7 @@ F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c 18d99e7146852d6064559561769fcca0743eb32b14a97da6dbed373a30ee0e76 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c d6c04eb93395024af80f61a8c278a33c2a0333aeb7d57bb6aa737a6f1c4af4b8 -F src/shell.c.in 18832612e74c92bbd25d88e1f92685f66589262f68cca1001d2a43bd6dd0ed60 +F src/shell.c.in 1a8fbf932ecd582b1a5f66c1e8294f92c30d954616f5c7cc54c9623fcdbb028d F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e @@ -624,7 +624,7 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c 4d8f5b013e1ad47240e9822217a4ac76041afd2667dcbefd26f598fe45f729a5 +F src/vdbe.c eefc5a96938cc113a95e36a42b626bf594a7f0b8bb56ae299accbbf015b973cd F src/vdbe.h 89f5edb1422c8783a0b29db836e409876f2b3e847f78e2b21b1fbcc48a93f85f F src/vdbeInt.h 5f3d0abcf30c2b7a6672ad4386f18be0fca9c9b2cefe18f85a2e3df74f2613bf F src/vdbeapi.c 354c893f1500cf524cc45c32879b9c68893a28b77e3442c24668d6afe4236217 @@ -641,7 +641,7 @@ F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b F src/where.c a2483d4fe7cde88638cd3140dd5d6ee3dc0c80d3b3fe20322a8d08dc451f97ae F src/whereInt.h 15d2975c3b4c193c78c26674400a840da8647fe1777ae3b026e2d15937b38a03 -F src/wherecode.c 555f598a9ddad81761f084710fdb4f8733fe31bc14cd6b19f8ca4274a7eaa04c +F src/wherecode.c 6292d7bf2d751b1ce68139a70e5468dd6615a9a9dab5b5e61c0053836723bb7a F src/whereexpr.c 612f58f5f6e3e3bb94d10e2c56672ade8bbf94d4a928d3edb4e84e2ed3c00dca F src/window.c 42a71595263dbd8ef8248218e4fc7d4b5ddccece52146ad48e079342d93f6f8f F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1945,8 +1945,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 201569e09b000919ccb463bd581fb2ecd5320e7f584fdb1bc2aaba111061d5c3 -R 3b3b7a8904349e1fc968ddd3854c9c21 +P fa5276725f246cef9d58b27c1e617ee3f873f7a9b88284a4e8fc453ebda338bc +R 3f3f316e7621b39e6212d4a123c3e0e2 U drh -Z 053f375f9db373c4b27ef764e92f78d7 +Z 65aae2da34a10e9f483e6d1ce0511661 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 70d47c032f..a72d788b29 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fa5276725f246cef9d58b27c1e617ee3f873f7a9b88284a4e8fc453ebda338bc \ No newline at end of file +c2965fea9df7076b235d3eadaf84f0a36242476d0329030b0e57557b66e2540c \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 9e6198f517..452e8b9cb1 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -2944,6 +2944,9 @@ static int str_in_array(const char *zStr, const char **azArray){ ** all opcodes that occur between the p2 jump destination and the opcode ** itself by 2 spaces. ** +** * Do the previous for "Return" instructions for when P2 is positive. +** See tag-20220407a in wherecode.c and vdbe.c. +** ** * For each "Goto", if the jump destination is earlier in the program ** and ends on one of: ** Yield SeekGt SeekLt RowSetRead Rewind @@ -2958,7 +2961,8 @@ static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){ int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */ int iOp; /* Index of operation in p->aiIndent[] */ - const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", 0 }; + const char *azNext[] = { "Next", "Prev", "VPrev", "VNext", "SorterNext", + "Return", 0 }; const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead", "Rewind", 0 }; const char *azGoto[] = { "Goto", 0 }; @@ -3016,7 +3020,7 @@ static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){ p->aiIndent[iOp] = 0; p->nIndent = iOp+1; - if( str_in_array(zOp, azNext) ){ + if( str_in_array(zOp, azNext) && p2op>0 ){ for(i=p2op; iaiIndent[i] += 2; } if( str_in_array(zOp, azGoto) && p2opnIndent diff --git a/src/vdbe.c b/src/vdbe.c index 02d0988f10..18286c297b 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -991,11 +991,19 @@ jump_to_p2: break; } -/* Opcode: Return P1 * P3 * * +/* Opcode: Return P1 P2 P3 * * ** ** Jump to the next instruction after the address in register P1. After ** the jump, register P1 becomes undefined. ** +** P2 is not used by the byte-code engine. However, if P2 is positive +** and also less than the current address, then the "EXPLAIN" output +** formatter in the CLI will indent all opcodes from the P2 opcode up +** to be not including the current Return. P2 should be the first opcode +** in the subroutine from which this opcode is returnning. Thus the P2 +** value is a byte-code indentation hint. See tag-20220407a in +** wherecode.c and shell.c. +** ** P3 is not used by the byte-code engine. However, the code generator ** sets P3 to address of the associated OP_BeginSubrtn opcode, if there is ** one. diff --git a/src/wherecode.c b/src/wherecode.c index ce0279a8f6..bab514a693 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -2534,6 +2534,14 @@ Bitmask sqlite3WhereCodeOneLoopStart( sqlite3VdbeGoto(v, pLevel->addrBrk); sqlite3VdbeResolveLabel(v, iLoopBody); + /* Set the P2 operand of the OP_Return opcode that will end the current + ** loop to point to this spot, which is the top of the next containing + ** loop. The byte-code formatter will use that P2 value as a hint to + ** indent everything in between the this point and the final OP_Return. + ** See tag-20220407a in vdbe.c and shell.c */ + assert( pLevel->op==OP_Return ); + pLevel->p2 = sqlite3VdbeCurrentAddr(v); + if( pWInfo->nLevel>1 ){ sqlite3StackFree(db, pOrTab); } if( !untestedTerms ) disableTerm(pLevel, pTerm); }else From ce5dd9e8d659f2e65031df7a9a6ed3a91ae417d7 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 7 Apr 2022 20:45:38 +0000 Subject: [PATCH 087/259] Fix two unreachable branches introduced by the recent sqlite3TriggersExist() optimization. FossilOrigin-Name: 1b5475d212cf9de0bff69eee8c607b4fcd8e04bf4df72171429e7609c4153951 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/trigger.c | 6 ++---- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 66ed4df0ca..9e29deaa06 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\sEXPLAIN\soutput\sformatting\sin\sthe\sCLI\sso\sthat\sthe\ssubroutine\sthat\nimplements\sthe\sloop\sbody\sfor\sthe\smulti-index\sOR\soptimization\sis\sindented. -D 2022-04-07T19:06:31.719 +C Fix\stwo\sunreachable\sbranches\sintroduced\sby\sthe\srecent\nsqlite3TriggersExist()\soptimization. +D 2022-04-07T20:45:38.697 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -618,7 +618,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98 F src/treeview.c 80a3d70bbc112399aa3cc7e777acc5d07c452e44c652630fc158d4594d86afd1 -F src/trigger.c 4cdfe612037f10a42b32a59ba2a356105d27f51fd245d448375b947fb34db9a4 +F src/trigger.c 372ada38f667c6823a3db15749eb668338e65c793394e55a37e56a489f2d1b55 F src/update.c 2cfaded82ca80ff56afb8c3ae5e88284e0824bfd86119827cc22481959f96f92 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 @@ -1945,8 +1945,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 fa5276725f246cef9d58b27c1e617ee3f873f7a9b88284a4e8fc453ebda338bc -R 3f3f316e7621b39e6212d4a123c3e0e2 +P c2965fea9df7076b235d3eadaf84f0a36242476d0329030b0e57557b66e2540c +R 07d0b0c26e9cd2798bbb00ddbafc6a3b U drh -Z 65aae2da34a10e9f483e6d1ce0511661 +Z 93237070ff101cf9292ceb1ee884c28a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a72d788b29..55edbcf9bb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c2965fea9df7076b235d3eadaf84f0a36242476d0329030b0e57557b66e2540c \ No newline at end of file +1b5475d212cf9de0bff69eee8c607b4fcd8e04bf4df72171429e7609c4153951 \ No newline at end of file diff --git a/src/trigger.c b/src/trigger.c index 3ff2ebc91b..109d82cc22 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -52,9 +52,7 @@ Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){ Trigger *pList; /* List of triggers to return */ HashElem *p; /* Loop variable for TEMP triggers */ - if( pParse->disableTriggers ){ - return 0; - } + assert( pParse->disableTriggers==0 ); pTmpSchema = pParse->db->aDb[1].pSchema; p = sqliteHashFirst(&pTmpSchema->trigHash); pList = pTab->pTrigger; @@ -733,7 +731,7 @@ static int checkColumnOverlap(IdList *pIdList, ExprList *pEList){ ** Return true if any TEMP triggers exist */ static int tempTriggersExist(sqlite3 *db){ - if( db->aDb[1].pSchema==0 ) return 0; + if( NEVER(db->aDb[1].pSchema==0) ) return 0; if( sqliteHashFirst(&db->aDb[1].pSchema->trigHash)==0 ) return 0; return 1; } From 81a23623d8790fca64f6e6551f59a2d4694dbf75 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 8 Apr 2022 15:11:10 +0000 Subject: [PATCH 088/259] Improved explanation and commentary on the sqlite3JoinType() routine. One of the error messages changes slightly, but besides that everything works the same. FossilOrigin-Name: 48f2e5a1fbaa8ceb32e08066766be74233b0c67ab430bbf7adfdff42cdb7b8ec --- manifest | 12 ++++----- manifest.uuid | 2 +- src/select.c | 75 +++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 68 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 9e29deaa06..a2472f06dc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stwo\sunreachable\sbranches\sintroduced\sby\sthe\srecent\nsqlite3TriggersExist()\soptimization. -D 2022-04-07T20:45:38.697 +C Improved\sexplanation\sand\scommentary\son\sthe\ssqlite3JoinType()\sroutine.\s\sOne\nof\sthe\serror\smessages\schanges\sslightly,\sbut\sbesides\sthat\severything\sworks\nthe\ssame. +D 2022-04-08T15:11:10.072 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -552,7 +552,7 @@ F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c 18d99e7146852d6064559561769fcca0743eb32b14a97da6dbed373a30ee0e76 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c d6c04eb93395024af80f61a8c278a33c2a0333aeb7d57bb6aa737a6f1c4af4b8 +F src/select.c 7c106b3f36d483242b0a9c696614cd53d6f29e1ac81da6a3f0e9ea92f4211cc3 F src/shell.c.in 1a8fbf932ecd582b1a5f66c1e8294f92c30d954616f5c7cc54c9623fcdbb028d F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1945,8 +1945,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 c2965fea9df7076b235d3eadaf84f0a36242476d0329030b0e57557b66e2540c -R 07d0b0c26e9cd2798bbb00ddbafc6a3b +P 1b5475d212cf9de0bff69eee8c607b4fcd8e04bf4df72171429e7609c4153951 +R 931142dc24337bfedaa0369d45a2c00c U drh -Z 93237070ff101cf9292ceb1ee884c28a +Z 277112caa7eb0641987ae3d1eca17748 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 55edbcf9bb..b27079fd83 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1b5475d212cf9de0bff69eee8c607b4fcd8e04bf4df72171429e7609c4153951 \ No newline at end of file +48f2e5a1fbaa8ceb32e08066766be74233b0c67ab430bbf7adfdff42cdb7b8ec \ No newline at end of file diff --git a/src/select.c b/src/select.c index 989446af61..7ac23bd388 100644 --- a/src/select.c +++ b/src/select.c @@ -204,6 +204,52 @@ static Select *findRightmost(Select *p){ ** ** If an illegal or unsupported join type is seen, then still return ** a join type, but put an error in the pParse structure. +** +** These are the valid join types: +** +** +** pA pB pC Return Value +** ------- ----- ----- ------------ +** CROSS - - JT_CROSS +** INNER - - JT_INNER +** LEFT - - JT_LEFT|JT_OUTER +** LEFT OUTER - JT_LEFT|JT_OUTER +** RIGHT - - JT_RIGHT|JT_OUTER +** RIGHT OUTER - JT_RIGHT|JT_OUTER +** FULL - - JT_LEFT|JT_RIGHT|JT_OUTER +** FULL OUTER - JT_LEFT|JT_RIGHT|JT_OUTER +** NATURAL INNER - JT_NATURAL|JT_INNER +** NATURAL LEFT - JT_NATURAL|JT_LEFT|JT_OUTER +** NATURAL LEFT OUTER JT_NATURAL|JT_LEFT|JT_OUTER +** NATURAL RIGHT - JT_NATURAL|JT_RIGHT|JT_OUTER +** NATURAL RIGHT OUTER JT_NATURAL|JT_RIGHT|JT_OUTER +** NATURAL FULL - JT_NATURAL|JT_LEFT|JT_RIGHT +** NATURAL FULL OUTER JT_NATRUAL|JT_LEFT|JT_RIGHT +** +** To preserve historical compatibly, SQLite also accepts a variety +** of other non-standard and in many cases non-sensical join types. +** This routine makes as much sense at it can from the nonsense join +** type and returns a result. Examples of accepted nonsense join types +** include but are not limited to: +** +** INNER CROSS JOIN -> same as JOIN +** NATURAL CROSS JOIN -> same as NATURAL JOIN +** OUTER LEFT JOIN -> same as LEFT JOIN +** LEFT NATURAL JOIN -> same as NATURAL LEFT JOIN +** LEFT RIGHT JOIN -> same as FULL JOIN +** RIGHT OUTER FULL JOIN -> same as FULL JOIN +** CROSS CROSS CROSS JOIN -> same as JOIN +** +** The only restrictions on the join type name are: +** +** * "INNER" cannot appear together with "OUTER", "LEFT", "RIGHT", +** or "FULL". +** +** * "CROSS" cannot appear together with "OUTER", "LEFT", "RIGHT, +** or "FULL". +** +** * If "OUTER" is present then there must also be one of +** "LEFT", "RIGHT", or "FULL" */ int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){ int jointype = 0; @@ -216,13 +262,13 @@ int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){ u8 nChar; /* Length of the keyword in characters */ u8 code; /* Join type mask */ } aKeyword[] = { - /* natural */ { 0, 7, JT_NATURAL }, - /* left */ { 6, 4, JT_LEFT|JT_OUTER }, - /* outer */ { 10, 5, JT_OUTER }, - /* right */ { 14, 5, JT_RIGHT|JT_OUTER }, - /* full */ { 19, 4, JT_LEFT|JT_RIGHT|JT_OUTER }, - /* inner */ { 23, 5, JT_INNER }, - /* cross */ { 28, 5, JT_INNER|JT_CROSS }, + /* (0) natural */ { 0, 7, JT_NATURAL }, + /* (1) left */ { 6, 4, JT_LEFT|JT_OUTER }, + /* (2) outer */ { 10, 5, JT_OUTER }, + /* (3) right */ { 14, 5, JT_RIGHT|JT_OUTER }, + /* (4) full */ { 19, 4, JT_LEFT|JT_RIGHT|JT_OUTER }, + /* (5) inner */ { 23, 5, JT_INNER }, + /* (6) cross */ { 28, 5, JT_INNER|JT_CROSS }, }; int i, j; apAll[0] = pA; @@ -245,16 +291,17 @@ int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){ } if( (jointype & (JT_INNER|JT_OUTER))==(JT_INNER|JT_OUTER) || - (jointype & JT_ERROR)!=0 + (jointype & JT_ERROR)!=0 || + (jointype & (JT_OUTER|JT_LEFT|JT_RIGHT))==JT_OUTER ){ - const char *zSp = " "; - assert( pB!=0 ); - if( pC==0 ){ zSp++; } + const char *zSp1 = " "; + const char *zSp2 = " "; + if( pB==0 ){ zSp1++; } + if( pC==0 ){ zSp2++; } sqlite3ErrorMsg(pParse, "unknown or unsupported join type: " - "%T %T%s%T", pA, pB, zSp, pC); + "%T%s%T%s%T", pA, zSp1, pB, zSp2, pC); jointype = JT_INNER; - }else if( (jointype & JT_OUTER)!=0 - && (jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ){ + }else if( (jointype & JT_RIGHT)!=0 ){ sqlite3ErrorMsg(pParse, "RIGHT and FULL OUTER JOINs are not currently supported"); jointype = JT_INNER; From 7d0ae00361386f87d179916d5abc6c11d3c85330 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 8 Apr 2022 17:01:29 +0000 Subject: [PATCH 089/259] Enhance the sqlite_dbpage fix at [/info/642a0b4752743216|check-in 642a0b4752743] from about a month ago such that it still takes a transaction on all attached databases, but it only starts a read transaction for read-only operations, rather than starting a write transaction for everything. FossilOrigin-Name: 8efd61e8518594e3e9c84681fc35796a78fe8885a97ad4dd19f1573ee8065b18 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/dbpage.c | 2 +- src/sqliteInt.h | 2 +- src/where.c | 17 ++++++++++++++--- 5 files changed, 25 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index a2472f06dc..4dcfbdb9c9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\sexplanation\sand\scommentary\son\sthe\ssqlite3JoinType()\sroutine.\s\sOne\nof\sthe\serror\smessages\schanges\sslightly,\sbut\sbesides\sthat\severything\sworks\nthe\ssame. -D 2022-04-08T15:11:10.072 +C Enhance\sthe\ssqlite_dbpage\sfix\sat\s[/info/642a0b4752743216|check-in\s642a0b4752743]\nfrom\sabout\sa\smonth\sago\ssuch\sthat\sit\sstill\stakes\sa\stransaction\son\sall\sattached\ndatabases,\sbut\sit\sonly\sstarts\sa\sread\stransaction\sfor\sread-only\soperations,\nrather\sthan\sstarting\sa\swrite\stransaction\sfor\severything. +D 2022-04-08T17:01:29.519 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -500,7 +500,7 @@ F src/callback.c 4c19af69835787bfe790ac560f3071a824eb629f34e41f97b52ce5235c77de1 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 026dbdcdbd8c3cde98a88483ee88310ff43150ab164ad768f12cc700a11495ad F src/date.c 15082566229d4b1e5f24fdb490bf9bcc68824b911d70e3573ef075a1b9e2d26f -F src/dbpage.c a70be9a4879ac5392673a1050d526a72b8b2f9938df7049f65348566a2637db3 +F src/dbpage.c 90661a87e1db8bfbc8d2ebbdcd3749651ddb287c555c07a28fb17c7c591ffb68 F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d F src/delete.c a8e844af211a48b13b5b358be77a12c860c6a557c21990ad51a548e2536500ce F src/expr.c 5e247a8dfabb92e9fd10b78a675dc5d25430433dfd9e316471b4447b548635ba @@ -557,7 +557,7 @@ F src/shell.c.in 1a8fbf932ecd582b1a5f66c1e8294f92c30d954616f5c7cc54c9623fcdbb028 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h 8262a5a484ffc0c0899537c9d99fff381f2d76061e256592a342bc098860a6ec +F src/sqliteInt.h 364699d46b6cd2fbcaedfb907cedd42c8ed6e32a671f7f72edb257cad861c40b F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -639,7 +639,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c a2483d4fe7cde88638cd3140dd5d6ee3dc0c80d3b3fe20322a8d08dc451f97ae +F src/where.c a17d57807aa63dca4f3204d01db7a863bc0290bd7913928582236d65c9ad4212 F src/whereInt.h 15d2975c3b4c193c78c26674400a840da8647fe1777ae3b026e2d15937b38a03 F src/wherecode.c 6292d7bf2d751b1ce68139a70e5468dd6615a9a9dab5b5e61c0053836723bb7a F src/whereexpr.c 612f58f5f6e3e3bb94d10e2c56672ade8bbf94d4a928d3edb4e84e2ed3c00dca @@ -1945,8 +1945,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 1b5475d212cf9de0bff69eee8c607b4fcd8e04bf4df72171429e7609c4153951 -R 931142dc24337bfedaa0369d45a2c00c +P 48f2e5a1fbaa8ceb32e08066766be74233b0c67ab430bbf7adfdff42cdb7b8ec +R 20c6686a28e5cb126a28d0c27a5e917b U drh -Z 277112caa7eb0641987ae3d1eca17748 +Z 5fb2265312a791be3cfc50f876b63b0a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b27079fd83..081aaf7939 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -48f2e5a1fbaa8ceb32e08066766be74233b0c67ab430bbf7adfdff42cdb7b8ec \ No newline at end of file +8efd61e8518594e3e9c84681fc35796a78fe8885a97ad4dd19f1573ee8065b18 \ No newline at end of file diff --git a/src/dbpage.c b/src/dbpage.c index 8a997e2def..003997b95f 100644 --- a/src/dbpage.c +++ b/src/dbpage.c @@ -156,7 +156,7 @@ static int dbpageBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ ){ pIdxInfo->orderByConsumed = 1; } - sqlite3VtabWriteAll(pIdxInfo); + sqlite3VtabUsesAllSchemas(pIdxInfo); return SQLITE_OK; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index a9f3121c7c..ead20c9a2f 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -5174,7 +5174,7 @@ int sqlite3VtabBegin(sqlite3 *, VTable *); FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*); #if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \ && !defined(SQLITE_OMIT_VIRTUALTABLE) - void sqlite3VtabWriteAll(sqlite3_index_info*); + void sqlite3VtabUsesAllSchemas(sqlite3_index_info*); #endif sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*); int sqlite3VdbeParameterIndex(Vdbe*, const char*, int); diff --git a/src/where.c b/src/where.c index f9f42d5285..f08c350b06 100644 --- a/src/where.c +++ b/src/where.c @@ -3788,15 +3788,26 @@ int sqlite3_vtab_distinct(sqlite3_index_info *pIdxInfo){ && !defined(SQLITE_OMIT_VIRTUALTABLE) /* ** Cause the prepared statement that is associated with a call to -** xBestIndex to open write transactions on all attached schemas. +** xBestIndex to potentiall use all schemas. If the statement being +** prepared is read-only, then just start read transactions on all +** schemas. But if this is a write operation, start writes on all +** schemas. +** ** This is used by the (built-in) sqlite_dbpage virtual table. */ -void sqlite3VtabWriteAll(sqlite3_index_info *pIdxInfo){ +void sqlite3VtabUsesAllSchemas(sqlite3_index_info *pIdxInfo){ HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; Parse *pParse = pHidden->pParse; int nDb = pParse->db->nDb; int i; - for(i=0; iwriteMask ){ + for(i=0; i Date: Fri, 8 Apr 2022 19:20:12 +0000 Subject: [PATCH 090/259] Preliminary code to support RIGHT JOIN. Everything seems to work, except that the code to compute the unmatched rows for the RIGHT JOIN has not yet been added, so the result of a RIGHT JOIN is currently the same as an INNER JOIN. FossilOrigin-Name: 415abd6731b8e8a605adabfa6066c8a852a8531c300df41325d5f7e75cae5a70 --- manifest | 33 +++++++++++---------- manifest.uuid | 2 +- src/build.c | 14 ++++++++- src/resolve.c | 4 +-- src/select.c | 10 ++----- src/sqliteInt.h | 15 +++++----- src/treeview.c | 6 +++- src/where.c | 79 +++++++++++++++++++++++-------------------------- src/wherecode.c | 6 ++-- src/whereexpr.c | 2 +- test/join.test | 12 ++++---- test/vtab6.test | 10 +++---- 12 files changed, 103 insertions(+), 90 deletions(-) diff --git a/manifest b/manifest index 4dcfbdb9c9..3f80acc376 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\ssqlite_dbpage\sfix\sat\s[/info/642a0b4752743216|check-in\s642a0b4752743]\nfrom\sabout\sa\smonth\sago\ssuch\sthat\sit\sstill\stakes\sa\stransaction\son\sall\sattached\ndatabases,\sbut\sit\sonly\sstarts\sa\sread\stransaction\sfor\sread-only\soperations,\nrather\sthan\sstarting\sa\swrite\stransaction\sfor\severything. -D 2022-04-08T17:01:29.519 +C Preliminary\scode\sto\ssupport\sRIGHT\sJOIN.\sEverything\sseems\sto\swork,\sexcept\sthat\nthe\scode\sto\scompute\sthe\sunmatched\srows\sfor\sthe\sRIGHT\sJOIN\shas\snot\syet\sbeen\nadded,\sso\sthe\sresult\sof\sa\sRIGHT\sJOIN\sis\scurrently\sthe\ssame\sas\san\sINNER\sJOIN. +D 2022-04-08T19:20:12.051 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -495,7 +495,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 45161c2d5c9527b9c9bbfd7478daf3e0a619cf4bbe3278378aaea3d4b4e4f5b5 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482e -F src/build.c ff119be98394a65bc8be7afc39d4a791a66f03a778d396de3ec456f5dfaf39e8 +F src/build.c 4a35acbeb5a73e5dfb0ed199a4ba601179cd22216654f9eb14c1dcfe993673e8 F src/callback.c 4c19af69835787bfe790ac560f3071a824eb629f34e41f97b52ce5235c77de1c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 026dbdcdbd8c3cde98a88483ee88310ff43150ab164ad768f12cc700a11495ad @@ -550,14 +550,14 @@ F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c fd940149c691684e7c1073c3787a7170e44852b02d1275d2e30a5b58e89cfcaf F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c -F src/resolve.c 18d99e7146852d6064559561769fcca0743eb32b14a97da6dbed373a30ee0e76 +F src/resolve.c 7110fc3b5a4dec5d11559141c1906c4a125349fb602f541b05db3a3d448d4b95 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 7c106b3f36d483242b0a9c696614cd53d6f29e1ac81da6a3f0e9ea92f4211cc3 +F src/select.c cfa10564953f08eae09e0e92038b168403aade2879ba772cd5a47a08474da5fe F src/shell.c.in 1a8fbf932ecd582b1a5f66c1e8294f92c30d954616f5c7cc54c9623fcdbb028d F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h 364699d46b6cd2fbcaedfb907cedd42c8ed6e32a671f7f72edb257cad861c40b +F src/sqliteInt.h f8dc31c997573ac608a52bd98af91f21298d46b392732267aefa84b705be0e5c F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -617,7 +617,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98 -F src/treeview.c 80a3d70bbc112399aa3cc7e777acc5d07c452e44c652630fc158d4594d86afd1 +F src/treeview.c d1401c129c980ace571f5071b91c349b8ad00bdb3d6f7112fb97a3da8bac85ff F src/trigger.c 372ada38f667c6823a3db15749eb668338e65c793394e55a37e56a489f2d1b55 F src/update.c 2cfaded82ca80ff56afb8c3ae5e88284e0824bfd86119827cc22481959f96f92 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 @@ -639,10 +639,10 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c a17d57807aa63dca4f3204d01db7a863bc0290bd7913928582236d65c9ad4212 +F src/where.c c752850f0d4b21656ef2901484fb7c799a6d20efe1d13fa5e77a3554b7568625 F src/whereInt.h 15d2975c3b4c193c78c26674400a840da8647fe1777ae3b026e2d15937b38a03 -F src/wherecode.c 6292d7bf2d751b1ce68139a70e5468dd6615a9a9dab5b5e61c0053836723bb7a -F src/whereexpr.c 612f58f5f6e3e3bb94d10e2c56672ade8bbf94d4a928d3edb4e84e2ed3c00dca +F src/wherecode.c 7025f2a5b8b160af7ec4837e5d3c5befc2e61f0aafeea3f5f0403e46674f284f +F src/whereexpr.c a4542ee72e05e4ab9dfadb5ddc0116007dc2420763992a79dbe83aaf73212311 F src/window.c 42a71595263dbd8ef8248218e4fc7d4b5ddccece52146ad48e079342d93f6f8f F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 @@ -1140,7 +1140,7 @@ F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4 F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b F test/istrue.test e7f285bb70282625c258e866ce6337d4c762922f5a300e1b50f958aef6e7d9c9 -F test/join.test 85e9c88bf4700b45a48a6362cd47e0c0aefc572629827c31aa58a5978cabdfc5 +F test/join.test a1832675aa30f2b422ff934b553e30294ca899484710242a2119ebf21f20a66a F test/join2.test 9bdc615841b91c97a16d68bad9508aea11fa0c6b34e5689847bcc4dac70e4990 F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 @@ -1711,7 +1711,7 @@ F test/vtab2.test 14d4ab26cee13ba6cf5c5601b158e4f57552d3b055cdd9406cf7f711e9c840 F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e F test/vtab4.test 8e73ed268f3d596bc3590f45fc948fb40f28e9c3 F test/vtab5.test 889f444970393c73f1e077e2bdc5d845e157a391 -F test/vtab6.test 7167e8e526bc2e719e7818e18b2fd7bb8c455fa018b74e611943a86782e10125 +F test/vtab6.test 5f5c10c694763d9cb438ec12aab7d6899f0bd6e2fa120551e11dea3daa8063ca F test/vtab7.test 70c6f4a1d6177144a8236e4172d5fba92e683440374664ad1f04851fbb335d3c F test/vtab8.test e19fa4a538fcd1bb66c22825fa8f71618fb13583 F test/vtab9.test ea58d2b95d61955f87226381716b2d0b1d4e4f9b @@ -1945,8 +1945,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 48f2e5a1fbaa8ceb32e08066766be74233b0c67ab430bbf7adfdff42cdb7b8ec -R 20c6686a28e5cb126a28d0c27a5e917b +P 8efd61e8518594e3e9c84681fc35796a78fe8885a97ad4dd19f1573ee8065b18 +R 322c8c2f976fdab57b24f3e90a096129 +T *branch * right-join +T *sym-right-join * +T -sym-trunk * U drh -Z 5fb2265312a791be3cfc50f876b63b0a +Z 04b77679382a7e72969224c19421c972 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 081aaf7939..9efedb98ec 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8efd61e8518594e3e9c84681fc35796a78fe8885a97ad4dd19f1573ee8065b18 \ No newline at end of file +415abd6731b8e8a605adabfa6066c8a852a8531c300df41325d5f7e75cae5a70 \ No newline at end of file diff --git a/src/build.c b/src/build.c index da862fa707..7181011c32 100644 --- a/src/build.c +++ b/src/build.c @@ -5071,10 +5071,22 @@ void sqlite3SrcListFuncArgs(Parse *pParse, SrcList *p, ExprList *pList){ void sqlite3SrcListShiftJoinType(SrcList *p){ if( p ){ int i; + u8 allFlags = 0; for(i=p->nSrc-1; i>0; i--){ - p->a[i].fg.jointype = p->a[i-1].fg.jointype; + allFlags |= p->a[i].fg.jointype = p->a[i-1].fg.jointype; } p->a[0].fg.jointype = 0; + + /* All terms to the left of a RIGHT JOIN should be tagged with the + ** JT_LTORJ flags */ + if( allFlags & JT_RIGHT ){ + for(i=p->nSrc-1; ALWAYS(i>0) && (p->a[i].fg.jointype&JT_RIGHT)==0; i--){} + i--; + assert( i>=0 ); + do{ + p->a[i--].fg.jointype |= JT_LTORJ; + }while( i>=0 ); + } } } diff --git a/src/resolve.c b/src/resolve.c index 30785ca706..ac00564daa 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -367,9 +367,7 @@ static int lookupName( pExpr->iTable = pMatch->iCursor; assert( ExprUseYTab(pExpr) ); pExpr->y.pTab = pMatch->pTab; - /* RIGHT JOIN not (yet) supported */ - assert( (pMatch->fg.jointype & JT_RIGHT)==0 ); - if( (pMatch->fg.jointype & JT_LEFT)!=0 ){ + if( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 ){ ExprSetProperty(pExpr, EP_CanBeNull); } pSchema = pExpr->y.pTab->pSchema; diff --git a/src/select.c b/src/select.c index 7ac23bd388..b9321aece7 100644 --- a/src/select.c +++ b/src/select.c @@ -301,10 +301,6 @@ int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){ sqlite3ErrorMsg(pParse, "unknown or unsupported join type: " "%T%s%T%s%T", pA, zSp1, pB, zSp2, pC); jointype = JT_INNER; - }else if( (jointype & JT_RIGHT)!=0 ){ - sqlite3ErrorMsg(pParse, - "RIGHT and FULL OUTER JOINs are not currently supported"); - jointype = JT_INNER; } return jointype; } @@ -6589,7 +6585,7 @@ int sqlite3Select( && i==0 && (p->selFlags & SF_ComplexResult)!=0 && (pTabList->nSrc==1 - || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0) + || (pTabList->a[1].fg.jointype&(JT_OUTER|JT_CROSS))!=0) ){ continue; } @@ -6741,8 +6737,8 @@ int sqlite3Select( */ if( i==0 && (pTabList->nSrc==1 - || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0) /* (1) */ - && (pItem->fg.isCte==0 || pItem->u2.pCteUse->eM10d!=M10d_Yes) /* (2) */ + || (pTabList->a[1].fg.jointype&(JT_OUTER|JT_CROSS))!=0) /* (1) */ + && (pItem->fg.isCte==0 || pItem->u2.pCteUse->eM10d!=M10d_Yes) /* (2) */ ){ /* Implement a co-routine that will return a single row of the result ** set on each invocation. diff --git a/src/sqliteInt.h b/src/sqliteInt.h index ead20c9a2f..264a9d3731 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3132,13 +3132,14 @@ struct SrcList { /* ** Permitted values of the SrcList.a.jointype field */ -#define JT_INNER 0x0001 /* Any kind of inner or cross join */ -#define JT_CROSS 0x0002 /* Explicit use of the CROSS keyword */ -#define JT_NATURAL 0x0004 /* True for a "natural" join */ -#define JT_LEFT 0x0008 /* Left outer join */ -#define JT_RIGHT 0x0010 /* Right outer join */ -#define JT_OUTER 0x0020 /* The "OUTER" keyword is present */ -#define JT_ERROR 0x0040 /* unknown or unsupported join type */ +#define JT_INNER 0x01 /* Any kind of inner or cross join */ +#define JT_CROSS 0x02 /* Explicit use of the CROSS keyword */ +#define JT_NATURAL 0x04 /* True for a "natural" join */ +#define JT_LEFT 0x08 /* Left outer join */ +#define JT_RIGHT 0x10 /* Right outer join */ +#define JT_OUTER 0x20 /* The "OUTER" keyword is present */ +#define JT_LTORJ 0x40 /* One of the LEFT operands of a RIGHT JOIN */ +#define JT_ERROR 0x80 /* unknown or unsupported join type */ /* diff --git a/src/treeview.c b/src/treeview.c index 91aff8ddf1..f32064cd8e 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -144,8 +144,12 @@ void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p used=%llx", pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab, pItem->colUsed); } - if( pItem->fg.jointype & JT_LEFT ){ + if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))==(JT_LEFT|JT_RIGHT) ){ + sqlite3_str_appendf(&x, " FULL-OUTER-JOIN"); + }else if( pItem->fg.jointype & JT_LEFT ){ sqlite3_str_appendf(&x, " LEFT-JOIN"); + }else if( pItem->fg.jointype & JT_RIGHT ){ + sqlite3_str_appendf(&x, " RIGHT-JOIN"); }else if( pItem->fg.jointype & JT_CROSS ){ sqlite3_str_appendf(&x, " CROSS-JOIN"); } diff --git a/src/where.c b/src/where.c index f08c350b06..60e314e758 100644 --- a/src/where.c +++ b/src/where.c @@ -732,13 +732,13 @@ static int termCanDriveIndex( char aff; if( pTerm->leftCursor!=pSrc->iCursor ) return 0; if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0; - if( (pSrc->fg.jointype & JT_LEFT) + if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 && !ExprHasProperty(pTerm->pExpr, EP_FromJoin) && (pTerm->eOperator & WO_IS) ){ /* Cannot use an IS term from the WHERE clause as an index driver for - ** the RHS of a LEFT JOIN. Such a term can only be used if it is from - ** the ON clause. */ + ** the RHS of a LEFT JOIN or for the LHS of a RIGHT JOIN. Such a term + ** can only be used if it is from the ON clause. */ return 0; } if( (pTerm->prereqRight & notReady)!=0 ) return 0; @@ -808,7 +808,8 @@ static SQLITE_NOINLINE void constructAutomaticIndex( ** WHERE clause (or the ON clause of a LEFT join) that constrain which ** rows of the target table (pSrc) that can be used. */ if( (pTerm->wtFlags & TERM_VIRTUAL)==0 - && ((pSrc->fg.jointype&JT_LEFT)==0 || ExprHasProperty(pExpr,EP_FromJoin)) + && ((pSrc->fg.jointype&(JT_LEFT|JT_LTORJ))==0 + || ExprHasProperty(pExpr,EP_FromJoin)) && sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor) ){ pPartial = sqlite3ExprAnd(pParse, pPartial, @@ -1081,7 +1082,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( const SrcItem *pTabItem; pLevel = &pWInfo->a[iLevel]; pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; - if( pTabItem->fg.jointype & JT_LEFT ) continue; + if( pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ) ) continue; pLoop = pLevel->pWLoop; if( NEVER(pLoop==0) ) continue; if( pLoop->prereq & notReady ) continue; @@ -1154,9 +1155,10 @@ static sqlite3_index_info *allocateIndexInfo( assert( pTerm->u.x.leftColumnnCol ); /* tag-20191211-002: WHERE-clause constraints are not useful to the - ** right-hand table of a LEFT JOIN. See tag-20191211-001 for the + ** right-hand table of a LEFT JOIN nor to the left-hand table of a + ** RIGHT JOIN. See tag-20191211-001 for the ** equivalent restriction for ordinary tables. */ - if( (pSrc->fg.jointype & JT_LEFT)!=0 + if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 && !ExprHasProperty(pTerm->pExpr, EP_FromJoin) ){ continue; @@ -2600,10 +2602,11 @@ static void whereLoopOutputAdjust( ** ** 2022-03-24: Self-culling only applies if either the extra terms ** are straight comparison operators that are non-true with NULL - ** operand, or if the loop is not a LEFT JOIN. + ** operand, or if the loop is not an OUTER JOIN. */ if( (pTerm->eOperator & 0x3f)!=0 - || (pWC->pWInfo->pTabList->a[pLoop->iTab].fg.jointype & JT_LEFT)==0 + || (pWC->pWInfo->pTabList->a[pLoop->iTab].fg.jointype + & (JT_LEFT|JT_LTORJ))==0 ){ pLoop->wsFlags |= WHERE_SELFCULL; } @@ -2810,9 +2813,10 @@ static int whereLoopAddBtreeIndex( if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue; /* tag-20191211-001: Do not allow constraints from the WHERE clause to - ** be used by the right table of a LEFT JOIN. Only constraints in the + ** be used by the right table of a LEFT JOIN nor by the left table of a + ** RIGHT JOIN. Only constraints in the ** ON clause are allowed. See tag-20191211-002 for the vtab equivalent. */ - if( (pSrc->fg.jointype & JT_LEFT)!=0 + if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 && !ExprHasProperty(pTerm->pExpr, EP_FromJoin) ){ continue; @@ -4114,9 +4118,9 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ pNew->iTab = iTab; pBuilder->iPlanLimit += SQLITE_QUERY_PLANNER_LIMIT_INCR; pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor); - if( (pItem->fg.jointype & (JT_LEFT|JT_CROSS))!=0 ){ + if( (pItem->fg.jointype & (JT_OUTER|JT_CROSS))!=0 ){ /* This condition is true when pItem is the FROM clause term on the - ** right-hand-side of a LEFT or CROSS JOIN. */ + ** right-hand-side of a OUTER or CROSS JOIN. */ mPrereq = mPrior; }else{ mPrereq = 0; @@ -4125,7 +4129,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ if( IsVirtual(pItem->pTab) ){ SrcItem *p; for(p=&pItem[1]; pfg.jointype & (JT_LEFT|JT_CROSS)) ){ + if( mUnusable || (p->fg.jointype & (JT_OUTER|JT_CROSS)) ){ mUnusable |= sqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor); } } @@ -5844,6 +5848,10 @@ WhereInfo *sqlite3WhereBegin( } } if( iDb>=0 ) sqlite3CodeVerifySchema(pParse, iDb); + if( pTabItem->fg.jointype & JT_RIGHT ){ + VdbeModuleComment((v, "TO-DO: Setup for the RIGHT JOIN of %s", + pTab->zName)); + } } pWInfo->iTop = sqlite3VdbeCurrentAddr(v); if( db->mallocFailed ) goto whereBeginError; @@ -6091,11 +6099,6 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ pWInfo->pTabList->a[pLevel->iFrom].pTab->zName)); } - /* The "break" point is here, just past the end of the outer loop. - ** Set it. - */ - sqlite3VdbeResolveLabel(v, pWInfo->iBreak); - assert( pWInfo->nLevel<=pTabList->nSrc ); for(i=0, pLevel=pWInfo->a; inLevel; i++, pLevel++){ int k, last; @@ -6106,6 +6109,16 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ assert( pTab!=0 ); pLoop = pLevel->pWLoop; + /* Do RIGHT JOIN processing. Generate code that will output the + ** unmatched rows of the right operand of the RIGHT JOIN with + ** all of the columns of the left operand set to NULL. + */ + if( pTabItem->fg.jointype & JT_RIGHT ){ + VdbeModuleComment((v, "TO-DO: RIGHT JOIN post-processing for %s", + pTab->zName)); + + } + /* For a co-routine, change all OP_Column references to the table of ** the co-routine into OP_Copy of result contained in a register. ** OP_Rowid becomes OP_Null. @@ -6117,29 +6130,6 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ continue; } -#ifdef SQLITE_ENABLE_EARLY_CURSOR_CLOSE - /* Close all of the cursors that were opened by sqlite3WhereBegin. - ** Except, do not close cursors that will be reused by the OR optimization - ** (WHERE_OR_SUBCLAUSE). And do not close the OP_OpenWrite cursors - ** created for the ONEPASS optimization. - */ - if( (pTab->tabFlags & TF_Ephemeral)==0 - && !IsView(pTab) - && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 - ){ - int ws = pLoop->wsFlags; - if( pWInfo->eOnePass==ONEPASS_OFF && (ws & WHERE_IDX_ONLY)==0 ){ - sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor); - } - if( (ws & WHERE_INDEXED)!=0 - && (ws & (WHERE_IPK|WHERE_AUTO_INDEX))==0 - && pLevel->iIdxCur!=pWInfo->aiCurOnePass[1] - ){ - sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur); - } - } -#endif - /* If this scan uses an index, make VDBE code substitutions to read data ** from the index instead of from the table where possible. In some cases ** this optimization prevents the table from ever being read, which can @@ -6240,6 +6230,11 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ } } + /* The "break" point is here, just past the end of the outer loop. + ** Set it. + */ + sqlite3VdbeResolveLabel(v, pWInfo->iBreak); + /* Final cleanup */ if( pWInfo->pExprMods ) whereUndoExprMods(pWInfo); diff --git a/src/wherecode.c b/src/wherecode.c index bab514a693..d349a94024 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -2604,7 +2604,9 @@ Bitmask sqlite3WhereCodeOneLoopStart( } pE = pTerm->pExpr; assert( pE!=0 ); - if( (pTabItem->fg.jointype&JT_LEFT) && !ExprHasProperty(pE,EP_FromJoin) ){ + if( (pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ)) + && !ExprHasProperty(pE,EP_FromJoin) + ){ continue; } @@ -2666,7 +2668,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue; if( (pTerm->eOperator & WO_EQUIV)==0 ) continue; if( pTerm->leftCursor!=iCur ) continue; - if( pTabItem->fg.jointype & JT_LEFT ) continue; + if( pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ) ) continue; pE = pTerm->pExpr; #ifdef WHERETRACE_ENABLED /* 0x800 */ if( sqlite3WhereTrace & 0x800 ){ diff --git a/src/whereexpr.c b/src/whereexpr.c index 26a521fffd..b74164d1f5 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1831,7 +1831,7 @@ void sqlite3WhereTabFuncArgs( pRhs = sqlite3PExpr(pParse, TK_UPLUS, sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0); pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs); - if( pItem->fg.jointype & JT_LEFT ){ + if( pItem->fg.jointype & (JT_LEFT|JT_LTORJ) ){ sqlite3SetJoinExpr(pTerm, pItem->iCursor); } whereClauseInsert(pWC, pTerm, TERM_DYNAMIC); diff --git a/test/join.test b/test/join.test index f48a1a149d..fdacfc25c2 100644 --- a/test/join.test +++ b/test/join.test @@ -272,11 +272,13 @@ do_test join-2.2 { SELECT * FROM t2 NATURAL LEFT OUTER JOIN t1; } } {1 2 3 {} 2 3 4 1 3 4 5 2} -do_test join-2.3 { - catchsql { - SELECT * FROM t1 NATURAL RIGHT OUTER JOIN t2; - } -} {1 {RIGHT and FULL OUTER JOINs are not currently supported}} + +#do_test join-2.3 { +# catchsql { +# SELECT * FROM t1 NATURAL RIGHT OUTER JOIN t2; +# } +#} {1 {RIGHT and FULL OUTER JOINs are not currently supported}} + do_test join-2.4 { execsql { SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.d diff --git a/test/vtab6.test b/test/vtab6.test index ab52c9f15c..d8016e02f4 100644 --- a/test/vtab6.test +++ b/test/vtab6.test @@ -223,11 +223,11 @@ do_test vtab6-2.2 { SELECT * FROM t2 NATURAL LEFT OUTER JOIN t1; } } {1 2 3 {} 2 3 4 1 3 4 5 2} -do_test vtab6-2.3 { - catchsql { - SELECT * FROM t1 NATURAL RIGHT OUTER JOIN t2; - } -} {1 {RIGHT and FULL OUTER JOINs are not currently supported}} +#do_test vtab6-2.3 { +# catchsql { +# SELECT * FROM t1 NATURAL RIGHT OUTER JOIN t2; +# } +#} {1 {RIGHT and FULL OUTER JOINs are not currently supported}} do_test vtab6-2.4 { execsql { SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.d From f8bdcfa3f17dead618d9f4f3d680f7a5cba4083b Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 9 Apr 2022 03:06:01 +0000 Subject: [PATCH 091/259] The sqlite3WhereMalloc() routine allocates memory that is automatically deleted when the corresponding WhereInfo object is destroyed. FossilOrigin-Name: f237e1d8cc41b937f34288daebfacf5f7b0990a807a805e0cb6b45bc730192d6 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/where.c | 37 +++++++++++++++++++++++++++++-------- src/whereInt.h | 13 +++++++++++++ src/wherecode.c | 5 +++-- src/whereexpr.c | 10 ++-------- 6 files changed, 57 insertions(+), 28 deletions(-) diff --git a/manifest b/manifest index 4dcfbdb9c9..bf8983c822 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\ssqlite_dbpage\sfix\sat\s[/info/642a0b4752743216|check-in\s642a0b4752743]\nfrom\sabout\sa\smonth\sago\ssuch\sthat\sit\sstill\stakes\sa\stransaction\son\sall\sattached\ndatabases,\sbut\sit\sonly\sstarts\sa\sread\stransaction\sfor\sread-only\soperations,\nrather\sthan\sstarting\sa\swrite\stransaction\sfor\severything. -D 2022-04-08T17:01:29.519 +C The\ssqlite3WhereMalloc()\sroutine\sallocates\smemory\sthat\sis\sautomatically\ndeleted\swhen\sthe\scorresponding\sWhereInfo\sobject\sis\sdestroyed. +D 2022-04-09T03:06:01.731 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -639,10 +639,10 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c a17d57807aa63dca4f3204d01db7a863bc0290bd7913928582236d65c9ad4212 -F src/whereInt.h 15d2975c3b4c193c78c26674400a840da8647fe1777ae3b026e2d15937b38a03 -F src/wherecode.c 6292d7bf2d751b1ce68139a70e5468dd6615a9a9dab5b5e61c0053836723bb7a -F src/whereexpr.c 612f58f5f6e3e3bb94d10e2c56672ade8bbf94d4a928d3edb4e84e2ed3c00dca +F src/where.c 929ac88a1b65bcdef7e05a0b87b13a0c55cd3d5d3bc27ec81a6f37eaca13e5fe +F src/whereInt.h 41ce0a8c0368372d8422e420e05a1e037624ce52fae139c3c19538ee491fb4c0 +F src/wherecode.c b7bc24b150d6a47c48844f89c3bf6d8f694780acb71768c83b9bec8a729e0d81 +F src/whereexpr.c 2ce4ff64b80fce0a0f7579f5ec2b953f10952a3410c441564e12b650ea8c2aba F src/window.c 42a71595263dbd8ef8248218e4fc7d4b5ddccece52146ad48e079342d93f6f8f F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 @@ -1945,8 +1945,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 48f2e5a1fbaa8ceb32e08066766be74233b0c67ab430bbf7adfdff42cdb7b8ec -R 20c6686a28e5cb126a28d0c27a5e917b +P 8efd61e8518594e3e9c84681fc35796a78fe8885a97ad4dd19f1573ee8065b18 +R 48010733dae82cb9023efd9a61e0d9ba U drh -Z 5fb2265312a791be3cfc50f876b63b0a +Z a50ac2a16236eccfde93e32da194e6bb # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 081aaf7939..0f6e9d2f91 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8efd61e8518594e3e9c84681fc35796a78fe8885a97ad4dd19f1573ee8065b18 \ No newline at end of file +f237e1d8cc41b937f34288daebfacf5f7b0990a807a805e0cb6b45bc730192d6 \ No newline at end of file diff --git a/src/where.c b/src/where.c index f08c350b06..4820a5c031 100644 --- a/src/where.c +++ b/src/where.c @@ -253,6 +253,30 @@ Bitmask sqlite3WhereGetMask(WhereMaskSet *pMaskSet, int iCursor){ return 0; } +/* Allocate memory that is automatically freed when pWInfo is freed. +*/ +void *sqlite3WhereMalloc(WhereInfo *pWInfo, u64 nByte){ + WhereMemBlock *pBlock; + pBlock = sqlite3DbMallocRawNN(pWInfo->pParse->db, nByte+sizeof(*pBlock)); + if( pBlock ){ + pBlock->pNext = pWInfo->pMemToFree; + pBlock->sz = nByte; + pWInfo->pMemToFree = pBlock; + pBlock++; + } + return (void*)pBlock; +} +void *sqlite3WhereRealloc(WhereInfo *pWInfo, void *pOld, u64 nByte){ + void *pNew = sqlite3WhereMalloc(pWInfo, nByte); + if( pNew && pOld ){ + WhereMemBlock *pOldBlk = (WhereMemBlock*)pOld; + pOldBlk--; + assert( pOldBlk->szsz); + } + return pNew; +} + /* ** Create a new mask for cursor iCursor. ** @@ -2216,15 +2240,7 @@ static void whereLoopDelete(sqlite3 *db, WhereLoop *p){ ** Free a WhereInfo structure */ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){ - int i; assert( pWInfo!=0 ); - for(i=0; inLevel; i++){ - WhereLevel *pLevel = &pWInfo->a[i]; - if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE)!=0 ){ - assert( (pLevel->pWLoop->wsFlags & WHERE_MULTI_OR)==0 ); - sqlite3DbFree(db, pLevel->u.in.aInLoop); - } - } sqlite3WhereClauseClear(&pWInfo->sWC); while( pWInfo->pLoops ){ WhereLoop *p = pWInfo->pLoops; @@ -2232,6 +2248,11 @@ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){ whereLoopDelete(db, p); } assert( pWInfo->pExprMods==0 ); + while( pWInfo->pMemToFree ){ + WhereMemBlock *pNext = pWInfo->pMemToFree->pNext; + sqlite3DbFreeNN(db, pWInfo->pMemToFree); + pWInfo->pMemToFree = pNext; + } sqlite3DbFreeNN(db, pWInfo); } diff --git a/src/whereInt.h b/src/whereInt.h index 3fc39f6b4a..e0f44d6bac 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -32,6 +32,16 @@ typedef struct WhereLoopBuilder WhereLoopBuilder; typedef struct WhereScan WhereScan; typedef struct WhereOrCost WhereOrCost; typedef struct WhereOrSet WhereOrSet; +typedef struct WhereMemBlock WhereMemBlock; + +/* +** This object is a header on a block of allocated memory that will be +** automatically freed when its WInfo oject is destructed. +*/ +struct WhereMemBlock { + WhereMemBlock *pNext; /* Next block in the chain */ + u8 sz; /* Bytes of space */ +}; /* ** This object contains information needed to implement a single nested @@ -478,6 +488,7 @@ struct WhereInfo { int iEndWhere; /* End of the WHERE clause itself */ WhereLoop *pLoops; /* List of all WhereLoop objects */ WhereExprMod *pExprMods; /* Expression modifications */ + WhereMemBlock *pMemToFree;/* Memory to free when this object destroyed */ Bitmask revMask; /* Mask of ORDER BY terms that need reversing */ WhereClause sWC; /* Decomposition of the WHERE clause */ WhereMaskSet sMaskSet; /* Map cursor numbers to bitmasks */ @@ -503,6 +514,8 @@ WhereTerm *sqlite3WhereFindTerm( u32 op, /* Mask of WO_xx values describing operator */ Index *pIdx /* Must be compatible with this index, if not NULL */ ); +void *sqlite3WhereMalloc(WhereInfo *pWInfo, u64 nByte); +void *sqlite3WhereRealloc(WhereInfo *pWInfo, void *pOld, u64 nByte); /* wherecode.c: */ #ifndef SQLITE_OMIT_EXPLAIN diff --git a/src/wherecode.c b/src/wherecode.c index bab514a693..561b34fc85 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -640,8 +640,9 @@ static int codeEqualityTerm( i = pLevel->u.in.nIn; pLevel->u.in.nIn += nEq; pLevel->u.in.aInLoop = - sqlite3DbReallocOrFree(pParse->db, pLevel->u.in.aInLoop, - sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn); + sqlite3WhereRealloc(pTerm->pWC->pWInfo, + pLevel->u.in.aInLoop, + sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn); pIn = pLevel->u.in.aInLoop; if( pIn ){ int iMap = 0; /* Index in aiMap[] */ diff --git a/src/whereexpr.c b/src/whereexpr.c index 26a521fffd..a3316db65b 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -64,7 +64,7 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){ if( pWC->nTerm>=pWC->nSlot ){ WhereTerm *pOld = pWC->a; sqlite3 *db = pWC->pWInfo->pParse->db; - pWC->a = sqlite3DbMallocRawNN(db, sizeof(pWC->a[0])*pWC->nSlot*2 ); + pWC->a = sqlite3WhereMalloc(pWC->pWInfo, sizeof(pWC->a[0])*pWC->nSlot*2 ); if( pWC->a==0 ){ if( wtFlags & TERM_DYNAMIC ){ sqlite3ExprDelete(db, p); @@ -73,10 +73,7 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){ return 0; } memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm); - if( pOld!=pWC->aStatic ){ - sqlite3DbFree(db, pOld); - } - pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]); + pWC->nSlot = pWC->nSlot*2; } pTerm = &pWC->a[idx = pWC->nTerm++]; if( (wtFlags & TERM_VIRTUAL)==0 ) pWC->nBase = pWC->nTerm; @@ -1686,9 +1683,6 @@ void sqlite3WhereClauseClear(WhereClause *pWC){ a++; } } - if( pWC->a!=pWC->aStatic ){ - sqlite3DbFree(db, pWC->a); - } } From c2308ad2a0cb4f6d957518c615d308ed79b42d04 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 9 Apr 2022 03:16:26 +0000 Subject: [PATCH 092/259] A few bits and bobs of code generation toward getting RIGHT JOIN to work. Much more remains to do. FossilOrigin-Name: 55b4543122646997d928598343bc467c993f971e86e9037c85430cc948750576 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/where.c | 18 ++++++++++++++++-- src/whereInt.h | 1 + src/wherecode.c | 35 +++++++++++++++++++++++++++++++++++ 5 files changed, 61 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 65eef2b977..639cdc85c3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\ssqlite3WhereMalloc()\sroutine\sfrom\strunk\sinto\sthe\sright-join\sbranch. -D 2022-04-09T03:12:52.801 +C A\sfew\sbits\sand\sbobs\sof\scode\sgeneration\stoward\sgetting\sRIGHT\sJOIN\sto\swork.\nMuch\smore\sremains\sto\sdo. +D 2022-04-09T03:16:26.838 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -639,9 +639,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c 20b6907d66577c02bc2be434c3c8fd5f00f0112d467cb8ae5d97ced3af14f484 -F src/whereInt.h 41ce0a8c0368372d8422e420e05a1e037624ce52fae139c3c19538ee491fb4c0 -F src/wherecode.c 79813939e009cbd8a042d57e6c0cad1a437d8e2e19b8be61c70760089f055c89 +F src/where.c 3bd028fa90533d5caad6c3160e404eff2595ee751a8e2c1f4d1617975caa192c +F src/whereInt.h 5cd48fd01bff983a86d0ef02f8e0c9a5c870dbaebc4d7b2ae2212aefd5df9cd7 +F src/wherecode.c f25a1d1ad2a8d002805e107d2ec323db410ad0246a52b944d10b8d4da0e01f7c F src/whereexpr.c ac8985bbd983f34273b1e0d05cd738ff436331674c1b22f4caf6537e1eca4691 F src/window.c 42a71595263dbd8ef8248218e4fc7d4b5ddccece52146ad48e079342d93f6f8f F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1945,8 +1945,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 415abd6731b8e8a605adabfa6066c8a852a8531c300df41325d5f7e75cae5a70 f237e1d8cc41b937f34288daebfacf5f7b0990a807a805e0cb6b45bc730192d6 -R 14570ffbcb3ed6fd5a47242c31653712 +P b1b3845aa38f469a27f07c8f6e8a98334f7967b19661ee4cf155d6997afd9d4c +R bc7d39cae3cf9a210e7fffa29f471f8f U drh -Z 80db52d601f5cc05776abad4ced7d9c5 +Z cd50394e42c6a1bed1272dd9e082a119 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b82dd29e59..1618a7c5ef 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b1b3845aa38f469a27f07c8f6e8a98334f7967b19661ee4cf155d6997afd9d4c \ No newline at end of file +55b4543122646997d928598343bc467c993f971e86e9037c85430cc948750576 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 338501090f..a5fab2cd51 100644 --- a/src/where.c +++ b/src/where.c @@ -5870,8 +5870,22 @@ WhereInfo *sqlite3WhereBegin( } if( iDb>=0 ) sqlite3CodeVerifySchema(pParse, iDb); if( pTabItem->fg.jointype & JT_RIGHT ){ - VdbeModuleComment((v, "TO-DO: Setup for the RIGHT JOIN of %s", - pTab->zName)); + assert( pTab==pTabItem->pTab ); + pLevel->iRJMatch = pParse->nTab++; + if( HasRowid(pTab) ){ + KeyInfo *pInfo; + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pLevel->iRJMatch, 1); + pInfo = sqlite3KeyInfoAlloc(pParse->db, 1, 0); + if( pInfo ){ + pInfo->aColl[0] = 0; + pInfo->aSortFlags[0] = 0; + sqlite3VdbeAppendP4(v, pInfo, P4_KEYINFO); + } + }else{ + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pLevel->iRJMatch, pPk->nKeyCol); + sqlite3VdbeSetP4KeyInfo(pParse, pPk); + } } } pWInfo->iTop = sqlite3VdbeCurrentAddr(v); diff --git a/src/whereInt.h b/src/whereInt.h index e0f44d6bac..df62db4f10 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -75,6 +75,7 @@ struct WhereLevel { int addrLikeRep; /* LIKE range processing address */ #endif int regFilter; /* Bloom filter */ + int iRJMatch; /* Cursor or rowset used for matched RIGHT JOIN rows */ u8 iFrom; /* Which entry in the FROM clause */ u8 op, p3, p5; /* Opcode, P3 & P5 of the opcode that ends the loop */ int p1, p2; /* Operands of the opcode used to end the loop */ diff --git a/src/wherecode.c b/src/wherecode.c index 74873de091..5b8ed8934b 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -2721,6 +2721,41 @@ Bitmask sqlite3WhereCodeOneLoopStart( } } + /* For a RIGHT OUTER JOIN, record the fact that the current row has + ** been matched at least once. + */ + if( pLevel->iRJMatch ){ + Table *pTab; + int nPk; + int r; + int jmp1 = 0; + + pTab = pWInfo->pTabList->a[pLevel->iFrom].pTab; + if( HasRowid(pTab) ){ + r = sqlite3GetTempRange(pParse, 2); + sqlite3ExprCodeGetColumnOfTable(v, pTab, pLevel->iTabCur, -1, r+1); + nPk = 1; + }else{ + int iPk; + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + nPk = pPk->nKeyCol; + r = sqlite3GetTempRange(pParse, nPk+1); + for(iPk=0; iPkaiColumn[iPk]; + sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol,r+1+iPk); + } + } + jmp1 = sqlite3VdbeAddOp4Int(v, OP_Found, pLevel->iRJMatch, 0, r+1, nPk); + VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_MakeRecord, r+1, nPk, r); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pLevel->iRJMatch, r, r+1, nPk); + sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); + sqlite3VdbeJumpHere(v, jmp1); + + /* Release the array of temp registers */ + sqlite3ReleaseTempRange(pParse, r, nPk+1); + } + #if WHERETRACE_ENABLED /* 0x20800 */ if( sqlite3WhereTrace & 0x20000 ){ sqlite3DebugPrintf("All WHERE-clause terms after coding level %d:\n", From 7c1734b09e436176c2aac461e835c29532403ad4 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 9 Apr 2022 12:27:20 +0000 Subject: [PATCH 093/259] The interior of the RIGHT JOIN loop is now a subroutine. FossilOrigin-Name: 549f5a7ee639de80f049445002f58e93c805f9a3d3db1987ec9d139ccef4805e --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/where.c | 19 +++++++++++++++---- src/whereInt.h | 13 ++++++++++++- src/wherecode.c | 24 +++++++++++++++++++----- 5 files changed, 55 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 639cdc85c3..f63c9edb92 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C A\sfew\sbits\sand\sbobs\sof\scode\sgeneration\stoward\sgetting\sRIGHT\sJOIN\sto\swork.\nMuch\smore\sremains\sto\sdo. -D 2022-04-09T03:16:26.838 +C The\sinterior\sof\sthe\sRIGHT\sJOIN\sloop\sis\snow\sa\ssubroutine. +D 2022-04-09T12:27:20.408 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -639,9 +639,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c 3bd028fa90533d5caad6c3160e404eff2595ee751a8e2c1f4d1617975caa192c -F src/whereInt.h 5cd48fd01bff983a86d0ef02f8e0c9a5c870dbaebc4d7b2ae2212aefd5df9cd7 -F src/wherecode.c f25a1d1ad2a8d002805e107d2ec323db410ad0246a52b944d10b8d4da0e01f7c +F src/where.c 8aed75fc91e396b4576fcd8fc38e617a049496102e36ab92f1ff79b88c06ad27 +F src/whereInt.h ecf0d9fe3e35f2546e660c6389e56aedb6fd2434e31a0449b261ff55ebc6df2d +F src/wherecode.c 39532c183ea306ae44b5ab3119b244407b46970b088c59d5751c5724b4b6ec15 F src/whereexpr.c ac8985bbd983f34273b1e0d05cd738ff436331674c1b22f4caf6537e1eca4691 F src/window.c 42a71595263dbd8ef8248218e4fc7d4b5ddccece52146ad48e079342d93f6f8f F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1945,8 +1945,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 b1b3845aa38f469a27f07c8f6e8a98334f7967b19661ee4cf155d6997afd9d4c -R bc7d39cae3cf9a210e7fffa29f471f8f +P 55b4543122646997d928598343bc467c993f971e86e9037c85430cc948750576 +R d55a6c933c69ce9dd22747640f9c6ba1 U drh -Z cd50394e42c6a1bed1272dd9e082a119 +Z 4ad8351a3e92bf37b209fecc61321431 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 1618a7c5ef..e1f7456fca 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -55b4543122646997d928598343bc467c993f971e86e9037c85430cc948750576 \ No newline at end of file +549f5a7ee639de80f049445002f58e93c805f9a3d3db1987ec9d139ccef4805e \ No newline at end of file diff --git a/src/where.c b/src/where.c index a5fab2cd51..afcecd77bf 100644 --- a/src/where.c +++ b/src/where.c @@ -5869,12 +5869,18 @@ WhereInfo *sqlite3WhereBegin( } } if( iDb>=0 ) sqlite3CodeVerifySchema(pParse, iDb); - if( pTabItem->fg.jointype & JT_RIGHT ){ + if( (pTabItem->fg.jointype & JT_RIGHT)!=0 + && (pLevel->pRJ = sqlite3WhereMalloc(pWInfo, sizeof(WhereRightJoin)))!=0 + ){ + WhereRightJoin *pRJ = pLevel->pRJ; + pRJ->iMatch = pParse->nTab++; + pRJ->regBloom = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Blob, 65536, pRJ->regBloom); + pRJ->regReturn = ++pParse->nMem; assert( pTab==pTabItem->pTab ); - pLevel->iRJMatch = pParse->nTab++; if( HasRowid(pTab) ){ KeyInfo *pInfo; - sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pLevel->iRJMatch, 1); + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRJ->iMatch, 1); pInfo = sqlite3KeyInfoAlloc(pParse->db, 1, 0); if( pInfo ){ pInfo->aColl[0] = 0; @@ -5883,7 +5889,7 @@ WhereInfo *sqlite3WhereBegin( } }else{ Index *pPk = sqlite3PrimaryKeyIndex(pTab); - sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pLevel->iRJMatch, pPk->nKeyCol); + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRJ->iMatch, pPk->nKeyCol); sqlite3VdbeSetP4KeyInfo(pParse, pPk); } } @@ -5999,6 +6005,11 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ for(i=pWInfo->nLevel-1; i>=0; i--){ int addr; pLevel = &pWInfo->a[i]; + if( pLevel->pRJ ){ + WhereRightJoin *pRJ = (WhereRightJoin*)pLevel->pRJ; + sqlite3VdbeChangeP2(v, pRJ->addrSubrtn-1, sqlite3VdbeCurrentAddr(v)); + sqlite3VdbeAddOp2(v, OP_Return, pRJ->regReturn, pRJ->addrSubrtn); + } pLoop = pLevel->pWLoop; if( pLevel->op!=OP_Noop ){ #ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT diff --git a/src/whereInt.h b/src/whereInt.h index df62db4f10..7b5be3011d 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -33,6 +33,7 @@ typedef struct WhereScan WhereScan; typedef struct WhereOrCost WhereOrCost; typedef struct WhereOrSet WhereOrSet; typedef struct WhereMemBlock WhereMemBlock; +typedef struct WhereRightJoin WhereRightJoin; /* ** This object is a header on a block of allocated memory that will be @@ -43,6 +44,16 @@ struct WhereMemBlock { u8 sz; /* Bytes of space */ }; +/* +** Extra information attached to a WhereLevel that is a RIGHT JOIN. +*/ +struct WhereRightJoin { + int iMatch; /* Cursor used to determine prior matched rows */ + int regBloom; /* Bloom filter for iRJMatch */ + int regReturn; /* Return register for the interior subroutine */ + int addrSubrtn; /* Starting address for the interior subroutine */ +}; + /* ** This object contains information needed to implement a single nested ** loop in WHERE clause. @@ -75,7 +86,7 @@ struct WhereLevel { int addrLikeRep; /* LIKE range processing address */ #endif int regFilter; /* Bloom filter */ - int iRJMatch; /* Cursor or rowset used for matched RIGHT JOIN rows */ + WhereRightJoin *pRJ; /* Extra information for RIGHT JOIN */ u8 iFrom; /* Which entry in the FROM clause */ u8 op, p3, p5; /* Opcode, P3 & P5 of the opcode that ends the loop */ int p1, p2; /* Operands of the opcode used to end the loop */ diff --git a/src/wherecode.c b/src/wherecode.c index 5b8ed8934b..853646c713 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -2724,12 +2724,18 @@ Bitmask sqlite3WhereCodeOneLoopStart( /* For a RIGHT OUTER JOIN, record the fact that the current row has ** been matched at least once. */ - if( pLevel->iRJMatch ){ + if( pLevel->pRJ ){ Table *pTab; int nPk; int r; int jmp1 = 0; + WhereRightJoin *pRJ = pLevel->pRJ; + /* pTab is the right-hand table of the RIGHT JOIN. Generate code that + ** will record that the current row of that table has been matched at + ** least once. This is accomplished by storing the PK for the row in + ** both the iMatch index and the regBloom Bloom filter. + */ pTab = pWInfo->pTabList->a[pLevel->iFrom].pTab; if( HasRowid(pTab) ){ r = sqlite3GetTempRange(pParse, 2); @@ -2745,15 +2751,23 @@ Bitmask sqlite3WhereCodeOneLoopStart( sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol,r+1+iPk); } } - jmp1 = sqlite3VdbeAddOp4Int(v, OP_Found, pLevel->iRJMatch, 0, r+1, nPk); + jmp1 = sqlite3VdbeAddOp4Int(v, OP_Found, pRJ->iMatch, 0, r+1, nPk); VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_MakeRecord, r+1, nPk, r); - sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pLevel->iRJMatch, r, r+1, nPk); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pRJ->iMatch, r, r+1, nPk); + sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pRJ->regBloom, 0, r+1, nPk); sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); sqlite3VdbeJumpHere(v, jmp1); - - /* Release the array of temp registers */ sqlite3ReleaseTempRange(pParse, r, nPk+1); + + /* Create a subroutine used to process all interior loops and code + ** of the RIGHT JOIN. During normal operation, the subroutine will + ** be in-line with the rest of the code. But at the end, a separate + ** loop will run that invokes this subroutine for unmatched rows + ** of pTab, with all tables to left begin set to NULL. + */ + sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pRJ->regReturn); + pRJ->addrSubrtn = sqlite3VdbeCurrentAddr(v); } #if WHERETRACE_ENABLED /* 0x20800 */ From 86c1beb402ef54c1427d5f2e6bbc38ebe1249843 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 9 Apr 2022 14:48:35 +0000 Subject: [PATCH 094/259] Add byte-code that computes unmatched rows on the right table of a RIGHT JOIN. Compiles, and the code looks semi-reasonable, but still does not run. Incremental check-in. FossilOrigin-Name: 2db5a498e74241dd19ef51c601f1a2b3b687faed3e1be2d1e3ada737406ac8e9 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 53 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index f63c9edb92..c3406710bb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sinterior\sof\sthe\sRIGHT\sJOIN\sloop\sis\snow\sa\ssubroutine. -D 2022-04-09T12:27:20.408 +C Add\sbyte-code\sthat\scomputes\sunmatched\srows\son\sthe\sright\stable\sof\sa\sRIGHT\sJOIN.\nCompiles,\sand\sthe\scode\slooks\ssemi-reasonable,\sbut\sstill\sdoes\snot\srun.\nIncremental\scheck-in. +D 2022-04-09T14:48:35.562 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -639,7 +639,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c 8aed75fc91e396b4576fcd8fc38e617a049496102e36ab92f1ff79b88c06ad27 +F src/where.c 7d0b140d373dce6b86e4023239265db5c4af465ea3cf1ff92f9a38369518e166 F src/whereInt.h ecf0d9fe3e35f2546e660c6389e56aedb6fd2434e31a0449b261ff55ebc6df2d F src/wherecode.c 39532c183ea306ae44b5ab3119b244407b46970b088c59d5751c5724b4b6ec15 F src/whereexpr.c ac8985bbd983f34273b1e0d05cd738ff436331674c1b22f4caf6537e1eca4691 @@ -1945,8 +1945,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 55b4543122646997d928598343bc467c993f971e86e9037c85430cc948750576 -R d55a6c933c69ce9dd22747640f9c6ba1 +P 549f5a7ee639de80f049445002f58e93c805f9a3d3db1987ec9d139ccef4805e +R 897adc2c472d0e3292a88884e473c6ff U drh -Z 4ad8351a3e92bf37b209fecc61321431 +Z 9e61af1d71063444102e67ca76812f4f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e1f7456fca..3031369ad5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -549f5a7ee639de80f049445002f58e93c805f9a3d3db1987ec9d139ccef4805e \ No newline at end of file +2db5a498e74241dd19ef51c601f1a2b3b687faed3e1be2d1e3ada737406ac8e9 \ No newline at end of file diff --git a/src/where.c b/src/where.c index afcecd77bf..eec8ccb981 100644 --- a/src/where.c +++ b/src/where.c @@ -6006,7 +6006,9 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ int addr; pLevel = &pWInfo->a[i]; if( pLevel->pRJ ){ - WhereRightJoin *pRJ = (WhereRightJoin*)pLevel->pRJ; + /* Terminate the subroutine that forms the interior of the loop of + ** the RIGHT JOIN table */ + WhereRightJoin *pRJ = pLevel->pRJ; sqlite3VdbeChangeP2(v, pRJ->addrSubrtn-1, sqlite3VdbeCurrentAddr(v)); sqlite3VdbeAddOp2(v, OP_Return, pRJ->regReturn, pRJ->addrSubrtn); } @@ -6159,10 +6161,49 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ ** unmatched rows of the right operand of the RIGHT JOIN with ** all of the columns of the left operand set to NULL. */ - if( pTabItem->fg.jointype & JT_RIGHT ){ - VdbeModuleComment((v, "TO-DO: RIGHT JOIN post-processing for %s", - pTab->zName)); - + if( pLevel->pRJ ){ + WhereRightJoin *pRJ = pLevel->pRJ; + Expr *pSubWhere = 0; + WhereClause *pWC = &pWInfo->sWC; + WhereInfo *pSubWInfo; + SrcList sFrom; + for(k=0; knTerm; k++){ + WhereTerm *pTerm = &pWC->a[i]; + if( pTerm->wtFlags & TERM_VIRTUAL ) break; + if( pTerm->prereqAll & ~pLoop->maskSelf ) continue; + pSubWhere = sqlite3ExprAnd(pParse, pSubWhere, + sqlite3ExprDup(db, pTerm->pExpr, 0)); + } + sFrom.nSrc = 1; + sFrom.nAlloc = 1; + memcpy(&sFrom.a[0], pTabItem, sizeof(SrcItem)); + sFrom.a[0].fg.jointype = 0; + pSubWInfo = sqlite3WhereBegin(pParse, &sFrom, pSubWhere, 0, 0, 0, + WHERE_OR_SUBCLAUSE, 0); + if( pSubWInfo ){ + int iCur = pLevel->iTabCur; + int r = ++pParse->nMem; + int nPk; + int addrCont = sqlite3WhereContinueLabel(pSubWInfo); + if( HasRowid(pTab) ){ + sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, r); + nPk = 1; + }else{ + int iPk; + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + nPk = pPk->nKeyCol; + pParse->nMem += nPk - 1; + for(iPk=0; iPkaiColumn[iPk]; + sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol,r+iPk); + } + } + sqlite3VdbeAddOp4Int(v, OP_Filter, pRJ->regBloom, addrCont, r, nPk); + sqlite3VdbeAddOp4Int(v, OP_Found, pRJ->iMatch, addrCont, r, nPk); + sqlite3VdbeAddOp2(v, OP_Gosub, pRJ->regReturn, pRJ->addrSubrtn); + sqlite3WhereEnd(pSubWInfo); + } + sqlite3ExprDelete(pParse->db, pSubWhere); } /* For a co-routine, change all OP_Column references to the table of From de24dd706e3f5e23389ad314a8941af8f56c8a2f Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 9 Apr 2022 18:48:11 +0000 Subject: [PATCH 095/259] Bug fixes. A basic FULL OUTER JOIN now works. FossilOrigin-Name: 34bbeeb77bd530b2b1f0390e9e552f65ae35f09a74d80a09dd327e64f9be51a1 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 6 ++++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index c3406710bb..f2bc29afed 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sbyte-code\sthat\scomputes\sunmatched\srows\son\sthe\sright\stable\sof\sa\sRIGHT\sJOIN.\nCompiles,\sand\sthe\scode\slooks\ssemi-reasonable,\sbut\sstill\sdoes\snot\srun.\nIncremental\scheck-in. -D 2022-04-09T14:48:35.562 +C Bug\sfixes.\s\sA\sbasic\sFULL\sOUTER\sJOIN\snow\sworks. +D 2022-04-09T18:48:11.005 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -639,7 +639,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c 7d0b140d373dce6b86e4023239265db5c4af465ea3cf1ff92f9a38369518e166 +F src/where.c ddeca7f959c3da448012737c0bf0c283232a317c7ef0bdc6587352f4189bd8aa F src/whereInt.h ecf0d9fe3e35f2546e660c6389e56aedb6fd2434e31a0449b261ff55ebc6df2d F src/wherecode.c 39532c183ea306ae44b5ab3119b244407b46970b088c59d5751c5724b4b6ec15 F src/whereexpr.c ac8985bbd983f34273b1e0d05cd738ff436331674c1b22f4caf6537e1eca4691 @@ -1945,8 +1945,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 549f5a7ee639de80f049445002f58e93c805f9a3d3db1987ec9d139ccef4805e -R 897adc2c472d0e3292a88884e473c6ff +P 2db5a498e74241dd19ef51c601f1a2b3b687faed3e1be2d1e3ada737406ac8e9 +R 0ae50938e4462db8bba3d38695099c31 U drh -Z 9e61af1d71063444102e67ca76812f4f +Z 29e379e6c2c78a86783f35cb54daa623 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3031369ad5..df20f470e8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2db5a498e74241dd19ef51c601f1a2b3b687faed3e1be2d1e3ada737406ac8e9 \ No newline at end of file +34bbeeb77bd530b2b1f0390e9e552f65ae35f09a74d80a09dd327e64f9be51a1 \ No newline at end of file diff --git a/src/where.c b/src/where.c index eec8ccb981..bec9da8db0 100644 --- a/src/where.c +++ b/src/where.c @@ -6009,7 +6009,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ /* Terminate the subroutine that forms the interior of the loop of ** the RIGHT JOIN table */ WhereRightJoin *pRJ = pLevel->pRJ; - sqlite3VdbeChangeP2(v, pRJ->addrSubrtn-1, sqlite3VdbeCurrentAddr(v)); + sqlite3VdbeChangeP1(v, pRJ->addrSubrtn-1, sqlite3VdbeCurrentAddr(v)); sqlite3VdbeAddOp2(v, OP_Return, pRJ->regReturn, pRJ->addrSubrtn); } pLoop = pLevel->pWLoop; @@ -6184,6 +6184,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ int iCur = pLevel->iTabCur; int r = ++pParse->nMem; int nPk; + int jmp; int addrCont = sqlite3WhereContinueLabel(pSubWInfo); if( HasRowid(pTab) ){ sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, r); @@ -6198,8 +6199,9 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol,r+iPk); } } - sqlite3VdbeAddOp4Int(v, OP_Filter, pRJ->regBloom, addrCont, r, nPk); + jmp = sqlite3VdbeAddOp4Int(v, OP_Filter, pRJ->regBloom, 0, r, nPk); sqlite3VdbeAddOp4Int(v, OP_Found, pRJ->iMatch, addrCont, r, nPk); + sqlite3VdbeJumpHere(v, jmp); sqlite3VdbeAddOp2(v, OP_Gosub, pRJ->regReturn, pRJ->addrSubrtn); sqlite3WhereEnd(pSubWInfo); } From 039132be208664a241b831a8a6ade069a8bb8c4d Mon Sep 17 00:00:00 2001 From: larrybr Date: Sat, 9 Apr 2022 18:51:49 +0000 Subject: [PATCH 096/259] Fix .import bug reported at https://sqlite.org/forum/forumpost/14db09d7e765b819 . zAutoColumn made to deliver characters, not bytes. FossilOrigin-Name: 21e96600d90c1cda84777abe22a11058eba46c9faefeb05f8c31bc0e7fa84b19 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/shell.c.in | 4 ++-- test/shell5.test | 30 ++++++++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index bf8983c822..e767080f57 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\ssqlite3WhereMalloc()\sroutine\sallocates\smemory\sthat\sis\sautomatically\ndeleted\swhen\sthe\scorresponding\sWhereInfo\sobject\sis\sdestroyed. -D 2022-04-09T03:06:01.731 +C Fix\s.import\sbug\sreported\sat\shttps://sqlite.org/forum/forumpost/14db09d7e765b819\s.\szAutoColumn\smade\sto\sdeliver\scharacters,\snot\sbytes. +D 2022-04-09T18:51:49.784 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -553,7 +553,7 @@ F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c 18d99e7146852d6064559561769fcca0743eb32b14a97da6dbed373a30ee0e76 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 7c106b3f36d483242b0a9c696614cd53d6f29e1ac81da6a3f0e9ea92f4211cc3 -F src/shell.c.in 1a8fbf932ecd582b1a5f66c1e8294f92c30d954616f5c7cc54c9623fcdbb028d +F src/shell.c.in eb7f10d5e2c47bd014d92ec5db1def21fcc1ed56ffaaa4ee715b6c37c370b47f F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e @@ -1393,7 +1393,7 @@ F test/shell1.test b224e0793c5f48aa3749e65d8c64b93a30731bd206f2e41e6c5f1bee1bdb1 F test/shell2.test 7a3a23a9f57b99453f1679b1fe8072cb30e382a622874c0c4d97695fadb0a787 F test/shell3.test a50628ab1d78d90889d9d3f32fb2c084ee15674771e96afe954aaa0accd1de3c F test/shell4.test 8f6c0fce4abed19a8a7f7262517149812a04caa905d01bdc8f5e92573504b759 -F test/shell5.test 0a9920d81fae28c45cd5dbd1deb809487a23c5f4b422a49f9d31c85f926d4a9c +F test/shell5.test 78a7a8516b1e7de560748881424f621321549023d3e5f7ed2e1c56497f64c06c F test/shell6.test 1ceb51b2678c472ba6cf1e5da96679ce8347889fe2c3bf93a0e0fa73f00b00d3 F test/shell7.test 115132f66d0463417f408562cc2cf534f6bbc6d83a6d50f0072a9eb171bae97f F test/shell8.test 388471d16e4de767333107e30653983f186232c0e863f4490bb230419e830aae @@ -1945,8 +1945,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 8efd61e8518594e3e9c84681fc35796a78fe8885a97ad4dd19f1573ee8065b18 -R 48010733dae82cb9023efd9a61e0d9ba -U drh -Z a50ac2a16236eccfde93e32da194e6bb +P f237e1d8cc41b937f34288daebfacf5f7b0990a807a805e0cb6b45bc730192d6 +R 32d747db1a8abc3115c9e0c3c720312e +U larrybr +Z 31d16ad9966991b7487e6e03ff8edde4 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0f6e9d2f91..b96920f440 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f237e1d8cc41b937f34288daebfacf5f7b0990a807a805e0cb6b45bc730192d6 \ No newline at end of file +21e96600d90c1cda84777abe22a11058eba46c9faefeb05f8c31bc0e7fa84b19 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 452e8b9cb1..996a7f942b 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -7962,12 +7962,12 @@ SELECT\ ','||iif((cpos-1)%4>0, ' ', x'0a'||' '))\ ||')' AS ColsSpec \ FROM (\ - SELECT cpos, printf('\"%w\"',printf('%.*s%s', nlen-chop,name,suff)) AS cname \ + SELECT cpos, printf('\"%w\"',printf('%!.*s%s', nlen-chop,name,suff)) AS cname \ FROM ColNames ORDER BY cpos\ )"; static const char * const zRenamesDone = "SELECT group_concat(" - " printf('\"%w\" to \"%w\"',name,printf('%.*s%s', nlen-chop, name, suff))," + " printf('\"%w\" to \"%w\"',name,printf('%!.*s%s', nlen-chop, name, suff))," " ','||x'0a')" "FROM ColNames WHERE suff<>'' OR chop!=0" ; diff --git a/test/shell5.test b/test/shell5.test index d63a0a20d3..00d89f8d78 100644 --- a/test/shell5.test +++ b/test/shell5.test @@ -540,4 +540,34 @@ Columns renamed during .import shell5.csv due to duplicates: "CoW" to "CoW_3", "cOw" to "cOw_4"}} +#---------------------------------------------------------------------------- +# Tests for preserving utf-8 that is not also ASCII. +# + +do_test shell5-6.1 { + set out [open shell5.csv w] + fconfigure $out -translation lf + puts $out {あい,うえお} + puts $out {1,2} + close $out + forcedelete test.db + catchcmd test.db {.import -csv shell5.csv t1 +.mode line +SELECT * FROM t1;} +} {0 { あい = 1 +うえお = 2}} + +do_test shell5-6.2 { + set out [open shell5.csv w] + fconfigure $out -translation lf + puts $out {1,2} + puts $out {あい,うえお} + close $out + forcedelete test.db + catchcmd test.db {.import -csv shell5.csv t1 +.mode line +SELECT * FROM t1;} +} {0 { 1 = あい + 2 = うえお}} + finish_test From ac8c438a79012f60c8acbbf9b9793fb18b91a518 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 9 Apr 2022 20:11:05 +0000 Subject: [PATCH 097/259] Add a simple test case. (It is not difficult to create additional test cases that assert, at this point.) FossilOrigin-Name: f2201d5dcfc552bdddd0780b3f466bdaa886e557f147335c085395bfc001f6b0 --- manifest | 11 ++++++----- manifest.uuid | 2 +- test/join7.test | 28 ++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 test/join7.test diff --git a/manifest b/manifest index f2bc29afed..ad2ff76bde 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Bug\sfixes.\s\sA\sbasic\sFULL\sOUTER\sJOIN\snow\sworks. -D 2022-04-09T18:48:11.005 +C Add\sa\ssimple\stest\scase.\s\s(It\sis\snot\sdifficult\sto\screate\sadditional\stest\ncases\sthat\sassert,\sat\sthis\spoint.) +D 2022-04-09T20:11:05.917 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1146,6 +1146,7 @@ F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test 0d63c7e43b3160b9d4b93f196ef83b6efc7751b9edd0d18c53a46fbec7a49cfc F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c +F test/join7.test b62546e7961a535f5ec2df1f7bd1b4deb60f40dd42444d3d409d53d8890988e2 F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -1945,8 +1946,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 2db5a498e74241dd19ef51c601f1a2b3b687faed3e1be2d1e3ada737406ac8e9 -R 0ae50938e4462db8bba3d38695099c31 +P 34bbeeb77bd530b2b1f0390e9e552f65ae35f09a74d80a09dd327e64f9be51a1 +R d71d5d031d27efcdf2eb198054735b86 U drh -Z 29e379e6c2c78a86783f35cb54daa623 +Z 3028a815e9da0bf5b69ea97a441052fd # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index df20f470e8..e71d4e93df 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -34bbeeb77bd530b2b1f0390e9e552f65ae35f09a74d80a09dd327e64f9be51a1 \ No newline at end of file +f2201d5dcfc552bdddd0780b3f466bdaa886e557f147335c085395bfc001f6b0 \ No newline at end of file diff --git a/test/join7.test b/test/join7.test new file mode 100644 index 0000000000..7edeaaa92a --- /dev/null +++ b/test/join7.test @@ -0,0 +1,28 @@ +# 2022-04-09 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. +# +# This file implements tests for RIGHT and FULL OUTER JOINs. + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +do_execsql_test join7-1.1 { + CREATE TABLE t1(a int,b int); + INSERT INTO t1 VALUES(1,2),(1,3),(1,4); + CREATE INDEX t1a ON t1(a); + CREATE TABLE t2(c int,d int); + INSERT INTO t2 VALUES(3,33),(4,44),(5,55); + CREATE INDEX t2c ON t2(c); + SELECT quote(b), quote(d), '|' FROM t1 FULL OUTER JOIN t2 ON b=c ORDER BY b; +} {NULL 55 | 2 NULL | 3 33 | 4 44 |} + +finish_test From a20c71e9e8300d9c60a83fb3d47b600c556bd952 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 10 Apr 2022 16:13:37 +0000 Subject: [PATCH 098/259] More RIGHT JOIN test cases and a bug fix. FossilOrigin-Name: 19e8ad690a140ca40838bf31a377c19010fcbbc2554a4f1746737543043e334b --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 6 ++++-- test/join7.test | 42 ++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 52 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index ad2ff76bde..9c8c01eb3f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\ssimple\stest\scase.\s\s(It\sis\snot\sdifficult\sto\screate\sadditional\stest\ncases\sthat\sassert,\sat\sthis\spoint.) -D 2022-04-09T20:11:05.917 +C More\sRIGHT\sJOIN\stest\scases\sand\sa\sbug\sfix. +D 2022-04-10T16:13:37.815 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -639,7 +639,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c ddeca7f959c3da448012737c0bf0c283232a317c7ef0bdc6587352f4189bd8aa +F src/where.c ca328251a356781a30c31f924ac935e4e5c8796e2174f50f18fbe3748de27073 F src/whereInt.h ecf0d9fe3e35f2546e660c6389e56aedb6fd2434e31a0449b261ff55ebc6df2d F src/wherecode.c 39532c183ea306ae44b5ab3119b244407b46970b088c59d5751c5724b4b6ec15 F src/whereexpr.c ac8985bbd983f34273b1e0d05cd738ff436331674c1b22f4caf6537e1eca4691 @@ -1146,7 +1146,7 @@ F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test 0d63c7e43b3160b9d4b93f196ef83b6efc7751b9edd0d18c53a46fbec7a49cfc F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c -F test/join7.test b62546e7961a535f5ec2df1f7bd1b4deb60f40dd42444d3d409d53d8890988e2 +F test/join7.test bdd814adf382f3202e8a1f0c0e03afc53d99cc389d80dfa2b25fc846635473f7 F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -1946,8 +1946,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 34bbeeb77bd530b2b1f0390e9e552f65ae35f09a74d80a09dd327e64f9be51a1 -R d71d5d031d27efcdf2eb198054735b86 +P f2201d5dcfc552bdddd0780b3f466bdaa886e557f147335c085395bfc001f6b0 +R af557aa48dcfca848766b5b48b1cbd15 U drh -Z 3028a815e9da0bf5b69ea97a441052fd +Z 2e79fb43e827a0cdd68dfc64d0cf2a68 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e71d4e93df..64168f852f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f2201d5dcfc552bdddd0780b3f466bdaa886e557f147335c085395bfc001f6b0 \ No newline at end of file +19e8ad690a140ca40838bf31a377c19010fcbbc2554a4f1746737543043e334b \ No newline at end of file diff --git a/src/where.c b/src/where.c index bec9da8db0..4216829e25 100644 --- a/src/where.c +++ b/src/where.c @@ -5766,8 +5766,10 @@ WhereInfo *sqlite3WhereBegin( /* noop */ }else #endif - if( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 - && (wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){ + if( ((pLoop->wsFlags & WHERE_IDX_ONLY)==0 + && (wctrlFlags & WHERE_OR_SUBCLAUSE)==0) + || (pTabItem->fg.jointype & (JT_LTORJ|JT_RIGHT))!=0 + ){ int op = OP_OpenRead; if( pWInfo->eOnePass!=ONEPASS_OFF ){ op = OP_OpenWrite; diff --git a/test/join7.test b/test/join7.test index 7edeaaa92a..9478edae65 100644 --- a/test/join7.test +++ b/test/join7.test @@ -22,7 +22,45 @@ do_execsql_test join7-1.1 { CREATE TABLE t2(c int,d int); INSERT INTO t2 VALUES(3,33),(4,44),(5,55); CREATE INDEX t2c ON t2(c); - SELECT quote(b), quote(d), '|' FROM t1 FULL OUTER JOIN t2 ON b=c ORDER BY b; -} {NULL 55 | 2 NULL | 3 33 | 4 44 |} + SELECT quote(b), quote(d) FROM t1 FULL OUTER JOIN t2 ON b=c ORDER BY +b; +} { + NULL 55 + 2 NULL + 3 33 + 4 44 +} +do_execsql_test join7-1.2 { + SELECT quote(a), quote(c) FROM t1 FULL OUTER JOIN t2 ON b=c ORDER BY +b; +} { + NULL 5 + 1 NULL + 1 3 + 1 4 +} +do_execsql_test join7-1.3 { + SELECT quote(a), quote(b), quote(c), quote(d) + FROM t1 FULL OUTER JOIN t2 ON b=c ORDER BY +b; +} { + NULL NULL 5 55 + 1 2 NULL NULL + 1 3 3 33 + 1 4 4 44 +} +do_execsql_test join7-1.4 { + SELECT quote(a), quote(b), quote(c), quote(d) + FROM t1 RIGHT OUTER JOIN t2 ON b=c ORDER BY +b; +} { + NULL NULL 5 55 + 1 3 3 33 + 1 4 4 44 +} +do_execsql_test join7-1.5 { + SELECT quote(a), quote(b), quote(c), quote(d) + FROM t1 LEFT OUTER JOIN t2 ON b=c ORDER BY +b; +} { + 1 2 NULL NULL + 1 3 3 33 + 1 4 4 44 +} finish_test From e21e36dd2cf71d4164bc188774fab5e4d2976cb6 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 10 Apr 2022 17:14:48 +0000 Subject: [PATCH 099/259] More test cases and bug fixes. FossilOrigin-Name: 140e97fde94fdc3babdd456ce1b22900ead0e40e2afe63d89d21ccdbf141b607 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 11 +++++++++-- test/join7.test | 39 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 9c8c01eb3f..37810b9bd5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\sRIGHT\sJOIN\stest\scases\sand\sa\sbug\sfix. -D 2022-04-10T16:13:37.815 +C More\stest\scases\sand\sbug\sfixes. +D 2022-04-10T17:14:48.880 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -639,7 +639,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c ca328251a356781a30c31f924ac935e4e5c8796e2174f50f18fbe3748de27073 +F src/where.c 4e72f26033d0977c4f5a21a06968d319b8c6eae8507f47a6245291cf570151a4 F src/whereInt.h ecf0d9fe3e35f2546e660c6389e56aedb6fd2434e31a0449b261ff55ebc6df2d F src/wherecode.c 39532c183ea306ae44b5ab3119b244407b46970b088c59d5751c5724b4b6ec15 F src/whereexpr.c ac8985bbd983f34273b1e0d05cd738ff436331674c1b22f4caf6537e1eca4691 @@ -1146,7 +1146,7 @@ F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test 0d63c7e43b3160b9d4b93f196ef83b6efc7751b9edd0d18c53a46fbec7a49cfc F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c -F test/join7.test bdd814adf382f3202e8a1f0c0e03afc53d99cc389d80dfa2b25fc846635473f7 +F test/join7.test efcf2ed9d568ab8d2f4145c25fd2a8ea5abc56290c3c5345f9af9aa7e08af693 F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -1946,8 +1946,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 f2201d5dcfc552bdddd0780b3f466bdaa886e557f147335c085395bfc001f6b0 -R af557aa48dcfca848766b5b48b1cbd15 +P 19e8ad690a140ca40838bf31a377c19010fcbbc2554a4f1746737543043e334b +R 9017b4087148be50d8587c5d8e48484b U drh -Z 2e79fb43e827a0cdd68dfc64d0cf2a68 +Z 12573aa0d9ba0f1640cbd083fd7493c6 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 64168f852f..c3bfc576aa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -19e8ad690a140ca40838bf31a377c19010fcbbc2554a4f1746737543043e334b \ No newline at end of file +140e97fde94fdc3babdd456ce1b22900ead0e40e2afe63d89d21ccdbf141b607 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 4216829e25..56c3a01712 100644 --- a/src/where.c +++ b/src/where.c @@ -5894,6 +5894,7 @@ WhereInfo *sqlite3WhereBegin( sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRJ->iMatch, pPk->nKeyCol); sqlite3VdbeSetP4KeyInfo(pParse, pPk); } + pLoop->wsFlags &= ~WHERE_IDX_ONLY; } } pWInfo->iTop = sqlite3VdbeCurrentAddr(v); @@ -6169,10 +6170,15 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ WhereClause *pWC = &pWInfo->sWC; WhereInfo *pSubWInfo; SrcList sFrom; + Bitmask mAll = 0; + for(k=0; k<=i; k++){ + mAll |= pWInfo->a[k].pWLoop->maskSelf; + } for(k=0; knTerm; k++){ - WhereTerm *pTerm = &pWC->a[i]; + WhereTerm *pTerm = &pWC->a[k]; if( pTerm->wtFlags & TERM_VIRTUAL ) break; - if( pTerm->prereqAll & ~pLoop->maskSelf ) continue; + if( pTerm->prereqAll & ~mAll ) continue; + if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) continue; pSubWhere = sqlite3ExprAnd(pParse, pSubWhere, sqlite3ExprDup(db, pTerm->pExpr, 0)); } @@ -6208,6 +6214,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ sqlite3WhereEnd(pSubWInfo); } sqlite3ExprDelete(pParse->db, pSubWhere); + continue; } /* For a co-routine, change all OP_Column references to the table of diff --git a/test/join7.test b/test/join7.test index 9478edae65..019ac322f1 100644 --- a/test/join7.test +++ b/test/join7.test @@ -63,4 +63,43 @@ do_execsql_test join7-1.5 { 1 4 4 44 } +do_execsql_test join7-2.1 { + SELECT quote(a), quote(b), quote(c), quote(d) + FROM t1 FULL OUTER JOIN t2 ON b=c AND a=1 ORDER BY +b; +} { + NULL NULL 5 55 + 1 2 NULL NULL + 1 3 3 33 + 1 4 4 44 +} +do_execsql_test join7-2.2 { + SELECT quote(a), quote(b), quote(c), quote(d) + FROM t1 FULL OUTER JOIN t2 ON b=c WHERE a=1 ORDER BY +b; +} { + 1 2 NULL NULL + 1 3 3 33 + 1 4 4 44 +} +do_execsql_test join7-2.3 { + SELECT quote(a), quote(b), quote(c), quote(d) + FROM t1 FULL OUTER JOIN t2 ON b=c WHERE a IS NULL ORDER BY +d; +} { + NULL NULL 3 33 + NULL NULL 4 44 + NULL NULL 5 55 +} +do_execsql_test join7-2.4 { + SELECT quote(a), quote(b), quote(c), quote(d) + FROM t1 FULL OUTER JOIN t2 ON b=c AND d<=0 ORDER BY +b, +d; +} { + NULL NULL 3 33 + NULL NULL 4 44 + NULL NULL 5 55 + 1 2 NULL NULL + 1 3 NULL NULL + 1 4 NULL NULL +} + + + finish_test From fcde633f7cd4e8c3de41a4f3250f45cd38f49490 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 10 Apr 2022 19:51:22 +0000 Subject: [PATCH 100/259] When the left-most table of a RIGHT JOIN is implemented as a co-routine, make sure all its columns are flushed to NULL when it finishes so that they appear to be NULL during the RIGHT JOIN post-processing. FossilOrigin-Name: f84b2beca719758979d7a5a63c3d16d5121a7518b3fbe5039af474a83dd569c2 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 3 +++ test/join7.test | 45 ++++++++++++++++++++++++++------------------- 4 files changed, 37 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index 37810b9bd5..300a7c0914 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C More\stest\scases\sand\sbug\sfixes. -D 2022-04-10T17:14:48.880 +C When\sthe\sleft-most\stable\sof\sa\sRIGHT\sJOIN\sis\simplemented\sas\sa\sco-routine,\s\nmake\ssure\sall\sits\scolumns\sare\sflushed\sto\sNULL\swhen\sit\sfinishes\sso\sthat\nthey\sappear\sto\sbe\sNULL\sduring\sthe\sRIGHT\sJOIN\spost-processing. +D 2022-04-10T19:51:22.704 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -552,7 +552,7 @@ F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c 7110fc3b5a4dec5d11559141c1906c4a125349fb602f541b05db3a3d448d4b95 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c cfa10564953f08eae09e0e92038b168403aade2879ba772cd5a47a08474da5fe +F src/select.c 3d723c58ce6f8b15ef2a3f7b816010efe11d3cf046f44ba9711b70a93d4144e7 F src/shell.c.in 1a8fbf932ecd582b1a5f66c1e8294f92c30d954616f5c7cc54c9623fcdbb028d F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1146,7 +1146,7 @@ F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test 0d63c7e43b3160b9d4b93f196ef83b6efc7751b9edd0d18c53a46fbec7a49cfc F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c -F test/join7.test efcf2ed9d568ab8d2f4145c25fd2a8ea5abc56290c3c5345f9af9aa7e08af693 +F test/join7.test 5a41d7b6089c05d3a081b73b9f1404f802104c8f6354eaaafdce07dcc03538f2 F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -1946,8 +1946,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 19e8ad690a140ca40838bf31a377c19010fcbbc2554a4f1746737543043e334b -R 9017b4087148be50d8587c5d8e48484b +P 140e97fde94fdc3babdd456ce1b22900ead0e40e2afe63d89d21ccdbf141b607 +R 4785f5aaf180af8e1a0a99264df2d1f5 U drh -Z 12573aa0d9ba0f1640cbd083fd7493c6 +Z 69bb375996d123a078fecd333472e7f3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c3bfc576aa..ac3f707f78 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -140e97fde94fdc3babdd456ce1b22900ead0e40e2afe63d89d21ccdbf141b607 \ No newline at end of file +f84b2beca719758979d7a5a63c3d16d5121a7518b3fbe5039af474a83dd569c2 \ No newline at end of file diff --git a/src/select.c b/src/select.c index b9321aece7..3672a7c0f8 100644 --- a/src/select.c +++ b/src/select.c @@ -6755,6 +6755,9 @@ int sqlite3Select( pItem->pTab->nRowLogEst = pSub->nSelectRow; pItem->fg.viaCoroutine = 1; pItem->regResult = dest.iSdst; + if( pItem->fg.jointype & JT_LTORJ ){ + sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSdst, dest.iSdst+dest.nSdst-1); + } sqlite3VdbeEndCoroutine(v, pItem->regReturn); sqlite3VdbeJumpHere(v, addrTop-1); sqlite3ClearTempRegCache(pParse); diff --git a/test/join7.test b/test/join7.test index 019ac322f1..b92bf3d9c8 100644 --- a/test/join7.test +++ b/test/join7.test @@ -15,6 +15,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +db nullvalue NULL do_execsql_test join7-1.1 { CREATE TABLE t1(a int,b int); INSERT INTO t1 VALUES(1,2),(1,3),(1,4); @@ -22,7 +23,8 @@ do_execsql_test join7-1.1 { CREATE TABLE t2(c int,d int); INSERT INTO t2 VALUES(3,33),(4,44),(5,55); CREATE INDEX t2c ON t2(c); - SELECT quote(b), quote(d) FROM t1 FULL OUTER JOIN t2 ON b=c ORDER BY +b; + CREATE VIEW dual AS SELECT 'x' AS dummy; + SELECT b, d FROM t1 FULL OUTER JOIN t2 ON b=c ORDER BY +b; } { NULL 55 2 NULL @@ -30,7 +32,7 @@ do_execsql_test join7-1.1 { 4 44 } do_execsql_test join7-1.2 { - SELECT quote(a), quote(c) FROM t1 FULL OUTER JOIN t2 ON b=c ORDER BY +b; + SELECT a, c FROM t1 FULL OUTER JOIN t2 ON b=c ORDER BY +b; } { NULL 5 1 NULL @@ -38,25 +40,36 @@ do_execsql_test join7-1.2 { 1 4 } do_execsql_test join7-1.3 { - SELECT quote(a), quote(b), quote(c), quote(d) - FROM t1 FULL OUTER JOIN t2 ON b=c ORDER BY +b; + SELECT * FROM t1 FULL OUTER JOIN t2 ON b=c ORDER BY +b; } { NULL NULL 5 55 1 2 NULL NULL 1 3 3 33 1 4 4 44 } -do_execsql_test join7-1.4 { - SELECT quote(a), quote(b), quote(c), quote(d) - FROM t1 RIGHT OUTER JOIN t2 ON b=c ORDER BY +b; +do_execsql_test join7-1.4a { + SELECT * FROM t1 RIGHT OUTER JOIN t2 ON b=c ORDER BY +b; } { NULL NULL 5 55 1 3 3 33 1 4 4 44 } +do_execsql_test join7-1.4b { + SELECT * FROM dual JOIN t1 ON true RIGHT OUTER JOIN t2 ON b=c ORDER BY +b; +} { + NULL NULL NULL 5 55 + x 1 3 3 33 + x 1 4 4 44 +} +do_execsql_test join7-1.4c { + SELECT * FROM dual CROSS JOIN t1 RIGHT OUTER JOIN t2 ON b=c ORDER BY +b; +} { + NULL NULL NULL 5 55 + x 1 3 3 33 + x 1 4 4 44 +} do_execsql_test join7-1.5 { - SELECT quote(a), quote(b), quote(c), quote(d) - FROM t1 LEFT OUTER JOIN t2 ON b=c ORDER BY +b; + SELECT * FROM t1 LEFT OUTER JOIN t2 ON b=c ORDER BY +b; } { 1 2 NULL NULL 1 3 3 33 @@ -64,8 +77,7 @@ do_execsql_test join7-1.5 { } do_execsql_test join7-2.1 { - SELECT quote(a), quote(b), quote(c), quote(d) - FROM t1 FULL OUTER JOIN t2 ON b=c AND a=1 ORDER BY +b; + SELECT * FROM t1 FULL OUTER JOIN t2 ON b=c AND a=1 ORDER BY +b; } { NULL NULL 5 55 1 2 NULL NULL @@ -73,24 +85,21 @@ do_execsql_test join7-2.1 { 1 4 4 44 } do_execsql_test join7-2.2 { - SELECT quote(a), quote(b), quote(c), quote(d) - FROM t1 FULL OUTER JOIN t2 ON b=c WHERE a=1 ORDER BY +b; + SELECT * FROM t1 FULL OUTER JOIN t2 ON b=c WHERE a=1 ORDER BY +b; } { 1 2 NULL NULL 1 3 3 33 1 4 4 44 } do_execsql_test join7-2.3 { - SELECT quote(a), quote(b), quote(c), quote(d) - FROM t1 FULL OUTER JOIN t2 ON b=c WHERE a IS NULL ORDER BY +d; + SELECT * FROM t1 FULL OUTER JOIN t2 ON b=c WHERE a IS NULL ORDER BY +d; } { NULL NULL 3 33 NULL NULL 4 44 NULL NULL 5 55 } do_execsql_test join7-2.4 { - SELECT quote(a), quote(b), quote(c), quote(d) - FROM t1 FULL OUTER JOIN t2 ON b=c AND d<=0 ORDER BY +b, +d; + SELECT * FROM t1 FULL OUTER JOIN t2 ON b=c AND d<=0 ORDER BY +b, +d; } { NULL NULL 3 33 NULL NULL 4 44 @@ -100,6 +109,4 @@ do_execsql_test join7-2.4 { 1 4 NULL NULL } - - finish_test From 62ed36bb5dd4e8a15042d9752abc4223cae3be14 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 10 Apr 2022 20:28:41 +0000 Subject: [PATCH 101/259] Minor improvements to the sqlite3SrcListShiftJoinType() routine. This started out to be an effort to convert RIGHT JOIN to LEFT JOIN if the join was on the first pair of relations, but that messes up the "*" expansion and so won't work. FossilOrigin-Name: a48902c71ed30c83de7dbd26d1c7956136c35dc53b1076bc8b1ebcba568a3fd3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/build.c | 15 +++++++++++---- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 300a7c0914..c280af91e6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sthe\sleft-most\stable\sof\sa\sRIGHT\sJOIN\sis\simplemented\sas\sa\sco-routine,\s\nmake\ssure\sall\sits\scolumns\sare\sflushed\sto\sNULL\swhen\sit\sfinishes\sso\sthat\nthey\sappear\sto\sbe\sNULL\sduring\sthe\sRIGHT\sJOIN\spost-processing. -D 2022-04-10T19:51:22.704 +C Minor\simprovements\sto\sthe\ssqlite3SrcListShiftJoinType()\sroutine.\s\sThis\sstarted\nout\sto\sbe\san\seffort\sto\sconvert\sRIGHT\sJOIN\sto\sLEFT\sJOIN\sif\sthe\sjoin\swas\son\nthe\sfirst\spair\sof\srelations,\sbut\sthat\smesses\sup\sthe\s"*"\sexpansion\sand\sso\swon't\nwork. +D 2022-04-10T20:28:41.210 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -495,7 +495,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 45161c2d5c9527b9c9bbfd7478daf3e0a619cf4bbe3278378aaea3d4b4e4f5b5 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482e -F src/build.c 4a35acbeb5a73e5dfb0ed199a4ba601179cd22216654f9eb14c1dcfe993673e8 +F src/build.c d30ef1cbd19efbaf8596521589f2a56292325e03f0801bf160608da7b03a03ff F src/callback.c 4c19af69835787bfe790ac560f3071a824eb629f34e41f97b52ce5235c77de1c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 026dbdcdbd8c3cde98a88483ee88310ff43150ab164ad768f12cc700a11495ad @@ -1946,8 +1946,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 140e97fde94fdc3babdd456ce1b22900ead0e40e2afe63d89d21ccdbf141b607 -R 4785f5aaf180af8e1a0a99264df2d1f5 +P f84b2beca719758979d7a5a63c3d16d5121a7518b3fbe5039af474a83dd569c2 +R cd052684f405fbc67ae88c7e7611d8e4 U drh -Z 69bb375996d123a078fecd333472e7f3 +Z ff6cefb3fcd28c733eed400a6a07e7f1 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index ac3f707f78..a904647d09 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f84b2beca719758979d7a5a63c3d16d5121a7518b3fbe5039af474a83dd569c2 \ No newline at end of file +a48902c71ed30c83de7dbd26d1c7956136c35dc53b1076bc8b1ebcba568a3fd3 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 7181011c32..22f7a79e05 100644 --- a/src/build.c +++ b/src/build.c @@ -5067,14 +5067,21 @@ void sqlite3SrcListFuncArgs(Parse *pParse, SrcList *p, ExprList *pList){ ** The operator is "natural cross join". The A and B operands are stored ** in p->a[0] and p->a[1], respectively. The parser initially stores the ** operator with A. This routine shifts that operator over to B. +** +** Additional changes: +** +** * All tables to the left of the right-most RIGHT JOIN are tagged with +** JT_LTORJ (mnemonic: Left Table Of Right Join) so that the +** code generator can easily tell that the table is part of +** the left operand of at least one RIGHT JOIN. */ void sqlite3SrcListShiftJoinType(SrcList *p){ - if( p ){ - int i; + if( p && p->nSrc>1 ){ + int i = p->nSrc-1; u8 allFlags = 0; - for(i=p->nSrc-1; i>0; i--){ + do{ allFlags |= p->a[i].fg.jointype = p->a[i-1].fg.jointype; - } + }while( (--i)>0 ); p->a[0].fg.jointype = 0; /* All terms to the left of a RIGHT JOIN should be tagged with the From 9debb58e4801ad5737ff88fbc117a1fc06695efa Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 10 Apr 2022 23:01:20 +0000 Subject: [PATCH 102/259] Revisit [f84b2beca7197589]: disallow co-routine implementations of tables that are to the left of a RIGHT JOIN, to avoid other complications. FossilOrigin-Name: cf00ebfc4b77f45ec466b0d57d7c22c7f48acab19e4e55b168eb4b53f390d887 --- manifest | 14 +-- manifest.uuid | 2 +- src/select.c | 12 ++- test/join7.test | 235 +++++++++++++++++++++++++++++------------------- 4 files changed, 155 insertions(+), 108 deletions(-) diff --git a/manifest b/manifest index c280af91e6..8ce42c41cd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\simprovements\sto\sthe\ssqlite3SrcListShiftJoinType()\sroutine.\s\sThis\sstarted\nout\sto\sbe\san\seffort\sto\sconvert\sRIGHT\sJOIN\sto\sLEFT\sJOIN\sif\sthe\sjoin\swas\son\nthe\sfirst\spair\sof\srelations,\sbut\sthat\smesses\sup\sthe\s"*"\sexpansion\sand\sso\swon't\nwork. -D 2022-04-10T20:28:41.210 +C Revisit\s[f84b2beca7197589]:\sdisallow\sco-routine\simplementations\sof\stables\nthat\sare\sto\sthe\sleft\sof\sa\sRIGHT\sJOIN,\sto\savoid\sother\scomplications. +D 2022-04-10T23:01:20.947 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -552,7 +552,7 @@ F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c 7110fc3b5a4dec5d11559141c1906c4a125349fb602f541b05db3a3d448d4b95 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 3d723c58ce6f8b15ef2a3f7b816010efe11d3cf046f44ba9711b70a93d4144e7 +F src/select.c 4b67f6d827a695cc78057f501dc84c95ce17863fc2047936859e7839d3191ba8 F src/shell.c.in 1a8fbf932ecd582b1a5f66c1e8294f92c30d954616f5c7cc54c9623fcdbb028d F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1146,7 +1146,7 @@ F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test 0d63c7e43b3160b9d4b93f196ef83b6efc7751b9edd0d18c53a46fbec7a49cfc F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c -F test/join7.test 5a41d7b6089c05d3a081b73b9f1404f802104c8f6354eaaafdce07dcc03538f2 +F test/join7.test b3e62ec45f9d8a17a4d13df7533805554e893d214554b4d998815834f7f674fa F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -1946,8 +1946,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 f84b2beca719758979d7a5a63c3d16d5121a7518b3fbe5039af474a83dd569c2 -R cd052684f405fbc67ae88c7e7611d8e4 +P a48902c71ed30c83de7dbd26d1c7956136c35dc53b1076bc8b1ebcba568a3fd3 +R ca36fcb77f7ad090453c7879b10dd2ed U drh -Z ff6cefb3fcd28c733eed400a6a07e7f1 +Z 2c5ea1399770dbe9a9af46dae89e29ee # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a904647d09..550964364e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a48902c71ed30c83de7dbd26d1c7956136c35dc53b1076bc8b1ebcba568a3fd3 \ No newline at end of file +cf00ebfc4b77f45ec466b0d57d7c22c7f48acab19e4e55b168eb4b53f390d887 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 3672a7c0f8..80b488777b 100644 --- a/src/select.c +++ b/src/select.c @@ -6727,18 +6727,19 @@ int sqlite3Select( /* Generate code to implement the subquery ** - ** The subquery is implemented as a co-routine if: + ** The subquery is implemented as a co-routine all of the following are + ** true: + ** ** (1) the subquery is guaranteed to be the outer loop (so that ** it does not need to be computed more than once), and ** (2) the subquery is not a CTE that should be materialized - ** - ** TODO: Are there other reasons beside (1) and (2) to use a co-routine - ** implementation? + ** (3) the subquery is not part of a left operand for a RIGHT JOIN */ if( i==0 && (pTabList->nSrc==1 || (pTabList->a[1].fg.jointype&(JT_OUTER|JT_CROSS))!=0) /* (1) */ && (pItem->fg.isCte==0 || pItem->u2.pCteUse->eM10d!=M10d_Yes) /* (2) */ + && (pTabList->a[0].fg.jointype & JT_LTORJ)==0 /* (3) */ ){ /* Implement a co-routine that will return a single row of the result ** set on each invocation. @@ -6755,9 +6756,6 @@ int sqlite3Select( pItem->pTab->nRowLogEst = pSub->nSelectRow; pItem->fg.viaCoroutine = 1; pItem->regResult = dest.iSdst; - if( pItem->fg.jointype & JT_LTORJ ){ - sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSdst, dest.iSdst+dest.nSdst-1); - } sqlite3VdbeEndCoroutine(v, pItem->regReturn); sqlite3VdbeJumpHere(v, addrTop-1); sqlite3ClearTempRegCache(pParse); diff --git a/test/join7.test b/test/join7.test index b92bf3d9c8..3b49664649 100644 --- a/test/join7.test +++ b/test/join7.test @@ -15,98 +15,147 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl -db nullvalue NULL -do_execsql_test join7-1.1 { - CREATE TABLE t1(a int,b int); - INSERT INTO t1 VALUES(1,2),(1,3),(1,4); - CREATE INDEX t1a ON t1(a); - CREATE TABLE t2(c int,d int); - INSERT INTO t2 VALUES(3,33),(4,44),(5,55); - CREATE INDEX t2c ON t2(c); - CREATE VIEW dual AS SELECT 'x' AS dummy; - SELECT b, d FROM t1 FULL OUTER JOIN t2 ON b=c ORDER BY +b; +foreach {id schema} { + 1 { + CREATE TABLE t1(a INT, b INT); + INSERT INTO t1 VALUES(1,2),(1,3),(1,4); + CREATE INDEX t1a ON t1(a); + CREATE TABLE t2(c INT, d INT); + INSERT INTO t2 VALUES(3,33),(4,44),(5,55); + CREATE INDEX t2c ON t2(c); + CREATE VIEW dual(dummy) AS VALUES('x'); + } + 2 { + CREATE TABLE t1(a INT, b INT); + INSERT INTO t1 VALUES(1,2),(1,3),(1,4); + CREATE INDEX t1ab ON t1(a,b); + CREATE TABLE t2(c INT, d INT); + INSERT INTO t2 VALUES(3,33),(4,44),(5,55); + CREATE INDEX t2cd ON t2(c,d); + CREATE VIEW dual(dummy) AS VALUES('x'); + } + 3 { + CREATE TABLE t1(a INT, b INT); + INSERT INTO t1 VALUES(1,2),(1,3),(1,4); + CREATE INDEX t1a ON t1(a); + CREATE TABLE t2(c INT, d INT PRIMARY KEY) WITHOUT ROWID; + INSERT INTO t2 VALUES(3,33),(4,44),(5,55); + CREATE INDEX t2c ON t2(c); + CREATE VIEW dual(dummy) AS VALUES('x'); + } + 4 { + CREATE TABLE t1(a INT, b INT); + INSERT INTO t1 VALUES(1,2),(1,3),(1,4); + CREATE TABLE t2(c INTEGER PRIMARY KEY, d INT); + INSERT INTO t2 VALUES(3,33),(4,44),(5,55); + CREATE VIEW dual(dummy) AS VALUES('x'); + } + 5 { + CREATE TABLE t1(a INT, b INT); + INSERT INTO t1 VALUES(1,2),(1,3),(1,4); + CREATE TABLE t2(c INT PRIMARY KEY, d INT) WITHOUT ROWID; + INSERT INTO t2 VALUES(3,33),(4,44),(5,55); + CREATE VIEW dual(dummy) AS VALUES('x'); + } + 6 { + CREATE TABLE t1(a INT, b INT); + INSERT INTO t1 VALUES(1,2),(1,3),(1,4); + CREATE VIEW t2(c,d) AS VALUES(3,33),(4,44),(5,55); + CREATE VIEW dual(dummy) AS VALUES('x'); + } + 7 { + CREATE VIEW t1(a,b) AS VALUES(1,2),(1,3),(1,4); + CREATE TABLE t2(c INTEGER PRIMARY KEY, d INT); + INSERT INTO t2 VALUES(3,33),(4,44),(5,55); + CREATE VIEW dual(dummy) AS VALUES('x'); + } } { - NULL 55 - 2 NULL - 3 33 - 4 44 -} -do_execsql_test join7-1.2 { - SELECT a, c FROM t1 FULL OUTER JOIN t2 ON b=c ORDER BY +b; -} { - NULL 5 - 1 NULL - 1 3 - 1 4 -} -do_execsql_test join7-1.3 { - SELECT * FROM t1 FULL OUTER JOIN t2 ON b=c ORDER BY +b; -} { - NULL NULL 5 55 - 1 2 NULL NULL - 1 3 3 33 - 1 4 4 44 -} -do_execsql_test join7-1.4a { - SELECT * FROM t1 RIGHT OUTER JOIN t2 ON b=c ORDER BY +b; -} { - NULL NULL 5 55 - 1 3 3 33 - 1 4 4 44 -} -do_execsql_test join7-1.4b { - SELECT * FROM dual JOIN t1 ON true RIGHT OUTER JOIN t2 ON b=c ORDER BY +b; -} { - NULL NULL NULL 5 55 - x 1 3 3 33 - x 1 4 4 44 -} -do_execsql_test join7-1.4c { - SELECT * FROM dual CROSS JOIN t1 RIGHT OUTER JOIN t2 ON b=c ORDER BY +b; -} { - NULL NULL NULL 5 55 - x 1 3 3 33 - x 1 4 4 44 -} -do_execsql_test join7-1.5 { - SELECT * FROM t1 LEFT OUTER JOIN t2 ON b=c ORDER BY +b; -} { - 1 2 NULL NULL - 1 3 3 33 - 1 4 4 44 -} - -do_execsql_test join7-2.1 { - SELECT * FROM t1 FULL OUTER JOIN t2 ON b=c AND a=1 ORDER BY +b; -} { - NULL NULL 5 55 - 1 2 NULL NULL - 1 3 3 33 - 1 4 4 44 -} -do_execsql_test join7-2.2 { - SELECT * FROM t1 FULL OUTER JOIN t2 ON b=c WHERE a=1 ORDER BY +b; -} { - 1 2 NULL NULL - 1 3 3 33 - 1 4 4 44 -} -do_execsql_test join7-2.3 { - SELECT * FROM t1 FULL OUTER JOIN t2 ON b=c WHERE a IS NULL ORDER BY +d; -} { - NULL NULL 3 33 - NULL NULL 4 44 - NULL NULL 5 55 -} -do_execsql_test join7-2.4 { - SELECT * FROM t1 FULL OUTER JOIN t2 ON b=c AND d<=0 ORDER BY +b, +d; -} { - NULL NULL 3 33 - NULL NULL 4 44 - NULL NULL 5 55 - 1 2 NULL NULL - 1 3 NULL NULL - 1 4 NULL NULL -} - + reset_db + db nullvalue NULL + db eval $schema + do_execsql_test join7-$id.1 { + SELECT b, d FROM t1 FULL OUTER JOIN t2 ON b=c ORDER BY +b; + } { + NULL 55 + 2 NULL + 3 33 + 4 44 + } + do_execsql_test join7-$id.2 { + SELECT a, c FROM t1 FULL OUTER JOIN t2 ON b=c ORDER BY +b; + } { + NULL 5 + 1 NULL + 1 3 + 1 4 + } + do_execsql_test join7-$id.3 { + SELECT * FROM t1 FULL OUTER JOIN t2 ON b=c ORDER BY +b; + } { + NULL NULL 5 55 + 1 2 NULL NULL + 1 3 3 33 + 1 4 4 44 + } + do_execsql_test join7-$id.4 { + SELECT * FROM t1 RIGHT OUTER JOIN t2 ON b=c ORDER BY +b; + } { + NULL NULL 5 55 + 1 3 3 33 + 1 4 4 44 + } + do_execsql_test join7-$id.5 { + SELECT * FROM dual JOIN t1 ON true RIGHT OUTER JOIN t2 ON b=c ORDER BY +b; + } { + NULL NULL NULL 5 55 + x 1 3 3 33 + x 1 4 4 44 + } + do_execsql_test join7-$id.6 { + SELECT * FROM dual CROSS JOIN t1 RIGHT OUTER JOIN t2 ON b=c ORDER BY +b; + } { + NULL NULL NULL 5 55 + x 1 3 3 33 + x 1 4 4 44 + } + do_execsql_test join7-$id.7 { + SELECT * FROM t1 LEFT OUTER JOIN t2 ON b=c ORDER BY +b; + } { + 1 2 NULL NULL + 1 3 3 33 + 1 4 4 44 + } + do_execsql_test join7-$id.8 { + SELECT * FROM t1 FULL OUTER JOIN t2 ON b=c AND a=1 ORDER BY +b; + } { + NULL NULL 5 55 + 1 2 NULL NULL + 1 3 3 33 + 1 4 4 44 + } + do_execsql_test join7-$id.9 { + SELECT * FROM t1 FULL OUTER JOIN t2 ON b=c WHERE a=1 ORDER BY +b; + } { + 1 2 NULL NULL + 1 3 3 33 + 1 4 4 44 + } + do_execsql_test join7-$id.10 { + SELECT * FROM t1 FULL OUTER JOIN t2 ON b=c WHERE a IS NULL ORDER BY +d; + } { + NULL NULL 3 33 + NULL NULL 4 44 + NULL NULL 5 55 + } + do_execsql_test join7-$id.11 { + SELECT * FROM t1 FULL OUTER JOIN t2 ON b=c AND d<=0 ORDER BY +b, +d; + } { + NULL NULL 3 33 + NULL NULL 4 44 + NULL NULL 5 55 + 1 2 NULL NULL + 1 3 NULL NULL + 1 4 NULL NULL + } +} finish_test From 529394e5c1399577be9a882b2f8be11fa1966cf5 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 10 Apr 2022 23:48:47 +0000 Subject: [PATCH 103/259] Cannot use an automatic index on the right table of a RIGHT JOIN because automatic indexes must be WHERE_IDX_ONLY, but the RIGHT JOIN post-processing does not know how to work with an index-only scan. FossilOrigin-Name: beb4401dc09fb68e85ddcf3f99598527691535d0eb7693168f440e5a5a076e3f --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 1 + test/join7.test | 9 ++++++++- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 8ce42c41cd..df80bde0ca 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Revisit\s[f84b2beca7197589]:\sdisallow\sco-routine\simplementations\sof\stables\nthat\sare\sto\sthe\sleft\sof\sa\sRIGHT\sJOIN,\sto\savoid\sother\scomplications. -D 2022-04-10T23:01:20.947 +C Cannot\suse\san\sautomatic\sindex\son\sthe\sright\stable\sof\sa\sRIGHT\sJOIN\sbecause\nautomatic\sindexes\smust\sbe\sWHERE_IDX_ONLY,\sbut\sthe\sRIGHT\sJOIN\spost-processing\ndoes\snot\sknow\show\sto\swork\swith\san\sindex-only\sscan. +D 2022-04-10T23:48:47.410 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -639,7 +639,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c 4e72f26033d0977c4f5a21a06968d319b8c6eae8507f47a6245291cf570151a4 +F src/where.c cfc0926a221884af46cf933c9462e85e391022cb6aa06a65523e7464294b75d0 F src/whereInt.h ecf0d9fe3e35f2546e660c6389e56aedb6fd2434e31a0449b261ff55ebc6df2d F src/wherecode.c 39532c183ea306ae44b5ab3119b244407b46970b088c59d5751c5724b4b6ec15 F src/whereexpr.c ac8985bbd983f34273b1e0d05cd738ff436331674c1b22f4caf6537e1eca4691 @@ -1146,7 +1146,7 @@ F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test 0d63c7e43b3160b9d4b93f196ef83b6efc7751b9edd0d18c53a46fbec7a49cfc F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c -F test/join7.test b3e62ec45f9d8a17a4d13df7533805554e893d214554b4d998815834f7f674fa +F test/join7.test 790f5fcb7de07fd7e231610ea0e3da7064cba09c1c1e0c3d879adf0c422680e7 F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -1946,8 +1946,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 a48902c71ed30c83de7dbd26d1c7956136c35dc53b1076bc8b1ebcba568a3fd3 -R ca36fcb77f7ad090453c7879b10dd2ed +P cf00ebfc4b77f45ec466b0d57d7c22c7f48acab19e4e55b168eb4b53f390d887 +R ace46715d37ee9d472092f5415672d4e U drh -Z 2c5ea1399770dbe9a9af46dae89e29ee +Z 7d6e1f7d66be1a3fd82f66b8d4846d22 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 550964364e..f40c2481c6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cf00ebfc4b77f45ec466b0d57d7c22c7f48acab19e4e55b168eb4b53f390d887 \ No newline at end of file +beb4401dc09fb68e85ddcf3f99598527691535d0eb7693168f440e5a5a076e3f \ No newline at end of file diff --git a/src/where.c b/src/where.c index 56c3a01712..adae72a4fe 100644 --- a/src/where.c +++ b/src/where.c @@ -3324,6 +3324,7 @@ static int whereLoopAddBtree( && HasRowid(pTab) /* Not WITHOUT ROWID table. (FIXME: Why not?) */ && !pSrc->fg.isCorrelated /* Not a correlated subquery */ && !pSrc->fg.isRecursive /* Not a recursive common table expression. */ + && (pSrc->fg.jointype & JT_RIGHT)==0 /* Not the right tab of a RIGHT JOIN */ ){ /* Generate auto-index WhereLoops */ LogEst rLogSize; /* Logarithm of the number of rows in the table */ diff --git a/test/join7.test b/test/join7.test index 3b49664649..e2e45dc94b 100644 --- a/test/join7.test +++ b/test/join7.test @@ -69,10 +69,17 @@ foreach {id schema} { INSERT INTO t2 VALUES(3,33),(4,44),(5,55); CREATE VIEW dual(dummy) AS VALUES('x'); } + 8 { + CREATE TABLE t1(a INT, b INT); + INSERT INTO t1 VALUES(1,2),(1,3),(1,4); + CREATE TABLE t2(c INT, d INT); + INSERT INTO t2 VALUES(3,33),(4,44),(5,55); + CREATE VIEW dual(dummy) AS VALUES('x'); + } } { reset_db db nullvalue NULL - db eval $schema + do_execsql_test join7-$id.setup $schema {} do_execsql_test join7-$id.1 { SELECT b, d FROM t1 FULL OUTER JOIN t2 ON b=c ORDER BY +b; } { From 41798d5bbc742999a8e8808eff7c2e29c9d4f32f Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 11 Apr 2022 00:21:53 +0000 Subject: [PATCH 104/259] Do not allow query flattening nor the push-down optimization on the right operand of a RIGHT JOIN. FossilOrigin-Name: 5aa0c9ea9cf53c13bf266278b479b2e7af3aa5c6b144bd49ff155a4eb3c23c96 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 16 +++++++++++----- test/join7.test | 11 +++++++++++ 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index df80bde0ca..bb5ed20c48 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Cannot\suse\san\sautomatic\sindex\son\sthe\sright\stable\sof\sa\sRIGHT\sJOIN\sbecause\nautomatic\sindexes\smust\sbe\sWHERE_IDX_ONLY,\sbut\sthe\sRIGHT\sJOIN\spost-processing\ndoes\snot\sknow\show\sto\swork\swith\san\sindex-only\sscan. -D 2022-04-10T23:48:47.410 +C Do\snot\sallow\squery\sflattening\snor\sthe\spush-down\soptimization\son\sthe\nright\soperand\sof\sa\sRIGHT\sJOIN. +D 2022-04-11T00:21:53.844 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -552,7 +552,7 @@ F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c 7110fc3b5a4dec5d11559141c1906c4a125349fb602f541b05db3a3d448d4b95 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 4b67f6d827a695cc78057f501dc84c95ce17863fc2047936859e7839d3191ba8 +F src/select.c 451df0c74466d56d9d69be0d06047b1a0be7d1fa0397ac7d9211f05eb5f06318 F src/shell.c.in 1a8fbf932ecd582b1a5f66c1e8294f92c30d954616f5c7cc54c9623fcdbb028d F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1146,7 +1146,7 @@ F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test 0d63c7e43b3160b9d4b93f196ef83b6efc7751b9edd0d18c53a46fbec7a49cfc F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c -F test/join7.test 790f5fcb7de07fd7e231610ea0e3da7064cba09c1c1e0c3d879adf0c422680e7 +F test/join7.test 059f7ab42737fbd835dfc791354f1b182585566b540b013f3ed46bfa1e80ba42 F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -1946,8 +1946,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 cf00ebfc4b77f45ec466b0d57d7c22c7f48acab19e4e55b168eb4b53f390d887 -R ace46715d37ee9d472092f5415672d4e +P beb4401dc09fb68e85ddcf3f99598527691535d0eb7693168f440e5a5a076e3f +R b2c7edceb2230e0242166af62b7682c3 U drh -Z 7d6e1f7d66be1a3fd82f66b8d4846d22 +Z a361fbcfdefe8d9e9f1c63be816d7720 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f40c2481c6..b9ca607662 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -beb4401dc09fb68e85ddcf3f99598527691535d0eb7693168f440e5a5a076e3f \ No newline at end of file +5aa0c9ea9cf53c13bf266278b479b2e7af3aa5c6b144bd49ff155a4eb3c23c96 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 80b488777b..2d09085f8a 100644 --- a/src/select.c +++ b/src/select.c @@ -3975,6 +3975,7 @@ static void renumberCursors( ** table and ** (3c) the outer query may not be an aggregate. ** (3d) the outer query may not be DISTINCT. +** See also (26) for restrictions on RIGHT JOIN. ** ** (4) The subquery can not be DISTINCT. ** @@ -4073,6 +4074,9 @@ static void renumberCursors( ** function in the select list or ORDER BY clause, flattening ** is not attempted. ** +** (26) The subquery may not be the right operand of a RIGHT JOIN. +** See also (3) for restrictions on LEFT JOIN. +** ** ** In this routine, the "p" parameter is a pointer to the outer query. ** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query @@ -4172,14 +4176,15 @@ static int flattenSubquery( ** See also tickets #306, #350, and #3300. */ if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){ - isLeftJoin = 1; - if( pSubSrc->nSrc>1 /* (3a) */ - || isAgg /* (3b) */ - || IsVirtual(pSubSrc->a[0].pTab) /* (3c) */ - || (p->selFlags & SF_Distinct)!=0 /* (3d) */ + if( pSubSrc->nSrc>1 /* (3a) */ + || isAgg /* (3b) */ + || IsVirtual(pSubSrc->a[0].pTab) /* (3c) */ + || (p->selFlags & SF_Distinct)!=0 /* (3d) */ + || (pSubitem->fg.jointype & JT_RIGHT)!=0 /* (26) */ ){ return 0; } + isLeftJoin = 1; } #ifdef SQLITE_EXTRA_IFNULLROW else if( iFrom>0 && !isAgg ){ @@ -6707,6 +6712,7 @@ int sqlite3Select( if( OptimizationEnabled(db, SQLITE_PushDown) && (pItem->fg.isCte==0 || (pItem->u2.pCteUse->eM10d!=M10d_Yes && pItem->u2.pCteUse->nUse<2)) + && (pItem->fg.jointype & JT_RIGHT)==0 && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor, (pItem->fg.jointype & JT_OUTER)!=0) ){ diff --git a/test/join7.test b/test/join7.test index e2e45dc94b..c1cd9ff6cb 100644 --- a/test/join7.test +++ b/test/join7.test @@ -76,6 +76,17 @@ foreach {id schema} { INSERT INTO t2 VALUES(3,33),(4,44),(5,55); CREATE VIEW dual(dummy) AS VALUES('x'); } + 9 { + CREATE TABLE t1(a INT, b INT); + INSERT INTO t1 VALUES(1,2),(1,3),(1,4); + CREATE TABLE t2a(c INTEGER PRIMARY KEY, i1 INT); + CREATE TABLE t2b(i1 INTEGER PRIMARY KEY, d INT); + CREATE VIEW t2(c,d) AS SELECT c, d FROM t2a NATURAL JOIN t2b; + INSERT INTO t2a VALUES(3,93),(4,94),(5,95),(6,96),(7,97); + INSERT INTO t2b VALUES(91,11),(92,22),(93,33),(94,44),(95,55); + CREATE TABLE dual(dummy TEXT); + INSERT INTO dual(dummy) VALUES('x'); + } } { reset_db db nullvalue NULL From 8a28ce7bc217871f58e0ce71aa207bbcaf1b338e Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 11 Apr 2022 00:54:30 +0000 Subject: [PATCH 105/259] Show the JT_LTORJ flag in TreeView debugging output. FossilOrigin-Name: 21eb44919f38abad30b75181ca8aec38b453b94dba2815caf7e946e07faa40d7 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/treeview.c | 3 +++ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index bb5ed20c48..6152eb5dd2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sallow\squery\sflattening\snor\sthe\spush-down\soptimization\son\sthe\nright\soperand\sof\sa\sRIGHT\sJOIN. -D 2022-04-11T00:21:53.844 +C Show\sthe\sJT_LTORJ\sflag\sin\sTreeView\sdebugging\soutput. +D 2022-04-11T00:54:30.476 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -617,7 +617,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98 -F src/treeview.c d1401c129c980ace571f5071b91c349b8ad00bdb3d6f7112fb97a3da8bac85ff +F src/treeview.c 7e50db6ae3bf4d2cb2451b72885667160b6670b0d17bc8d59525b0de6aabf036 F src/trigger.c 372ada38f667c6823a3db15749eb668338e65c793394e55a37e56a489f2d1b55 F src/update.c 2cfaded82ca80ff56afb8c3ae5e88284e0824bfd86119827cc22481959f96f92 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 @@ -1946,8 +1946,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 beb4401dc09fb68e85ddcf3f99598527691535d0eb7693168f440e5a5a076e3f -R b2c7edceb2230e0242166af62b7682c3 +P 5aa0c9ea9cf53c13bf266278b479b2e7af3aa5c6b144bd49ff155a4eb3c23c96 +R 1822de81f6d5e04eb79ec5cea58d30a4 U drh -Z a361fbcfdefe8d9e9f1c63be816d7720 +Z 5ed5c4da0a2f8bbe8f27f2f95fe823d4 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b9ca607662..cbc7f3de0c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5aa0c9ea9cf53c13bf266278b479b2e7af3aa5c6b144bd49ff155a4eb3c23c96 \ No newline at end of file +21eb44919f38abad30b75181ca8aec38b453b94dba2815caf7e946e07faa40d7 \ No newline at end of file diff --git a/src/treeview.c b/src/treeview.c index f32064cd8e..d2ccb545b2 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -153,6 +153,9 @@ void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ }else if( pItem->fg.jointype & JT_CROSS ){ sqlite3_str_appendf(&x, " CROSS-JOIN"); } + if( pItem->fg.jointype & JT_LTORJ ){ + sqlite3_str_appendf(&x, " LTORJ"); + } if( pItem->fg.fromDDL ){ sqlite3_str_appendf(&x, " DDL"); } From 79d26586710bc91822bcaf4c2838e153e62aa6c8 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 11 Apr 2022 10:38:28 +0000 Subject: [PATCH 106/259] Ensure that the JT_LTORJ flag is preserved when flattening a subquery that is on the left side of a RIGHT JOIN. FossilOrigin-Name: ccb61fb1f30e2741b19c1a0cbd2951715224852c86234a3c6a4bbd2e1187634a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 4 +++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 6152eb5dd2..b853591122 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Show\sthe\sJT_LTORJ\sflag\sin\sTreeView\sdebugging\soutput. -D 2022-04-11T00:54:30.476 +C Ensure\sthat\sthe\sJT_LTORJ\sflag\sis\spreserved\swhen\sflattening\sa\ssubquery\sthat\nis\son\sthe\sleft\sside\sof\sa\sRIGHT\sJOIN. +D 2022-04-11T10:38:28.801 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -552,7 +552,7 @@ F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c 7110fc3b5a4dec5d11559141c1906c4a125349fb602f541b05db3a3d448d4b95 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 451df0c74466d56d9d69be0d06047b1a0be7d1fa0397ac7d9211f05eb5f06318 +F src/select.c e889b6a0fee9341820adc9a421f6cabb69171360f7750c0ba175e0a6ac0fd537 F src/shell.c.in 1a8fbf932ecd582b1a5f66c1e8294f92c30d954616f5c7cc54c9623fcdbb028d F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1946,8 +1946,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 5aa0c9ea9cf53c13bf266278b479b2e7af3aa5c6b144bd49ff155a4eb3c23c96 -R 1822de81f6d5e04eb79ec5cea58d30a4 +P 21eb44919f38abad30b75181ca8aec38b453b94dba2815caf7e946e07faa40d7 +R 582e9a3c8a9436aaf5a30603f3b09f3b U drh -Z 5ed5c4da0a2f8bbe8f27f2f95fe823d4 +Z 8d7ebe62739250aad2468a2b76ceb82f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index cbc7f3de0c..654a625162 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -21eb44919f38abad30b75181ca8aec38b453b94dba2815caf7e946e07faa40d7 \ No newline at end of file +ccb61fb1f30e2741b19c1a0cbd2951715224852c86234a3c6a4bbd2e1187634a \ No newline at end of file diff --git a/src/select.c b/src/select.c index 2d09085f8a..08824150e8 100644 --- a/src/select.c +++ b/src/select.c @@ -4373,6 +4373,7 @@ static int flattenSubquery( for(pParent=p; pParent; pParent=pParent->pPrior, pSub=pSub->pPrior){ int nSubSrc; u8 jointype = 0; + u8 ltorj = pSrc->a[iFrom].fg.jointype & JT_LTORJ; assert( pSub!=0 ); pSubSrc = pSub->pSrc; /* FROM clause of subquery */ nSubSrc = pSubSrc->nSrc; /* Number of terms in subquery FROM clause */ @@ -4411,10 +4412,11 @@ static int flattenSubquery( if( pItem->fg.isUsing ) sqlite3IdListDelete(db, pItem->u3.pUsing); assert( pItem->fg.isTabFunc==0 ); *pItem = pSubSrc->a[i]; + pItem->fg.jointype |= ltorj; iNewParent = pSubSrc->a[i].iCursor; memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i])); } - pSrc->a[iFrom].fg.jointype = jointype; + pSrc->a[iFrom].fg.jointype = jointype | ltorj; /* Now begin substituting subquery result set expressions for ** references to the iParent in the outer query. From d198526289eb59cd19529c6c70ce0d8d40bf167a Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 11 Apr 2022 11:25:28 +0000 Subject: [PATCH 107/259] Rename the Expr.w.iRightJoinTable to just Expr.w.iJoin, so that the words "RightJoin" in the former name do not lead readers to believe that this has something to do with RIGHT JOINs in particular. FossilOrigin-Name: e8c00442d2daedec079748d13147bf73b0ec3c3cf432bce2cdccb706bdff2853 --- manifest | 24 ++++++++++++------------ manifest.uuid | 2 +- src/select.c | 26 +++++++++++++------------- src/sqliteInt.h | 2 +- src/treeview.c | 2 +- src/where.c | 4 ++-- src/wherecode.c | 2 +- src/whereexpr.c | 6 +++--- 8 files changed, 34 insertions(+), 34 deletions(-) diff --git a/manifest b/manifest index e767080f57..6ca6515ff8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\s.import\sbug\sreported\sat\shttps://sqlite.org/forum/forumpost/14db09d7e765b819\s.\szAutoColumn\smade\sto\sdeliver\scharacters,\snot\sbytes. -D 2022-04-09T18:51:49.784 +C Rename\sthe\sExpr.w.iRightJoinTable\sto\sjust\sExpr.w.iJoin,\sso\sthat\sthe\swords\n"RightJoin"\sin\sthe\sformer\sname\sdo\snot\slead\sreaders\sto\sbelieve\sthat\sthis\shas\nsomething\sto\sdo\swith\sRIGHT\sJOINs\sin\sparticular. +D 2022-04-11T11:25:28.307 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -552,12 +552,12 @@ F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c 18d99e7146852d6064559561769fcca0743eb32b14a97da6dbed373a30ee0e76 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 7c106b3f36d483242b0a9c696614cd53d6f29e1ac81da6a3f0e9ea92f4211cc3 +F src/select.c 5ac7c08646ac5a03634da8a954645bdaa13d9bf692fb6b0b5fb3b55b19ab884e F src/shell.c.in eb7f10d5e2c47bd014d92ec5db1def21fcc1ed56ffaaa4ee715b6c37c370b47f F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h 364699d46b6cd2fbcaedfb907cedd42c8ed6e32a671f7f72edb257cad861c40b +F src/sqliteInt.h 5260c849fd1ac36d763f8efe9438437eb0bbde9a7956287e5e795cc514b30bc3 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -617,7 +617,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98 -F src/treeview.c 80a3d70bbc112399aa3cc7e777acc5d07c452e44c652630fc158d4594d86afd1 +F src/treeview.c 67fc7d8960e525026eb7f8f4afae0d3652cc3f1260f5adeab062079e25bf0879 F src/trigger.c 372ada38f667c6823a3db15749eb668338e65c793394e55a37e56a489f2d1b55 F src/update.c 2cfaded82ca80ff56afb8c3ae5e88284e0824bfd86119827cc22481959f96f92 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 @@ -639,10 +639,10 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c 929ac88a1b65bcdef7e05a0b87b13a0c55cd3d5d3bc27ec81a6f37eaca13e5fe +F src/where.c 3b23b363455f1d12cf36c7baa679b16bf1e48cfdd6cf0166bd52202823212f14 F src/whereInt.h 41ce0a8c0368372d8422e420e05a1e037624ce52fae139c3c19538ee491fb4c0 -F src/wherecode.c b7bc24b150d6a47c48844f89c3bf6d8f694780acb71768c83b9bec8a729e0d81 -F src/whereexpr.c 2ce4ff64b80fce0a0f7579f5ec2b953f10952a3410c441564e12b650ea8c2aba +F src/wherecode.c b48476855e4802276e9d9aabb407609059220774b586c8c3a5a61e430aa0eb27 +F src/whereexpr.c 346ca19fa89bcb966feb9ae42324fe7636130757f34890aaa6ef922b96be17a5 F src/window.c 42a71595263dbd8ef8248218e4fc7d4b5ddccece52146ad48e079342d93f6f8f F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 @@ -1945,8 +1945,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 f237e1d8cc41b937f34288daebfacf5f7b0990a807a805e0cb6b45bc730192d6 -R 32d747db1a8abc3115c9e0c3c720312e -U larrybr -Z 31d16ad9966991b7487e6e03ff8edde4 +P 21e96600d90c1cda84777abe22a11058eba46c9faefeb05f8c31bc0e7fa84b19 +R a4105d42712d7aa2e6c32a68a1a189b9 +U drh +Z 0c17b37ca377860b400b2aceb3280c9a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b96920f440..1302d31a5e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -21e96600d90c1cda84777abe22a11058eba46c9faefeb05f8c31bc0e7fa84b19 \ No newline at end of file +e8c00442d2daedec079748d13147bf73b0ec3c3cf432bce2cdccb706bdff2853 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 7ac23bd388..28934ffd94 100644 --- a/src/select.c +++ b/src/select.c @@ -401,14 +401,14 @@ static void addWhereTerm( ExprSetProperty(pEq, EP_FromJoin); assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) ); ExprSetVVAProperty(pEq, EP_NoReduce); - pEq->w.iRightJoinTable = pE2->iTable; + pEq->w.iJoin = pE2->iTable; } *ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq); } /* ** Set the EP_FromJoin property on all terms of the given expression. -** And set the Expr.w.iRightJoinTable to iTable for every term in the +** And set the Expr.w.iJoin to iTable for every term in the ** expression. ** ** The EP_FromJoin property is used on terms of an expression to tell @@ -418,8 +418,8 @@ static void addWhereTerm( ** WHERE clause during join processing but we need to remember that they ** originated in the ON or USING clause. ** -** The Expr.w.iRightJoinTable tells the WHERE clause processing that the -** expression depends on table w.iRightJoinTable even if that table is not +** The Expr.w.iJoin tells the WHERE clause processing that the +** expression depends on table w.iJoin even if that table is not ** explicitly mentioned in the expression. That information is needed ** for cases like this: ** @@ -437,7 +437,7 @@ void sqlite3SetJoinExpr(Expr *p, int iTable){ ExprSetProperty(p, EP_FromJoin); assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); ExprSetVVAProperty(p, EP_NoReduce); - p->w.iRightJoinTable = iTable; + p->w.iJoin = iTable; if( p->op==TK_FUNCTION ){ assert( ExprUseXList(p) ); if( p->x.pList ){ @@ -453,7 +453,7 @@ void sqlite3SetJoinExpr(Expr *p, int iTable){ } /* Undo the work of sqlite3SetJoinExpr(). In the expression p, convert every -** term that is marked with EP_FromJoin and w.iRightJoinTable==iTable into +** term that is marked with EP_FromJoin and w.iJoin==iTable into ** an ordinary term that omits the EP_FromJoin mark. ** ** This happens when a LEFT JOIN is simplified into an ordinary JOIN. @@ -461,7 +461,7 @@ void sqlite3SetJoinExpr(Expr *p, int iTable){ static void unsetJoinExpr(Expr *p, int iTable){ while( p ){ if( ExprHasProperty(p, EP_FromJoin) - && (iTable<0 || p->w.iRightJoinTable==iTable) ){ + && (iTable<0 || p->w.iJoin==iTable) ){ ExprClearProperty(p, EP_FromJoin); } if( p->op==TK_COLUMN && p->iTable==iTable ){ @@ -3688,9 +3688,9 @@ static Expr *substExpr( ){ if( pExpr==0 ) return 0; if( ExprHasProperty(pExpr, EP_FromJoin) - && pExpr->w.iRightJoinTable==pSubst->iTable + && pExpr->w.iJoin==pSubst->iTable ){ - pExpr->w.iRightJoinTable = pSubst->iNewTable; + pExpr->w.iJoin = pSubst->iNewTable; } if( pExpr->op==TK_COLUMN && pExpr->iTable==pSubst->iTable @@ -3729,7 +3729,7 @@ static Expr *substExpr( ExprSetProperty(pNew, EP_CanBeNull); } if( ExprHasProperty(pExpr,EP_FromJoin) ){ - sqlite3SetJoinExpr(pNew, pExpr->w.iRightJoinTable); + sqlite3SetJoinExpr(pNew, pExpr->w.iJoin); } sqlite3ExprDelete(db, pExpr); pExpr = pNew; @@ -3894,7 +3894,7 @@ static int renumberCursorsCb(Walker *pWalker, Expr *pExpr){ renumberCursorDoMapping(pWalker, &pExpr->iTable); } if( ExprHasProperty(pExpr, EP_FromJoin) ){ - renumberCursorDoMapping(pWalker, &pExpr->w.iRightJoinTable); + renumberCursorDoMapping(pWalker, &pExpr->w.iJoin); } return WRC_Continue; } @@ -4905,12 +4905,12 @@ static int pushDownWhereTerms( } if( isLeftJoin && (ExprHasProperty(pWhere,EP_FromJoin)==0 - || pWhere->w.iRightJoinTable!=iCursor) + || pWhere->w.iJoin!=iCursor) ){ return 0; /* restriction (4) */ } if( ExprHasProperty(pWhere,EP_FromJoin) - && pWhere->w.iRightJoinTable!=iCursor + && pWhere->w.iJoin!=iCursor ){ return 0; /* restriction (5) */ } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index ead20c9a2f..42554d2636 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2844,7 +2844,7 @@ struct Expr { ** TK_SELECT_COLUMN: column of the result vector */ i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */ union { - int iRightJoinTable; /* If EP_FromJoin, the right table of the join */ + int iJoin; /* If EP_FromJoin, the right table of the join */ int iOfst; /* else: start of token from start of statement */ } w; AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */ diff --git a/src/treeview.c b/src/treeview.c index 91aff8ddf1..c3ecdefefc 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -416,7 +416,7 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ sqlite3_str_appendf(&x, " fg.af=%x.%c", pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n'); if( ExprHasProperty(pExpr, EP_FromJoin) ){ - sqlite3_str_appendf(&x, " iRJT=%d", pExpr->w.iRightJoinTable); + sqlite3_str_appendf(&x, " iJoin=%d", pExpr->w.iJoin); } if( ExprHasProperty(pExpr, EP_FromDDL) ){ sqlite3_str_appendf(&x, " DDL"); diff --git a/src/where.c b/src/where.c index 4820a5c031..2e97509e0c 100644 --- a/src/where.c +++ b/src/where.c @@ -3203,7 +3203,7 @@ static int whereUsablePartialIndex( for(i=0, pTerm=pWC->a; inTerm; i++, pTerm++){ Expr *pExpr; pExpr = pTerm->pExpr; - if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->w.iRightJoinTable==iTab) + if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->w.iJoin==iTab) && (isLeft==0 || ExprHasProperty(pExpr, EP_FromJoin)) && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab) && (pTerm->wtFlags & TERM_VNULL)==0 @@ -5209,7 +5209,7 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin( for(pTerm=pWInfo->sWC.a; pTermprereqAll & pLoop->maskSelf)!=0 ){ if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin) - || pTerm->pExpr->w.iRightJoinTable!=pItem->iCursor + || pTerm->pExpr->w.iJoin!=pItem->iCursor ){ break; } diff --git a/src/wherecode.c b/src/wherecode.c index 561b34fc85..158fb806c7 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1064,7 +1064,7 @@ static void codeCursorHint( if( pTabItem->fg.jointype & JT_LEFT ){ Expr *pExpr = pTerm->pExpr; if( !ExprHasProperty(pExpr, EP_FromJoin) - || pExpr->w.iRightJoinTable!=pTabItem->iCursor + || pExpr->w.iJoin!=pTabItem->iCursor ){ sWalker.eCode = 0; sWalker.xExprCallback = codeCursorHintIsOrFunction; diff --git a/src/whereexpr.c b/src/whereexpr.c index a3316db65b..adcb90d0b4 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -463,7 +463,7 @@ static int isAuxiliaryVtabOperator( static void transferJoinMarkings(Expr *pDerived, Expr *pBase){ if( pDerived ){ pDerived->flags |= pBase->flags & EP_FromJoin; - pDerived->w.iRightJoinTable = pBase->w.iRightJoinTable; + pDerived->w.iJoin = pBase->w.iJoin; } } @@ -1110,7 +1110,7 @@ static void exprAnalyze( #endif if( ExprHasProperty(pExpr, EP_FromJoin) ){ - Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->w.iRightJoinTable); + Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->w.iJoin); prereqAll |= x; extraRight = x-1; /* ON clause terms may not be used with an index ** on left table of a LEFT JOIN. Ticket #3015 */ @@ -1461,7 +1461,7 @@ static void exprAnalyze( 0, sqlite3ExprDup(db, pRight, 0)); if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){ ExprSetProperty(pNewExpr, EP_FromJoin); - pNewExpr->w.iRightJoinTable = pExpr->w.iRightJoinTable; + pNewExpr->w.iJoin = pExpr->w.iJoin; } idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); testcase( idxNew==0 ); From b77c07a715dacfb4ffa968c6ac26ac46bf18776c Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 11 Apr 2022 11:59:25 +0000 Subject: [PATCH 108/259] Fix some comments that refer to LEFT JOIN that should refer to OUTER JOIN. No changes to code. FossilOrigin-Name: 5be5ede5cca1cd5ef863fe0feb2b4a990f4a42865281a6c2e4eb816f48847dc6 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 4 ++-- src/select.c | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 7663e4d4cb..1ac8ab2ca0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\sExpr.w.iJoin\sname\schange\sfrom\strunk\sinto\sthe\sright-join\sbranch. -D 2022-04-11T11:48:17.550 +C Fix\ssome\scomments\sthat\srefer\sto\sLEFT\sJOIN\sthat\sshould\srefer\sto\sOUTER\sJOIN.\nNo\schanges\sto\scode. +D 2022-04-11T11:59:25.896 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -503,7 +503,7 @@ F src/date.c 15082566229d4b1e5f24fdb490bf9bcc68824b911d70e3573ef075a1b9e2d26f F src/dbpage.c 90661a87e1db8bfbc8d2ebbdcd3749651ddb287c555c07a28fb17c7c591ffb68 F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d F src/delete.c a8e844af211a48b13b5b358be77a12c860c6a557c21990ad51a548e2536500ce -F src/expr.c 5e247a8dfabb92e9fd10b78a675dc5d25430433dfd9e316471b4447b548635ba +F src/expr.c d5be48b7f3f58026a7e8386ad8cb65c3550bbec79b0fe053a69594a81a5b20e9 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 94927f9b46d72a9cb858c208febf04ceb0a3270c5fa5fd0b7f436cf16e09f72a F src/func.c a3407a6fbb0d4088d8d502e46f0ace63e0aeae7467ae23a9ca9815bbf9239761 @@ -552,7 +552,7 @@ F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c 7110fc3b5a4dec5d11559141c1906c4a125349fb602f541b05db3a3d448d4b95 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 360720df7dbf31977fb265aa49fc9b99599e16de521ac5a7a683c16d26d65acf +F src/select.c 178edb7fc4e6f5dabbd9c3755eb601151af78eaf69af73cc6bfe8195121c3d41 F src/shell.c.in eb7f10d5e2c47bd014d92ec5db1def21fcc1ed56ffaaa4ee715b6c37c370b47f F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1946,8 +1946,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 ccb61fb1f30e2741b19c1a0cbd2951715224852c86234a3c6a4bbd2e1187634a e8c00442d2daedec079748d13147bf73b0ec3c3cf432bce2cdccb706bdff2853 -R 0d4dae690860c958443834a66cabd1f6 +P 29927926eb32acd963e2c496ad67d55177615ec4150fd218afaf2f9a730cabec +R 6a36a3a28fad2aa38e4b5d7c8bda927a U drh -Z a424a48ba2c370ac2094114fa017cf8b +Z 390b95acc02a593d1c52fcc716321c1e # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 21a1d0077c..11566ff6d2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -29927926eb32acd963e2c496ad67d55177615ec4150fd218afaf2f9a730cabec \ No newline at end of file +5be5ede5cca1cd5ef863fe0feb2b4a990f4a42865281a6c2e4eb816f48847dc6 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 2c00bb498d..fcef002f24 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2179,7 +2179,7 @@ Expr *sqlite3ExprSimplifiedAndOr(Expr *pExpr){ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ /* If pWalker->eCode is 2 then any term of the expression that comes from - ** the ON or USING clauses of a left join disqualifies the expression + ** the ON or USING clauses of an outer join disqualifies the expression ** from being considered constant. */ if( pWalker->eCode==2 && ExprHasProperty(pExpr, EP_FromJoin) ){ pWalker->eCode = 0; @@ -5817,7 +5817,7 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ ** in an incorrect answer. ** ** Terms of p that are marked with EP_FromJoin (and hence that come from -** the ON or USING clauses of LEFT JOINS) are excluded from the analysis. +** the ON or USING clauses of OUTER JOINS) are excluded from the analysis. ** ** This routine is used to check if a LEFT JOIN can be converted into ** an ordinary JOIN. The p argument is the WHERE clause. If the WHERE diff --git a/src/select.c b/src/select.c index 1c929d0b94..3e4f783a33 100644 --- a/src/select.c +++ b/src/select.c @@ -408,7 +408,7 @@ static void addWhereTerm( ** expression. ** ** The EP_FromJoin property is used on terms of an expression to tell -** the LEFT OUTER JOIN processing logic that this term is part of the +** the OUTER JOIN processing logic that this term is part of the ** join restriction specified in the ON or USING clause and not a part ** of the more general WHERE clause. These terms are moved over to the ** WHERE clause during join processing but we need to remember that they From 3a6e4c59c480d0f00ba70b44529ba9925f61064b Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 11 Apr 2022 12:38:06 +0000 Subject: [PATCH 109/259] Make a distinction between (1) WHERE clause constraints, (2) ON/USING constraints on outer joins, and (3) ON/USING clause constraints on inner joins. Formerly, there was no distinctionb between 1 and 3, but RIGHT JOIN needs to know the difference. Make RIGHT JOIN aware of this difference and add test cases. FossilOrigin-Name: 0f6f61c3664cc87209c2a6f9b6df3a750d1510723fcde209c33db8feaf48bcf3 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/select.c | 33 ++++++++++++++++++--------------- src/sqliteInt.h | 4 ++-- src/where.c | 8 ++++++-- src/whereexpr.c | 6 +++++- test/join7.test | 11 +++++++++++ 7 files changed, 53 insertions(+), 31 deletions(-) diff --git a/manifest b/manifest index 1ac8ab2ca0..235ea5152d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\ssome\scomments\sthat\srefer\sto\sLEFT\sJOIN\sthat\sshould\srefer\sto\sOUTER\sJOIN.\nNo\schanges\sto\scode. -D 2022-04-11T11:59:25.896 +C Make\sa\sdistinction\sbetween\s(1)\sWHERE\sclause\sconstraints,\s(2)\sON/USING\nconstraints\son\souter\sjoins,\sand\s(3)\sON/USING\sclause\sconstraints\son\sinner\njoins.\s\sFormerly,\sthere\swas\sno\sdistinctionb\sbetween\s1\sand\s3,\sbut\sRIGHT\sJOIN\nneeds\sto\sknow\sthe\sdifference.\s\sMake\sRIGHT\sJOIN\saware\sof\sthis\sdifference\sand\nadd\stest\scases. +D 2022-04-11T12:38:06.753 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -552,12 +552,12 @@ F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c 7110fc3b5a4dec5d11559141c1906c4a125349fb602f541b05db3a3d448d4b95 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 178edb7fc4e6f5dabbd9c3755eb601151af78eaf69af73cc6bfe8195121c3d41 +F src/select.c 41d1b171d123a98bff4a2ddbe5ef7c47324274ca967030615506c4e246e96c12 F src/shell.c.in eb7f10d5e2c47bd014d92ec5db1def21fcc1ed56ffaaa4ee715b6c37c370b47f F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h 8a804f402410b06958bf6376daa91f11e2667ebd60e149eb5a371654a71ce448 +F src/sqliteInt.h fa220cb1b04ae45fa34de634efec4c04ce668ddcb6316c8f3260a8cf1a31310b F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -639,10 +639,10 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c e05c2c85a894d0175983241789344e48ed134f79bb84adda23a6bff53c39cf42 +F src/where.c 8d8e54e2e29ac503ac5824cac0d368a9a45b0a2a3f129b0f2d50a1e3a891c62f F src/whereInt.h ecf0d9fe3e35f2546e660c6389e56aedb6fd2434e31a0449b261ff55ebc6df2d F src/wherecode.c 808e94b66f1bf052cbb77665ba08625ba93fbb0c343fe0ecafdfdd264bf0c6c9 -F src/whereexpr.c d79dd55b6ad4d072c16838e9709d7b144c321e463ebd216de224821c06bc1fd3 +F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 F src/window.c 42a71595263dbd8ef8248218e4fc7d4b5ddccece52146ad48e079342d93f6f8f F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 @@ -1146,7 +1146,7 @@ F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test 0d63c7e43b3160b9d4b93f196ef83b6efc7751b9edd0d18c53a46fbec7a49cfc F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c -F test/join7.test 059f7ab42737fbd835dfc791354f1b182585566b540b013f3ed46bfa1e80ba42 +F test/join7.test 87f08f814012b4593a7b6021ebfbcc0d2c837045cad012a3a38e810182fe268a F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -1946,8 +1946,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 29927926eb32acd963e2c496ad67d55177615ec4150fd218afaf2f9a730cabec -R 6a36a3a28fad2aa38e4b5d7c8bda927a +P 5be5ede5cca1cd5ef863fe0feb2b4a990f4a42865281a6c2e4eb816f48847dc6 +R 9c8f191b416653ff62ae70d11a61358b U drh -Z 390b95acc02a593d1c52fcc716321c1e +Z e1bd204470110fd5d9bea7467b9ac13a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 11566ff6d2..41dbfa450d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5be5ede5cca1cd5ef863fe0feb2b4a990f4a42865281a6c2e4eb816f48847dc6 \ No newline at end of file +0f6f61c3664cc87209c2a6f9b6df3a750d1510723fcde209c33db8feaf48bcf3 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 3e4f783a33..79ff500f41 100644 --- a/src/select.c +++ b/src/select.c @@ -373,7 +373,7 @@ static void addWhereTerm( int iColLeft, /* Index of column in first table */ int iRight, /* Index of second table in pSrc */ int iColRight, /* Index of column in second table */ - int isOuterJoin, /* True if this is an OUTER join */ + u32 joinType, /* EP_FromJoin or EP_InnerJoin */ Expr **ppWhere /* IN/OUT: The WHERE clause to add to */ ){ sqlite3 *db = pParse->db; @@ -393,8 +393,8 @@ static void addWhereTerm( assert( pE2!=0 || pEq==0 ); /* Due to db->mallocFailed test ** in sqlite3DbMallocRawNN() called from ** sqlite3PExpr(). */ - if( pEq && isOuterJoin ){ - ExprSetProperty(pEq, EP_FromJoin); + if( pEq ){ + ExprSetProperty(pEq, joinType); assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) ); ExprSetVVAProperty(pEq, EP_NoReduce); pEq->w.iJoin = pE2->iTable; @@ -428,9 +428,10 @@ static void addWhereTerm( ** after the t1 loop and rows with t1.x!=5 will never appear in ** the output, which is incorrect. */ -void sqlite3SetJoinExpr(Expr *p, int iTable){ +void sqlite3SetJoinExpr(Expr *p, int iTable, u32 joinFlag){ + assert( joinFlag==EP_FromJoin || joinFlag==EP_InnerJoin ); while( p ){ - ExprSetProperty(p, EP_FromJoin); + ExprSetProperty(p, joinFlag); assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); ExprSetVVAProperty(p, EP_NoReduce); p->w.iJoin = iTable; @@ -439,11 +440,11 @@ void sqlite3SetJoinExpr(Expr *p, int iTable){ if( p->x.pList ){ int i; for(i=0; ix.pList->nExpr; i++){ - sqlite3SetJoinExpr(p->x.pList->a[i].pExpr, iTable); + sqlite3SetJoinExpr(p->x.pList->a[i].pExpr, iTable, joinFlag); } } } - sqlite3SetJoinExpr(p->pLeft, iTable); + sqlite3SetJoinExpr(p->pLeft, iTable, joinFlag); p = p->pRight; } } @@ -459,6 +460,7 @@ static void unsetJoinExpr(Expr *p, int iTable){ if( ExprHasProperty(p, EP_FromJoin) && (iTable<0 || p->w.iJoin==iTable) ){ ExprClearProperty(p, EP_FromJoin); + ExprSetProperty(p, EP_InnerJoin); } if( p->op==TK_COLUMN && p->iTable==iTable ){ ExprClearProperty(p, EP_CanBeNull); @@ -502,10 +504,10 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ pRight = &pLeft[1]; for(i=0; inSrc-1; i++, pRight++, pLeft++){ Table *pRightTab = pRight->pTab; - int isOuter; + u32 joinType; if( NEVER(pLeft->pTab==0 || pRightTab==0) ) continue; - isOuter = (pRight->fg.jointype & JT_OUTER)!=0; + joinType = (pRight->fg.jointype & JT_OUTER)!=0 ? EP_FromJoin : EP_InnerJoin; /* When the NATURAL keyword is present, add WHERE clause terms for ** every column that the two tables have in common. @@ -525,7 +527,7 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ zName = pRightTab->aCol[j].zCnName; if( tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol, 1) ){ addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, j, - isOuter, &p->pWhere); + joinType, &p->pWhere); } } } @@ -556,7 +558,7 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ return 1; } addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, iRightCol, - isOuter, &p->pWhere); + joinType, &p->pWhere); } } @@ -564,7 +566,7 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ ** an AND operator. */ else if( pRight->u3.pOn ){ - if( isOuter ) sqlite3SetJoinExpr(pRight->u3.pOn, pRight->iCursor); + sqlite3SetJoinExpr(pRight->u3.pOn, pRight->iCursor, joinType); p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pRight->u3.pOn); pRight->u3.pOn = 0; } @@ -3724,8 +3726,9 @@ static Expr *substExpr( if( pSubst->isLeftJoin ){ ExprSetProperty(pNew, EP_CanBeNull); } - if( ExprHasProperty(pExpr,EP_FromJoin) ){ - sqlite3SetJoinExpr(pNew, pExpr->w.iJoin); + if( ExprHasProperty(pExpr,EP_FromJoin|EP_InnerJoin) ){ + sqlite3SetJoinExpr(pNew, pExpr->w.iJoin, + pExpr->flags & (EP_FromJoin|EP_InnerJoin)); } sqlite3ExprDelete(db, pExpr); pExpr = pNew; @@ -4452,7 +4455,7 @@ static int flattenSubquery( pWhere = pSub->pWhere; pSub->pWhere = 0; if( isLeftJoin>0 ){ - sqlite3SetJoinExpr(pWhere, iNewParent); + sqlite3SetJoinExpr(pWhere, iNewParent, EP_FromJoin); } if( pWhere ){ if( pParent->pWhere ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7f8a8e0151..b9eb970c7a 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2887,7 +2887,7 @@ struct Expr { #define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */ #define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */ #define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */ - /* 0x400000 // Available */ +#define EP_InnerJoin 0x400000 /* Originates in ON/USING of an inner join */ #define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */ #define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */ #define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */ @@ -4829,7 +4829,7 @@ void sqlite3MaterializeView(Parse*, Table*, Expr*, ExprList*,Expr*,int); int sqlite3JoinType(Parse*, Token*, Token*, Token*); int sqlite3ColumnIndex(Table *pTab, const char *zCol); -void sqlite3SetJoinExpr(Expr*,int); +void sqlite3SetJoinExpr(Expr*,int,u32); void sqlite3CreateForeignKey(Parse*, ExprList*, Token*, ExprList*, int); void sqlite3DeferForeignKey(Parse*, int); #ifndef SQLITE_OMIT_AUTHORIZATION diff --git a/src/where.c b/src/where.c index 3fbe69e593..1cd8f4ded8 100644 --- a/src/where.c +++ b/src/where.c @@ -6172,14 +6172,18 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ WhereInfo *pSubWInfo; SrcList sFrom; Bitmask mAll = 0; - for(k=0; k<=i; k++){ + for(k=0; ka[k].pWLoop->maskSelf; + iIdxCur = pWInfo->a[k].iIdxCur; + if( iIdxCur ) sqlite3VdbeAddOp1(v, OP_NullRow, iIdxCur); } + mAll |= pLoop->maskSelf; for(k=0; knTerm; k++){ WhereTerm *pTerm = &pWC->a[k]; if( pTerm->wtFlags & TERM_VIRTUAL ) break; if( pTerm->prereqAll & ~mAll ) continue; - if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) continue; + if( ExprHasProperty(pTerm->pExpr, EP_FromJoin|EP_InnerJoin) ) continue; pSubWhere = sqlite3ExprAnd(pParse, pSubWhere, sqlite3ExprDup(db, pTerm->pExpr, 0)); } diff --git a/src/whereexpr.c b/src/whereexpr.c index b622eed1b3..90c344806e 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1809,6 +1809,7 @@ void sqlite3WhereTabFuncArgs( if( pArgs==0 ) return; for(j=k=0; jnExpr; j++){ Expr *pRhs; + u32 joinType; while( knCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){k++;} if( k>=pTab->nCol ){ sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d", @@ -1826,8 +1827,11 @@ void sqlite3WhereTabFuncArgs( sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0); pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs); if( pItem->fg.jointype & (JT_LEFT|JT_LTORJ) ){ - sqlite3SetJoinExpr(pTerm, pItem->iCursor); + joinType = EP_FromJoin; + }else{ + joinType = EP_InnerJoin; } + sqlite3SetJoinExpr(pTerm, pItem->iCursor, joinType); whereClauseInsert(pWC, pTerm, TERM_DYNAMIC); } } diff --git a/test/join7.test b/test/join7.test index c1cd9ff6cb..3b7d1f684e 100644 --- a/test/join7.test +++ b/test/join7.test @@ -175,5 +175,16 @@ foreach {id schema} { 1 3 NULL NULL 1 4 NULL NULL } + do_execsql_test join7-$id.12 { + SELECT a, b, c, d + FROM t2 FULL OUTER JOIN t1 ON b=c AND d<=0 ORDER BY +b, +d; + } { + NULL NULL 3 33 + NULL NULL 4 44 + NULL NULL 5 55 + 1 2 NULL NULL + 1 3 NULL NULL + 1 4 NULL NULL + } } finish_test From 37259f4e6b5c4645aa732b0e2c7dada27c3f3259 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 11 Apr 2022 13:13:57 +0000 Subject: [PATCH 110/259] New test cases. FossilOrigin-Name: d5f6791b86f946b348f5ddc9cedc0df4a86b17854a97554140799caf74c602f3 --- manifest | 12 ++++---- manifest.uuid | 2 +- test/join7.test | 74 +++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 69 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 235ea5152d..86737b58ad 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sa\sdistinction\sbetween\s(1)\sWHERE\sclause\sconstraints,\s(2)\sON/USING\nconstraints\son\souter\sjoins,\sand\s(3)\sON/USING\sclause\sconstraints\son\sinner\njoins.\s\sFormerly,\sthere\swas\sno\sdistinctionb\sbetween\s1\sand\s3,\sbut\sRIGHT\sJOIN\nneeds\sto\sknow\sthe\sdifference.\s\sMake\sRIGHT\sJOIN\saware\sof\sthis\sdifference\sand\nadd\stest\scases. -D 2022-04-11T12:38:06.753 +C New\stest\scases. +D 2022-04-11T13:13:57.688 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1146,7 +1146,7 @@ F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test 0d63c7e43b3160b9d4b93f196ef83b6efc7751b9edd0d18c53a46fbec7a49cfc F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c -F test/join7.test 87f08f814012b4593a7b6021ebfbcc0d2c837045cad012a3a38e810182fe268a +F test/join7.test 1046604adf0c14d511b9fdd32d0ae0dbd0b72bf5bdb743f8c2e2308ab2ece16d F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -1946,8 +1946,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 5be5ede5cca1cd5ef863fe0feb2b4a990f4a42865281a6c2e4eb816f48847dc6 -R 9c8f191b416653ff62ae70d11a61358b +P 0f6f61c3664cc87209c2a6f9b6df3a750d1510723fcde209c33db8feaf48bcf3 +R f9db99ab6a64191d51c5383e6585d61d U drh -Z e1bd204470110fd5d9bea7467b9ac13a +Z 5631bbf7326a120ea1b6b188ec3bde18 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 41dbfa450d..7b36e498af 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0f6f61c3664cc87209c2a6f9b6df3a750d1510723fcde209c33db8feaf48bcf3 \ No newline at end of file +d5f6791b86f946b348f5ddc9cedc0df4a86b17854a97554140799caf74c602f3 \ No newline at end of file diff --git a/test/join7.test b/test/join7.test index 3b7d1f684e..fc6d898fc4 100644 --- a/test/join7.test +++ b/test/join7.test @@ -87,11 +87,22 @@ foreach {id schema} { CREATE TABLE dual(dummy TEXT); INSERT INTO dual(dummy) VALUES('x'); } + 10 { + CREATE TABLE t1(a INT, b INT, PRIMARY KEY(a,b)) WITHOUT ROWID; + INSERT INTO t1 VALUES(1,2),(1,3),(1,4); + CREATE TABLE t2a(c INTEGER PRIMARY KEY, i1 INT); + CREATE TABLE t2b(i1 INTEGER PRIMARY KEY, d INT); + CREATE VIEW t2(c,d) AS SELECT c, d FROM t2a NATURAL JOIN t2b; + INSERT INTO t2a VALUES(3,93),(4,94),(5,95),(6,96),(7,97); + INSERT INTO t2b VALUES(91,11),(92,22),(93,33),(94,44),(95,55); + CREATE TABLE dual(dummy TEXT); + INSERT INTO dual(dummy) VALUES('x'); + } } { reset_db db nullvalue NULL do_execsql_test join7-$id.setup $schema {} - do_execsql_test join7-$id.1 { + do_execsql_test join7-$id.10 { SELECT b, d FROM t1 FULL OUTER JOIN t2 ON b=c ORDER BY +b; } { NULL 55 @@ -99,7 +110,7 @@ foreach {id schema} { 3 33 4 44 } - do_execsql_test join7-$id.2 { + do_execsql_test join7-$id.20 { SELECT a, c FROM t1 FULL OUTER JOIN t2 ON b=c ORDER BY +b; } { NULL 5 @@ -107,7 +118,7 @@ foreach {id schema} { 1 3 1 4 } - do_execsql_test join7-$id.3 { + do_execsql_test join7-$id.30 { SELECT * FROM t1 FULL OUTER JOIN t2 ON b=c ORDER BY +b; } { NULL NULL 5 55 @@ -115,35 +126,66 @@ foreach {id schema} { 1 3 3 33 1 4 4 44 } - do_execsql_test join7-$id.4 { + do_execsql_test join7-$id.31 { + SELECT t1.*, t2.* FROM t2 FULL OUTER JOIN t1 ON b=c ORDER BY +b; + } { + NULL NULL 5 55 + 1 2 NULL NULL + 1 3 3 33 + 1 4 4 44 + } + do_execsql_test join7-$id.40 { SELECT * FROM t1 RIGHT OUTER JOIN t2 ON b=c ORDER BY +b; } { NULL NULL 5 55 1 3 3 33 1 4 4 44 } - do_execsql_test join7-$id.5 { + do_execsql_test join7-$id.50 { + SELECT t1.*, t2.* FROM t2 LEFT OUTER JOIN t1 ON b=c ORDER BY +b; + } { + NULL NULL 5 55 + 1 3 3 33 + 1 4 4 44 + } + do_execsql_test join7-$id.60 { SELECT * FROM dual JOIN t1 ON true RIGHT OUTER JOIN t2 ON b=c ORDER BY +b; } { NULL NULL NULL 5 55 x 1 3 3 33 x 1 4 4 44 } - do_execsql_test join7-$id.6 { + do_execsql_test join7-$id.70 { + SELECT t1.*, t2.* + FROM t2 LEFT JOIN (dual JOIN t1 ON true) ON b=c ORDER BY +b; + } { + NULL NULL 5 55 + 1 3 3 33 + 1 4 4 44 + } + do_execsql_test join7-$id.80 { SELECT * FROM dual CROSS JOIN t1 RIGHT OUTER JOIN t2 ON b=c ORDER BY +b; } { NULL NULL NULL 5 55 x 1 3 3 33 x 1 4 4 44 } - do_execsql_test join7-$id.7 { + do_execsql_test join7-$id.81 { + SELECT dual.*, t1.*, t2.* + FROM t1 CROSS JOIN dual RIGHT OUTER JOIN t2 ON b=c ORDER BY +b; + } { + NULL NULL NULL 5 55 + x 1 3 3 33 + x 1 4 4 44 + } + do_execsql_test join7-$id.90 { SELECT * FROM t1 LEFT OUTER JOIN t2 ON b=c ORDER BY +b; } { 1 2 NULL NULL 1 3 3 33 1 4 4 44 } - do_execsql_test join7-$id.8 { + do_execsql_test join7-$id.100 { SELECT * FROM t1 FULL OUTER JOIN t2 ON b=c AND a=1 ORDER BY +b; } { NULL NULL 5 55 @@ -151,21 +193,29 @@ foreach {id schema} { 1 3 3 33 1 4 4 44 } - do_execsql_test join7-$id.9 { + do_execsql_test join7-$id.101 { + SELECT t1.*, t2.* FROM t2 FULL OUTER JOIN t1 ON b=c AND a=1 ORDER BY +b; + } { + NULL NULL 5 55 + 1 2 NULL NULL + 1 3 3 33 + 1 4 4 44 + } + do_execsql_test join7-$id.110 { SELECT * FROM t1 FULL OUTER JOIN t2 ON b=c WHERE a=1 ORDER BY +b; } { 1 2 NULL NULL 1 3 3 33 1 4 4 44 } - do_execsql_test join7-$id.10 { + do_execsql_test join7-$id.120 { SELECT * FROM t1 FULL OUTER JOIN t2 ON b=c WHERE a IS NULL ORDER BY +d; } { NULL NULL 3 33 NULL NULL 4 44 NULL NULL 5 55 } - do_execsql_test join7-$id.11 { + do_execsql_test join7-$id.130 { SELECT * FROM t1 FULL OUTER JOIN t2 ON b=c AND d<=0 ORDER BY +b, +d; } { NULL NULL 3 33 @@ -175,7 +225,7 @@ foreach {id schema} { 1 3 NULL NULL 1 4 NULL NULL } - do_execsql_test join7-$id.12 { + do_execsql_test join7-$id.140 { SELECT a, b, c, d FROM t2 FULL OUTER JOIN t1 ON b=c AND d<=0 ORDER BY +b, +d; } { From c583719b65d2fca51178d40826f3b325329fe12a Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 11 Apr 2022 14:26:37 +0000 Subject: [PATCH 111/259] Show LEFT and RIGHT JOIN processing in the EXPLAIN QUERY PLAN output. FossilOrigin-Name: d91faeffea5cf0585fb71e5311fdcc6b8be85c7e9c732050b4448e617c970101 --- ext/rtree/rtreeC.test | 2 +- manifest | 30 +++++++++++++++--------------- manifest.uuid | 2 +- src/sqliteInt.h | 2 +- src/where.c | 4 +++- src/wherecode.c | 13 ++++++++----- test/autoindex1.test | 2 +- test/fts3join.test | 2 +- test/index6.test | 2 +- test/join2.test | 16 ++++++++-------- test/join5.test | 6 +++--- test/where9.test | 4 ++-- 12 files changed, 45 insertions(+), 40 deletions(-) diff --git a/ext/rtree/rtreeC.test b/ext/rtree/rtreeC.test index 75afcd7e22..bddc7d3030 100644 --- a/ext/rtree/rtreeC.test +++ b/ext/rtree/rtreeC.test @@ -342,7 +342,7 @@ do_eqp_execsql_test 7.2 { QUERY PLAN |--SCAN xdir |--SCAN rt VIRTUAL TABLE INDEX 2:B0D1 - `--SCAN ydir + `--SCAN ydir LEFT-JOIN } { 5 1 2 7 12 14 {} 5 2 2 7 8 12 10 diff --git a/manifest b/manifest index 86737b58ad..6a3bfffcd7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\stest\scases. -D 2022-04-11T13:13:57.688 +C Show\sLEFT\sand\sRIGHT\sJOIN\sprocessing\sin\sthe\sEXPLAIN\sQUERY\sPLAN\soutput. +D 2022-04-11T14:26:37.296 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -409,7 +409,7 @@ F ext/rtree/rtree8.test 2d99006a1386663978c9e1df167554671e4f711c419175b39f332719 F ext/rtree/rtree9.test fd3c9384ef8aabbc127b3878764070398f136eebc551cd20484b570f2cc1956a F ext/rtree/rtreeA.test a7fd235d8194115fa2e14d300337931eb2e960fe8a46cdfb66add2206412ea41 F ext/rtree/rtreeB.test 4cec297f8e5c588654bbf3c6ed0903f10612be8a2878055dd25faf8c71758bc9 -F ext/rtree/rtreeC.test c4bfa9a61c6788c03e4a9ce40ab2cfc6100982559effd9842d1b658e1d47aa5f +F ext/rtree/rtreeC.test 2978b194d09b13e106bdb0e1c5b408b9d42eb338c1082bf43c87ef43bd626147 F ext/rtree/rtreeD.test fe46aa7f012e137bd58294409b16c0d43976c3bb92c8f710481e577c4a1100dc F ext/rtree/rtreeE.test e65d3fc625da1800b412fc8785817327d43ccfec5f5973912d8c9e471928caa9 F ext/rtree/rtreeF.test 81ffa7ef51c4e4618d497a57328c265bf576990c7070633b623b23cd450ed331 @@ -557,7 +557,7 @@ F src/shell.c.in eb7f10d5e2c47bd014d92ec5db1def21fcc1ed56ffaaa4ee715b6c37c370b47 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h fa220cb1b04ae45fa34de634efec4c04ce668ddcb6316c8f3260a8cf1a31310b +F src/sqliteInt.h cfdfe65eeb87d3fa8319481fb541586f49e93d5715e9f487ae83362844a9abc7 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -639,9 +639,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c 8d8e54e2e29ac503ac5824cac0d368a9a45b0a2a3f129b0f2d50a1e3a891c62f +F src/where.c d5ad5f449c937f78b60a154c4ed9b6ccc6d4874ae14f7375e910f07addd143ab F src/whereInt.h ecf0d9fe3e35f2546e660c6389e56aedb6fd2434e31a0449b261ff55ebc6df2d -F src/wherecode.c 808e94b66f1bf052cbb77665ba08625ba93fbb0c343fe0ecafdfdd264bf0c6c9 +F src/wherecode.c bdf7de22c7ac38ad92e78214231a6054019521bfab943c2bfd5ddfb9e8ad9255 F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 F src/window.c 42a71595263dbd8ef8248218e4fc7d4b5ddccece52146ad48e079342d93f6f8f F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -704,7 +704,7 @@ F test/auth2.test 9eb7fce9f34bf1f50d3f366fb3e606be5a2000a1 F test/auth3.test 76d20a7fa136d63bcfcf8bcb65c0b1455ed71078d81f22bcd0550d3eb18594ab F test/autoanalyze1.test b9cc3f32a990fa56669b668d237c6d53e983554ae80c0604992e18869a0b2dec F test/autoinc.test 997d6f185f138229dc4251583a1d04816423dddc2fc034871a01aeb1d728cb39 -F test/autoindex1.test fe27af92eaf884bd9c38f94be3e8afa04ec494e5eefb189902026181a6175f5e +F test/autoindex1.test 523b26034dc5e0c5ff0865055b4593f75863b82f17748dec9ca64bb8b267c502 F test/autoindex2.test 12ef578928102baaa0dc23ad397601a2f4ecb0df F test/autoindex3.test 2d13958a5617e987624a428d7aed91bf51f322b49b476e3573fadec697ce6da5 F test/autoindex4.test 75cb1191a552b8201351f5a50d160fcb9387a0fbbfb820c77798bfee7da3f8cf @@ -1008,7 +1008,7 @@ F test/fts3fault.test 798e45af84be7978ca33d5bdc94246eb44724db24174b5d8e9b1ac46c5 F test/fts3fault2.test 6a17a11d8034b1c4eca9f3091649273d56c49ff049e2173df8060f94341e9da0 F test/fts3first.test dbdedd20914c8d539aa3206c9b34a23775644641 F test/fts3fuzz001.test e3c7b0ce9b04cc02281dcc96812a277f02df03cd7dc082055d87e11eb18aaf56 -F test/fts3join.test b285c919559af5b093c51abb2c07ce7ec0156dbc9573f444b78dabd9f3040db2 +F test/fts3join.test ee25def5e763ea8879c19e74f862d5191410ccc7259338887a3685e97f512662 F test/fts3malloc.test b0e4c133b8d61d4f6d112d8110f8320e9e453ef6 F test/fts3matchinfo.test aa66cc50615578b30f6df9984819ae5b702511cf8a94251ec7c594096a703a4a F test/fts3matchinfo2.test 00144e841704b8debfcdf6097969cd9f2a1cf759e2203cda42583648f2e6bf58 @@ -1110,7 +1110,7 @@ F test/index2.test f835d5e13ca163bd78c4459ca15fd2e4ed487407 F test/index3.test 51685f39345462b84fcf77eb8537af847fdf438cc96b05c45d6aaca4e473ade0 F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6 F test/index5.test 8621491915800ec274609e42e02a97d67e9b13e7 -F test/index6.test 5a7ab531c692ff3b3d139ef8ea6709fab40f9c6862ed418b4976752a5481da3a +F test/index6.test 6e5b6943f6a97a34898e48c4d0d4990caf55c12c00465a43a9c33d2fd9a3a820 F test/index7.test b238344318e0b4e42126717f6554f0e7dfd0b39cecad4b736039b43e1e3b6eb3 F test/index8.test caa097735c91dbc23d8a402f5e63a2a03c83840ba3928733ed7f9a03f8a912a3 F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721 @@ -1141,10 +1141,10 @@ F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4 F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b F test/istrue.test e7f285bb70282625c258e866ce6337d4c762922f5a300e1b50f958aef6e7d9c9 F test/join.test a1832675aa30f2b422ff934b553e30294ca899484710242a2119ebf21f20a66a -F test/join2.test 9bdc615841b91c97a16d68bad9508aea11fa0c6b34e5689847bcc4dac70e4990 +F test/join2.test bf5ce6bfcef40dd49cfa51dd338eee62551e1efd85cadc68456c9beb43a06914 F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 -F test/join5.test 0d63c7e43b3160b9d4b93f196ef83b6efc7751b9edd0d18c53a46fbec7a49cfc +F test/join5.test c4df54e2e204d7f1417bfbdd21ca324b4b07415c647595cc47798eacfddc96d3 F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c F test/join7.test 1046604adf0c14d511b9fdd32d0ae0dbd0b72bf5bdb743f8c2e2308ab2ece16d F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 @@ -1778,7 +1778,7 @@ F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2 F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b F test/where7.test 1c1bf436bf31b913d4764a2b62ac6e98b9681e5c7ae2b562605592a56b7e946b F test/where8.test 461ca40265ed996a6305da99bb024b0e41602bb586acf544c08f95922358e49f -F test/where9.test 1ffb75edc50a8faa6e7bd77f8221d783febb00b44b0bdb32fb48cec6e38eca95 +F test/where9.test 2db942671a002621eff4f713e347bb25243295f79d8990297cd160bebcfde3f7 F test/whereA.test 9d1077b117f1b68d5f739d94f36956c36cf995eb87bb19b77b2e81af020edd20 F test/whereB.test 0def95db3bdec220a731c7e4bec5930327c1d8c5 F test/whereC.test cae295158703cb3fc23bf1a108a9ab730efff0f6 @@ -1946,8 +1946,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 0f6f61c3664cc87209c2a6f9b6df3a750d1510723fcde209c33db8feaf48bcf3 -R f9db99ab6a64191d51c5383e6585d61d +P d5f6791b86f946b348f5ddc9cedc0df4a86b17854a97554140799caf74c602f3 +R e0e6850d0795cb014db7acec54c6d9c7 U drh -Z 5631bbf7326a120ea1b6b188ec3bde18 +Z 41018e27e5349147bcae79649d9ca497 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7b36e498af..2b59843c0c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d5f6791b86f946b348f5ddc9cedc0df4a86b17854a97554140799caf74c602f3 \ No newline at end of file +d91faeffea5cf0585fb71e5311fdcc6b8be85c7e9c732050b4448e617c970101 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index b9eb970c7a..330d58fa48 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3163,7 +3163,7 @@ struct SrcList { #define WHERE_SORTBYGROUP 0x0200 /* Support sqlite3WhereIsSorted() */ #define WHERE_AGG_DISTINCT 0x0400 /* Query is "SELECT agg(DISTINCT ...)" */ #define WHERE_ORDERBY_LIMIT 0x0800 /* ORDERBY+LIMIT on the inner loop */ - /* 0x1000 not currently used */ +#define WHERE_RIGHT_JOIN 0x1000 /* Processing a RIGHT JOIN */ /* 0x2000 not currently used */ #define WHERE_USE_LIMIT 0x4000 /* Use the LIMIT in cost estimates */ /* 0x8000 not currently used */ diff --git a/src/where.c b/src/where.c index 1cd8f4ded8..3677759ce8 100644 --- a/src/where.c +++ b/src/where.c @@ -6191,8 +6191,9 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ sFrom.nAlloc = 1; memcpy(&sFrom.a[0], pTabItem, sizeof(SrcItem)); sFrom.a[0].fg.jointype = 0; + ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTab->zName)); pSubWInfo = sqlite3WhereBegin(pParse, &sFrom, pSubWhere, 0, 0, 0, - WHERE_OR_SUBCLAUSE, 0); + WHERE_RIGHT_JOIN, 0); if( pSubWInfo ){ int iCur = pLevel->iTabCur; int r = ++pParse->nMem; @@ -6219,6 +6220,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ sqlite3WhereEnd(pSubWInfo); } sqlite3ExprDelete(pParse->db, pSubWhere); + ExplainQueryPlanPop(pParse); continue; } diff --git a/src/wherecode.c b/src/wherecode.c index 0c81048678..410d6f206e 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -204,6 +204,9 @@ int sqlite3WhereExplainOneScan( pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr); } #endif + if( pItem->fg.jointype & JT_LEFT ){ + sqlite3_str_appendf(&str, " LEFT-JOIN"); + } #ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS if( pLoop->nOut>=10 ){ sqlite3_str_appendf(&str, " (~%llu rows)", @@ -1150,7 +1153,7 @@ static void codeDeferredSeek( pWInfo->bDeferredSeek = 1; sqlite3VdbeAddOp3(v, OP_DeferredSeek, iIdxCur, 0, iCur); - if( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE) + if( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN)) && DbMaskAllZero(sqlite3ParseToplevel(pParse)->writeMask) ){ int i; @@ -1502,7 +1505,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( ** initialize a memory cell that records if this table matches any ** row of the left table of the join. */ - assert( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE) + assert( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN)) || pLevel->iFrom>0 || (pTabItem[0].fg.jointype & JT_LEFT)==0 ); if( pLevel->iFrom>0 && (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){ @@ -2140,7 +2143,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( /* Seek the table cursor, if required */ omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0 - && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0; + && (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))==0; if( omitTable ){ /* pIdx is a covering index. No need to access the main table. */ }else if( HasRowid(pIdx->pTable) ){ @@ -2174,7 +2177,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( ** move forward to the next index. ** https://sqlite.org/src/info/4e8e4857d32d401f */ - if( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){ + if( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))==0 ){ whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo); } @@ -2193,7 +2196,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( /* The following assert() is not a requirement, merely an observation: ** The OR-optimization doesn't work for the right hand table of ** a LEFT JOIN: */ - assert( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ); + assert( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))==0 ); } /* Record the instruction used to terminate the loop. */ diff --git a/test/autoindex1.test b/test/autoindex1.test index 6b437f1867..2cd4900400 100644 --- a/test/autoindex1.test +++ b/test/autoindex1.test @@ -283,7 +283,7 @@ do_eqp_test autoindex1-600a { | `--CORRELATED SCALAR SUBQUERY xxxxxx | `--SEARCH later USING COVERING INDEX sqlite_autoindex_flock_owner_1 (flock_no=? AND owner_change_date>? AND owner_change_date Date: Mon, 11 Apr 2022 14:43:11 +0000 Subject: [PATCH 112/259] Do not attempt the LEFT JOIN strength reduction optimization on a FULL JOIN. FossilOrigin-Name: 7ef3e99a73d70405a185d5d31f2d97d3bd99568fd6f10941e75d6c0baa27dc4f --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 2 +- test/join7.test | 7 +++++++ 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 6a3bfffcd7..fc6f19d7ac 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Show\sLEFT\sand\sRIGHT\sJOIN\sprocessing\sin\sthe\sEXPLAIN\sQUERY\sPLAN\soutput. -D 2022-04-11T14:26:37.296 +C Do\snot\sattempt\sthe\sLEFT\sJOIN\sstrength\sreduction\soptimization\son\sa\sFULL\sJOIN. +D 2022-04-11T14:43:11.140 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -552,7 +552,7 @@ F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c 7110fc3b5a4dec5d11559141c1906c4a125349fb602f541b05db3a3d448d4b95 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 41d1b171d123a98bff4a2ddbe5ef7c47324274ca967030615506c4e246e96c12 +F src/select.c 67d793d9d3008699bc67a079de9eafc0c07d84c12fb867e5b735a79a456a77cb F src/shell.c.in eb7f10d5e2c47bd014d92ec5db1def21fcc1ed56ffaaa4ee715b6c37c370b47f F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1146,7 +1146,7 @@ F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test c4df54e2e204d7f1417bfbdd21ca324b4b07415c647595cc47798eacfddc96d3 F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c -F test/join7.test 1046604adf0c14d511b9fdd32d0ae0dbd0b72bf5bdb743f8c2e2308ab2ece16d +F test/join7.test 55bb771ea4a1bfe13a30cc4e1d1e248e52ed995027f578b4301cfed24b38fccc F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -1946,8 +1946,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 d5f6791b86f946b348f5ddc9cedc0df4a86b17854a97554140799caf74c602f3 -R e0e6850d0795cb014db7acec54c6d9c7 +P d91faeffea5cf0585fb71e5311fdcc6b8be85c7e9c732050b4448e617c970101 +R 5d3448a355057fba04d29e5742ae9a58 U drh -Z 41018e27e5349147bcae79649d9ca497 +Z a47161e29e441e2be838325980d1fa2a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2b59843c0c..8d2561664e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d91faeffea5cf0585fb71e5311fdcc6b8be85c7e9c732050b4448e617c970101 \ No newline at end of file +7ef3e99a73d70405a185d5d31f2d97d3bd99568fd6f10941e75d6c0baa27dc4f \ No newline at end of file diff --git a/src/select.c b/src/select.c index 79ff500f41..cede26d1c7 100644 --- a/src/select.c +++ b/src/select.c @@ -6509,7 +6509,7 @@ int sqlite3Select( /* Convert LEFT JOIN into JOIN if there are terms of the right table ** of the LEFT JOIN used in the WHERE clause. */ - if( (pItem->fg.jointype & JT_LEFT)!=0 + if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))==JT_LEFT && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor) && OptimizationEnabled(db, SQLITE_SimplifyJoin) ){ diff --git a/test/join7.test b/test/join7.test index fc6d898fc4..a2c020f324 100644 --- a/test/join7.test +++ b/test/join7.test @@ -208,6 +208,13 @@ foreach {id schema} { 1 3 3 33 1 4 4 44 } + do_execsql_test join7-$id.111 { + SELECT t1.*, t2.* FROM t2 FULL OUTER JOIN t1 ON b=c WHERE a=1 ORDER BY +b; + } { + 1 2 NULL NULL + 1 3 3 33 + 1 4 4 44 + } do_execsql_test join7-$id.120 { SELECT * FROM t1 FULL OUTER JOIN t2 ON b=c WHERE a IS NULL ORDER BY +d; } { From 6134b2dff2d5df510210880f935bbd2b0a08f93c Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 11 Apr 2022 17:27:38 +0000 Subject: [PATCH 113/259] Fix handling of "continue" and "break" from inside the loop for the right operand of a RIGHT JOIN. FossilOrigin-Name: b6e773a26c2c6ee76ea61acb059b4e676d07ea62f6db9c513638f8986557cf04 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/vdbe.c | 10 +++++++--- src/where.c | 11 ++++++++--- src/whereInt.h | 1 + test/join7.test | 26 ++++++++++++++++++++++++++ test/where.test | 9 +++++++++ 7 files changed, 62 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index fc6f19d7ac..fce667eaea 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sattempt\sthe\sLEFT\sJOIN\sstrength\sreduction\soptimization\son\sa\sFULL\sJOIN. -D 2022-04-11T14:43:11.140 +C Fix\shandling\sof\s"continue"\sand\s"break"\sfrom\sinside\sthe\sloop\sfor\sthe\sright\noperand\sof\sa\sRIGHT\sJOIN. +D 2022-04-11T17:27:38.662 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -624,7 +624,7 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c eefc5a96938cc113a95e36a42b626bf594a7f0b8bb56ae299accbbf015b973cd +F src/vdbe.c 871c55b7eea607980465a3e9d5c1ba1af679789be5e9181af11ed2ff9ffd420f F src/vdbe.h 89f5edb1422c8783a0b29db836e409876f2b3e847f78e2b21b1fbcc48a93f85f F src/vdbeInt.h 5f3d0abcf30c2b7a6672ad4386f18be0fca9c9b2cefe18f85a2e3df74f2613bf F src/vdbeapi.c 354c893f1500cf524cc45c32879b9c68893a28b77e3442c24668d6afe4236217 @@ -639,8 +639,8 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c d5ad5f449c937f78b60a154c4ed9b6ccc6d4874ae14f7375e910f07addd143ab -F src/whereInt.h ecf0d9fe3e35f2546e660c6389e56aedb6fd2434e31a0449b261ff55ebc6df2d +F src/where.c e704ad49ef2907633148e2c2d2a22abba229f0ded23a498e4b9587fd02c6d965 +F src/whereInt.h cd6bddac3a26640b92d86e2b45ecc6e82d663cbcac6fd5d6d9690dfb280b1668 F src/wherecode.c bdf7de22c7ac38ad92e78214231a6054019521bfab943c2bfd5ddfb9e8ad9255 F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 F src/window.c 42a71595263dbd8ef8248218e4fc7d4b5ddccece52146ad48e079342d93f6f8f @@ -1146,7 +1146,7 @@ F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test c4df54e2e204d7f1417bfbdd21ca324b4b07415c647595cc47798eacfddc96d3 F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c -F test/join7.test 55bb771ea4a1bfe13a30cc4e1d1e248e52ed995027f578b4301cfed24b38fccc +F test/join7.test e5c9b1b729d7e1d0b4195e99833e0ff0cf2d88e7fdd32b49af1044f4c76f72d9 F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -1770,7 +1770,7 @@ F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2a F test/walvfs.test bccb3e0d235ef85e276f491d34db32c9ada1ea67be8d9f10aabe7b30319ec656 F test/wapp.tcl b440cd8cf57953d3a49e7ee81e6a18f18efdaf113b69f7d8482b0710a64566ec F test/wapptest.tcl 899594e25684861d5b0c0880fb012364def50ef8097041b8ddf74be5ba7fa270 x -F test/where.test f114842c1851d257a26770f2ad55119b084001c0e1b8c214f886f45152d37cd8 +F test/where.test 8c6bbd0cae8feae142a7946e3484a802fa566bacf38452b1c3e48cb77321f9a4 F test/where2.test 03c21a11e7b90e2845fc3c8b4002fc44cc2797fa74c86ee47d70bd7ea4f29ed6 F test/where3.test 5b4ffc0ac2ea0fe92f02b1244b7531522fe4d7bccf6fa8741d54e82c10e67753 F test/where4.test 4a371bfcc607f41d233701bdec33ac2972908ba8 @@ -1946,8 +1946,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 d91faeffea5cf0585fb71e5311fdcc6b8be85c7e9c732050b4448e617c970101 -R 5d3448a355057fba04d29e5742ae9a58 +P 7ef3e99a73d70405a185d5d31f2d97d3bd99568fd6f10941e75d6c0baa27dc4f +R 6de58d614948b06c1662abe14fed19fe U drh -Z a47161e29e441e2be838325980d1fa2a +Z e47a7befddcb419a51a3526b7bfafbab # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8d2561664e..11c7f5d20d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7ef3e99a73d70405a185d5d31f2d97d3bd99568fd6f10941e75d6c0baa27dc4f \ No newline at end of file +b6e773a26c2c6ee76ea61acb059b4e676d07ea62f6db9c513638f8986557cf04 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 18286c297b..45a47756eb 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -993,8 +993,12 @@ jump_to_p2: /* Opcode: Return P1 P2 P3 * * ** -** Jump to the next instruction after the address in register P1. After -** the jump, register P1 becomes undefined. +** Jump to the next instruction after the address stored in register P1. +** +** It used to be that after the jump, register P1 would become undefined. +** However, for the subroutine used for the inner loop of a RIGHT JOIN, +** it is useful for R1 register to be unchanged, so that is what happens +** now. ** ** P2 is not used by the byte-code engine. However, if P2 is positive ** and also less than the current address, then the "EXPLAIN" output @@ -1012,7 +1016,7 @@ case OP_Return: { /* in1 */ pIn1 = &aMem[pOp->p1]; assert( pIn1->flags==MEM_Int ); pOp = &aOp[pIn1->u.i]; - pIn1->flags = MEM_Undefined; + /* pIn1->flags = MEM_Undefined; */ break; } diff --git a/src/where.c b/src/where.c index 3677759ce8..defbc860fc 100644 --- a/src/where.c +++ b/src/where.c @@ -5880,6 +5880,7 @@ WhereInfo *sqlite3WhereBegin( pRJ->regBloom = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Blob, 65536, pRJ->regBloom); pRJ->regReturn = ++pParse->nMem; + pRJ->addrInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, pRJ->regReturn); assert( pTab==pTabItem->pTab ); if( HasRowid(pTab) ){ KeyInfo *pInfo; @@ -6013,7 +6014,11 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ /* Terminate the subroutine that forms the interior of the loop of ** the RIGHT JOIN table */ WhereRightJoin *pRJ = pLevel->pRJ; - sqlite3VdbeChangeP1(v, pRJ->addrSubrtn-1, sqlite3VdbeCurrentAddr(v)); + int addrHere = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeChangeP1(v, pRJ->addrSubrtn-1, addrHere); + sqlite3VdbeChangeP1(v, pRJ->addrInit, addrHere); + sqlite3VdbeResolveLabel(v, pLevel->addrCont); + pLevel->addrCont = 0; sqlite3VdbeAddOp2(v, OP_Return, pRJ->regReturn, pRJ->addrSubrtn); } pLoop = pLevel->pWLoop; @@ -6043,7 +6048,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ } #endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */ /* The common case: Advance to the next row */ - sqlite3VdbeResolveLabel(v, pLevel->addrCont); + if( pLevel->addrCont ) sqlite3VdbeResolveLabel(v, pLevel->addrCont); sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3); sqlite3VdbeChangeP5(v, pLevel->p5); VdbeCoverage(v); @@ -6058,7 +6063,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ #ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT if( addrSeek ) sqlite3VdbeJumpHere(v, addrSeek); #endif - }else{ + }else if( pLevel->addrCont ){ sqlite3VdbeResolveLabel(v, pLevel->addrCont); } if( (pLoop->wsFlags & WHERE_IN_ABLE)!=0 && pLevel->u.in.nIn>0 ){ diff --git a/src/whereInt.h b/src/whereInt.h index 7b5be3011d..6be8234e27 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -52,6 +52,7 @@ struct WhereRightJoin { int regBloom; /* Bloom filter for iRJMatch */ int regReturn; /* Return register for the interior subroutine */ int addrSubrtn; /* Starting address for the interior subroutine */ + int addrInit; /* OP_Integer used for early init of regReturn */ }; /* diff --git a/test/join7.test b/test/join7.test index a2c020f324..a0507be1d9 100644 --- a/test/join7.test +++ b/test/join7.test @@ -215,6 +215,24 @@ foreach {id schema} { 1 3 3 33 1 4 4 44 } + do_execsql_test join7-$id.115 { + SELECT * FROM t1 FULL OUTER JOIN t2 ON b=c + WHERE a=1 OR a IS NULL ORDER BY +b; + } { + NULL NULL 5 55 + 1 2 NULL NULL + 1 3 3 33 + 1 4 4 44 + } + do_execsql_test join7-$id.116 { + SELECT t1.*, t2.* FROM t2 FULL OUTER JOIN t1 ON b=c + WHERE a=1 OR a IS NULL ORDER BY +b; + } { + NULL NULL 5 55 + 1 2 NULL NULL + 1 3 3 33 + 1 4 4 44 + } do_execsql_test join7-$id.120 { SELECT * FROM t1 FULL OUTER JOIN t2 ON b=c WHERE a IS NULL ORDER BY +d; } { @@ -243,5 +261,13 @@ foreach {id schema} { 1 3 NULL NULL 1 4 NULL NULL } + do_execsql_test join7-$id.141 { + SELECT a, b, c, d + FROM t2 FULL OUTER JOIN t1 ON b=c AND d<=0 + ORDER BY +b, +d LIMIT 2 OFFSET 2 + } { + NULL NULL 5 55 + 1 2 NULL NULL + } } finish_test diff --git a/test/where.test b/test/where.test index 8ee57b8b6f..2f53f2cb49 100644 --- a/test/where.test +++ b/test/where.test @@ -1348,16 +1348,25 @@ do_execsql_test where-18.1 { INSERT INTO t181 VALUES(1); SELECT DISTINCT a FROM t181 LEFT JOIN t182 ON a=b ORDER BY c IS NULL; } {1} +do_execsql_test where-18.1rj { + SELECT DISTINCT a FROM t182 RIGHT JOIN t181 ON a=b ORDER BY c IS NULL; +} {1} do_execsql_test where-18.2 { SELECT DISTINCT a FROM t181 LEFT JOIN t182 ON a=b ORDER BY +c; } {1} do_execsql_test where-18.3 { SELECT DISTINCT a FROM t181 LEFT JOIN t182 ON a=b ORDER BY c; } {1} +do_execsql_test where-18.3rj { + SELECT DISTINCT a FROM t182 RIGHT JOIN t181 ON a=b ORDER BY c; +} {1} do_execsql_test where-18.4 { INSERT INTO t181 VALUES(1),(1),(1),(1); SELECT DISTINCT a FROM t181 LEFT JOIN t182 ON a=b ORDER BY +c; } {1} +do_execsql_test where-18.4rj { + SELECT DISTINCT a FROM t182 RIGHT JOIN t181 ON a=b ORDER BY +c; +} {1} do_execsql_test where-18.5 { INSERT INTO t181 VALUES(2); SELECT DISTINCT a FROM t181 LEFT JOIN t182 ON a=b ORDER BY c IS NULL, +a; From ec27077c4f1dc2753ab3f26be7024c3b8af5491c Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 11 Apr 2022 18:54:23 +0000 Subject: [PATCH 114/259] New test cases added. FossilOrigin-Name: bdd1499c0fa4f8aadf4857a0ccc0d839c250369f29766ebef80330964905e63b --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- test/affinity3.test | 32 ++++++++++++++++++++++++++++++++ test/aggnested.test | 11 +++++++++++ test/autoindex4.test | 25 +++++++++++++++++++++++++ test/btree01.test | 3 +++ test/collate2.test | 24 +++++++++++++++++++++--- test/join2.test | 15 +++++++++++++++ 8 files changed, 119 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index fce667eaea..0a663ec1c8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\shandling\sof\s"continue"\sand\s"break"\sfrom\sinside\sthe\sloop\sfor\sthe\sright\noperand\sof\sa\sRIGHT\sJOIN. -D 2022-04-11T17:27:38.662 +C New\stest\scases\sadded. +D 2022-04-11T18:54:23.445 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -646,9 +646,9 @@ F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249 F src/window.c 42a71595263dbd8ef8248218e4fc7d4b5ddccece52146ad48e079342d93f6f8f F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 -F test/affinity3.test eecb0dabee4b7765a8465439d5e99429279ffba23ca74a7eae270a452799f9e7 +F test/affinity3.test b5c19d504dec222c0dc66642673d23dce915d35737b68e74d9f237b80493eb53 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 -F test/aggnested.test cc47afa5e11e0d6771a85a4993fa6ff721480ddb53ea538ec3fdbafb720bd505 +F test/aggnested.test 7269d07ac879fce161cb26c8fabe65cba5715742fac8a1fccac570dcdaf28f00 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 F test/all.test 2ecb8bbd52416642e41c9081182a8df05d42c75637afd4488aace78cc4b69e13 F test/alter.test 313073774ab5c3f2ef1d3f0d03757c9d3a81284ae7e1b4a6ca34db088f886896 @@ -707,7 +707,7 @@ F test/autoinc.test 997d6f185f138229dc4251583a1d04816423dddc2fc034871a01aeb1d728 F test/autoindex1.test 523b26034dc5e0c5ff0865055b4593f75863b82f17748dec9ca64bb8b267c502 F test/autoindex2.test 12ef578928102baaa0dc23ad397601a2f4ecb0df F test/autoindex3.test 2d13958a5617e987624a428d7aed91bf51f322b49b476e3573fadec697ce6da5 -F test/autoindex4.test 75cb1191a552b8201351f5a50d160fcb9387a0fbbfb820c77798bfee7da3f8cf +F test/autoindex4.test 5df39313526b6f22a26bd119bbd97ca69f28386ab3c671fc10568d921c41eb08 F test/autoindex5.test 2ee94f033b87ca0160e08d81034c507aff8e230df2627f0304fa309b2fee19a3 F test/autovacuum.test 00671369bbf96c6a49989a9425f5b78b94075d6a4b031e5e00000c2c32f365df F test/autovacuum2.test 76f7eb4fe6a6bf6d33a196a7141dba98886d2fb53a268d7feca285d5da4759d7 @@ -752,7 +752,7 @@ F test/boundary3.tcl 23361e108a125dca9c4080c2feb884fe54d69243 F test/boundary3.test 56ef82096b4329aca2be74fa1e2b0f762ea0eb45 F test/boundary4.tcl 0bb4b1a94f4fc5ae59b79b9a2b7a140c405e2983 F test/boundary4.test 89e02fa66397b8a325d5eb102b5806f961f8ec4b -F test/btree01.test 8e1ba2f857608ad8fbf9fcc11f33b15b083711162f9566b0a21fb573f2008593 +F test/btree01.test fef17d9e999ac4f04095948e3438fbe674f4e07bb2c63bb1cad41d87baee077f F test/btree02.test 7555a5440453d900410160a52554fe6478af4faf53098f7235f1f443d5a1d6cc F test/btreefault.test c2bcb542685eea44621275cfedbd8a13f65201e3 F test/busy.test 510dc6daaad18bcbbc085bcc6217d6dc418def5e73f72ce1475eea0cb7834727 @@ -777,7 +777,7 @@ F test/close.test eccbad8ecd611d974cbf47278c3d4e5874faf02d811338d5d348af42d56d64 F test/closure01.test 9905883f1b171a4638f98fc764879f154e214a306d3d8daf412a15e7f3a9b1e0 F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91 F test/collate1.test 71a6f27fdc93a92f14d8ab80c05e1937656a5a03197e1a10157314554d630ce8 -F test/collate2.test 9aaa410a00734e48bcb27f3872617d6f69b2a621 +F test/collate2.test 471c6f74573382b89b0f8b88a05256faa52f7964f9e4799e76708a3b1ece6ba4 F test/collate3.test 89defc49983ddfbf0a0555aca8c0521a676f56a5 F test/collate4.test c953715fb498b87163e3e73dd94356bff1f317bd F test/collate5.test 65d928034d30d2d263a80f6359f7549ee1598ec6 @@ -1141,7 +1141,7 @@ F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4 F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b F test/istrue.test e7f285bb70282625c258e866ce6337d4c762922f5a300e1b50f958aef6e7d9c9 F test/join.test a1832675aa30f2b422ff934b553e30294ca899484710242a2119ebf21f20a66a -F test/join2.test bf5ce6bfcef40dd49cfa51dd338eee62551e1efd85cadc68456c9beb43a06914 +F test/join2.test 9751dac84a46a960281ca372fe2350252ef40286dde3c542540bccdea9a2d5c6 F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test c4df54e2e204d7f1417bfbdd21ca324b4b07415c647595cc47798eacfddc96d3 @@ -1946,8 +1946,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 7ef3e99a73d70405a185d5d31f2d97d3bd99568fd6f10941e75d6c0baa27dc4f -R 6de58d614948b06c1662abe14fed19fe +P b6e773a26c2c6ee76ea61acb059b4e676d07ea62f6db9c513638f8986557cf04 +R ea6a6206ccd15b1ede34fe0a185bc5f1 U drh -Z e47a7befddcb419a51a3526b7bfafbab +Z 7ac11620004b739208f6ff19e0608f85 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 11c7f5d20d..3f8fbe197f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b6e773a26c2c6ee76ea61acb059b4e676d07ea62f6db9c513638f8986557cf04 \ No newline at end of file +bdd1499c0fa4f8aadf4857a0ccc0d839c250369f29766ebef80330964905e63b \ No newline at end of file diff --git a/test/affinity3.test b/test/affinity3.test index ef1533a8f8..48942de72e 100644 --- a/test/affinity3.test +++ b/test/affinity3.test @@ -30,11 +30,24 @@ do_execsql_test affinity3-100 { FROM customer c LEFT JOIN apr i ON i.id=c.id; + CREATE VIEW v1rj AS + SELECT c.id, i.apr + FROM apr i + RIGHT JOIN customer c ON i.id=c.id; + CREATE VIEW v2 AS SELECT c.id, v1.apr FROM customer c LEFT JOIN v1 ON v1.id=c.id; + CREATE VIEW v2rj AS + SELECT c.id, v1.apr + FROM v1 RIGHT JOIN customer c ON v1.id=c.id; + + CREATE VIEW v2rjrj AS + SELECT c.id, v1rj.apr + FROM v1rj RIGHT JOIN customer c ON v1rj.id=c.id; + INSERT INTO customer (id) VALUES (1); INSERT INTO apr (id, apr) VALUES (1, 12); INSERT INTO customer (id) VALUES (2); @@ -44,16 +57,35 @@ do_execsql_test affinity3-110 { PRAGMA automatic_index=ON; SELECT id, (apr / 100), typeof(apr) apr_type FROM v1; } {1 0.12 real 2 0.1201 real} +do_execsql_test affinity3-111 { + PRAGMA automatic_index=ON; + SELECT id, (apr / 100), typeof(apr) apr_type FROM v1rj; +} {1 0.12 real 2 0.1201 real} do_execsql_test affinity3-120 { SELECT id, (apr / 100), typeof(apr) apr_type FROM v2; } {1 0.12 real 2 0.1201 real} +do_execsql_test affinity3-121 { + SELECT id, (apr / 100), typeof(apr) apr_type FROM v2rj; +} {1 0.12 real 2 0.1201 real} +do_execsql_test affinity3-122 { + SELECT id, (apr / 100), typeof(apr) apr_type FROM v2rjrj; +} {1 0.12 real 2 0.1201 real} do_execsql_test affinity3-130 { PRAGMA automatic_index=OFF; SELECT id, (apr / 100), typeof(apr) apr_type FROM v1; } {1 0.12 real 2 0.1201 real} +do_execsql_test affinity3-131 { + SELECT id, (apr / 100), typeof(apr) apr_type FROM v1rj; +} {1 0.12 real 2 0.1201 real} do_execsql_test affinity3-140 { SELECT id, (apr / 100), typeof(apr) apr_type FROM v2; } {1 0.12 real 2 0.1201 real} +do_execsql_test affinity3-141 { + SELECT id, (apr / 100), typeof(apr) apr_type FROM v2rj; +} {1 0.12 real 2 0.1201 real} +do_execsql_test affinity3-142 { + SELECT id, (apr / 100), typeof(apr) apr_type FROM v2rjrj; +} {1 0.12 real 2 0.1201 real} # Ticket https://www.sqlite.org/src/info/7ffd1ca1d2ad4ecf (2017-01-16) # Incorrect affinity when using automatic indexes diff --git a/test/aggnested.test b/test/aggnested.test index 35d5f1e3a6..1b8b608803 100644 --- a/test/aggnested.test +++ b/test/aggnested.test @@ -137,6 +137,17 @@ do_test aggnested-3.1 { GROUP BY curr.id1); } } {1 1} +do_test aggnested-3.1-rj { + db eval { + SELECT + (SELECT sum(value2==xyz) FROM t2) + FROM + (SELECT curr.value1 as xyz + FROM t1 AS other RIGHT JOIN t1 AS curr + GROUP BY curr.id1); + } +} {1 1} + do_test aggnested-3.2 { db eval { DROP TABLE IF EXISTS t1; diff --git a/test/autoindex4.test b/test/autoindex4.test index 24604af588..d9ab783e42 100644 --- a/test/autoindex4.test +++ b/test/autoindex4.test @@ -32,12 +32,21 @@ do_execsql_test autoindex4-1.1 { do_execsql_test autoindex4-1.2 { SELECT *, '|' FROM t1 LEFT JOIN t2 ON a=234 AND x=555; } {123 abc {} {} | 234 def {} {} | 234 ghi {} {} | 345 jkl {} {} |} +do_execsql_test autoindex4-1.2-rj { + SELECT t1.*, t2.*, '|' FROM t2 RIGHT JOIN t1 ON a=234 AND x=555; +} {123 abc {} {} | 234 def {} {} | 234 ghi {} {} | 345 jkl {} {} |} do_execsql_test autoindex4-1.3 { SELECT *, '|' FROM t1 LEFT JOIN t2 ON x=555 WHERE a=234; } {234 def {} {} | 234 ghi {} {} |} +do_execsql_test autoindex4-1.3-rj { + SELECT t1.*, t2.*, '|' FROM t2 RIGHT JOIN t1 ON x=555 WHERE a=234; +} {234 def {} {} | 234 ghi {} {} |} do_execsql_test autoindex4-1.4 { SELECT *, '|' FROM t1 LEFT JOIN t2 WHERE a=234 AND x=555; } {} +do_execsql_test autoindex4-1.4-rj { + SELECT t1.*, t2.*, '|' FROM t2 RIGHT JOIN t1 WHERE a=234 AND x=555; +} {} do_execsql_test autoindex4-2.0 { @@ -69,6 +78,14 @@ do_execsql_test autoindex4-3.0 { ORDER BY Items.ItemName; } {Item1 Item2} do_execsql_test autoindex4-3.1 { + SELECT Items.ItemName + FROM A + RIGHT JOIN Items ON (A.Name = Items.ItemName and Items.ItemName = 'dummy') + LEFT JOIN B ON (B.Name = Items.ItemName) + WHERE Items.Name = 'Parent' + ORDER BY Items.ItemName; +} {Item1 Item2} +do_execsql_test autoindex4-3.10 { CREATE INDEX Items_x1 ON Items(ItemName,Name) WHERE ItemName = 'dummy'; SELECT Items.ItemName @@ -78,6 +95,14 @@ do_execsql_test autoindex4-3.1 { WHERE Items.Name = 'Parent' ORDER BY Items.ItemName; } {Item1 Item2} +do_execsql_test autoindex4-3.11 { + SELECT Items.ItemName + FROM A + RIGHT JOIN Items ON (A.Name = Items.ItemName and Items.ItemName = 'dummy') + LEFT JOIN B ON (B.Name = Items.ItemName) + WHERE Items.Name = 'Parent' + ORDER BY Items.ItemName; +} {Item1 Item2} # 2021-11-30 - Enhancement to help the automatic index mechanism to # create a partial index more often. diff --git a/test/btree01.test b/test/btree01.test index 9c309760d5..6e4717ae65 100644 --- a/test/btree01.test +++ b/test/btree01.test @@ -148,6 +148,9 @@ do_execsql_test btree01-2.1 { INSERT INTO t2(y) VALUES(198),(187),(100); SELECT y, c FROM t2 LEFT JOIN t1 ON y=a ORDER BY x; } {198 99 187 {} 100 50} +do_execsql_test btree01-2.2 { + SELECT y, c FROM t1 RIGHT JOIN t2 ON y=a ORDER BY x; +} {198 99 187 {} 100 50} finish_test diff --git a/test/collate2.test b/test/collate2.test index d5aadb4eb5..281aa35709 100644 --- a/test/collate2.test +++ b/test/collate2.test @@ -684,16 +684,34 @@ do_test collate2-5.3 { SELECT collate2t1.b FROM collate2t2 NATURAL JOIN collate2t1; } } {aa} -do_test collate2-5.4 { +do_test collate2-5.4.1 { execsql { - SELECT collate2t2.b FROM collate2t1 LEFT OUTER JOIN collate2t2 USING (b) order by collate2t1.oid; + SELECT collate2t2.b FROM collate2t1 LEFT JOIN collate2t2 USING (b) order by collate2t1.oid; } } {{} aa {} {} {} aa {} {} {} aa {} {} {} aa {} {} {}} -do_test collate2-5.5 { +do_test collate2-5.4.2 { + execsql { + SELECT collate2t2.b FROM collate2t2 RIGHT JOIN collate2t1 ON collate2t1.b=collate2t2.b + ORDER BY collate2t1.oid; + } +} {{} aa {} {} {} aa {} {} {} aa {} {} {} aa {} {} {}} +do_test collate2-5.4.3 { + execsql { + SELECT collate2t2.b FROM collate2t1 LEFT JOIN collate2t2 ON collate2t2.b=collate2t1.b + ORDER BY collate2t1.oid; + } +} {{} aa {} {} {} {} {} {} {} {} {} {} {} {} {} {} {}} +do_test collate2-5.5.1 { execsql { SELECT collate2t1.b, collate2t2.b FROM collate2t2 LEFT OUTER JOIN collate2t1 USING (b); } } {aa aa} +do_test collate2-5.5.2 { + execsql { + SELECT collate2t1.b, collate2t2.b + FROM collate2t1 RIGHT JOIN collate2t2 ON collate2t2.b=collate2t1.b + } +} {aa aa} do_execsql_test 6.1 { CREATE TABLE t1(x); diff --git a/test/join2.test b/test/join2.test index 8af242b1ad..4142fd15b3 100644 --- a/test/join2.test +++ b/test/join2.test @@ -63,6 +63,12 @@ do_test join2-1.6 { t1 NATURAL LEFT OUTER JOIN t2 NATURAL JOIN t3 } } {1 11 111 1111} +do_test join2-1.6-rj { + execsql { + SELECT * FROM + t2 NATURAL RIGHT OUTER JOIN t1 NATURAL JOIN t3 + } +} {11 111 1 1111} ifcapable subquery { do_test join2-1.7 { execsql { @@ -70,6 +76,12 @@ ifcapable subquery { t1 NATURAL LEFT OUTER JOIN (t2 NATURAL JOIN t3) } } {1 11 111 1111 2 22 {} {} 3 33 {} {}} + do_test join2-1.7-rj { + execsql { + SELECT * FROM + (t2 NATURAL JOIN t3) NATURAL RIGHT JOIN t1 + } + } {11 111 1111 1 {} {} {} 2 {} {} {} 3} } #------------------------------------------------------------------------- @@ -88,6 +100,9 @@ do_execsql_test 2.0 { do_catchsql_test 2.1 { SELECT * FROM aa LEFT JOIN cc ON (a=b) JOIN bb ON (b=coalesce(c,1)); } {1 {ON clause references tables to its right}} +do_catchsql_test 2.1b { + SELECT * FROM aa RIGHT JOIN cc ON (a=b) JOIN bb ON (b=coalesce(c,1)); +} {1 {ON clause references tables to its right}} do_catchsql_test 2.2 { SELECT * FROM aa JOIN cc ON (a=b) JOIN bb ON (b=c); } {0 {one one one}} From c133bab72a60fc020fffce0a329c1a4092f20aa0 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 11 Apr 2022 20:15:52 +0000 Subject: [PATCH 115/259] The query flattener must add TK_IF_NULL_ROW opcodes on substituted values that land on the left operand of a RIGHT JOIN, just as it already does for the right operand of a LEFT JOIN. FossilOrigin-Name: 8e02cdf5b1128f5e5b82d93903063415ec312694e5ccdd19e99fa35433f1b68a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 52 +++++++++++++++++++++++++++++++++++++++------------ 3 files changed, 47 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 0a663ec1c8..a2d3e3fd54 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\stest\scases\sadded. -D 2022-04-11T18:54:23.445 +C The\squery\sflattener\smust\sadd\sTK_IF_NULL_ROW\sopcodes\son\ssubstituted\svalues\nthat\sland\son\sthe\sleft\soperand\sof\sa\sRIGHT\sJOIN,\sjust\sas\sit\salready\sdoes\sfor\nthe\sright\soperand\sof\sa\sLEFT\sJOIN. +D 2022-04-11T20:15:52.179 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -552,7 +552,7 @@ F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c 7110fc3b5a4dec5d11559141c1906c4a125349fb602f541b05db3a3d448d4b95 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 67d793d9d3008699bc67a079de9eafc0c07d84c12fb867e5b735a79a456a77cb +F src/select.c fdec126045cf441883836756d6d949367e8a2945c53fa6e98d6c51a08d7efc81 F src/shell.c.in eb7f10d5e2c47bd014d92ec5db1def21fcc1ed56ffaaa4ee715b6c37c370b47f F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1946,8 +1946,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 b6e773a26c2c6ee76ea61acb059b4e676d07ea62f6db9c513638f8986557cf04 -R ea6a6206ccd15b1ede34fe0a185bc5f1 +P bdd1499c0fa4f8aadf4857a0ccc0d839c250369f29766ebef80330964905e63b +R 1528160c8ffde5ccc7d4edc8311e6b3e U drh -Z 7ac11620004b739208f6ff19e0608f85 +Z 0a6599330cad92a7a73b62ce77e2586b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3f8fbe197f..bd94247551 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bdd1499c0fa4f8aadf4857a0ccc0d839c250369f29766ebef80330964905e63b \ No newline at end of file +8e02cdf5b1128f5e5b82d93903063415ec312694e5ccdd19e99fa35433f1b68a \ No newline at end of file diff --git a/src/select.c b/src/select.c index cede26d1c7..7230ff90c9 100644 --- a/src/select.c +++ b/src/select.c @@ -3654,12 +3654,40 @@ static int multiSelectOrderBy( ** ** All references to columns in table iTable are to be replaced by corresponding ** expressions in pEList. +** +** ## About "isOuterJoin": +** +** The isOuterJoin column indicates that the replacement will occur into a +** position in the parent that NULL-able due to an OUTER JOIN. Either the +** target slot in the parent is the right operand of a LEFT JOIN, or one of +** the left operands of a RIGHT JOIN. In either case, we need to potentially +** bypass the substituted expression with OP_IfNullRow. +** +** Suppose the original expression integer constant. Even though the table +** has the nullRow flag set, because the expression is an integer constant, +** it will not be NULLed out. So instead, we insert an OP_IfNullRow opcode +** that checks to see if the nullRow flag is set on the table. If the nullRow +** flag is set, then the value in the register is set to NULL and the original +** expression is bypassed. If the nullRow flag is not set, then the original +** expression runs to populate the register. +** +** Example where this is needed: +** +** CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT); +** CREATE TABLE t2(x INT UNIQUE); +** +** SELECT a,b,m,x FROM t1 LEFT JOIN (SELECT 59 AS m,x FROM t2) ON b=x; +** +** When the subquery on the right side of the LEFT JOIN is flattened, we +** have to add OP_IfNullRow in front of the OP_Integer that implements the +** "m" value of the subquery so that a NULL will be loaded instead of 59 +** when processing a non-matched row of the left. */ typedef struct SubstContext { Parse *pParse; /* The parsing context */ int iTable; /* Replace references to this table */ int iNewTable; /* New table number */ - int isLeftJoin; /* Add TK_IF_NULL_ROW opcodes on each replacement */ + int isOuterJoin; /* Add TK_IF_NULL_ROW opcodes on each replacement */ ExprList *pEList; /* Replacement expressions */ } SubstContext; @@ -3709,7 +3737,7 @@ static Expr *substExpr( sqlite3VectorErrorMsg(pSubst->pParse, pCopy); }else{ sqlite3 *db = pSubst->pParse->db; - if( pSubst->isLeftJoin && pCopy->op!=TK_COLUMN ){ + if( pSubst->isOuterJoin && pCopy->op!=TK_COLUMN ){ memset(&ifNullRow, 0, sizeof(ifNullRow)); ifNullRow.op = TK_IF_NULL_ROW; ifNullRow.pLeft = pCopy; @@ -3723,7 +3751,7 @@ static Expr *substExpr( sqlite3ExprDelete(db, pNew); return pExpr; } - if( pSubst->isLeftJoin ){ + if( pSubst->isOuterJoin ){ ExprSetProperty(pNew, EP_CanBeNull); } if( ExprHasProperty(pExpr,EP_FromJoin|EP_InnerJoin) ){ @@ -4105,7 +4133,7 @@ static int flattenSubquery( SrcList *pSubSrc; /* The FROM clause of the subquery */ int iParent; /* VDBE cursor number of the pSub result set temp table */ int iNewParent = -1;/* Replacement table for iParent */ - int isLeftJoin = 0; /* True if pSub is the right side of a LEFT JOIN */ + int isOuterJoin = 0; /* True if pSub is the right side of a LEFT JOIN */ int i; /* Loop counter */ Expr *pWhere; /* The WHERE clause */ SrcItem *pSubitem; /* The subquery */ @@ -4178,7 +4206,7 @@ static int flattenSubquery( ** ** See also tickets #306, #350, and #3300. */ - if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){ + if( (pSubitem->fg.jointype & (JT_OUTER|JT_LTORJ))!=0 ){ if( pSubSrc->nSrc>1 /* (3a) */ || isAgg /* (3b) */ || IsVirtual(pSubSrc->a[0].pTab) /* (3c) */ @@ -4187,15 +4215,15 @@ static int flattenSubquery( ){ return 0; } - isLeftJoin = 1; + isOuterJoin = 1; } #ifdef SQLITE_EXTRA_IFNULLROW else if( iFrom>0 && !isAgg ){ - /* Setting isLeftJoin to -1 causes OP_IfNullRow opcodes to be generated for + /* Setting isOuterJoin to -1 causes OP_IfNullRow opcodes to be generated for ** every reference to any result column from subquery in a join, even ** though they are not necessary. This will stress-test the OP_IfNullRow ** opcode. */ - isLeftJoin = -1; + isOuterJoin = -1; } #endif @@ -4208,7 +4236,7 @@ static int flattenSubquery( if( pSub->pOrderBy ){ return 0; /* Restriction (20) */ } - if( isAgg || (p->selFlags & SF_Distinct)!=0 || isLeftJoin>0 ){ + if( isAgg || (p->selFlags & SF_Distinct)!=0 || isOuterJoin>0 ){ return 0; /* (17d1), (17d2), or (17f) */ } for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){ @@ -4454,7 +4482,7 @@ static int flattenSubquery( } pWhere = pSub->pWhere; pSub->pWhere = 0; - if( isLeftJoin>0 ){ + if( isOuterJoin>0 ){ sqlite3SetJoinExpr(pWhere, iNewParent, EP_FromJoin); } if( pWhere ){ @@ -4469,7 +4497,7 @@ static int flattenSubquery( x.pParse = pParse; x.iTable = iParent; x.iNewTable = iNewParent; - x.isLeftJoin = isLeftJoin; + x.isOuterJoin = isOuterJoin; x.pEList = pSub->pEList; substSelect(&x, pParent, 0); } @@ -4930,7 +4958,7 @@ static int pushDownWhereTerms( x.pParse = pParse; x.iTable = iCursor; x.iNewTable = iCursor; - x.isLeftJoin = 0; + x.isOuterJoin = 0; x.pEList = pSubq->pEList; pNew = substExpr(&x, pNew); #ifndef SQLITE_OMIT_WINDOWFUNC From b087de063bed22932287aff4f12a2e5a3083aa8d Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 11 Apr 2022 21:00:38 +0000 Subject: [PATCH 116/259] Fix RIGHT JOIN for virtual tables. FossilOrigin-Name: 75a9116e98b9ac5c1a4c62a01143a016d9ba6a0b495ff7af7468c11947a3e888 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 7 ++++++- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index a2d3e3fd54..aa0aec2054 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\squery\sflattener\smust\sadd\sTK_IF_NULL_ROW\sopcodes\son\ssubstituted\svalues\nthat\sland\son\sthe\sleft\soperand\sof\sa\sRIGHT\sJOIN,\sjust\sas\sit\salready\sdoes\sfor\nthe\sright\soperand\sof\sa\sLEFT\sJOIN. -D 2022-04-11T20:15:52.179 +C Fix\sRIGHT\sJOIN\sfor\svirtual\stables. +D 2022-04-11T21:00:38.338 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -639,7 +639,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c e704ad49ef2907633148e2c2d2a22abba229f0ded23a498e4b9587fd02c6d965 +F src/where.c 728d2d5c6259b576c33a2f5107b871e9819484509126bd40ade8b95224852655 F src/whereInt.h cd6bddac3a26640b92d86e2b45ecc6e82d663cbcac6fd5d6d9690dfb280b1668 F src/wherecode.c bdf7de22c7ac38ad92e78214231a6054019521bfab943c2bfd5ddfb9e8ad9255 F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 @@ -1946,8 +1946,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 bdd1499c0fa4f8aadf4857a0ccc0d839c250369f29766ebef80330964905e63b -R 1528160c8ffde5ccc7d4edc8311e6b3e +P 8e02cdf5b1128f5e5b82d93903063415ec312694e5ccdd19e99fa35433f1b68a +R 5708722e4ffecbe2e31f6fd1bda81037 U drh -Z 0a6599330cad92a7a73b62ce77e2586b +Z 577b70851c6bc25c90b72e9816f63b4e # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index bd94247551..fb8b6444cb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8e02cdf5b1128f5e5b82d93903063415ec312694e5ccdd19e99fa35433f1b68a \ No newline at end of file +75a9116e98b9ac5c1a4c62a01143a016d9ba6a0b495ff7af7468c11947a3e888 \ No newline at end of file diff --git a/src/where.c b/src/where.c index defbc860fc..f1d3ad2655 100644 --- a/src/where.c +++ b/src/where.c @@ -6181,7 +6181,12 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ int iIdxCur; mAll |= pWInfo->a[k].pWLoop->maskSelf; iIdxCur = pWInfo->a[k].iIdxCur; - if( iIdxCur ) sqlite3VdbeAddOp1(v, OP_NullRow, iIdxCur); + if( iIdxCur ){ + sqlite3VdbeAddOp1(v, OP_NullRow, iIdxCur); + } + if( pWInfo->a[k].pWLoop->wsFlags & WHERE_VIRTUALTABLE ){ + sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur); + } } mAll |= pLoop->maskSelf; for(k=0; knTerm; k++){ From f7413d9acf1e9aefc2226baf77852b67efb58e2a Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 12 Apr 2022 11:02:06 +0000 Subject: [PATCH 117/259] Modify utility function sqlite3SetString() so that it may be used safely on Parse.zErrMsg. Fuzzer test case "crash-1604e5d76c92574e21e437049dab9b672e06b767.txt". FossilOrigin-Name: 09c5a4ec13b02efd6207e26dab7beaf184f0d8ccea0bd0dfe94fc803fe5636ce --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/malloc.c | 3 ++- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 6ca6515ff8..0428ce8b73 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rename\sthe\sExpr.w.iRightJoinTable\sto\sjust\sExpr.w.iJoin,\sso\sthat\sthe\swords\n"RightJoin"\sin\sthe\sformer\sname\sdo\snot\slead\sreaders\sto\sbelieve\sthat\sthis\shas\nsomething\sto\sdo\swith\sRIGHT\sJOINs\sin\sparticular. -D 2022-04-11T11:25:28.307 +C Modify\sutility\sfunction\ssqlite3SetString()\sso\sthat\sit\smay\sbe\sused\ssafely\son\sParse.zErrMsg.\sFuzzer\stest\scase\s"crash-1604e5d76c92574e21e437049dab9b672e06b767.txt". +D 2022-04-12T11:02:06.896 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -517,7 +517,7 @@ F src/json.c 7749b98c62f691697c7ee536b570c744c0583cab4a89200fdd0fc2aa8cc8cbd6 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 2ecb1441f9b1c22e9e022ee0776e67d259facf34b56ba892b206f0a294ee6f8c F src/main.c 135858d2ede0b83d779e71b07ede9c1d6b6eaab7b77bc2a85729584152769faf -F src/malloc.c fec841aa0a0400a6f7d20706178a5d8e8219a6bf562b6fe712c17f6c26813266 +F src/malloc.c a9127efdcef92d6934c6339ea9813075b90edc0ce2e5c723556381a3828fb720 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de F src/mem2.c c8bfc9446fd0798bddd495eb5d9dbafa7d4b7287d8c22d50a83ac9daa26d8a75 @@ -1945,8 +1945,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 21e96600d90c1cda84777abe22a11058eba46c9faefeb05f8c31bc0e7fa84b19 -R a4105d42712d7aa2e6c32a68a1a189b9 -U drh -Z 0c17b37ca377860b400b2aceb3280c9a +P e8c00442d2daedec079748d13147bf73b0ec3c3cf432bce2cdccb706bdff2853 +R ce69914b0449933d45ec56e1376c0a3b +U dan +Z 3e44eca52a4693d55a51d186d7ab15b4 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 1302d31a5e..131b4fe466 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e8c00442d2daedec079748d13147bf73b0ec3c3cf432bce2cdccb706bdff2853 \ No newline at end of file +09c5a4ec13b02efd6207e26dab7beaf184f0d8ccea0bd0dfe94fc803fe5636ce \ No newline at end of file diff --git a/src/malloc.c b/src/malloc.c index 21e5245891..cfda60a0b6 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -750,8 +750,9 @@ char *sqlite3DbSpanDup(sqlite3 *db, const char *zStart, const char *zEnd){ ** Free any prior content in *pz and replace it with a copy of zNew. */ void sqlite3SetString(char **pz, sqlite3 *db, const char *zNew){ + char *z = sqlite3DbStrDup(db, zNew); sqlite3DbFree(db, *pz); - *pz = sqlite3DbStrDup(db, zNew); + *pz = z; } /* From a70782407d12bae34240167814b49e1593048aca Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 12 Apr 2022 13:46:21 +0000 Subject: [PATCH 118/259] Always explicitly set each table cursor to NullRow before doing the RIGHT-JOIN unmatched row pass. This is a cheap opcode, and it adds an extra layer of defense against incorrect results. FossilOrigin-Name: a3d14e61ca22167296fee125a3e9aa63413408955e03bb3f9d85fa9f22df1b79 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 4 +--- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index aa0aec2054..3cd8c98914 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sRIGHT\sJOIN\sfor\svirtual\stables. -D 2022-04-11T21:00:38.338 +C Always\sexplicitly\sset\seach\stable\scursor\sto\sNullRow\sbefore\sdoing\sthe\sRIGHT-JOIN\nunmatched\srow\spass.\s\sThis\sis\sa\scheap\sopcode,\sand\sit\sadds\san\sextra\slayer\sof\ndefense\sagainst\sincorrect\sresults. +D 2022-04-12T13:46:21.228 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -639,7 +639,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c 728d2d5c6259b576c33a2f5107b871e9819484509126bd40ade8b95224852655 +F src/where.c 2e4c4a9140a5feb5d55613786f253e2684408e830fc1108abd854d95ef926d68 F src/whereInt.h cd6bddac3a26640b92d86e2b45ecc6e82d663cbcac6fd5d6d9690dfb280b1668 F src/wherecode.c bdf7de22c7ac38ad92e78214231a6054019521bfab943c2bfd5ddfb9e8ad9255 F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 @@ -1946,8 +1946,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 8e02cdf5b1128f5e5b82d93903063415ec312694e5ccdd19e99fa35433f1b68a -R 5708722e4ffecbe2e31f6fd1bda81037 +P 75a9116e98b9ac5c1a4c62a01143a016d9ba6a0b495ff7af7468c11947a3e888 +R 7f21190d047eb5dd5ac5fcbb3009e4d3 U drh -Z 577b70851c6bc25c90b72e9816f63b4e +Z fd007c71d1edd8db14c7de90c355f1d6 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index fb8b6444cb..55b041541b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -75a9116e98b9ac5c1a4c62a01143a016d9ba6a0b495ff7af7468c11947a3e888 \ No newline at end of file +a3d14e61ca22167296fee125a3e9aa63413408955e03bb3f9d85fa9f22df1b79 \ No newline at end of file diff --git a/src/where.c b/src/where.c index f1d3ad2655..2883653317 100644 --- a/src/where.c +++ b/src/where.c @@ -6180,13 +6180,11 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ for(k=0; ka[k].pWLoop->maskSelf; + sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur); iIdxCur = pWInfo->a[k].iIdxCur; if( iIdxCur ){ sqlite3VdbeAddOp1(v, OP_NullRow, iIdxCur); } - if( pWInfo->a[k].pWLoop->wsFlags & WHERE_VIRTUALTABLE ){ - sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur); - } } mAll |= pLoop->maskSelf; for(k=0; knTerm; k++){ From 61dac44eb91f0e9f37eb5ccdfe9877f0cdc39a97 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 12 Apr 2022 14:23:45 +0000 Subject: [PATCH 119/259] The multi-index OR optimization does not work for RIGHT join, so disallow it. FossilOrigin-Name: 34c2f7b237fa4e0e1cd94fb9c44ebe194b86b88dc575055cc46c7f3695d02756 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 3 +++ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 3cd8c98914..1b8dc3a8c1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Always\sexplicitly\sset\seach\stable\scursor\sto\sNullRow\sbefore\sdoing\sthe\sRIGHT-JOIN\nunmatched\srow\spass.\s\sThis\sis\sa\scheap\sopcode,\sand\sit\sadds\san\sextra\slayer\sof\ndefense\sagainst\sincorrect\sresults. -D 2022-04-12T13:46:21.228 +C The\smulti-index\sOR\soptimization\sdoes\snot\swork\sfor\sRIGHT\sjoin,\sso\sdisallow\sit. +D 2022-04-12T14:23:45.158 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -639,7 +639,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c 2e4c4a9140a5feb5d55613786f253e2684408e830fc1108abd854d95ef926d68 +F src/where.c 5473af25fd2acd2898574950f51e4eaec77d57c450c0d3339905f3db42c6bb30 F src/whereInt.h cd6bddac3a26640b92d86e2b45ecc6e82d663cbcac6fd5d6d9690dfb280b1668 F src/wherecode.c bdf7de22c7ac38ad92e78214231a6054019521bfab943c2bfd5ddfb9e8ad9255 F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 @@ -1946,8 +1946,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 75a9116e98b9ac5c1a4c62a01143a016d9ba6a0b495ff7af7468c11947a3e888 -R 7f21190d047eb5dd5ac5fcbb3009e4d3 +P a3d14e61ca22167296fee125a3e9aa63413408955e03bb3f9d85fa9f22df1b79 +R 4bae6c9d6bdd8a980fce4f657c738433 U drh -Z fd007c71d1edd8db14c7de90c355f1d6 +Z f042afe955449d12af108738d6fffc40 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 55b041541b..71af4118a6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a3d14e61ca22167296fee125a3e9aa63413408955e03bb3f9d85fa9f22df1b79 \ No newline at end of file +34c2f7b237fa4e0e1cd94fb9c44ebe194b86b88dc575055cc46c7f3695d02756 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 2883653317..4c9ba86b12 100644 --- a/src/where.c +++ b/src/where.c @@ -4016,6 +4016,9 @@ static int whereLoopAddOr( pItem = pWInfo->pTabList->a + pNew->iTab; iCur = pItem->iCursor; + /* The multi-index OR optimization does not work for RIGHT and FULL JOIN */ + if( pItem->fg.jointype & JT_RIGHT ) return SQLITE_OK; + for(pTerm=pWC->a; pTermeOperator & WO_OR)!=0 && (pTerm->u.pOrInfo->indexable & pNew->maskSelf)!=0 From 6625d6d8736ac11d87bed407e1e08268ef554f45 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 12 Apr 2022 17:02:27 +0000 Subject: [PATCH 120/259] Earlier detection of corruption in balance_nonroot(). dbsqlfuzz 9191ade77ebd3b7a3356e074957aa85b0c669d14. FossilOrigin-Name: bff4f083eb1c35544988493a5d73a42e646c4250b841f5aae38c2183f0867a0e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 0428ce8b73..a5a6f9b519 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Modify\sutility\sfunction\ssqlite3SetString()\sso\sthat\sit\smay\sbe\sused\ssafely\son\sParse.zErrMsg.\sFuzzer\stest\scase\s"crash-1604e5d76c92574e21e437049dab9b672e06b767.txt". -D 2022-04-12T11:02:06.896 +C Earlier\sdetection\sof\scorruption\sin\sbalance_nonroot().\sdbsqlfuzz\s9191ade77ebd3b7a3356e074957aa85b0c669d14. +D 2022-04-12T17:02:27.322 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -492,7 +492,7 @@ F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf F src/backup.c a2891172438e385fdbe97c11c9745676bec54f518d4447090af97189fd8e52d7 F src/bitvec.c 7c849aac407230278445cb069bebc5f89bf2ddd87c5ed9459b070a9175707b3d F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c 45161c2d5c9527b9c9bbfd7478daf3e0a619cf4bbe3278378aaea3d4b4e4f5b5 +F src/btree.c c5ede430f700fef60a7b770b64f05071099042fbde87c3e72363baa06e98574b F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482e F src/build.c ff119be98394a65bc8be7afc39d4a791a66f03a778d396de3ec456f5dfaf39e8 @@ -1945,8 +1945,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 e8c00442d2daedec079748d13147bf73b0ec3c3cf432bce2cdccb706bdff2853 -R ce69914b0449933d45ec56e1376c0a3b +P 09c5a4ec13b02efd6207e26dab7beaf184f0d8ccea0bd0dfe94fc803fe5636ce +R d18f99fed866e9865bcdfe9b0a30dad2 U dan -Z 3e44eca52a4693d55a51d186d7ab15b4 +Z 6817a1ac7fab2812dd812cb873794720 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 131b4fe466..919aafb7a6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -09c5a4ec13b02efd6207e26dab7beaf184f0d8ccea0bd0dfe94fc803fe5636ce \ No newline at end of file +bff4f083eb1c35544988493a5d73a42e646c4250b841f5aae38c2183f0867a0e \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 9e721ee5af..cf92eecd80 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8491,7 +8491,7 @@ static int balance_nonroot( iOvflSpace += sz; assert( sz<=pBt->maxLocal+23 ); assert( iOvflSpace <= (int)pBt->pageSize ); - for(k=0; b.ixNx[k]<=i && ALWAYS(k Date: Tue, 12 Apr 2022 18:04:29 +0000 Subject: [PATCH 121/259] Factor out the RIGHT JOIN non-matched row loop from sqlite3WhereEnd(). This reduces the register pressure on that routine and helps it to run faster in the common case where there is no RIGHT JOIN. FossilOrigin-Name: beeecf1604d4fb11e45058f48cb2289c6542e0bc218d63a245198113d8d5476b --- manifest | 16 +++++------ manifest.uuid | 2 +- src/where.c | 59 +------------------------------------- src/whereInt.h | 5 ++++ src/wherecode.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 91 insertions(+), 67 deletions(-) diff --git a/manifest b/manifest index b250272df0..a4942b77dc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\slatest\senhancements\sfrom\strunk\sinto\sthe\sright-join\sbranch. -D 2022-04-12T17:43:30.239 +C Factor\sout\sthe\sRIGHT\sJOIN\snon-matched\srow\sloop\sfrom\ssqlite3WhereEnd().\s\sThis\nreduces\sthe\sregister\spressure\son\sthat\sroutine\sand\shelps\sit\sto\srun\sfaster\nin\sthe\scommon\scase\swhere\sthere\sis\sno\sRIGHT\sJOIN. +D 2022-04-12T18:04:29.831 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -639,9 +639,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c 5473af25fd2acd2898574950f51e4eaec77d57c450c0d3339905f3db42c6bb30 -F src/whereInt.h cd6bddac3a26640b92d86e2b45ecc6e82d663cbcac6fd5d6d9690dfb280b1668 -F src/wherecode.c bdf7de22c7ac38ad92e78214231a6054019521bfab943c2bfd5ddfb9e8ad9255 +F src/where.c 4176c858089e521de3f0961751016dc23314bd8bc5ae382ef2619eb38f6b968e +F src/whereInt.h ea1e4b6639c4c32246f4c54b733143df76109894adf08bedee4f3999ece62c2d +F src/wherecode.c 3b0cfb2f794ae3f84c01c6d1c38ccd99886c79caab5c18550b1781ccfc27aa9c F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 F src/window.c 42a71595263dbd8ef8248218e4fc7d4b5ddccece52146ad48e079342d93f6f8f F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1946,8 +1946,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 34c2f7b237fa4e0e1cd94fb9c44ebe194b86b88dc575055cc46c7f3695d02756 bff4f083eb1c35544988493a5d73a42e646c4250b841f5aae38c2183f0867a0e -R 6edf425faad4274a6a777cbfb5cf556e +P b3e57ba120067c79e0398e39da9f00ecb11a5e18c36479da4c36a39e88a78a27 +R bf3e23f39f0d1aa0a416881bc1478c40 U drh -Z d12d0f4af27fba9957f9dda2ef72c12a +Z ccf3d060da235adb8537400c4c3b77af # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 6963963ddb..4182150ca6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b3e57ba120067c79e0398e39da9f00ecb11a5e18c36479da4c36a39e88a78a27 \ No newline at end of file +beeecf1604d4fb11e45058f48cb2289c6542e0bc218d63a245198113d8d5476b \ No newline at end of file diff --git a/src/where.c b/src/where.c index 4c9ba86b12..836b7d6dc9 100644 --- a/src/where.c +++ b/src/where.c @@ -6174,64 +6174,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ ** all of the columns of the left operand set to NULL. */ if( pLevel->pRJ ){ - WhereRightJoin *pRJ = pLevel->pRJ; - Expr *pSubWhere = 0; - WhereClause *pWC = &pWInfo->sWC; - WhereInfo *pSubWInfo; - SrcList sFrom; - Bitmask mAll = 0; - for(k=0; ka[k].pWLoop->maskSelf; - sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur); - iIdxCur = pWInfo->a[k].iIdxCur; - if( iIdxCur ){ - sqlite3VdbeAddOp1(v, OP_NullRow, iIdxCur); - } - } - mAll |= pLoop->maskSelf; - for(k=0; knTerm; k++){ - WhereTerm *pTerm = &pWC->a[k]; - if( pTerm->wtFlags & TERM_VIRTUAL ) break; - if( pTerm->prereqAll & ~mAll ) continue; - if( ExprHasProperty(pTerm->pExpr, EP_FromJoin|EP_InnerJoin) ) continue; - pSubWhere = sqlite3ExprAnd(pParse, pSubWhere, - sqlite3ExprDup(db, pTerm->pExpr, 0)); - } - sFrom.nSrc = 1; - sFrom.nAlloc = 1; - memcpy(&sFrom.a[0], pTabItem, sizeof(SrcItem)); - sFrom.a[0].fg.jointype = 0; - ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTab->zName)); - pSubWInfo = sqlite3WhereBegin(pParse, &sFrom, pSubWhere, 0, 0, 0, - WHERE_RIGHT_JOIN, 0); - if( pSubWInfo ){ - int iCur = pLevel->iTabCur; - int r = ++pParse->nMem; - int nPk; - int jmp; - int addrCont = sqlite3WhereContinueLabel(pSubWInfo); - if( HasRowid(pTab) ){ - sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, r); - nPk = 1; - }else{ - int iPk; - Index *pPk = sqlite3PrimaryKeyIndex(pTab); - nPk = pPk->nKeyCol; - pParse->nMem += nPk - 1; - for(iPk=0; iPkaiColumn[iPk]; - sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol,r+iPk); - } - } - jmp = sqlite3VdbeAddOp4Int(v, OP_Filter, pRJ->regBloom, 0, r, nPk); - sqlite3VdbeAddOp4Int(v, OP_Found, pRJ->iMatch, addrCont, r, nPk); - sqlite3VdbeJumpHere(v, jmp); - sqlite3VdbeAddOp2(v, OP_Gosub, pRJ->regReturn, pRJ->addrSubrtn); - sqlite3WhereEnd(pSubWInfo); - } - sqlite3ExprDelete(pParse->db, pSubWhere); - ExplainQueryPlanPop(pParse); + sqlite3WhereRightJoinLoop(pWInfo, i, pLevel); continue; } diff --git a/src/whereInt.h b/src/whereInt.h index 6be8234e27..c8a188f80c 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -565,6 +565,11 @@ Bitmask sqlite3WhereCodeOneLoopStart( WhereLevel *pLevel, /* The current level pointer */ Bitmask notReady /* Which tables are currently available */ ); +SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( + WhereInfo *pWInfo, + int iLevel, + WhereLevel *pLevel +); /* whereexpr.c: */ void sqlite3WhereClauseInit(WhereClause*,WhereInfo*); diff --git a/src/wherecode.c b/src/wherecode.c index 410d6f206e..d2cb85aee7 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -2786,3 +2786,79 @@ Bitmask sqlite3WhereCodeOneLoopStart( #endif return pLevel->notReady; } + +/* +** Generate the code for the loop that finds all non-matched terms +** for a RIGHT JOIN. +*/ +SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( + WhereInfo *pWInfo, + int iLevel, + WhereLevel *pLevel +){ + Parse *pParse = pWInfo->pParse; + Vdbe *v = pParse->pVdbe; + WhereRightJoin *pRJ = pLevel->pRJ; + Expr *pSubWhere = 0; + WhereClause *pWC = &pWInfo->sWC; + WhereInfo *pSubWInfo; + WhereLoop *pLoop = pLevel->pWLoop; + SrcItem *pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; + SrcList sFrom; + Bitmask mAll = 0; + int k; + + for(k=0; ka[k].pWLoop->maskSelf; + sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur); + iIdxCur = pWInfo->a[k].iIdxCur; + if( iIdxCur ){ + sqlite3VdbeAddOp1(v, OP_NullRow, iIdxCur); + } + } + mAll |= pLoop->maskSelf; + for(k=0; knTerm; k++){ + WhereTerm *pTerm = &pWC->a[k]; + if( pTerm->wtFlags & TERM_VIRTUAL ) break; + if( pTerm->prereqAll & ~mAll ) continue; + if( ExprHasProperty(pTerm->pExpr, EP_FromJoin|EP_InnerJoin) ) continue; + pSubWhere = sqlite3ExprAnd(pParse, pSubWhere, + sqlite3ExprDup(pParse->db, pTerm->pExpr, 0)); + } + sFrom.nSrc = 1; + sFrom.nAlloc = 1; + memcpy(&sFrom.a[0], pTabItem, sizeof(SrcItem)); + sFrom.a[0].fg.jointype = 0; + ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pTab->zName)); + pSubWInfo = sqlite3WhereBegin(pParse, &sFrom, pSubWhere, 0, 0, 0, + WHERE_RIGHT_JOIN, 0); + if( pSubWInfo ){ + int iCur = pLevel->iTabCur; + int r = ++pParse->nMem; + int nPk; + int jmp; + int addrCont = sqlite3WhereContinueLabel(pSubWInfo); + Table *pTab = pTabItem->pTab; + if( HasRowid(pTab) ){ + sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, r); + nPk = 1; + }else{ + int iPk; + Index *pPk = sqlite3PrimaryKeyIndex(pTab); + nPk = pPk->nKeyCol; + pParse->nMem += nPk - 1; + for(iPk=0; iPkaiColumn[iPk]; + sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol,r+iPk); + } + } + jmp = sqlite3VdbeAddOp4Int(v, OP_Filter, pRJ->regBloom, 0, r, nPk); + sqlite3VdbeAddOp4Int(v, OP_Found, pRJ->iMatch, addrCont, r, nPk); + sqlite3VdbeJumpHere(v, jmp); + sqlite3VdbeAddOp2(v, OP_Gosub, pRJ->regReturn, pRJ->addrSubrtn); + sqlite3WhereEnd(pSubWInfo); + } + sqlite3ExprDelete(pParse->db, pSubWhere); + ExplainQueryPlanPop(pParse); +} From 0879d5f9e04b3f309d8f9b669d29b12608052ebb Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 12 Apr 2022 18:40:14 +0000 Subject: [PATCH 122/259] For the bad join type error message "unknown or unsupported join type" remove the "or unsupported" clause, because we now support all valid join types. FossilOrigin-Name: ab0a0562dd3594cf50ee56f6b3a5847fa5dcadf69146d560e3e7a95651b8f405 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/select.c | 2 +- test/join.test | 12 ++++++------ test/vtab6.test | 4 ++-- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index a4942b77dc..8fb8878ffd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Factor\sout\sthe\sRIGHT\sJOIN\snon-matched\srow\sloop\sfrom\ssqlite3WhereEnd().\s\sThis\nreduces\sthe\sregister\spressure\son\sthat\sroutine\sand\shelps\sit\sto\srun\sfaster\nin\sthe\scommon\scase\swhere\sthere\sis\sno\sRIGHT\sJOIN. -D 2022-04-12T18:04:29.831 +C For\sthe\sbad\sjoin\stype\serror\smessage\s"unknown\sor\sunsupported\sjoin\stype"\nremove\sthe\s"or\sunsupported"\sclause,\sbecause\swe\snow\ssupport\sall\svalid\sjoin\ntypes. +D 2022-04-12T18:40:14.753 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -552,7 +552,7 @@ F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c 7110fc3b5a4dec5d11559141c1906c4a125349fb602f541b05db3a3d448d4b95 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c fdec126045cf441883836756d6d949367e8a2945c53fa6e98d6c51a08d7efc81 +F src/select.c 31148fafdfb7bac67389f3db8eba9ecaee1d8f41105d87d9cc53a5009ebedad5 F src/shell.c.in eb7f10d5e2c47bd014d92ec5db1def21fcc1ed56ffaaa4ee715b6c37c370b47f F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1140,7 +1140,7 @@ F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4 F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b F test/istrue.test e7f285bb70282625c258e866ce6337d4c762922f5a300e1b50f958aef6e7d9c9 -F test/join.test a1832675aa30f2b422ff934b553e30294ca899484710242a2119ebf21f20a66a +F test/join.test d9c8cb2769b147b223f9dff8f694f56cfd9d0c097f8af9c7c6562b2e4ad256b5 F test/join2.test 9751dac84a46a960281ca372fe2350252ef40286dde3c542540bccdea9a2d5c6 F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 @@ -1712,7 +1712,7 @@ F test/vtab2.test 14d4ab26cee13ba6cf5c5601b158e4f57552d3b055cdd9406cf7f711e9c840 F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e F test/vtab4.test 8e73ed268f3d596bc3590f45fc948fb40f28e9c3 F test/vtab5.test 889f444970393c73f1e077e2bdc5d845e157a391 -F test/vtab6.test 5f5c10c694763d9cb438ec12aab7d6899f0bd6e2fa120551e11dea3daa8063ca +F test/vtab6.test fa609a4af96da30beceefa3cb624abe9be38c4747ab373d98179b24027d6b798 F test/vtab7.test 70c6f4a1d6177144a8236e4172d5fba92e683440374664ad1f04851fbb335d3c F test/vtab8.test e19fa4a538fcd1bb66c22825fa8f71618fb13583 F test/vtab9.test ea58d2b95d61955f87226381716b2d0b1d4e4f9b @@ -1946,8 +1946,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 b3e57ba120067c79e0398e39da9f00ecb11a5e18c36479da4c36a39e88a78a27 -R bf3e23f39f0d1aa0a416881bc1478c40 +P beeecf1604d4fb11e45058f48cb2289c6542e0bc218d63a245198113d8d5476b +R 94bd645abdceb148bbc9cc013d9cfae2 U drh -Z ccf3d060da235adb8537400c4c3b77af +Z 54dfd3d74916a39a639c494027c1dd34 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 4182150ca6..f63e3cd4d9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -beeecf1604d4fb11e45058f48cb2289c6542e0bc218d63a245198113d8d5476b \ No newline at end of file +ab0a0562dd3594cf50ee56f6b3a5847fa5dcadf69146d560e3e7a95651b8f405 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 7230ff90c9..af3c30bfe1 100644 --- a/src/select.c +++ b/src/select.c @@ -298,7 +298,7 @@ int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){ const char *zSp2 = " "; if( pB==0 ){ zSp1++; } if( pC==0 ){ zSp2++; } - sqlite3ErrorMsg(pParse, "unknown or unsupported join type: " + sqlite3ErrorMsg(pParse, "unknown join type: " "%T%s%T%s%T", pA, zSp1, pB, zSp2, pC); jointype = JT_INNER; } diff --git a/test/join.test b/test/join.test index fdacfc25c2..d6e775436b 100644 --- a/test/join.test +++ b/test/join.test @@ -332,32 +332,32 @@ do_test join-3.7 { catchsql { SELECT * FROM t1 INNER OUTER JOIN t2; } -} {1 {unknown or unsupported join type: INNER OUTER}} +} {1 {unknown join type: INNER OUTER}} do_test join-3.8 { catchsql { SELECT * FROM t1 INNER OUTER CROSS JOIN t2; } -} {1 {unknown or unsupported join type: INNER OUTER CROSS}} +} {1 {unknown join type: INNER OUTER CROSS}} do_test join-3.9 { catchsql { SELECT * FROM t1 OUTER NATURAL INNER JOIN t2; } -} {1 {unknown or unsupported join type: OUTER NATURAL INNER}} +} {1 {unknown join type: OUTER NATURAL INNER}} do_test join-3.10 { catchsql { SELECT * FROM t1 LEFT BOGUS JOIN t2; } -} {1 {unknown or unsupported join type: LEFT BOGUS}} +} {1 {unknown join type: LEFT BOGUS}} do_test join-3.11 { catchsql { SELECT * FROM t1 INNER BOGUS CROSS JOIN t2; } -} {1 {unknown or unsupported join type: INNER BOGUS CROSS}} +} {1 {unknown join type: INNER BOGUS CROSS}} do_test join-3.12 { catchsql { SELECT * FROM t1 NATURAL AWK SED JOIN t2; } -} {1 {unknown or unsupported join type: NATURAL AWK SED}} +} {1 {unknown join type: NATURAL AWK SED}} do_test join-4.1 { execsql { diff --git a/test/vtab6.test b/test/vtab6.test index d8016e02f4..2ee5e27051 100644 --- a/test/vtab6.test +++ b/test/vtab6.test @@ -281,12 +281,12 @@ do_test vtab6-3.7 { catchsql { SELECT * FROM t1 INNER OUTER JOIN t2; } -} {1 {unknown or unsupported join type: INNER OUTER}} +} {1 {unknown join type: INNER OUTER}} do_test vtab6-3.7 { catchsql { SELECT * FROM t1 LEFT BOGUS JOIN t2; } -} {1 {unknown or unsupported join type: LEFT BOGUS}} +} {1 {unknown join type: LEFT BOGUS}} do_test vtab6-4.1 { execsql { From f7309bce1050a416e0ed1f4b375149a311abe960 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 12 Apr 2022 20:20:54 +0000 Subject: [PATCH 123/259] Ensure that the JT_LTORJ bit in the SrcItem.fg.jointype is preserved during query flattening. FossilOrigin-Name: 61259050152321bc57dbdfdc3edcabb4f18c021b1ee0491c1e04ae24c7a59d89 --- manifest | 13 +++++++------ manifest.uuid | 2 +- src/select.c | 3 ++- test/join8.test | 24 ++++++++++++++++++++++++ 4 files changed, 34 insertions(+), 8 deletions(-) create mode 100644 test/join8.test diff --git a/manifest b/manifest index 8fb8878ffd..06139b2324 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C For\sthe\sbad\sjoin\stype\serror\smessage\s"unknown\sor\sunsupported\sjoin\stype"\nremove\sthe\s"or\sunsupported"\sclause,\sbecause\swe\snow\ssupport\sall\svalid\sjoin\ntypes. -D 2022-04-12T18:40:14.753 +C Ensure\sthat\sthe\sJT_LTORJ\sbit\sin\sthe\sSrcItem.fg.jointype\sis\spreserved\sduring\nquery\sflattening. +D 2022-04-12T20:20:54.995 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -552,7 +552,7 @@ F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c 7110fc3b5a4dec5d11559141c1906c4a125349fb602f541b05db3a3d448d4b95 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 31148fafdfb7bac67389f3db8eba9ecaee1d8f41105d87d9cc53a5009ebedad5 +F src/select.c d48e4ddfd0ff34caca8650a668eb3c9ba75bab21264026f0e9a9c2271334090c F src/shell.c.in eb7f10d5e2c47bd014d92ec5db1def21fcc1ed56ffaaa4ee715b6c37c370b47f F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1147,6 +1147,7 @@ F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test c4df54e2e204d7f1417bfbdd21ca324b4b07415c647595cc47798eacfddc96d3 F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c F test/join7.test e5c9b1b729d7e1d0b4195e99833e0ff0cf2d88e7fdd32b49af1044f4c76f72d9 +F test/join8.test 72248c33b44f8fc8614c739eff176fd8e18ffab04896b9ce6fd7933854dd7d25 F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -1946,8 +1947,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 beeecf1604d4fb11e45058f48cb2289c6542e0bc218d63a245198113d8d5476b -R 94bd645abdceb148bbc9cc013d9cfae2 +P ab0a0562dd3594cf50ee56f6b3a5847fa5dcadf69146d560e3e7a95651b8f405 +R e0fbee6d64529aa79fe75ea2bbc77de8 U drh -Z 54dfd3d74916a39a639c494027c1dd34 +Z a261d34a7d2a2349b187bf56d06e0666 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f63e3cd4d9..ef1dbb8c11 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ab0a0562dd3594cf50ee56f6b3a5847fa5dcadf69146d560e3e7a95651b8f405 \ No newline at end of file +61259050152321bc57dbdfdc3edcabb4f18c021b1ee0491c1e04ae24c7a59d89 \ No newline at end of file diff --git a/src/select.c b/src/select.c index af3c30bfe1..2e5c1ac97a 100644 --- a/src/select.c +++ b/src/select.c @@ -4447,7 +4447,8 @@ static int flattenSubquery( iNewParent = pSubSrc->a[i].iCursor; memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i])); } - pSrc->a[iFrom].fg.jointype = jointype | ltorj; + pSrc->a[iFrom].fg.jointype &= JT_LTORJ; + pSrc->a[iFrom].fg.jointype |= jointype | ltorj; /* Now begin substituting subquery result set expressions for ** references to the iParent in the outer query. diff --git a/test/join8.test b/test/join8.test new file mode 100644 index 0000000000..0854d97292 --- /dev/null +++ b/test/join8.test @@ -0,0 +1,24 @@ +# 2022-04-12 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file implements tests for RIGHT and FULL OUTER JOINs. + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +db null NULL +do_execsql_test join8-10 { + CREATE TABLE t1(a,b,c); + CREATE TABLE t2(x,y); + CREATE INDEX t2x ON t2(x); + SELECT avg(DISTINCT b) FROM (SELECT * FROM t2 LEFT RIGHT JOIN t1 ON c); +} {NULL} +finish_test From 146e64d2e4f9ef6e3ce55eb87ebaeca794ec9396 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 13 Apr 2022 01:52:32 +0000 Subject: [PATCH 124/259] Add missing VdbeCoverage() macros on new branch byte-code opcodes. FossilOrigin-Name: 218c7167e562f5c327124f02a92de85079315320a221fb0508310d927596b14c --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/wherecode.c | 2 ++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 06139b2324..e1594d4e39 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sthe\sJT_LTORJ\sbit\sin\sthe\sSrcItem.fg.jointype\sis\spreserved\sduring\nquery\sflattening. -D 2022-04-12T20:20:54.995 +C Add\smissing\sVdbeCoverage()\smacros\son\snew\sbranch\sbyte-code\sopcodes. +D 2022-04-13T01:52:32.481 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -641,7 +641,7 @@ F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b F src/where.c 4176c858089e521de3f0961751016dc23314bd8bc5ae382ef2619eb38f6b968e F src/whereInt.h ea1e4b6639c4c32246f4c54b733143df76109894adf08bedee4f3999ece62c2d -F src/wherecode.c 3b0cfb2f794ae3f84c01c6d1c38ccd99886c79caab5c18550b1781ccfc27aa9c +F src/wherecode.c e0f7b26a9c2de2cbaa635e5c1ef47b9c22250b0245a14a4b785ff4c61215fa13 F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 F src/window.c 42a71595263dbd8ef8248218e4fc7d4b5ddccece52146ad48e079342d93f6f8f F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1947,8 +1947,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 ab0a0562dd3594cf50ee56f6b3a5847fa5dcadf69146d560e3e7a95651b8f405 -R e0fbee6d64529aa79fe75ea2bbc77de8 +P 61259050152321bc57dbdfdc3edcabb4f18c021b1ee0491c1e04ae24c7a59d89 +R 3ebbb5ad8363d344d9fe2023b4974777 U drh -Z a261d34a7d2a2349b187bf56d06e0666 +Z 8ce073acecbbfacea87c4e9aefc95045 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index ef1dbb8c11..667dee749c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -61259050152321bc57dbdfdc3edcabb4f18c021b1ee0491c1e04ae24c7a59d89 \ No newline at end of file +218c7167e562f5c327124f02a92de85079315320a221fb0508310d927596b14c \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index d2cb85aee7..a438db5301 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -2854,7 +2854,9 @@ SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( } } jmp = sqlite3VdbeAddOp4Int(v, OP_Filter, pRJ->regBloom, 0, r, nPk); + VdbeCoverage(v); sqlite3VdbeAddOp4Int(v, OP_Found, pRJ->iMatch, addrCont, r, nPk); + VdbeCoverage(v); sqlite3VdbeJumpHere(v, jmp); sqlite3VdbeAddOp2(v, OP_Gosub, pRJ->regReturn, pRJ->addrSubrtn); sqlite3WhereEnd(pSubWInfo); From 3b79f7580a30e7a49962e9a2538498c65227a4d7 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 13 Apr 2022 10:49:50 +0000 Subject: [PATCH 125/259] Fix an assert() in btree.c that might not be true for a corrupt database file. FossilOrigin-Name: dbd8e2e46cfb2de0ebdbb62cda2fe669df3eda98f5d6112d541f581995b1361d --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/btree.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index a5a6f9b519..85b801ffe8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Earlier\sdetection\sof\scorruption\sin\sbalance_nonroot().\sdbsqlfuzz\s9191ade77ebd3b7a3356e074957aa85b0c669d14. -D 2022-04-12T17:02:27.322 +C Fix\san\sassert()\sin\sbtree.c\sthat\smight\snot\sbe\strue\sfor\sa\scorrupt\sdatabase\sfile. +D 2022-04-13T10:49:50.291 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -492,7 +492,7 @@ F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf F src/backup.c a2891172438e385fdbe97c11c9745676bec54f518d4447090af97189fd8e52d7 F src/bitvec.c 7c849aac407230278445cb069bebc5f89bf2ddd87c5ed9459b070a9175707b3d F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c c5ede430f700fef60a7b770b64f05071099042fbde87c3e72363baa06e98574b +F src/btree.c 093c940ddf1d0753542d04e37eb9903cbc126e997815d234dd2b6317e812b192 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482e F src/build.c ff119be98394a65bc8be7afc39d4a791a66f03a778d396de3ec456f5dfaf39e8 @@ -1945,8 +1945,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 09c5a4ec13b02efd6207e26dab7beaf184f0d8ccea0bd0dfe94fc803fe5636ce -R d18f99fed866e9865bcdfe9b0a30dad2 -U dan -Z 6817a1ac7fab2812dd812cb873794720 +P bff4f083eb1c35544988493a5d73a42e646c4250b841f5aae38c2183f0867a0e +R 1538c33a9ca8b52845c5bdc4ee31c46c +U drh +Z 98d0ff758b95c26883d10f0f51771962 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 919aafb7a6..2a7d8f8807 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bff4f083eb1c35544988493a5d73a42e646c4250b841f5aae38c2183f0867a0e \ No newline at end of file +dbd8e2e46cfb2de0ebdbb62cda2fe669df3eda98f5d6112d541f581995b1361d \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index cf92eecd80..734c92e46c 100644 --- a/src/btree.c +++ b/src/btree.c @@ -5967,7 +5967,7 @@ bypass_moveto_root: assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) ); assert( pPage->isInit ); if( pPage->leaf ){ - assert( pCur->ixpPage->nCell ); + assert( pCur->ixpPage->nCell || CORRUPT_DB ); pCur->ix = (u16)idx; *pRes = c; rc = SQLITE_OK; From 12c35ec322dc2b394a3a6d8b3997ef60574414a0 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 13 Apr 2022 12:12:01 +0000 Subject: [PATCH 126/259] The rows of a RIGHT JOIN might come out in any arbitrary order. So disable the ORDER-BY/GROUP-BY optimizations if a RIGHT JOIN is involved. FossilOrigin-Name: d168f245ecf497368feea4697769930c00420ef47a584904dac85371b61fb78a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 5 +++++ 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index e1594d4e39..4f666e4221 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\smissing\sVdbeCoverage()\smacros\son\snew\sbranch\sbyte-code\sopcodes. -D 2022-04-13T01:52:32.481 +C The\srows\sof\sa\sRIGHT\sJOIN\smight\scome\sout\sin\sany\sarbitrary\sorder.\s\sSo\sdisable\nthe\sORDER-BY/GROUP-BY\soptimizations\sif\sa\sRIGHT\sJOIN\sis\sinvolved. +D 2022-04-13T12:12:01.948 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -639,7 +639,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c 4176c858089e521de3f0961751016dc23314bd8bc5ae382ef2619eb38f6b968e +F src/where.c 793d09ef0d824efb953cdaff59102dcdd5390f8c59d1d5119ddfd26dcf5cd957 F src/whereInt.h ea1e4b6639c4c32246f4c54b733143df76109894adf08bedee4f3999ece62c2d F src/wherecode.c e0f7b26a9c2de2cbaa635e5c1ef47b9c22250b0245a14a4b785ff4c61215fa13 F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 @@ -1947,8 +1947,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 61259050152321bc57dbdfdc3edcabb4f18c021b1ee0491c1e04ae24c7a59d89 -R 3ebbb5ad8363d344d9fe2023b4974777 +P 218c7167e562f5c327124f02a92de85079315320a221fb0508310d927596b14c +R ad78fe8a972588635938e37b65ef3078 U drh -Z 8ce073acecbbfacea87c4e9aefc95045 +Z 45a91ae6630079ad59ce11d407cbe16e # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 667dee749c..66ed4d8aa0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -218c7167e562f5c327124f02a92de85079315320a221fb0508310d927596b14c \ No newline at end of file +d168f245ecf497368feea4697769930c00420ef47a584904dac85371b61fb78a \ No newline at end of file diff --git a/src/where.c b/src/where.c index 836b7d6dc9..1ce569d37b 100644 --- a/src/where.c +++ b/src/where.c @@ -5900,6 +5900,11 @@ WhereInfo *sqlite3WhereBegin( sqlite3VdbeSetP4KeyInfo(pParse, pPk); } pLoop->wsFlags &= ~WHERE_IDX_ONLY; + /* The nature of RIGHT JOIN processing is such that it messes up + ** the output order. So omit any ORDER BY/GROUP BY elimination + ** optimizations. We need to do an actual sort for RIGHT JOIN. */ + pWInfo->nOBSat = 0; + pWInfo->eDistinct = WHERE_DISTINCT_UNORDERED; } } pWInfo->iTop = sqlite3VdbeCurrentAddr(v); From f7ecd956cedda9a5e73708b5263ef59da09c14c1 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 13 Apr 2022 16:46:35 +0000 Subject: [PATCH 127/259] Move the explain comment for the RIGHT-JOIN post-processing loop to the verify beginning of the loop - to make the start of the loop clearer to human bytecode readers. FossilOrigin-Name: 7ed2a271e6fcbb5e69a7f3a88d3f45fe6318819c0cc6a0dcc06c3dae5aa1503f --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/wherecode.c | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index a5552c1fb8..3131341e68 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssupport\sfor\sRIGHT\sand\sFULL\sOUTER\sJOINs. -D 2022-04-13T12:34:54.242 +C Move\sthe\sexplain\scomment\sfor\sthe\sRIGHT-JOIN\spost-processing\sloop\sto\sthe\nverify\sbeginning\sof\sthe\sloop\s-\sto\smake\sthe\sstart\sof\sthe\sloop\sclearer\sto\nhuman\sbytecode\sreaders. +D 2022-04-13T16:46:35.568 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -641,7 +641,7 @@ F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b F src/where.c 793d09ef0d824efb953cdaff59102dcdd5390f8c59d1d5119ddfd26dcf5cd957 F src/whereInt.h ea1e4b6639c4c32246f4c54b733143df76109894adf08bedee4f3999ece62c2d -F src/wherecode.c e0f7b26a9c2de2cbaa635e5c1ef47b9c22250b0245a14a4b785ff4c61215fa13 +F src/wherecode.c 34e4c445371b0ac19d234c5b454fa04d650417f10a702331ca590dc870254c41 F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 F src/window.c 42a71595263dbd8ef8248218e4fc7d4b5ddccece52146ad48e079342d93f6f8f F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1947,9 +1947,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 dbd8e2e46cfb2de0ebdbb62cda2fe669df3eda98f5d6112d541f581995b1361d d168f245ecf497368feea4697769930c00420ef47a584904dac85371b61fb78a -R cd533386f7e40127c2a7f7341f982c4d -T +closed d168f245ecf497368feea4697769930c00420ef47a584904dac85371b61fb78a +P fa9d206f904280e3eafc6f4ba6c0c7325948364c62eeeb9f0fdc5825d622ec35 +R 417e8b623ef51e88d5d23ce84cb0214d U drh -Z cd041ad39f6b49ac02cacaab1e4031e1 +Z c96a6f41b9eb32bc9d4646f151818910 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 438edba240..cc4629dc90 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fa9d206f904280e3eafc6f4ba6c0c7325948364c62eeeb9f0fdc5825d622ec35 \ No newline at end of file +7ed2a271e6fcbb5e69a7f3a88d3f45fe6318819c0cc6a0dcc06c3dae5aa1503f \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index a438db5301..62c733bbd4 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -2808,6 +2808,7 @@ SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( Bitmask mAll = 0; int k; + ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pTab->zName)); for(k=0; ka[k].pWLoop->maskSelf; @@ -2830,7 +2831,6 @@ SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( sFrom.nAlloc = 1; memcpy(&sFrom.a[0], pTabItem, sizeof(SrcItem)); sFrom.a[0].fg.jointype = 0; - ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pTab->zName)); pSubWInfo = sqlite3WhereBegin(pParse, &sFrom, pSubWhere, 0, 0, 0, WHERE_RIGHT_JOIN, 0); if( pSubWInfo ){ From 3ac624344d7dae3d4dc30ecb38b950cf49ba000c Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 13 Apr 2022 17:41:03 +0000 Subject: [PATCH 128/259] If the OP_NullRow opcode is given a cursor that has not yet been opened, then go automatically open it to a special pseudo-cursor that allows returns NULL for every column. Used by the new RIGHT JOIN implementation. FossilOrigin-Name: 4526c5d316508093b7f3aeda1ce9d16ceb0be79842015a6d51f28c22b4473ca2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 18 ++++++++++++------ 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 3131341e68..3e4338817a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Move\sthe\sexplain\scomment\sfor\sthe\sRIGHT-JOIN\spost-processing\sloop\sto\sthe\nverify\sbeginning\sof\sthe\sloop\s-\sto\smake\sthe\sstart\sof\sthe\sloop\sclearer\sto\nhuman\sbytecode\sreaders. -D 2022-04-13T16:46:35.568 +C If\sthe\sOP_NullRow\sopcode\sis\sgiven\sa\scursor\sthat\shas\snot\syet\sbeen\sopened,\nthen\sgo\sautomatically\sopen\sit\sto\sa\sspecial\spseudo-cursor\sthat\sallows\sreturns\nNULL\sfor\severy\scolumn.\s\sUsed\sby\sthe\snew\sRIGHT\sJOIN\simplementation. +D 2022-04-13T17:41:03.247 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -624,7 +624,7 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c 871c55b7eea607980465a3e9d5c1ba1af679789be5e9181af11ed2ff9ffd420f +F src/vdbe.c 6d0790dd22255dc9a1f3fa89131c78aa4b38ec541688a3d722e7646b6b0ed792 F src/vdbe.h 89f5edb1422c8783a0b29db836e409876f2b3e847f78e2b21b1fbcc48a93f85f F src/vdbeInt.h 5f3d0abcf30c2b7a6672ad4386f18be0fca9c9b2cefe18f85a2e3df74f2613bf F src/vdbeapi.c 354c893f1500cf524cc45c32879b9c68893a28b77e3442c24668d6afe4236217 @@ -1947,8 +1947,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 fa9d206f904280e3eafc6f4ba6c0c7325948364c62eeeb9f0fdc5825d622ec35 -R 417e8b623ef51e88d5d23ce84cb0214d +P 7ed2a271e6fcbb5e69a7f3a88d3f45fe6318819c0cc6a0dcc06c3dae5aa1503f +R fa7cb92eb7963a9424648d6e8405a1a6 U drh -Z c96a6f41b9eb32bc9d4646f151818910 +Z 03080d3b275bf11b0b4b2d9c4c59a668 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index cc4629dc90..eef2da0ec5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7ed2a271e6fcbb5e69a7f3a88d3f45fe6318819c0cc6a0dcc06c3dae5aa1503f \ No newline at end of file +4526c5d316508093b7f3aeda1ce9d16ceb0be79842015a6d51f28c22b4473ca2 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 45a47756eb..34c3dd1fd4 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2714,10 +2714,9 @@ op_column_restart: if( pC->cacheStatus!=p->cacheCtr ){ /*OPTIMIZATION-IF-FALSE*/ if( pC->nullRow ){ - if( pC->eCurType==CURTYPE_PSEUDO ){ + if( pC->eCurType==CURTYPE_PSEUDO && pC->seekResult>0 ){ /* For the special case of as pseudo-cursor, the seekResult field ** identifies the register that holds the record */ - assert( pC->seekResult>0 ); pReg = &aMem[pC->seekResult]; assert( pReg->flags & MEM_Blob ); assert( memIsValid(pReg) ); @@ -5802,16 +5801,23 @@ case OP_Rowid: { /* out2 */ ** that occur while the cursor is on the null row will always ** write a NULL. ** -** Or, if P1 is a Pseudo-Cursor (a cursor opened using OP_OpenPseudo) -** just reset the cache for that cursor. This causes the row of -** content held by the pseudo-cursor to be reparsed. +** If cursor P1 is not previously opened, open it now to a special +** pseudo-cursor that always returns NULL for every column. */ case OP_NullRow: { VdbeCursor *pC; assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; - assert( pC!=0 ); + if( pC==0 ){ + /* If the cursor is not already open, create a special kind of + ** pseudo-cursor that always gives null rows. */ + pC = allocateCursor(p, pOp->p1, 1, CURTYPE_PSEUDO); + if( pC==0 ) goto no_mem; + pC->seekResult = 0; + pC->isTable = 1; + pC->uc.pCursor = sqlite3BtreeFakeValidCursor(); + } pC->nullRow = 1; pC->cacheStatus = CACHE_STALE; if( pC->eCurType==CURTYPE_BTREE ){ From 7c96039492926b4b62e0a2c4e0208e42c0eb06b4 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 13 Apr 2022 18:20:23 +0000 Subject: [PATCH 129/259] Fix an assert() in OP_Column so that it accounts for the new type of pseudo-cursor that always returns NULL for any column. FossilOrigin-Name: 371ddc97bef8e0d88ad965f00d27e010880174312ea36c4f1165dcf08441f40a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 3 ++- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 3e4338817a..634d236a9a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C If\sthe\sOP_NullRow\sopcode\sis\sgiven\sa\scursor\sthat\shas\snot\syet\sbeen\sopened,\nthen\sgo\sautomatically\sopen\sit\sto\sa\sspecial\spseudo-cursor\sthat\sallows\sreturns\nNULL\sfor\severy\scolumn.\s\sUsed\sby\sthe\snew\sRIGHT\sJOIN\simplementation. -D 2022-04-13T17:41:03.247 +C Fix\san\sassert()\sin\sOP_Column\sso\sthat\sit\saccounts\sfor\sthe\snew\stype\sof\npseudo-cursor\sthat\salways\sreturns\sNULL\sfor\sany\scolumn. +D 2022-04-13T18:20:23.344 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -624,7 +624,7 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c 6d0790dd22255dc9a1f3fa89131c78aa4b38ec541688a3d722e7646b6b0ed792 +F src/vdbe.c 18da83475f1df9dd3c5b9f0a203d21ce07cd515328d93af9d7fde26db7dbe6fd F src/vdbe.h 89f5edb1422c8783a0b29db836e409876f2b3e847f78e2b21b1fbcc48a93f85f F src/vdbeInt.h 5f3d0abcf30c2b7a6672ad4386f18be0fca9c9b2cefe18f85a2e3df74f2613bf F src/vdbeapi.c 354c893f1500cf524cc45c32879b9c68893a28b77e3442c24668d6afe4236217 @@ -1947,8 +1947,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 7ed2a271e6fcbb5e69a7f3a88d3f45fe6318819c0cc6a0dcc06c3dae5aa1503f -R fa7cb92eb7963a9424648d6e8405a1a6 +P 4526c5d316508093b7f3aeda1ce9d16ceb0be79842015a6d51f28c22b4473ca2 +R 524bc4951ee53f483cb0759d1623e373 U drh -Z 03080d3b275bf11b0b4b2d9c4c59a668 +Z 801ae4a0d64a340d177c53f7000f155f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index eef2da0ec5..de3a0225fe 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4526c5d316508093b7f3aeda1ce9d16ceb0be79842015a6d51f28c22b4473ca2 \ No newline at end of file +371ddc97bef8e0d88ad965f00d27e010880174312ea36c4f1165dcf08441f40a \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 34c3dd1fd4..19a8c1b36c 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2705,7 +2705,8 @@ case OP_Column: { op_column_restart: assert( pC!=0 ); - assert( p2<(u32)pC->nField ); + assert( p2<(u32)pC->nField + || (pC->eCurType==CURTYPE_PSEUDO && pC->seekResult==0) ); aOffset = pC->aOffset; assert( aOffset==pC->aType+pC->nField ); assert( pC->eCurType!=CURTYPE_VTAB ); From b60d1fbe8e49bfa04ab4f63d8131cc4c9040d25e Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 13 Apr 2022 18:32:04 +0000 Subject: [PATCH 130/259] Make the sqlite3TreeViewSrcList() routine a no-op if called with a NULL SrcList object. FossilOrigin-Name: 185d2720e7775e3060a1647353c10aada435244db53a0732ee786788a6ecae3f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/treeview.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 634d236a9a..e1bb3d3538 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sassert()\sin\sOP_Column\sso\sthat\sit\saccounts\sfor\sthe\snew\stype\sof\npseudo-cursor\sthat\salways\sreturns\sNULL\sfor\sany\scolumn. -D 2022-04-13T18:20:23.344 +C Make\sthe\ssqlite3TreeViewSrcList()\sroutine\sa\sno-op\sif\scalled\swith\sa\nNULL\sSrcList\sobject. +D 2022-04-13T18:32:04.638 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -617,7 +617,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98 -F src/treeview.c e143d3def263f304066e87628eebc7c2921a12245541f09b61d0e45009091474 +F src/treeview.c cf275af590023b0288ed02012b293a9f73869299e4259ec9f070b0ccb3a55f55 F src/trigger.c 372ada38f667c6823a3db15749eb668338e65c793394e55a37e56a489f2d1b55 F src/update.c 2cfaded82ca80ff56afb8c3ae5e88284e0824bfd86119827cc22481959f96f92 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 @@ -1947,8 +1947,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 4526c5d316508093b7f3aeda1ce9d16ceb0be79842015a6d51f28c22b4473ca2 -R 524bc4951ee53f483cb0759d1623e373 +P 371ddc97bef8e0d88ad965f00d27e010880174312ea36c4f1165dcf08441f40a +R 4e8aae8397ba409b4ce8af13c47b6cbd U drh -Z 801ae4a0d64a340d177c53f7000f155f +Z 074a8672cb0be9c5d7de4b7d70546458 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index de3a0225fe..02dac6271a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -371ddc97bef8e0d88ad965f00d27e010880174312ea36c4f1165dcf08441f40a \ No newline at end of file +185d2720e7775e3060a1647353c10aada435244db53a0732ee786788a6ecae3f \ No newline at end of file diff --git a/src/treeview.c b/src/treeview.c index 4593161905..0a3f942677 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -133,6 +133,7 @@ void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){ */ void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ int i; + if( pSrc==0 ) return; for(i=0; inSrc; i++){ const SrcItem *pItem = &pSrc->a[i]; StrAccum x; From 95b1036e9a06613201f723f231689fe9639f5769 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 13 Apr 2022 19:00:57 +0000 Subject: [PATCH 131/259] Fix a harmless (false-positive) unused variable compiler warning on MSVC. FossilOrigin-Name: 63b04c63de680261a0d3eaf27154a1e8e77e3e166c3f2dbaea985603991c74f7 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 13 ++++++------- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index e1bb3d3538..f41fb698fc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sthe\ssqlite3TreeViewSrcList()\sroutine\sa\sno-op\sif\scalled\swith\sa\nNULL\sSrcList\sobject. -D 2022-04-13T18:32:04.638 +C Fix\sa\sharmless\s(false-positive)\sunused\svariable\scompiler\swarning\son\sMSVC. +D 2022-04-13T19:00:57.522 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -624,7 +624,7 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c 18da83475f1df9dd3c5b9f0a203d21ce07cd515328d93af9d7fde26db7dbe6fd +F src/vdbe.c 3ad67541cde0b63a096d2e6bb8257d4b6018c997999d67a5a984f4cec304e633 F src/vdbe.h 89f5edb1422c8783a0b29db836e409876f2b3e847f78e2b21b1fbcc48a93f85f F src/vdbeInt.h 5f3d0abcf30c2b7a6672ad4386f18be0fca9c9b2cefe18f85a2e3df74f2613bf F src/vdbeapi.c 354c893f1500cf524cc45c32879b9c68893a28b77e3442c24668d6afe4236217 @@ -1947,8 +1947,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 371ddc97bef8e0d88ad965f00d27e010880174312ea36c4f1165dcf08441f40a -R 4e8aae8397ba409b4ce8af13c47b6cbd +P 185d2720e7775e3060a1647353c10aada435244db53a0732ee786788a6ecae3f +R fcfe56f1e9aa9c1e774f8b3416754aa1 U drh -Z 074a8672cb0be9c5d7de4b7d70546458 +Z a0e8c96182df0ebcaf49be445aec0e16 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 02dac6271a..066704d872 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -185d2720e7775e3060a1647353c10aada435244db53a0732ee786788a6ecae3f \ No newline at end of file +63b04c63de680261a0d3eaf27154a1e8e77e3e166c3f2dbaea985603991c74f7 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 19a8c1b36c..1cc0a422c3 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4994,15 +4994,14 @@ case OP_Found: { /* jump, in3 */ #ifdef SQLITE_DEBUG pC->seekOp = pOp->opcode; #endif - pIn3 = &aMem[pOp->p3]; + r.aMem = &aMem[pOp->p3]; assert( pC->eCurType==CURTYPE_BTREE ); assert( pC->uc.pCursor!=0 ); assert( pC->isTable==0 ); - if( pOp->p4.i>0 ){ + r.nField = (u16)pOp->p4.i; + if( r.nField>0 ){ /* Key values in an array of registers */ - r.nField = (u16)pOp->p4.i; r.pKeyInfo = pC->pKeyInfo; - r.aMem = pIn3; r.default_rc = 0; #ifdef SQLITE_DEBUG for(ii=0; iiuc.pCursor, &r, &pC->seekResult); }else{ /* Composite key generated by OP_MakeRecord */ - assert( pIn3->flags & MEM_Blob ); + assert( r.aMem->flags & MEM_Blob ); assert( pOp->opcode!=OP_NoConflict ); - rc = ExpandBlob(pIn3); + rc = ExpandBlob(r.aMem); assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); if( rc ) goto no_mem; pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo); if( pIdxKey==0 ) goto no_mem; - sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey); + sqlite3VdbeRecordUnpack(pC->pKeyInfo, r.aMem->n, r.aMem->z, pIdxKey); pIdxKey->default_rc = 0; rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, pIdxKey, &pC->seekResult); sqlite3DbFreeNN(db, pIdxKey); From eab6c125bd9e68867cee6ee538e0d305e6f59ab3 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 14 Apr 2022 12:59:25 +0000 Subject: [PATCH 132/259] Fix assert() statements associated with artifical null-value cursors created by RIGHT JOIN. FossilOrigin-Name: f5bce5f152259767497ae6826c558003822d976b3f35f4d74edee59a3490efb2 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/vdbe.c | 4 ++-- src/vdbeInt.h | 5 +++++ src/vdbeaux.c | 2 +- 5 files changed, 17 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index f41fb698fc..5f89ed4c4b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sharmless\s(false-positive)\sunused\svariable\scompiler\swarning\son\sMSVC. -D 2022-04-13T19:00:57.522 +C Fix\sassert()\sstatements\sassociated\swith\sartifical\snull-value\scursors\ncreated\sby\sRIGHT\sJOIN. +D 2022-04-14T12:59:25.672 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -624,11 +624,11 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c 3ad67541cde0b63a096d2e6bb8257d4b6018c997999d67a5a984f4cec304e633 +F src/vdbe.c df6107a37d3ee11ac94bb847aa8817894dd3a279bfc8b928c36f1b697201e3db F src/vdbe.h 89f5edb1422c8783a0b29db836e409876f2b3e847f78e2b21b1fbcc48a93f85f -F src/vdbeInt.h 5f3d0abcf30c2b7a6672ad4386f18be0fca9c9b2cefe18f85a2e3df74f2613bf +F src/vdbeInt.h ef43f7fdc5fde29fc3fd29c506c12830f366178fdb4edbbf0cbc3dfbd1278b5f F src/vdbeapi.c 354c893f1500cf524cc45c32879b9c68893a28b77e3442c24668d6afe4236217 -F src/vdbeaux.c baafd56664ccca4cf361a48b912f7ff37f95ee19aaf7cada420ce2ca73396833 +F src/vdbeaux.c c1718405a9ce07d84adc5bc36e17016f73170de1015d818bc82ebfdf76d88bad F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 7189090b72baa025f945a1ac8c61ee420c645254476e8a191d555db76dfea5d4 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 @@ -1947,8 +1947,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 185d2720e7775e3060a1647353c10aada435244db53a0732ee786788a6ecae3f -R fcfe56f1e9aa9c1e774f8b3416754aa1 +P 63b04c63de680261a0d3eaf27154a1e8e77e3e166c3f2dbaea985603991c74f7 +R 9bf8e7ee771780f4b1d0790385799db1 U drh -Z a0e8c96182df0ebcaf49be445aec0e16 +Z d30e0e99e2bb4c65405c63a835afccc6 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 066704d872..9e67c5cbd0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -63b04c63de680261a0d3eaf27154a1e8e77e3e166c3f2dbaea985603991c74f7 \ No newline at end of file +f5bce5f152259767497ae6826c558003822d976b3f35f4d74edee59a3490efb2 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 1cc0a422c3..5f018f200e 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -6264,9 +6264,9 @@ case OP_IdxRowid: { /* out2 */ assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); - assert( pC->eCurType==CURTYPE_BTREE ); + assert( pC->eCurType==CURTYPE_BTREE || IsNullCursor(pC) ); assert( pC->uc.pCursor!=0 ); - assert( pC->isTable==0 ); + assert( pC->isTable!=0 || IsNullCursor(pC) ); assert( pC->deferredMoveto==0 ); assert( !pC->nullRow || pOp->opcode==OP_IdxRowid ); diff --git a/src/vdbeInt.h b/src/vdbeInt.h index b07aee0c05..2a2e403173 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -134,6 +134,11 @@ struct VdbeCursor { u32 aType[1]; /* Type values record decode. MUST BE LAST */ }; +/* Return true if P is a null-only cursor +*/ +#define IsNullCursor(P) \ + ((P)->eCurType==CURTYPE_PSEUDO && (P)->nullRow && (P)->seekResult==0) + /* ** A value for VdbeCursor.cacheStatus that means the cache is always invalid. diff --git a/src/vdbeaux.c b/src/vdbeaux.c index cb2433c2cd..f598b0d545 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -3549,7 +3549,7 @@ int SQLITE_NOINLINE sqlite3VdbeHandleMovedCursor(VdbeCursor *p){ ** if need be. Return any I/O error from the restore operation. */ int sqlite3VdbeCursorRestore(VdbeCursor *p){ - assert( p->eCurType==CURTYPE_BTREE ); + assert( p->eCurType==CURTYPE_BTREE || IsNullCursor(p) ); if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){ return sqlite3VdbeHandleMovedCursor(p); } From c504f677b6378e7727dca82ec33ea4e6e97ea5cf Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 14 Apr 2022 14:19:23 +0000 Subject: [PATCH 133/259] Previous check-in accidentally inverted a test on an assert(). Fix that. FossilOrigin-Name: 5ec4f806c569428851b6f0159451aa3ed66b3bc61a845fd7c543cffb694b882d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 5f89ed4c4b..da78658373 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sassert()\sstatements\sassociated\swith\sartifical\snull-value\scursors\ncreated\sby\sRIGHT\sJOIN. -D 2022-04-14T12:59:25.672 +C Previous\scheck-in\saccidentally\sinverted\sa\stest\son\san\sassert().\s\sFix\sthat. +D 2022-04-14T14:19:23.735 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -624,7 +624,7 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c df6107a37d3ee11ac94bb847aa8817894dd3a279bfc8b928c36f1b697201e3db +F src/vdbe.c 85a13807359cdfd9ea94140c16d2ad9d64da99c9287eb8dda84743779fd7e14e F src/vdbe.h 89f5edb1422c8783a0b29db836e409876f2b3e847f78e2b21b1fbcc48a93f85f F src/vdbeInt.h ef43f7fdc5fde29fc3fd29c506c12830f366178fdb4edbbf0cbc3dfbd1278b5f F src/vdbeapi.c 354c893f1500cf524cc45c32879b9c68893a28b77e3442c24668d6afe4236217 @@ -1947,8 +1947,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 63b04c63de680261a0d3eaf27154a1e8e77e3e166c3f2dbaea985603991c74f7 -R 9bf8e7ee771780f4b1d0790385799db1 +P f5bce5f152259767497ae6826c558003822d976b3f35f4d74edee59a3490efb2 +R cf81eb9addb3ddebf19d1624814ed06a U drh -Z d30e0e99e2bb4c65405c63a835afccc6 +Z fb9cf63c0aab3de6d9e384a52fd24a3e # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9e67c5cbd0..fefaa8e5e7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f5bce5f152259767497ae6826c558003822d976b3f35f4d74edee59a3490efb2 \ No newline at end of file +5ec4f806c569428851b6f0159451aa3ed66b3bc61a845fd7c543cffb694b882d \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 5f018f200e..81f552998a 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -6266,7 +6266,7 @@ case OP_IdxRowid: { /* out2 */ assert( pC!=0 ); assert( pC->eCurType==CURTYPE_BTREE || IsNullCursor(pC) ); assert( pC->uc.pCursor!=0 ); - assert( pC->isTable!=0 || IsNullCursor(pC) ); + assert( pC->isTable==0 || IsNullCursor(pC) ); assert( pC->deferredMoveto==0 ); assert( !pC->nullRow || pOp->opcode==OP_IdxRowid ); From d345dcf39a4bdb0d2550e165b671c18676ba9ea1 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 14 Apr 2022 14:58:50 +0000 Subject: [PATCH 134/259] Disable autoindexing for the RIGHT JOIN loop. FossilOrigin-Name: 402a89e33e39b00352dc9fb3301d03c6f75d8bb5c2ad540cd22506bff10b4d85 --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/where.c | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 53be0b2896..ac54b65451 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Adjust\sassert()\sstatements\sto\saccount\sfor\sthe\snew\salways-NULL\scursor\stype\nadded\sby\s[4526c5d316508093]. -D 2022-04-14T14:40:29.990 +C Disable\sautoindexing\sfor\sthe\sRIGHT\sJOIN\sloop. +D 2022-04-14T14:58:50.589 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -639,7 +639,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c 793d09ef0d824efb953cdaff59102dcdd5390f8c59d1d5119ddfd26dcf5cd957 +F src/where.c 0db7dcbdacb3568f6b45aa419c37eaf0e25538bba15140acee74caee8b2e77fd F src/whereInt.h ea1e4b6639c4c32246f4c54b733143df76109894adf08bedee4f3999ece62c2d F src/wherecode.c 34e4c445371b0ac19d234c5b454fa04d650417f10a702331ca590dc870254c41 F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 @@ -1947,9 +1947,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 63b04c63de680261a0d3eaf27154a1e8e77e3e166c3f2dbaea985603991c74f7 5ec4f806c569428851b6f0159451aa3ed66b3bc61a845fd7c543cffb694b882d -R cf81eb9addb3ddebf19d1624814ed06a -T +closed 5ec4f806c569428851b6f0159451aa3ed66b3bc61a845fd7c543cffb694b882d +P 7822faa48a058c0b0313b9241d290153fbe74ab84f58369a70014118a9085d1d +R 236e005565a5c9ed4ac4494c6199358f U drh -Z 3009f9859b3841a2479bfb7b97dc45b2 +Z a9122a09b9d099ad3181af175e428792 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7aa1e77e27..1f348c82af 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7822faa48a058c0b0313b9241d290153fbe74ab84f58369a70014118a9085d1d \ No newline at end of file +402a89e33e39b00352dc9fb3301d03c6f75d8bb5c2ad540cd22506bff10b4d85 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 1ce569d37b..dca78e11b9 100644 --- a/src/where.c +++ b/src/where.c @@ -3317,7 +3317,7 @@ static int whereLoopAddBtree( #ifndef SQLITE_OMIT_AUTOMATIC_INDEX /* Automatic indexes */ if( !pBuilder->pOrSet /* Not part of an OR optimization */ - && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 + && (pWInfo->wctrlFlags & (WHERE_RIGHT_JOIN|WHERE_OR_SUBCLAUSE))==0 && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0 && !pSrc->fg.isIndexedBy /* Has no INDEXED BY clause */ && !pSrc->fg.notIndexed /* Has no NOT INDEXED clause */ From 37f5584a2fc62560333d86a533d6aee0c4589d6a Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 14 Apr 2022 15:55:34 +0000 Subject: [PATCH 135/259] Adjust the output formatting of bytecode listings so that subroutines used to implement subqueries are indented one level. FossilOrigin-Name: 079b7b125206fb295720612f4853a5b786ec431ab595d35407195844779c149d --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index ac54b65451..119a0315e0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disable\sautoindexing\sfor\sthe\sRIGHT\sJOIN\sloop. -D 2022-04-14T14:58:50.589 +C Adjust\sthe\soutput\sformatting\sof\sbytecode\slistings\sso\sthat\ssubroutines\sused\nto\simplement\ssubqueries\sare\sindented\sone\slevel. +D 2022-04-14T15:55:34.630 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -503,7 +503,7 @@ F src/date.c 15082566229d4b1e5f24fdb490bf9bcc68824b911d70e3573ef075a1b9e2d26f F src/dbpage.c 90661a87e1db8bfbc8d2ebbdcd3749651ddb287c555c07a28fb17c7c591ffb68 F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d F src/delete.c a8e844af211a48b13b5b358be77a12c860c6a557c21990ad51a548e2536500ce -F src/expr.c d5be48b7f3f58026a7e8386ad8cb65c3550bbec79b0fe053a69594a81a5b20e9 +F src/expr.c e33323313316fc7544fe4f0ed2a089ff3f8e1fc402e7fa77a3db78cf97eb7958 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 94927f9b46d72a9cb858c208febf04ceb0a3270c5fa5fd0b7f436cf16e09f72a F src/func.c a3407a6fbb0d4088d8d502e46f0ace63e0aeae7467ae23a9ca9815bbf9239761 @@ -1947,8 +1947,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 7822faa48a058c0b0313b9241d290153fbe74ab84f58369a70014118a9085d1d -R 236e005565a5c9ed4ac4494c6199358f +P 402a89e33e39b00352dc9fb3301d03c6f75d8bb5c2ad540cd22506bff10b4d85 +R 36bb3f178ff0bc5642fa30a4c8645d1c U drh -Z a9122a09b9d099ad3181af175e428792 +Z c6740140f49ce0f64d3f4ac433c56e97 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 1f348c82af..0d8f0623a4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -402a89e33e39b00352dc9fb3301d03c6f75d8bb5c2ad540cd22506bff10b4d85 \ No newline at end of file +079b7b125206fb295720612f4853a5b786ec431ab595d35407195844779c149d \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index fcef002f24..20adea5dca 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3312,8 +3312,8 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ assert( ExprUseYSub(pExpr) ); assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn || pParse->nErr ); - sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, 0, - pExpr->y.sub.iAddr-1); + sqlite3VdbeAddOp2(v, OP_Return, pExpr->y.sub.regReturn, + pExpr->y.sub.iAddr); sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1); sqlite3ClearTempRegCache(pParse); return rReg; From 2c31c00bfa7001f9d775a5d137da51c5b2ce78f4 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 14 Apr 2022 16:34:07 +0000 Subject: [PATCH 136/259] Rerun the subroutines that compute row-values if necessary from within the RIGHT JOIN body subroutine. FossilOrigin-Name: 9b9038bcd0ab5c4f01661456635526cef764f854ff24018a5e6e43825d07eb59 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/expr.c | 12 +++++++----- src/sqliteInt.h | 1 + src/where.c | 2 ++ src/wherecode.c | 2 ++ 6 files changed, 22 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 119a0315e0..1ed80e82f7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Adjust\sthe\soutput\sformatting\sof\sbytecode\slistings\sso\sthat\ssubroutines\sused\nto\simplement\ssubqueries\sare\sindented\sone\slevel. -D 2022-04-14T15:55:34.630 +C Rerun\sthe\ssubroutines\sthat\scompute\srow-values\sif\snecessary\sfrom\swithin\nthe\sRIGHT\sJOIN\sbody\ssubroutine. +D 2022-04-14T16:34:07.896 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -503,7 +503,7 @@ F src/date.c 15082566229d4b1e5f24fdb490bf9bcc68824b911d70e3573ef075a1b9e2d26f F src/dbpage.c 90661a87e1db8bfbc8d2ebbdcd3749651ddb287c555c07a28fb17c7c591ffb68 F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d F src/delete.c a8e844af211a48b13b5b358be77a12c860c6a557c21990ad51a548e2536500ce -F src/expr.c e33323313316fc7544fe4f0ed2a089ff3f8e1fc402e7fa77a3db78cf97eb7958 +F src/expr.c f4020ee000cf0d7d891456f09465bc121773a34e2ccb7bcfc18964a470679d08 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 94927f9b46d72a9cb858c208febf04ceb0a3270c5fa5fd0b7f436cf16e09f72a F src/func.c a3407a6fbb0d4088d8d502e46f0ace63e0aeae7467ae23a9ca9815bbf9239761 @@ -557,7 +557,7 @@ F src/shell.c.in eb7f10d5e2c47bd014d92ec5db1def21fcc1ed56ffaaa4ee715b6c37c370b47 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h cfdfe65eeb87d3fa8319481fb541586f49e93d5715e9f487ae83362844a9abc7 +F src/sqliteInt.h ce8d798a966d6cd373fe12a2a5a90c9e6d5c8f2d98cbed4cd3efabd91b3f196b F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -639,9 +639,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c 0db7dcbdacb3568f6b45aa419c37eaf0e25538bba15140acee74caee8b2e77fd +F src/where.c 963c06826218535bcebc8a8c41dcb2a8abf3cd340022d5b2cb503e7ce328cc47 F src/whereInt.h ea1e4b6639c4c32246f4c54b733143df76109894adf08bedee4f3999ece62c2d -F src/wherecode.c 34e4c445371b0ac19d234c5b454fa04d650417f10a702331ca590dc870254c41 +F src/wherecode.c cb747d628e8fdc0396529c07be9c772c2978016a723eba9c3329f8ef5e4411f1 F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 F src/window.c 42a71595263dbd8ef8248218e4fc7d4b5ddccece52146ad48e079342d93f6f8f F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1947,8 +1947,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 402a89e33e39b00352dc9fb3301d03c6f75d8bb5c2ad540cd22506bff10b4d85 -R 36bb3f178ff0bc5642fa30a4c8645d1c +P 079b7b125206fb295720612f4853a5b786ec431ab595d35407195844779c149d +R af437a21d494eabd20c43af2912355e1 U drh -Z c6740140f49ce0f64d3f4ac433c56e97 +Z 9fe409698cfd512a3fa64bb15b8f5185 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0d8f0623a4..7303907ef2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -079b7b125206fb295720612f4853a5b786ec431ab595d35407195844779c149d \ No newline at end of file +9b9038bcd0ab5c4f01661456635526cef764f854ff24018a5e6e43825d07eb59 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 20adea5dca..79a79ed05e 100644 --- a/src/expr.c +++ b/src/expr.c @@ -4500,16 +4500,18 @@ expr_code_doover: } case TK_SELECT_COLUMN: { int n; - if( pExpr->pLeft->iTable==0 ){ - pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft); + Expr *pLeft = pExpr->pLeft; + if( pLeft->iTable==0 || pParse->withinRJSubrtn > pLeft->op2 ){ + pLeft->iTable = sqlite3CodeSubselect(pParse, pLeft); + pLeft->op2 = pParse->withinRJSubrtn; } - assert( pExpr->pLeft->op==TK_SELECT || pExpr->pLeft->op==TK_ERROR ); - n = sqlite3ExprVectorSize(pExpr->pLeft); + assert( pLeft->op==TK_SELECT || pLeft->op==TK_ERROR ); + n = sqlite3ExprVectorSize(pLeft); if( pExpr->iTable!=n ){ sqlite3ErrorMsg(pParse, "%d columns assigned %d values", pExpr->iTable, n); } - return pExpr->pLeft->iTable + pExpr->iColumn; + return pLeft->iTable + pExpr->iColumn; } case TK_IN: { int destIfFalse = sqlite3VdbeMakeLabel(pParse); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 330d58fa48..1cd3e75b44 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3570,6 +3570,7 @@ struct Parse { u8 okConstFactor; /* OK to factor out constants */ u8 disableLookaside; /* Number of times lookaside has been disabled */ u8 disableVtab; /* Disable all virtual tables for this parse */ + u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */ #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */ #endif diff --git a/src/where.c b/src/where.c index dca78e11b9..7b37db2158 100644 --- a/src/where.c +++ b/src/where.c @@ -6028,6 +6028,8 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ sqlite3VdbeResolveLabel(v, pLevel->addrCont); pLevel->addrCont = 0; sqlite3VdbeAddOp2(v, OP_Return, pRJ->regReturn, pRJ->addrSubrtn); + assert( pParse->withinRJSubrtn>0 ); + pParse->withinRJSubrtn--; } pLoop = pLevel->pWLoop; if( pLevel->op!=OP_Noop ){ diff --git a/src/wherecode.c b/src/wherecode.c index 62c733bbd4..f08a4c2806 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -2771,6 +2771,8 @@ Bitmask sqlite3WhereCodeOneLoopStart( */ sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pRJ->regReturn); pRJ->addrSubrtn = sqlite3VdbeCurrentAddr(v); + assert( pParse->withinRJSubrtn < 255 ); + pParse->withinRJSubrtn++; } #if WHERETRACE_ENABLED /* 0x20800 */ From d549a702b3b2789156f5697242ea6ae0d1a59b91 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 14 Apr 2022 18:19:06 +0000 Subject: [PATCH 137/259] Check for interrupts and invoke the progress handler following a Gosub opcode, to avoid and recover from infinite subroutine loops. FossilOrigin-Name: 647211e044a5856ceb6bf3e7b78e650fe7d81f8b7bf34568b99b346405ba520c --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 14 +++++++------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 1ed80e82f7..2ea2df5a75 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Rerun\sthe\ssubroutines\sthat\scompute\srow-values\sif\snecessary\sfrom\swithin\nthe\sRIGHT\sJOIN\sbody\ssubroutine. -D 2022-04-14T16:34:07.896 +C Check\sfor\sinterrupts\sand\sinvoke\sthe\sprogress\shandler\sfollowing\sa\sGosub\nopcode,\sto\savoid\sand\srecover\sfrom\sinfinite\ssubroutine\sloops. +D 2022-04-14T18:19:06.650 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -624,7 +624,7 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c 85a13807359cdfd9ea94140c16d2ad9d64da99c9287eb8dda84743779fd7e14e +F src/vdbe.c b72147e70498ad005eece5c6336bfa1b9eaff09a673044eb866df8e402d1f12f F src/vdbe.h 89f5edb1422c8783a0b29db836e409876f2b3e847f78e2b21b1fbcc48a93f85f F src/vdbeInt.h ef43f7fdc5fde29fc3fd29c506c12830f366178fdb4edbbf0cbc3dfbd1278b5f F src/vdbeapi.c 354c893f1500cf524cc45c32879b9c68893a28b77e3442c24668d6afe4236217 @@ -1947,8 +1947,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 079b7b125206fb295720612f4853a5b786ec431ab595d35407195844779c149d -R af437a21d494eabd20c43af2912355e1 +P 9b9038bcd0ab5c4f01661456635526cef764f854ff24018a5e6e43825d07eb59 +R 4462ab5ae008c57419f7b3043a0a5f70 U drh -Z 9fe409698cfd512a3fa64bb15b8f5185 +Z 0cc7c2df08ce35b42a210b10f061249d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7303907ef2..1ba5e38a26 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9b9038bcd0ab5c4f01661456635526cef764f854ff24018a5e6e43825d07eb59 \ No newline at end of file +647211e044a5856ceb6bf3e7b78e650fe7d81f8b7bf34568b99b346405ba520c \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 81f552998a..283151d1fc 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -983,12 +983,7 @@ case OP_Gosub: { /* jump */ pIn1->flags = MEM_Int; pIn1->u.i = (int)(pOp-aOp); REGISTER_TRACE(pOp->p1, pIn1); - - /* Most jump operations do a goto to this spot in order to update - ** the pOp pointer. */ -jump_to_p2: - pOp = &aOp[pOp->p2 - 1]; - break; + goto jump_to_p2_and_check_for_interrupt; } /* Opcode: Return P1 P2 P3 * * @@ -1039,7 +1034,12 @@ case OP_InitCoroutine: { /* jump */ assert( !VdbeMemDynamic(pOut) ); pOut->u.i = pOp->p3 - 1; pOut->flags = MEM_Int; - if( pOp->p2 ) goto jump_to_p2; + if( pOp->p2==0 ) break; + + /* Most jump operations do a goto to this spot in order to update + ** the pOp pointer. */ +jump_to_p2: + pOp = &aOp[pOp->p2 - 1]; break; } From 79f60034ee5f64e55f1aba9ee180f3b27ab1a931 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 14 Apr 2022 19:05:17 +0000 Subject: [PATCH 138/259] Another instance of indenting a subroutine. FossilOrigin-Name: 73f4036b04798660b30e540cbab69420078df9fb62a6a39944e078c36272f905 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 2ea2df5a75..7681e2c0af 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Check\sfor\sinterrupts\sand\sinvoke\sthe\sprogress\shandler\sfollowing\sa\sGosub\nopcode,\sto\savoid\sand\srecover\sfrom\sinfinite\ssubroutine\sloops. -D 2022-04-14T18:19:06.650 +C Another\sinstance\sof\sindenting\sa\ssubroutine. +D 2022-04-14T19:05:17.456 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -503,7 +503,7 @@ F src/date.c 15082566229d4b1e5f24fdb490bf9bcc68824b911d70e3573ef075a1b9e2d26f F src/dbpage.c 90661a87e1db8bfbc8d2ebbdcd3749651ddb287c555c07a28fb17c7c591ffb68 F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d F src/delete.c a8e844af211a48b13b5b358be77a12c860c6a557c21990ad51a548e2536500ce -F src/expr.c f4020ee000cf0d7d891456f09465bc121773a34e2ccb7bcfc18964a470679d08 +F src/expr.c 6cf41bfa55c4c65b9d30a8251070bf90bc799a25699cfe5fbd15f9e497913b6d F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 94927f9b46d72a9cb858c208febf04ceb0a3270c5fa5fd0b7f436cf16e09f72a F src/func.c a3407a6fbb0d4088d8d502e46f0ace63e0aeae7467ae23a9ca9815bbf9239761 @@ -1947,8 +1947,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 9b9038bcd0ab5c4f01661456635526cef764f854ff24018a5e6e43825d07eb59 -R 4462ab5ae008c57419f7b3043a0a5f70 +P 647211e044a5856ceb6bf3e7b78e650fe7d81f8b7bf34568b99b346405ba520c +R 2197645c7a941ac2357190e97207d106 U drh -Z 0cc7c2df08ce35b42a210b10f061249d +Z e29940f759984b818be8f8538ce00e8e # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 1ba5e38a26..fdb88c42da 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -647211e044a5856ceb6bf3e7b78e650fe7d81f8b7bf34568b99b346405ba520c \ No newline at end of file +73f4036b04798660b30e540cbab69420078df9fb62a6a39944e078c36272f905 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 79a79ed05e..e6d7f9e69e 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3181,8 +3181,8 @@ void sqlite3CodeRhsOfIN( assert( ExprUseYSub(pExpr) ); assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn || pParse->nErr ); - sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, 0, - pExpr->y.sub.iAddr-1); + sqlite3VdbeAddOp2(v, OP_Return, pExpr->y.sub.regReturn, + pExpr->y.sub.iAddr); sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1); sqlite3ClearTempRegCache(pParse); } From b3ebf3043faaf96f0042dc0bce1876efc81c52ad Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 14 Apr 2022 19:48:32 +0000 Subject: [PATCH 139/259] Cherry pick subroutine indentation improvements and the hardening of OP_Gosub from the right-join branch back into trunk. FossilOrigin-Name: 12645f100d902690630a2925674aedbb01d41a53426a26a2f56de5b8fdec955f --- manifest | 17 ++++++++++------- manifest.uuid | 2 +- src/expr.c | 8 ++++---- src/vdbe.c | 14 +++++++------- 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 85b801ffe8..917b78da94 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sassert()\sin\sbtree.c\sthat\smight\snot\sbe\strue\sfor\sa\scorrupt\sdatabase\sfile. -D 2022-04-13T10:49:50.291 +C Cherry\spick\ssubroutine\sindentation\simprovements\sand\sthe\shardening\sof\nOP_Gosub\sfrom\sthe\sright-join\sbranch\sback\sinto\strunk. +D 2022-04-14T19:48:32.540 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -503,7 +503,7 @@ F src/date.c 15082566229d4b1e5f24fdb490bf9bcc68824b911d70e3573ef075a1b9e2d26f F src/dbpage.c 90661a87e1db8bfbc8d2ebbdcd3749651ddb287c555c07a28fb17c7c591ffb68 F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d F src/delete.c a8e844af211a48b13b5b358be77a12c860c6a557c21990ad51a548e2536500ce -F src/expr.c 5e247a8dfabb92e9fd10b78a675dc5d25430433dfd9e316471b4447b548635ba +F src/expr.c 38a25dcba22bc6c9d8614e64624497aab1762911ba88e81fc55f1e67a85ebc16 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 94927f9b46d72a9cb858c208febf04ceb0a3270c5fa5fd0b7f436cf16e09f72a F src/func.c a3407a6fbb0d4088d8d502e46f0ace63e0aeae7467ae23a9ca9815bbf9239761 @@ -624,7 +624,7 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c eefc5a96938cc113a95e36a42b626bf594a7f0b8bb56ae299accbbf015b973cd +F src/vdbe.c 841057c12c1c4e2dcc7e51516a06aabb72d9898ab50484edef162b9218da65b0 F src/vdbe.h 89f5edb1422c8783a0b29db836e409876f2b3e847f78e2b21b1fbcc48a93f85f F src/vdbeInt.h 5f3d0abcf30c2b7a6672ad4386f18be0fca9c9b2cefe18f85a2e3df74f2613bf F src/vdbeapi.c 354c893f1500cf524cc45c32879b9c68893a28b77e3442c24668d6afe4236217 @@ -1945,8 +1945,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P bff4f083eb1c35544988493a5d73a42e646c4250b841f5aae38c2183f0867a0e -R 1538c33a9ca8b52845c5bdc4ee31c46c +P dbd8e2e46cfb2de0ebdbb62cda2fe669df3eda98f5d6112d541f581995b1361d +Q +079b7b125206fb295720612f4853a5b786ec431ab595d35407195844779c149d +Q +647211e044a5856ceb6bf3e7b78e650fe7d81f8b7bf34568b99b346405ba520c +Q +73f4036b04798660b30e540cbab69420078df9fb62a6a39944e078c36272f905 +R a06dd4204ed9dc6148823319b9085bc9 U drh -Z 98d0ff758b95c26883d10f0f51771962 +Z 8357da3748da436bd7d9f47cf82232f1 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2a7d8f8807..2cd2ea1e78 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dbd8e2e46cfb2de0ebdbb62cda2fe669df3eda98f5d6112d541f581995b1361d \ No newline at end of file +12645f100d902690630a2925674aedbb01d41a53426a26a2f56de5b8fdec955f \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 2c00bb498d..78bb0c2ebf 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3181,8 +3181,8 @@ void sqlite3CodeRhsOfIN( assert( ExprUseYSub(pExpr) ); assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn || pParse->nErr ); - sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, 0, - pExpr->y.sub.iAddr-1); + sqlite3VdbeAddOp2(v, OP_Return, pExpr->y.sub.regReturn, + pExpr->y.sub.iAddr); sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1); sqlite3ClearTempRegCache(pParse); } @@ -3312,8 +3312,8 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ assert( ExprUseYSub(pExpr) ); assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn || pParse->nErr ); - sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, 0, - pExpr->y.sub.iAddr-1); + sqlite3VdbeAddOp2(v, OP_Return, pExpr->y.sub.regReturn, + pExpr->y.sub.iAddr); sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1); sqlite3ClearTempRegCache(pParse); return rReg; diff --git a/src/vdbe.c b/src/vdbe.c index 18286c297b..092ccbcd1b 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -983,12 +983,7 @@ case OP_Gosub: { /* jump */ pIn1->flags = MEM_Int; pIn1->u.i = (int)(pOp-aOp); REGISTER_TRACE(pOp->p1, pIn1); - - /* Most jump operations do a goto to this spot in order to update - ** the pOp pointer. */ -jump_to_p2: - pOp = &aOp[pOp->p2 - 1]; - break; + goto jump_to_p2_and_check_for_interrupt; } /* Opcode: Return P1 P2 P3 * * @@ -1035,7 +1030,12 @@ case OP_InitCoroutine: { /* jump */ assert( !VdbeMemDynamic(pOut) ); pOut->u.i = pOp->p3 - 1; pOut->flags = MEM_Int; - if( pOp->p2 ) goto jump_to_p2; + if( pOp->p2==0 ) break; + + /* Most jump operations do a goto to this spot in order to update + ** the pOp pointer. */ +jump_to_p2: + pOp = &aOp[pOp->p2 - 1]; break; } From a51379ad78864ba32b0f7afc5bbde5c774239a5e Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 14 Apr 2022 20:43:22 +0000 Subject: [PATCH 140/259] Record the three known big issues with the current RIGHT JOIN design in the join8 test module, with tests that deliberately fail in order to remind us to fix the issues. FossilOrigin-Name: 2c4ee723f4d0591d09776adfb82246bfa89153ab390b8b3f1878d1cdc43d68c8 --- manifest | 12 +++++------ manifest.uuid | 2 +- test/join8.test | 57 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 7681e2c0af..5a00ef8c06 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Another\sinstance\sof\sindenting\sa\ssubroutine. -D 2022-04-14T19:05:17.456 +C Record\sthe\sthree\sknown\sbig\sissues\swith\sthe\scurrent\sRIGHT\sJOIN\sdesign\sin\nthe\sjoin8\stest\smodule,\swith\stests\sthat\sdeliberately\sfail\sin\sorder\sto\sremind\nus\sto\sfix\sthe\sissues. +D 2022-04-14T20:43:22.638 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1147,7 +1147,7 @@ F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test c4df54e2e204d7f1417bfbdd21ca324b4b07415c647595cc47798eacfddc96d3 F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c F test/join7.test e5c9b1b729d7e1d0b4195e99833e0ff0cf2d88e7fdd32b49af1044f4c76f72d9 -F test/join8.test 72248c33b44f8fc8614c739eff176fd8e18ffab04896b9ce6fd7933854dd7d25 +F test/join8.test 9731b16dbb4309a980ba4adcb4ec31277626230300f819296ffc753c564b2011 F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -1947,8 +1947,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 647211e044a5856ceb6bf3e7b78e650fe7d81f8b7bf34568b99b346405ba520c -R 2197645c7a941ac2357190e97207d106 +P 73f4036b04798660b30e540cbab69420078df9fb62a6a39944e078c36272f905 +R 2147cfd4b343bafdc07bef52bfee2ef0 U drh -Z e29940f759984b818be8f8538ce00e8e +Z 5c1d0d9c07677bde5075ec99ede43a74 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index fdb88c42da..7a8d3db95f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -73f4036b04798660b30e540cbab69420078df9fb62a6a39944e078c36272f905 \ No newline at end of file +2c4ee723f4d0591d09776adfb82246bfa89153ab390b8b3f1878d1cdc43d68c8 \ No newline at end of file diff --git a/test/join8.test b/test/join8.test index 0854d97292..bd80c96ded 100644 --- a/test/join8.test +++ b/test/join8.test @@ -21,4 +21,61 @@ do_execsql_test join8-10 { CREATE INDEX t2x ON t2(x); SELECT avg(DISTINCT b) FROM (SELECT * FROM t2 LEFT RIGHT JOIN t1 ON c); } {NULL} + +# Pending issue #1: +# Row-value initialization subroutines must be called from with the +# RIGHT JOIN body subroutine before the first use of any register containing +# the results of that subroutine. This seems dodgy. Test case: +# +# CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT,b,c,d,e,f,g,h,j,k,l,m,n,o,p,q,r,s); +# CREATE INDEX t1x1 ON t1(g+h,j,k); +# CREATE INDEX t1x2 ON t1(b); +# INSERT INTO t1 DEFAULT VALUES; +# SELECT a FROM (SELECT a FROM (SELECT a FROM (SELECT a FROM t1 NATURAL LEFT JOIN t1 WHERE (b, 2 ) IS ( SELECT 2 IN(2,2),2)) NATURAL LEFT FULL JOIN t1 WHERE ( rowid , 1 )<=(CASE 5 WHEN 619 THEN 841 ELSE 3374391096 END,0) ORDER BY a ASC) NATURAL LEFT JOIN t1 WHERE (b, 2 ) IS ( SELECT 3 IN(3,3),3)) NATURAL LEFT FULL JOIN t1 WHERE ( rowid , 1 )<=(CASE 5 WHEN 619 THEN 841 ELSE 3374391096 END,0) ORDER BY a ASC; +# +do_test join8-issue-1 {set rc "Issue-1 'row-value subroutine' unresolved"} {} + +# Pending issue #2: +# Jump to addrHalt inside the RIGHT JOIN body subroutine bypasses the +# OP_Return, resulting in a subroutine loop. Test case: +# +# CREATE TABLE t1(a int, b int, c int); +# INSERT INTO t1 VALUES(1,2,3),(4,5,6); +# CREATE TABLE t2(d int, e int); +# INSERT INTO t2 VALUES(3,333),(4,444); +# CREATE TABLE t3(f int, g int); +# PRAGMA automatic_index=off; +# .eqp trace +# SELECT * FROM t1 RIGHT JOIN t2 ON c=d JOIN t3 ON f=e; +# +do_test join8-issue-2 {set rc "Issue-2 'jump to addrHalt' unresolved"} {} + +# Pending issue #3: +# USING does not work with RIGHT JOIN. +# Test case: +# +# CREATE TABLE t4(id INTEGER PRIMARY KEY, x TEXT); +# CREATE TABLE t5(id INTEGER PRIMARY KEY, y TEXT); +# CREATE TABLE t6(id INTEGER PRIMARY KEY, z INT); +# +# INSERT INTO t4(id,x) VALUES(2,'alice'),(4,'bob'),(6,'cindy'),(8,'dave'); +# INSERT INTO t5(id,y) VALUES(1,'red'),(2,'orange'),(3,'yellow'),(4,'green'), +# (5,'blue'); +# INSERT INTO t6(id,z) VALUES(3,333),(4,444),(5,555),(0,1000),(9,999); +# +# .mode box +# SELECT *, t4.id, t5.id, t6.id +# FROM t4 NATURAL LEFT JOIN t5 NATURAL LEFT JOIN t6 +# ORDER BY coalesce(t4.id,t5.id,t6.id); +# +# SELECT *, t4.id, t5.id, t6.id +# FROM t4 NATURAL RIGHT JOIN t5 NATURAL RIGHT JOIN t6 +# ORDER BY coalesce(t4.id,t5.id,t6.id); +# +# SELECT *, t4.id, t5.id, t6.id +# FROM t4 NATURAL FULL JOIN t5 NATURAL FULL JOIN t6 +# ORDER BY coalesce(t4.id,t5.id,t6.id); +# +do_test join8-issue-3 {set rc "Issue-3 'USING' unresolved"} {} + finish_test From 358424aeff71bc8b38053b822091f4c6532ec5b1 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 15 Apr 2022 15:15:01 +0000 Subject: [PATCH 141/259] Add the "3" in the name of the sqlite3ProcessJoin() function. FossilOrigin-Name: b925f72b6f679c61b0d6be16fabe64dc7605550b7bd86f35c586dcecd8217673 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 5a00ef8c06..8378565aa6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Record\sthe\sthree\sknown\sbig\sissues\swith\sthe\scurrent\sRIGHT\sJOIN\sdesign\sin\nthe\sjoin8\stest\smodule,\swith\stests\sthat\sdeliberately\sfail\sin\sorder\sto\sremind\nus\sto\sfix\sthe\sissues. -D 2022-04-14T20:43:22.638 +C Add\sthe\s"3"\sin\sthe\sname\sof\sthe\ssqlite3ProcessJoin()\sfunction. +D 2022-04-15T15:15:01.170 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -552,7 +552,7 @@ F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c 7110fc3b5a4dec5d11559141c1906c4a125349fb602f541b05db3a3d448d4b95 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c d48e4ddfd0ff34caca8650a668eb3c9ba75bab21264026f0e9a9c2271334090c +F src/select.c b785c8d0dc9b00d3ddac164f57d586f893c259a5ccc8c18284fec06451109278 F src/shell.c.in eb7f10d5e2c47bd014d92ec5db1def21fcc1ed56ffaaa4ee715b6c37c370b47f F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1947,8 +1947,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 73f4036b04798660b30e540cbab69420078df9fb62a6a39944e078c36272f905 -R 2147cfd4b343bafdc07bef52bfee2ef0 +P 2c4ee723f4d0591d09776adfb82246bfa89153ab390b8b3f1878d1cdc43d68c8 +R 0c69b944fdb1ef8478f9b21563a2b465 U drh -Z 5c1d0d9c07677bde5075ec99ede43a74 +Z 4eff36418fdc185b6e45146c045232b8 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7a8d3db95f..47c6265192 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2c4ee723f4d0591d09776adfb82246bfa89153ab390b8b3f1878d1cdc43d68c8 \ No newline at end of file +b925f72b6f679c61b0d6be16fabe64dc7605550b7bd86f35c586dcecd8217673 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 2e5c1ac97a..d7d289ef53 100644 --- a/src/select.c +++ b/src/select.c @@ -493,7 +493,7 @@ static void unsetJoinExpr(Expr *p, int iTable){ ** ** This routine returns the number of errors encountered. */ -static int sqliteProcessJoin(Parse *pParse, Select *p){ +static int sqlite3ProcessJoin(Parse *pParse, Select *p){ SrcList *pSrc; /* All tables in the FROM clause */ int i, j; /* Loop counters */ SrcItem *pLeft; /* Left table being joined */ @@ -5667,7 +5667,7 @@ static int selectExpander(Walker *pWalker, Select *p){ /* Process NATURAL keywords, and ON and USING clauses of joins. */ assert( db->mallocFailed==0 || pParse->nErr!=0 ); - if( pParse->nErr || sqliteProcessJoin(pParse, p) ){ + if( pParse->nErr || sqlite3ProcessJoin(pParse, p) ){ return WRC_Abort; } From a99e325468d0c46919cf8a88f7c0b5bb8a4987a8 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 15 Apr 2022 15:47:14 +0000 Subject: [PATCH 142/259] Enhance the IdList object to exist in a single memory allocation (rather than a separate allocate for the base object and the array of IDs). Also permit an IdList object to store an Expr pointer together with each name. FossilOrigin-Name: 40f3c95871e6f40f287ef2756abafb8fc56dffdd0af69436e5c7d8e95022d94e --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/build.c | 25 +++++++++++++------------ src/expr.c | 16 +++++----------- src/insert.c | 9 ++++++--- src/sqliteInt.h | 18 +++++++++++++++--- src/treeview.c | 16 +++++++++++++++- 7 files changed, 65 insertions(+), 41 deletions(-) diff --git a/manifest b/manifest index 8378565aa6..c8c5ea8505 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s"3"\sin\sthe\sname\sof\sthe\ssqlite3ProcessJoin()\sfunction. -D 2022-04-15T15:15:01.170 +C Enhance\sthe\sIdList\sobject\sto\sexist\sin\sa\ssingle\smemory\sallocation\s(rather\sthan\na\sseparate\sallocate\sfor\sthe\sbase\sobject\sand\sthe\sarray\sof\sIDs).\s\sAlso\spermit\nan\sIdList\sobject\sto\sstore\san\sExpr\spointer\stogether\swith\seach\sname. +D 2022-04-15T15:47:14.312 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -495,7 +495,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 093c940ddf1d0753542d04e37eb9903cbc126e997815d234dd2b6317e812b192 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482e -F src/build.c d30ef1cbd19efbaf8596521589f2a56292325e03f0801bf160608da7b03a03ff +F src/build.c ecbe7ecacf653408c4bf7bb40097ee846614c2336deac62cd30e207b9a42a784 F src/callback.c 4c19af69835787bfe790ac560f3071a824eb629f34e41f97b52ce5235c77de1c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 026dbdcdbd8c3cde98a88483ee88310ff43150ab164ad768f12cc700a11495ad @@ -503,7 +503,7 @@ F src/date.c 15082566229d4b1e5f24fdb490bf9bcc68824b911d70e3573ef075a1b9e2d26f F src/dbpage.c 90661a87e1db8bfbc8d2ebbdcd3749651ddb287c555c07a28fb17c7c591ffb68 F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d F src/delete.c a8e844af211a48b13b5b358be77a12c860c6a557c21990ad51a548e2536500ce -F src/expr.c 6cf41bfa55c4c65b9d30a8251070bf90bc799a25699cfe5fbd15f9e497913b6d +F src/expr.c 5f4fa51dde6af4f7a622f4f6b04bcdae400bf7ef0090c37b9a03740113ad71c0 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 94927f9b46d72a9cb858c208febf04ceb0a3270c5fa5fd0b7f436cf16e09f72a F src/func.c a3407a6fbb0d4088d8d502e46f0ace63e0aeae7467ae23a9ca9815bbf9239761 @@ -512,7 +512,7 @@ F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51 F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 221ae0496a53fcf74321d6dcdd7fa2d3c17ede1c17fa1d9020e2465da4a4505a +F src/insert.c 173845e5a6bac96ae937409e4f876b631f26b31dabb9df8fd0eb3b130b2bb3a7 F src/json.c 7749b98c62f691697c7ee536b570c744c0583cab4a89200fdd0fc2aa8cc8cbd6 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 2ecb1441f9b1c22e9e022ee0776e67d259facf34b56ba892b206f0a294ee6f8c @@ -557,7 +557,7 @@ F src/shell.c.in eb7f10d5e2c47bd014d92ec5db1def21fcc1ed56ffaaa4ee715b6c37c370b47 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h ce8d798a966d6cd373fe12a2a5a90c9e6d5c8f2d98cbed4cd3efabd91b3f196b +F src/sqliteInt.h d0d71e92d3e2c7e00659057a214ef5d5516ec720ec0378b7ae4e82b02386174e F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -617,7 +617,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98 -F src/treeview.c cf275af590023b0288ed02012b293a9f73869299e4259ec9f070b0ccb3a55f55 +F src/treeview.c d5fae332a51d0e15a32281d3f215c6c2aa79dfed2b168f1ce70155a8a5f194df F src/trigger.c 372ada38f667c6823a3db15749eb668338e65c793394e55a37e56a489f2d1b55 F src/update.c 2cfaded82ca80ff56afb8c3ae5e88284e0824bfd86119827cc22481959f96f92 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 @@ -1947,8 +1947,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 2c4ee723f4d0591d09776adfb82246bfa89153ab390b8b3f1878d1cdc43d68c8 -R 0c69b944fdb1ef8478f9b21563a2b465 +P b925f72b6f679c61b0d6be16fabe64dc7605550b7bd86f35c586dcecd8217673 +R b11d83f7cd569b4ace13c0dab33f163b U drh -Z 4eff36418fdc185b6e45146c045232b8 +Z a062e1ee126eb5e46a77952af86658af # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 47c6265192..33815810f5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b925f72b6f679c61b0d6be16fabe64dc7605550b7bd86f35c586dcecd8217673 \ No newline at end of file +40f3c95871e6f40f287ef2756abafb8fc56dffdd0af69436e5c7d8e95022d94e \ No newline at end of file diff --git a/src/build.c b/src/build.c index 22f7a79e05..30908500a9 100644 --- a/src/build.c +++ b/src/build.c @@ -4672,18 +4672,17 @@ IdList *sqlite3IdListAppend(Parse *pParse, IdList *pList, Token *pToken){ if( pList==0 ){ pList = sqlite3DbMallocZero(db, sizeof(IdList) ); if( pList==0 ) return 0; + }else{ + IdList *pNew; + pNew = sqlite3DbRealloc(db, pList, + sizeof(IdList) + pList->nId*sizeof(pList->a)); + if( pNew==0 ){ + sqlite3IdListDelete(db, pList); + return 0; + } + pList = pNew; } - pList->a = sqlite3ArrayAllocate( - db, - pList->a, - sizeof(pList->a[0]), - &pList->nId, - &i - ); - if( i<0 ){ - sqlite3IdListDelete(db, pList); - return 0; - } + i = pList->nId++; pList->a[i].zName = sqlite3NameFromToken(db, pToken); if( IN_RENAME_OBJECT && pList->a[i].zName ){ sqlite3RenameTokenMap(pParse, (void*)pList->a[i].zName, pToken); @@ -4696,11 +4695,13 @@ IdList *sqlite3IdListAppend(Parse *pParse, IdList *pList, Token *pToken){ */ void sqlite3IdListDelete(sqlite3 *db, IdList *pList){ int i; + int delExpr; if( pList==0 ) return; + delExpr = pList->eU4==EU4_EXPR; for(i=0; inId; i++){ sqlite3DbFree(db, pList->a[i].zName); + if( delExpr ) sqlite3ExprDelete(db, pList->a[i].u4.pExpr); } - sqlite3DbFree(db, pList->a); sqlite3DbFreeNN(db, pList); } diff --git a/src/expr.c b/src/expr.c index e6d7f9e69e..4e036c9343 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1698,22 +1698,16 @@ IdList *sqlite3IdListDup(sqlite3 *db, const IdList *p){ int i; assert( db!=0 ); if( p==0 ) return 0; - pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) ); + assert( p->eU4!=EU4_EXPR ); + pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew)+(p->nId-1)*sizeof(p->a[0]) ); if( pNew==0 ) return 0; pNew->nId = p->nId; - pNew->a = sqlite3DbMallocRawNN(db, p->nId*sizeof(p->a[0]) ); - if( pNew->a==0 ){ - sqlite3DbFreeNN(db, pNew); - return 0; - } - /* Note that because the size of the allocation for p->a[] is not - ** necessarily a power of two, sqlite3IdListAppend() may not be called - ** on the duplicate created by this function. */ + pNew->eU4 = p->eU4; for(i=0; inId; i++){ struct IdList_item *pNewItem = &pNew->a[i]; - struct IdList_item *pOldItem = &p->a[i]; + const struct IdList_item *pOldItem = &p->a[i]; pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); - pNewItem->idx = pOldItem->idx; + pNewItem->u4 = pOldItem->u4; } return pNew; } diff --git a/src/insert.c b/src/insert.c index 2593f353b3..9b97b99a35 100644 --- a/src/insert.c +++ b/src/insert.c @@ -851,13 +851,15 @@ void sqlite3Insert( */ bIdListInOrder = (pTab->tabFlags & (TF_OOOHidden|TF_HasStored))==0; if( pColumn ){ + assert( pColumn->eU4!=EU4_EXPR ); + pColumn->eU4 = EU4_IDX; for(i=0; inId; i++){ - pColumn->a[i].idx = -1; + pColumn->a[i].u4.idx = -1; } for(i=0; inId; i++){ for(j=0; jnCol; j++){ if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zCnName)==0 ){ - pColumn->a[i].idx = j; + pColumn->a[i].u4.idx = j; if( i!=j ) bIdListInOrder = 0; if( j==pTab->iPKey ){ ipkColumn = i; assert( !withoutRowid ); @@ -1159,7 +1161,8 @@ void sqlite3Insert( } } if( pColumn ){ - for(j=0; jnId && pColumn->a[j].idx!=i; j++){} + assert( pColumn->eU4==EU4_IDX ); + for(j=0; jnId && pColumn->a[j].u4.idx!=i; j++){} if( j>=pColumn->nId ){ /* A column not named in the insert column list gets its ** default value */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 1cd3e75b44..3a9d8b8a0e 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3038,13 +3038,25 @@ struct ExprList { ** If "a" is the k-th column of table "t", then IdList.a[0].idx==k. */ struct IdList { + int nId; /* Number of identifiers on the list */ + u8 eU4; /* Which element of a.u4 is valid */ struct IdList_item { char *zName; /* Name of the identifier */ - int idx; /* Index in some Table.aCol[] of a column named zName */ - } *a; - int nId; /* Number of identifiers on the list */ + union { + int idx; /* Index in some Table.aCol[] of a column named zName */ + Expr *pExpr; /* Expr to implement a USING variable */ + } u4; + } a[1]; }; +/* +** Allowed values for IdList.eType, which determines which value of the a.u4 +** is valid. +*/ +#define EU4_NONE 0 /* Does not use IdList.a.u4 */ +#define EU4_IDX 1 /* Uses IdList.a.u4.idx */ +#define EU4_EXPR 2 /* Uses IdList.a.u4.pExpr */ + /* ** The SrcItem object represents a single term in the FROM clause of a query. ** The SrcList object is mostly an array of SrcItems. diff --git a/src/treeview.c b/src/treeview.c index 0a3f942677..ff5558acab 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -846,7 +846,21 @@ void sqlite3TreeViewBareIdList( if( zName==0 ) zName = "(null)"; sqlite3TreeViewPush(&pView, moreToFollow); sqlite3TreeViewLine(pView, 0); - fprintf(stdout, "%s (%d)\n", zName, pList->a[i].idx); + if( pList->eU4==EU4_NONE ){ + fprintf(stdout, "%s\n", zName); + }else if( pList->eU4==EU4_IDX ){ + fprintf(stdout, "%s (%d)\n", zName, pList->a[i].u4.idx); + }else{ + assert( pList->eU4==EU4_EXPR ); + if( pList->a[i].u4.pExpr==0 ){ + fprintf(stdout, "%s (pExpr=NULL)\n", zName); + }else{ + fprintf(stdout, "%s\n", zName); + sqlite3TreeViewPush(&pView, inId-1); + sqlite3TreeViewExpr(pView, pList->a[i].u4.pExpr, 0); + sqlite3TreeViewPop(&pView); + } + } sqlite3TreeViewPop(&pView); } } From 22c4bc8991e45118d22a8bf818aad0191ee5979d Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 15 Apr 2022 17:08:40 +0000 Subject: [PATCH 143/259] The sqlite3ProcessJoin() routine converts a NATURAL JOIN into a JOIN USING so that henceforth the NATURAL keyword can be ignored. FossilOrigin-Name: 8378e1e0d289627fb294ccd3f5865ef49df3a42b8a5aa211e21be1b42d9da753 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/resolve.c | 1 - src/select.c | 47 +++++++++++++++++++++++++++-------------------- 4 files changed, 35 insertions(+), 29 deletions(-) diff --git a/manifest b/manifest index c8c5ea8505..fc69bf60d0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\sIdList\sobject\sto\sexist\sin\sa\ssingle\smemory\sallocation\s(rather\sthan\na\sseparate\sallocate\sfor\sthe\sbase\sobject\sand\sthe\sarray\sof\sIDs).\s\sAlso\spermit\nan\sIdList\sobject\sto\sstore\san\sExpr\spointer\stogether\swith\seach\sname. -D 2022-04-15T15:47:14.312 +C The\ssqlite3ProcessJoin()\sroutine\sconverts\sa\sNATURAL\sJOIN\sinto\sa\sJOIN\sUSING\sso\nthat\shenceforth\sthe\sNATURAL\skeyword\scan\sbe\signored. +D 2022-04-15T17:08:40.527 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -550,9 +550,9 @@ F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c fd940149c691684e7c1073c3787a7170e44852b02d1275d2e30a5b58e89cfcaf F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c -F src/resolve.c 7110fc3b5a4dec5d11559141c1906c4a125349fb602f541b05db3a3d448d4b95 +F src/resolve.c 2d0f29eadbc87154399b2794490a5bfd104daf818d76e59845ab5afb9bf66824 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c b785c8d0dc9b00d3ddac164f57d586f893c259a5ccc8c18284fec06451109278 +F src/select.c 820941d6c857e2cfdb2e56565bacd2b31b4adacc468550d44f8f9089888405e2 F src/shell.c.in eb7f10d5e2c47bd014d92ec5db1def21fcc1ed56ffaaa4ee715b6c37c370b47f F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1947,8 +1947,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 b925f72b6f679c61b0d6be16fabe64dc7605550b7bd86f35c586dcecd8217673 -R b11d83f7cd569b4ace13c0dab33f163b +P 40f3c95871e6f40f287ef2756abafb8fc56dffdd0af69436e5c7d8e95022d94e +R a4dbe6f876199f457625a48f56e40a96 U drh -Z a062e1ee126eb5e46a77952af86658af +Z 67a6ae70c20850bccd3ed1b730f595c0 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 33815810f5..a6a2850870 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -40f3c95871e6f40f287ef2756abafb8fc56dffdd0af69436e5c7d8e95022d94e \ No newline at end of file +8378e1e0d289627fb294ccd3f5865ef49df3a42b8a5aa211e21be1b42d9da753 \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index ac00564daa..ecc07b296e 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -344,7 +344,6 @@ static int lookupName( ** USING clause, then skip this match. */ if( cnt==1 ){ - if( pItem->fg.jointype & JT_NATURAL ) continue; if( pItem->fg.isUsing && nameInUsingClause(pItem->u3.pUsing, zCol) ){ diff --git a/src/select.c b/src/select.c index d7d289ef53..9c60e209e7 100644 --- a/src/select.c +++ b/src/select.c @@ -320,8 +320,11 @@ int sqlite3ColumnIndex(Table *pTab, const char *zCol){ } /* -** Search the first N tables in pSrc, from left to right, looking for a -** table that has a column named zCol. +** Search the first N tables in pSrc, looking for a +** table that has a column named zCol. +** +** Search left-to-right if bRightmost is false. Search right-to-left +** if bRightmost is true. ** ** When found, set *piTab and *piCol to the table index and column index ** of the matching column and return TRUE. @@ -334,11 +337,15 @@ static int tableAndColumnIndex( const char *zCol, /* Name of the column we are looking for */ int *piTab, /* Write index of pSrc->a[] here */ int *piCol, /* Write index of pSrc->a[*piTab].pTab->aCol[] here */ - int bIgnoreHidden /* True to ignore hidden columns */ + int bIgnoreHidden, /* True to ignore hidden columns */ + int bRightmost /* Return the right-most match */ ){ int i; /* For looping over tables in pSrc */ int iCol; /* Index of column matching zCol */ + int rc = 0; + assert( N<=pSrc->nSrc ); + assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */ for(i=0; ia[i].pTab, zCol); @@ -349,10 +356,11 @@ static int tableAndColumnIndex( *piTab = i; *piCol = iCol; } - return 1; + rc = 1; + if( !bRightmost ) break; } } - return 0; + return rc; } /* @@ -509,10 +517,11 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ if( NEVER(pLeft->pTab==0 || pRightTab==0) ) continue; joinType = (pRight->fg.jointype & JT_OUTER)!=0 ? EP_FromJoin : EP_InnerJoin; - /* When the NATURAL keyword is present, add WHERE clause terms for - ** every column that the two tables have in common. + /* If this is a NATURAL join, synthesize an approprate USING clause + ** to specify which columns should be joined. */ if( pRight->fg.jointype & JT_NATURAL ){ + IdList *pUsing = 0; if( pRight->fg.isUsing || pRight->u3.pOn ){ sqlite3ErrorMsg(pParse, "a NATURAL join may not have " "an ON or USING clause", 0); @@ -520,16 +529,20 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ } for(j=0; jnCol; j++){ char *zName; /* Name of column in the right table */ - int iLeft; /* Matching left table */ - int iLeftCol; /* Matching column in the left table */ if( IsHiddenColumn(&pRightTab->aCol[j]) ) continue; zName = pRightTab->aCol[j].zCnName; - if( tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol, 1) ){ - addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, j, - joinType, &p->pWhere); + if( tableAndColumnIndex(pSrc, i+1, zName, 0, 0, 1, 0) ){ + Token x; + x.z = zName; + x.n = sqlite3Strlen30(zName); + pUsing = sqlite3IdListAppend(pParse, pUsing, &x); } } + if( pUsing ){ + pRight->fg.isUsing = 1; + pRight->u3.pUsing = pUsing; + } } /* Create extra terms on the WHERE clause for each column named @@ -541,6 +554,7 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ */ if( pRight->fg.isUsing ){ IdList *pList = pRight->u3.pUsing; + int bRight = (pRight->fg.jointype & JT_RIGHT)!=0; assert( pList!=0 ); for(j=0; jnId; j++){ char *zName; /* Name of the term in the USING clause */ @@ -551,7 +565,7 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ zName = pList->a[j].zName; iRightCol = sqlite3ColumnIndex(pRightTab, zName); if( iRightCol<0 - || !tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol, 0) + || !tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol,0,bRight) ){ sqlite3ErrorMsg(pParse, "cannot join using column %s - column " "not present in both tables", zName); @@ -5772,13 +5786,6 @@ static int selectExpander(Walker *pWalker, Select *p){ tableSeen = 1; if( i>0 && zTName==0 ){ - if( (pFrom->fg.jointype & JT_NATURAL)!=0 - && tableAndColumnIndex(pTabList, i, zName, 0, 0, 1) - ){ - /* In a NATURAL join, omit the join columns from the - ** table to the right of the join */ - continue; - } if( pFrom->fg.isUsing && sqlite3IdListIndex(pFrom->u3.pUsing, zName)>=0 ){ From 4ce7bf91562a41739cb03943d9342740a72140ac Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 15 Apr 2022 18:30:48 +0000 Subject: [PATCH 144/259] When expanding "*" in the result set of a SELECT, do not attach a table name to columns that are in subsequent USING clauses. FossilOrigin-Name: 91530990e018580ec5322ace6f0c369a32a3529a0bfb4defb25ca20223a2a80f --- manifest | 17 ++++++++++------- manifest.uuid | 2 +- src/select.c | 49 +++++++++++++++++++++++++++++++++++++++---------- src/sqliteInt.h | 1 + 4 files changed, 51 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index fc69bf60d0..0837f71c44 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\ssqlite3ProcessJoin()\sroutine\sconverts\sa\sNATURAL\sJOIN\sinto\sa\sJOIN\sUSING\sso\nthat\shenceforth\sthe\sNATURAL\skeyword\scan\sbe\signored. -D 2022-04-15T17:08:40.527 +C When\sexpanding\s"*"\sin\sthe\sresult\sset\sof\sa\sSELECT,\sdo\snot\sattach\sa\stable\sname\nto\scolumns\sthat\sare\sin\ssubsequent\sUSING\sclauses. +D 2022-04-15T18:30:48.111 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -552,12 +552,12 @@ F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c 2d0f29eadbc87154399b2794490a5bfd104daf818d76e59845ab5afb9bf66824 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 820941d6c857e2cfdb2e56565bacd2b31b4adacc468550d44f8f9089888405e2 +F src/select.c d36cf25d63f1a2f2dd342cf4ade0d8b14e9ade92b3617627ecc7609d3cf7b624 F src/shell.c.in eb7f10d5e2c47bd014d92ec5db1def21fcc1ed56ffaaa4ee715b6c37c370b47f F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h d0d71e92d3e2c7e00659057a214ef5d5516ec720ec0378b7ae4e82b02386174e +F src/sqliteInt.h 51b79f1db169deb87fc8ac2f1c11e2c4fcf9893737072ce56dd45e6e7917d61b F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -1947,8 +1947,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 40f3c95871e6f40f287ef2756abafb8fc56dffdd0af69436e5c7d8e95022d94e -R a4dbe6f876199f457625a48f56e40a96 +P 8378e1e0d289627fb294ccd3f5865ef49df3a42b8a5aa211e21be1b42d9da753 +R ec06a8420fc58788f4e87c08a362458b +T *branch * right-join-using +T *sym-right-join-using * +T -sym-right-join * U drh -Z 67a6ae70c20850bccd3ed1b730f595c0 +Z ea7a56f0892499e7077e3a35b99d310a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a6a2850870..4017be264b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8378e1e0d289627fb294ccd3f5865ef49df3a42b8a5aa211e21be1b42d9da753 \ No newline at end of file +91530990e018580ec5322ace6f0c369a32a3529a0bfb4defb25ca20223a2a80f \ No newline at end of file diff --git a/src/select.c b/src/select.c index 9c60e209e7..8c01b01aa5 100644 --- a/src/select.c +++ b/src/select.c @@ -541,6 +541,7 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ } if( pUsing ){ pRight->fg.isUsing = 1; + pRight->fg.isSynthUsing = 1; pRight->u3.pUsing = pUsing; } } @@ -565,7 +566,8 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ zName = pList->a[j].zName; iRightCol = sqlite3ColumnIndex(pRightTab, zName); if( iRightCol<0 - || !tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol,0,bRight) + || !tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol, + pRight->fg.isSynthUsing, bRight) ){ sqlite3ErrorMsg(pParse, "cannot join using column %s - column " "not present in both tables", zName); @@ -5527,11 +5529,35 @@ int sqlite3ExpandSubquery(Parse *pParse, SrcItem *pFrom){ #else pTab->tabFlags |= TF_Ephemeral; /* Legacy compatibility mode */ #endif - - return pParse->nErr ? SQLITE_ERROR : SQLITE_OK; } + +/* +** Check the N SrcItem objects to the right of pBase. (N might be zero!) +** If any of those SrcItem objects have a USING clause containing zName +** then return true. +** +** If N is zero, or none of the N SrcItem objects to the right of pBase +** contains a USING clause, or if none of the USING clauses contain zName, +** then return false. +*/ +static int inAnyUsingClause( + const char *zName, /* Name we are looking for */ + SrcItem *pBase, /* The base SrcItem. Looking at pBase[1] and following */ + int N /* How many SrcItems to check */ +){ + while( N>0 ){ + N--; + pBase++; + if( pBase->fg.isUsing==0 ) continue; + if( pBase->u3.pUsing==0 ) continue; + if( sqlite3IdListIndex(pBase->u3.pUsing, zName)>=0 ) return 1; + } + return 0; +} + + /* ** This routine is a Walker callback for "expanding" a SELECT statement. ** "Expanding" means to do the following: @@ -5795,9 +5821,16 @@ static int selectExpander(Walker *pWalker, Select *p){ } } pRight = sqlite3Expr(db, TK_ID, zName); - zColname = zName; - zToFree = 0; - if( longNames || pTabList->nSrc>1 ){ + if( longNames ){ + zColname = sqlite3MPrintf(db, "%s.%s", zTabName, zName); + zToFree = zColname; + }else{ + zColname = zName; + zToFree = 0; + } + if( pTabList->nSrc>1 + && !inAnyUsingClause(zName,pFrom,pTabList->nSrc-i-1) + ){ Expr *pLeft; pLeft = sqlite3Expr(db, TK_ID, zTabName); pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); @@ -5805,10 +5838,6 @@ static int selectExpander(Walker *pWalker, Select *p){ pLeft = sqlite3Expr(db, TK_ID, zSchemaName); pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pExpr); } - if( longNames ){ - zColname = sqlite3MPrintf(db, "%s.%s", zTabName, zName); - zToFree = zColname; - } }else{ pExpr = pRight; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 3a9d8b8a0e..51f5d06d28 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3090,6 +3090,7 @@ struct SrcItem { unsigned isCte :1; /* This is a CTE */ unsigned notCte :1; /* This item may not match a CTE */ unsigned isUsing :1; /* u3.pUsing is valid */ + unsigned isSynthUsing :1; /* u3.pUsing is synthensized from NATURAL */ } fg; int iCursor; /* The VDBE cursor number used to access this table */ union { From bb3c62a758d65bc4bf5f4eb10f4d48dc998a6602 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 15 Apr 2022 19:27:02 +0000 Subject: [PATCH 145/259] Progress toward a working USING for FULL JOIN. FossilOrigin-Name: fed2646adecb0a05dd674dc1cd2c0ae205078fe552ba93b8d68891c728c67637 --- manifest | 15 +++---- manifest.uuid | 2 +- src/resolve.c | 113 +++++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 101 insertions(+), 29 deletions(-) diff --git a/manifest b/manifest index 0837f71c44..cbfe237c21 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sexpanding\s"*"\sin\sthe\sresult\sset\sof\sa\sSELECT,\sdo\snot\sattach\sa\stable\sname\nto\scolumns\sthat\sare\sin\ssubsequent\sUSING\sclauses. -D 2022-04-15T18:30:48.111 +C Progress\stoward\sa\sworking\sUSING\sfor\sFULL\sJOIN. +D 2022-04-15T19:27:02.160 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -550,7 +550,7 @@ F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c fd940149c691684e7c1073c3787a7170e44852b02d1275d2e30a5b58e89cfcaf F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c -F src/resolve.c 2d0f29eadbc87154399b2794490a5bfd104daf818d76e59845ab5afb9bf66824 +F src/resolve.c 7ed7a871146da603301ad1d5874a650c855f242a28af8b8a55c921003a142673 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c d36cf25d63f1a2f2dd342cf4ade0d8b14e9ade92b3617627ecc7609d3cf7b624 F src/shell.c.in eb7f10d5e2c47bd014d92ec5db1def21fcc1ed56ffaaa4ee715b6c37c370b47f @@ -1947,11 +1947,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 8378e1e0d289627fb294ccd3f5865ef49df3a42b8a5aa211e21be1b42d9da753 -R ec06a8420fc58788f4e87c08a362458b -T *branch * right-join-using -T *sym-right-join-using * -T -sym-right-join * +P 91530990e018580ec5322ace6f0c369a32a3529a0bfb4defb25ca20223a2a80f +R 614ceffda705b0fa9287c7a51b45e503 U drh -Z ea7a56f0892499e7077e3a35b99d310a +Z d653e8290a074ee40bf85ba696b38740 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 4017be264b..422bec2b8c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -91530990e018580ec5322ace6f0c369a32a3529a0bfb4defb25ca20223a2a80f \ No newline at end of file +fed2646adecb0a05dd674dc1cd2c0ae205078fe552ba93b8d68891c728c67637 \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index ecc07b296e..83a7c5028e 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -207,6 +207,31 @@ Bitmask sqlite3ExprColUsed(Expr *pExpr){ } } +/* +** Create a new expression term for the column specified by pMatch and +** iColumn. Append this new expression term to the FULL JOIN Match set +** in *ppList. Create a new *ppList if this is the first term in the +** set. +*/ +static void extendFJMatch( + Parse *pParse, /* Parsing context */ + ExprList **ppList, /* ExprList to extend */ + SrcItem *pMatch, /* Source table containing the column */ + i16 iColumn /* The column number */ +){ + Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0); + if( pNew ){ + Table *pTab; + pNew->iTable = pMatch->iCursor; + assert( ExprUseYTab(pNew) ); + pTab = pNew->y.pTab = pMatch->pTab; + pNew->iColumn = iColumn==pTab->iPKey ? -1 : iColumn; + assert( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 ); + ExprSetProperty(pNew, EP_CanBeNull); + *ppList = sqlite3ExprListAppend(pParse, *ppList, pNew); + } +} + /* ** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up ** that name in the set of source tables in pSrcList and make the pExpr @@ -252,8 +277,9 @@ static int lookupName( NameContext *pTopNC = pNC; /* First namecontext in the list */ Schema *pSchema = 0; /* Schema of the expression */ int eNewExprOp = TK_COLUMN; /* New value for pExpr->op on success */ - Table *pTab = 0; /* Table hold the row */ + Table *pTab = 0; /* Table holding the row */ Column *pCol; /* A column of pTab */ + ExprList *pFJMatch = 0; /* Matches for FULL JOIN .. USING */ assert( pNC ); /* the name context cannot be NULL. */ assert( zCol ); /* The Z in X.Y.Z cannot be NULL */ @@ -310,6 +336,27 @@ static int lookupName( pEList = pItem->pSelect->pEList; for(j=0; jnExpr; j++){ if( sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb) ){ + if( cnt>0 ){ + if( pItem->fg.isUsing==0 + || !nameInUsingClause(pItem->u3.pUsing, zCol) + ){ + sqlite3ExprListDelete(db, pFJMatch); + pFJMatch = 0; + }else + if( (pItem->fg.jointype & JT_RIGHT)==0 ){ + /* An INNER or LEFT JOIN. Use the left-most table */ + continue; + }else + if( (pItem->fg.jointype & JT_LEFT)==0 ){ + /* A RIGHT JOIN. Use the right-most table */ + cnt = 0; + sqlite3ExprListDelete(db, pFJMatch); + pFJMatch = 0; + }else{ + /* For a FULL JOIN, we must construct a coalesce() func */ + extendFJMatch(pParse, &pFJMatch, pMatch, j); + } + } cnt++; cntTab = 2; pMatch = pItem; @@ -339,15 +386,25 @@ static int lookupName( if( pCol->hName==hCol && sqlite3StrICmp(pCol->zCnName, zCol)==0 ){ - /* If there has been exactly one prior match and this match - ** is for the right-hand table of a NATURAL JOIN or is in a - ** USING clause, then skip this match. - */ - if( cnt==1 ){ - if( pItem->fg.isUsing - && nameInUsingClause(pItem->u3.pUsing, zCol) + if( cnt>0 ){ + if( pItem->fg.isUsing==0 + || !nameInUsingClause(pItem->u3.pUsing, zCol) ){ + sqlite3ExprListDelete(db, pFJMatch); + pFJMatch = 0; + }else + if( (pItem->fg.jointype & JT_RIGHT)==0 ){ + /* An INNER or LEFT JOIN. Use the left-most table */ continue; + }else + if( (pItem->fg.jointype & JT_LEFT)==0 ){ + /* A RIGHT JOIN. Use the right-most table */ + cnt = 0; + sqlite3ExprListDelete(db, pFJMatch); + pFJMatch = 0; + }else{ + /* For a FULL JOIN, we must construct a coalesce() func */ + extendFJMatch(pParse, &pFJMatch, pMatch, j); } } cnt++; @@ -606,12 +663,37 @@ static int lookupName( } } - /* - ** cnt==0 means there was not match. cnt>1 means there were two or - ** more matches. Either way, we have an error. + /* Remove any substructure from pExpr */ + if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ + sqlite3ExprDelete(db, pExpr->pLeft); + pExpr->pLeft = 0; + sqlite3ExprDelete(db, pExpr->pRight); + pExpr->pRight = 0; + } + + /* + ** cnt==0 means there was not match. + ** cnt>1 means there were two or more matches. + ** + ** cnt==0 is always an error. cnt>1 is often an error, but might + ** be multiple matches for a NATURAL LEFT JOIN or a LEFT JOIN USING. + */ + assert( pFJMatch==0 || cnt>0 ); if( cnt!=1 ){ const char *zErr; + if( pFJMatch ){ + if( pFJMatch->nExpr==cnt-1 ){ + extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn); + pExpr->op = TK_FUNCTION; + pExpr->u.zToken = "coalesce"; + pExpr->x.pList = pFJMatch; + goto lookupname_end; + }else{ + sqlite3ExprListDelete(db, pFJMatch); + pFJMatch = 0; + } + } zErr = cnt==0 ? "no such column" : "ambiguous column name"; if( zDb ){ sqlite3ErrorMsg(pParse, "%s: %s.%s.%s", zErr, zDb, zTab, zCol); @@ -624,6 +706,7 @@ static int lookupName( pParse->checkSchema = 1; pTopNC->nNcErr++; } + assert( pFJMatch==0 ); /* If a column from a table in pSrcList is referenced, then record ** this fact in the pSrcList.a[].colUsed bitmask. Column 0 causes @@ -643,14 +726,6 @@ static int lookupName( pMatch->colUsed |= sqlite3ExprColUsed(pExpr); } - /* Clean up and return - */ - if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ - sqlite3ExprDelete(db, pExpr->pLeft); - pExpr->pLeft = 0; - sqlite3ExprDelete(db, pExpr->pRight); - pExpr->pRight = 0; - } pExpr->op = eNewExprOp; ExprSetProperty(pExpr, EP_Leaf); lookupname_end: From e62d9149a65bc5eefbdf69586f3cd6e3b6b6c59f Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 15 Apr 2022 19:49:28 +0000 Subject: [PATCH 146/259] Avoid deleting substructure of the Expr node in lookupName() until after the error message is generated. FossilOrigin-Name: b8e717663957dfd84e580bf21bc8e8881b33fdb94a2cc0c664a230e54d5e5076 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/resolve.c | 17 +++++++---------- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index cbfe237c21..f16f6e9564 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Progress\stoward\sa\sworking\sUSING\sfor\sFULL\sJOIN. -D 2022-04-15T19:27:02.160 +C Avoid\sdeleting\ssubstructure\sof\sthe\sExpr\snode\sin\slookupName()\suntil\safter\nthe\serror\smessage\sis\sgenerated. +D 2022-04-15T19:49:28.612 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -550,7 +550,7 @@ F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c fd940149c691684e7c1073c3787a7170e44852b02d1275d2e30a5b58e89cfcaf F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c -F src/resolve.c 7ed7a871146da603301ad1d5874a650c855f242a28af8b8a55c921003a142673 +F src/resolve.c ecd1623bf1737c755eedea91761f715c7fd7fb9fe75f8852a59c69ed7eabe23d F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c d36cf25d63f1a2f2dd342cf4ade0d8b14e9ade92b3617627ecc7609d3cf7b624 F src/shell.c.in eb7f10d5e2c47bd014d92ec5db1def21fcc1ed56ffaaa4ee715b6c37c370b47f @@ -1947,8 +1947,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 91530990e018580ec5322ace6f0c369a32a3529a0bfb4defb25ca20223a2a80f -R 614ceffda705b0fa9287c7a51b45e503 +P fed2646adecb0a05dd674dc1cd2c0ae205078fe552ba93b8d68891c728c67637 +R 1c50cd468ee936498b2b4c9dc93da894 U drh -Z d653e8290a074ee40bf85ba696b38740 +Z f18fddb58ed361d0fe042b1d1d670157 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 422bec2b8c..130732878a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fed2646adecb0a05dd674dc1cd2c0ae205078fe552ba93b8d68891c728c67637 \ No newline at end of file +b8e717663957dfd84e580bf21bc8e8881b33fdb94a2cc0c664a230e54d5e5076 \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index 83a7c5028e..2047328506 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -663,15 +663,6 @@ static int lookupName( } } - /* Remove any substructure from pExpr - */ - if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ - sqlite3ExprDelete(db, pExpr->pLeft); - pExpr->pLeft = 0; - sqlite3ExprDelete(db, pExpr->pRight); - pExpr->pRight = 0; - } - /* ** cnt==0 means there was not match. ** cnt>1 means there were two or more matches. @@ -727,10 +718,16 @@ static int lookupName( } pExpr->op = eNewExprOp; - ExprSetProperty(pExpr, EP_Leaf); lookupname_end: if( cnt==1 ){ assert( pNC!=0 ); + if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ + sqlite3ExprDelete(db, pExpr->pLeft); + pExpr->pLeft = 0; + sqlite3ExprDelete(db, pExpr->pRight); + pExpr->pRight = 0; + ExprSetProperty(pExpr, EP_Leaf); + } #ifndef SQLITE_OMIT_AUTHORIZATION if( pParse->db->xAuth && (pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER) From bdbda1eb1f47462d3b61129e409e0219e3203787 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 16 Apr 2022 12:40:52 +0000 Subject: [PATCH 147/259] RIGHT JOIN USING now appears to work the same as PG-14. Legacy tests pass. FossilOrigin-Name: 5bfb862419541de955dae35fc91f6e9fc70e2744bb786d49fa26bede80b9091d --- manifest | 16 ++++++------ manifest.uuid | 2 +- src/resolve.c | 31 +++++++++++++++++----- src/select.c | 3 ++- test/join9.test | 69 +++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 104 insertions(+), 17 deletions(-) create mode 100644 test/join9.test diff --git a/manifest b/manifest index fed1873bb6..a8f3238cc5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Revamp\sthe\sUSING\sclause\sprocessing\sso\sthat\sit\sworks\s(mostly)\swith\sRIGHT\nand\sFULL\sJOIN. -D 2022-04-15T19:53:35.253 +C RIGHT\sJOIN\sUSING\snow\sappears\sto\swork\sthe\ssame\sas\sPG-14.\s\sLegacy\stests\spass. +D 2022-04-16T12:40:52.845 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -550,9 +550,9 @@ F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c fd940149c691684e7c1073c3787a7170e44852b02d1275d2e30a5b58e89cfcaf F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c -F src/resolve.c ecd1623bf1737c755eedea91761f715c7fd7fb9fe75f8852a59c69ed7eabe23d +F src/resolve.c ed18f81f424c473e37b6ab7dcd3d0a0e2198590a4342d4f2b2a999e94ff0c97b F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c d36cf25d63f1a2f2dd342cf4ade0d8b14e9ade92b3617627ecc7609d3cf7b624 +F src/select.c d273657c2958eb5eee34d68920796b6e0214034dd3a2a88dc8e6dc92a4804271 F src/shell.c.in eb7f10d5e2c47bd014d92ec5db1def21fcc1ed56ffaaa4ee715b6c37c370b47f F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1148,6 +1148,7 @@ F test/join5.test c4df54e2e204d7f1417bfbdd21ca324b4b07415c647595cc47798eacfddc96 F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c F test/join7.test e5c9b1b729d7e1d0b4195e99833e0ff0cf2d88e7fdd32b49af1044f4c76f72d9 F test/join8.test 9731b16dbb4309a980ba4adcb4ec31277626230300f819296ffc753c564b2011 +F test/join9.test ab637b0983877c802b02c7cba71c8fc849bcff55edb819bea31ad8aade3e7dbc F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -1947,9 +1948,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 8378e1e0d289627fb294ccd3f5865ef49df3a42b8a5aa211e21be1b42d9da753 b8e717663957dfd84e580bf21bc8e8881b33fdb94a2cc0c664a230e54d5e5076 -R 1c50cd468ee936498b2b4c9dc93da894 -T +closed b8e717663957dfd84e580bf21bc8e8881b33fdb94a2cc0c664a230e54d5e5076 +P 719c8d920b435b0f234d47467a2abe2941ab7d55ecca886e211cfce577ae648c +R c3fdd17a4836973d7440bcccabeca593 U drh -Z e84867876e1dda583c8d47e448336a7d +Z da7116bcca24d6303c79a8dd758b8403 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2a8e66f8f7..a977f88626 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -719c8d920b435b0f234d47467a2abe2941ab7d55ecca886e211cfce577ae648c \ No newline at end of file +5bfb862419541de955dae35fc91f6e9fc70e2744bb786d49fa26bede80b9091d \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index 2047328506..d1698b127f 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -342,6 +342,10 @@ static int lookupName( ){ sqlite3ExprListDelete(db, pFJMatch); pFJMatch = 0; + if( pItem->fg.jointype & JT_LTORJ ){ + cnt++; + continue; + } }else if( (pItem->fg.jointype & JT_RIGHT)==0 ){ /* An INNER or LEFT JOIN. Use the left-most table */ @@ -392,6 +396,10 @@ static int lookupName( ){ sqlite3ExprListDelete(db, pFJMatch); pFJMatch = 0; + if( pItem->fg.jointype & JT_LTORJ ){ + cnt++; + continue; + } }else if( (pItem->fg.jointype & JT_RIGHT)==0 ){ /* An INNER or LEFT JOIN. Use the left-most table */ @@ -671,10 +679,17 @@ static int lookupName( ** be multiple matches for a NATURAL LEFT JOIN or a LEFT JOIN USING. */ assert( pFJMatch==0 || cnt>0 ); + assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) ); if( cnt!=1 ){ const char *zErr; if( pFJMatch ){ if( pFJMatch->nExpr==cnt-1 ){ + if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ + sqlite3ExprDelete(db, pExpr->pLeft); + pExpr->pLeft = 0; + sqlite3ExprDelete(db, pExpr->pRight); + pExpr->pRight = 0; + } extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn); pExpr->op = TK_FUNCTION; pExpr->u.zToken = "coalesce"; @@ -699,6 +714,15 @@ static int lookupName( } assert( pFJMatch==0 ); + /* Remove all substructure from pExpr */ + if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ + sqlite3ExprDelete(db, pExpr->pLeft); + pExpr->pLeft = 0; + sqlite3ExprDelete(db, pExpr->pRight); + pExpr->pRight = 0; + ExprSetProperty(pExpr, EP_Leaf); + } + /* If a column from a table in pSrcList is referenced, then record ** this fact in the pSrcList.a[].colUsed bitmask. Column 0 causes ** bit 0 to be set. Column 1 sets bit 1. And so forth. Bit 63 is @@ -721,13 +745,6 @@ static int lookupName( lookupname_end: if( cnt==1 ){ assert( pNC!=0 ); - if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ - sqlite3ExprDelete(db, pExpr->pLeft); - pExpr->pLeft = 0; - sqlite3ExprDelete(db, pExpr->pRight); - pExpr->pRight = 0; - ExprSetProperty(pExpr, EP_Leaf); - } #ifndef SQLITE_OMIT_AUTHORIZATION if( pParse->db->xAuth && (pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER) diff --git a/src/select.c b/src/select.c index 8c01b01aa5..245b9cf5df 100644 --- a/src/select.c +++ b/src/select.c @@ -5829,7 +5829,8 @@ static int selectExpander(Walker *pWalker, Select *p){ zToFree = 0; } if( pTabList->nSrc>1 - && !inAnyUsingClause(zName,pFrom,pTabList->nSrc-i-1) + && ( (pFrom->fg.jointype & JT_LTORJ)==0 + || !inAnyUsingClause(zName,pFrom,pTabList->nSrc-i-1) ) ){ Expr *pLeft; pLeft = sqlite3Expr(db, TK_ID, zTabName); diff --git a/test/join9.test b/test/join9.test new file mode 100644 index 0000000000..fde5436ea3 --- /dev/null +++ b/test/join9.test @@ -0,0 +1,69 @@ +# 2022-04-16 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. +# +# This file implements tests for RIGHT and FULL OUTER JOINs. + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +foreach {id schema} { + 1 { + CREATE TABLE t4(id INTEGER PRIMARY KEY, x TEXT); + CREATE TABLE t5(id INTEGER PRIMARY KEY, y TEXT); + CREATE TABLE t6(id INTEGER PRIMARY KEY, z INT); + INSERT INTO t4(id,x) VALUES(2,'alice'),(4,'bob'),(6,'cindy'),(8,'dave'); + INSERT INTO t5(id,y) VALUES(1,'red'),(2,'orange'),(3,'yellow'),(4,'green'), + (5,'blue'); + INSERT INTO t6(id,z) VALUES(3,333),(4,444),(5,555),(0,1000),(9,999); + } +} { + reset_db + db nullvalue - + do_execsql_test join9-$id.setup $schema {} + do_execsql_test join9-$id.10 { + SELECT *, t4.id, t5.id, t6.id + FROM t4 NATURAL LEFT JOIN t5 NATURAL LEFT JOIN t6 + ORDER BY id; + } { + 2 alice orange - 2 2 - + 4 bob green 444 4 4 4 + 6 cindy - - 6 - - + 8 dave - - 8 - - + } + do_execsql_test join9-$id.20 { + SELECT *, t4.id, t5.id, t6.id + FROM t4 NATURAL RIGHT JOIN t5 NATURAL RIGHT JOIN t6 + ORDER BY id; + } { + 0 - - 1000 - - 0 + 3 - yellow 333 - 3 3 + 4 bob green 444 4 4 4 + 5 - blue 555 - 5 5 + 9 - - 999 - - 9 + } + do_execsql_test join9-$id.30 { + SELECT *, t4.id, t5.id, t6.id + FROM t4 NATURAL FULL JOIN t5 NATURAL FULL JOIN t6 + ORDER BY id; + } { + 0 - - 1000 - - 0 + 1 - red - - 1 - + 2 alice orange - 2 2 - + 3 - yellow 333 - 3 3 + 4 bob green 444 4 4 4 + 5 - blue 555 - 5 5 + 6 cindy - - 6 - - + 8 dave - - 8 - - + 9 - - 999 - - 9 + } +} +finish_test From 977eef6cdc97f55c551aed68cd7621d551c1b63f Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 16 Apr 2022 13:55:48 +0000 Subject: [PATCH 148/259] New test cases. One of the new test cases shows a flaw in the base design of RIGHT JOIN. FossilOrigin-Name: 4c3ce6475a67b1e207a5b63d9e2d38ee5bc45c899ad00ee327f292bf59039b9c --- manifest | 14 +++---- manifest.uuid | 2 +- src/resolve.c | 4 +- test/join9.test | 102 ++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 110 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index a8f3238cc5..6220e0f079 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C RIGHT\sJOIN\sUSING\snow\sappears\sto\swork\sthe\ssame\sas\sPG-14.\s\sLegacy\stests\spass. -D 2022-04-16T12:40:52.845 +C New\stest\scases.\s\sOne\sof\sthe\snew\stest\scases\sshows\sa\sflaw\sin\sthe\sbase\sdesign\nof\sRIGHT\sJOIN. +D 2022-04-16T13:55:48.695 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -550,7 +550,7 @@ F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c fd940149c691684e7c1073c3787a7170e44852b02d1275d2e30a5b58e89cfcaf F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c -F src/resolve.c ed18f81f424c473e37b6ab7dcd3d0a0e2198590a4342d4f2b2a999e94ff0c97b +F src/resolve.c 58b5c54b7e5cd7101b57901f9039dee86224b6a93699a5e8639f402aff43e7cc F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c d273657c2958eb5eee34d68920796b6e0214034dd3a2a88dc8e6dc92a4804271 F src/shell.c.in eb7f10d5e2c47bd014d92ec5db1def21fcc1ed56ffaaa4ee715b6c37c370b47f @@ -1148,7 +1148,7 @@ F test/join5.test c4df54e2e204d7f1417bfbdd21ca324b4b07415c647595cc47798eacfddc96 F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c F test/join7.test e5c9b1b729d7e1d0b4195e99833e0ff0cf2d88e7fdd32b49af1044f4c76f72d9 F test/join8.test 9731b16dbb4309a980ba4adcb4ec31277626230300f819296ffc753c564b2011 -F test/join9.test ab637b0983877c802b02c7cba71c8fc849bcff55edb819bea31ad8aade3e7dbc +F test/join9.test 195c9986d1d1a9840627d610056718c6747e3e6bbc230ac711fe3c4465aa21c7 F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -1948,8 +1948,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 719c8d920b435b0f234d47467a2abe2941ab7d55ecca886e211cfce577ae648c -R c3fdd17a4836973d7440bcccabeca593 +P 5bfb862419541de955dae35fc91f6e9fc70e2744bb786d49fa26bede80b9091d +R 567fa939c6a9dfdced52167ff4c7578b U drh -Z da7116bcca24d6303c79a8dd758b8403 +Z 987f243665c64e4fbbc2d1f9cc8152ec # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a977f88626..37ed90638a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5bfb862419541de955dae35fc91f6e9fc70e2744bb786d49fa26bede80b9091d \ No newline at end of file +4c3ce6475a67b1e207a5b63d9e2d38ee5bc45c899ad00ee327f292bf59039b9c \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index d1698b127f..09b16f1ad2 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -684,7 +684,9 @@ static int lookupName( const char *zErr; if( pFJMatch ){ if( pFJMatch->nExpr==cnt-1 ){ - if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ + if( ExprHasProperty(pExpr,EP_Leaf) ){ + ExprClearProperty(pExpr,EP_Leaf); + }else{ sqlite3ExprDelete(db, pExpr->pLeft); pExpr->pLeft = 0; sqlite3ExprDelete(db, pExpr->pRight); diff --git a/test/join9.test b/test/join9.test index fde5436ea3..ad0545942f 100644 --- a/test/join9.test +++ b/test/join9.test @@ -17,9 +17,12 @@ source $testdir/tester.tcl foreach {id schema} { 1 { + CREATE TABLE t3(id INTEGER PRIMARY KEY, w TEXT); CREATE TABLE t4(id INTEGER PRIMARY KEY, x TEXT); CREATE TABLE t5(id INTEGER PRIMARY KEY, y TEXT); CREATE TABLE t6(id INTEGER PRIMARY KEY, z INT); + CREATE VIEW dual(dummy) AS VALUES('x'); + INSERT INTO t3(id,w) VALUES(2,'two'),(3,'three'),(6,'six'),(7,'seven'); INSERT INTO t4(id,x) VALUES(2,'alice'),(4,'bob'),(6,'cindy'),(8,'dave'); INSERT INTO t5(id,y) VALUES(1,'red'),(2,'orange'),(3,'yellow'),(4,'green'), (5,'blue'); @@ -29,7 +32,20 @@ foreach {id schema} { reset_db db nullvalue - do_execsql_test join9-$id.setup $schema {} - do_execsql_test join9-$id.10 { + + # Verifid by PG-14 for case 1 + do_execsql_test join9-$id.100 { + SELECT *, t4.id, t5.id, t6.id + FROM t4 NATURAL LEFT JOIN t5 NATURAL LEFT JOIN t6 + ORDER BY 1; + } { + 2 alice orange - 2 2 - + 4 bob green 444 4 4 4 + 6 cindy - - 6 - - + 8 dave - - 8 - - + } + + do_execsql_test join9-$id.101 { SELECT *, t4.id, t5.id, t6.id FROM t4 NATURAL LEFT JOIN t5 NATURAL LEFT JOIN t6 ORDER BY id; @@ -39,7 +55,54 @@ foreach {id schema} { 6 cindy - - 6 - - 8 dave - - 8 - - } - do_execsql_test join9-$id.20 { + do_execsql_test join9-$id.102 { + SELECT *, t4.id, t5.id, t6.id + FROM t4 LEFT JOIN t5 USING(id) LEFT JOIN t6 USING(id) + ORDER BY id; + } { + 2 alice orange - 2 2 - + 4 bob green 444 4 4 4 + 6 cindy - - 6 - - + 8 dave - - 8 - - + } + + # Verifid by PG-14 using case 1 + do_execsql_test join9-$id.200 { + SELECT id, x, y, z, t4.id, t5.id, t6.id + FROM t5 NATURAL RIGHT JOIN t4 NATURAL LEFT JOIN t6 + ORDER BY 1; + } { + 2 alice orange - 2 2 - + 4 bob green 444 4 4 4 + 6 cindy - - 6 - - + 8 dave - - 8 - - + } + + do_execsql_test join9-$id.201 { + SELECT id, x, y, z, t4.id, t5.id, t6.id + FROM t5 NATURAL RIGHT JOIN t4 NATURAL LEFT JOIN t6 + ORDER BY id; + } { + 2 alice orange - 2 2 - + 4 bob green 444 4 4 4 + 6 cindy - - 6 - - + 8 dave - - 8 - - + } + + # Verified by PG-14 using case 1 + do_execsql_test join9-$id.300 { + SELECT *, t4.id, t5.id, t6.id + FROM t4 NATURAL RIGHT JOIN t5 NATURAL RIGHT JOIN t6 + ORDER BY 1; + } { + 0 - - 1000 - - 0 + 3 - yellow 333 - 3 3 + 4 bob green 444 4 4 4 + 5 - blue 555 - 5 5 + 9 - - 999 - - 9 + } + + do_execsql_test join9-$id.301 { SELECT *, t4.id, t5.id, t6.id FROM t4 NATURAL RIGHT JOIN t5 NATURAL RIGHT JOIN t6 ORDER BY id; @@ -50,7 +113,25 @@ foreach {id schema} { 5 - blue 555 - 5 5 9 - - 999 - - 9 } - do_execsql_test join9-$id.30 { + + # Verified by PG-14 for case 1 + do_execsql_test join9-$id.400 { + SELECT *, t4.id, t5.id, t6.id + FROM t4 NATURAL FULL JOIN t5 NATURAL FULL JOIN t6 + ORDER BY 1; + } { + 0 - - 1000 - - 0 + 1 - red - - 1 - + 2 alice orange - 2 2 - + 3 - yellow 333 - 3 3 + 4 bob green 444 4 4 4 + 5 - blue 555 - 5 5 + 6 cindy - - 6 - - + 8 dave - - 8 - - + 9 - - 999 - - 9 + } + + do_execsql_test join9-$id.401 { SELECT *, t4.id, t5.id, t6.id FROM t4 NATURAL FULL JOIN t5 NATURAL FULL JOIN t6 ORDER BY id; @@ -65,5 +146,20 @@ foreach {id schema} { 8 dave - - 8 - - 9 - - 999 - - 9 } + do_execsql_test join9-$id.402 { + SELECT id, x, y, z, t4.id, t5.id, t6.id + FROM t4 NATURAL FULL JOIN t6 NATURAL FULL JOIN t5 + ORDER BY id; + } { + 0 - - 1000 - - 0 + 1 - red - - 1 - + 2 alice orange - 2 2 - + 3 - yellow 333 - 3 3 + 4 bob green 444 4 4 4 + 5 - blue 555 - 5 5 + 6 cindy - - 6 - - + 8 dave - - 8 - - + 9 - - 999 - - 9 + } } finish_test From b192970809949903b955e37b71853585cef864c4 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 16 Apr 2022 15:46:23 +0000 Subject: [PATCH 149/259] Fix a problem with "ON DELETE RESTRICT" and "ON UPDATE RESTRICT" foreign keys in attached databases scanning child tables in the wrong schema. FossilOrigin-Name: 04d5b637f087520cd58211505f9b5c086ff96d864a1908f60464b6fe22c62b7d --- manifest | 19 ++++++++----------- manifest.uuid | 2 +- src/fkey.c | 17 +++++++++-------- test/fkey8.test | 22 ++++++++++++++++++++++ 4 files changed, 40 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index 917b78da94..1436d1d1ca 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Cherry\spick\ssubroutine\sindentation\simprovements\sand\sthe\shardening\sof\nOP_Gosub\sfrom\sthe\sright-join\sbranch\sback\sinto\strunk. -D 2022-04-14T19:48:32.540 +C Fix\sa\sproblem\swith\s"ON\sDELETE\sRESTRICT"\sand\s"ON\sUPDATE\sRESTRICT"\sforeign\skeys\sin\sattached\sdatabases\sscanning\schild\stables\sin\sthe\swrong\sschema. +D 2022-04-16T15:46:23.749 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -505,7 +505,7 @@ F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d F src/delete.c a8e844af211a48b13b5b358be77a12c860c6a557c21990ad51a548e2536500ce F src/expr.c 38a25dcba22bc6c9d8614e64624497aab1762911ba88e81fc55f1e67a85ebc16 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 -F src/fkey.c 94927f9b46d72a9cb858c208febf04ceb0a3270c5fa5fd0b7f436cf16e09f72a +F src/fkey.c d965ede15d8360c09ed59348940649ee647b192e784466837d7aefa836d1d91e F src/func.c a3407a6fbb0d4088d8d502e46f0ace63e0aeae7467ae23a9ca9815bbf9239761 F src/global.c e83ee571b79ee3adc32e380cf554cf1254bc43763d23786c71721fbcdfbbb965 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 @@ -920,7 +920,7 @@ F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d F test/fkey5.test 6727452e163a427147e84e739da18713da553d79f9783559b04fdcd36d5c7421 F test/fkey6.test d078a1e323a740062bed38df32b8a736fd320dc0 F test/fkey7.test 64fb28da03da5dfe3cdef5967aa7e832c2507bf7fb8f0780cacbca1f2338d031 -F test/fkey8.test 48ef829d63f5f7b37aabd4df9363ac05f65539d1da8c4a44251631769d920579 +F test/fkey8.test 51deda7f1a1448bca95875e4a6e1a3a75b4bd7215e924e845bd60de60e4d84bf F test/fkey_malloc.test 594a7ea1fbab553c036c70813cd8bd9407d63749 F test/fordelete.test ba98f14446b310f9c9d935b97ec748753d0144a28b356ba30d1f4f6958fdde5c F test/format4.test eeae341953db8b6bda7f549044797c3278a6cc345d11ada81471671b654f8ef4 @@ -1945,11 +1945,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 dbd8e2e46cfb2de0ebdbb62cda2fe669df3eda98f5d6112d541f581995b1361d -Q +079b7b125206fb295720612f4853a5b786ec431ab595d35407195844779c149d -Q +647211e044a5856ceb6bf3e7b78e650fe7d81f8b7bf34568b99b346405ba520c -Q +73f4036b04798660b30e540cbab69420078df9fb62a6a39944e078c36272f905 -R a06dd4204ed9dc6148823319b9085bc9 -U drh -Z 8357da3748da436bd7d9f47cf82232f1 +P 12645f100d902690630a2925674aedbb01d41a53426a26a2f56de5b8fdec955f +R 65b6ae478c0c46336b2e3d4a00d84d7d +U dan +Z 20ffa409115b35ade94fa1104d7de644 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2cd2ea1e78..d23cd4cac5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -12645f100d902690630a2925674aedbb01d41a53426a26a2f56de5b8fdec955f \ No newline at end of file +04d5b637f087520cd58211505f9b5c086ff96d864a1908f60464b6fe22c62b7d \ No newline at end of file diff --git a/src/fkey.c b/src/fkey.c index bae9b11ac3..a057925145 100644 --- a/src/fkey.c +++ b/src/fkey.c @@ -534,14 +534,10 @@ static Expr *exprTableColumn( ** Operation | FK type | Action taken ** -------------------------------------------------------------------------- ** DELETE immediate Increment the "immediate constraint counter". -** Or, if the ON (UPDATE|DELETE) action is RESTRICT, -** throw a "FOREIGN KEY constraint failed" exception. ** ** INSERT immediate Decrement the "immediate constraint counter". ** ** DELETE deferred Increment the "deferred constraint counter". -** Or, if the ON (UPDATE|DELETE) action is RESTRICT, -** throw a "FOREIGN KEY constraint failed" exception. ** ** INSERT deferred Decrement the "deferred constraint counter". ** @@ -1189,9 +1185,9 @@ int sqlite3FkRequired( ** ** It returns a pointer to a Trigger structure containing a trigger ** equivalent to the ON UPDATE or ON DELETE action specified by pFKey. -** If the action is "NO ACTION" or "RESTRICT", then a NULL pointer is -** returned (these actions require no special handling by the triggers -** sub-system, code for them is created by fkScanChildren()). +** If the action is "NO ACTION" then a NULL pointer is returned (these actions +** require no special handling by the triggers sub-system, code for them is +** created by fkScanChildren()). ** ** For example, if pFKey is the foreign key and pTab is table "p" in ** the following schema: @@ -1320,18 +1316,23 @@ static Trigger *fkActionTrigger( nFrom = sqlite3Strlen30(zFrom); if( action==OE_Restrict ){ + int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); Token tFrom; + Token tDb; Expr *pRaise; tFrom.z = zFrom; tFrom.n = nFrom; + tDb.z = db->aDb[iDb].zDbSName; + tDb.n = sqlite3Strlen30(tDb.z); + pRaise = sqlite3Expr(db, TK_RAISE, "FOREIGN KEY constraint failed"); if( pRaise ){ pRaise->affExpr = OE_Abort; } pSelect = sqlite3SelectNew(pParse, sqlite3ExprListAppend(pParse, 0, pRaise), - sqlite3SrcListAppend(pParse, 0, &tFrom, 0), + sqlite3SrcListAppend(pParse, 0, &tDb, &tFrom), pWhere, 0, 0, 0, 0, 0 ); diff --git a/test/fkey8.test b/test/fkey8.test index 085190e675..2d72f6fcf0 100644 --- a/test/fkey8.test +++ b/test/fkey8.test @@ -228,4 +228,26 @@ do_execsql_test 5.3 { PRAGMA integrity_check; } {ok} +#------------------------------------------------------------------------- +reset_db +forcedelete test.db2 +do_execsql_test 6.1 { + PRAGMA foreign_keys = on; + CREATE TABLE c1(b); + INSERT INTO c1 VALUES(123); +} + +do_execsql_test 6.2 { + ATTACH 'test.db2' AS aux; + CREATE TABLE aux.p1(a INTEGER PRIMARY KEY); + CREATE TABLE aux.c1(b REFERENCES p1(a) ON DELETE RESTRICT); + + INSERT INTO aux.p1 VALUES(123); +} + +do_execsql_test 6.3 { + DELETE FROM aux.p1 WHERE a=123; +} + + finish_test From 2d27d36cba01b9ceff2c36ad0cef9468db370024 Mon Sep 17 00:00:00 2001 From: larrybr Date: Sat, 16 Apr 2022 17:53:25 +0000 Subject: [PATCH 150/259] Make shell auto-column work with lots of columns when log() is missing. FossilOrigin-Name: 82366436ef74838dae1f379f3e5b8ad187225a30ec58fb49f047ab7c08a263cf --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c.in | 13 ++++++++----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 1436d1d1ca..375c4eca36 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\s"ON\sDELETE\sRESTRICT"\sand\s"ON\sUPDATE\sRESTRICT"\sforeign\skeys\sin\sattached\sdatabases\sscanning\schild\stables\sin\sthe\swrong\sschema. -D 2022-04-16T15:46:23.749 +C Make\sshell\sauto-column\swork\swith\slots\sof\scolumns\swhen\slog()\sis\smissing. +D 2022-04-16T17:53:25.671 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -553,7 +553,7 @@ F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c 18d99e7146852d6064559561769fcca0743eb32b14a97da6dbed373a30ee0e76 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 5ac7c08646ac5a03634da8a954645bdaa13d9bf692fb6b0b5fb3b55b19ab884e -F src/shell.c.in eb7f10d5e2c47bd014d92ec5db1def21fcc1ed56ffaaa4ee715b6c37c370b47f +F src/shell.c.in ecff6f4ab0e8e25acd578b3eb27ac0bad4d48643c160259a277151d6e9d412e1 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e @@ -1945,8 +1945,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 12645f100d902690630a2925674aedbb01d41a53426a26a2f56de5b8fdec955f -R 65b6ae478c0c46336b2e3d4a00d84d7d -U dan -Z 20ffa409115b35ade94fa1104d7de644 +P 04d5b637f087520cd58211505f9b5c086ff96d864a1908f60464b6fe22c62b7d +R 247d42769b42eb4f49b3d0e81a9caafe +U larrybr +Z 012ec694a47eae04b9be0b86d525b8a4 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d23cd4cac5..0034ef782e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -04d5b637f087520cd58211505f9b5c086ff96d864a1908f60464b6fe22c62b7d \ No newline at end of file +82366436ef74838dae1f379f3e5b8ad187225a30ec58fb49f047ab7c08a263cf \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 996a7f942b..5a2ff6ea26 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -7833,7 +7833,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ #endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */ -/* +/* * zAutoColumn(zCol, &db, ?) => Maybe init db, add column zCol to it. * zAutoColumn(0, &db, ?) => (db!=0) Form columns spec for CREATE TABLE, * close db and set it to 0, and return the columns spec, to later @@ -7916,6 +7916,13 @@ UPDATE ColNames AS t SET reps=\ static const char * const zColDigits = "\ SELECT CAST(ceil(log(count(*)+0.5)) AS INT) FROM ColNames \ "; +#else + /* Counting on SQLITE_MAX_COLUMN < 100,000 here. (32767 is the hard limit.) */ + static const char * const zColDigits = "\ +SELECT CASE WHEN (nc < 10) THEN 1 WHEN (nc < 100) THEN 2 \ + WHEN (nc < 1000) THEN 3 WHEN (nc < 10000) THEN 4 \ + ELSE 5 FROM (SELECT count(*) AS nc FROM ColNames) \ +"; #endif static const char * const zRenameRank = #ifdef SHELL_COLUMN_RENAME_CLEAN @@ -8001,11 +8008,7 @@ FROM (\ /* Formulate the columns spec, close the DB, zero *pDb. */ char *zColsSpec = 0; int hasDupes = db_int(*pDb, zHasDupes); -#ifdef SQLITE_ENABLE_MATH_FUNCTIONS int nDigits = (hasDupes)? db_int(*pDb, zColDigits) : 0; -#else -# define nDigits 2 -#endif if( hasDupes ){ #ifdef SHELL_COLUMN_RENAME_CLEAN rc = sqlite3_exec(*pDb, zDedoctor, 0, 0, 0); From cebc8009ede4871c9f83ad9bfe1f64b2eebcd585 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 16 Apr 2022 18:33:22 +0000 Subject: [PATCH 151/259] Additional SELECT trace logic: Show the tree after result-set wildcard expansion but before name resolution. FossilOrigin-Name: a7babf75418adffa27dec7a9d382a60e1b9364fb51d72b0a10e2769b308b3c54 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 6 ++++++ 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 6220e0f079..5386ee8c8e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\stest\scases.\s\sOne\sof\sthe\snew\stest\scases\sshows\sa\sflaw\sin\sthe\sbase\sdesign\nof\sRIGHT\sJOIN. -D 2022-04-16T13:55:48.695 +C Additional\sSELECT\strace\slogic:\s\sShow\sthe\stree\safter\sresult-set\swildcard\nexpansion\sbut\sbefore\sname\sresolution. +D 2022-04-16T18:33:22.370 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -552,7 +552,7 @@ F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c 58b5c54b7e5cd7101b57901f9039dee86224b6a93699a5e8639f402aff43e7cc F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c d273657c2958eb5eee34d68920796b6e0214034dd3a2a88dc8e6dc92a4804271 +F src/select.c 3074a36194727755f60e4496289b267ebc98d183d33f54ef22d5aa312968c0ce F src/shell.c.in eb7f10d5e2c47bd014d92ec5db1def21fcc1ed56ffaaa4ee715b6c37c370b47f F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1948,8 +1948,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 5bfb862419541de955dae35fc91f6e9fc70e2744bb786d49fa26bede80b9091d -R 567fa939c6a9dfdced52167ff4c7578b +P 4c3ce6475a67b1e207a5b63d9e2d38ee5bc45c899ad00ee327f292bf59039b9c +R c8fd0258e87ea644726dd2408171a53e U drh -Z 987f243665c64e4fbbc2d1f9cc8152ec +Z 10f070fbe0626760b7aa50e27688efaa # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 37ed90638a..0ca2ab7f44 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4c3ce6475a67b1e207a5b63d9e2d38ee5bc45c899ad00ee327f292bf59039b9c \ No newline at end of file +a7babf75418adffa27dec7a9d382a60e1b9364fb51d72b0a10e2769b308b3c54 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 245b9cf5df..cd8cfb91b5 100644 --- a/src/select.c +++ b/src/select.c @@ -5882,6 +5882,12 @@ static int selectExpander(Walker *pWalker, Select *p){ p->selFlags |= SF_ComplexResult; } } +#if TREETRACE_ENABLED + if( sqlite3TreeTrace & 0x100 ){ + SELECTTRACE(0x100,pParse,p,("After result-set wildcard expansion:\n")); + sqlite3TreeViewSelect(0, p, 0); + } +#endif return WRC_Continue; } From fdc621aece3f79093fdc442c771dc86001ab5223 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 16 Apr 2022 19:13:16 +0000 Subject: [PATCH 152/259] Since the query planner is unable to cope with a LEFT JOIN on the left-hand side of a RIGHT JOIN, detect that situation early and raise a parsing error. This is a temporary measure that needs to be fixed. FossilOrigin-Name: 6d5d6e0403241c99ab4a47d7b6eedcd8ebc615a8ca8d66d7e81171f901b170d7 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/build.c | 10 +++++++--- src/parse.y | 4 ++-- src/sqliteInt.h | 2 +- 5 files changed, 19 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 5386ee8c8e..912fbe3f41 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Additional\sSELECT\strace\slogic:\s\sShow\sthe\stree\safter\sresult-set\swildcard\nexpansion\sbut\sbefore\sname\sresolution. -D 2022-04-16T18:33:22.370 +C Since\sthe\squery\splanner\sis\sunable\sto\scope\swith\sa\sLEFT\sJOIN\son\sthe\sleft-hand\sside\nof\sa\sRIGHT\sJOIN,\sdetect\sthat\ssituation\searly\sand\sraise\sa\sparsing\serror.\nThis\sis\sa\stemporary\smeasure\sthat\sneeds\sto\sbe\sfixed. +D 2022-04-16T19:13:16.788 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -495,7 +495,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 093c940ddf1d0753542d04e37eb9903cbc126e997815d234dd2b6317e812b192 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482e -F src/build.c ecbe7ecacf653408c4bf7bb40097ee846614c2336deac62cd30e207b9a42a784 +F src/build.c fad98f43a755f48ccdd0ba31d91f5a829cddd344dd3babaad0646bd23c2fcdc6 F src/callback.c 4c19af69835787bfe790ac560f3071a824eb629f34e41f97b52ce5235c77de1c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 026dbdcdbd8c3cde98a88483ee88310ff43150ab164ad768f12cc700a11495ad @@ -541,7 +541,7 @@ F src/os_win.c a8ea80037e81127ca01959daa87387cc135f325c88dc745376c4f760de852a10 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 42120492784fc9bcd9082b5c9b5e329b7318c357f9f3574a1bbfcf7418910356 F src/pager.h f82e9844166e1585f5786837ddc7709966138ced17f568c16af7ccf946c2baa3 -F src/parse.y 9130a936927658e7c574e97e5d4f0a747a3f6b9a42bc5c63e455c8e40cc74216 +F src/parse.y e221a1159c5e73730b4d3d87fe4b5ad4b10ea2237ff59804e6402495a04a26c7 F src/pcache.c 084e638432c610f95aea72b8509f0845d2791293f39d1b82f0c0a7e089c3bb6b F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 54881292a9a5db202b2c0ac541c5e3ef9a5e8c4f1c1383adb2601d5499a60e65 @@ -557,7 +557,7 @@ F src/shell.c.in eb7f10d5e2c47bd014d92ec5db1def21fcc1ed56ffaaa4ee715b6c37c370b47 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h 51b79f1db169deb87fc8ac2f1c11e2c4fcf9893737072ce56dd45e6e7917d61b +F src/sqliteInt.h afec51781b0ff21126c4cbd812be873f801810fef7ecee6c11e56ab85c6fe577 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -1948,8 +1948,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 4c3ce6475a67b1e207a5b63d9e2d38ee5bc45c899ad00ee327f292bf59039b9c -R c8fd0258e87ea644726dd2408171a53e +P a7babf75418adffa27dec7a9d382a60e1b9364fb51d72b0a10e2769b308b3c54 +R 45449a4d7735a1a3898975e3feb2590b U drh -Z 10f070fbe0626760b7aa50e27688efaa +Z 24f79365e5bd75e3605e6ecd98fb146e # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0ca2ab7f44..c0376615bf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a7babf75418adffa27dec7a9d382a60e1b9364fb51d72b0a10e2769b308b3c54 \ No newline at end of file +6d5d6e0403241c99ab4a47d7b6eedcd8ebc615a8ca8d66d7e81171f901b170d7 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 30908500a9..89228024d5 100644 --- a/src/build.c +++ b/src/build.c @@ -5076,7 +5076,7 @@ void sqlite3SrcListFuncArgs(Parse *pParse, SrcList *p, ExprList *pList){ ** code generator can easily tell that the table is part of ** the left operand of at least one RIGHT JOIN. */ -void sqlite3SrcListShiftJoinType(SrcList *p){ +void sqlite3SrcListShiftJoinType(Parse *pParse, SrcList *p){ if( p && p->nSrc>1 ){ int i = p->nSrc-1; u8 allFlags = 0; @@ -5092,8 +5092,12 @@ void sqlite3SrcListShiftJoinType(SrcList *p){ i--; assert( i>=0 ); do{ - p->a[i--].fg.jointype |= JT_LTORJ; - }while( i>=0 ); + if( p->a[i].fg.jointype & JT_LEFT ){ + sqlite3ErrorMsg(pParse, "unable to compute a LEFT or FULL JOIN" + " that is a left operand of a RIGHT or FULL JOIN"); + } + p->a[i].fg.jointype |= JT_LTORJ; + }while( (--i)>=0 ); } } } diff --git a/src/parse.y b/src/parse.y index 4deae14b4c..65977bbbad 100644 --- a/src/parse.y +++ b/src/parse.y @@ -685,7 +685,7 @@ as(X) ::= . {X.n = 0; X.z = 0;} from(A) ::= . {A = 0;} from(A) ::= FROM seltablist(X). { A = X; - sqlite3SrcListShiftJoinType(A); + sqlite3SrcListShiftJoinType(pParse,A); } // "seltablist" is a "Select Table List" - the content of the FROM clause @@ -733,7 +733,7 @@ seltablist(A) ::= stl_prefix(A) nm(Y) dbnm(D) LP exprlist(E) RP as(Z) on_using(N sqlite3SrcListDelete(pParse->db, F); }else{ Select *pSubquery; - sqlite3SrcListShiftJoinType(F); + sqlite3SrcListShiftJoinType(pParse,F); pSubquery = sqlite3SelectNew(pParse,0,F,0,0,0,0,SF_NestedFrom,0); A = sqlite3SrcListAppendFromTerm(pParse,A,0,0,&Z,pSubquery,&N); } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 51f5d06d28..bc618df7df 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4643,7 +4643,7 @@ SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*, void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *); void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*); int sqlite3IndexedByLookup(Parse *, SrcItem *); -void sqlite3SrcListShiftJoinType(SrcList*); +void sqlite3SrcListShiftJoinType(Parse*,SrcList*); void sqlite3SrcListAssignCursors(Parse*, SrcList*); void sqlite3IdListDelete(sqlite3*, IdList*); void sqlite3ClearOnOrUsing(sqlite3*, OnOrUsing*); From 052953a4e601dc19166d0d8a66873198497f65cf Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 16 Apr 2022 22:57:41 +0000 Subject: [PATCH 153/259] Fix the USING to ON translation so that it works correctly for a sequence of two or more joins where one of the joins to the right-hand side of the list is a RIGHT or FULL JOIN. FossilOrigin-Name: 9ffc2b231956cde1bc90519aa174b0e2dc30ef671ed745f4f3ffa9fbb7ffab4b --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/build.c | 4 ---- src/select.c | 44 +++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 49 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 912fbe3f41..9cc5d17b45 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Since\sthe\squery\splanner\sis\sunable\sto\scope\swith\sa\sLEFT\sJOIN\son\sthe\sleft-hand\sside\nof\sa\sRIGHT\sJOIN,\sdetect\sthat\ssituation\searly\sand\sraise\sa\sparsing\serror.\nThis\sis\sa\stemporary\smeasure\sthat\sneeds\sto\sbe\sfixed. -D 2022-04-16T19:13:16.788 +C Fix\sthe\sUSING\sto\sON\stranslation\sso\sthat\sit\sworks\scorrectly\sfor\sa\ssequence\nof\stwo\sor\smore\sjoins\swhere\sone\sof\sthe\sjoins\sto\sthe\sright-hand\sside\sof\sthe\nlist\sis\sa\sRIGHT\sor\sFULL\sJOIN. +D 2022-04-16T22:57:41.804 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -495,7 +495,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 093c940ddf1d0753542d04e37eb9903cbc126e997815d234dd2b6317e812b192 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482e -F src/build.c fad98f43a755f48ccdd0ba31d91f5a829cddd344dd3babaad0646bd23c2fcdc6 +F src/build.c d6518b209ec89e0b0c744564213369b772b00efa698c3f121d14cf25c5806ade F src/callback.c 4c19af69835787bfe790ac560f3071a824eb629f34e41f97b52ce5235c77de1c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 026dbdcdbd8c3cde98a88483ee88310ff43150ab164ad768f12cc700a11495ad @@ -552,7 +552,7 @@ F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c 58b5c54b7e5cd7101b57901f9039dee86224b6a93699a5e8639f402aff43e7cc F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 3074a36194727755f60e4496289b267ebc98d183d33f54ef22d5aa312968c0ce +F src/select.c 0af8c196a4b3fdf5fa4f6aae4045758467d143efd32711bfc4bf711e8e8a04cc F src/shell.c.in eb7f10d5e2c47bd014d92ec5db1def21fcc1ed56ffaaa4ee715b6c37c370b47f F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1948,8 +1948,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 a7babf75418adffa27dec7a9d382a60e1b9364fb51d72b0a10e2769b308b3c54 -R 45449a4d7735a1a3898975e3feb2590b +P 6d5d6e0403241c99ab4a47d7b6eedcd8ebc615a8ca8d66d7e81171f901b170d7 +R 4be646ba0dcbc3b7d9317327df4f7fe8 U drh -Z 24f79365e5bd75e3605e6ecd98fb146e +Z 4c860c34eaaf8b2ecd96a50692d3cbf3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c0376615bf..b2cd850431 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6d5d6e0403241c99ab4a47d7b6eedcd8ebc615a8ca8d66d7e81171f901b170d7 \ No newline at end of file +9ffc2b231956cde1bc90519aa174b0e2dc30ef671ed745f4f3ffa9fbb7ffab4b \ No newline at end of file diff --git a/src/build.c b/src/build.c index 89228024d5..cf277b9073 100644 --- a/src/build.c +++ b/src/build.c @@ -5092,10 +5092,6 @@ void sqlite3SrcListShiftJoinType(Parse *pParse, SrcList *p){ i--; assert( i>=0 ); do{ - if( p->a[i].fg.jointype & JT_LEFT ){ - sqlite3ErrorMsg(pParse, "unable to compute a LEFT or FULL JOIN" - " that is a left operand of a RIGHT or FULL JOIN"); - } p->a[i].fg.jointype |= JT_LTORJ; }while( (--i)>=0 ); } diff --git a/src/select.c b/src/select.c index cd8cfb91b5..f6938ccabe 100644 --- a/src/select.c +++ b/src/select.c @@ -555,13 +555,14 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ */ if( pRight->fg.isUsing ){ IdList *pList = pRight->u3.pUsing; - int bRight = (pRight->fg.jointype & JT_RIGHT)!=0; + int bRight = (pLeft->fg.jointype & JT_RIGHT)!=0; assert( pList!=0 ); for(j=0; jnId; j++){ char *zName; /* Name of the term in the USING clause */ int iLeft; /* Table on the left with matching column name */ int iLeftCol; /* Column number of matching column on the left */ int iRightCol; /* Column number of matching column on the right */ + int iNxLeft, iNxLeftCol; zName = pList->a[j].zName; iRightCol = sqlite3ColumnIndex(pRightTab, zName); @@ -573,8 +574,45 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ "not present in both tables", zName); return 1; } - addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, iRightCol, - joinType, &p->pWhere); + if( (pLeft->fg.jointype & (JT_RIGHT|JT_LEFT))!=(JT_LEFT|JT_RIGHT) + || 0==tableAndColumnIndex(pSrc, iLeft, zName, &iNxLeft, &iNxLeftCol, + pRight->fg.isSynthUsing, 1) + ){ + addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, iRightCol, + joinType, &p->pWhere); + }else{ + /* Because the left-hand side of this join is another RIGHT or FULL + ** JOIN with two or more tables hold zName, we need to construct + ** a coalesce() function for left side of the ON constraint. + */ + ExprList *pList; + Expr *pE; + Expr *pE2; + Expr *pEq; + sqlite3 *db = pParse->db; + static const Token tkCoalesce = { "coalesce", 8 }; + pE = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol); + pList = sqlite3ExprListAppend(pParse, 0, pE); + pE = sqlite3CreateColumnExpr(db, pSrc, iNxLeft, iNxLeftCol); + pList = sqlite3ExprListAppend(pParse, pList, pE); + while( tableAndColumnIndex(pSrc, iNxLeft, zName, + &iNxLeft, &iNxLeftCol, + pRight->fg.isSynthUsing, 1)!=0 ){ + pE = sqlite3CreateColumnExpr(db, pSrc, iNxLeft, iNxLeftCol); + pList = sqlite3ExprListAppend(pParse, pList, pE); + } + pE = sqlite3ExprFunction(pParse, pList, &tkCoalesce, 0); + pE2 = sqlite3CreateColumnExpr(db, pSrc, i+1, iRightCol); + pEq = sqlite3PExpr(pParse, TK_EQ, pE, pE2); + assert( pE2!=0 || pEq==0 ); + if( pEq ){ + ExprSetProperty(pEq, joinType); + assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) ); + ExprSetVVAProperty(pEq, EP_NoReduce); + pEq->w.iJoin = pE2->iTable; + } + p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pEq); + } } } From 6fda176ba61b0a37ca70ec9fdf3ed9e80732ab8c Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 16 Apr 2022 23:38:29 +0000 Subject: [PATCH 154/259] New test cases, one of which is failing, indicating a bug that needs fixing. FossilOrigin-Name: bd5fd68435ff068c18d7d46b33cf7591263a03c32a917a7df7c087b08c573cc8 --- manifest | 16 +++---- manifest.uuid | 2 +- test/join2.test | 6 +-- test/join8.test | 78 +++++++++++++++++++++----------- test/join9.test | 116 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 180 insertions(+), 38 deletions(-) diff --git a/manifest b/manifest index 9cc5d17b45..07f28c3684 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sUSING\sto\sON\stranslation\sso\sthat\sit\sworks\scorrectly\sfor\sa\ssequence\nof\stwo\sor\smore\sjoins\swhere\sone\sof\sthe\sjoins\sto\sthe\sright-hand\sside\sof\sthe\nlist\sis\sa\sRIGHT\sor\sFULL\sJOIN. -D 2022-04-16T22:57:41.804 +C New\stest\scases,\sone\sof\swhich\sis\sfailing,\sindicating\sa\sbug\sthat\sneeds\sfixing. +D 2022-04-16T23:38:29.234 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1141,14 +1141,14 @@ F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4 F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b F test/istrue.test e7f285bb70282625c258e866ce6337d4c762922f5a300e1b50f958aef6e7d9c9 F test/join.test d9c8cb2769b147b223f9dff8f694f56cfd9d0c097f8af9c7c6562b2e4ad256b5 -F test/join2.test 9751dac84a46a960281ca372fe2350252ef40286dde3c542540bccdea9a2d5c6 +F test/join2.test 466b07233820f5deee66a6c3bf6e4500c8bbf7b83649e67606f5f649c07928c0 F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test c4df54e2e204d7f1417bfbdd21ca324b4b07415c647595cc47798eacfddc96d3 F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c F test/join7.test e5c9b1b729d7e1d0b4195e99833e0ff0cf2d88e7fdd32b49af1044f4c76f72d9 -F test/join8.test 9731b16dbb4309a980ba4adcb4ec31277626230300f819296ffc753c564b2011 -F test/join9.test 195c9986d1d1a9840627d610056718c6747e3e6bbc230ac711fe3c4465aa21c7 +F test/join8.test 4f085a233582724be035e83100f458c4cfdd8101699c27feac2782242c037682 +F test/join9.test afd899f0bda3db6d5fefae2275ad91802d056c7dcd109030100b87e0b75f47ff F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -1948,8 +1948,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 6d5d6e0403241c99ab4a47d7b6eedcd8ebc615a8ca8d66d7e81171f901b170d7 -R 4be646ba0dcbc3b7d9317327df4f7fe8 +P 9ffc2b231956cde1bc90519aa174b0e2dc30ef671ed745f4f3ffa9fbb7ffab4b +R 6e1aaa1b139d709bc01047520c7bb6df U drh -Z 4c860c34eaaf8b2ecd96a50692d3cbf3 +Z d4fc26ab748be0192a3f4dfcc716caef # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b2cd850431..94e1a8b487 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9ffc2b231956cde1bc90519aa174b0e2dc30ef671ed745f4f3ffa9fbb7ffab4b \ No newline at end of file +bd5fd68435ff068c18d7d46b33cf7591263a03c32a917a7df7c087b08c573cc8 \ No newline at end of file diff --git a/test/join2.test b/test/join2.test index 4142fd15b3..e549c49343 100644 --- a/test/join2.test +++ b/test/join2.test @@ -78,10 +78,10 @@ ifcapable subquery { } {1 11 111 1111 2 22 {} {} 3 33 {} {}} do_test join2-1.7-rj { execsql { - SELECT * FROM - (t2 NATURAL JOIN t3) NATURAL RIGHT JOIN t1 + SELECT a, b, c, d FROM + t2 NATURAL JOIN t3 NATURAL RIGHT JOIN t1 } - } {11 111 1111 1 {} {} {} 2 {} {} {} 3} + } {1 11 111 1111 2 22 {} {} 3 33 {} {}} } #------------------------------------------------------------------------- diff --git a/test/join8.test b/test/join8.test index bd80c96ded..0317722fd0 100644 --- a/test/join8.test +++ b/test/join8.test @@ -50,32 +50,58 @@ do_test join8-issue-1 {set rc "Issue-1 'row-value subroutine' unresolved"} {} # do_test join8-issue-2 {set rc "Issue-2 'jump to addrHalt' unresolved"} {} -# Pending issue #3: -# USING does not work with RIGHT JOIN. -# Test case: +# Demonstrate that nested FULL JOINs and USING clauses work # -# CREATE TABLE t4(id INTEGER PRIMARY KEY, x TEXT); -# CREATE TABLE t5(id INTEGER PRIMARY KEY, y TEXT); -# CREATE TABLE t6(id INTEGER PRIMARY KEY, z INT); -# -# INSERT INTO t4(id,x) VALUES(2,'alice'),(4,'bob'),(6,'cindy'),(8,'dave'); -# INSERT INTO t5(id,y) VALUES(1,'red'),(2,'orange'),(3,'yellow'),(4,'green'), -# (5,'blue'); -# INSERT INTO t6(id,z) VALUES(3,333),(4,444),(5,555),(0,1000),(9,999); -# -# .mode box -# SELECT *, t4.id, t5.id, t6.id -# FROM t4 NATURAL LEFT JOIN t5 NATURAL LEFT JOIN t6 -# ORDER BY coalesce(t4.id,t5.id,t6.id); -# -# SELECT *, t4.id, t5.id, t6.id -# FROM t4 NATURAL RIGHT JOIN t5 NATURAL RIGHT JOIN t6 -# ORDER BY coalesce(t4.id,t5.id,t6.id); -# -# SELECT *, t4.id, t5.id, t6.id -# FROM t4 NATURAL FULL JOIN t5 NATURAL FULL JOIN t6 -# ORDER BY coalesce(t4.id,t5.id,t6.id); -# -do_test join8-issue-3 {set rc "Issue-3 'USING' unresolved"} {} +reset_db +load_static_extension db series +do_execsql_test join8-3000 { + CREATE TABLE t1(id INTEGER PRIMARY KEY, a INT); + CREATE TABLE t2(id INTEGER PRIMARY KEY, b INT); + CREATE TABLE t3(id INTEGER PRIMARY KEY, c INT); + CREATE TABLE t4(id INTEGER PRIMARY KEY, d INT); + CREATE TABLE t5(id INTEGER PRIMARY KEY, e INT); + CREATE TABLE t6(id INTEGER PRIMARY KEY, f INT); + CREATE TABLE t7(id INTEGER PRIMARY KEY, g INT); + CREATE TABLE t8(id INTEGER PRIMARY KEY, h INT); + INSERT INTO t1 SELECT value, 1 FROM generate_series(1,256) WHERE value & 1; + INSERT INTO t2 SELECT value, 1 FROM generate_series(1,256) WHERE value & 2; + INSERT INTO t3 SELECT value, 1 FROM generate_series(1,256) WHERE value & 4; + INSERT INTO t4 SELECT value, 1 FROM generate_series(1,256) WHERE value & 8; + INSERT INTO t5 SELECT value, 1 FROM generate_series(1,256) WHERE value & 16; + INSERT INTO t6 SELECT value, 1 FROM generate_series(1,256) WHERE value & 32; + INSERT INTO t7 SELECT value, 1 FROM generate_series(1,256) WHERE value & 64; + INSERT INTO t8 SELECT value, 1 FROM generate_series(1,256) WHERE value & 128; + CREATE TABLE t9 AS + SELECT id, h, g, f, e, d, c, b, a + FROM t1 + NATURAL FULL JOIN t2 + NATURAL FULL JOIN t3 + NATURAL FULL JOIN t4 + NATURAL FULL JOIN t5 + NATURAL FULL JOIN t6 + NATURAL FULL JOIN t7 + NATURAL FULL JOIN t8; +} {} +do_execsql_test join8-3010 { + SELECT count(*) FROM t9; +} {255} +do_execsql_test join8-3020 { + SELECT id, count(*) FROM t9 GROUP BY id HAVING count(*)!=1; +} {} +do_execsql_test join8-3030 { + UPDATE t9 SET a=0 WHERE a IS NULL; + UPDATE t9 SET b=0 WHERE b IS NULL; + UPDATE t9 SET c=0 WHERE c IS NULL; + UPDATE t9 SET d=0 WHERE d IS NULL; + UPDATE t9 SET e=0 WHERE e IS NULL; + UPDATE t9 SET f=0 WHERE f IS NULL; + UPDATE t9 SET g=0 WHERE g IS NULL; + UPDATE t9 SET h=0 WHERE h IS NULL; + SELECT count(*) FROM t9 WHERE id=128*h+64*g+32*f+16*e+8*d+4*c+2*b+a; +} {255} +do_execsql_test join8-3040 { + SELECT * FROM t9 WHERE id<>128*h+64*g+32*f+16*e+8*d+4*c+2*b+a; +} {} + finish_test diff --git a/test/join9.test b/test/join9.test index ad0545942f..69f7dcbd5f 100644 --- a/test/join9.test +++ b/test/join9.test @@ -28,6 +28,18 @@ foreach {id schema} { (5,'blue'); INSERT INTO t6(id,z) VALUES(3,333),(4,444),(5,555),(0,1000),(9,999); } + 2 { + CREATE TABLE t3(id INT PRIMARY KEY, w TEXT) WITHOUT ROWID; + CREATE TABLE t4(id INT PRIMARY KEY, x TEXT) WITHOUT ROWID; + CREATE TABLE t5(id INT PRIMARY KEY, y TEXT) WITHOUT ROWID; + CREATE TABLE t6(id INT PRIMARY KEY, z INT) WITHOUT ROWID; + CREATE VIEW dual(dummy) AS VALUES('x'); + INSERT INTO t3(id,w) VALUES(2,'two'),(3,'three'),(6,'six'),(7,'seven'); + INSERT INTO t4(id,x) VALUES(2,'alice'),(4,'bob'),(6,'cindy'),(8,'dave'); + INSERT INTO t5(id,y) VALUES(1,'red'),(2,'orange'),(3,'yellow'),(4,'green'), + (5,'blue'); + INSERT INTO t6(id,z) VALUES(3,333),(4,444),(5,555),(0,1000),(9,999); + } } { reset_db db nullvalue - @@ -161,5 +173,109 @@ foreach {id schema} { 8 dave - - 8 - - 9 - - 999 - - 9 } + do_execsql_test join9-$id.403 { + SELECT id, x, y, z, t4.id, t5.id, t6.id + FROM t5 NATURAL FULL JOIN t4 NATURAL FULL JOIN t6 + ORDER BY id; + } { + 0 - - 1000 - - 0 + 1 - red - - 1 - + 2 alice orange - 2 2 - + 3 - yellow 333 - 3 3 + 4 bob green 444 4 4 4 + 5 - blue 555 - 5 5 + 6 cindy - - 6 - - + 8 dave - - 8 - - + 9 - - 999 - - 9 + } + do_execsql_test join9-$id.404 { + SELECT id, x, y, z, t4.id, t5.id, t6.id + FROM t5 NATURAL FULL JOIN t6 NATURAL FULL JOIN t4 + ORDER BY id; + } { + 0 - - 1000 - - 0 + 1 - red - - 1 - + 2 alice orange - 2 2 - + 3 - yellow 333 - 3 3 + 4 bob green 444 4 4 4 + 5 - blue 555 - 5 5 + 6 cindy - - 6 - - + 8 dave - - 8 - - + 9 - - 999 - - 9 + } + do_execsql_test join9-$id.405 { + SELECT id, x, y, z, t4.id, t5.id, t6.id + FROM t6 NATURAL FULL JOIN t4 NATURAL FULL JOIN t5 + ORDER BY id; + } { + 0 - - 1000 - - 0 + 1 - red - - 1 - + 2 alice orange - 2 2 - + 3 - yellow 333 - 3 3 + 4 bob green 444 4 4 4 + 5 - blue 555 - 5 5 + 6 cindy - - 6 - - + 8 dave - - 8 - - + 9 - - 999 - - 9 + } + do_execsql_test join9-$id.406 { + SELECT id, x, y, z, t4.id, t5.id, t6.id + FROM t6 NATURAL FULL JOIN t5 NATURAL FULL JOIN t4 + ORDER BY id; + } { + 0 - - 1000 - - 0 + 1 - red - - 1 - + 2 alice orange - 2 2 - + 3 - yellow 333 - 3 3 + 4 bob green 444 4 4 4 + 5 - blue 555 - 5 5 + 6 cindy - - 6 - - + 8 dave - - 8 - - + 9 - - 999 - - 9 + } + + # Verified by PG-14 using case 1 + do_execsql_test join9-$id.500 { + SELECT id, w, x, y, z + FROM t3 FULL JOIN t4 USING(id) + NATURAL FULL JOIN t5 + FULL JOIN t6 USING(id) + ORDER BY 1; + } { + 0 - - - 1000 + 1 - - red - + 2 two alice orange - + 3 three - yellow 333 + 4 - bob green 444 + 5 - - blue 555 + 6 six cindy - - + 7 seven - - - + 8 - dave - - + 9 - - - 999 + } + + # Verified by PG-14 using case 1 + do_execsql_test join9-$id.600 { + SELECT id, w, x, y, z + FROM t3 JOIN dual ON true + FULL JOIN t4 USING(id) + JOIN dual AS d2 ON true + NATURAL FULL JOIN t5 + JOIN dual AS d3 ON true FULL + JOIN t6 USING(id) + CROSS JOIN dual AS d4 + ORDER BY 1; + } { + 0 - - - 1000 + 1 - - red - + 2 two alice orange - + 3 three - yellow 333 + 4 - bob green 444 + 5 - - blue 555 + 6 six cindy - - + 7 seven - - - + 8 - dave - - + 9 - - - 999 + } } finish_test From fe146997650b13b4adc306dcecc9c3617d2e326a Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 17 Apr 2022 18:46:17 +0000 Subject: [PATCH 155/259] Further improvements to USING() processing for RIGHT and FULL JOINs. All currently known issues are now resolved. Performace is improved. FossilOrigin-Name: 9fd3f22e2228dfba127f6ffe549109f3a4e910fa124adcc9c5483931bd6d5cd7 --- manifest | 14 ++--- manifest.uuid | 2 +- src/resolve.c | 20 +------ src/select.c | 159 ++++++++++++++++++-------------------------------- 4 files changed, 68 insertions(+), 127 deletions(-) diff --git a/manifest b/manifest index 07f28c3684..3be5508455 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\stest\scases,\sone\sof\swhich\sis\sfailing,\sindicating\sa\sbug\sthat\sneeds\sfixing. -D 2022-04-16T23:38:29.234 +C Further\simprovements\sto\sUSING()\sprocessing\sfor\sRIGHT\sand\sFULL\sJOINs.\s\sAll\ncurrently\sknown\sissues\sare\snow\sresolved.\s\sPerformace\sis\simproved. +D 2022-04-17T18:46:17.120 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -550,9 +550,9 @@ F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c fd940149c691684e7c1073c3787a7170e44852b02d1275d2e30a5b58e89cfcaf F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c -F src/resolve.c 58b5c54b7e5cd7101b57901f9039dee86224b6a93699a5e8639f402aff43e7cc +F src/resolve.c d38fc50ba853bead084c571dae2218620655dfb952eb535b8f29c9757e92fa87 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 0af8c196a4b3fdf5fa4f6aae4045758467d143efd32711bfc4bf711e8e8a04cc +F src/select.c 1d0c3aece7221fb1e5b10f636eed074ee1318d7bb93e1029004d84447f825562 F src/shell.c.in eb7f10d5e2c47bd014d92ec5db1def21fcc1ed56ffaaa4ee715b6c37c370b47f F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1948,8 +1948,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 9ffc2b231956cde1bc90519aa174b0e2dc30ef671ed745f4f3ffa9fbb7ffab4b -R 6e1aaa1b139d709bc01047520c7bb6df +P bd5fd68435ff068c18d7d46b33cf7591263a03c32a917a7df7c087b08c573cc8 +R 59e0d103b473769389ca9e8aa4f28bed U drh -Z d4fc26ab748be0192a3f4dfcc716caef +Z de5ba2466670ff117c1fafe3df9d0ad6 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 94e1a8b487..8f14605142 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bd5fd68435ff068c18d7d46b33cf7591263a03c32a917a7df7c087b08c573cc8 \ No newline at end of file +9fd3f22e2228dfba127f6ffe549109f3a4e910fa124adcc9c5483931bd6d5cd7 \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index 09b16f1ad2..0f0b853060 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -115,22 +115,6 @@ static void resolveAlias( } } - -/* -** Return TRUE if the name zCol occurs anywhere in the USING clause. -** -** Return FALSE if the USING clause is NULL or if it does not contain -** zCol. -*/ -static int nameInUsingClause(IdList *pUsing, const char *zCol){ - int k; - assert( pUsing!=0 ); - for(k=0; knId; k++){ - if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ) return 1; - } - return 0; -} - /* ** Subqueries stores the original database, table and column names for their ** result sets in ExprList.a[].zSpan, in the form "DATABASE.TABLE.COLUMN". @@ -338,7 +322,7 @@ static int lookupName( if( sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb) ){ if( cnt>0 ){ if( pItem->fg.isUsing==0 - || !nameInUsingClause(pItem->u3.pUsing, zCol) + || sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0 ){ sqlite3ExprListDelete(db, pFJMatch); pFJMatch = 0; @@ -392,7 +376,7 @@ static int lookupName( ){ if( cnt>0 ){ if( pItem->fg.isUsing==0 - || !nameInUsingClause(pItem->u3.pUsing, zCol) + || sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0 ){ sqlite3ExprListDelete(db, pFJMatch); pFJMatch = 0; diff --git a/src/select.c b/src/select.c index f6938ccabe..db41172098 100644 --- a/src/select.c +++ b/src/select.c @@ -320,11 +320,9 @@ int sqlite3ColumnIndex(Table *pTab, const char *zCol){ } /* -** Search the first N tables in pSrc, looking for a -** table that has a column named zCol. -** -** Search left-to-right if bRightmost is false. Search right-to-left -** if bRightmost is true. +** Search the tables iStart..iEnd (inclusive) in pSrc, looking for a +** table that has a column named zCol. The search is left-to-right. +** The first match found is returned. ** ** When found, set *piTab and *piCol to the table index and column index ** of the matching column and return TRUE. @@ -333,21 +331,21 @@ int sqlite3ColumnIndex(Table *pTab, const char *zCol){ */ static int tableAndColumnIndex( SrcList *pSrc, /* Array of tables to search */ - int N, /* Number of tables in pSrc->a[] to search */ + int iStart, /* First member of pSrc->a[] to check */ + int iEnd, /* Last member of pSrc->a[] to check */ const char *zCol, /* Name of the column we are looking for */ int *piTab, /* Write index of pSrc->a[] here */ int *piCol, /* Write index of pSrc->a[*piTab].pTab->aCol[] here */ - int bIgnoreHidden, /* True to ignore hidden columns */ - int bRightmost /* Return the right-most match */ + int bIgnoreHidden /* Ignore hidden columns */ ){ int i; /* For looping over tables in pSrc */ int iCol; /* Index of column matching zCol */ - int rc = 0; - assert( N<=pSrc->nSrc ); - + assert( iEndnSrc ); + assert( iStart>=0 ); assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */ - for(i=0; ia[i].pTab, zCol); if( iCol>=0 && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pTab->aCol[iCol])==0) @@ -356,58 +354,10 @@ static int tableAndColumnIndex( *piTab = i; *piCol = iCol; } - rc = 1; - if( !bRightmost ) break; + return 1; } } - return rc; -} - -/* -** This function is used to add terms implied by JOIN syntax to the -** WHERE clause expression of a SELECT statement. The new term, which -** is ANDed with the existing WHERE clause, is of the form: -** -** (tab1.col1 = tab2.col2) -** -** where tab1 is the iSrc'th table in SrcList pSrc and tab2 is the -** (iSrc+1)'th. Column col1 is column iColLeft of tab1, and col2 is -** column iColRight of tab2. -*/ -static void addWhereTerm( - Parse *pParse, /* Parsing context */ - SrcList *pSrc, /* List of tables in FROM clause */ - int iLeft, /* Index of first table to join in pSrc */ - int iColLeft, /* Index of column in first table */ - int iRight, /* Index of second table in pSrc */ - int iColRight, /* Index of column in second table */ - u32 joinType, /* EP_FromJoin or EP_InnerJoin */ - Expr **ppWhere /* IN/OUT: The WHERE clause to add to */ -){ - sqlite3 *db = pParse->db; - Expr *pE1; - Expr *pE2; - Expr *pEq; - - assert( iLeftnSrc>iRight ); - assert( pSrc->a[iLeft].pTab ); - assert( pSrc->a[iRight].pTab ); - - pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iColLeft); - pE2 = sqlite3CreateColumnExpr(db, pSrc, iRight, iColRight); - - pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2); - assert( pE2!=0 || pEq==0 ); /* Due to db->mallocFailed test - ** in sqlite3DbMallocRawNN() called from - ** sqlite3PExpr(). */ - if( pEq ){ - ExprSetProperty(pEq, joinType); - assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) ); - ExprSetVVAProperty(pEq, EP_NoReduce); - pEq->w.iJoin = pE2->iTable; - } - *ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq); + return 0; } /* @@ -532,7 +482,7 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ if( IsHiddenColumn(&pRightTab->aCol[j]) ) continue; zName = pRightTab->aCol[j].zCnName; - if( tableAndColumnIndex(pSrc, i+1, zName, 0, 0, 1, 0) ){ + if( tableAndColumnIndex(pSrc, 0, i, zName, 0, 0, 1) ){ Token x; x.z = zName; x.n = sqlite3Strlen30(zName); @@ -555,64 +505,71 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ */ if( pRight->fg.isUsing ){ IdList *pList = pRight->u3.pUsing; - int bRight = (pLeft->fg.jointype & JT_RIGHT)!=0; + sqlite3 *db = pParse->db; assert( pList!=0 ); for(j=0; jnId; j++){ char *zName; /* Name of the term in the USING clause */ int iLeft; /* Table on the left with matching column name */ int iLeftCol; /* Column number of matching column on the left */ int iRightCol; /* Column number of matching column on the right */ - int iNxLeft, iNxLeftCol; + Expr *pE1; /* Reference to the column on the LEFT of the join */ + Expr *pE2; /* Reference to the column on the RIGHT of the join */ + Expr *pEq; /* Equality constraint. pE1 == pE2 */ zName = pList->a[j].zName; iRightCol = sqlite3ColumnIndex(pRightTab, zName); if( iRightCol<0 - || !tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol, - pRight->fg.isSynthUsing, bRight) + || tableAndColumnIndex(pSrc, 0, i, zName, &iLeft, &iLeftCol, + pRight->fg.isSynthUsing)==0 ){ sqlite3ErrorMsg(pParse, "cannot join using column %s - column " "not present in both tables", zName); return 1; } - if( (pLeft->fg.jointype & (JT_RIGHT|JT_LEFT))!=(JT_LEFT|JT_RIGHT) - || 0==tableAndColumnIndex(pSrc, iLeft, zName, &iNxLeft, &iNxLeftCol, - pRight->fg.isSynthUsing, 1) - ){ - addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, iRightCol, - joinType, &p->pWhere); - }else{ - /* Because the left-hand side of this join is another RIGHT or FULL - ** JOIN with two or more tables hold zName, we need to construct - ** a coalesce() function for left side of the ON constraint. + pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol); + if( (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ + /* This branch runs if the query contains one or more RIGHT or FULL + ** JOINs. If only a single table on the left side of this join + ** contains the zName column, then this routine is branch is + ** a no-op. But if there are two or more tables on the left side + ** of the join, construct a coalesce() function that gathers all + ** such tables. Raise an error if more than one of those references + ** to zName is not also within a prior USING clause. + ** + ** We really ought to raise an error if there are two or more + ** non-USING references to zName on the left of an INNER or LEFT + ** JOIN. But older versions of SQLite do not do that, so we avoid + ** adding a new error so as to not break legacy applications. */ - ExprList *pList; - Expr *pE; - Expr *pE2; - Expr *pEq; - sqlite3 *db = pParse->db; + ExprList *pFuncArgs = 0; /* Arguments to the coalesce() */ static const Token tkCoalesce = { "coalesce", 8 }; - pE = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol); - pList = sqlite3ExprListAppend(pParse, 0, pE); - pE = sqlite3CreateColumnExpr(db, pSrc, iNxLeft, iNxLeftCol); - pList = sqlite3ExprListAppend(pParse, pList, pE); - while( tableAndColumnIndex(pSrc, iNxLeft, zName, - &iNxLeft, &iNxLeftCol, - pRight->fg.isSynthUsing, 1)!=0 ){ - pE = sqlite3CreateColumnExpr(db, pSrc, iNxLeft, iNxLeftCol); - pList = sqlite3ExprListAppend(pParse, pList, pE); + while( tableAndColumnIndex(pSrc, iLeft+1, i, zName, &iLeft, &iLeftCol, + pRight->fg.isSynthUsing)!=0 ){ + if( pSrc->a[iLeft].fg.isUsing==0 + || sqlite3IdListIndex(pSrc->a[iLeft].u3.pUsing, zName)<0 + ){ + sqlite3ErrorMsg(pParse, "ambiguous reference to %s in USING()", + zName); + break; + } + pFuncArgs = sqlite3ExprListAppend(pParse, pFuncArgs, pE1); + pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol); } - pE = sqlite3ExprFunction(pParse, pList, &tkCoalesce, 0); - pE2 = sqlite3CreateColumnExpr(db, pSrc, i+1, iRightCol); - pEq = sqlite3PExpr(pParse, TK_EQ, pE, pE2); - assert( pE2!=0 || pEq==0 ); - if( pEq ){ - ExprSetProperty(pEq, joinType); - assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) ); - ExprSetVVAProperty(pEq, EP_NoReduce); - pEq->w.iJoin = pE2->iTable; + if( pFuncArgs ){ + pFuncArgs = sqlite3ExprListAppend(pParse, pFuncArgs, pE1); + pE1 = sqlite3ExprFunction(pParse, pFuncArgs, &tkCoalesce, 0); } - p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pEq); } + pE2 = sqlite3CreateColumnExpr(db, pSrc, i+1, iRightCol); + pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2); + assert( pE2!=0 || pEq==0 ); + if( pEq ){ + ExprSetProperty(pEq, joinType); + assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) ); + ExprSetVVAProperty(pEq, EP_NoReduce); + pEq->w.iJoin = pE2->iTable; + } + p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pEq); } } From 2bd9f44a1867c7d91bebb756a998fe1dda09d8f4 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 17 Apr 2022 20:30:52 +0000 Subject: [PATCH 156/259] Change OP_Return such that if P3 is 1, the Return is a no-op when the P1 register contains a NULL. FossilOrigin-Name: c90602328a4b26f06d76c5343d29ebb7a782186c86ea88f5965a41040cff5346 --- manifest | 18 +++++++-------- manifest.uuid | 2 +- src/expr.c | 12 +++++----- src/vdbe.c | 62 +++++++++++++++++++++++++++++++------------------- src/where.c | 8 +++---- src/whereInt.h | 1 - 6 files changed, 58 insertions(+), 45 deletions(-) diff --git a/manifest b/manifest index 3be5508455..ff4937a423 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\simprovements\sto\sUSING()\sprocessing\sfor\sRIGHT\sand\sFULL\sJOINs.\s\sAll\ncurrently\sknown\sissues\sare\snow\sresolved.\s\sPerformace\sis\simproved. -D 2022-04-17T18:46:17.120 +C Change\sOP_Return\ssuch\sthat\sif\sP3\sis\s1,\sthe\sReturn\sis\sa\sno-op\swhen\sthe\nP1\sregister\scontains\sa\sNULL. +D 2022-04-17T20:30:52.124 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -503,7 +503,7 @@ F src/date.c 15082566229d4b1e5f24fdb490bf9bcc68824b911d70e3573ef075a1b9e2d26f F src/dbpage.c 90661a87e1db8bfbc8d2ebbdcd3749651ddb287c555c07a28fb17c7c591ffb68 F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d F src/delete.c a8e844af211a48b13b5b358be77a12c860c6a557c21990ad51a548e2536500ce -F src/expr.c 5f4fa51dde6af4f7a622f4f6b04bcdae400bf7ef0090c37b9a03740113ad71c0 +F src/expr.c efde3f5034b94999ce34458ddcc43d9a82de7b43cf3a0d377b74585af7f140a1 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 94927f9b46d72a9cb858c208febf04ceb0a3270c5fa5fd0b7f436cf16e09f72a F src/func.c a3407a6fbb0d4088d8d502e46f0ace63e0aeae7467ae23a9ca9815bbf9239761 @@ -624,7 +624,7 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c b72147e70498ad005eece5c6336bfa1b9eaff09a673044eb866df8e402d1f12f +F src/vdbe.c 1b48646ce4824b4e3aa31b1aa278200b87b4218fedc2f606a25f1a467a978c87 F src/vdbe.h 89f5edb1422c8783a0b29db836e409876f2b3e847f78e2b21b1fbcc48a93f85f F src/vdbeInt.h ef43f7fdc5fde29fc3fd29c506c12830f366178fdb4edbbf0cbc3dfbd1278b5f F src/vdbeapi.c 354c893f1500cf524cc45c32879b9c68893a28b77e3442c24668d6afe4236217 @@ -639,8 +639,8 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c 963c06826218535bcebc8a8c41dcb2a8abf3cd340022d5b2cb503e7ce328cc47 -F src/whereInt.h ea1e4b6639c4c32246f4c54b733143df76109894adf08bedee4f3999ece62c2d +F src/where.c cbbfdcbf701cc018f1a688da53b082f9cf2ea067ecadd0648ecd6c4244ecc4da +F src/whereInt.h eecce79edc6f7005f91f35be6b18b7053f794e1b50e95bcd06a2d537fc176734 F src/wherecode.c cb747d628e8fdc0396529c07be9c772c2978016a723eba9c3329f8ef5e4411f1 F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 F src/window.c 42a71595263dbd8ef8248218e4fc7d4b5ddccece52146ad48e079342d93f6f8f @@ -1948,8 +1948,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 bd5fd68435ff068c18d7d46b33cf7591263a03c32a917a7df7c087b08c573cc8 -R 59e0d103b473769389ca9e8aa4f28bed +P 9fd3f22e2228dfba127f6ffe549109f3a4e910fa124adcc9c5483931bd6d5cd7 +R 18079ef5a0c4d399c9c19e3618838c8a U drh -Z de5ba2466670ff117c1fafe3df9d0ad6 +Z 584bf1a379a2119bed4485fb42b41022 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8f14605142..133b551cdc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9fd3f22e2228dfba127f6ffe549109f3a4e910fa124adcc9c5483931bd6d5cd7 \ No newline at end of file +c90602328a4b26f06d76c5343d29ebb7a782186c86ea88f5965a41040cff5346 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 4e036c9343..b90d537d8d 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3175,9 +3175,9 @@ void sqlite3CodeRhsOfIN( assert( ExprUseYSub(pExpr) ); assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn || pParse->nErr ); - sqlite3VdbeAddOp2(v, OP_Return, pExpr->y.sub.regReturn, - pExpr->y.sub.iAddr); - sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1); + sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, + pExpr->y.sub.iAddr, 1); + VdbeCoverage(v); sqlite3ClearTempRegCache(pParse); } } @@ -3306,9 +3306,9 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ assert( ExprUseYSub(pExpr) ); assert( sqlite3VdbeGetOp(v,pExpr->y.sub.iAddr-1)->opcode==OP_BeginSubrtn || pParse->nErr ); - sqlite3VdbeAddOp2(v, OP_Return, pExpr->y.sub.regReturn, - pExpr->y.sub.iAddr); - sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1); + sqlite3VdbeAddOp3(v, OP_Return, pExpr->y.sub.regReturn, + pExpr->y.sub.iAddr, 1); + VdbeCoverage(v); sqlite3ClearTempRegCache(pParse); return rReg; } diff --git a/src/vdbe.c b/src/vdbe.c index 283151d1fc..ca94f06419 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -988,12 +988,17 @@ case OP_Gosub: { /* jump */ /* Opcode: Return P1 P2 P3 * * ** -** Jump to the next instruction after the address stored in register P1. +** Jump to the address stored in register P1. If P1 is a return address +** register, then this accomplishes a return from a subroutine. ** -** It used to be that after the jump, register P1 would become undefined. -** However, for the subroutine used for the inner loop of a RIGHT JOIN, -** it is useful for R1 register to be unchanged, so that is what happens -** now. +** If P3 is 1, then the jump is only taken if register P1 holds an integer +** values, otherwise execution falls through to the next opcode, and the +** OP_Return becomes a no-op. If P3 is 0, then register P1 must hold an +** integer or else an assert() is raised. P3 should be set to 1 when +** this opcode is used in combination with OP_BeginSubrtn, and set to 0 +** otherwise. +** +** The value in register P1 is unchanged by this opcode. ** ** P2 is not used by the byte-code engine. However, if P2 is positive ** and also less than the current address, then the "EXPLAIN" output @@ -1002,16 +1007,15 @@ case OP_Gosub: { /* jump */ ** in the subroutine from which this opcode is returnning. Thus the P2 ** value is a byte-code indentation hint. See tag-20220407a in ** wherecode.c and shell.c. -** -** P3 is not used by the byte-code engine. However, the code generator -** sets P3 to address of the associated OP_BeginSubrtn opcode, if there is -** one. */ case OP_Return: { /* in1 */ pIn1 = &aMem[pOp->p1]; - assert( pIn1->flags==MEM_Int ); - pOp = &aOp[pIn1->u.i]; - /* pIn1->flags = MEM_Undefined; */ + if( pIn1->flags & MEM_Int ){ + if( pOp->p3 ) VdbeBranchTaken(1, 2); + pOp = &aOp[pIn1->u.i]; + }else if( ALWAYS(pOp->p3) ){ + VdbeBranchTaken(0, 2); + } break; } @@ -1197,22 +1201,11 @@ case OP_Halt: { goto vdbe_return; } -/* Opcode: BeginSubrtn P1 P2 * * * -** Synopsis: r[P2]=P1 -** -** Mark the beginning of a subroutine by loading the integer value P1 -** into register r[P2]. The P2 register is used to store the return -** address of the subroutine call. -** -** This opcode is identical to OP_Integer. It has a different name -** only to make the byte code easier to read and verify. -*/ /* Opcode: Integer P1 P2 * * * ** Synopsis: r[P2]=P1 ** ** The 32-bit integer value P1 is written into register P2. */ -case OP_BeginSubrtn: case OP_Integer: { /* out2 */ pOut = out2Prerelease(p, pOp); pOut->u.i = pOp->p1; @@ -1319,6 +1312,28 @@ case OP_String: { /* out2 */ break; } +/* Opcode: BeginSubrtn * P2 * * * +** Synopsis: r[P2]=NULL +** +** Mark the beginning of a subroutine that can be entered in-line +** or that can be called using OP_Gosub. The subroutine should +** be terminated by an OP_Return instruction that has a P1 operand that +** is the same as the P2 operand to this opcode and that has P3 set to 1. +** If the subroutine is entered in-line, then the OP_Return will simply +** fall through. But if the subroutine is entered using OP_Gosub, then +** the OP_Return will jump back to the first instruction after the OP_Gosub. +** +** This routine works by loading a NULL into the P2 register. When the +** return address register contains a NULL, the OP_Return instruction is +** a no-op that simply falls through to the next instruction (assuming that +** the OP_Return opcode has a P3 value of 1). Thus if the subroutine is +** entered in-line, then the OP_Return will cause in-line execution to +** continue. But if the subroutine is entered via OP_Gosub, then the +** OP_Return will cause a return to the address following the OP_Gosub. +** +** This opcode is identical to OP_Null. It has a different name +** only to make the byte code easier to read and verify. +*/ /* Opcode: Null P1 P2 P3 * * ** Synopsis: r[P2..P3]=NULL ** @@ -1331,6 +1346,7 @@ case OP_String: { /* out2 */ ** NULL values will not compare equal even if SQLITE_NULLEQ is set on ** OP_Ne or OP_Eq. */ +case OP_BeginSubrtn: case OP_Null: { /* out2 */ int cnt; u16 nullFlag; diff --git a/src/where.c b/src/where.c index 7b37db2158..8755ccd2ce 100644 --- a/src/where.c +++ b/src/where.c @@ -5883,7 +5883,7 @@ WhereInfo *sqlite3WhereBegin( pRJ->regBloom = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Blob, 65536, pRJ->regBloom); pRJ->regReturn = ++pParse->nMem; - pRJ->addrInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, pRJ->regReturn); + sqlite3VdbeAddOp2(v, OP_Null, 0, pRJ->regReturn); assert( pTab==pTabItem->pTab ); if( HasRowid(pTab) ){ KeyInfo *pInfo; @@ -6022,12 +6022,10 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ /* Terminate the subroutine that forms the interior of the loop of ** the RIGHT JOIN table */ WhereRightJoin *pRJ = pLevel->pRJ; - int addrHere = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeChangeP1(v, pRJ->addrSubrtn-1, addrHere); - sqlite3VdbeChangeP1(v, pRJ->addrInit, addrHere); sqlite3VdbeResolveLabel(v, pLevel->addrCont); pLevel->addrCont = 0; - sqlite3VdbeAddOp2(v, OP_Return, pRJ->regReturn, pRJ->addrSubrtn); + sqlite3VdbeAddOp3(v, OP_Return, pRJ->regReturn, pRJ->addrSubrtn, 1); + VdbeCoverage(v); assert( pParse->withinRJSubrtn>0 ); pParse->withinRJSubrtn--; } diff --git a/src/whereInt.h b/src/whereInt.h index c8a188f80c..acc9ec3ddd 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -52,7 +52,6 @@ struct WhereRightJoin { int regBloom; /* Bloom filter for iRJMatch */ int regReturn; /* Return register for the interior subroutine */ int addrSubrtn; /* Starting address for the interior subroutine */ - int addrInit; /* OP_Integer used for early init of regReturn */ }; /* From f68621fe83984d264c690fce98fb3f2e5dd7f99f Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 17 Apr 2022 22:58:23 +0000 Subject: [PATCH 157/259] Deal with OP_Return bypass in the RIGHT JOIN subroutine by adding extra OP_Returns where needed. FossilOrigin-Name: 71abe5641f599f27d1f0c800f6182e1168909f8aa99389b835b07d4b5f5483eb --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 4 ++++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index ff4937a423..e4a8d10814 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sOP_Return\ssuch\sthat\sif\sP3\sis\s1,\sthe\sReturn\sis\sa\sno-op\swhen\sthe\nP1\sregister\scontains\sa\sNULL. -D 2022-04-17T20:30:52.124 +C Deal\swith\sOP_Return\sbypass\sin\sthe\sRIGHT\sJOIN\ssubroutine\sby\sadding\sextra\nOP_Returns\swhere\sneeded. +D 2022-04-17T22:58:23.198 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -639,7 +639,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c cbbfdcbf701cc018f1a688da53b082f9cf2ea067ecadd0648ecd6c4244ecc4da +F src/where.c 45102d682f6efd450d89c0c5f09b838be6d69c84c6105336730ee38d3b452fad F src/whereInt.h eecce79edc6f7005f91f35be6b18b7053f794e1b50e95bcd06a2d537fc176734 F src/wherecode.c cb747d628e8fdc0396529c07be9c772c2978016a723eba9c3329f8ef5e4411f1 F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 @@ -1948,8 +1948,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 9fd3f22e2228dfba127f6ffe549109f3a4e910fa124adcc9c5483931bd6d5cd7 -R 18079ef5a0c4d399c9c19e3618838c8a +P c90602328a4b26f06d76c5343d29ebb7a782186c86ea88f5965a41040cff5346 +R c6c7dddd732c43b8717c6704e8264673 U drh -Z 584bf1a379a2119bed4485fb42b41022 +Z 0ea458b3f473eb82432ab8cf97d554a5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 133b551cdc..d418abf9d8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c90602328a4b26f06d76c5343d29ebb7a782186c86ea88f5965a41040cff5346 \ No newline at end of file +71abe5641f599f27d1f0c800f6182e1168909f8aa99389b835b07d4b5f5483eb \ No newline at end of file diff --git a/src/where.c b/src/where.c index 8755ccd2ce..8526f7c5ab 100644 --- a/src/where.c +++ b/src/where.c @@ -6121,6 +6121,10 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ } } sqlite3VdbeResolveLabel(v, pLevel->addrBrk); + if( pLevel->pRJ ){ + sqlite3VdbeAddOp3(v, OP_Return, pLevel->pRJ->regReturn, 0, 1); + VdbeCoverage(v); + } if( pLevel->addrSkip ){ sqlite3VdbeGoto(v, pLevel->addrSkip); VdbeComment((v, "next skip-scan on %s", pLoop->u.btree.pIndex->zName)); From a3e2518bb349d9f635ac3599e2f39cc733d2ad44 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sun, 17 Apr 2022 23:46:18 +0000 Subject: [PATCH 158/259] Fix to the logic that computes coalesc() functions to resolve USING terms. FossilOrigin-Name: 20388548d868511f8c8437718985d75fe9801835811fec716f1700727b9aa367 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/resolve.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index e4a8d10814..f0c9f00d2b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Deal\swith\sOP_Return\sbypass\sin\sthe\sRIGHT\sJOIN\ssubroutine\sby\sadding\sextra\nOP_Returns\swhere\sneeded. -D 2022-04-17T22:58:23.198 +C Fix\sto\sthe\slogic\sthat\scomputes\scoalesc()\sfunctions\sto\sresolve\sUSING\sterms. +D 2022-04-17T23:46:18.306 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -550,7 +550,7 @@ F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c fd940149c691684e7c1073c3787a7170e44852b02d1275d2e30a5b58e89cfcaf F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c -F src/resolve.c d38fc50ba853bead084c571dae2218620655dfb952eb535b8f29c9757e92fa87 +F src/resolve.c c6591eb339fb21e907485020cb2b7967a6ebd61533bec8841fb12d154e99a7fa F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 1d0c3aece7221fb1e5b10f636eed074ee1318d7bb93e1029004d84447f825562 F src/shell.c.in eb7f10d5e2c47bd014d92ec5db1def21fcc1ed56ffaaa4ee715b6c37c370b47f @@ -1948,8 +1948,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 c90602328a4b26f06d76c5343d29ebb7a782186c86ea88f5965a41040cff5346 -R c6c7dddd732c43b8717c6704e8264673 +P 71abe5641f599f27d1f0c800f6182e1168909f8aa99389b835b07d4b5f5483eb +R 8fb229091ea6e9ef20c8b036edcf4ea5 U drh -Z 0ea458b3f473eb82432ab8cf97d554a5 +Z aeae6fd254922cd510b69a69105d63ce # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d418abf9d8..c53f6ff17d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -71abe5641f599f27d1f0c800f6182e1168909f8aa99389b835b07d4b5f5483eb \ No newline at end of file +20388548d868511f8c8437718985d75fe9801835811fec716f1700727b9aa367 \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index 0f0b853060..d114dfc467 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -680,6 +680,7 @@ static int lookupName( pExpr->op = TK_FUNCTION; pExpr->u.zToken = "coalesce"; pExpr->x.pList = pFJMatch; + cnt = 1; goto lookupname_end; }else{ sqlite3ExprListDelete(db, pFJMatch); From d0453f7ec53693c32b058909ebb3d954ffe0c054 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 18 Apr 2022 00:04:15 +0000 Subject: [PATCH 159/259] When converting a NATURAL JOIN into a JOIN USING, make sure to insert the name correctly into the IdList even if it is a wierd quoted name. FossilOrigin-Name: e62156b696f2496e2697cb3b46f136551b58644e2a5824aa3d759596694b2f4b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 10 ++++++---- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index f0c9f00d2b..e68f297a3c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sto\sthe\slogic\sthat\scomputes\scoalesc()\sfunctions\sto\sresolve\sUSING\sterms. -D 2022-04-17T23:46:18.306 +C When\sconverting\sa\sNATURAL\sJOIN\sinto\sa\sJOIN\sUSING,\smake\ssure\sto\sinsert\sthe\nname\scorrectly\sinto\sthe\sIdList\seven\sif\sit\sis\sa\swierd\squoted\sname. +D 2022-04-18T00:04:15.097 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -552,7 +552,7 @@ F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c c6591eb339fb21e907485020cb2b7967a6ebd61533bec8841fb12d154e99a7fa F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 1d0c3aece7221fb1e5b10f636eed074ee1318d7bb93e1029004d84447f825562 +F src/select.c fcfa9e78068a9b7e7e8ae5e99dd9ad67b494f8af494c83d608e22bf3a24dc1a2 F src/shell.c.in eb7f10d5e2c47bd014d92ec5db1def21fcc1ed56ffaaa4ee715b6c37c370b47f F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1948,8 +1948,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 71abe5641f599f27d1f0c800f6182e1168909f8aa99389b835b07d4b5f5483eb -R 8fb229091ea6e9ef20c8b036edcf4ea5 +P 20388548d868511f8c8437718985d75fe9801835811fec716f1700727b9aa367 +R 47315d601cc104e0c12b223bfb8b1dba U drh -Z aeae6fd254922cd510b69a69105d63ce +Z 7934b697ad8bfcf0f014801a6142f07d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c53f6ff17d..77981c4449 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -20388548d868511f8c8437718985d75fe9801835811fec716f1700727b9aa367 \ No newline at end of file +e62156b696f2496e2697cb3b46f136551b58644e2a5824aa3d759596694b2f4b \ No newline at end of file diff --git a/src/select.c b/src/select.c index db41172098..b41a44cff1 100644 --- a/src/select.c +++ b/src/select.c @@ -483,10 +483,12 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ if( IsHiddenColumn(&pRightTab->aCol[j]) ) continue; zName = pRightTab->aCol[j].zCnName; if( tableAndColumnIndex(pSrc, 0, i, zName, 0, 0, 1) ){ - Token x; - x.z = zName; - x.n = sqlite3Strlen30(zName); - pUsing = sqlite3IdListAppend(pParse, pUsing, &x); + pUsing = sqlite3IdListAppend(pParse, pUsing, 0); + if( pUsing ){ + assert( pUsing->nId>0 ); + assert( pUsing->a[pUsing->nId-1].zName==0 ); + pUsing->a[pUsing->nId-1].zName = sqlite3DbStrDup(pParse->db, zName); + } } } if( pUsing ){ From 79a25ee0215401931c33b0c2630e2523c53f445d Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 18 Apr 2022 00:57:11 +0000 Subject: [PATCH 160/259] Fix to the coalesce() function generation in the resolver. FossilOrigin-Name: 584bd55e20669d09b7efe3429ba847c42c32fb1eb960784c4e0dedcd96899313 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/resolve.c | 10 ++++------ 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index e68f297a3c..4dd3668654 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sconverting\sa\sNATURAL\sJOIN\sinto\sa\sJOIN\sUSING,\smake\ssure\sto\sinsert\sthe\nname\scorrectly\sinto\sthe\sIdList\seven\sif\sit\sis\sa\swierd\squoted\sname. -D 2022-04-18T00:04:15.097 +C Fix\sto\sthe\scoalesce()\sfunction\sgeneration\sin\sthe\sresolver. +D 2022-04-18T00:57:11.470 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -550,7 +550,7 @@ F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c fd940149c691684e7c1073c3787a7170e44852b02d1275d2e30a5b58e89cfcaf F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c -F src/resolve.c c6591eb339fb21e907485020cb2b7967a6ebd61533bec8841fb12d154e99a7fa +F src/resolve.c ce4cb0889f1bf5990b698740b88026385cf6f30222fde1f02a3168bb780eb579 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c fcfa9e78068a9b7e7e8ae5e99dd9ad67b494f8af494c83d608e22bf3a24dc1a2 F src/shell.c.in eb7f10d5e2c47bd014d92ec5db1def21fcc1ed56ffaaa4ee715b6c37c370b47f @@ -1948,8 +1948,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 20388548d868511f8c8437718985d75fe9801835811fec716f1700727b9aa367 -R 47315d601cc104e0c12b223bfb8b1dba +P e62156b696f2496e2697cb3b46f136551b58644e2a5824aa3d759596694b2f4b +R bdbe7ed2c4fc36f304a762252cc7a276 U drh -Z 7934b697ad8bfcf0f014801a6142f07d +Z c9db4d2e3dbbaf57eb9975f4478e4f80 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 77981c4449..d3f35cd80e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e62156b696f2496e2697cb3b46f136551b58644e2a5824aa3d759596694b2f4b \ No newline at end of file +584bd55e20669d09b7efe3429ba847c42c32fb1eb960784c4e0dedcd96899313 \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index d114dfc467..76e635acff 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -205,11 +205,9 @@ static void extendFJMatch( ){ Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0); if( pNew ){ - Table *pTab; pNew->iTable = pMatch->iCursor; - assert( ExprUseYTab(pNew) ); - pTab = pNew->y.pTab = pMatch->pTab; - pNew->iColumn = iColumn==pTab->iPKey ? -1 : iColumn; + pNew->iColumn = iColumn; + pNew->y.pTab = pMatch->pTab; assert( (pMatch->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 ); ExprSetProperty(pNew, EP_CanBeNull); *ppList = sqlite3ExprListAppend(pParse, *ppList, pNew); @@ -342,7 +340,7 @@ static int lookupName( pFJMatch = 0; }else{ /* For a FULL JOIN, we must construct a coalesce() func */ - extendFJMatch(pParse, &pFJMatch, pMatch, j); + extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn); } } cnt++; @@ -396,7 +394,7 @@ static int lookupName( pFJMatch = 0; }else{ /* For a FULL JOIN, we must construct a coalesce() func */ - extendFJMatch(pParse, &pFJMatch, pMatch, j); + extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn); } } cnt++; From abf86bd3133c71c5eae6203699dc9e469f981ab7 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 18 Apr 2022 09:59:33 +0000 Subject: [PATCH 161/259] Leave sqlite3ProcessJoin() early if an OOM is encountered in the NATURAL to USING converter. This avoids NULL pointer dereferences further along in the code. FossilOrigin-Name: 0ccb224e13ad44c7e1a3aa186821a929faabc0075fe15799476c00d9a92e9d91 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 4dd3668654..dadd1cbe4d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sto\sthe\scoalesce()\sfunction\sgeneration\sin\sthe\sresolver. -D 2022-04-18T00:57:11.470 +C Leave\ssqlite3ProcessJoin()\searly\sif\san\sOOM\sis\sencountered\sin\sthe\sNATURAL\nto\sUSING\sconverter.\s\sThis\savoids\sNULL\spointer\sdereferences\sfurther\salong\sin\nthe\scode. +D 2022-04-18T09:59:33.646 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -552,7 +552,7 @@ F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c ce4cb0889f1bf5990b698740b88026385cf6f30222fde1f02a3168bb780eb579 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c fcfa9e78068a9b7e7e8ae5e99dd9ad67b494f8af494c83d608e22bf3a24dc1a2 +F src/select.c 6544e02167adbb89a7152acf6ff2f0218a6de94146377b83e79bc8b09bf6f16e F src/shell.c.in eb7f10d5e2c47bd014d92ec5db1def21fcc1ed56ffaaa4ee715b6c37c370b47f F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1948,8 +1948,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 e62156b696f2496e2697cb3b46f136551b58644e2a5824aa3d759596694b2f4b -R bdbe7ed2c4fc36f304a762252cc7a276 +P 584bd55e20669d09b7efe3429ba847c42c32fb1eb960784c4e0dedcd96899313 +R ca8f575b2af503ca4b68b7060e8a8208 U drh -Z c9db4d2e3dbbaf57eb9975f4478e4f80 +Z 9aaf25063fb0e8b19b18a7c621baebac # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d3f35cd80e..a2cbf273c4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -584bd55e20669d09b7efe3429ba847c42c32fb1eb960784c4e0dedcd96899313 \ No newline at end of file +0ccb224e13ad44c7e1a3aa186821a929faabc0075fe15799476c00d9a92e9d91 \ No newline at end of file diff --git a/src/select.c b/src/select.c index b41a44cff1..6d185a1685 100644 --- a/src/select.c +++ b/src/select.c @@ -496,6 +496,7 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ pRight->fg.isSynthUsing = 1; pRight->u3.pUsing = pUsing; } + if( pParse->nErr ) return 1; } /* Create extra terms on the WHERE clause for each column named From d973268ccfc5c545faa346ad6e6e236a936f6ef2 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 18 Apr 2022 10:09:29 +0000 Subject: [PATCH 162/259] Fix the sqlite3SrcListAppendList() routine so that it correctly adds the JT_LTORJ attribute to the first SrcItem, if needed. FossilOrigin-Name: 07ed0dca310d828f9fe152efa8ee2a89202771a8f661afa1dbeee34aaabef67a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/build.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index dadd1cbe4d..539aa8cb55 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Leave\ssqlite3ProcessJoin()\searly\sif\san\sOOM\sis\sencountered\sin\sthe\sNATURAL\nto\sUSING\sconverter.\s\sThis\savoids\sNULL\spointer\sdereferences\sfurther\salong\sin\nthe\scode. -D 2022-04-18T09:59:33.646 +C Fix\sthe\ssqlite3SrcListAppendList()\sroutine\sso\sthat\sit\scorrectly\sadds\nthe\sJT_LTORJ\sattribute\sto\sthe\sfirst\sSrcItem,\sif\sneeded. +D 2022-04-18T10:09:29.854 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -495,7 +495,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 093c940ddf1d0753542d04e37eb9903cbc126e997815d234dd2b6317e812b192 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482e -F src/build.c d6518b209ec89e0b0c744564213369b772b00efa698c3f121d14cf25c5806ade +F src/build.c f7098ca5006891b1877fb2e8f9aa52243338983696123f5a4e30fa9dda06debc F src/callback.c 4c19af69835787bfe790ac560f3071a824eb629f34e41f97b52ce5235c77de1c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 026dbdcdbd8c3cde98a88483ee88310ff43150ab164ad768f12cc700a11495ad @@ -1948,8 +1948,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 584bd55e20669d09b7efe3429ba847c42c32fb1eb960784c4e0dedcd96899313 -R ca8f575b2af503ca4b68b7060e8a8208 +P 0ccb224e13ad44c7e1a3aa186821a929faabc0075fe15799476c00d9a92e9d91 +R 868a3abe5b71496a81ccd2968e4bc123 U drh -Z 9aaf25063fb0e8b19b18a7c621baebac +Z 4d37f6a11fcac66c4ed7fb866c6b8bbc # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a2cbf273c4..b6fbaa25a3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0ccb224e13ad44c7e1a3aa186821a929faabc0075fe15799476c00d9a92e9d91 \ No newline at end of file +07ed0dca310d828f9fe152efa8ee2a89202771a8f661afa1dbeee34aaabef67a \ No newline at end of file diff --git a/src/build.c b/src/build.c index cf277b9073..126897c856 100644 --- a/src/build.c +++ b/src/build.c @@ -5032,6 +5032,7 @@ SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2){ p1 = pNew; memcpy(&p1->a[1], p2->a, p2->nSrc*sizeof(SrcItem)); sqlite3DbFree(pParse->db, p2); + p1->a[0].fg.jointype |= (JT_LTORJ & p1->a[1].fg.jointype); } } return p1; From d875c7eefec1d7e6192948f87c8b34ce98b0ca45 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 18 Apr 2022 10:26:50 +0000 Subject: [PATCH 163/259] Do not allow an empty table bypass to jump outside of a right-join body subroutine. FossilOrigin-Name: 1549dcd2353903b70abadd428eeef971ab940df04fb05a6b83b04ee30932db6d --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/wherecode.c | 5 ++++- test/join8.test | 24 +++++++++++++----------- 4 files changed, 25 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index 539aa8cb55..618e2ae14f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\ssqlite3SrcListAppendList()\sroutine\sso\sthat\sit\scorrectly\sadds\nthe\sJT_LTORJ\sattribute\sto\sthe\sfirst\sSrcItem,\sif\sneeded. -D 2022-04-18T10:09:29.854 +C Do\snot\sallow\san\sempty\stable\sbypass\sto\sjump\soutside\sof\sa\sright-join\sbody\nsubroutine. +D 2022-04-18T10:26:50.482 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -641,7 +641,7 @@ F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b F src/where.c 45102d682f6efd450d89c0c5f09b838be6d69c84c6105336730ee38d3b452fad F src/whereInt.h eecce79edc6f7005f91f35be6b18b7053f794e1b50e95bcd06a2d537fc176734 -F src/wherecode.c cb747d628e8fdc0396529c07be9c772c2978016a723eba9c3329f8ef5e4411f1 +F src/wherecode.c 4e03f17f8e7b89b9f85d14d705944acf0b0adff3de47753bdd99cf98b0142997 F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 F src/window.c 42a71595263dbd8ef8248218e4fc7d4b5ddccece52146ad48e079342d93f6f8f F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1147,7 +1147,7 @@ F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test c4df54e2e204d7f1417bfbdd21ca324b4b07415c647595cc47798eacfddc96d3 F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c F test/join7.test e5c9b1b729d7e1d0b4195e99833e0ff0cf2d88e7fdd32b49af1044f4c76f72d9 -F test/join8.test 4f085a233582724be035e83100f458c4cfdd8101699c27feac2782242c037682 +F test/join8.test 8a4cea60cc57ad95f0c718f460d86a7a239fbb50eaf2fa37b66d5f195f40220c F test/join9.test afd899f0bda3db6d5fefae2275ad91802d056c7dcd109030100b87e0b75f47ff F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 @@ -1948,8 +1948,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 0ccb224e13ad44c7e1a3aa186821a929faabc0075fe15799476c00d9a92e9d91 -R 868a3abe5b71496a81ccd2968e4bc123 +P 07ed0dca310d828f9fe152efa8ee2a89202771a8f661afa1dbeee34aaabef67a +R a87b222d27880866b7dfd28f3fc0e49d U drh -Z 4d37f6a11fcac66c4ed7fb866c6b8bbc +Z 6dba88c851bb0b27e425f682c55f1888 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b6fbaa25a3..176d66942a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -07ed0dca310d828f9fe152efa8ee2a89202771a8f661afa1dbeee34aaabef67a \ No newline at end of file +1549dcd2353903b70abadd428eeef971ab940df04fb05a6b83b04ee30932db6d \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index f08a4c2806..e4a7b449f1 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1516,7 +1516,10 @@ Bitmask sqlite3WhereCodeOneLoopStart( /* Compute a safe address to jump to if we discover that the table for ** this loop is empty and can never contribute content. */ - for(j=iLevel; j>0 && pWInfo->a[j].iLeftJoin==0; j--){} + for(j=iLevel; j>0; j--){ + if( pWInfo->a[j].iLeftJoin ) break; + if( pWInfo->a[j].pRJ ) break; + } addrHalt = pWInfo->a[j].addrBrk; /* Special case of a FROM clause subquery implemented as a co-routine */ diff --git a/test/join8.test b/test/join8.test index 0317722fd0..c99b0f8c64 100644 --- a/test/join8.test +++ b/test/join8.test @@ -35,20 +35,22 @@ do_execsql_test join8-10 { # do_test join8-issue-1 {set rc "Issue-1 'row-value subroutine' unresolved"} {} -# Pending issue #2: +# Pending issue #2: (now resolved) # Jump to addrHalt inside the RIGHT JOIN body subroutine bypasses the # OP_Return, resulting in a subroutine loop. Test case: # -# CREATE TABLE t1(a int, b int, c int); -# INSERT INTO t1 VALUES(1,2,3),(4,5,6); -# CREATE TABLE t2(d int, e int); -# INSERT INTO t2 VALUES(3,333),(4,444); -# CREATE TABLE t3(f int, g int); -# PRAGMA automatic_index=off; -# .eqp trace -# SELECT * FROM t1 RIGHT JOIN t2 ON c=d JOIN t3 ON f=e; -# -do_test join8-issue-2 {set rc "Issue-2 'jump to addrHalt' unresolved"} {} +reset_db +do_execsql_test join8-2000 { + CREATE TABLE t1(a int, b int, c int); + INSERT INTO t1 VALUES(1,2,3),(4,5,6); + CREATE TABLE t2(d int, e int); + INSERT INTO t2 VALUES(3,333),(4,444); + CREATE TABLE t3(f int, g int); + PRAGMA automatic_index=off; +} {} +do_catchsql_test join8-2010 { + SELECT * FROM t1 RIGHT JOIN t2 ON c=d JOIN t3 ON f=e; +} {0 {}} # Demonstrate that nested FULL JOINs and USING clauses work # From a1848a5d225a1abf434d2d2da83d3f808951effc Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 18 Apr 2022 11:22:46 +0000 Subject: [PATCH 164/259] Change the row-value initialization subroutine call from within the right-join body subroutine from an issue to an optimization opportunity. FossilOrigin-Name: 829d49f27c041651ffeadc1397e4dd87a9994c9290e13b93542dbd2c514769cd --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/join8.test | 37 +++++++++++++++++++++++++++++-------- 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 618e2ae14f..ed0f446fb0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sallow\san\sempty\stable\sbypass\sto\sjump\soutside\sof\sa\sright-join\sbody\nsubroutine. -D 2022-04-18T10:26:50.482 +C Change\sthe\srow-value\sinitialization\ssubroutine\scall\sfrom\swithin\sthe\nright-join\sbody\ssubroutine\sfrom\san\sissue\sto\san\soptimization\sopportunity. +D 2022-04-18T11:22:46.211 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1147,7 +1147,7 @@ F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test c4df54e2e204d7f1417bfbdd21ca324b4b07415c647595cc47798eacfddc96d3 F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c F test/join7.test e5c9b1b729d7e1d0b4195e99833e0ff0cf2d88e7fdd32b49af1044f4c76f72d9 -F test/join8.test 8a4cea60cc57ad95f0c718f460d86a7a239fbb50eaf2fa37b66d5f195f40220c +F test/join8.test 6ed7eed8993e060e5e9d07f6bcadf1bb634742a03b9824afbcfa193adf7f9965 F test/join9.test afd899f0bda3db6d5fefae2275ad91802d056c7dcd109030100b87e0b75f47ff F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 @@ -1948,8 +1948,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 07ed0dca310d828f9fe152efa8ee2a89202771a8f661afa1dbeee34aaabef67a -R a87b222d27880866b7dfd28f3fc0e49d +P 1549dcd2353903b70abadd428eeef971ab940df04fb05a6b83b04ee30932db6d +R bf21b74f8101c167d0386cef1bd86b5d U drh -Z 6dba88c851bb0b27e425f682c55f1888 +Z 5ad80f89a1f49f3de1c0f70362c7802e # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 176d66942a..f65776145d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1549dcd2353903b70abadd428eeef971ab940df04fb05a6b83b04ee30932db6d \ No newline at end of file +829d49f27c041651ffeadc1397e4dd87a9994c9290e13b93542dbd2c514769cd \ No newline at end of file diff --git a/test/join8.test b/test/join8.test index c99b0f8c64..5ef85c4cf8 100644 --- a/test/join8.test +++ b/test/join8.test @@ -22,18 +22,39 @@ do_execsql_test join8-10 { SELECT avg(DISTINCT b) FROM (SELECT * FROM t2 LEFT RIGHT JOIN t1 ON c); } {NULL} -# Pending issue #1: +# Pending optimization opportunity: # Row-value initialization subroutines must be called from with the # RIGHT JOIN body subroutine before the first use of any register containing # the results of that subroutine. This seems dodgy. Test case: # -# CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT,b,c,d,e,f,g,h,j,k,l,m,n,o,p,q,r,s); -# CREATE INDEX t1x1 ON t1(g+h,j,k); -# CREATE INDEX t1x2 ON t1(b); -# INSERT INTO t1 DEFAULT VALUES; -# SELECT a FROM (SELECT a FROM (SELECT a FROM (SELECT a FROM t1 NATURAL LEFT JOIN t1 WHERE (b, 2 ) IS ( SELECT 2 IN(2,2),2)) NATURAL LEFT FULL JOIN t1 WHERE ( rowid , 1 )<=(CASE 5 WHEN 619 THEN 841 ELSE 3374391096 END,0) ORDER BY a ASC) NATURAL LEFT JOIN t1 WHERE (b, 2 ) IS ( SELECT 3 IN(3,3),3)) NATURAL LEFT FULL JOIN t1 WHERE ( rowid , 1 )<=(CASE 5 WHEN 619 THEN 841 ELSE 3374391096 END,0) ORDER BY a ASC; -# -do_test join8-issue-1 {set rc "Issue-1 'row-value subroutine' unresolved"} {} +reset_db +do_execsql_test join8-1000 { + CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT,b,c,d,e,f,g,h,j,k,l,m,n,o,p,q,r,s); + CREATE INDEX t1x1 ON t1(g+h,j,k); + CREATE INDEX t1x2 ON t1(b); + INSERT INTO t1 DEFAULT VALUES; +} {} +do_catchsql_test join8-1010 { + SELECT a + FROM ( + SELECT a + FROM ( + SELECT a + FROM ( + SELECT a FROM t1 NATURAL LEFT JOIN t1 + WHERE (b, 2 ) IS ( SELECT 2 IN(2,2),2) + ) + NATURAL LEFT FULL JOIN t1 + WHERE ( rowid , 1 )<=(CASE 5 WHEN 619 THEN 841 ELSE 3374391096 END,0) + ORDER BY a ASC + ) + NATURAL LEFT JOIN t1 + WHERE (b, 2 ) IS ( SELECT 3 IN(3,3),3) + ) + NATURAL LEFT FULL JOIN t1 + WHERE ( rowid , 1 )<=(CASE 5 WHEN 619 THEN 841 ELSE 3374391096 END,0) + ORDER BY a ASC; +} {0 1} # Pending issue #2: (now resolved) # Jump to addrHalt inside the RIGHT JOIN body subroutine bypasses the From 01a6c16e0c5bdfa5c2d36f5d9a401dd54dd95c78 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 18 Apr 2022 13:08:17 +0000 Subject: [PATCH 165/259] New RIGHT JOIN test cases, one of which is currently failing. FossilOrigin-Name: 9168cbbedd1c9d735279295a78212d830e24269f6d7e445e71faa2c06973223d --- manifest | 12 +++---- manifest.uuid | 2 +- test/join9.test | 95 ++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 98 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index ed0f446fb0..1eb18fd580 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\srow-value\sinitialization\ssubroutine\scall\sfrom\swithin\sthe\nright-join\sbody\ssubroutine\sfrom\san\sissue\sto\san\soptimization\sopportunity. -D 2022-04-18T11:22:46.211 +C New\sRIGHT\sJOIN\stest\scases,\sone\sof\swhich\sis\scurrently\sfailing. +D 2022-04-18T13:08:17.738 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1148,7 +1148,7 @@ F test/join5.test c4df54e2e204d7f1417bfbdd21ca324b4b07415c647595cc47798eacfddc96 F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c F test/join7.test e5c9b1b729d7e1d0b4195e99833e0ff0cf2d88e7fdd32b49af1044f4c76f72d9 F test/join8.test 6ed7eed8993e060e5e9d07f6bcadf1bb634742a03b9824afbcfa193adf7f9965 -F test/join9.test afd899f0bda3db6d5fefae2275ad91802d056c7dcd109030100b87e0b75f47ff +F test/join9.test f5db0954fe5aee36fbecb75a80c764d5f0a4b35335016c5829b0d2616039df6e F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -1948,8 +1948,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 1549dcd2353903b70abadd428eeef971ab940df04fb05a6b83b04ee30932db6d -R bf21b74f8101c167d0386cef1bd86b5d +P 829d49f27c041651ffeadc1397e4dd87a9994c9290e13b93542dbd2c514769cd +R 6347c73ed0e7137db9741231b5b4504b U drh -Z 5ad80f89a1f49f3de1c0f70362c7802e +Z e66211318cb81105e5a2b7fa53682c62 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f65776145d..bb4aeed99f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -829d49f27c041651ffeadc1397e4dd87a9994c9290e13b93542dbd2c514769cd \ No newline at end of file +9168cbbedd1c9d735279295a78212d830e24269f6d7e445e71faa2c06973223d \ No newline at end of file diff --git a/test/join9.test b/test/join9.test index 69f7dcbd5f..e0edb7bc7b 100644 --- a/test/join9.test +++ b/test/join9.test @@ -33,13 +33,76 @@ foreach {id schema} { CREATE TABLE t4(id INT PRIMARY KEY, x TEXT) WITHOUT ROWID; CREATE TABLE t5(id INT PRIMARY KEY, y TEXT) WITHOUT ROWID; CREATE TABLE t6(id INT PRIMARY KEY, z INT) WITHOUT ROWID; - CREATE VIEW dual(dummy) AS VALUES('x'); + CREATE TABLE dual(dummy TEXT); + INSERT INTO dual(dummy) VALUES('x'); INSERT INTO t3(id,w) VALUES(2,'two'),(3,'three'),(6,'six'),(7,'seven'); INSERT INTO t4(id,x) VALUES(2,'alice'),(4,'bob'),(6,'cindy'),(8,'dave'); INSERT INTO t5(id,y) VALUES(1,'red'),(2,'orange'),(3,'yellow'),(4,'green'), (5,'blue'); INSERT INTO t6(id,z) VALUES(3,333),(4,444),(5,555),(0,1000),(9,999); } + 3 { + CREATE TABLE t3x(id INTEGER PRIMARY KEY, w TEXT); + CREATE TABLE t4x(id INTEGER PRIMARY KEY, x TEXT); + CREATE TABLE t5x(id INTEGER PRIMARY KEY, y TEXT); + CREATE TABLE t6x(id INTEGER PRIMARY KEY, z INT); + CREATE VIEW dual(dummy) AS VALUES('x'); + INSERT INTO t3x(id,w) VALUES(2,'two'),(3,'three'),(6,'six'),(7,'seven'); + INSERT INTO t4x(id,x) VALUES(2,'alice'),(4,'bob'),(6,'cindy'),(8,'dave'); + INSERT INTO t5x(id,y) VALUES(1,'red'),(2,'orange'),(3,'yellow'),(4,'green'), + (5,'blue'); + INSERT INTO t6x(id,z) VALUES(3,333),(4,444),(5,555),(0,1000),(9,999); + CREATE VIEW t3 AS SELECT * FROM t3x LIMIT 1000; + CREATE VIEW t4 AS SELECT * FROM t4x LIMIT 1000; + CREATE VIEW t5 AS SELECT * FROM t5x LIMIT 1000; + CREATE VIEW t6 AS SELECT * FROM t6x LIMIT 1000; + } + 4 { + CREATE TABLE t3a(id INTEGER PRIMARY KEY, w TEXT); + CREATE TABLE t3b(id INTEGER PRIMARY KEY, w TEXT); + CREATE TABLE t4a(id INTEGER PRIMARY KEY, x TEXT); + CREATE TABLE t4b(id INTEGER PRIMARY KEY, x TEXT); + CREATE TABLE t5a(id INTEGER PRIMARY KEY, y TEXT); + CREATE TABLE t5b(id INTEGER PRIMARY KEY, y TEXT); + CREATE TABLE t6a(id INTEGER PRIMARY KEY, z INT); + CREATE TABLE t6b(id INTEGER PRIMARY KEY, z INT); + CREATE VIEW dual(dummy) AS VALUES('x'); + INSERT INTO t3a(id,w) VALUES(2,'two'),(3,'three'); + INSERT INTO t3b(id,w) VALUES(6,'six'),(7,'seven'); + INSERT INTO t4a(id,x) VALUES(2,'alice'),(4,'bob'); + INSERT INTO t4b(id,x) VALUES(6,'cindy'),(8,'dave'); + INSERT INTO t5a(id,y) VALUES(1,'red'),(2,'orange'),(3,'yellow'); + INSERT INTO t5b(id,y) VALUES(4,'green'),(5,'blue'); + INSERT INTO t6a(id,z) VALUES(3,333),(4,444); + INSERT INTO t6b(id,z) VALUES(5,555),(0,1000),(9,999); + CREATE VIEW t3 AS SELECT * FROM t3a UNION ALL SELECT * FROM t3b; + CREATE VIEW t4 AS SELECT * FROM t4a UNION ALL SELECT * FROM t4b; + CREATE VIEW t5 AS SELECT * FROM t5a UNION ALL SELECT * FROM t5b; + CREATE VIEW t6 AS SELECT * FROM t6a UNION ALL SELECT * FROM t6b; + } + 5 { + CREATE TABLE t3a(id INTEGER PRIMARY KEY, w TEXT) WITHOUT ROWID; + CREATE TABLE t3b(id INTEGER PRIMARY KEY, w TEXT); + CREATE TABLE t4a(id INTEGER PRIMARY KEY, x TEXT) WITHOUT ROWID; + CREATE TABLE t4b(id INTEGER PRIMARY KEY, x TEXT) WITHOUT ROWID; + CREATE TABLE t5a(id INTEGER PRIMARY KEY, y TEXT); + CREATE TABLE t5b(id INTEGER PRIMARY KEY, y TEXT) WITHOUT ROWID; + CREATE TABLE t6a(id INTEGER PRIMARY KEY, z INT); + CREATE TABLE t6b(id INTEGER PRIMARY KEY, z INT); + CREATE VIEW dual(dummy) AS VALUES('x'); + INSERT INTO t3a(id,w) VALUES(2,'two'),(3,'three'); + INSERT INTO t3b(id,w) VALUES(6,'six'),(7,'seven'); + INSERT INTO t4a(id,x) VALUES(2,'alice'),(4,'bob'); + INSERT INTO t4b(id,x) VALUES(6,'cindy'),(8,'dave'); + INSERT INTO t5a(id,y) VALUES(1,'red'),(2,'orange'),(3,'yellow'); + INSERT INTO t5b(id,y) VALUES(4,'green'),(5,'blue'); + INSERT INTO t6a(id,z) VALUES(3,333),(4,444); + INSERT INTO t6b(id,z) VALUES(5,555),(0,1000),(9,999); + CREATE VIEW t3 AS SELECT * FROM t3a UNION ALL SELECT * FROM t3b; + CREATE VIEW t4 AS SELECT * FROM t4a UNION ALL SELECT * FROM t4b LIMIT 50; + CREATE VIEW t5 AS SELECT * FROM t5a UNION ALL SELECT * FROM t5b LIMIT 100; + CREATE VIEW t6 AS SELECT * FROM t6a UNION ALL SELECT * FROM t6b; + } } { reset_db db nullvalue - @@ -257,12 +320,12 @@ foreach {id schema} { # Verified by PG-14 using case 1 do_execsql_test join9-$id.600 { SELECT id, w, x, y, z - FROM t3 JOIN dual ON true + FROM t3 JOIN dual AS d1 ON true FULL JOIN t4 USING(id) JOIN dual AS d2 ON true NATURAL FULL JOIN t5 - JOIN dual AS d3 ON true FULL - JOIN t6 USING(id) + JOIN dual AS d3 ON true + FULL JOIN t6 USING(id) CROSS JOIN dual AS d4 ORDER BY 1; } { @@ -277,5 +340,29 @@ foreach {id schema} { 8 - dave - - 9 - - - 999 } + + # Verified by PG-14 using case 1 + do_execsql_test join9-$id.700 { + SELECT id, w, x, y, z + FROM t3 JOIN dual AS d1 ON true + FULL JOIN t4 USING(id) + JOIN dual AS d2 ON true + NATURAL FULL JOIN t5 + JOIN dual AS d3 ON true + FULL JOIN t6 USING(id) + CROSS JOIN dual AS d4 + WHERE x<>'bob' OR x IS NULL + ORDER BY 1; + } { + 0 - - - 1000 + 1 - - red - + 2 two alice orange - + 3 three - yellow 333 + 5 - - blue 555 + 6 six cindy - - + 7 seven - - - + 8 - dave - - + 9 - - - 999 + } } finish_test From 088b615acd1e2713dff4aef9e631e93b0293ab02 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 18 Apr 2022 13:57:57 +0000 Subject: [PATCH 166/259] Improved comment field in the bytecode generated for OP_Column and OP_Rowid. FossilOrigin-Name: 009bbf8026106c5a74cced06cced48badb870a4b6e6a2f8104a544d2a8d79e45 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 1 + src/vdbe.c | 4 ++-- src/vdbeaux.c | 7 ++++++- 5 files changed, 18 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index 1eb18fd580..b50049c60c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\sRIGHT\sJOIN\stest\scases,\sone\sof\swhich\sis\scurrently\sfailing. -D 2022-04-18T13:08:17.738 +C Improved\scomment\sfield\sin\sthe\sbytecode\sgenerated\sfor\sOP_Column\sand\sOP_Rowid. +D 2022-04-18T13:57:57.631 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -503,7 +503,7 @@ F src/date.c 15082566229d4b1e5f24fdb490bf9bcc68824b911d70e3573ef075a1b9e2d26f F src/dbpage.c 90661a87e1db8bfbc8d2ebbdcd3749651ddb287c555c07a28fb17c7c591ffb68 F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d F src/delete.c a8e844af211a48b13b5b358be77a12c860c6a557c21990ad51a548e2536500ce -F src/expr.c efde3f5034b94999ce34458ddcc43d9a82de7b43cf3a0d377b74585af7f140a1 +F src/expr.c 0714987d576d13acb64630274677ff0df336013bf83dfc1ff24a339b8ae2ae81 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 94927f9b46d72a9cb858c208febf04ceb0a3270c5fa5fd0b7f436cf16e09f72a F src/func.c a3407a6fbb0d4088d8d502e46f0ace63e0aeae7467ae23a9ca9815bbf9239761 @@ -624,11 +624,11 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c 1b48646ce4824b4e3aa31b1aa278200b87b4218fedc2f606a25f1a467a978c87 +F src/vdbe.c 4efdce17535c925a040cf289bef12e12f7be9e2e02825c67db52c4e8723b89fb F src/vdbe.h 89f5edb1422c8783a0b29db836e409876f2b3e847f78e2b21b1fbcc48a93f85f F src/vdbeInt.h ef43f7fdc5fde29fc3fd29c506c12830f366178fdb4edbbf0cbc3dfbd1278b5f F src/vdbeapi.c 354c893f1500cf524cc45c32879b9c68893a28b77e3442c24668d6afe4236217 -F src/vdbeaux.c c1718405a9ce07d84adc5bc36e17016f73170de1015d818bc82ebfdf76d88bad +F src/vdbeaux.c d1fce1d9c1045622d2a878ddcbec1c431eb186a17674b64ffe231e8d14db0451 F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 7189090b72baa025f945a1ac8c61ee420c645254476e8a191d555db76dfea5d4 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 @@ -1948,8 +1948,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 829d49f27c041651ffeadc1397e4dd87a9994c9290e13b93542dbd2c514769cd -R 6347c73ed0e7137db9741231b5b4504b +P 9168cbbedd1c9d735279295a78212d830e24269f6d7e445e71faa2c06973223d +R a4c354da2123e1486588766b1d4b51f3 U drh -Z e66211318cb81105e5a2b7fa53682c62 +Z 78587092c64ce3133bf29634c7d55b8b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index bb4aeed99f..a668ebd610 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9168cbbedd1c9d735279295a78212d830e24269f6d7e445e71faa2c06973223d \ No newline at end of file +009bbf8026106c5a74cced06cced48badb870a4b6e6a2f8104a544d2a8d79e45 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index b90d537d8d..eb3ba35ba1 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3742,6 +3742,7 @@ void sqlite3ExprCodeGetColumnOfTable( } if( iCol<0 || iCol==pTab->iPKey ){ sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut); + VdbeComment((v, "%s.rowid", pTab->zName)); }else{ int op; int x; diff --git a/src/vdbe.c b/src/vdbe.c index ca94f06419..65e843fd2b 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2679,7 +2679,7 @@ case OP_Offset: { /* out3 */ #endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */ /* Opcode: Column P1 P2 P3 P4 P5 -** Synopsis: r[P3]=PX +** Synopsis: r[P3]=PX cursor P1 column P2 ** ** Interpret the data that cursor P1 points to as a structure built using ** the MakeRecord instruction. (See the MakeRecord opcode for additional @@ -5761,7 +5761,7 @@ case OP_RowData: { } /* Opcode: Rowid P1 P2 * * * -** Synopsis: r[P2]=rowid +** Synopsis: r[P2]=PX rowid of P1 ** ** Store in register P2 an integer which is the key of the table entry that ** P1 is currently point to. diff --git a/src/vdbeaux.c b/src/vdbeaux.c index f598b0d545..eaf5780ab1 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1490,8 +1490,13 @@ char *sqlite3VdbeDisplayComment( if( c=='4' ){ sqlite3_str_appendall(&x, zP4); }else if( c=='X' ){ - sqlite3_str_appendall(&x, pOp->zComment); + if( pOp->zComment && pOp->zComment[0] ){ + sqlite3_str_appendall(&x, pOp->zComment); + }else{ + sqlite3_str_appendall(&x, zSynopsis+1); + } seenCom = 1; + break; }else{ int v1 = translateP(c, pOp); int v2; From e98b71e65dcb073550c80e8dcf9c37434cd17639 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 18 Apr 2022 14:15:07 +0000 Subject: [PATCH 167/259] Improved comment field in the bytecode generated for OP_Column and OP_Rowid. FossilOrigin-Name: 1b2c5cef9560123344db391cd065090d1914724715ec6643d2d9b5fac2051a21 --- manifest | 19 ++++++++++--------- manifest.uuid | 2 +- src/expr.c | 1 + src/vdbe.c | 4 ++-- src/vdbeaux.c | 7 ++++++- 5 files changed, 20 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 375c4eca36..275be40dfb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\sshell\sauto-column\swork\swith\slots\sof\scolumns\swhen\slog()\sis\smissing. -D 2022-04-16T17:53:25.671 +C Improved\scomment\sfield\sin\sthe\sbytecode\sgenerated\sfor\sOP_Column\sand\sOP_Rowid. +D 2022-04-18T14:15:07.659 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -503,7 +503,7 @@ F src/date.c 15082566229d4b1e5f24fdb490bf9bcc68824b911d70e3573ef075a1b9e2d26f F src/dbpage.c 90661a87e1db8bfbc8d2ebbdcd3749651ddb287c555c07a28fb17c7c591ffb68 F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d F src/delete.c a8e844af211a48b13b5b358be77a12c860c6a557c21990ad51a548e2536500ce -F src/expr.c 38a25dcba22bc6c9d8614e64624497aab1762911ba88e81fc55f1e67a85ebc16 +F src/expr.c 1d9a1eefd803c9f9b1cfed9015589157de173e0994b7a73e2d9cf5a267a77449 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c d965ede15d8360c09ed59348940649ee647b192e784466837d7aefa836d1d91e F src/func.c a3407a6fbb0d4088d8d502e46f0ace63e0aeae7467ae23a9ca9815bbf9239761 @@ -624,11 +624,11 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c 841057c12c1c4e2dcc7e51516a06aabb72d9898ab50484edef162b9218da65b0 +F src/vdbe.c e82071ff183d3cf9aa3afeefc40f10a2443e8056e16c38f6d80e041da7ec3fb2 F src/vdbe.h 89f5edb1422c8783a0b29db836e409876f2b3e847f78e2b21b1fbcc48a93f85f F src/vdbeInt.h 5f3d0abcf30c2b7a6672ad4386f18be0fca9c9b2cefe18f85a2e3df74f2613bf F src/vdbeapi.c 354c893f1500cf524cc45c32879b9c68893a28b77e3442c24668d6afe4236217 -F src/vdbeaux.c baafd56664ccca4cf361a48b912f7ff37f95ee19aaf7cada420ce2ca73396833 +F src/vdbeaux.c ac98cd2fbf32fd1dec548d362f69103b64ec391a3926bb64ab2e9cfa875f6b05 F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 7189090b72baa025f945a1ac8c61ee420c645254476e8a191d555db76dfea5d4 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 @@ -1945,8 +1945,9 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 04d5b637f087520cd58211505f9b5c086ff96d864a1908f60464b6fe22c62b7d -R 247d42769b42eb4f49b3d0e81a9caafe -U larrybr -Z 012ec694a47eae04b9be0b86d525b8a4 +P 82366436ef74838dae1f379f3e5b8ad187225a30ec58fb49f047ab7c08a263cf +Q +009bbf8026106c5a74cced06cced48badb870a4b6e6a2f8104a544d2a8d79e45 +R 7ec2e027f14c1113394a6f2b89ad97e8 +U drh +Z 913b185da9d2fc4d6a61edeeeba6fe46 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0034ef782e..da113a5941 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -82366436ef74838dae1f379f3e5b8ad187225a30ec58fb49f047ab7c08a263cf \ No newline at end of file +1b2c5cef9560123344db391cd065090d1914724715ec6643d2d9b5fac2051a21 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 78bb0c2ebf..f5916c53ee 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3748,6 +3748,7 @@ void sqlite3ExprCodeGetColumnOfTable( } if( iCol<0 || iCol==pTab->iPKey ){ sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut); + VdbeComment((v, "%s.rowid", pTab->zName)); }else{ int op; int x; diff --git a/src/vdbe.c b/src/vdbe.c index 092ccbcd1b..16b6f9bb55 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2659,7 +2659,7 @@ case OP_Offset: { /* out3 */ #endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */ /* Opcode: Column P1 P2 P3 P4 P5 -** Synopsis: r[P3]=PX +** Synopsis: r[P3]=PX cursor P1 column P2 ** ** Interpret the data that cursor P1 points to as a structure built using ** the MakeRecord instruction. (See the MakeRecord opcode for additional @@ -5742,7 +5742,7 @@ case OP_RowData: { } /* Opcode: Rowid P1 P2 * * * -** Synopsis: r[P2]=rowid +** Synopsis: r[P2]=PX rowid of P1 ** ** Store in register P2 an integer which is the key of the table entry that ** P1 is currently point to. diff --git a/src/vdbeaux.c b/src/vdbeaux.c index cb2433c2cd..a67bc68f9e 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1490,8 +1490,13 @@ char *sqlite3VdbeDisplayComment( if( c=='4' ){ sqlite3_str_appendall(&x, zP4); }else if( c=='X' ){ - sqlite3_str_appendall(&x, pOp->zComment); + if( pOp->zComment && pOp->zComment[0] ){ + sqlite3_str_appendall(&x, pOp->zComment); + }else{ + sqlite3_str_appendall(&x, zSynopsis+1); + } seenCom = 1; + break; }else{ int v1 = translateP(c, pOp); int v2; From 1942d1f2368e962c372c0adaf0ee2f0a909ce261 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 18 Apr 2022 15:56:58 +0000 Subject: [PATCH 168/259] Avoid an assert() failure in allocateSpace() triggered by a corrupt database. dbsqlfuzz f022eb0ce64d27808574d1dcde5cf7d002dabde8. FossilOrigin-Name: 2de7f8cc7fe18f0828bb53f1fd11f5eb828faf4d6dfaf39693dff4f8926c1c7a --- manifest | 17 +++++++------- manifest.uuid | 2 +- src/btree.c | 2 ++ test/corruptL.test | 55 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 66 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 275be40dfb..141bae7e73 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\scomment\sfield\sin\sthe\sbytecode\sgenerated\sfor\sOP_Column\sand\sOP_Rowid. -D 2022-04-18T14:15:07.659 +C Avoid\san\sassert()\sfailure\sin\sallocateSpace()\striggered\sby\sa\scorrupt\sdatabase.\sdbsqlfuzz\sf022eb0ce64d27808574d1dcde5cf7d002dabde8. +D 2022-04-18T15:56:58.902 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -492,7 +492,7 @@ F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf F src/backup.c a2891172438e385fdbe97c11c9745676bec54f518d4447090af97189fd8e52d7 F src/bitvec.c 7c849aac407230278445cb069bebc5f89bf2ddd87c5ed9459b070a9175707b3d F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c 093c940ddf1d0753542d04e37eb9903cbc126e997815d234dd2b6317e812b192 +F src/btree.c df695e953c2ce78ce4878ee5016751df9bc9a921dc0500a0f53ab3bb3196e505 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482e F src/build.c ff119be98394a65bc8be7afc39d4a791a66f03a778d396de3ec456f5dfaf39e8 @@ -814,7 +814,7 @@ F test/corruptH.test 79801d97ec5c2f9f3c87739aa1ec2eb786f96454 F test/corruptI.test a17bbf54fdde78d43cf3cc34b0057719fd4a173a3d824285b67dc5257c064c7b F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4 F test/corruptK.test 5b4212fe346699831c5ad559a62c54e11c0611bdde1ea8423a091f9c01aa32af -F test/corruptL.test 7d3440831ca24ba64305583c4d4506d417d3f89f5775c0b7cc8102db078f8ff5 +F test/corruptL.test 21a951d1eb09120f3c1561af5bac30ed49be2d9dfcad039f71759c5d9e28a349 F test/corruptM.test 7d574320e08c1b36caa3e47262061f186367d593a7e305d35f15289cc2c3e067 F test/corruptN.test 60b5a62944b4f0029ba07edaa5fd8e670539d6b0a8d99db26c068d435675cbfe F test/cost.test b11cdbf9f11ffe8ef99c9881bf390e61fe92baf2182bad1dbe6de59a7295c576 @@ -1945,9 +1945,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 82366436ef74838dae1f379f3e5b8ad187225a30ec58fb49f047ab7c08a263cf -Q +009bbf8026106c5a74cced06cced48badb870a4b6e6a2f8104a544d2a8d79e45 -R 7ec2e027f14c1113394a6f2b89ad97e8 -U drh -Z 913b185da9d2fc4d6a61edeeeba6fe46 +P 1b2c5cef9560123344db391cd065090d1914724715ec6643d2d9b5fac2051a21 +R e0f5c0c7d688fc682a2227f01f890489 +U dan +Z ae7698eacadb5d5e1bd63dbe1476a21d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index da113a5941..f29a4816df 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1b2c5cef9560123344db391cd065090d1914724715ec6643d2d9b5fac2051a21 \ No newline at end of file +2de7f8cc7fe18f0828bb53f1fd11f5eb828faf4d6dfaf39693dff4f8926c1c7a \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 734c92e46c..7ebdec5b62 100644 --- a/src/btree.c +++ b/src/btree.c @@ -1657,6 +1657,8 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){ ** fragmented bytes within the page. */ memcpy(&aData[iAddr], &aData[pc], 2); aData[hdr+7] += (u8)x; + testcase( pc+x>maxPC ); + return &aData[pc]; }else if( x+pc > maxPC ){ /* This slot extends off the end of the usable part of the page */ *pRc = SQLITE_CORRUPT_PAGE(pPg); diff --git a/test/corruptL.test b/test/corruptL.test index b7ff45d2ed..eef91b7747 100644 --- a/test/corruptL.test +++ b/test/corruptL.test @@ -1429,4 +1429,59 @@ do_catchsql_test 18.1 { } {1 {JSON cannot hold BLOB values}} } ;# ifcapable json1 +#------------------------------------------------------------------------- +reset_db +do_test 19.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +.open --hexdb +| size 20480 pagesize 4096 filename crash-f022eb0ce64d27.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 05 .....@ ........ +| 32: 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 04 ................ +| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................ +| 96: 00 00 00 00 0d 0f f8 00 04 0e d2 00 0f 08 0f d3 ................ +| 112: 0f ae 0e d2 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 3792: 00 00 34 04 06 17 0f 11 01 57 69 6e 64 65 78 61 ..4......Windexa +| 3808: 74 31 05 43 52 45 41 54 45 20 55 4e 49 51 55 45 t1.CREATE UNIQUE +| 3824: 20 49 4e 44 45 58 20 61 20 4f 4e 20 74 31 28 61 INDEX a ON t1(a +| 3840: 2c 20 30 20 7c 20 61 29 81 23 01 07 17 11 11 01 , 0 | a).#...... +| 3856: 82 31 74 61 62 6c 65 74 31 74 31 02 43 52 45 41 .1tablet1t1.CREA +| 3872: 54 45 20 54 41 42 4c 45 20 74 31 28 0a 20 20 20 TE TABLE t1(. +| 3888: 20 67 63 62 20 41 53 20 28 62 2a 31 29 2c 0a 20 gcb AS (b*1),. +| 3904: 20 20 20 61 20 49 34 54 45 47 45 52 20 50 52 49 a I4TEGER PRI +| 3920: 4d 41 52 59 20 4b 45 59 2c 0a 20 20 20 20 67 63 MARY KEY,. gc +| 3936: 63 20 41 53 20 28 74 32 2b 30 29 2c 0a 20 20 20 c AS (t2+0),. +| 3952: 20 62 20 55 4e 49 51 55 45 2c 0a 20 20 20 20 67 b UNIQUE,. g +| 3968: 63 61 20 41 53 20 28 31 2a 61 2b 30 29 2c 0a 20 ca AS (1*a+0),. +| 3984: 20 20 20 74 32 20 55 4e 49 51 55 45 0a 20 20 29 t2 UNIQUE. ) +| 4000: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 23 03 WITHOUT ROWID#. +| 4016: 06 17 37 11 01 00 69 6e 64 65 78 73 71 6c 69 74 ..7...indexsqlit +| 4032: 65 5f 61 75 74 6f 69 6e 64 65 78 5f 74 31 5f 33 e_autoindex_t1_3 +| 4048: 74 31 02 23 02 06 17 37 11 01 00 69 6e 64 65 78 t1.#...7...index +| 4064: 73 71 6c 69 74 65 5f 61 75 74 6f 69 6e 64 65 78 sqlite_autoindex +| 4080: 5f 74 31 5f 32 74 31 02 00 00 00 08 00 00 00 00 _t1_2t1......... +| page 2 offset 4096 +| 0: 0a 00 00 00 05 0f d8 00 0f f8 0f f8 9f e8 0f e0 ................ +| 16: 0f d8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 4048: 00 00 00 00 00 00 00 00 07 04 01 02 00 0f 13 88 ................ +| 4064: 07 04 01 02 00 0e 0f a0 07 04 01 02 00 0d 0b b8 ................ +| 4080: 07 04 01 02 00 0c 07 d0 07 04 01 02 00 0b 03 e8 ................ +| page 5 offset 16384 +| 0: 0a 00 00 00 05 0f e2 00 0f fa 0f f4 0f ee 0f e8 ................ +| 16: 0f e2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 4064: 00 00 05 03 01 01 0f 0f 05 03 01 01 0e 0e 05 03 ................ +| 4080: 01 01 0d 0d 05 03 01 01 0c 0c 05 03 01 01 0b 0b ................ +| end crash-f022eb0ce64d27.db +}]} {} + +do_execsql_test 19.1 { + PRAGMA writable_schema=ON; +} + +do_catchsql_test 19.2 { + UPDATE t1 SET a=1; +} {1 {UNIQUE constraint failed: index 'a'}} + finish_test From 2e1bcc9dd083888a7581d7db8c8fd7d0d9d98e17 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 18 Apr 2022 16:10:07 +0000 Subject: [PATCH 169/259] Fix problems with WHERE clauses that follow multiple FULL JOINs. This introduces some new faults in the tests, probably due to something unrelated. FossilOrigin-Name: 95b242d4c2fed7c713299565ac1010f8a7534a5695589e87d5a0204c7bf5f3dc --- manifest | 14 ++++----- manifest.uuid | 2 +- src/wherecode.c | 81 +++++++++++++++++++++++++++---------------------- test/join7.test | 20 ++++++++++-- 4 files changed, 70 insertions(+), 47 deletions(-) diff --git a/manifest b/manifest index c0b5272577..ee28bfc67b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\slatest\sfixes\sfrom\strunk. -D 2022-04-18T14:41:24.045 +C Fix\sproblems\swith\sWHERE\sclauses\sthat\sfollow\smultiple\sFULL\sJOINs.\s\sThis\nintroduces\ssome\snew\sfaults\sin\sthe\stests,\sprobably\sdue\sto\ssomething\nunrelated. +D 2022-04-18T16:10:07.804 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -641,7 +641,7 @@ F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b F src/where.c 45102d682f6efd450d89c0c5f09b838be6d69c84c6105336730ee38d3b452fad F src/whereInt.h eecce79edc6f7005f91f35be6b18b7053f794e1b50e95bcd06a2d537fc176734 -F src/wherecode.c 4e03f17f8e7b89b9f85d14d705944acf0b0adff3de47753bdd99cf98b0142997 +F src/wherecode.c 1770ab730f14949fe55104b7970e4646087b1ff7f78a906b275cb08ae256f027 F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 F src/window.c 42a71595263dbd8ef8248218e4fc7d4b5ddccece52146ad48e079342d93f6f8f F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1146,7 +1146,7 @@ F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test c4df54e2e204d7f1417bfbdd21ca324b4b07415c647595cc47798eacfddc96d3 F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c -F test/join7.test e5c9b1b729d7e1d0b4195e99833e0ff0cf2d88e7fdd32b49af1044f4c76f72d9 +F test/join7.test 8e72de4b45e5e930d18c305c7efe86015fb2552731e4e03ea226353036b0dab0 F test/join8.test 6ed7eed8993e060e5e9d07f6bcadf1bb634742a03b9824afbcfa193adf7f9965 F test/join9.test f5db0954fe5aee36fbecb75a80c764d5f0a4b35335016c5829b0d2616039df6e F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 @@ -1948,8 +1948,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 009bbf8026106c5a74cced06cced48badb870a4b6e6a2f8104a544d2a8d79e45 1b2c5cef9560123344db391cd065090d1914724715ec6643d2d9b5fac2051a21 -R 7231a9090bdeb7be15e705cd24ff1359 +P 1ba3b3ccf145d84fa75afabe2fa925f65e43f815b25b15bd60073a41aa97bf57 +R 7c5e9401c90d81242051e832c8ba8500 U drh -Z 90235891d6fa6cd74fed426055fa90a6 +Z 6ccb42e7d5486d8748e5216dc5361d97 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index db6197b441..3d64846252 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1ba3b3ccf145d84fa75afabe2fa925f65e43f815b25b15bd60073a41aa97bf57 \ No newline at end of file +95b242d4c2fed7c713299565ac1010f8a7534a5695589e87d5a0204c7bf5f3dc \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index e4a7b449f1..ca02acf45a 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -2706,27 +2706,6 @@ Bitmask sqlite3WhereCodeOneLoopStart( pAlt->wtFlags |= TERM_CODED; } - /* For a LEFT OUTER JOIN, generate code that will record the fact that - ** at least one row of the right table has matched the left table. - */ - if( pLevel->iLeftJoin ){ - pLevel->addrFirst = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin); - VdbeComment((v, "record LEFT JOIN hit")); - for(pTerm=pWC->a, j=0; jnBase; j++, pTerm++){ - testcase( pTerm->wtFlags & TERM_VIRTUAL ); - testcase( pTerm->wtFlags & TERM_CODED ); - if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; - if( (pTerm->prereqAll & pLevel->notReady)!=0 ){ - assert( pWInfo->untestedTerms ); - continue; - } - assert( pTerm->pExpr ); - sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL); - pTerm->wtFlags |= TERM_CODED; - } - } - /* For a RIGHT OUTER JOIN, record the fact that the current row has ** been matched at least once. */ @@ -2759,19 +2738,45 @@ Bitmask sqlite3WhereCodeOneLoopStart( } jmp1 = sqlite3VdbeAddOp4Int(v, OP_Found, pRJ->iMatch, 0, r+1, nPk); VdbeCoverage(v); + VdbeComment((v, "match against %s", pTab->zName)); sqlite3VdbeAddOp3(v, OP_MakeRecord, r+1, nPk, r); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pRJ->iMatch, r, r+1, nPk); sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pRJ->regBloom, 0, r+1, nPk); sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); sqlite3VdbeJumpHere(v, jmp1); sqlite3ReleaseTempRange(pParse, r, nPk+1); + } + /* For a LEFT OUTER JOIN, generate code that will record the fact that + ** at least one row of the right table has matched the left table. + */ + if( pLevel->iLeftJoin ){ + pLevel->addrFirst = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin); + VdbeComment((v, "record LEFT JOIN hit")); + for(pTerm=pWC->a, j=0; jnBase; j++, pTerm++){ + testcase( pTerm->wtFlags & TERM_VIRTUAL ); + testcase( pTerm->wtFlags & TERM_CODED ); + if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; + if( (pTerm->prereqAll & pLevel->notReady)!=0 ){ + assert( pWInfo->untestedTerms ); + continue; + } + if( pTabItem->fg.jointype & JT_LTORJ ) continue; + assert( pTerm->pExpr ); + sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL); + pTerm->wtFlags |= TERM_CODED; + } + } + + if( pLevel->pRJ ){ /* Create a subroutine used to process all interior loops and code ** of the RIGHT JOIN. During normal operation, the subroutine will ** be in-line with the rest of the code. But at the end, a separate ** loop will run that invokes this subroutine for unmatched rows ** of pTab, with all tables to left begin set to NULL. */ + WhereRightJoin *pRJ = pLevel->pRJ; sqlite3VdbeAddOp2(v, OP_BeginSubrtn, 0, pRJ->regReturn); pRJ->addrSubrtn = sqlite3VdbeCurrentAddr(v); assert( pParse->withinRJSubrtn < 255 ); @@ -2814,23 +2819,25 @@ SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( int k; ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pTab->zName)); - for(k=0; ka[k].pWLoop->maskSelf; - sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur); - iIdxCur = pWInfo->a[k].iIdxCur; - if( iIdxCur ){ - sqlite3VdbeAddOp1(v, OP_NullRow, iIdxCur); + if( (pTabItem->fg.jointype & JT_LTORJ)==0 ){ + for(k=0; ka[k].pWLoop->maskSelf; + sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur); + iIdxCur = pWInfo->a[k].iIdxCur; + if( iIdxCur ){ + sqlite3VdbeAddOp1(v, OP_NullRow, iIdxCur); + } + } + mAll |= pLoop->maskSelf; + for(k=0; knTerm; k++){ + WhereTerm *pTerm = &pWC->a[k]; + if( pTerm->wtFlags & TERM_VIRTUAL ) break; + if( pTerm->prereqAll & ~mAll ) continue; + if( ExprHasProperty(pTerm->pExpr, EP_FromJoin|EP_InnerJoin) ) continue; + pSubWhere = sqlite3ExprAnd(pParse, pSubWhere, + sqlite3ExprDup(pParse->db, pTerm->pExpr, 0)); } - } - mAll |= pLoop->maskSelf; - for(k=0; knTerm; k++){ - WhereTerm *pTerm = &pWC->a[k]; - if( pTerm->wtFlags & TERM_VIRTUAL ) break; - if( pTerm->prereqAll & ~mAll ) continue; - if( ExprHasProperty(pTerm->pExpr, EP_FromJoin|EP_InnerJoin) ) continue; - pSubWhere = sqlite3ExprAnd(pParse, pSubWhere, - sqlite3ExprDup(pParse->db, pTerm->pExpr, 0)); } sFrom.nSrc = 1; sFrom.nAlloc = 1; diff --git a/test/join7.test b/test/join7.test index a0507be1d9..a665ba1a93 100644 --- a/test/join7.test +++ b/test/join7.test @@ -102,6 +102,8 @@ foreach {id schema} { reset_db db nullvalue NULL do_execsql_test join7-$id.setup $schema {} + + # Verified against PG-14 for case 1 do_execsql_test join7-$id.10 { SELECT b, d FROM t1 FULL OUTER JOIN t2 ON b=c ORDER BY +b; } { @@ -110,6 +112,8 @@ foreach {id schema} { 3 33 4 44 } + + # Verified against PG-14 for case 1 do_execsql_test join7-$id.20 { SELECT a, c FROM t1 FULL OUTER JOIN t2 ON b=c ORDER BY +b; } { @@ -118,6 +122,7 @@ foreach {id schema} { 1 3 1 4 } + do_execsql_test join7-$id.30 { SELECT * FROM t1 FULL OUTER JOIN t2 ON b=c ORDER BY +b; } { @@ -201,6 +206,8 @@ foreach {id schema} { 1 3 3 33 1 4 4 44 } + + # Verified against PG-14 for case 1 do_execsql_test join7-$id.110 { SELECT * FROM t1 FULL OUTER JOIN t2 ON b=c WHERE a=1 ORDER BY +b; } { @@ -208,6 +215,7 @@ foreach {id schema} { 1 3 3 33 1 4 4 44 } + do_execsql_test join7-$id.111 { SELECT t1.*, t2.* FROM t2 FULL OUTER JOIN t1 ON b=c WHERE a=1 ORDER BY +b; } { @@ -215,6 +223,8 @@ foreach {id schema} { 1 3 3 33 1 4 4 44 } + + # Verified against PG-14 for case 1 do_execsql_test join7-$id.115 { SELECT * FROM t1 FULL OUTER JOIN t2 ON b=c WHERE a=1 OR a IS NULL ORDER BY +b; @@ -224,6 +234,7 @@ foreach {id schema} { 1 3 3 33 1 4 4 44 } + do_execsql_test join7-$id.116 { SELECT t1.*, t2.* FROM t2 FULL OUTER JOIN t1 ON b=c WHERE a=1 OR a IS NULL ORDER BY +b; @@ -233,13 +244,15 @@ foreach {id schema} { 1 3 3 33 1 4 4 44 } + + # Verified against PG-14 for case 1: do_execsql_test join7-$id.120 { SELECT * FROM t1 FULL OUTER JOIN t2 ON b=c WHERE a IS NULL ORDER BY +d; } { - NULL NULL 3 33 - NULL NULL 4 44 NULL NULL 5 55 } + + # Verified against PG-14 for case 1: do_execsql_test join7-$id.130 { SELECT * FROM t1 FULL OUTER JOIN t2 ON b=c AND d<=0 ORDER BY +b, +d; } { @@ -250,6 +263,8 @@ foreach {id schema} { 1 3 NULL NULL 1 4 NULL NULL } + + # Verified against PG-14 for case 1: do_execsql_test join7-$id.140 { SELECT a, b, c, d FROM t2 FULL OUTER JOIN t1 ON b=c AND d<=0 ORDER BY +b, +d; @@ -261,6 +276,7 @@ foreach {id schema} { 1 3 NULL NULL 1 4 NULL NULL } + do_execsql_test join7-$id.141 { SELECT a, b, c, d FROM t2 FULL OUTER JOIN t1 ON b=c AND d<=0 From 7348ca4e0b92cccf3d94c89190b3664e3106f738 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 18 Apr 2022 16:20:59 +0000 Subject: [PATCH 170/259] Ensure that left-hand side WITHOUT ROWID tables are set to OP_NullRow prior to running the right-join loop. This fixes a problem introduced by the previous check-in. FossilOrigin-Name: aab7665ce6c004df701a72aef1a5135f2c78f16c6ff728a00076afb66ba9d3a0 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/wherecode.c | 18 +++++++++--------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index ee28bfc67b..34c4db93e0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sproblems\swith\sWHERE\sclauses\sthat\sfollow\smultiple\sFULL\sJOINs.\s\sThis\nintroduces\ssome\snew\sfaults\sin\sthe\stests,\sprobably\sdue\sto\ssomething\nunrelated. -D 2022-04-18T16:10:07.804 +C Ensure\sthat\sleft-hand\sside\sWITHOUT\sROWID\stables\sare\sset\sto\sOP_NullRow\sprior\nto\srunning\sthe\sright-join\sloop.\s\sThis\sfixes\sa\sproblem\sintroduced\sby\sthe\nprevious\scheck-in. +D 2022-04-18T16:20:59.567 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -641,7 +641,7 @@ F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b F src/where.c 45102d682f6efd450d89c0c5f09b838be6d69c84c6105336730ee38d3b452fad F src/whereInt.h eecce79edc6f7005f91f35be6b18b7053f794e1b50e95bcd06a2d537fc176734 -F src/wherecode.c 1770ab730f14949fe55104b7970e4646087b1ff7f78a906b275cb08ae256f027 +F src/wherecode.c dcf622a9650638c80c86699d3fbd39526016ac36488f6db3878fcf530803f30d F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 F src/window.c 42a71595263dbd8ef8248218e4fc7d4b5ddccece52146ad48e079342d93f6f8f F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1948,8 +1948,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 1ba3b3ccf145d84fa75afabe2fa925f65e43f815b25b15bd60073a41aa97bf57 -R 7c5e9401c90d81242051e832c8ba8500 +P 95b242d4c2fed7c713299565ac1010f8a7534a5695589e87d5a0204c7bf5f3dc +R 64e006161878d7a0b97de4889394a4bc U drh -Z 6ccb42e7d5486d8748e5216dc5361d97 +Z 861a84ea03f43168120caaccf0f7691d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3d64846252..65011899de 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -95b242d4c2fed7c713299565ac1010f8a7534a5695589e87d5a0204c7bf5f3dc \ No newline at end of file +aab7665ce6c004df701a72aef1a5135f2c78f16c6ff728a00076afb66ba9d3a0 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index ca02acf45a..9ba987ca6a 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -2819,16 +2819,16 @@ SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( int k; ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pTab->zName)); - if( (pTabItem->fg.jointype & JT_LTORJ)==0 ){ - for(k=0; ka[k].pWLoop->maskSelf; - sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur); - iIdxCur = pWInfo->a[k].iIdxCur; - if( iIdxCur ){ - sqlite3VdbeAddOp1(v, OP_NullRow, iIdxCur); - } + for(k=0; ka[k].pWLoop->maskSelf; + sqlite3VdbeAddOp1(v, OP_NullRow, pWInfo->a[k].iTabCur); + iIdxCur = pWInfo->a[k].iIdxCur; + if( iIdxCur ){ + sqlite3VdbeAddOp1(v, OP_NullRow, iIdxCur); } + } + if( (pTabItem->fg.jointype & JT_LTORJ)==0 ){ mAll |= pLoop->maskSelf; for(k=0; knTerm; k++){ WhereTerm *pTerm = &pWC->a[k]; From a20922cb20925118813f34ee02bef0c15e4d1777 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 18 Apr 2022 18:01:38 +0000 Subject: [PATCH 171/259] New test case demonstrating the ability to invoke OP_NullRow on a cursor that has never been opened. FossilOrigin-Name: d173edc242f295f5812a58cad184695881d9b1b160cd5b25e303e22848e90ce1 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/join9.test | 16 +++++++++++++++- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index ce2e243173..d2b604fa11 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\sbtree\sbug-fix\sfrom\strunk. -D 2022-04-18T16:23:01.233 +C New\stest\scase\sdemonstrating\sthe\sability\sto\sinvoke\sOP_NullRow\son\sa\scursor\nthat\shas\snever\sbeen\sopened. +D 2022-04-18T18:01:38.190 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1148,7 +1148,7 @@ F test/join5.test c4df54e2e204d7f1417bfbdd21ca324b4b07415c647595cc47798eacfddc96 F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c F test/join7.test 8e72de4b45e5e930d18c305c7efe86015fb2552731e4e03ea226353036b0dab0 F test/join8.test 6ed7eed8993e060e5e9d07f6bcadf1bb634742a03b9824afbcfa193adf7f9965 -F test/join9.test f5db0954fe5aee36fbecb75a80c764d5f0a4b35335016c5829b0d2616039df6e +F test/join9.test 37204222103dc6d04883d2b1f533d9e35b7112ed131c258dc550e132dba48107 F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -1948,8 +1948,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 aab7665ce6c004df701a72aef1a5135f2c78f16c6ff728a00076afb66ba9d3a0 2de7f8cc7fe18f0828bb53f1fd11f5eb828faf4d6dfaf39693dff4f8926c1c7a -R c2bad799ccc2e68c52faa7ef529226a2 +P a333c0b50c3af7cd818470a647d78c7c691ef15418ec7cffe80dd88405393069 +R 9645873f15ef6d0ee81aef92418cd2d4 U drh -Z af5a0bcb393fda3761d5ef89c60ee039 +Z 96b862d75b3a9bbbe11e25b2234325fb # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f815780a9b..195e951e64 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a333c0b50c3af7cd818470a647d78c7c691ef15418ec7cffe80dd88405393069 \ No newline at end of file +d173edc242f295f5812a58cad184695881d9b1b160cd5b25e303e22848e90ce1 \ No newline at end of file diff --git a/test/join9.test b/test/join9.test index e0edb7bc7b..9b7ca4da39 100644 --- a/test/join9.test +++ b/test/join9.test @@ -364,5 +364,19 @@ foreach {id schema} { 8 - dave - - 9 - - - 999 } -} + + # Verified by PG-14 using case 1 + do_execsql_test join9-$id.800 { + WITH t7(id,a) AS MATERIALIZED (SELECT * FROM t4 WHERE false) + SELECT * + FROM t7 + JOIN t7 AS t7b USING(id) + FULL JOIN t3 USING(id); + } { + 2 - - two + 3 - - three + 6 - - six + 7 - - seven + } +} finish_test From 23f240b3250a394959a11e1a6cd211475ffbc297 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 18 Apr 2022 19:28:08 +0000 Subject: [PATCH 172/259] New test cases for parenthesized NATURAL FULL JOINs. FossilOrigin-Name: e34250efd34b526373bf072a43a7984ca19690836d7d2464dea8338066eaee8f --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/join9.test | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index d2b604fa11..af6a5fe192 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\stest\scase\sdemonstrating\sthe\sability\sto\sinvoke\sOP_NullRow\son\sa\scursor\nthat\shas\snever\sbeen\sopened. -D 2022-04-18T18:01:38.190 +C New\stest\scases\sfor\sparenthesized\sNATURAL\sFULL\sJOINs. +D 2022-04-18T19:28:08.212 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1148,7 +1148,7 @@ F test/join5.test c4df54e2e204d7f1417bfbdd21ca324b4b07415c647595cc47798eacfddc96 F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c F test/join7.test 8e72de4b45e5e930d18c305c7efe86015fb2552731e4e03ea226353036b0dab0 F test/join8.test 6ed7eed8993e060e5e9d07f6bcadf1bb634742a03b9824afbcfa193adf7f9965 -F test/join9.test 37204222103dc6d04883d2b1f533d9e35b7112ed131c258dc550e132dba48107 +F test/join9.test 97230650581a5521ea4c2391ca0f29ffcf2c1285e84e5c9d6d9b1ccbafd7cb01 F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -1948,8 +1948,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 a333c0b50c3af7cd818470a647d78c7c691ef15418ec7cffe80dd88405393069 -R 9645873f15ef6d0ee81aef92418cd2d4 +P d173edc242f295f5812a58cad184695881d9b1b160cd5b25e303e22848e90ce1 +R 49eb4f421eb5be48a14ef53b7b33206a U drh -Z 96b862d75b3a9bbbe11e25b2234325fb +Z f309f4fd1fefc1337b9405848765b78b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 195e951e64..dff30f389c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d173edc242f295f5812a58cad184695881d9b1b160cd5b25e303e22848e90ce1 \ No newline at end of file +e34250efd34b526373bf072a43a7984ca19690836d7d2464dea8338066eaee8f \ No newline at end of file diff --git a/test/join9.test b/test/join9.test index 9b7ca4da39..ae0dde0be5 100644 --- a/test/join9.test +++ b/test/join9.test @@ -378,5 +378,43 @@ foreach {id schema} { 6 - - six 7 - - seven } + + # Verified by PG-14 + do_execsql_test join9-$id.900 { + SELECT * + FROM (t3 NATURAL FULL JOIN t4) + NATURAL FULL JOIN + (t5 NATURAL FULL JOIN t6) + ORDER BY 1; + } { + 0 - - - 1000 + 1 - - red - + 2 two alice orange - + 3 three - yellow 333 + 4 - bob green 444 + 5 - - blue 555 + 6 six cindy - - + 7 seven - - - + 8 - dave - - + 9 - - - 999 + } + do_execsql_test join9-$id.910 { + SELECT * + FROM t3 NATURAL FULL JOIN + (t4 NATURAL FULL JOIN + (t5 NATURAL FULL JOIN t6)) + ORDER BY 1; + } { + 0 - - - 1000 + 1 - - red - + 2 two alice orange - + 3 three - yellow 333 + 4 - bob green 444 + 5 - - blue 555 + 6 six cindy - - + 7 seven - - - + 8 - dave - - + 9 - - - 999 + } } finish_test From 7466d5665af4965e4fc8b78df89b4d310d63b752 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 18 Apr 2022 19:34:41 +0000 Subject: [PATCH 173/259] Even more test cases. FossilOrigin-Name: 5f4310a104443ac3fc56f9d9cd2d428dd3e7a2a0285c8e74de6f499439fd6868 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/join9.test | 20 ++++++++++++++++++++ 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index af6a5fe192..ac054ce787 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\stest\scases\sfor\sparenthesized\sNATURAL\sFULL\sJOINs. -D 2022-04-18T19:28:08.212 +C Even\smore\stest\scases. +D 2022-04-18T19:34:41.878 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1148,7 +1148,7 @@ F test/join5.test c4df54e2e204d7f1417bfbdd21ca324b4b07415c647595cc47798eacfddc96 F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c F test/join7.test 8e72de4b45e5e930d18c305c7efe86015fb2552731e4e03ea226353036b0dab0 F test/join8.test 6ed7eed8993e060e5e9d07f6bcadf1bb634742a03b9824afbcfa193adf7f9965 -F test/join9.test 97230650581a5521ea4c2391ca0f29ffcf2c1285e84e5c9d6d9b1ccbafd7cb01 +F test/join9.test 2f0202b86a863c1823b12475d0630ac612b7a59dd888ae96c067d3a3e1059b22 F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -1948,8 +1948,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 d173edc242f295f5812a58cad184695881d9b1b160cd5b25e303e22848e90ce1 -R 49eb4f421eb5be48a14ef53b7b33206a +P e34250efd34b526373bf072a43a7984ca19690836d7d2464dea8338066eaee8f +R 69108f498c0556000e4436e5f3e7a04b U drh -Z f309f4fd1fefc1337b9405848765b78b +Z 659794332d44475059e268cfdb5be5e9 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index dff30f389c..7b0c55236e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e34250efd34b526373bf072a43a7984ca19690836d7d2464dea8338066eaee8f \ No newline at end of file +5f4310a104443ac3fc56f9d9cd2d428dd3e7a2a0285c8e74de6f499439fd6868 \ No newline at end of file diff --git a/test/join9.test b/test/join9.test index ae0dde0be5..6062567beb 100644 --- a/test/join9.test +++ b/test/join9.test @@ -416,5 +416,25 @@ foreach {id schema} { 8 - dave - - 9 - - - 999 } + do_execsql_test join9-$id.920 { + SELECT * + FROM t3 FULL JOIN ( + t4 FULL JOIN ( + t5 FULL JOIN t6 USING (id) + ) USING(id) + ) USING(id) + ORDER BY 1; + } { + 0 - - - 1000 + 1 - - red - + 2 two alice orange - + 3 three - yellow 333 + 4 - bob green 444 + 5 - - blue 555 + 6 six cindy - - + 7 seven - - - + 8 - dave - - + 9 - - - 999 + } } finish_test From f80bb195b3ad5328a74455b34216b1ce0c719ff5 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 18 Apr 2022 19:48:31 +0000 Subject: [PATCH 174/259] Disable the unused EU4_EXPR mode for the IdList object. FossilOrigin-Name: 5bcf4aa3bf6b1b9f47142bc37683bb3bf0adeffd052d07449af7c9b415add052 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/build.c | 4 +--- src/sqliteInt.h | 4 ++-- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index ac054ce787..bd5ae8fad1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Even\smore\stest\scases. -D 2022-04-18T19:34:41.878 +C Disable\sthe\sunused\sEU4_EXPR\smode\sfor\sthe\sIdList\sobject. +D 2022-04-18T19:48:31.484 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -495,7 +495,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c df695e953c2ce78ce4878ee5016751df9bc9a921dc0500a0f53ab3bb3196e505 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482e -F src/build.c f7098ca5006891b1877fb2e8f9aa52243338983696123f5a4e30fa9dda06debc +F src/build.c 7f4286d2b4c4ed013e8e064f958f10c277126085f7918c306e9f54c238b36393 F src/callback.c 4c19af69835787bfe790ac560f3071a824eb629f34e41f97b52ce5235c77de1c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 026dbdcdbd8c3cde98a88483ee88310ff43150ab164ad768f12cc700a11495ad @@ -557,7 +557,7 @@ F src/shell.c.in ecff6f4ab0e8e25acd578b3eb27ac0bad4d48643c160259a277151d6e9d412e F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h afec51781b0ff21126c4cbd812be873f801810fef7ecee6c11e56ab85c6fe577 +F src/sqliteInt.h e748c9855541432874b37dbf11550d46ea66cac3958857dad4643fc48308d398 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -1948,8 +1948,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 e34250efd34b526373bf072a43a7984ca19690836d7d2464dea8338066eaee8f -R 69108f498c0556000e4436e5f3e7a04b +P 5f4310a104443ac3fc56f9d9cd2d428dd3e7a2a0285c8e74de6f499439fd6868 +R 733c72f2d655615b5133b4dde2b9b4c2 U drh -Z 659794332d44475059e268cfdb5be5e9 +Z d36c5cf3e20140eaf0c13a45e8b8e619 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7b0c55236e..33260b53b1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5f4310a104443ac3fc56f9d9cd2d428dd3e7a2a0285c8e74de6f499439fd6868 \ No newline at end of file +5bcf4aa3bf6b1b9f47142bc37683bb3bf0adeffd052d07449af7c9b415add052 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 126897c856..1c632c94ed 100644 --- a/src/build.c +++ b/src/build.c @@ -4695,12 +4695,10 @@ IdList *sqlite3IdListAppend(Parse *pParse, IdList *pList, Token *pToken){ */ void sqlite3IdListDelete(sqlite3 *db, IdList *pList){ int i; - int delExpr; if( pList==0 ) return; - delExpr = pList->eU4==EU4_EXPR; + assert( pList->eU4!=EU4_EXPR ); /* EU4_EXPR mode is not currently used */ for(i=0; inId; i++){ sqlite3DbFree(db, pList->a[i].zName); - if( delExpr ) sqlite3ExprDelete(db, pList->a[i].u4.pExpr); } sqlite3DbFreeNN(db, pList); } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index bc618df7df..9363adbb9f 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3044,7 +3044,7 @@ struct IdList { char *zName; /* Name of the identifier */ union { int idx; /* Index in some Table.aCol[] of a column named zName */ - Expr *pExpr; /* Expr to implement a USING variable */ + Expr *pExpr; /* Expr to implement a USING variable -- NOT USED */ } u4; } a[1]; }; @@ -3055,7 +3055,7 @@ struct IdList { */ #define EU4_NONE 0 /* Does not use IdList.a.u4 */ #define EU4_IDX 1 /* Uses IdList.a.u4.idx */ -#define EU4_EXPR 2 /* Uses IdList.a.u4.pExpr */ +#define EU4_EXPR 2 /* Uses IdList.a.u4.pExpr -- NOT CURRENTLY USED */ /* ** The SrcItem object represents a single term in the FROM clause of a query. From ec39c96473ab8607cf47d32d6c9e72f653c781d5 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 18 Apr 2022 22:51:24 +0000 Subject: [PATCH 175/259] New test cases, including one that gets a different result than Postgres. FossilOrigin-Name: 49ea11a4a5fd630db44f458304d4f45fa103529ed6b36d538c78074965e8d799 --- manifest | 12 +++--- manifest.uuid | 2 +- test/join9.test | 102 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index bd5ae8fad1..2e1950ca86 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disable\sthe\sunused\sEU4_EXPR\smode\sfor\sthe\sIdList\sobject. -D 2022-04-18T19:48:31.484 +C New\stest\scases,\sincluding\sone\sthat\sgets\sa\sdifferent\sresult\sthan\sPostgres. +D 2022-04-18T22:51:24.965 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1148,7 +1148,7 @@ F test/join5.test c4df54e2e204d7f1417bfbdd21ca324b4b07415c647595cc47798eacfddc96 F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c F test/join7.test 8e72de4b45e5e930d18c305c7efe86015fb2552731e4e03ea226353036b0dab0 F test/join8.test 6ed7eed8993e060e5e9d07f6bcadf1bb634742a03b9824afbcfa193adf7f9965 -F test/join9.test 2f0202b86a863c1823b12475d0630ac612b7a59dd888ae96c067d3a3e1059b22 +F test/join9.test a651f427b9906fda7c3548a0a9dbec725b9e80e92a65787f9d2a845d49af649d F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -1948,8 +1948,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 5f4310a104443ac3fc56f9d9cd2d428dd3e7a2a0285c8e74de6f499439fd6868 -R 733c72f2d655615b5133b4dde2b9b4c2 +P 5bcf4aa3bf6b1b9f47142bc37683bb3bf0adeffd052d07449af7c9b415add052 +R 81d9c0efaaa8f2b2681b74a83997038e U drh -Z d36c5cf3e20140eaf0c13a45e8b8e619 +Z 354a9aaf45b00cc0c5b254cdf7868063 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 33260b53b1..8a412559d8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5bcf4aa3bf6b1b9f47142bc37683bb3bf0adeffd052d07449af7c9b415add052 \ No newline at end of file +49ea11a4a5fd630db44f458304d4f45fa103529ed6b36d538c78074965e8d799 \ No newline at end of file diff --git a/test/join9.test b/test/join9.test index 6062567beb..4f143034c4 100644 --- a/test/join9.test +++ b/test/join9.test @@ -436,5 +436,107 @@ foreach {id schema} { 8 - dave - - 9 - - - 999 } + do_execsql_test join9-$id.920 { + SELECT * + FROM t3 FULL JOIN ( + t4 FULL JOIN ( + t5 FULL JOIN t6 USING (id) + ) USING(id) + ) USING(id) + ORDER BY 1; + } { + 0 - - - 1000 + 1 - - red - + 2 two alice orange - + 3 three - yellow 333 + 4 - bob green 444 + 5 - - blue 555 + 6 six cindy - - + 7 seven - - - + 8 - dave - - + 9 - - - 999 + } + + # Verified by PG-14 + do_execsql_test join9-$id.930 { + SELECT * + FROM t3 FULL JOIN ( + t4 FULL JOIN ( + t5 FULL JOIN t6 USING(id) + ) USING(id) + ) AS j1 ON j1.id=t3.id + ORDER BY coalesce(t3.id,j1.id); + } { + - - 0 - - 1000 + - - 1 - red - + 2 two 2 alice orange - + 3 three 3 - yellow 333 + - - 4 bob green 444 + - - 5 - blue 555 + 6 six 6 cindy - - + 7 seven - - - - + - - 8 dave - - + - - 9 - - 999 + } + + # Verified by PG-14 + do_execsql_test join9-$id.940 { + SELECT * + FROM t3 FULL JOIN ( + t4 RIGHT JOIN ( + t5 FULL JOIN t6 USING(id) + ) USING(id) + ) AS j1 ON j1.id=t3.id + ORDER BY coalesce(t3.id,j1.id); + } { + - - 0 - - 1000 + - - 1 - red - + 2 two 2 alice orange - + 3 three 3 - yellow 333 + - - 4 bob green 444 + - - 5 - blue 555 + 6 six - - - - + 7 seven - - - - + - - 9 - - 999 + } + + # Verified by PG-14 + do_execsql_test join9-$id.950 { + SELECT * + FROM t3 FULL JOIN ( + t4 LEFT JOIN ( + t5 FULL JOIN t6 USING(id) + ) USING(id) + ) AS j1 ON j1.id=t3.id + ORDER BY coalesce(t3.id,j1.id); + } { + 2 two 2 alice orange - + 3 three - - - - + - - 4 bob green 444 + 6 six 6 cindy - - + 7 seven - - - - + - - 8 dave - - + } + + # Verified by PG-14 + do_execsql_test join9-$id.1000 { + WITH t56(id,y,z) AS (SELECT * FROM t5 FULL JOIN t6 USING(id) LIMIT 50) + SELECT id,x,y,z FROM t4 JOIN t56 USING(id) + ORDER BY 1; + } { + 2 alice orange - + 4 bob green 444 + } + + # Verified by PG-14 + do_execsql_test join9-$id.1010 { + SELECT id,x,y,z + FROM t4 INNER JOIN (t5 FULL JOIN t6 USING(id)) USING(id) + ORDER BY 1; + } { + 2 alice orange - + 4 bob green 444 + } + } finish_test From 1c2bf41a12cc6101d99fb95732559f98d3981c39 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 18 Apr 2022 23:20:02 +0000 Subject: [PATCH 176/259] Fix the query flattener so that it does not flatten a RIGHT or FULL JOIN into any position of the outer query other than the first. FossilOrigin-Name: 837322aa95b1c46201b7dd0c2e6c7b9915b4276d997949f1ecf961fb7f3514cf --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 8 ++++++++ test/join9.test | 23 +++++++++++++++++++++++ 4 files changed, 39 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 2e1950ca86..77c55c7a93 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\stest\scases,\sincluding\sone\sthat\sgets\sa\sdifferent\sresult\sthan\sPostgres. -D 2022-04-18T22:51:24.965 +C Fix\sthe\squery\sflattener\sso\sthat\sit\sdoes\snot\sflatten\sa\sRIGHT\sor\sFULL\sJOIN\sinto\nany\sposition\sof\sthe\souter\squery\sother\sthan\sthe\sfirst. +D 2022-04-18T23:20:02.870 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -552,7 +552,7 @@ F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c ce4cb0889f1bf5990b698740b88026385cf6f30222fde1f02a3168bb780eb579 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 6544e02167adbb89a7152acf6ff2f0218a6de94146377b83e79bc8b09bf6f16e +F src/select.c 459cea7ae6e6ff517b04ad3ec7ed6479b666096a85fcec5b4edec2d5cacca2d8 F src/shell.c.in ecff6f4ab0e8e25acd578b3eb27ac0bad4d48643c160259a277151d6e9d412e1 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1148,7 +1148,7 @@ F test/join5.test c4df54e2e204d7f1417bfbdd21ca324b4b07415c647595cc47798eacfddc96 F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c F test/join7.test 8e72de4b45e5e930d18c305c7efe86015fb2552731e4e03ea226353036b0dab0 F test/join8.test 6ed7eed8993e060e5e9d07f6bcadf1bb634742a03b9824afbcfa193adf7f9965 -F test/join9.test a651f427b9906fda7c3548a0a9dbec725b9e80e92a65787f9d2a845d49af649d +F test/join9.test 9056ddd3b0c0f4f9d658f4521038d9a37dc23ead8ca9a505d0b0db2b6a471e05 F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -1948,8 +1948,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 5bcf4aa3bf6b1b9f47142bc37683bb3bf0adeffd052d07449af7c9b415add052 -R 81d9c0efaaa8f2b2681b74a83997038e +P 49ea11a4a5fd630db44f458304d4f45fa103529ed6b36d538c78074965e8d799 +R f732ede2542062631f39bbd96137d61f U drh -Z 354a9aaf45b00cc0c5b254cdf7868063 +Z dd5cee205fd9f7e997652ba77ec73d51 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8a412559d8..bbad85cdc6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -49ea11a4a5fd630db44f458304d4f45fa103529ed6b36d538c78074965e8d799 \ No newline at end of file +837322aa95b1c46201b7dd0c2e6c7b9915b4276d997949f1ecf961fb7f3514cf \ No newline at end of file diff --git a/src/select.c b/src/select.c index 6d185a1685..d65719e0ab 100644 --- a/src/select.c +++ b/src/select.c @@ -4122,6 +4122,9 @@ static void renumberCursors( ** (26) The subquery may not be the right operand of a RIGHT JOIN. ** See also (3) for restrictions on LEFT JOIN. ** +** (27) The subquery may not contain a FULL or RIGHT JOIN unless it +** is the first element of the parent query. +** ** ** In this routine, the "p" parameter is a pointer to the outer query. ** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query @@ -4241,6 +4244,11 @@ static int flattenSubquery( } #endif + assert( pSubSrc->nSrc>0 ); /* True by restriction (7) */ + if( iFrom>0 && (pSubSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ + return 0; /* Restriction (27) */ + } + /* Restriction (17): If the sub-query is a compound SELECT, then it must ** use only the UNION ALL operator. And none of the simple select queries ** that make up the compound SELECT are allowed to be aggregate or distinct diff --git a/test/join9.test b/test/join9.test index 4f143034c4..e547d4ce70 100644 --- a/test/join9.test +++ b/test/join9.test @@ -518,6 +518,7 @@ foreach {id schema} { - - 8 dave - - } + # Restriction (27) in the query flattener # Verified by PG-14 do_execsql_test join9-$id.1000 { WITH t56(id,y,z) AS (SELECT * FROM t5 FULL JOIN t6 USING(id) LIMIT 50) @@ -538,5 +539,27 @@ foreach {id schema} { 4 bob green 444 } + # Verified by PG-14 + do_execsql_test join9-$id.1020 { + SELECT id,x,y,z + FROM t4 FULL JOIN t5 USING(id) INNER JOIN t6 USING(id) + ORDER BY 1; + } { + 3 - yellow 333 + 4 bob green 444 + 5 - blue 555 + } + + # Verified by PG-14 + do_execsql_test join9-$id.1030 { + WITH t45(id,x,y) AS (SELECT * FROM t4 FULL JOIN t5 USING(id) LIMIT 50) + SELECT id,x,y,z FROM t45 JOIN t6 USING(id) + ORDER BY 1; + } { + 3 - yellow 333 + 4 bob green 444 + 5 - blue 555 + } + } finish_test From 3b8c7545df5bf3f322ffe4d8134a887c5480cd67 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 19 Apr 2022 00:24:52 +0000 Subject: [PATCH 177/259] New test cases for RIGHT and FULL JOIN. FossilOrigin-Name: 5c2f670e0fb35648e1d6e1c48f4d8af815cd57d59eac6ba22e253511bb078870 --- manifest | 11 +-- manifest.uuid | 2 +- test/joinA.test | 213 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 220 insertions(+), 6 deletions(-) create mode 100644 test/joinA.test diff --git a/manifest b/manifest index 77c55c7a93..03a3a773c6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\squery\sflattener\sso\sthat\sit\sdoes\snot\sflatten\sa\sRIGHT\sor\sFULL\sJOIN\sinto\nany\sposition\sof\sthe\souter\squery\sother\sthan\sthe\sfirst. -D 2022-04-18T23:20:02.870 +C New\stest\scases\sfor\sRIGHT\sand\sFULL\sJOIN. +D 2022-04-19T00:24:52.147 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1149,6 +1149,7 @@ F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc F test/join7.test 8e72de4b45e5e930d18c305c7efe86015fb2552731e4e03ea226353036b0dab0 F test/join8.test 6ed7eed8993e060e5e9d07f6bcadf1bb634742a03b9824afbcfa193adf7f9965 F test/join9.test 9056ddd3b0c0f4f9d658f4521038d9a37dc23ead8ca9a505d0b0db2b6a471e05 +F test/joinA.test 71672b591fe7ea87837b0a22e7e022aa1513f39991c31938f67d63c6a366d66c F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -1948,8 +1949,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 49ea11a4a5fd630db44f458304d4f45fa103529ed6b36d538c78074965e8d799 -R f732ede2542062631f39bbd96137d61f +P 837322aa95b1c46201b7dd0c2e6c7b9915b4276d997949f1ecf961fb7f3514cf +R 3bb4cbe21854d93bac5653e430f69487 U drh -Z dd5cee205fd9f7e997652ba77ec73d51 +Z 7e7983c98db07942264cc173c5b87cf4 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index bbad85cdc6..71b52fed8f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -837322aa95b1c46201b7dd0c2e6c7b9915b4276d997949f1ecf961fb7f3514cf \ No newline at end of file +5c2f670e0fb35648e1d6e1c48f4d8af815cd57d59eac6ba22e253511bb078870 \ No newline at end of file diff --git a/test/joinA.test b/test/joinA.test new file mode 100644 index 0000000000..6f7818a1ba --- /dev/null +++ b/test/joinA.test @@ -0,0 +1,213 @@ +# 2022-04-18 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. +# +# This file implements tests for RIGHT and FULL OUTER JOINs. + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +foreach {id schema} { + 1 { + CREATE TABLE t1(a INT, b INT, c INT, d INT); + CREATE TABLE t2(c INT, d INT, e INT, f INT); + CREATE TABLE t3(a INT, b INT, e INT, f INT); + CREATE TABLE t4(a INT, c INT, d INT, f INT); + INSERT INTO t1 VALUES(11,21,31,41),(12,22,32,42),(15,25,35,45),(18,28,38,48); + INSERT INTO t2 VALUES(12,22,32,42),(13,23,33,43),(15,25,35,45),(17,27,37,47); + INSERT INTO t3 VALUES(14,24,34,44),(15,25,35,45),(16,26,36,46); + INSERT INTO t4 VALUES(11,21,31,41),(13,23,33,43),(16,26,36,46),(19,29,39,49); + } + 2 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT, c INT, d INT); + CREATE TABLE t2(c INT, d INTEGER PRIMARY KEY, e INT, f INT); + CREATE TABLE t3(a INT, b INT, e INTEGER PRIMARY KEY, f INT); + CREATE TABLE t4(a INT, c INT, d INT, f INT PRIMARY KEY) WITHOUT ROWID; + INSERT INTO t1 VALUES(11,21,31,41),(12,22,32,42),(15,25,35,45),(18,28,38,48); + INSERT INTO t2 VALUES(12,22,32,42),(13,23,33,43),(15,25,35,45),(17,27,37,47); + INSERT INTO t3 VALUES(14,24,34,44),(15,25,35,45),(16,26,36,46); + INSERT INTO t4 VALUES(11,21,31,41),(13,23,33,43),(16,26,36,46),(19,29,39,49); + } + 3 { + CREATE TABLE t1a(a INT, b INT, c INT, d INT); + CREATE TABLE t2a(c INT, d INT, e INT, f INT); + CREATE TABLE t3a(a INT, b INT, e INT, f INT); + CREATE TABLE t4a(a INT, c INT, d INT, f INT); + INSERT INTO t1a VALUES(11,21,31,41),(12,22,32,42); + INSERT INTO t2a VALUES(12,22,32,42),(13,23,33,43); + INSERT INTO t3a VALUES(14,24,34,44),(15,25,35,45); + INSERT INTO t4a VALUES(11,21,31,41),(13,23,33,43); + CREATE TABLE t1b(a INT, b INT, c INT, d INT); + CREATE TABLE t2b(c INT, d INT, e INT, f INT); + CREATE TABLE t3b(a INT, b INT, e INT, f INT); + CREATE TABLE t4b(a INT, c INT, d INT, f INT); + INSERT INTO t1b VALUES(15,25,35,45),(18,28,38,48); + INSERT INTO t2b VALUES(15,25,35,45),(17,27,37,47); + INSERT INTO t3b VALUES(15,25,35,45),(16,26,36,46); + INSERT INTO t4b VALUES(16,26,36,46),(19,29,39,49); + CREATE VIEW t1 AS SELECT * FROM t1a UNION SELECT * FROM t1b; + CREATE VIEW t2 AS SELECT * FROM t2a UNION SELECT * FROM t2b; + CREATE VIEW t3 AS SELECT * FROM t3a UNION SELECT * FROM t3b; + CREATE VIEW t4 AS SELECT * FROM t4a UNION SELECT * FROM t4b; + } +} { + reset_db + db nullvalue - + do_execsql_test joinA-$id.setup $schema {} + + # Verified by PG-14 + do_execsql_test joinA-$id.100 { + SELECT a,b,c,d,t2.e,f,t3.e + FROM t1 + INNER JOIN t2 USING(c,d) + INNER JOIN t3 USING(a,b,f) + INNER JOIN t4 USING(a,c,d,f) + ORDER BY 1 nulls first, 3 nulls first; + } {} + + + # Verified by PG-14 + do_execsql_test joinA-$id.110 { + SELECT a,b,c,d,t2.e,f,t3.e + FROM t1 + LEFT JOIN t2 USING(c,d) + LEFT JOIN t3 USING(a,b,f) + LEFT JOIN t4 USING(a,c,d,f) + ORDER BY 1 nulls first, 3 nulls first; + } { + 11 21 31 41 - - - + 12 22 32 42 - - - + 15 25 35 45 - - - + 18 28 38 48 - - - + } + + # Verified by PG-14 + do_execsql_test joinA-$id.120 { + SELECT a,b,c,d,t2.e,f,t3.e + FROM t1 + LEFT JOIN t2 USING(c,d) + RIGHT JOIN t3 USING(a,b,f) + LEFT JOIN t4 USING(a,c,d,f) + ORDER BY 1 nulls first, 3 nulls first; + } { + 14 24 - - - 44 34 + 15 25 - - - 45 35 + 16 26 - - - 46 36 + } + + # Verified by PG-14 + do_execsql_test joinA-$id.130 { + SELECT a,b,c,d,t2.e,f,t3.e + FROM t1 + RIGHT JOIN t2 USING(c,d) + LEFT JOIN t3 USING(a,b,f) + RIGHT JOIN t4 USING(a,c,d,f) + ORDER BY 1 nulls first, 3 nulls first; + } { + 11 - 21 31 - 41 - + 13 - 23 33 - 43 - + 16 - 26 36 - 46 - + 19 - 29 39 - 49 - + } + + # Verified by PG-14 + do_execsql_test joinA-$id.140 { + SELECT a,b,c,d,t2.e,f,t3.e + FROM t1 + FULL JOIN t2 USING(c,d) + LEFT JOIN t3 USING(a,b,f) + RIGHT JOIN t4 USING(a,c,d,f) + ORDER BY 1 nulls first, 3 nulls first; + } { + 11 - 21 31 - 41 - + 13 - 23 33 - 43 - + 16 - 26 36 - 46 - + 19 - 29 39 - 49 - + } + + # Verified by PG-14 + do_execsql_test joinA-$id.150 { + SELECT a,b,c,d,t2.e,f,t3.e + FROM t1 + RIGHT JOIN t2 USING(c,d) + FULL JOIN t3 USING(a,b,f) + RIGHT JOIN t4 USING(a,c,d,f) + ORDER BY 1 nulls first, 3 nulls first; + } { + 11 - 21 31 - 41 - + 13 - 23 33 - 43 - + 16 - 26 36 - 46 - + 19 - 29 39 - 49 - + } + + # Verified by PG-14 + do_execsql_test joinA-$id.160 { + SELECT a,b,c,d,t2.e,f,t3.e + FROM t1 + RIGHT JOIN t2 USING(c,d) + LEFT JOIN t3 USING(a,b,f) + FULL JOIN t4 USING(a,c,d,f) + ORDER BY 1 nulls first, 3 nulls first; + } { + - - 12 22 32 42 - + - - 13 23 33 43 - + - - 15 25 35 45 - + - - 17 27 37 47 - + 11 - 21 31 - 41 - + 13 - 23 33 - 43 - + 16 - 26 36 - 46 - + 19 - 29 39 - 49 - + } + + # Verified by PG-14 + do_execsql_test joinA-$id.170 { + SELECT a,b,c,d,t2.e,f,t3.e + FROM t1 + LEFT JOIN t2 USING(c,d) + RIGHT JOIN t3 USING(a,b,f) + FULL JOIN t4 USING(a,c,d,f) + ORDER BY 1 nulls first, 3 nulls first; + } { + 11 - 21 31 - 41 - + 13 - 23 33 - 43 - + 14 24 - - - 44 34 + 15 25 - - - 45 35 + 16 26 - - - 46 36 + 16 - 26 36 - 46 - + 19 - 29 39 - 49 - + } + + # Verified by PG-14 + do_execsql_test joinA-$id.200 { + SELECT a,b,c,d,t2.e,f,t3.e + FROM t1 + FULL JOIN t2 USING(c,d) + FULL JOIN t3 USING(a,b,f) + FULL JOIN t4 USING(a,c,d,f) + ORDER BY 1 nulls first, 3 nulls first; + } { + - - 12 22 32 42 - + - - 13 23 33 43 - + - - 15 25 35 45 - + - - 17 27 37 47 - + 11 - 21 31 - 41 - + 11 21 31 41 - - - + 12 22 32 42 - - - + 13 - 23 33 - 43 - + 14 24 - - - 44 34 + 15 25 - - - 45 35 + 15 25 35 45 - - - + 16 26 - - - 46 36 + 16 - 26 36 - 46 - + 18 28 38 48 - - - + 19 - 29 39 - 49 - + } +} From d737b16f922e6d14c2607ee2e7a91d255951c6e5 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 19 Apr 2022 02:03:18 +0000 Subject: [PATCH 178/259] Add the omitted "finish_test" to the end of joinA.test. FossilOrigin-Name: 0907505cc9bb051280108fe5074211374b31836fae1ae6667a3de69f9d83fc01 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/joinA.test | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 03a3a773c6..b65721e364 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\stest\scases\sfor\sRIGHT\sand\sFULL\sJOIN. -D 2022-04-19T00:24:52.147 +C Add\sthe\somitted\s"finish_test"\sto\sthe\send\sof\sjoinA.test. +D 2022-04-19T02:03:18.069 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1149,7 +1149,7 @@ F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc F test/join7.test 8e72de4b45e5e930d18c305c7efe86015fb2552731e4e03ea226353036b0dab0 F test/join8.test 6ed7eed8993e060e5e9d07f6bcadf1bb634742a03b9824afbcfa193adf7f9965 F test/join9.test 9056ddd3b0c0f4f9d658f4521038d9a37dc23ead8ca9a505d0b0db2b6a471e05 -F test/joinA.test 71672b591fe7ea87837b0a22e7e022aa1513f39991c31938f67d63c6a366d66c +F test/joinA.test 7eab225dc1c1ab258a5e62513a4ed7cabbd3db971d59d5d92f4fb6fa14c12f6a F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -1949,8 +1949,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 837322aa95b1c46201b7dd0c2e6c7b9915b4276d997949f1ecf961fb7f3514cf -R 3bb4cbe21854d93bac5653e430f69487 +P 5c2f670e0fb35648e1d6e1c48f4d8af815cd57d59eac6ba22e253511bb078870 +R bb5ed5e9ec8911fef5a8aa38ca9d5eee U drh -Z 7e7983c98db07942264cc173c5b87cf4 +Z 938a68f2e1d34b25353fa58c5f0735ee # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 71b52fed8f..15199a9feb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5c2f670e0fb35648e1d6e1c48f4d8af815cd57d59eac6ba22e253511bb078870 \ No newline at end of file +0907505cc9bb051280108fe5074211374b31836fae1ae6667a3de69f9d83fc01 \ No newline at end of file diff --git a/test/joinA.test b/test/joinA.test index 6f7818a1ba..d6bb678c54 100644 --- a/test/joinA.test +++ b/test/joinA.test @@ -211,3 +211,4 @@ foreach {id schema} { 19 - 29 39 - 49 - } } +finish_test From 2e61588931976d27935b49352ae606d23a38c69b Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 19 Apr 2022 09:39:39 +0000 Subject: [PATCH 179/259] Remove unnecessary cases for the resolver. FossilOrigin-Name: 5bc9aa68e2f938f6a70dd4b08703fe52416d17efe461ec65d37332b57b827fdd --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/resolve.c | 14 ++++++-------- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index b65721e364..a37e2c85dc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\somitted\s"finish_test"\sto\sthe\send\sof\sjoinA.test. -D 2022-04-19T02:03:18.069 +C Remove\sunnecessary\scases\sfor\sthe\sresolver. +D 2022-04-19T09:39:39.006 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -550,7 +550,7 @@ F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c fd940149c691684e7c1073c3787a7170e44852b02d1275d2e30a5b58e89cfcaf F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c -F src/resolve.c ce4cb0889f1bf5990b698740b88026385cf6f30222fde1f02a3168bb780eb579 +F src/resolve.c a3d58967025858f0f61b7b5d6c45914650acce05c33e4379a43ca4d042a68573 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 459cea7ae6e6ff517b04ad3ec7ed6479b666096a85fcec5b4edec2d5cacca2d8 F src/shell.c.in ecff6f4ab0e8e25acd578b3eb27ac0bad4d48643c160259a277151d6e9d412e1 @@ -1949,8 +1949,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 5c2f670e0fb35648e1d6e1c48f4d8af815cd57d59eac6ba22e253511bb078870 -R bb5ed5e9ec8911fef5a8aa38ca9d5eee +P 0907505cc9bb051280108fe5074211374b31836fae1ae6667a3de69f9d83fc01 +R af8749bf8e5681ed93958baf8fbcfed8 U drh -Z 938a68f2e1d34b25353fa58c5f0735ee +Z 9bd754afd9f14824483f75f7cef5bcee # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 15199a9feb..e2eb30dbdd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0907505cc9bb051280108fe5074211374b31836fae1ae6667a3de69f9d83fc01 \ No newline at end of file +5bc9aa68e2f938f6a70dd4b08703fe52416d17efe461ec65d37332b57b827fdd \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index 76e635acff..4d5e23dff4 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -322,12 +322,11 @@ static int lookupName( if( pItem->fg.isUsing==0 || sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0 ){ + /* Two or more tables have the same column name which is + ** not joined by USING. This is an error. Signal as much + ** by clearing pFJMatch and letting cnt go above 1. */ sqlite3ExprListDelete(db, pFJMatch); pFJMatch = 0; - if( pItem->fg.jointype & JT_LTORJ ){ - cnt++; - continue; - } }else if( (pItem->fg.jointype & JT_RIGHT)==0 ){ /* An INNER or LEFT JOIN. Use the left-most table */ @@ -376,12 +375,11 @@ static int lookupName( if( pItem->fg.isUsing==0 || sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0 ){ + /* Two or more tables have the same column name which is + ** not joined by USING. This is an error. Signal as much + ** by clearing pFJMatch and letting cnt go above 1. */ sqlite3ExprListDelete(db, pFJMatch); pFJMatch = 0; - if( pItem->fg.jointype & JT_LTORJ ){ - cnt++; - continue; - } }else if( (pItem->fg.jointype & JT_RIGHT)==0 ){ /* An INNER or LEFT JOIN. Use the left-most table */ From de75638b33c84970fbc96c327a557399a5948a96 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 19 Apr 2022 15:01:57 +0000 Subject: [PATCH 180/259] Add 512 new join test cases derived from PostgreSQL output. FossilOrigin-Name: 78d58e461f99366d2749ccd6d02ab4cba0cab20bb80c097e7128da1e50303549 --- manifest | 11 +- manifest.uuid | 2 +- test/joinB.test | 7252 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 7259 insertions(+), 6 deletions(-) create mode 100644 test/joinB.test diff --git a/manifest b/manifest index a37e2c85dc..e22d300275 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sunnecessary\scases\sfor\sthe\sresolver. -D 2022-04-19T09:39:39.006 +C Add\s512\snew\sjoin\stest\scases\sderived\sfrom\sPostgreSQL\soutput. +D 2022-04-19T15:01:57.355 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1150,6 +1150,7 @@ F test/join7.test 8e72de4b45e5e930d18c305c7efe86015fb2552731e4e03ea226353036b0da F test/join8.test 6ed7eed8993e060e5e9d07f6bcadf1bb634742a03b9824afbcfa193adf7f9965 F test/join9.test 9056ddd3b0c0f4f9d658f4521038d9a37dc23ead8ca9a505d0b0db2b6a471e05 F test/joinA.test 7eab225dc1c1ab258a5e62513a4ed7cabbd3db971d59d5d92f4fb6fa14c12f6a +F test/joinB.test 1b2ba3fc8568b49411787fccbf540570c148e9b6a53a30f80691cb6268098ded F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -1949,8 +1950,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 0907505cc9bb051280108fe5074211374b31836fae1ae6667a3de69f9d83fc01 -R af8749bf8e5681ed93958baf8fbcfed8 +P 5bc9aa68e2f938f6a70dd4b08703fe52416d17efe461ec65d37332b57b827fdd +R c6f0e66c49ec69e517ae5327330e468a U drh -Z 9bd754afd9f14824483f75f7cef5bcee +Z aaf42e80bfa2ba0860c31afbcd3466d6 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e2eb30dbdd..a47836b75f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5bc9aa68e2f938f6a70dd4b08703fe52416d17efe461ec65d37332b57b827fdd \ No newline at end of file +78d58e461f99366d2749ccd6d02ab4cba0cab20bb80c097e7128da1e50303549 \ No newline at end of file diff --git a/test/joinB.test b/test/joinB.test new file mode 100644 index 0000000000..baaeae677e --- /dev/null +++ b/test/joinB.test @@ -0,0 +1,7252 @@ +set testdir [file dirname $argv0] +# 2022-04-19 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file implements tests for JOINs. +# +# The test case output is all generated by PostgreSQL 14. This test module +# was created as follows: +# +# 1. Run a TCL script (included at the bottom of this file) that +# generates an input script for "psql" that will run man +# diverse tests on joins. +# +# 2. Run the script from step (1) through psql and collect the +# output. +# +# 3. Make a few minor global search-and-replace operations to convert +# the psql output into a form suitable for this test module. +# +# 4. Add this header, and the script content at the footer. +# +source $testdir/tester.tcl +db nullvalue - +db eval { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + DROP TABLE IF EXISTS t3; + DROP TABLE IF EXISTS t4; + DROP TABLE IF EXISTS t5; + CREATE TABLE t1(a INT, b INT, c INT); + CREATE TABLE t2(a INT, b INT, d INT); + CREATE TABLE t3(a INT, b INT, e INT); + CREATE TABLE t4(a INT, b INT, f INT); + CREATE TABLE t5(a INT, b INT, g INT); + INSERT INTO t1 VALUES(11,21,31),(12,22,32),(15,25,35),(17,27,37); + INSERT INTO t2 VALUES(12,22,32),(13,23,33),(15,25,35),(18,28,38), + (NULL,NULL,36); + INSERT INTO t4 VALUES(11,21,31),(13,23,33),(15,25,35),(19,29,39); + INSERT INTO t3 SELECT * FROM t1 UNION SELECT * FROM t2 UNION SELECT * FROM t4; + INSERT INTO t5 SELECT * FROM t3 WHERE a>=15; +} +do_execsql_test joinB-1 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + INNER JOIN t3 USING(a) + INNER JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 +} +do_execsql_test joinB-2 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 +} +do_execsql_test joinB-3 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + INNER JOIN t3 USING(a) + INNER JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 +} +do_execsql_test joinB-4 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN (t2 INNER JOIN t3 USING(a)) USING(a) + INNER JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 +} +do_execsql_test joinB-5 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + INNER JOIN t3 USING(a) + INNER JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - - 19 +} +do_execsql_test joinB-6 { + SELECT a, b, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - - - 39 +} +do_execsql_test joinB-7 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + INNER JOIN t3 USING(a) + INNER JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - - 19 +} +do_execsql_test joinB-8 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL INNER JOIN t2 + NATURAL INNER JOIN t3 + NATURAL INNER JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-9 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + INNER JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 +} +do_execsql_test joinB-10 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 +} +do_execsql_test joinB-11 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + INNER JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 12 - - + 15 15 15 15 15 15 +} +do_execsql_test joinB-12 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN (t2 INNER JOIN t3 USING(a)) USING(a) + LEFT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 12 32 32 32 - - + 15 35 35 35 35 35 +} +do_execsql_test joinB-13 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + INNER JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - - 19 +} +do_execsql_test joinB-14 { + SELECT a, b, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - - - 39 +} +do_execsql_test joinB-15 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + INNER JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - - 19 +} +do_execsql_test joinB-16 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL INNER JOIN t2 + NATURAL INNER JOIN t3 + NATURAL LEFT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-17 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + INNER JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 19 - - - 19 19 +} +do_execsql_test joinB-18 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 19 - - - 39 39 +} +do_execsql_test joinB-19 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + INNER JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 - - - 11 - + 13 - - - 13 - + 15 15 15 15 15 15 + 19 - - - 19 19 +} +do_execsql_test joinB-20 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN (t2 INNER JOIN t3 USING(a)) USING(a) + RIGHT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 - - - 31 - + 13 - - - 33 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-21 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + INNER JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-22 { + SELECT a, b, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - - 39 39 +} +do_execsql_test joinB-23 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + INNER JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 - - - 11 - + 13 - - - 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-24 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL INNER JOIN t2 + NATURAL INNER JOIN t3 + NATURAL RIGHT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-25 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + INNER JOIN t3 USING(a) + FULL JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 19 - - - 19 19 +} +do_execsql_test joinB-26 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 19 - - - 39 39 +} +do_execsql_test joinB-27 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + INNER JOIN t3 USING(a) + FULL JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 - - - 11 - + 12 12 12 12 - - + 13 - - - 13 - + 15 15 15 15 15 15 + 19 - - - 19 19 +} +do_execsql_test joinB-28 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN (t2 INNER JOIN t3 USING(a)) USING(a) + FULL JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 - - - 31 - + 12 32 32 32 - - + 13 - - - 33 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-29 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + INNER JOIN t3 USING(a) + FULL JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-30 { + SELECT a, b, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - - 39 39 +} +do_execsql_test joinB-31 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + INNER JOIN t3 USING(a) + FULL JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 - - - 11 - + 12 12 12 12 - - + 13 - - - 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-32 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL INNER JOIN t2 + NATURAL INNER JOIN t3 + NATURAL FULL JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-33 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 +} +do_execsql_test joinB-34 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 +} +do_execsql_test joinB-35 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 +} +do_execsql_test joinB-36 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN (t2 LEFT JOIN t3 USING(a)) USING(a) + INNER JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 +} +do_execsql_test joinB-37 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - - 19 +} +do_execsql_test joinB-38 { + SELECT a, b, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - - - 39 +} +do_execsql_test joinB-39 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - - 19 +} +do_execsql_test joinB-40 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL INNER JOIN t2 + NATURAL LEFT JOIN t3 + NATURAL INNER JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-41 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 +} +do_execsql_test joinB-42 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 +} +do_execsql_test joinB-43 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 12 - - + 15 15 15 15 15 15 +} +do_execsql_test joinB-44 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN (t2 LEFT JOIN t3 USING(a)) USING(a) + LEFT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 12 32 32 32 - - + 15 35 35 35 35 35 +} +do_execsql_test joinB-45 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - - 19 +} +do_execsql_test joinB-46 { + SELECT a, b, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - - - 39 +} +do_execsql_test joinB-47 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - - 19 +} +do_execsql_test joinB-48 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL INNER JOIN t2 + NATURAL LEFT JOIN t3 + NATURAL LEFT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-49 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 19 - - - 19 19 +} +do_execsql_test joinB-50 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 19 - - - 39 39 +} +do_execsql_test joinB-51 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 - - - 11 - + 13 - - - 13 - + 15 15 15 15 15 15 + 19 - - - 19 19 +} +do_execsql_test joinB-52 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN (t2 LEFT JOIN t3 USING(a)) USING(a) + RIGHT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 - - - 31 - + 13 - - - 33 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-53 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-54 { + SELECT a, b, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - - 39 39 +} +do_execsql_test joinB-55 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 - - - 11 - + 13 - - - 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-56 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL INNER JOIN t2 + NATURAL LEFT JOIN t3 + NATURAL RIGHT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-57 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 19 - - - 19 19 +} +do_execsql_test joinB-58 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 19 - - - 39 39 +} +do_execsql_test joinB-59 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 - - - 11 - + 12 12 12 12 - - + 13 - - - 13 - + 15 15 15 15 15 15 + 19 - - - 19 19 +} +do_execsql_test joinB-60 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN (t2 LEFT JOIN t3 USING(a)) USING(a) + FULL JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 - - - 31 - + 12 32 32 32 - - + 13 - - - 33 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-61 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-62 { + SELECT a, b, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - - 39 39 +} +do_execsql_test joinB-63 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 - - - 11 - + 12 12 12 12 - - + 13 - - - 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-64 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL INNER JOIN t2 + NATURAL LEFT JOIN t3 + NATURAL FULL JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-65 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-66 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 19 - - 39 39 39 +} +do_execsql_test joinB-67 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 - - 11 11 - + 13 - - 13 13 - + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-68 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN (t2 RIGHT JOIN t3 USING(a)) USING(a) + INNER JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-69 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-70 { + SELECT a, b, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-71 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 - - 11 11 - + 13 - - 13 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-72 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL INNER JOIN t2 + NATURAL RIGHT JOIN t3 + NATURAL INNER JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-73 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-74 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 17 - - 37 - 37 + 18 - - 38 - 38 + 19 - - 39 39 39 +} +do_execsql_test joinB-75 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 - - 11 11 - + 12 12 12 12 - - + 13 - - 13 13 - + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-76 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN (t2 RIGHT JOIN t3 USING(a)) USING(a) + LEFT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 12 32 32 32 - - + 15 35 35 35 35 35 + 17 37 - 37 - - +} +do_execsql_test joinB-77 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-78 { + SELECT a, b, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - 37 - 37 + 18 28 - - 38 - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-79 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 - - 11 11 - + 12 12 12 12 - - + 13 - - 13 13 - + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-80 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL INNER JOIN t2 + NATURAL RIGHT JOIN t3 + NATURAL LEFT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-81 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-82 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 19 - - 39 39 39 +} +do_execsql_test joinB-83 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 - - 11 11 - + 13 - - 13 13 - + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-84 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN (t2 RIGHT JOIN t3 USING(a)) USING(a) + RIGHT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 13 - - - 33 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-85 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-86 { + SELECT a, b, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-87 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 - - 11 11 - + 13 - - 13 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-88 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL INNER JOIN t2 + NATURAL RIGHT JOIN t3 + NATURAL RIGHT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-89 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-90 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 17 - - 37 - 37 + 18 - - 38 - 38 + 19 - - 39 39 39 +} +do_execsql_test joinB-91 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 - - 11 11 - + 12 12 12 12 - - + 13 - - 13 13 - + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-92 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN (t2 RIGHT JOIN t3 USING(a)) USING(a) + FULL JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 12 32 32 32 - - + 13 - - - 33 - + 15 35 35 35 35 35 + 17 37 - 37 - - +} +do_execsql_test joinB-93 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-94 { + SELECT a, b, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - 37 - 37 + 18 28 - - 38 - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-95 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 - - 11 11 - + 12 12 12 12 - - + 13 - - 13 13 - + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-96 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL INNER JOIN t2 + NATURAL RIGHT JOIN t3 + NATURAL FULL JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-97 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + FULL JOIN t3 USING(a) + INNER JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-98 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 19 - - 39 39 39 +} +do_execsql_test joinB-99 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + FULL JOIN t3 USING(a) + INNER JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 - - 11 11 - + 13 - - 13 13 - + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-100 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN (t2 FULL JOIN t3 USING(a)) USING(a) + INNER JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-101 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + FULL JOIN t3 USING(a) + INNER JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-102 { + SELECT a, b, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-103 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + FULL JOIN t3 USING(a) + INNER JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 - - 11 11 - + 13 - - 13 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-104 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL INNER JOIN t2 + NATURAL FULL JOIN t3 + NATURAL INNER JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-105 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + FULL JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-106 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 17 - - 37 - 37 + 18 - - 38 - 38 + 19 - - 39 39 39 +} +do_execsql_test joinB-107 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + FULL JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 - - 11 11 - + 12 12 12 12 - - + 13 - - 13 13 - + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-108 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN (t2 FULL JOIN t3 USING(a)) USING(a) + LEFT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 12 32 32 32 - - + 15 35 35 35 35 35 + 17 37 - 37 - - +} +do_execsql_test joinB-109 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + FULL JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-110 { + SELECT a, b, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - 37 - 37 + 18 28 - - 38 - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-111 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + FULL JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 - - 11 11 - + 12 12 12 12 - - + 13 - - 13 13 - + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-112 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL INNER JOIN t2 + NATURAL FULL JOIN t3 + NATURAL LEFT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-113 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + FULL JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-114 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 19 - - 39 39 39 +} +do_execsql_test joinB-115 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + FULL JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 - - 11 11 - + 13 - - 13 13 - + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-116 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN (t2 FULL JOIN t3 USING(a)) USING(a) + RIGHT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 13 - - - 33 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-117 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + FULL JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-118 { + SELECT a, b, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-119 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + FULL JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 - - 11 11 - + 13 - - 13 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-120 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL INNER JOIN t2 + NATURAL FULL JOIN t3 + NATURAL RIGHT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-121 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + FULL JOIN t3 USING(a) + FULL JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-122 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 17 - - 37 - 37 + 18 - - 38 - 38 + 19 - - 39 39 39 +} +do_execsql_test joinB-123 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + FULL JOIN t3 USING(a) + FULL JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 - - 11 11 - + 12 12 12 12 - - + 13 - - 13 13 - + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-124 { + SELECT a, c, d, e, f, g + FROM t1 + INNER JOIN (t2 FULL JOIN t3 USING(a)) USING(a) + FULL JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 12 32 32 32 - - + 13 - - - 33 - + 15 35 35 35 35 35 + 17 37 - 37 - - +} +do_execsql_test joinB-125 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + FULL JOIN t3 USING(a) + FULL JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-126 { + SELECT a, b, c, d, e, f, g + FROM t1 + INNER JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - 37 - 37 + 18 28 - - 38 - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-127 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + INNER JOIN t2 USING(a) + FULL JOIN t3 USING(a) + FULL JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 - - 11 11 - + 12 12 12 12 - - + 13 - - 13 13 - + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-128 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL INNER JOIN t2 + NATURAL FULL JOIN t3 + NATURAL FULL JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-129 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + INNER JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 +} +do_execsql_test joinB-130 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 +} +do_execsql_test joinB-131 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + INNER JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 15 15 15 15 15 15 +} +do_execsql_test joinB-132 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN (t2 INNER JOIN t3 USING(a)) USING(a) + INNER JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - - 31 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-133 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + INNER JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - - 19 +} +do_execsql_test joinB-134 { + SELECT a, b, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - - - 39 +} +do_execsql_test joinB-135 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + INNER JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - - 19 +} +do_execsql_test joinB-136 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL LEFT JOIN t2 + NATURAL INNER JOIN t3 + NATURAL INNER JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-137 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 +} +do_execsql_test joinB-138 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 17 37 - 37 - 37 +} +do_execsql_test joinB-139 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 +} +do_execsql_test joinB-140 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN (t2 INNER JOIN t3 USING(a)) USING(a) + LEFT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - - 31 - + 12 32 32 32 - - + 15 35 35 35 35 35 + 17 37 - - - - +} +do_execsql_test joinB-141 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - - - - 18 + 19 - - - - 19 +} +do_execsql_test joinB-142 { + SELECT a, b, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 37 - 37 - 37 + 18 28 - - - - 38 + 19 29 - - - - 39 +} +do_execsql_test joinB-143 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - - - - 18 + 19 - - - - 19 +} +do_execsql_test joinB-144 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL LEFT JOIN t2 + NATURAL INNER JOIN t3 + NATURAL LEFT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-145 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 19 - - - 19 19 +} +do_execsql_test joinB-146 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 19 - - - 39 39 +} +do_execsql_test joinB-147 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - - - 13 - + 15 15 15 15 15 15 + 19 - - - 19 19 +} +do_execsql_test joinB-148 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN (t2 INNER JOIN t3 USING(a)) USING(a) + RIGHT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - - 31 - + 13 - - - 33 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-149 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-150 { + SELECT a, b, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - - 39 39 +} +do_execsql_test joinB-151 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - - - 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-152 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL LEFT JOIN t2 + NATURAL INNER JOIN t3 + NATURAL RIGHT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-153 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + FULL JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 19 - - - 19 19 +} +do_execsql_test joinB-154 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 17 37 - 37 - 37 + 19 - - - 39 39 +} +do_execsql_test joinB-155 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + FULL JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - - - 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 19 - - - 19 19 +} +do_execsql_test joinB-156 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN (t2 INNER JOIN t3 USING(a)) USING(a) + FULL JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - - 31 - + 12 32 32 32 - - + 13 - - - 33 - + 15 35 35 35 35 35 + 17 37 - - - - +} +do_execsql_test joinB-157 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + FULL JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - - - - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-158 { + SELECT a, b, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 37 - 37 - 37 + 18 28 - - - - 38 + 19 29 - - - 39 39 +} +do_execsql_test joinB-159 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + FULL JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - - - 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - - - - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-160 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL LEFT JOIN t2 + NATURAL INNER JOIN t3 + NATURAL FULL JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-161 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 +} +do_execsql_test joinB-162 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 +} +do_execsql_test joinB-163 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 15 15 15 15 15 15 +} +do_execsql_test joinB-164 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN (t2 LEFT JOIN t3 USING(a)) USING(a) + INNER JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - - 31 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-165 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - - 19 +} +do_execsql_test joinB-166 { + SELECT a, b, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - - - 39 +} +do_execsql_test joinB-167 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - - 19 +} +do_execsql_test joinB-168 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL LEFT JOIN t2 + NATURAL LEFT JOIN t3 + NATURAL INNER JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-169 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 +} +do_execsql_test joinB-170 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 17 37 - 37 - 37 +} +do_execsql_test joinB-171 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 +} +do_execsql_test joinB-172 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN (t2 LEFT JOIN t3 USING(a)) USING(a) + LEFT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - - 31 - + 12 32 32 32 - - + 15 35 35 35 35 35 + 17 37 - - - - +} +do_execsql_test joinB-173 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - - - - 18 + 19 - - - - 19 +} +do_execsql_test joinB-174 { + SELECT a, b, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 37 - 37 - 37 + 18 28 - - - - 38 + 19 29 - - - - 39 +} +do_execsql_test joinB-175 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - - - - 18 + 19 - - - - 19 +} +do_execsql_test joinB-176 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL LEFT JOIN t2 + NATURAL LEFT JOIN t3 + NATURAL LEFT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-177 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 19 - - - 19 19 +} +do_execsql_test joinB-178 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 19 - - - 39 39 +} +do_execsql_test joinB-179 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - - - 13 - + 15 15 15 15 15 15 + 19 - - - 19 19 +} +do_execsql_test joinB-180 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN (t2 LEFT JOIN t3 USING(a)) USING(a) + RIGHT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - - 31 - + 13 - - - 33 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-181 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-182 { + SELECT a, b, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - - 39 39 +} +do_execsql_test joinB-183 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - - - 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-184 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL LEFT JOIN t2 + NATURAL LEFT JOIN t3 + NATURAL RIGHT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-185 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 19 - - - 19 19 +} +do_execsql_test joinB-186 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 17 37 - 37 - 37 + 19 - - - 39 39 +} +do_execsql_test joinB-187 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - - - 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 19 - - - 19 19 +} +do_execsql_test joinB-188 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN (t2 LEFT JOIN t3 USING(a)) USING(a) + FULL JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - - 31 - + 12 32 32 32 - - + 13 - - - 33 - + 15 35 35 35 35 35 + 17 37 - - - - +} +do_execsql_test joinB-189 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - - - - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-190 { + SELECT a, b, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 37 - 37 - 37 + 18 28 - - - - 38 + 19 29 - - - 39 39 +} +do_execsql_test joinB-191 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - - - 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - - - - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-192 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL LEFT JOIN t2 + NATURAL LEFT JOIN t3 + NATURAL FULL JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-193 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-194 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 19 - - 39 39 39 +} +do_execsql_test joinB-195 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - - 13 13 - + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-196 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN (t2 RIGHT JOIN t3 USING(a)) USING(a) + INNER JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-197 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-198 { + SELECT a, b, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-199 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - - 13 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-200 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL LEFT JOIN t2 + NATURAL RIGHT JOIN t3 + NATURAL INNER JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-201 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-202 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 17 37 - 37 - 37 + 18 - - 38 - 38 + 19 - - 39 39 39 +} +do_execsql_test joinB-203 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - - 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-204 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN (t2 RIGHT JOIN t3 USING(a)) USING(a) + LEFT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 12 32 32 32 - - + 15 35 35 35 35 35 + 17 37 - 37 - - +} +do_execsql_test joinB-205 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-206 { + SELECT a, b, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 37 - 37 - 37 + 18 28 - - 38 - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-207 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - - 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-208 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL LEFT JOIN t2 + NATURAL RIGHT JOIN t3 + NATURAL LEFT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-209 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-210 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 19 - - 39 39 39 +} +do_execsql_test joinB-211 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - - 13 13 - + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-212 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN (t2 RIGHT JOIN t3 USING(a)) USING(a) + RIGHT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 13 - - - 33 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-213 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-214 { + SELECT a, b, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-215 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - - 13 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-216 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL LEFT JOIN t2 + NATURAL RIGHT JOIN t3 + NATURAL RIGHT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-217 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-218 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 17 37 - 37 - 37 + 18 - - 38 - 38 + 19 - - 39 39 39 +} +do_execsql_test joinB-219 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - - 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-220 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN (t2 RIGHT JOIN t3 USING(a)) USING(a) + FULL JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 12 32 32 32 - - + 13 - - - 33 - + 15 35 35 35 35 35 + 17 37 - 37 - - +} +do_execsql_test joinB-221 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-222 { + SELECT a, b, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 37 - 37 - 37 + 18 28 - - 38 - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-223 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - - 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-224 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL LEFT JOIN t2 + NATURAL RIGHT JOIN t3 + NATURAL FULL JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-225 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + INNER JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-226 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 19 - - 39 39 39 +} +do_execsql_test joinB-227 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + INNER JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - - 13 13 - + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-228 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN (t2 FULL JOIN t3 USING(a)) USING(a) + INNER JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-229 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + INNER JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-230 { + SELECT a, b, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-231 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + INNER JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - - 13 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-232 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL LEFT JOIN t2 + NATURAL FULL JOIN t3 + NATURAL INNER JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-233 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-234 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 17 37 - 37 - 37 + 18 - - 38 - 38 + 19 - - 39 39 39 +} +do_execsql_test joinB-235 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - - 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-236 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN (t2 FULL JOIN t3 USING(a)) USING(a) + LEFT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 12 32 32 32 - - + 15 35 35 35 35 35 + 17 37 - 37 - - +} +do_execsql_test joinB-237 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-238 { + SELECT a, b, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 37 - 37 - 37 + 18 28 - - 38 - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-239 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - - 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-240 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL LEFT JOIN t2 + NATURAL FULL JOIN t3 + NATURAL LEFT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-241 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-242 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 19 - - 39 39 39 +} +do_execsql_test joinB-243 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - - 13 13 - + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-244 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN (t2 FULL JOIN t3 USING(a)) USING(a) + RIGHT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 13 - - - 33 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-245 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-246 { + SELECT a, b, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-247 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - - 13 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-248 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL LEFT JOIN t2 + NATURAL FULL JOIN t3 + NATURAL RIGHT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-249 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + FULL JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-250 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 17 37 - 37 - 37 + 18 - - 38 - 38 + 19 - - 39 39 39 +} +do_execsql_test joinB-251 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + FULL JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - - 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-252 { + SELECT a, c, d, e, f, g + FROM t1 + LEFT JOIN (t2 FULL JOIN t3 USING(a)) USING(a) + FULL JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 12 32 32 32 - - + 13 - - - 33 - + 15 35 35 35 35 35 + 17 37 - 37 - - +} +do_execsql_test joinB-253 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + FULL JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-254 { + SELECT a, b, c, d, e, f, g + FROM t1 + LEFT JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 37 - 37 - 37 + 18 28 - - 38 - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-255 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + LEFT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + FULL JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - - 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - - 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-256 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL LEFT JOIN t2 + NATURAL FULL JOIN t3 + NATURAL FULL JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-257 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + INNER JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 +} +do_execsql_test joinB-258 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 +} +do_execsql_test joinB-259 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + INNER JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 13 - 13 13 13 - + 15 15 15 15 15 15 +} +do_execsql_test joinB-260 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN (t2 INNER JOIN t3 USING(a)) USING(a) + INNER JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 13 - 33 33 33 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-261 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + INNER JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - - 19 +} +do_execsql_test joinB-262 { + SELECT a, b, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - - - 39 +} +do_execsql_test joinB-263 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + INNER JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - - 19 +} +do_execsql_test joinB-264 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL RIGHT JOIN t2 + NATURAL INNER JOIN t3 + NATURAL INNER JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-265 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 18 - 18 18 - 18 +} +do_execsql_test joinB-266 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 18 - 38 38 - 38 +} +do_execsql_test joinB-267 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 18 - 18 18 - 18 +} +do_execsql_test joinB-268 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN (t2 INNER JOIN t3 USING(a)) USING(a) + LEFT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 12 32 32 32 - - + 13 - 33 33 33 - + 15 35 35 35 35 35 + 18 - 38 38 - - +} +do_execsql_test joinB-269 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - 18 18 - 18 + 19 - - - - 19 +} +do_execsql_test joinB-270 { + SELECT a, b, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - 38 38 - 38 + 19 29 - - - - 39 +} +do_execsql_test joinB-271 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - 18 18 - 18 + 19 - - - - 19 +} +do_execsql_test joinB-272 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL RIGHT JOIN t2 + NATURAL INNER JOIN t3 + NATURAL LEFT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-273 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 19 - - - 19 19 +} +do_execsql_test joinB-274 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 19 - - - 39 39 +} +do_execsql_test joinB-275 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 - - - 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 19 - - - 19 19 +} +do_execsql_test joinB-276 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN (t2 INNER JOIN t3 USING(a)) USING(a) + RIGHT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 - - - 31 - + 13 - 33 33 33 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-277 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-278 { + SELECT a, b, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - - 39 39 +} +do_execsql_test joinB-279 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 - - - 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-280 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL RIGHT JOIN t2 + NATURAL INNER JOIN t3 + NATURAL RIGHT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-281 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + FULL JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 18 - 18 18 - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-282 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 18 - 38 38 - 38 + 19 - - - 39 39 +} +do_execsql_test joinB-283 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + FULL JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 - - - 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 18 - 18 18 - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-284 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN (t2 INNER JOIN t3 USING(a)) USING(a) + FULL JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 - - - 31 - + 12 32 32 32 - - + 13 - 33 33 33 - + 15 35 35 35 35 35 + 18 - 38 38 - - +} +do_execsql_test joinB-285 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + FULL JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - 18 18 - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-286 { + SELECT a, b, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - 38 38 - 38 + 19 29 - - - 39 39 +} +do_execsql_test joinB-287 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + INNER JOIN t3 USING(a) + FULL JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 - - - 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - 18 18 - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-288 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL RIGHT JOIN t2 + NATURAL INNER JOIN t3 + NATURAL FULL JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-289 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 +} +do_execsql_test joinB-290 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 +} +do_execsql_test joinB-291 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 13 - 13 13 13 - + 15 15 15 15 15 15 +} +do_execsql_test joinB-292 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN (t2 LEFT JOIN t3 USING(a)) USING(a) + INNER JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 13 - 33 33 33 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-293 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - - 19 +} +do_execsql_test joinB-294 { + SELECT a, b, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - - - 39 +} +do_execsql_test joinB-295 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - - 19 +} +do_execsql_test joinB-296 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL RIGHT JOIN t2 + NATURAL LEFT JOIN t3 + NATURAL INNER JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-297 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 18 - 18 18 - 18 +} +do_execsql_test joinB-298 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 18 - 38 38 - 38 +} +do_execsql_test joinB-299 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 18 - 18 18 - 18 +} +do_execsql_test joinB-300 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN (t2 LEFT JOIN t3 USING(a)) USING(a) + LEFT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 12 32 32 32 - - + 13 - 33 33 33 - + 15 35 35 35 35 35 + 18 - 38 38 - - +} +do_execsql_test joinB-301 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - 18 18 - 18 + 19 - - - - 19 +} +do_execsql_test joinB-302 { + SELECT a, b, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - 38 38 - 38 + 19 29 - - - - 39 +} +do_execsql_test joinB-303 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - 18 18 - 18 + 19 - - - - 19 +} +do_execsql_test joinB-304 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL RIGHT JOIN t2 + NATURAL LEFT JOIN t3 + NATURAL LEFT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-305 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 19 - - - 19 19 +} +do_execsql_test joinB-306 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 19 - - - 39 39 +} +do_execsql_test joinB-307 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 - - - 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 19 - - - 19 19 +} +do_execsql_test joinB-308 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN (t2 LEFT JOIN t3 USING(a)) USING(a) + RIGHT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 - - - 31 - + 13 - 33 33 33 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-309 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-310 { + SELECT a, b, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - - 39 39 +} +do_execsql_test joinB-311 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 - - - 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-312 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL RIGHT JOIN t2 + NATURAL LEFT JOIN t3 + NATURAL RIGHT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-313 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 18 - 18 18 - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-314 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 18 - 38 38 - 38 + 19 - - - 39 39 +} +do_execsql_test joinB-315 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 - - - 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 18 - 18 18 - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-316 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN (t2 LEFT JOIN t3 USING(a)) USING(a) + FULL JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 - - - 31 - + 12 32 32 32 - - + 13 - 33 33 33 - + 15 35 35 35 35 35 + 18 - 38 38 - - +} +do_execsql_test joinB-317 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - 18 18 - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-318 { + SELECT a, b, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - 38 38 - 38 + 19 29 - - - 39 39 +} +do_execsql_test joinB-319 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 - - - 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - 18 18 - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-320 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL RIGHT JOIN t2 + NATURAL LEFT JOIN t3 + NATURAL FULL JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-321 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-322 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 19 - - 39 39 39 +} +do_execsql_test joinB-323 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 - - 11 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-324 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN (t2 RIGHT JOIN t3 USING(a)) USING(a) + INNER JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 13 - 33 33 33 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-325 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-326 { + SELECT a, b, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-327 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 - - 11 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-328 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL RIGHT JOIN t2 + NATURAL RIGHT JOIN t3 + NATURAL INNER JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-329 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-330 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 17 - - 37 - 37 + 18 - 38 38 - 38 + 19 - - 39 39 39 +} +do_execsql_test joinB-331 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 - - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-332 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN (t2 RIGHT JOIN t3 USING(a)) USING(a) + LEFT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 12 32 32 32 - - + 13 - 33 33 33 - + 15 35 35 35 35 35 + 17 37 - 37 - - + 18 - 38 38 - - +} +do_execsql_test joinB-333 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-334 { + SELECT a, b, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - 37 - 37 + 18 28 - 38 38 - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-335 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 - - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-336 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL RIGHT JOIN t2 + NATURAL RIGHT JOIN t3 + NATURAL LEFT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-337 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-338 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 19 - - 39 39 39 +} +do_execsql_test joinB-339 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 - - 11 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-340 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN (t2 RIGHT JOIN t3 USING(a)) USING(a) + RIGHT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 13 - 33 33 33 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-341 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-342 { + SELECT a, b, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-343 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 - - 11 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-344 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL RIGHT JOIN t2 + NATURAL RIGHT JOIN t3 + NATURAL RIGHT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-345 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-346 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 17 - - 37 - 37 + 18 - 38 38 - 38 + 19 - - 39 39 39 +} +do_execsql_test joinB-347 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 - - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-348 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN (t2 RIGHT JOIN t3 USING(a)) USING(a) + FULL JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 12 32 32 32 - - + 13 - 33 33 33 - + 15 35 35 35 35 35 + 17 37 - 37 - - + 18 - 38 38 - - +} +do_execsql_test joinB-349 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-350 { + SELECT a, b, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - 37 - 37 + 18 28 - 38 38 - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-351 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 - - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-352 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL RIGHT JOIN t2 + NATURAL RIGHT JOIN t3 + NATURAL FULL JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-353 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + INNER JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-354 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 19 - - 39 39 39 +} +do_execsql_test joinB-355 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + INNER JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 - - 11 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-356 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN (t2 FULL JOIN t3 USING(a)) USING(a) + INNER JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 13 - 33 33 33 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-357 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + INNER JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-358 { + SELECT a, b, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-359 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + INNER JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 - - 11 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-360 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL RIGHT JOIN t2 + NATURAL FULL JOIN t3 + NATURAL INNER JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-361 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-362 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 17 - - 37 - 37 + 18 - 38 38 - 38 + 19 - - 39 39 39 +} +do_execsql_test joinB-363 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + - - - - - - + 11 - - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-364 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN (t2 FULL JOIN t3 USING(a)) USING(a) + LEFT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 12 32 32 32 - - + 13 - 33 33 33 - + 15 35 35 35 35 35 + 17 37 - 37 - - + 18 - 38 38 - - +} +do_execsql_test joinB-365 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-366 { + SELECT a, b, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - 37 - 37 + 18 28 - 38 38 - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-367 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + - - - - - - + 11 - - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-368 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL RIGHT JOIN t2 + NATURAL FULL JOIN t3 + NATURAL LEFT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-369 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-370 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 19 - - 39 39 39 +} +do_execsql_test joinB-371 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 - - 11 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-372 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN (t2 FULL JOIN t3 USING(a)) USING(a) + RIGHT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 13 - 33 33 33 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-373 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-374 { + SELECT a, b, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-375 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 - - 11 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-376 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL RIGHT JOIN t2 + NATURAL FULL JOIN t3 + NATURAL RIGHT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-377 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + FULL JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-378 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 17 - - 37 - 37 + 18 - 38 38 - 38 + 19 - - 39 39 39 +} +do_execsql_test joinB-379 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + FULL JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + - - - - - - + 11 - - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-380 { + SELECT a, c, d, e, f, g + FROM t1 + RIGHT JOIN (t2 FULL JOIN t3 USING(a)) USING(a) + FULL JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 12 32 32 32 - - + 13 - 33 33 33 - + 15 35 35 35 35 35 + 17 37 - 37 - - + 18 - 38 38 - - +} +do_execsql_test joinB-381 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + FULL JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-382 { + SELECT a, b, c, d, e, f, g + FROM t1 + RIGHT JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - 37 - 37 + 18 28 - 38 38 - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-383 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + RIGHT JOIN t2 USING(a) + FULL JOIN t3 USING(a) + FULL JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + - - - - - - + 11 - - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 - - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-384 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL RIGHT JOIN t2 + NATURAL FULL JOIN t3 + NATURAL FULL JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-385 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + INNER JOIN t3 USING(a) + INNER JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 +} +do_execsql_test joinB-386 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 +} +do_execsql_test joinB-387 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + INNER JOIN t3 USING(a) + INNER JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 +} +do_execsql_test joinB-388 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN (t2 INNER JOIN t3 USING(a)) USING(a) + INNER JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - - 31 - + 13 - 33 33 33 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-389 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + INNER JOIN t3 USING(a) + INNER JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - - 19 +} +do_execsql_test joinB-390 { + SELECT a, b, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - - - 39 +} +do_execsql_test joinB-391 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + INNER JOIN t3 USING(a) + INNER JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - - 19 +} +do_execsql_test joinB-392 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL FULL JOIN t2 + NATURAL INNER JOIN t3 + NATURAL INNER JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-393 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + INNER JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 +} +do_execsql_test joinB-394 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 17 37 - 37 - 37 + 18 - 38 38 - 38 +} +do_execsql_test joinB-395 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + INNER JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 +} +do_execsql_test joinB-396 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN (t2 INNER JOIN t3 USING(a)) USING(a) + LEFT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - - 31 - + 12 32 32 32 - - + 13 - 33 33 33 - + 15 35 35 35 35 35 + 17 37 - - - - + 18 - 38 38 - - +} +do_execsql_test joinB-397 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + INNER JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - - - 19 +} +do_execsql_test joinB-398 { + SELECT a, b, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 37 - 37 - 37 + 18 28 - 38 38 - 38 + 19 29 - - - - 39 +} +do_execsql_test joinB-399 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + INNER JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - - - 19 +} +do_execsql_test joinB-400 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL FULL JOIN t2 + NATURAL INNER JOIN t3 + NATURAL LEFT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-401 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + INNER JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 19 - - - 19 19 +} +do_execsql_test joinB-402 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 19 - - - 39 39 +} +do_execsql_test joinB-403 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + INNER JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 19 - - - 19 19 +} +do_execsql_test joinB-404 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN (t2 INNER JOIN t3 USING(a)) USING(a) + RIGHT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - - 31 - + 13 - 33 33 33 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-405 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + INNER JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-406 { + SELECT a, b, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - - 39 39 +} +do_execsql_test joinB-407 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + INNER JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-408 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL FULL JOIN t2 + NATURAL INNER JOIN t3 + NATURAL RIGHT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-409 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + INNER JOIN t3 USING(a) + FULL JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-410 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 17 37 - 37 - 37 + 18 - 38 38 - 38 + 19 - - - 39 39 +} +do_execsql_test joinB-411 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + INNER JOIN t3 USING(a) + FULL JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-412 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN (t2 INNER JOIN t3 USING(a)) USING(a) + FULL JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - - 31 - + 12 32 32 32 - - + 13 - 33 33 33 - + 15 35 35 35 35 35 + 17 37 - - - - + 18 - 38 38 - - +} +do_execsql_test joinB-413 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + INNER JOIN t3 USING(a) + FULL JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-414 { + SELECT a, b, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + INNER JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 37 - 37 - 37 + 18 28 - 38 38 - 38 + 19 29 - - - 39 39 +} +do_execsql_test joinB-415 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + INNER JOIN t3 USING(a) + FULL JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-416 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL FULL JOIN t2 + NATURAL INNER JOIN t3 + NATURAL FULL JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-417 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 +} +do_execsql_test joinB-418 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 +} +do_execsql_test joinB-419 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 +} +do_execsql_test joinB-420 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN (t2 LEFT JOIN t3 USING(a)) USING(a) + INNER JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - - 31 - + 13 - 33 33 33 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-421 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - - 19 +} +do_execsql_test joinB-422 { + SELECT a, b, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - - - 39 +} +do_execsql_test joinB-423 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - - 19 +} +do_execsql_test joinB-424 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL FULL JOIN t2 + NATURAL LEFT JOIN t3 + NATURAL INNER JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-425 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 +} +do_execsql_test joinB-426 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 17 37 - 37 - 37 + 18 - 38 38 - 38 +} +do_execsql_test joinB-427 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 +} +do_execsql_test joinB-428 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN (t2 LEFT JOIN t3 USING(a)) USING(a) + LEFT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - - 31 - + 12 32 32 32 - - + 13 - 33 33 33 - + 15 35 35 35 35 35 + 17 37 - - - - + 18 - 38 38 - - +} +do_execsql_test joinB-429 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - - - 19 +} +do_execsql_test joinB-430 { + SELECT a, b, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 37 - 37 - 37 + 18 28 - 38 38 - 38 + 19 29 - - - - 39 +} +do_execsql_test joinB-431 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - - - 19 +} +do_execsql_test joinB-432 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL FULL JOIN t2 + NATURAL LEFT JOIN t3 + NATURAL LEFT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-433 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 19 - - - 19 19 +} +do_execsql_test joinB-434 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 19 - - - 39 39 +} +do_execsql_test joinB-435 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 19 - - - 19 19 +} +do_execsql_test joinB-436 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN (t2 LEFT JOIN t3 USING(a)) USING(a) + RIGHT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - - 31 - + 13 - 33 33 33 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-437 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-438 { + SELECT a, b, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - - 39 39 +} +do_execsql_test joinB-439 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-440 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL FULL JOIN t2 + NATURAL LEFT JOIN t3 + NATURAL RIGHT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-441 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-442 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 17 37 - 37 - 37 + 18 - 38 38 - 38 + 19 - - - 39 39 +} +do_execsql_test joinB-443 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-444 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN (t2 LEFT JOIN t3 USING(a)) USING(a) + FULL JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - - 31 - + 12 32 32 32 - - + 13 - 33 33 33 - + 15 35 35 35 35 35 + 17 37 - - - - + 18 - 38 38 - - +} +do_execsql_test joinB-445 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-446 { + SELECT a, b, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + LEFT JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 37 - 37 - 37 + 18 28 - 38 38 - 38 + 19 29 - - - 39 39 +} +do_execsql_test joinB-447 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + LEFT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - - 19 19 +} +do_execsql_test joinB-448 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL FULL JOIN t2 + NATURAL LEFT JOIN t3 + NATURAL FULL JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-449 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-450 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 19 - - 39 39 39 +} +do_execsql_test joinB-451 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-452 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN (t2 RIGHT JOIN t3 USING(a)) USING(a) + INNER JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 13 - 33 33 33 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-453 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-454 { + SELECT a, b, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-455 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + INNER JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-456 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL FULL JOIN t2 + NATURAL RIGHT JOIN t3 + NATURAL INNER JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-457 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-458 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 17 37 - 37 - 37 + 18 - 38 38 - 38 + 19 - - 39 39 39 +} +do_execsql_test joinB-459 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-460 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN (t2 RIGHT JOIN t3 USING(a)) USING(a) + LEFT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 12 32 32 32 - - + 13 - 33 33 33 - + 15 35 35 35 35 35 + 17 37 - 37 - - + 18 - 38 38 - - +} +do_execsql_test joinB-461 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-462 { + SELECT a, b, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 37 - 37 - 37 + 18 28 - 38 38 - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-463 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-464 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL FULL JOIN t2 + NATURAL RIGHT JOIN t3 + NATURAL LEFT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-465 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-466 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 19 - - 39 39 39 +} +do_execsql_test joinB-467 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-468 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN (t2 RIGHT JOIN t3 USING(a)) USING(a) + RIGHT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 13 - 33 33 33 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-469 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-470 { + SELECT a, b, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-471 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-472 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL FULL JOIN t2 + NATURAL RIGHT JOIN t3 + NATURAL RIGHT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-473 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-474 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 17 37 - 37 - 37 + 18 - 38 38 - 38 + 19 - - 39 39 39 +} +do_execsql_test joinB-475 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-476 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN (t2 RIGHT JOIN t3 USING(a)) USING(a) + FULL JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 12 32 32 32 - - + 13 - 33 33 33 - + 15 35 35 35 35 35 + 17 37 - 37 - - + 18 - 38 38 - - +} +do_execsql_test joinB-477 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-478 { + SELECT a, b, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + RIGHT JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 37 - 37 - 37 + 18 28 - 38 38 - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-479 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + RIGHT JOIN t3 USING(a) + FULL JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-480 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL FULL JOIN t2 + NATURAL RIGHT JOIN t3 + NATURAL FULL JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-481 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + FULL JOIN t3 USING(a) + INNER JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-482 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 19 - - 39 39 39 +} +do_execsql_test joinB-483 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + FULL JOIN t3 USING(a) + INNER JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-484 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN (t2 FULL JOIN t3 USING(a)) USING(a) + INNER JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 13 - 33 33 33 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-485 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + FULL JOIN t3 USING(a) + INNER JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-486 { + SELECT a, b, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + INNER JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-487 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + FULL JOIN t3 USING(a) + INNER JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-488 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL FULL JOIN t2 + NATURAL FULL JOIN t3 + NATURAL INNER JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-489 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + FULL JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-490 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 17 37 - 37 - 37 + 18 - 38 38 - 38 + 19 - - 39 39 39 +} +do_execsql_test joinB-491 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + FULL JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-492 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN (t2 FULL JOIN t3 USING(a)) USING(a) + LEFT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 12 32 32 32 - - + 13 - 33 33 33 - + 15 35 35 35 35 35 + 17 37 - 37 - - + 18 - 38 38 - - +} +do_execsql_test joinB-493 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + FULL JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-494 { + SELECT a, b, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + LEFT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 37 - 37 - 37 + 18 28 - 38 38 - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-495 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + FULL JOIN t3 USING(a) + LEFT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-496 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL FULL JOIN t2 + NATURAL FULL JOIN t3 + NATURAL LEFT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-497 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + FULL JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-498 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 19 - - 39 39 39 +} +do_execsql_test joinB-499 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + FULL JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 19 - - 19 19 19 +} +do_execsql_test joinB-500 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN (t2 FULL JOIN t3 USING(a)) USING(a) + RIGHT JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 13 - 33 33 33 - + 15 35 35 35 35 35 +} +do_execsql_test joinB-501 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + FULL JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-502 { + SELECT a, b, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + RIGHT JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 - - - - 37 + 18 28 - - - - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-503 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + FULL JOIN t3 USING(a) + RIGHT JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 - - - - 17 + 18 - - - - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-504 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL FULL JOIN t2 + NATURAL FULL JOIN t3 + NATURAL RIGHT JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +do_execsql_test joinB-505 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + FULL JOIN t3 USING(a) + FULL JOIN t4 USING(a) + INNER JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-506 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + INNER JOIN t5 USING(a,b) + WHERE a<>13 + ORDER BY 1 NULLS FIRST; +} { + 15 35 35 35 35 35 + 17 37 - 37 - 37 + 18 - 38 38 - 38 + 19 - - 39 39 39 +} +do_execsql_test joinB-507 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + FULL JOIN t3 USING(a) + FULL JOIN t4 USING(a) + LEFT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-508 { + SELECT a, c, d, e, f, g + FROM t1 + FULL JOIN (t2 FULL JOIN t3 USING(a)) USING(a) + FULL JOIN (t4 LEFT JOIN t5 USING(a)) USING(a) + WHERE a<=18 + ORDER BY 1 NULLS FIRST; +} { + 11 31 - 31 31 - + 12 32 32 32 - - + 13 - 33 33 33 - + 15 35 35 35 35 35 + 17 37 - 37 - - + 18 - 38 38 - - +} +do_execsql_test joinB-509 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + FULL JOIN t3 USING(a) + FULL JOIN t4 USING(a) + RIGHT JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-510 { + SELECT a, b, c, d, e, f, g + FROM t1 + FULL JOIN t2 USING(a,b) + FULL JOIN t3 USING(a,b) + FULL JOIN t4 USING(a,b) + RIGHT JOIN t5 USING(a,b) + WHERE d<>33 OR d IS NULL + ORDER BY 1 NULLS FIRST; +} { + 15 25 35 35 35 35 35 + 17 27 37 - 37 - 37 + 18 28 - 38 38 - 38 + 19 29 - - 39 39 39 +} +do_execsql_test joinB-511 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 + FULL JOIN t2 USING(a) + FULL JOIN t3 USING(a) + FULL JOIN t4 USING(a) + FULL JOIN t5 USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 +} +do_execsql_test joinB-512 { + SELECT b, c, d, e, f, g + FROM t1 + NATURAL FULL JOIN t2 + NATURAL FULL JOIN t3 + NATURAL FULL JOIN t4 + NATURAL FULL JOIN t5 + WHERE b BETWEEN 12 AND 17 + ORDER BY 1 NULLS FIRST; +} { +} +finish_test + +############################################################################## +# Here is the original TCL script that generated the psql input file: +# +# +# puts " +# \\pset border off +# \\pset tuples_only on +# \\pset null - +# +# DROP TABLE IF EXISTS t1; +# DROP TABLE IF EXISTS t2; +# DROP TABLE IF EXISTS t3; +# DROP TABLE IF EXISTS t4; +# DROP TABLE IF EXISTS t5; +# CREATE TABLE t1(a INT, b INT, c INT); +# CREATE TABLE t2(a INT, b INT, d INT); +# CREATE TABLE t3(a INT, b INT, e INT); +# CREATE TABLE t4(a INT, b INT, f INT); +# CREATE TABLE t5(a INT, b INT, g INT); +# INSERT INTO t1 VALUES(11,21,31),(12,22,32),(15,25,35),(17,27,37); +# INSERT INTO t2 VALUES(12,22,32),(13,23,33),(15,25,35),(18,28,38),(NULL,NULL,36); +# INSERT INTO t4 VALUES(11,21,31),(13,23,33),(15,25,35),(19,29,39); +# INSERT INTO t3 SELECT * FROM t1 UNION SELECT * FROM t2 UNION SELECT * FROM t4; +# INSERT INTO t5 SELECT * FROM t3 WHERE a>=15; +# " +# +# proc echo {prefix txt} { +# regsub -all {\n} $txt \n$prefix txt +# puts "$prefix$txt" +# } +# +# set n 0 +# set k 0 +# foreach j1 {INNER LEFT RIGHT FULL} { +# foreach j2 {INNER LEFT RIGHT FULL} { +# foreach j3 {INNER LEFT RIGHT FULL} { +# foreach j4 {INNER LEFT RIGHT FULL} { +# +# incr n +# incr k +# set q1 "" +# append q1 "SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a\n" +# append q1 " FROM t1\n" +# append q1 " $j1 JOIN t2 USING(a)\n" +# append q1 " $j2 JOIN t3 USING(a)\n" +# append q1 " $j3 JOIN t4 USING(a)\n" +# append q1 " $j4 JOIN t5 USING(a)\n" +# append q1 " ORDER BY 1 NULLS FIRST;" +# +# echo "\\qecho " "do_execsql_test joinB-$n \{" +# echo "\\qecho X " $q1 +# echo "\\qecho " "\} \{" +# puts $q1 +# echo "\\qecho " "\}" +# +# switch [expr {$k%4}] { +# 0 { +# set q2 "" +# append q2 "SELECT b, c, d, e, f, g\n" +# append q2 " FROM t1\n" +# append q2 " NATURAL $j1 JOIN t2\n" +# append q2 " NATURAL $j2 JOIN t3\n" +# append q2 " NATURAL $j3 JOIN t4\n" +# append q2 " NATURAL $j4 JOIN t5\n" +# append q2 " WHERE b BETWEEN 12 AND 17\n" +# append q2 " ORDER BY 1 NULLS FIRST;" +# incr n +# echo "\\qecho " "do_execsql_test joinB-$n \{" +# echo "\\qecho X " $q2 +# echo "\\qecho " "\} \{" +# puts $q2 +# echo "\\qecho " "\}" +# } +# 1 { +# set q2 "" +# append q2 "SELECT a, c, d, e, f, g\n" +# append q2 " FROM t1\n" +# append q2 " $j1 JOIN t2 USING(a,b)\n" +# append q2 " $j2 JOIN t3 USING(a,b)\n" +# append q2 " $j3 JOIN t4 USING(a,b)\n" +# append q2 " $j4 JOIN t5 USING(a,b)\n" +# append q2 " WHERE a<>13\n" +# append q2 " ORDER BY 1 NULLS FIRST;" +# incr n +# echo "\\qecho " "do_execsql_test joinB-$n \{" +# echo "\\qecho X " $q2 +# echo "\\qecho " "\} \{" +# puts $q2 +# echo "\\qecho " "\}" +# } +# 2 { +# set q2 "" +# append q2 "SELECT a, c, d, e, f, g\n" +# append q2 " FROM t1\n" +# append q2 " $j1 JOIN (t2 $j2 JOIN t3 USING(a)) USING(a)\n" +# append q2 " $j3 JOIN (t4 $j4 JOIN t5 USING(a)) USING(a)\n" +# append q2 " WHERE a<=18\n" +# append q2 " ORDER BY 1 NULLS FIRST;" +# incr n +# echo "\\qecho " "do_execsql_test joinB-$n \{" +# echo "\\qecho X " $q2 +# echo "\\qecho " "\} \{" +# puts $q2 +# echo "\\qecho " "\}" +# } +# 3 { +# set q2 "" +# append q2 "SELECT a, b, c, d, e, f, g\n" +# append q2 " FROM t1\n" +# append q2 " $j1 JOIN t2 USING(a,b)\n" +# append q2 " $j2 JOIN t3 USING(a,b)\n" +# append q2 " $j3 JOIN t4 USING(a,b)\n" +# append q2 " $j4 JOIN t5 USING(a,b)\n" +# append q2 " WHERE d<>33 OR d IS NULL\n" +# append q2 " ORDER BY 1 NULLS FIRST;" +# incr n +# echo "\\qecho " "do_execsql_test joinB-$n \{" +# echo "\\qecho X " $q2 +# echo "\\qecho " "\} \{" +# puts $q2 +# echo "\\qecho " "\}" +# } +# } +# +# } +# } +# } +# } +############################################################################## From e32d6a0bbf002423c819ef56de85b0130b3861b5 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 19 Apr 2022 15:56:03 +0000 Subject: [PATCH 181/259] Mark an unreachable "just-in-case" branch as unreachable. FossilOrigin-Name: b966d52437f08a6759a83a45cafb0d706a8933a8e55dee38ae78166d1a5b3ba4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index e22d300275..0ed381f292 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\s512\snew\sjoin\stest\scases\sderived\sfrom\sPostgreSQL\soutput. -D 2022-04-19T15:01:57.355 +C Mark\san\sunreachable\s"just-in-case"\sbranch\sas\sunreachable. +D 2022-04-19T15:56:03.282 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -552,7 +552,7 @@ F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c a3d58967025858f0f61b7b5d6c45914650acce05c33e4379a43ca4d042a68573 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 459cea7ae6e6ff517b04ad3ec7ed6479b666096a85fcec5b4edec2d5cacca2d8 +F src/select.c 50051eee5a598bd4ec5e47daeb3e20294bb98002d3a8bd8adbb1fef2b47cd980 F src/shell.c.in ecff6f4ab0e8e25acd578b3eb27ac0bad4d48643c160259a277151d6e9d412e1 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1950,8 +1950,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 5bc9aa68e2f938f6a70dd4b08703fe52416d17efe461ec65d37332b57b827fdd -R c6f0e66c49ec69e517ae5327330e468a +P 78d58e461f99366d2749ccd6d02ab4cba0cab20bb80c097e7128da1e50303549 +R 8b7a68ba170d685963d5182430216b5b U drh -Z aaf42e80bfa2ba0860c31afbcd3466d6 +Z abc8af7302efb06e9c77f2c011b16ae4 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a47836b75f..79ca8ed8af 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -78d58e461f99366d2749ccd6d02ab4cba0cab20bb80c097e7128da1e50303549 \ No newline at end of file +b966d52437f08a6759a83a45cafb0d706a8933a8e55dee38ae78166d1a5b3ba4 \ No newline at end of file diff --git a/src/select.c b/src/select.c index d65719e0ab..a59e50674e 100644 --- a/src/select.c +++ b/src/select.c @@ -5557,7 +5557,7 @@ static int inAnyUsingClause( N--; pBase++; if( pBase->fg.isUsing==0 ) continue; - if( pBase->u3.pUsing==0 ) continue; + if( NEVER(pBase->u3.pUsing==0) ) continue; if( sqlite3IdListIndex(pBase->u3.pUsing, zName)>=0 ) return 1; } return 0; From 3117b7b081d782c5da91da94a03cf135ed05533d Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 19 Apr 2022 18:23:01 +0000 Subject: [PATCH 182/259] Fix a NULL-pointer dereference that can occur on an aggregate query that uses FULL JOIN. dbsqlfuzz 496a35dd4eefcd7935aaaeb0c69056bf49785d28. FossilOrigin-Name: 63b8f8aec2a9ac3fbbd02715aa308eaf43c9ffde9d7c6db026d46edc575e7bdd --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 4 +++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 0ed381f292..2052de4c10 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Mark\san\sunreachable\s"just-in-case"\sbranch\sas\sunreachable. -D 2022-04-19T15:56:03.282 +C Fix\sa\sNULL-pointer\sdereference\sthat\scan\soccur\son\san\saggregate\squery\sthat\nuses\sFULL\sJOIN.\s\sdbsqlfuzz\s496a35dd4eefcd7935aaaeb0c69056bf49785d28. +D 2022-04-19T18:23:01.497 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -552,7 +552,7 @@ F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c a3d58967025858f0f61b7b5d6c45914650acce05c33e4379a43ca4d042a68573 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 50051eee5a598bd4ec5e47daeb3e20294bb98002d3a8bd8adbb1fef2b47cd980 +F src/select.c 6fa15ee07a8da8198e74f0092f681dd5f572e9e14b756dd140e0bba18a53bed7 F src/shell.c.in ecff6f4ab0e8e25acd578b3eb27ac0bad4d48643c160259a277151d6e9d412e1 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1950,8 +1950,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 78d58e461f99366d2749ccd6d02ab4cba0cab20bb80c097e7128da1e50303549 -R 8b7a68ba170d685963d5182430216b5b +P b966d52437f08a6759a83a45cafb0d706a8933a8e55dee38ae78166d1a5b3ba4 +R 700d351d60353bc6a3752c8bca1af8cc U drh -Z abc8af7302efb06e9c77f2c011b16ae4 +Z 79f7f3b783582a1aa6157ba5326441d3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 79ca8ed8af..65ce384d8b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b966d52437f08a6759a83a45cafb0d706a8933a8e55dee38ae78166d1a5b3ba4 \ No newline at end of file +63b8f8aec2a9ac3fbbd02715aa308eaf43c9ffde9d7c6db026d46edc575e7bdd \ No newline at end of file diff --git a/src/select.c b/src/select.c index a59e50674e..6ebc1dc3cb 100644 --- a/src/select.c +++ b/src/select.c @@ -7606,7 +7606,9 @@ int sqlite3Select( updateAccumulator(pParse, regAcc, pAggInfo, eDist); if( eDist!=WHERE_DISTINCT_NOOP ){ struct AggInfo_func *pF = &pAggInfo->aFunc[0]; - fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr); + if( pF ){ + fixDistinctOpenEph(pParse, eDist, pF->iDistinct, pF->iDistAddr); + } } if( regAcc ) sqlite3VdbeAddOp2(v, OP_Integer, 1, regAcc); From 4d0d071a53d02015f7411ba8832f191b2e91b71a Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 19 Apr 2022 19:51:51 +0000 Subject: [PATCH 183/259] Improved comment on the JF_LTORJ constant definition. FossilOrigin-Name: e0744da95fc010dc3a2e030ff491bcfa08a18691ee6ebc7d4e8aab3850f56eec --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqliteInt.h | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 2052de4c10..89f11648b0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sNULL-pointer\sdereference\sthat\scan\soccur\son\san\saggregate\squery\sthat\nuses\sFULL\sJOIN.\s\sdbsqlfuzz\s496a35dd4eefcd7935aaaeb0c69056bf49785d28. -D 2022-04-19T18:23:01.497 +C Improved\scomment\son\sthe\sJF_LTORJ\sconstant\sdefinition. +D 2022-04-19T19:51:51.383 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -557,7 +557,7 @@ F src/shell.c.in ecff6f4ab0e8e25acd578b3eb27ac0bad4d48643c160259a277151d6e9d412e F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h e748c9855541432874b37dbf11550d46ea66cac3958857dad4643fc48308d398 +F src/sqliteInt.h f1c2ad8969396460805c3334f55d623123f2ad2c79d468242b2332e9584453f3 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -1950,8 +1950,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 b966d52437f08a6759a83a45cafb0d706a8933a8e55dee38ae78166d1a5b3ba4 -R 700d351d60353bc6a3752c8bca1af8cc +P 63b8f8aec2a9ac3fbbd02715aa308eaf43c9ffde9d7c6db026d46edc575e7bdd +R 0e43081825ba2ac344b2260d536ab5ce U drh -Z 79f7f3b783582a1aa6157ba5326441d3 +Z 728f00126338b98c12a3542524a6b6aa # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 65ce384d8b..d89f6ecb3a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -63b8f8aec2a9ac3fbbd02715aa308eaf43c9ffde9d7c6db026d46edc575e7bdd \ No newline at end of file +e0744da95fc010dc3a2e030ff491bcfa08a18691ee6ebc7d4e8aab3850f56eec \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 9363adbb9f..56b885906e 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3151,10 +3151,10 @@ struct SrcList { #define JT_LEFT 0x08 /* Left outer join */ #define JT_RIGHT 0x10 /* Right outer join */ #define JT_OUTER 0x20 /* The "OUTER" keyword is present */ -#define JT_LTORJ 0x40 /* One of the LEFT operands of a RIGHT JOIN */ +#define JT_LTORJ 0x40 /* One of the LEFT operands of a RIGHT JOIN + ** Mnemonic: Left Table Of Right Join */ #define JT_ERROR 0x80 /* unknown or unsupported join type */ - /* ** Flags appropriate for the wctrlFlags parameter of sqlite3WhereBegin() ** and the WhereInfo.wctrlFlags member. From cbde37d8e447ce4094eca5bc40847651d74e38a9 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 19 Apr 2022 20:47:18 +0000 Subject: [PATCH 184/259] Fix a problem in ALTER TABLE with handling "table.*" expressions within SELECT statements in triggers. FossilOrigin-Name: 24755fd0657252e49793bb1fe906973a2dd84a1bde03bea9a762de36cc96c2d2 --- manifest | 14 ++++++------- manifest.uuid | 2 +- src/select.c | 6 +++++- test/altertab3.test | 50 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 141bae7e73..af7df567ef 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\san\sassert()\sfailure\sin\sallocateSpace()\striggered\sby\sa\scorrupt\sdatabase.\sdbsqlfuzz\sf022eb0ce64d27808574d1dcde5cf7d002dabde8. -D 2022-04-18T15:56:58.902 +C Fix\sa\sproblem\sin\sALTER\sTABLE\swith\shandling\s"table.*"\sexpressions\swithin\sSELECT\sstatements\sin\striggers. +D 2022-04-19T20:47:18.245 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -552,7 +552,7 @@ F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c 18d99e7146852d6064559561769fcca0743eb32b14a97da6dbed373a30ee0e76 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 5ac7c08646ac5a03634da8a954645bdaa13d9bf692fb6b0b5fb3b55b19ab884e +F src/select.c 2df3b525acb48c4e005556771164cefca301e32aad14ffc51f5c9480ea04ff38 F src/shell.c.in ecff6f4ab0e8e25acd578b3eb27ac0bad4d48643c160259a277151d6e9d412e1 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -669,7 +669,7 @@ F test/altermalloc3.test 55e606edf4b0acfbbd851ddfe93cfdddfae43d103644dcfd6008ae4 F test/alterqf.test ff6c6f881485c29ed699b8ef4774864ca1b0c01a6c08f5cdd624a008e4b40fca F test/altertab.test 7273b8506eab46342be016af78028df49f3bd99037412f997a8f1011b37a6912 F test/altertab2.test 62597b6fd08feaba1b6bfe7d31dac6117c67e06dc9ce9c478a3abe75b5926de0 -F test/altertab3.test 5929f522fd6fd708396ad9f317d4af9ff1a93e460df85bb1d54d4499eeb94960 +F test/altertab3.test 8af5c6eb4a7dd2fc73235b865b53561bf07428d1d6a9cd59a067abf51141891e F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f F test/analyze.test 547bb700f903107b38611b014ca645d6b5bb819f5210d7bf39c40802aafeb7d7 F test/analyze3.test 4440c4932247adb2b4e0c838f657c19dc7af4f56859255436dc4e855f39b9324 @@ -1945,8 +1945,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 1b2c5cef9560123344db391cd065090d1914724715ec6643d2d9b5fac2051a21 -R e0f5c0c7d688fc682a2227f01f890489 +P 2de7f8cc7fe18f0828bb53f1fd11f5eb828faf4d6dfaf39693dff4f8926c1c7a +R 318ac48bd1e34a4b6fd3ff5eb21b8cab U dan -Z ae7698eacadb5d5e1bd63dbe1476a21d +Z f1a4a18eaaf67a9686b3da1f44ac683c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index f29a4816df..e6f39a5899 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2de7f8cc7fe18f0828bb53f1fd11f5eb828faf4d6dfaf39693dff4f8926c1c7a \ No newline at end of file +24755fd0657252e49793bb1fe906973a2dd84a1bde03bea9a762de36cc96c2d2 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 28934ffd94..bc6a0b1d1d 100644 --- a/src/select.c +++ b/src/select.c @@ -5755,10 +5755,13 @@ static int selectExpander(Walker *pWalker, Select *p){ pRight = sqlite3Expr(db, TK_ID, zName); zColname = zName; zToFree = 0; - if( longNames || pTabList->nSrc>1 ){ + if( longNames || pTabList->nSrc>1 || IN_RENAME_OBJECT ){ Expr *pLeft; pLeft = sqlite3Expr(db, TK_ID, zTabName); pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); + if( IN_RENAME_OBJECT && pE->pLeft ){ + sqlite3RenameTokenRemap(pParse, pLeft, pE->pLeft); + } if( zSchemaName ){ pLeft = sqlite3Expr(db, TK_ID, zSchemaName); pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pExpr); @@ -5771,6 +5774,7 @@ static int selectExpander(Walker *pWalker, Select *p){ pExpr = pRight; } pNew = sqlite3ExprListAppend(pParse, pNew, pExpr); + sqlite3TokenInit(&sColname, zColname); sqlite3ExprListSetName(pParse, pNew, &sColname, 0); if( pNew && (p->selFlags & SF_NestedFrom)!=0 && !IN_RENAME_OBJECT ){ diff --git a/test/altertab3.test b/test/altertab3.test index 2b9aac3ef8..c786570451 100644 --- a/test/altertab3.test +++ b/test/altertab3.test @@ -686,4 +686,54 @@ do_execsql_test 28.2 { UPDATE "t2" SET (c,d)=(a,b); END}} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 29.1 { + CREATE TABLE t1(x, y); + CREATE TRIGGER Trigger1 DELETE ON t1 + BEGIN + SELECT t1.*, t1.x FROM t1 ORDER BY t1.x; + END; +} + + +do_execsql_test 29.2 { + ALTER TABLE t1 RENAME x TO z; +} + +do_execsql_test 29.3 { + ALTER TABLE t1 RENAME TO t2; +} + +do_execsql_test 29.4 { + CREATE TRIGGER tr2 AFTER DELETE ON t2 BEGIN + SELECT z, y FROM ( + SELECT t2.* FROM t2 + ); + END; +} + +do_execsql_test 29.5 { + DELETE FROM t2 +} + +do_execsql_test 29.6 { + ALTER TABLE t2 RENAME TO t3; +} + +do_execsql_test 29.7 { + SELECT sql FROM sqlite_schema WHERE type='trigger' +} { + {CREATE TRIGGER Trigger1 DELETE ON "t3" + BEGIN + SELECT "t3".*, "t3".z FROM "t3" ORDER BY "t3".z; + END} + {CREATE TRIGGER tr2 AFTER DELETE ON "t3" BEGIN + SELECT z, y FROM ( + SELECT "t3".* FROM "t3" + ); + END} +} + finish_test From 2627cbd4b505282ce6e8e8dc6082468cc181c992 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 20 Apr 2022 12:02:52 +0000 Subject: [PATCH 185/259] Add a new comment to the body of lookupName(). No code changes. FossilOrigin-Name: 22fa9b9b450fbbf7578597714eb1094f7d7433ac13497dc7d4a9affc4a2652ad --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/resolve.c | 6 ++++++ 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 53dbf9966a..abf140fb45 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\sALTER\sTABLE\sfix\sfrom\strunk. -D 2022-04-19T23:00:32.393 +C Add\sa\snew\scomment\sto\sthe\sbody\sof\slookupName().\s\sNo\scode\schanges. +D 2022-04-20T12:02:52.532 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -550,7 +550,7 @@ F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c fd940149c691684e7c1073c3787a7170e44852b02d1275d2e30a5b58e89cfcaf F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c -F src/resolve.c a3d58967025858f0f61b7b5d6c45914650acce05c33e4379a43ca4d042a68573 +F src/resolve.c a5ded9df5914fb1ff71e69e8d0c4aebfa04ad145e9ea8d9fbf185e409047e354 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 708edcf15749d1a91b8bc820f546772409b3a1a33d18ca70ff90f7253c470f5a F src/shell.c.in ecff6f4ab0e8e25acd578b3eb27ac0bad4d48643c160259a277151d6e9d412e1 @@ -1950,8 +1950,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 e0744da95fc010dc3a2e030ff491bcfa08a18691ee6ebc7d4e8aab3850f56eec 24755fd0657252e49793bb1fe906973a2dd84a1bde03bea9a762de36cc96c2d2 -R 87c5522f1cf8919e21182be37373bb83 +P d5ceaef3fca8cb4791ead9cbfe00d0eafa1bdc2b0522c3599c68b40fe6a7efe2 +R 739e562be9542d144d481afc7ff917e9 U drh -Z c5b965cb083a0fb5798e9eb24bfa9f0b +Z 237984b1f871665535324c226d9e5df6 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 506b7930c5..25e395773b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d5ceaef3fca8cb4791ead9cbfe00d0eafa1bdc2b0522c3599c68b40fe6a7efe2 \ No newline at end of file +22fa9b9b450fbbf7578597714eb1094f7d7433ac13497dc7d4a9affc4a2652ad \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index 4d5e23dff4..c1a2a790ca 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -314,6 +314,12 @@ static int lookupName( assert( pTab!=0 && pTab->zName!=0 ); assert( pTab->nCol>0 || pParse->nErr ); if( pItem->pSelect && (pItem->pSelect->selFlags & SF_NestedFrom)!=0 ){ + /* In this case, pItem is a subquery that has been formed from a + ** parenthesized subset of the FROM clause terms. Example: + ** .... FROM t1 LEFT JOIN (t2 RIGHT JOIN t3 USING(x)) USING(y) ... + ** \_________________________/ + ** This pItem -------------^ + */ int hit = 0; pEList = pItem->pSelect->pEList; for(j=0; jnExpr; j++){ From d4e9caf987267011760a0040b5c95c3611533b0f Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 20 Apr 2022 12:14:20 +0000 Subject: [PATCH 186/259] Improved TreeView output for ExprList: Show the ENAME_TAB value, if there is one. FossilOrigin-Name: eb3f883b45f1bf3f388823360f4aec2d4b8776bfd96185b4fb44b7bc95c62318 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/treeview.c | 14 ++++++++++++-- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index abf140fb45..9753cf95ad 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\snew\scomment\sto\sthe\sbody\sof\slookupName().\s\sNo\scode\schanges. -D 2022-04-20T12:02:52.532 +C Improved\sTreeView\soutput\sfor\sExprList:\s\s\sShow\sthe\sENAME_TAB\svalue,\sif\sthere\nis\sone. +D 2022-04-20T12:14:20.002 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -617,7 +617,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98 -F src/treeview.c d5fae332a51d0e15a32281d3f215c6c2aa79dfed2b168f1ce70155a8a5f194df +F src/treeview.c 5271fe3267ab592adf36893c0484491faafba184c22813acead5b7123f09fd71 F src/trigger.c 372ada38f667c6823a3db15749eb668338e65c793394e55a37e56a489f2d1b55 F src/update.c 2cfaded82ca80ff56afb8c3ae5e88284e0824bfd86119827cc22481959f96f92 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 @@ -1950,8 +1950,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 d5ceaef3fca8cb4791ead9cbfe00d0eafa1bdc2b0522c3599c68b40fe6a7efe2 -R 739e562be9542d144d481afc7ff917e9 +P 22fa9b9b450fbbf7578597714eb1094f7d7433ac13497dc7d4a9affc4a2652ad +R 8444cde187eaff36f6e6263467c0a8ab U drh -Z 237984b1f871665535324c226d9e5df6 +Z bb9f9b5433b5e512da686be16375854b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 25e395773b..a6ad236c3f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -22fa9b9b450fbbf7578597714eb1094f7d7433ac13497dc7d4a9affc4a2652ad \ No newline at end of file +eb3f883b45f1bf3f388823360f4aec2d4b8776bfd96185b4fb44b7bc95c62318 \ No newline at end of file diff --git a/src/treeview.c b/src/treeview.c index ff5558acab..68b95c4453 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -794,13 +794,23 @@ void sqlite3TreeViewBareExprList( int j = pList->a[i].u.x.iOrderByCol; char *zName = pList->a[i].zEName; int moreToFollow = inExpr - 1; - if( pList->a[i].eEName!=ENAME_NAME ) zName = 0; + if( pList->a[i].eEName==ENAME_SPAN ) zName = 0; if( j || zName ){ sqlite3TreeViewPush(&pView, moreToFollow); moreToFollow = 0; sqlite3TreeViewLine(pView, 0); if( zName ){ - fprintf(stdout, "AS %s ", zName); + switch( pList->a[i].eEName ){ + default: + fprintf(stdout, "AS %s ", zName); + break; + case ENAME_TAB: + fprintf(stdout, "TABLE-ALIAS-NAME(\"%s\") ", zName); + break; + case ENAME_SPAN: + fprintf(stdout, "SPAN(\"%s\") ", zName); + break; + } } if( j ){ fprintf(stdout, "iOrderByCol=%d", j); From b465a83353cdc4a89375b272064b2b952508a62d Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 20 Apr 2022 12:15:51 +0000 Subject: [PATCH 187/259] Also show the ENAME_SPAN value in sqlite3TreeViewExprList(), if there is one. FossilOrigin-Name: c1d42861778d65f7014c43fbaf09972a69ff0d81bfc2f4720160a989489cf2c8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/treeview.c | 1 - 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 9753cf95ad..a19f3d315d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\sTreeView\soutput\sfor\sExprList:\s\s\sShow\sthe\sENAME_TAB\svalue,\sif\sthere\nis\sone. -D 2022-04-20T12:14:20.002 +C Also\sshow\sthe\sENAME_SPAN\svalue\sin\ssqlite3TreeViewExprList(),\sif\sthere\sis\sone. +D 2022-04-20T12:15:51.225 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -617,7 +617,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98 -F src/treeview.c 5271fe3267ab592adf36893c0484491faafba184c22813acead5b7123f09fd71 +F src/treeview.c 26c904f27ac8b02ce3e2cd12caf451d48cdce2e0af89021629fb27800351e799 F src/trigger.c 372ada38f667c6823a3db15749eb668338e65c793394e55a37e56a489f2d1b55 F src/update.c 2cfaded82ca80ff56afb8c3ae5e88284e0824bfd86119827cc22481959f96f92 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 @@ -1950,8 +1950,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 22fa9b9b450fbbf7578597714eb1094f7d7433ac13497dc7d4a9affc4a2652ad -R 8444cde187eaff36f6e6263467c0a8ab +P eb3f883b45f1bf3f388823360f4aec2d4b8776bfd96185b4fb44b7bc95c62318 +R e8d9048ff74b7a71cf59494018285469 U drh -Z bb9f9b5433b5e512da686be16375854b +Z 087ab6d881fce9542bec295d73873a1e # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a6ad236c3f..c6a7b1c525 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -eb3f883b45f1bf3f388823360f4aec2d4b8776bfd96185b4fb44b7bc95c62318 \ No newline at end of file +c1d42861778d65f7014c43fbaf09972a69ff0d81bfc2f4720160a989489cf2c8 \ No newline at end of file diff --git a/src/treeview.c b/src/treeview.c index 68b95c4453..6b77d41338 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -794,7 +794,6 @@ void sqlite3TreeViewBareExprList( int j = pList->a[i].u.x.iOrderByCol; char *zName = pList->a[i].zEName; int moreToFollow = inExpr - 1; - if( pList->a[i].eEName==ENAME_SPAN ) zName = 0; if( j || zName ){ sqlite3TreeViewPush(&pView, moreToFollow); moreToFollow = 0; From 815b782e997307921640c419e4b567f216afaf94 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 20 Apr 2022 15:07:39 +0000 Subject: [PATCH 188/259] Improved tracking of nested SELECT objects used to implement parenthensized FROM terms. FossilOrigin-Name: 0da2232624571f4020c05d775ea518514d748fba8dacd4caba2e2e6ed1ae399f --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/build.c | 7 ++++++- src/resolve.c | 8 +++++++- src/select.c | 29 +++++++++++++++++++++++++++-- src/sqliteInt.h | 6 ++++++ src/treeview.c | 1 + 7 files changed, 58 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index a19f3d315d..432ff35dcf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Also\sshow\sthe\sENAME_SPAN\svalue\sin\ssqlite3TreeViewExprList(),\sif\sthere\sis\sone. -D 2022-04-20T12:15:51.225 +C Improved\stracking\sof\snested\sSELECT\sobjects\sused\sto\simplement\nparenthensized\sFROM\sterms. +D 2022-04-20T15:07:39.807 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -495,7 +495,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c df695e953c2ce78ce4878ee5016751df9bc9a921dc0500a0f53ab3bb3196e505 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482e -F src/build.c 7f4286d2b4c4ed013e8e064f958f10c277126085f7918c306e9f54c238b36393 +F src/build.c e1ecd83b3f9ff5079e63e5223ae02bbbd50335dbcf65b54405545de8988e6fae F src/callback.c 4c19af69835787bfe790ac560f3071a824eb629f34e41f97b52ce5235c77de1c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 026dbdcdbd8c3cde98a88483ee88310ff43150ab164ad768f12cc700a11495ad @@ -550,14 +550,14 @@ F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c fd940149c691684e7c1073c3787a7170e44852b02d1275d2e30a5b58e89cfcaf F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c -F src/resolve.c a5ded9df5914fb1ff71e69e8d0c4aebfa04ad145e9ea8d9fbf185e409047e354 +F src/resolve.c 0d0bfa186b020909a26e776f34af1ddb060c653d99c0e80ec3de79efeada1093 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 708edcf15749d1a91b8bc820f546772409b3a1a33d18ca70ff90f7253c470f5a +F src/select.c df2bea1b4c6a5456f0f9892a633d59c2e2a3be0179ecd0c803bca75ddc1fd28d F src/shell.c.in ecff6f4ab0e8e25acd578b3eb27ac0bad4d48643c160259a277151d6e9d412e1 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h f1c2ad8969396460805c3334f55d623123f2ad2c79d468242b2332e9584453f3 +F src/sqliteInt.h 36b5d1cce15971fa71b53a950de3158197d85dbaf9b8b2f0bc6279347b09606a F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -617,7 +617,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98 -F src/treeview.c 26c904f27ac8b02ce3e2cd12caf451d48cdce2e0af89021629fb27800351e799 +F src/treeview.c f304faa8b595121da33f78f1f898af48a4db0caa7e310431aa27039ea5dbab36 F src/trigger.c 372ada38f667c6823a3db15749eb668338e65c793394e55a37e56a489f2d1b55 F src/update.c 2cfaded82ca80ff56afb8c3ae5e88284e0824bfd86119827cc22481959f96f92 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 @@ -1950,8 +1950,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 eb3f883b45f1bf3f388823360f4aec2d4b8776bfd96185b4fb44b7bc95c62318 -R e8d9048ff74b7a71cf59494018285469 +P c1d42861778d65f7014c43fbaf09972a69ff0d81bfc2f4720160a989489cf2c8 +R 29bf9f13e64da641ea2eb344ef47fe0b U drh -Z 087ab6d881fce9542bec295d73873a1e +Z 1cabab88f048c2ecc5e840f82512e328 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c6a7b1c525..76b90cdf5f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c1d42861778d65f7014c43fbaf09972a69ff0d81bfc2f4720160a989489cf2c8 \ No newline at end of file +0da2232624571f4020c05d775ea518514d748fba8dacd4caba2e2e6ed1ae399f \ No newline at end of file diff --git a/src/build.c b/src/build.c index 1c632c94ed..e1051ab9f3 100644 --- a/src/build.c +++ b/src/build.c @@ -4970,7 +4970,12 @@ SrcList *sqlite3SrcListAppendFromTerm( if( pAlias->n ){ pItem->zAlias = sqlite3NameFromToken(db, pAlias); } - pItem->pSelect = pSubquery; + if( pSubquery ){ + pItem->pSelect = pSubquery; + if( pSubquery->selFlags & SF_NestedFrom ){ + pItem->fg.isNestedFrom = 1; + } + } assert( pOnUsing==0 || pOnUsing->pOn==0 || pOnUsing->pUsing==0 ); assert( pItem->fg.isUsing==0 ); if( pOnUsing==0 ){ diff --git a/src/resolve.c b/src/resolve.c index c1a2a790ca..ed764a5b1f 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -313,7 +313,8 @@ static int lookupName( pTab = pItem->pTab; assert( pTab!=0 && pTab->zName!=0 ); assert( pTab->nCol>0 || pParse->nErr ); - if( pItem->pSelect && (pItem->pSelect->selFlags & SF_NestedFrom)!=0 ){ + assert( pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); + if( pItem->fg.isNestedFrom ){ /* In this case, pItem is a subquery that has been formed from a ** parenthesized subset of the FROM clause terms. Example: ** .... FROM t1 LEFT JOIN (t2 RIGHT JOIN t3 USING(x)) USING(y) ... @@ -321,7 +322,10 @@ static int lookupName( ** This pItem -------------^ */ int hit = 0; + assert( pItem->pSelect!=0 ); pEList = pItem->pSelect->pEList; + assert( pEList!=0 ); + assert( pEList->nExpr==pTab->nCol ); for(j=0; jnExpr; j++){ if( sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb) ){ if( cnt>0 ){ @@ -353,6 +357,8 @@ static int lookupName( pMatch = pItem; pExpr->iColumn = j; hit = 1; + pEList->a[j].bUsed = 1; + pTab->aCol[j].colFlags &= ~COLFLAG_HIDDEN; } } if( hit || zTab==0 ) continue; diff --git a/src/select.c b/src/select.c index 65ca283b3e..3f754915df 100644 --- a/src/select.c +++ b/src/select.c @@ -319,6 +319,22 @@ int sqlite3ColumnIndex(Table *pTab, const char *zCol){ return -1; } +/* +** Mark a subquery result column as having been used. +*/ +void sqlite3SrcItemColumnUsed(SrcItem *pItem, int iCol){ + assert( pItem!=0 ); + assert( pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); + if( pItem->fg.isNestedFrom ){ + ExprList *pResults; + assert( pItem->pSelect!=0 ); + pResults = pItem->pSelect->pEList; + assert( pResults!=0 ); + assert( iCol>=0 && iColnExpr ); + pResults->a[iCol].bUsed = 1; + } +} + /* ** Search the tables iStart..iEnd (inclusive) in pSrc, looking for a ** table that has a column named zCol. The search is left-to-right. @@ -351,6 +367,7 @@ static int tableAndColumnIndex( && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pTab->aCol[iCol])==0) ){ if( piTab ){ + sqlite3SrcItemColumnUsed(&pSrc->a[i], iCol); *piTab = i; *piCol = iCol; } @@ -530,6 +547,7 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ return 1; } pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol); + sqlite3SrcItemColumnUsed(pLeft, iLeftCol); if( (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ /* This branch runs if the query contains one or more RIGHT or FULL ** JOINs. If only a single table on the left side of this join @@ -557,6 +575,7 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ } pFuncArgs = sqlite3ExprListAppend(pParse, pFuncArgs, pE1); pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol); + sqlite3SrcItemColumnUsed(pLeft, iLeftCol); } if( pFuncArgs ){ pFuncArgs = sqlite3ExprListAppend(pParse, pFuncArgs, pE1); @@ -564,6 +583,7 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ } } pE2 = sqlite3CreateColumnExpr(db, pSrc, i+1, iRightCol); + sqlite3SrcItemColumnUsed(pRight, iRightCol); pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2); assert( pE2!=0 || pEq==0 ); if( pEq ){ @@ -5777,7 +5797,7 @@ static int selectExpander(Walker *pWalker, Select *p){ } for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ Table *pTab = pFrom->pTab; - Select *pSub = pFrom->pSelect; + Select *pSub; char *zTabName = pFrom->zAlias; const char *zSchemaName = 0; int iDb; @@ -5785,7 +5805,12 @@ static int selectExpander(Walker *pWalker, Select *p){ zTabName = pTab->zName; } if( db->mallocFailed ) break; - if( pSub==0 || (pSub->selFlags & SF_NestedFrom)==0 ){ + assert( pFrom->fg.isNestedFrom == IsNestedFrom(pFrom->pSelect) ); + if( pFrom->fg.isNestedFrom ){ + pSub = pFrom->pSelect; + assert( pSub->pEList!=0 ); + assert( pSub->pEList->nExpr==pTab->nCol ); + }else{ pSub = 0; if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){ continue; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 56b885906e..ec465cdb33 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3004,6 +3004,7 @@ struct ExprList { unsigned reusable :1; /* Constant expression is reusable */ unsigned bSorterRef :1; /* Defer evaluation until after sorting */ unsigned bNulls: 1; /* True if explicit "NULLS FIRST/LAST" */ + unsigned bUsed: 1; /* This column used in a SF_NestedFrom subquery */ union { struct { /* Used by any ExprList other than Parse.pConsExpr */ u16 iOrderByCol; /* For ORDER BY, column number in result set */ @@ -3091,6 +3092,7 @@ struct SrcItem { unsigned notCte :1; /* This item may not match a CTE */ unsigned isUsing :1; /* u3.pUsing is valid */ unsigned isSynthUsing :1; /* u3.pUsing is synthensized from NATURAL */ + unsigned isNestedFrom :1; /* pSelect is a SF_NestedFrom subquery */ } fg; int iCursor; /* The VDBE cursor number used to access this table */ union { @@ -3372,6 +3374,9 @@ struct Select { #define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */ #define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */ +/* True if S exists and has SF_NestedFrom */ +#define IsNestedFrom(S) ((S)!=0 && ((S)->selFlags&SF_NestedFrom)!=0) + /* ** The results of a SELECT can be distributed in several ways, as defined ** by one of the following macros. The "SRT" prefix means "SELECT Result @@ -4843,6 +4848,7 @@ void sqlite3MaterializeView(Parse*, Table*, Expr*, ExprList*,Expr*,int); int sqlite3JoinType(Parse*, Token*, Token*, Token*); int sqlite3ColumnIndex(Table *pTab, const char *zCol); +void sqlite3SrcItemColumnUsed(SrcItem*,int); void sqlite3SetJoinExpr(Expr*,int,u32); void sqlite3CreateForeignKey(Parse*, ExprList*, Token*, ExprList*, int); void sqlite3DeferForeignKey(Parse*, int); diff --git a/src/treeview.c b/src/treeview.c index 6b77d41338..95c14448fd 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -805,6 +805,7 @@ void sqlite3TreeViewBareExprList( break; case ENAME_TAB: fprintf(stdout, "TABLE-ALIAS-NAME(\"%s\") ", zName); + if( pList->a[i].bUsed==0 ) fprintf(stdout, "(unused) "); break; case ENAME_SPAN: fprintf(stdout, "SPAN(\"%s\") ", zName); From bc656e220fd36377df63a422ee355d42fd65a053 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 20 Apr 2022 16:26:22 +0000 Subject: [PATCH 189/259] Comment fixes and improvements in sqlite3ProcessJoin(). FossilOrigin-Name: 1118655f4d58da1273e83954c80d8bc17fa3bde7a39e81cb9947d59894d5ab93 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 19 +++++++++++++------ 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 432ff35dcf..505107b986 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\stracking\sof\snested\sSELECT\sobjects\sused\sto\simplement\nparenthensized\sFROM\sterms. -D 2022-04-20T15:07:39.807 +C Comment\sfixes\sand\simprovements\sin\ssqlite3ProcessJoin(). +D 2022-04-20T16:26:22.293 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -552,7 +552,7 @@ F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c 0d0bfa186b020909a26e776f34af1ddb060c653d99c0e80ec3de79efeada1093 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c df2bea1b4c6a5456f0f9892a633d59c2e2a3be0179ecd0c803bca75ddc1fd28d +F src/select.c 88f00d5b9b399f96cabe23a97cfc2be41c34696b057e4563b7e7bdb68c5b2a17 F src/shell.c.in ecff6f4ab0e8e25acd578b3eb27ac0bad4d48643c160259a277151d6e9d412e1 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1950,8 +1950,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 c1d42861778d65f7014c43fbaf09972a69ff0d81bfc2f4720160a989489cf2c8 -R 29bf9f13e64da641ea2eb344ef47fe0b +P 0da2232624571f4020c05d775ea518514d748fba8dacd4caba2e2e6ed1ae399f +R 5a2e4f3e85f13e8d01e09d4b54ea6710 U drh -Z 1cabab88f048c2ecc5e840f82512e328 +Z 8b4e17289b78c9908d49197f73d337c0 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 76b90cdf5f..362eed4630 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0da2232624571f4020c05d775ea518514d748fba8dacd4caba2e2e6ed1ae399f \ No newline at end of file +1118655f4d58da1273e83954c80d8bc17fa3bde7a39e81cb9947d59894d5ab93 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 3f754915df..c86ae1f521 100644 --- a/src/select.c +++ b/src/select.c @@ -456,15 +456,22 @@ static void unsetJoinExpr(Expr *p, int iTable){ /* ** This routine processes the join information for a SELECT statement. -** ON and USING clauses are converted into extra terms of the WHERE clause. -** NATURAL joins also create extra WHERE clause terms. +** +** * A NATURAL join is converted into a USING join. After that, we +** do not need to be concerned with NATURAL joins and we only have +** think about USING joins. +** +** * ON and USING clauses result in extra terms being added to the +** WHERE clause to enforce the specified constraints. The extra +** WHERE clause terms will be tagged with EP_FromJoin or +** EP_InnerJoin so that we know that they originated in ON/USING. ** ** The terms of a FROM clause are contained in the Select.pSrc structure. ** The left most table is the first entry in Select.pSrc. The right-most ** table is the last entry. The join operator is held in the entry to -** the left. Thus entry 0 contains the join operator for the join between +** the right. Thus entry 1 contains the join operator for the join between ** entries 0 and 1. Any ON or USING clauses associated with the join are -** also attached to the left entry. +** also attached to the right entry. ** ** This routine returns the number of errors encountered. */ @@ -551,8 +558,8 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ if( (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ /* This branch runs if the query contains one or more RIGHT or FULL ** JOINs. If only a single table on the left side of this join - ** contains the zName column, then this routine is branch is - ** a no-op. But if there are two or more tables on the left side + ** contains the zName column, then this branch is a no-op. + ** But if there are two or more tables on the left side ** of the join, construct a coalesce() function that gathers all ** such tables. Raise an error if more than one of those references ** to zName is not also within a prior USING clause. From 41150bf35b2dbf42eaf8c2732b59a5b687935e82 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 20 Apr 2022 16:42:57 +0000 Subject: [PATCH 190/259] Fix a problem with using multiple SQLITE_SUBTYPE function as window functions in a single query. FossilOrigin-Name: 9430ead7ba433cbfce99f4f364a0c08499230e3a04f167326b0f131f098ffa09 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/window.c | 2 +- test/windowB.test | 45 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index af7df567ef..661b43a6b2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\sin\sALTER\sTABLE\swith\shandling\s"table.*"\sexpressions\swithin\sSELECT\sstatements\sin\striggers. -D 2022-04-19T20:47:18.245 +C Fix\sa\sproblem\swith\susing\smultiple\sSQLITE_SUBTYPE\sfunction\sas\swindow\sfunctions\sin\sa\ssingle\squery. +D 2022-04-20T16:42:57.645 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -643,7 +643,7 @@ F src/where.c 3b23b363455f1d12cf36c7baa679b16bf1e48cfdd6cf0166bd52202823212f14 F src/whereInt.h 41ce0a8c0368372d8422e420e05a1e037624ce52fae139c3c19538ee491fb4c0 F src/wherecode.c b48476855e4802276e9d9aabb407609059220774b586c8c3a5a61e430aa0eb27 F src/whereexpr.c 346ca19fa89bcb966feb9ae42324fe7636130757f34890aaa6ef922b96be17a5 -F src/window.c 42a71595263dbd8ef8248218e4fc7d4b5ddccece52146ad48e079342d93f6f8f +F src/window.c 924e04fd6e0e113d4dba18b78d43fcb8e42b8ebffc8fc728da52cf3ab014cf3c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 F test/affinity3.test eecb0dabee4b7765a8465439d5e99429279ffba23ca74a7eae270a452799f9e7 @@ -1814,7 +1814,7 @@ F test/window8.tcl 5e02e41d9d9a80f597063aed1a381eb19d1d0ef677a4f0df352c5365cf23f F test/window8.test 4ab16817414af0c904abe2ebdf88eb6c2b00058b84f9748c6174ff11fc45f1ed F test/window9.test 349c71eab4288a1ffc19e2f65872ec2c37e6cf8a1dda2ad300364b7450ae4836 F test/windowA.test 6d63dc1260daa17141a55007600581778523a8b420629f1282d2acfc36af23be -F test/windowB.test b67bda5645f3226790e1a360c4225241840b84adb5aa2e69bfb0b27eef3b84d9 +F test/windowB.test f2fb42b864b0cf431c956407583e9478a74c3642bdf8737fdcb6ff4a40298b07 F test/windowC.test 6fd75f5bb2f1343d34e470e36e68f0ff638d8a42f6aa7d99471261b31a0d42f2 F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0 F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b @@ -1945,8 +1945,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 2de7f8cc7fe18f0828bb53f1fd11f5eb828faf4d6dfaf39693dff4f8926c1c7a -R 318ac48bd1e34a4b6fd3ff5eb21b8cab +P 24755fd0657252e49793bb1fe906973a2dd84a1bde03bea9a762de36cc96c2d2 +R ce489bf3c5c40bd5978c1e86f73a33b2 U dan -Z f1a4a18eaaf67a9686b3da1f44ac683c +Z 359eb52948ae09bab85dc59e491e4aa7 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e6f39a5899..e5bdbcaf67 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -24755fd0657252e49793bb1fe906973a2dd84a1bde03bea9a762de36cc96c2d2 \ No newline at end of file +9430ead7ba433cbfce99f4f364a0c08499230e3a04f167326b0f131f098ffa09 \ No newline at end of file diff --git a/src/window.c b/src/window.c index d0ef81ae59..7db5f6f1c7 100644 --- a/src/window.c +++ b/src/window.c @@ -1729,7 +1729,7 @@ static void windowAggStep( for(iEnd=sqlite3VdbeCurrentAddr(v); iOpopcode==OP_Column && pOp->p1==pWin->iEphCsr ){ + if( pOp->opcode==OP_Column && pOp->p1==pMWin->iEphCsr ){ pOp->p1 = csr; } } diff --git a/test/windowB.test b/test/windowB.test index 52221c445c..0a9aef724f 100644 --- a/test/windowB.test +++ b/test/windowB.test @@ -365,4 +365,49 @@ do_execsql_test 9.0 { FROM seps; } {-22- -22-333- -333-4444- -4444-} +#------------------------------------------------------------------------- +reset_db +do_execsql_test 10.1 { + CREATE TABLE t1(i INTEGER PRIMARY KEY, v); + INSERT INTO t1 VALUES( 1, 'one' ); + INSERT INTO t1 VALUES( 2, 'two' ); +} + +do_execsql_test 10.2 { + SELECT + json_group_array( v ) OVER w, + json_group_array( v ) OVER w + FROM t1 + window w as ( + range between unbounded preceding and unbounded following + ) +} { + {["one","two"]} + {["one","two"]} + {["one","two"]} + {["one","two"]} +} + +do_execsql_test 10.3 { + SELECT + group_concat( v ) OVER w, + json_group_array( v ) OVER w, + json_group_array( v ) OVER w, + group_concat( v ) OVER w + FROM t1 + window w as ( + range between unbounded preceding and unbounded following + ) +} { + one,two + {["one","two"]} + {["one","two"]} + one,two + + one,two + {["one","two"]} + {["one","two"]} + one,two +} + finish_test From 910e57b9df714b03f5481ff23b165d89be1d15a1 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 20 Apr 2022 16:53:23 +0000 Subject: [PATCH 191/259] Remove an unnecessary assignment operation. FossilOrigin-Name: ed46527aca170ccbe9ed9ea4ae065db72c82dec17da7b99c928fae4495f05c2b --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/resolve.c | 1 - 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 505107b986..d47122c5f0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Comment\sfixes\sand\simprovements\sin\ssqlite3ProcessJoin(). -D 2022-04-20T16:26:22.293 +C Remove\san\sunnecessary\sassignment\soperation. +D 2022-04-20T16:53:23.152 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -550,7 +550,7 @@ F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c fd940149c691684e7c1073c3787a7170e44852b02d1275d2e30a5b58e89cfcaf F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c -F src/resolve.c 0d0bfa186b020909a26e776f34af1ddb060c653d99c0e80ec3de79efeada1093 +F src/resolve.c 4039e3d89af416ffa8d665b59aac53ccdb10e088d8017649f2ceabda5e73473b F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 88f00d5b9b399f96cabe23a97cfc2be41c34696b057e4563b7e7bdb68c5b2a17 F src/shell.c.in ecff6f4ab0e8e25acd578b3eb27ac0bad4d48643c160259a277151d6e9d412e1 @@ -1950,8 +1950,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 0da2232624571f4020c05d775ea518514d748fba8dacd4caba2e2e6ed1ae399f -R 5a2e4f3e85f13e8d01e09d4b54ea6710 +P 1118655f4d58da1273e83954c80d8bc17fa3bde7a39e81cb9947d59894d5ab93 +R edf3e42048aadaf122b7620ac21e901b U drh -Z 8b4e17289b78c9908d49197f73d337c0 +Z b461f1dbdf9602f594f3deb9c2289e0f # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 362eed4630..bd1f5c6274 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1118655f4d58da1273e83954c80d8bc17fa3bde7a39e81cb9947d59894d5ab93 \ No newline at end of file +ed46527aca170ccbe9ed9ea4ae065db72c82dec17da7b99c928fae4495f05c2b \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index ed764a5b1f..446004bfe2 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -358,7 +358,6 @@ static int lookupName( pExpr->iColumn = j; hit = 1; pEList->a[j].bUsed = 1; - pTab->aCol[j].colFlags &= ~COLFLAG_HIDDEN; } } if( hit || zTab==0 ) continue; From 22b410d894fa44d7944c4f0ca5448d3937123f64 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 20 Apr 2022 18:12:42 +0000 Subject: [PATCH 192/259] Small correction to the new bUsed logic of sqlite3ProcessJoin(). FossilOrigin-Name: ba04142e09bb1ccc86824760a2e11df47e070285a2d09c2f61b75255886597cd --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index f7b1689508..cc8af505d8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\swindow\sfunction\sfix\sfrom\strunk. -D 2022-04-20T16:54:47.749 +C Small\scorrection\sto\sthe\snew\sbUsed\slogic\sof\ssqlite3ProcessJoin(). +D 2022-04-20T18:12:42.455 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -552,7 +552,7 @@ F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c 4039e3d89af416ffa8d665b59aac53ccdb10e088d8017649f2ceabda5e73473b F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 88f00d5b9b399f96cabe23a97cfc2be41c34696b057e4563b7e7bdb68c5b2a17 +F src/select.c 8978bab868e63781d91d0b689b08f8ed62398cfce7945c465c8998133f8e2c52 F src/shell.c.in ecff6f4ab0e8e25acd578b3eb27ac0bad4d48643c160259a277151d6e9d412e1 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1950,8 +1950,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 ed46527aca170ccbe9ed9ea4ae065db72c82dec17da7b99c928fae4495f05c2b 9430ead7ba433cbfce99f4f364a0c08499230e3a04f167326b0f131f098ffa09 -R 9e45b0e607b815fcf8a23e78f449116c +P b6b9e185f8c44b5f2f51111f7c5e4e2d77c8b853c5be271467ce138e8066340c +R 71f32b965c53fefec5ed2ab5db6eaed7 U drh -Z 15057c54b73b1d1c0f60c76ea8c87053 +Z dfb5b3729b0976a766bdc021ea7b2468 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index aa99d45d34..cc8ec6cc3a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b6b9e185f8c44b5f2f51111f7c5e4e2d77c8b853c5be271467ce138e8066340c \ No newline at end of file +ba04142e09bb1ccc86824760a2e11df47e070285a2d09c2f61b75255886597cd \ No newline at end of file diff --git a/src/select.c b/src/select.c index c86ae1f521..d1605a565c 100644 --- a/src/select.c +++ b/src/select.c @@ -554,7 +554,7 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ return 1; } pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol); - sqlite3SrcItemColumnUsed(pLeft, iLeftCol); + sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol); if( (pSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ /* This branch runs if the query contains one or more RIGHT or FULL ** JOINs. If only a single table on the left side of this join @@ -582,7 +582,7 @@ static int sqlite3ProcessJoin(Parse *pParse, Select *p){ } pFuncArgs = sqlite3ExprListAppend(pParse, pFuncArgs, pE1); pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iLeftCol); - sqlite3SrcItemColumnUsed(pLeft, iLeftCol); + sqlite3SrcItemColumnUsed(&pSrc->a[iLeft], iLeftCol); } if( pFuncArgs ){ pFuncArgs = sqlite3ExprListAppend(pParse, pFuncArgs, pE1); From 6403e77d3b001e8cd5a26d2b0fc6a47a8c8a4d0b Mon Sep 17 00:00:00 2001 From: larrybr Date: Wed, 20 Apr 2022 22:41:10 +0000 Subject: [PATCH 193/259] For CLI, fix how columnar mode fills in empty portions of wrapped row outputs. FossilOrigin-Name: 77aed89192bdbad819ac17bf5d08728278a9b8cbbbef1d805df230caff79b417 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/shell.c.in | 11 +++++++++-- test/shell1.test | 17 +++++++++++++++++ 4 files changed, 35 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 661b43a6b2..3a1dd36072 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\susing\smultiple\sSQLITE_SUBTYPE\sfunction\sas\swindow\sfunctions\sin\sa\ssingle\squery. -D 2022-04-20T16:42:57.645 +C For\sCLI,\sfix\show\scolumnar\smode\sfills\sin\sempty\sportions\sof\swrapped\srow\soutputs. +D 2022-04-20T22:41:10.920 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -553,7 +553,7 @@ F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c 18d99e7146852d6064559561769fcca0743eb32b14a97da6dbed373a30ee0e76 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 2df3b525acb48c4e005556771164cefca301e32aad14ffc51f5c9480ea04ff38 -F src/shell.c.in ecff6f4ab0e8e25acd578b3eb27ac0bad4d48643c160259a277151d6e9d412e1 +F src/shell.c.in b3250485b9b6c926c2576e6e89b23574b6d59fcd04ea9bc63131a13fb4243628 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e @@ -1389,7 +1389,7 @@ F test/sharedA.test 49d87ec54ab640fbbc3786ee3c01de94aaa482a3a9f834ad3fe92770eb69 F test/sharedB.test 16cc7178e20965d75278f410943109b77b2e645e F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test b224e0793c5f48aa3749e65d8c64b93a30731bd206f2e41e6c5f1bee1bdb16c6 +F test/shell1.test f7a2ef8260aa01f20be3185118213b1ae70518fdcd2105f3e25b021b5ca800ac F test/shell2.test 7a3a23a9f57b99453f1679b1fe8072cb30e382a622874c0c4d97695fadb0a787 F test/shell3.test a50628ab1d78d90889d9d3f32fb2c084ee15674771e96afe954aaa0accd1de3c F test/shell4.test 8f6c0fce4abed19a8a7f7262517149812a04caa905d01bdc8f5e92573504b759 @@ -1945,8 +1945,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 24755fd0657252e49793bb1fe906973a2dd84a1bde03bea9a762de36cc96c2d2 -R ce489bf3c5c40bd5978c1e86f73a33b2 -U dan -Z 359eb52948ae09bab85dc59e491e4aa7 +P 9430ead7ba433cbfce99f4f364a0c08499230e3a04f167326b0f131f098ffa09 +R 6ef848a57b0ae2fb87aa59c0dc6c64a7 +U larrybr +Z 0a5dc40772a2c0441c803c4b4812274a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e5bdbcaf67..e8362d9747 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9430ead7ba433cbfce99f4f364a0c08499230e3a04f167326b0f131f098ffa09 \ No newline at end of file +77aed89192bdbad819ac17bf5d08728278a9b8cbbbef1d805df230caff79b417 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 5a2ff6ea26..e6f4a2c95b 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -3350,6 +3350,8 @@ static void exec_prepared_stmt_columnar( int bNextLine = 0; int bMultiLineRowExists = 0; int bw = p->cmOpts.bWordWrap; + const char *zEmpty = ""; + const char *zShowNull = p->nullValue; rc = sqlite3_step(pStmt); if( rc!=SQLITE_ROW ) return; @@ -3411,12 +3413,14 @@ static void exec_prepared_stmt_columnar( if( wx<0 ) wx = -wx; if( useNextLine ){ uz = azNextLine[i]; + if( uz==0 ) uz = (char*)zEmpty; }else if( p->cmOpts.bQuote ){ sqlite3_free(azQuoted[i]); azQuoted[i] = quoted_column(pStmt,i); uz = (const unsigned char*)azQuoted[i]; }else{ uz = (const unsigned char*)sqlite3_column_text(pStmt,i); + if( uz==0 ) uz = (char*)zShowNull; } azData[nRow*nColumn + i] = translateForDisplayAndDup(uz, &azNextLine[i], wx, bw); @@ -3430,7 +3434,7 @@ static void exec_prepared_stmt_columnar( nTotal = nColumn*(nRow+1); for(i=0; inullValue; + if( z==0 ) z = (char*)zEmpty; n = strlenChar(z); j = i%nColumn; if( n>p->actualWidth[j] ) p->actualWidth[j] = n; @@ -3534,7 +3538,10 @@ columnar_end: utf8_printf(p->out, "Interrupt\n"); } nData = (nRow+1)*nColumn; - for(i=0; i Date: Thu, 21 Apr 2022 13:11:26 +0000 Subject: [PATCH 194/259] Avoid materializing columns of SF_NestedFrom subqueries that are never used. Other code improvements manually imported from the right-join-paren branch. FossilOrigin-Name: cd8272fc2a34d1b245fd95208b9b601266ee7d2ff0f5ce52d03752f2c4e852a2 --- manifest | 16 +++++------ manifest.uuid | 2 +- src/expr.c | 1 + src/resolve.c | 79 ++++++++++++++++++++++++++++----------------------- src/select.c | 51 +++++++++++++++++++-------------- 5 files changed, 83 insertions(+), 66 deletions(-) diff --git a/manifest b/manifest index cc8af505d8..e4a592253d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Small\scorrection\sto\sthe\snew\sbUsed\slogic\sof\ssqlite3ProcessJoin(). -D 2022-04-20T18:12:42.455 +C Avoid\smaterializing\scolumns\sof\sSF_NestedFrom\ssubqueries\sthat\sare\snever\sused.\nOther\scode\simprovements\smanually\simported\sfrom\sthe\sright-join-paren\sbranch. +D 2022-04-21T13:11:26.388 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -503,7 +503,7 @@ F src/date.c 15082566229d4b1e5f24fdb490bf9bcc68824b911d70e3573ef075a1b9e2d26f F src/dbpage.c 90661a87e1db8bfbc8d2ebbdcd3749651ddb287c555c07a28fb17c7c591ffb68 F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d F src/delete.c a8e844af211a48b13b5b358be77a12c860c6a557c21990ad51a548e2536500ce -F src/expr.c 0714987d576d13acb64630274677ff0df336013bf83dfc1ff24a339b8ae2ae81 +F src/expr.c 899c77da1cd4d836d93f94cf435fc761695938dda8932becfccfdb2eb7d6a7d9 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c d965ede15d8360c09ed59348940649ee647b192e784466837d7aefa836d1d91e F src/func.c a3407a6fbb0d4088d8d502e46f0ace63e0aeae7467ae23a9ca9815bbf9239761 @@ -550,9 +550,9 @@ F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c fd940149c691684e7c1073c3787a7170e44852b02d1275d2e30a5b58e89cfcaf F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c -F src/resolve.c 4039e3d89af416ffa8d665b59aac53ccdb10e088d8017649f2ceabda5e73473b +F src/resolve.c f72bb13359dd5a74d440df25f320dc2c1baff5cde4fc9f0d1bc3feba90b8932a F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 8978bab868e63781d91d0b689b08f8ed62398cfce7945c465c8998133f8e2c52 +F src/select.c 51e8b778abdd89289e2f2a6733d5e7ac6082f6c56ca717fa15f64f202e66bf42 F src/shell.c.in ecff6f4ab0e8e25acd578b3eb27ac0bad4d48643c160259a277151d6e9d412e1 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1950,8 +1950,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 b6b9e185f8c44b5f2f51111f7c5e4e2d77c8b853c5be271467ce138e8066340c -R 71f32b965c53fefec5ed2ab5db6eaed7 +P ba04142e09bb1ccc86824760a2e11df47e070285a2d09c2f61b75255886597cd +R 10336f90bf1e8bd2097eb8ad35da3707 U drh -Z dfb5b3729b0976a766bdc021ea7b2468 +Z 3ded7fd2b5106a18a37cbebcaf60418c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index cc8ec6cc3a..6ed0124f95 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ba04142e09bb1ccc86824760a2e11df47e070285a2d09c2f61b75255886597cd \ No newline at end of file +cd8272fc2a34d1b245fd95208b9b601266ee7d2ff0f5ce52d03752f2c4e852a2 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index eb3ba35ba1..a300971345 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1631,6 +1631,7 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, const ExprList *p, int flags){ pItem->eEName = pOldItem->eEName; pItem->done = 0; pItem->bNulls = pOldItem->bNulls; + pItem->bUsed = pOldItem->bUsed; pItem->bSorterRef = pOldItem->bSorterRef; pItem->u = pOldItem->u; } diff --git a/src/resolve.c b/src/resolve.c index 446004bfe2..e9cfe9d9f1 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -265,6 +265,7 @@ static int lookupName( assert( pNC ); /* the name context cannot be NULL. */ assert( zCol ); /* The Z in X.Y.Z cannot be NULL */ + assert( zDb==0 || zTab!=0 ); assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); /* Initialize the node to no-match */ @@ -327,47 +328,50 @@ static int lookupName( assert( pEList!=0 ); assert( pEList->nExpr==pTab->nCol ); for(j=0; jnExpr; j++){ - if( sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb) ){ - if( cnt>0 ){ - if( pItem->fg.isUsing==0 - || sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0 - ){ - /* Two or more tables have the same column name which is - ** not joined by USING. This is an error. Signal as much - ** by clearing pFJMatch and letting cnt go above 1. */ - sqlite3ExprListDelete(db, pFJMatch); - pFJMatch = 0; - }else - if( (pItem->fg.jointype & JT_RIGHT)==0 ){ - /* An INNER or LEFT JOIN. Use the left-most table */ - continue; - }else - if( (pItem->fg.jointype & JT_LEFT)==0 ){ - /* A RIGHT JOIN. Use the right-most table */ - cnt = 0; - sqlite3ExprListDelete(db, pFJMatch); - pFJMatch = 0; - }else{ - /* For a FULL JOIN, we must construct a coalesce() func */ - extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn); - } - } - cnt++; - cntTab = 2; - pMatch = pItem; - pExpr->iColumn = j; - hit = 1; - pEList->a[j].bUsed = 1; + if( !sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb) ){ + continue; } + if( cnt>0 ){ + if( pItem->fg.isUsing==0 + || sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0 + ){ + /* Two or more tables have the same column name which is + ** not joined by USING. This is an error. Signal as much + ** by clearing pFJMatch and letting cnt go above 1. */ + sqlite3ExprListDelete(db, pFJMatch); + pFJMatch = 0; + }else + if( (pItem->fg.jointype & JT_RIGHT)==0 ){ + /* An INNER or LEFT JOIN. Use the left-most table */ + continue; + }else + if( (pItem->fg.jointype & JT_LEFT)==0 ){ + /* A RIGHT JOIN. Use the right-most table */ + cnt = 0; + sqlite3ExprListDelete(db, pFJMatch); + pFJMatch = 0; + }else{ + /* For a FULL JOIN, we must construct a coalesce() func */ + extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn); + } + } + cnt++; + cntTab = 2; + pMatch = pItem; + pExpr->iColumn = j; + pEList->a[j].bUsed = 1; + hit = 1; } if( hit || zTab==0 ) continue; } - if( zDb ){ - if( pTab->pSchema!=pSchema ) continue; - if( pSchema==0 && strcmp(zDb,"*")!=0 ) continue; - } + assert( zDb==0 || zTab!=0 ); if( zTab ){ - const char *zTabName = pItem->zAlias ? pItem->zAlias : pTab->zName; + const char *zTabName; + if( zDb ){ + if( pTab->pSchema!=pSchema ) continue; + if( pSchema==0 && strcmp(zDb,"*")!=0 ) continue; + } + zTabName = pItem->zAlias ? pItem->zAlias : pTab->zName; assert( zTabName!=0 ); if( sqlite3StrICmp(zTabName, zTab)!=0 ){ continue; @@ -410,6 +414,9 @@ static int lookupName( pMatch = pItem; /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */ pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j; + if( pItem->fg.isNestedFrom ){ + sqlite3SrcItemColumnUsed(pItem, j); + } break; } } diff --git a/src/select.c b/src/select.c index d1605a565c..f0a3e58775 100644 --- a/src/select.c +++ b/src/select.c @@ -2179,12 +2179,13 @@ int sqlite3ColumnsFromExprList( *paCol = aCol; for(i=0, pCol=aCol; imallocFailed; i++, pCol++){ + struct ExprList_item *pX = &pEList->a[i]; /* Get an appropriate name for the column */ - if( (zName = pEList->a[i].zEName)!=0 && pEList->a[i].eEName==ENAME_NAME ){ + if( (zName = pX->zEName)!=0 && pX->eEName==ENAME_NAME ){ /* If the column contains an "AS " phrase, use as the name */ }else{ - Expr *pColExpr = sqlite3ExprSkipCollateAndLikely(pEList->a[i].pExpr); + Expr *pColExpr = sqlite3ExprSkipCollateAndLikely(pX->pExpr); while( ALWAYS(pColExpr!=0) && pColExpr->op==TK_DOT ){ pColExpr = pColExpr->pRight; assert( pColExpr!=0 ); @@ -2202,7 +2203,7 @@ int sqlite3ColumnsFromExprList( zName = pColExpr->u.zToken; }else{ /* Use the original text of the column expression as its name */ - zName = pEList->a[i].zEName; + assert( zName==pX->zEName ); /* pointer comparison intended */ } } if( zName && !sqlite3IsTrueOrFalse(zName) ){ @@ -5827,9 +5828,7 @@ static int selectExpander(Walker *pWalker, Select *p){ } for(j=0; jnCol; j++){ char *zName = pTab->aCol[j].zCnName; - char *zColname; /* The computed column name */ - char *zToFree; /* Malloced string that needs to be freed */ - Token sColname; /* Computed column name as a token */ + struct ExprList_item *pX; /* Newly added ExprList term */ assert( zName ); if( zTName && pSub @@ -5859,13 +5858,6 @@ static int selectExpander(Walker *pWalker, Select *p){ } } pRight = sqlite3Expr(db, TK_ID, zName); - if( longNames ){ - zColname = sqlite3MPrintf(db, "%s.%s", zTabName, zName); - zToFree = zColname; - }else{ - zColname = zName; - zToFree = 0; - } if( (pTabList->nSrc>1 && ( (pFrom->fg.jointype & JT_LTORJ)==0 || !inAnyUsingClause(zName,pFrom,pTabList->nSrc-i-1) @@ -5887,23 +5879,28 @@ static int selectExpander(Walker *pWalker, Select *p){ pExpr = pRight; } pNew = sqlite3ExprListAppend(pParse, pNew, pExpr); - - sqlite3TokenInit(&sColname, zColname); - sqlite3ExprListSetName(pParse, pNew, &sColname, 0); - if( pNew && (p->selFlags & SF_NestedFrom)!=0 && !IN_RENAME_OBJECT ){ - struct ExprList_item *pX = &pNew->a[pNew->nExpr-1]; - sqlite3DbFree(db, pX->zEName); + if( pNew==0 ){ + break; /* OOM */ + } + pX = &pNew->a[pNew->nExpr-1]; + assert( pX->zEName==0 ); + if( (selFlags & SF_NestedFrom)!=0 && !IN_RENAME_OBJECT ){ if( pSub ){ pX->zEName = sqlite3DbStrDup(db, pSub->pEList->a[j].zEName); testcase( pX->zEName==0 ); }else{ pX->zEName = sqlite3MPrintf(db, "%s.%s.%s", - zSchemaName, zTabName, zColname); + zSchemaName, zTabName, zName); testcase( pX->zEName==0 ); } pX->eEName = ENAME_TAB; + }else if( longNames ){ + pX->zEName = sqlite3MPrintf(db, "%s.%s", zTabName, zName); + pX->eEName = ENAME_NAME; + }else{ + pX->zEName = sqlite3DbStrDup(db, zName); + pX->eEName = ENAME_NAME; } - sqlite3DbFree(db, zToFree); } } if( !tableSeen ){ @@ -7029,6 +7026,18 @@ int sqlite3Select( */ if( pDest->eDest==SRT_EphemTab ){ sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr); + if( p->selFlags & SF_NestedFrom ){ + /* Delete or NULL-out result columns that will never be used */ + int ii; + for(ii=pEList->nExpr-1; ii>0 && pEList->a[ii].bUsed==0; ii--){ + sqlite3ExprDelete(db, pEList->a[ii].pExpr); + sqlite3DbFree(db, pEList->a[ii].zEName); + pEList->nExpr--; + } + for(ii=0; iinExpr; ii++){ + if( pEList->a[ii].bUsed==0 ) pEList->a[ii].pExpr->op = TK_NULL; + } + } } /* Set the limiter. From 825a6bffc406a274b184da61bca398f86a352bdb Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 21 Apr 2022 14:08:29 +0000 Subject: [PATCH 195/259] Ensure correct fg.isNestedFrom values even on crazy parses. FossilOrigin-Name: e611e8e62c948d28cd3f28452d3096bab06998a685ed9434061cc2054f5cac32 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/parse.y | 3 +++ src/treeview.c | 1 + test/join.test | 9 +++++++++ 5 files changed, 22 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index e4a592253d..afac86bafa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\smaterializing\scolumns\sof\sSF_NestedFrom\ssubqueries\sthat\sare\snever\sused.\nOther\scode\simprovements\smanually\simported\sfrom\sthe\sright-join-paren\sbranch. -D 2022-04-21T13:11:26.388 +C Ensure\scorrect\sfg.isNestedFrom\svalues\seven\son\scrazy\sparses. +D 2022-04-21T14:08:29.121 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -541,7 +541,7 @@ F src/os_win.c a8ea80037e81127ca01959daa87387cc135f325c88dc745376c4f760de852a10 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 42120492784fc9bcd9082b5c9b5e329b7318c357f9f3574a1bbfcf7418910356 F src/pager.h f82e9844166e1585f5786837ddc7709966138ced17f568c16af7ccf946c2baa3 -F src/parse.y e221a1159c5e73730b4d3d87fe4b5ad4b10ea2237ff59804e6402495a04a26c7 +F src/parse.y b86d56b446afb9c203d8354dc6c422818a62b4bbab52b76ab3da06d7b1d07e44 F src/pcache.c 084e638432c610f95aea72b8509f0845d2791293f39d1b82f0c0a7e089c3bb6b F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 54881292a9a5db202b2c0ac541c5e3ef9a5e8c4f1c1383adb2601d5499a60e65 @@ -617,7 +617,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98 -F src/treeview.c f304faa8b595121da33f78f1f898af48a4db0caa7e310431aa27039ea5dbab36 +F src/treeview.c c834e0c9030b1f9971152e049f44e2f973625c680f10aed2fbcc956da2301d0b F src/trigger.c 372ada38f667c6823a3db15749eb668338e65c793394e55a37e56a489f2d1b55 F src/update.c 2cfaded82ca80ff56afb8c3ae5e88284e0824bfd86119827cc22481959f96f92 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 @@ -1140,7 +1140,7 @@ F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4 F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b F test/istrue.test e7f285bb70282625c258e866ce6337d4c762922f5a300e1b50f958aef6e7d9c9 -F test/join.test d9c8cb2769b147b223f9dff8f694f56cfd9d0c097f8af9c7c6562b2e4ad256b5 +F test/join.test e5f165dfd84fd46406ddae6614b0122c3bfa23a26ef62966442e1503c40d96aa F test/join2.test 466b07233820f5deee66a6c3bf6e4500c8bbf7b83649e67606f5f649c07928c0 F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 @@ -1950,8 +1950,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 ba04142e09bb1ccc86824760a2e11df47e070285a2d09c2f61b75255886597cd -R 10336f90bf1e8bd2097eb8ad35da3707 +P cd8272fc2a34d1b245fd95208b9b601266ee7d2ff0f5ce52d03752f2c4e852a2 +R 8a87ff03f3b9042d5d80a515b01bbe71 U drh -Z 3ded7fd2b5106a18a37cbebcaf60418c +Z 4f221c243b1c9d53087ee3bfbfa41863 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 6ed0124f95..b5360486b6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cd8272fc2a34d1b245fd95208b9b601266ee7d2ff0f5ce52d03752f2c4e852a2 \ No newline at end of file +e611e8e62c948d28cd3f28452d3096bab06998a685ed9434061cc2054f5cac32 \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index 65977bbbad..37560a2e0b 100644 --- a/src/parse.y +++ b/src/parse.y @@ -721,6 +721,9 @@ seltablist(A) ::= stl_prefix(A) nm(Y) dbnm(D) LP exprlist(E) RP as(Z) on_using(N pNew->zName = pOld->zName; pNew->zDatabase = pOld->zDatabase; pNew->pSelect = pOld->pSelect; + if( pNew->pSelect && (pNew->pSelect->selFlags & SF_NestedFrom)!=0 ){ + pNew->fg.isNestedFrom = 1; + } if( pOld->fg.isTabFunc ){ pNew->u1.pFuncArg = pOld->u1.pFuncArg; pOld->u1.pFuncArg = 0; diff --git a/src/treeview.c b/src/treeview.c index 95c14448fd..3ba8a63cd7 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -166,6 +166,7 @@ void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ sqlite3StrAccumFinish(&x); sqlite3TreeViewItem(pView, zLine, inSrc-1); if( pItem->pSelect ){ + assert( pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); sqlite3TreeViewSelect(pView, pItem->pSelect, 0); } if( pItem->fg.isTabFunc ){ diff --git a/test/join.test b/test/join.test index d6e775436b..38cfb74569 100644 --- a/test/join.test +++ b/test/join.test @@ -1041,5 +1041,14 @@ do_execsql_test join-25.1 { SELECT count(*) FROM v0 LEFT JOIN t0 ON v0.c0; } {1} +# 2022-04-21 Parser issue detected by dbsqlfuzz +# +reset_db +do_catchsql_test join-26.1 { + CREATE TABLE t4(a,b); + CREATE TABLE t5(a,c); + CREATE TABLE t6(a,d); + SELECT * FROM t5 JOIN ((t4 JOIN (t5 JOIN t6)) t7); +} {/1 {.*}/} finish_test From 503ad9c72dd28d4175ce1ad1d400d9b62d885afd Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 21 Apr 2022 14:48:40 +0000 Subject: [PATCH 196/259] Make sure the code generator knows to invoke row-value subroutines which running the right-join post-processing loop. FossilOrigin-Name: fd328e52aee1dace12b1c2f44b6f7e9d15d8f77c8e9d9e3d85840a129a4b1808 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/wherecode.c | 4 ++++ test/join8.test | 10 ++++++++++ 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index afac86bafa..447c65a511 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\scorrect\sfg.isNestedFrom\svalues\seven\son\scrazy\sparses. -D 2022-04-21T14:08:29.121 +C Make\ssure\sthe\scode\sgenerator\sknows\sto\sinvoke\srow-value\ssubroutines\swhich\nrunning\sthe\sright-join\spost-processing\sloop. +D 2022-04-21T14:48:40.635 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -641,7 +641,7 @@ F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b F src/where.c 45102d682f6efd450d89c0c5f09b838be6d69c84c6105336730ee38d3b452fad F src/whereInt.h eecce79edc6f7005f91f35be6b18b7053f794e1b50e95bcd06a2d537fc176734 -F src/wherecode.c dcf622a9650638c80c86699d3fbd39526016ac36488f6db3878fcf530803f30d +F src/wherecode.c 1bff158d8672524d0e9a398b01a8ed2d98fffb9ae38837a8335c7162500a1d8f F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 F src/window.c 924e04fd6e0e113d4dba18b78d43fcb8e42b8ebffc8fc728da52cf3ab014cf3c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1147,7 +1147,7 @@ F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test c4df54e2e204d7f1417bfbdd21ca324b4b07415c647595cc47798eacfddc96d3 F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c F test/join7.test 8e72de4b45e5e930d18c305c7efe86015fb2552731e4e03ea226353036b0dab0 -F test/join8.test 6ed7eed8993e060e5e9d07f6bcadf1bb634742a03b9824afbcfa193adf7f9965 +F test/join8.test f9b4e3be35d8546e934ea9e18244d3a26d6e22c51dadef9d721db7cd25c606b5 F test/join9.test 9056ddd3b0c0f4f9d658f4521038d9a37dc23ead8ca9a505d0b0db2b6a471e05 F test/joinA.test 7eab225dc1c1ab258a5e62513a4ed7cabbd3db971d59d5d92f4fb6fa14c12f6a F test/joinB.test 1b2ba3fc8568b49411787fccbf540570c148e9b6a53a30f80691cb6268098ded @@ -1950,8 +1950,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 cd8272fc2a34d1b245fd95208b9b601266ee7d2ff0f5ce52d03752f2c4e852a2 -R 8a87ff03f3b9042d5d80a515b01bbe71 +P e611e8e62c948d28cd3f28452d3096bab06998a685ed9434061cc2054f5cac32 +R 6eb9ce78903cb51667587564d90eaf9e U drh -Z 4f221c243b1c9d53087ee3bfbfa41863 +Z b02c9deafbd857b68575d851608b8518 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b5360486b6..cd4b508973 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e611e8e62c948d28cd3f28452d3096bab06998a685ed9434061cc2054f5cac32 \ No newline at end of file +fd328e52aee1dace12b1c2f44b6f7e9d15d8f77c8e9d9e3d85840a129a4b1808 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 9ba987ca6a..4f525a8fbf 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -2843,6 +2843,8 @@ SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( sFrom.nAlloc = 1; memcpy(&sFrom.a[0], pTabItem, sizeof(SrcItem)); sFrom.a[0].fg.jointype = 0; + assert( pParse->withinRJSubrtn < 100 ); + pParse->withinRJSubrtn++; pSubWInfo = sqlite3WhereBegin(pParse, &sFrom, pSubWhere, 0, 0, 0, WHERE_RIGHT_JOIN, 0); if( pSubWInfo ){ @@ -2875,4 +2877,6 @@ SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( } sqlite3ExprDelete(pParse->db, pSubWhere); ExplainQueryPlanPop(pParse); + assert( pParse->withinRJSubrtn>0 ); + pParse->withinRJSubrtn--; } diff --git a/test/join8.test b/test/join8.test index 5ef85c4cf8..fada516492 100644 --- a/test/join8.test +++ b/test/join8.test @@ -126,5 +126,15 @@ do_execsql_test join8-3040 { SELECT * FROM t9 WHERE id<>128*h+64*g+32*f+16*e+8*d+4*c+2*b+a; } {} +# 2022-04-21 dbsqlfuzz find +# +reset_db +do_execsql_test join8-4000 { + CREATE TABLE t1(x INTEGER PRIMARY KEY, a, b); + INSERT INTO t1 VALUES(1,5555,4); + CREATE INDEX i1a ON t1(a); + CREATE INDEX i1b ON t1(b); + SELECT a FROM t1 NATURAL RIGHT JOIN t1 WHERE a=5555 OR (1,b)==(SELECT 2 IN (2,2),4); +} {5555} finish_test From 7e9a56f70f5f361a2ca30efdc15f073318c42254 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 21 Apr 2022 19:14:23 +0000 Subject: [PATCH 197/259] Fix harmless compiler warnings in the CLI. FossilOrigin-Name: dfd2100bc4f316825fd199b347849d1a2b941837f9eedcf36f3c3d280692b991 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c.in | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 3a1dd36072..ec569dd78e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C For\sCLI,\sfix\show\scolumnar\smode\sfills\sin\sempty\sportions\sof\swrapped\srow\soutputs. -D 2022-04-20T22:41:10.920 +C Fix\sharmless\scompiler\swarnings\sin\sthe\sCLI. +D 2022-04-21T19:14:23.704 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -553,7 +553,7 @@ F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c 18d99e7146852d6064559561769fcca0743eb32b14a97da6dbed373a30ee0e76 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 2df3b525acb48c4e005556771164cefca301e32aad14ffc51f5c9480ea04ff38 -F src/shell.c.in b3250485b9b6c926c2576e6e89b23574b6d59fcd04ea9bc63131a13fb4243628 +F src/shell.c.in ae0a6fae983caac6f8c824733f0599dfdf7b3a7e8efdef3cb5e3ab2e457ffc35 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e @@ -1945,8 +1945,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 9430ead7ba433cbfce99f4f364a0c08499230e3a04f167326b0f131f098ffa09 -R 6ef848a57b0ae2fb87aa59c0dc6c64a7 -U larrybr -Z 0a5dc40772a2c0441c803c4b4812274a +P 77aed89192bdbad819ac17bf5d08728278a9b8cbbbef1d805df230caff79b417 +R 9aaafc06672426af81fcdc005d19ebe8 +U drh +Z 3b2a5cb05d697a79a788f6022f5820da # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e8362d9747..3e212c427a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -77aed89192bdbad819ac17bf5d08728278a9b8cbbbef1d805df230caff79b417 \ No newline at end of file +dfd2100bc4f316825fd199b347849d1a2b941837f9eedcf36f3c3d280692b991 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index e6f4a2c95b..95a32f5247 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -3413,14 +3413,14 @@ static void exec_prepared_stmt_columnar( if( wx<0 ) wx = -wx; if( useNextLine ){ uz = azNextLine[i]; - if( uz==0 ) uz = (char*)zEmpty; + if( uz==0 ) uz = (u8*)zEmpty; }else if( p->cmOpts.bQuote ){ sqlite3_free(azQuoted[i]); azQuoted[i] = quoted_column(pStmt,i); uz = (const unsigned char*)azQuoted[i]; }else{ uz = (const unsigned char*)sqlite3_column_text(pStmt,i); - if( uz==0 ) uz = (char*)zShowNull; + if( uz==0 ) uz = (u8*)zShowNull; } azData[nRow*nColumn + i] = translateForDisplayAndDup(uz, &azNextLine[i], wx, bw); From a74b4c4d4558504d4ad8cef81d18ce7f45ad05ea Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 21 Apr 2022 19:20:38 +0000 Subject: [PATCH 198/259] Fix a harmless uninitialized variable warning in MSVC. FossilOrigin-Name: b870d2a2fa54ddab6ffc9b9d95f52420a5a6831aeb73dac75355ca1ab15a190e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 3 +++ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index ec569dd78e..1a14169f7a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sin\sthe\sCLI. -D 2022-04-21T19:14:23.704 +C Fix\sa\sharmless\suninitialized\svariable\swarning\sin\sMSVC. +D 2022-04-21T19:20:38.804 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -624,7 +624,7 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c e82071ff183d3cf9aa3afeefc40f10a2443e8056e16c38f6d80e041da7ec3fb2 +F src/vdbe.c a4d710ef5a5a5be60cbb0ae74bba569d2689b670a73e825276687d89559ab917 F src/vdbe.h 89f5edb1422c8783a0b29db836e409876f2b3e847f78e2b21b1fbcc48a93f85f F src/vdbeInt.h 5f3d0abcf30c2b7a6672ad4386f18be0fca9c9b2cefe18f85a2e3df74f2613bf F src/vdbeapi.c 354c893f1500cf524cc45c32879b9c68893a28b77e3442c24668d6afe4236217 @@ -1945,8 +1945,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 77aed89192bdbad819ac17bf5d08728278a9b8cbbbef1d805df230caff79b417 -R 9aaafc06672426af81fcdc005d19ebe8 +P dfd2100bc4f316825fd199b347849d1a2b941837f9eedcf36f3c3d280692b991 +R b0caf88c4ea0c8c655e6322050b10cd7 U drh -Z 3b2a5cb05d697a79a788f6022f5820da +Z 411498f228eb3c02198e993caa11ad7e # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 3e212c427a..88f8c21426 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dfd2100bc4f316825fd199b347849d1a2b941837f9eedcf36f3c3d280692b991 \ No newline at end of file +b870d2a2fa54ddab6ffc9b9d95f52420a5a6831aeb73dac75355ca1ab15a190e \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 16b6f9bb55..7d7ff3e4fb 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5012,6 +5012,9 @@ case OP_Found: { /* jump, in3 */ /* Composite key generated by OP_MakeRecord */ assert( pIn3->flags & MEM_Blob ); assert( pOp->opcode!=OP_NoConflict ); +#if defined(_MSC_VER) + memset(&r, 0, sizeof(r)); /* Silence a harmless compiler warning */ +#endif rc = ExpandBlob(pIn3); assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); if( rc ) goto no_mem; From 6dab33bf40922a55475f8eefc5ab3fc239b768b9 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 21 Apr 2022 19:25:51 +0000 Subject: [PATCH 199/259] Fix harmless compiler warnings. FossilOrigin-Name: 29255664127a975e5b0d5767cd4e56d93ff2ea1994702cdfbdca1b700952502e --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/build.c | 1 + src/vdbe.c | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 447c65a511..3100e2ab68 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sthe\scode\sgenerator\sknows\sto\sinvoke\srow-value\ssubroutines\swhich\nrunning\sthe\sright-join\spost-processing\sloop. -D 2022-04-21T14:48:40.635 +C Fix\sharmless\scompiler\swarnings. +D 2022-04-21T19:25:51.652 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -495,7 +495,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c df695e953c2ce78ce4878ee5016751df9bc9a921dc0500a0f53ab3bb3196e505 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482e -F src/build.c e1ecd83b3f9ff5079e63e5223ae02bbbd50335dbcf65b54405545de8988e6fae +F src/build.c 470be339e458a48456cb317ad207ab3cb68ace8b2d76625d2a7eace660fc9674 F src/callback.c 4c19af69835787bfe790ac560f3071a824eb629f34e41f97b52ce5235c77de1c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 026dbdcdbd8c3cde98a88483ee88310ff43150ab164ad768f12cc700a11495ad @@ -624,7 +624,7 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c 4efdce17535c925a040cf289bef12e12f7be9e2e02825c67db52c4e8723b89fb +F src/vdbe.c 9527ab7f71c5b0291e5ed7727f213f4d7f6e0a82af019da5b365fd5a0f56bb96 F src/vdbe.h 89f5edb1422c8783a0b29db836e409876f2b3e847f78e2b21b1fbcc48a93f85f F src/vdbeInt.h ef43f7fdc5fde29fc3fd29c506c12830f366178fdb4edbbf0cbc3dfbd1278b5f F src/vdbeapi.c 354c893f1500cf524cc45c32879b9c68893a28b77e3442c24668d6afe4236217 @@ -1950,8 +1950,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 e611e8e62c948d28cd3f28452d3096bab06998a685ed9434061cc2054f5cac32 -R 6eb9ce78903cb51667587564d90eaf9e +P fd328e52aee1dace12b1c2f44b6f7e9d15d8f77c8e9d9e3d85840a129a4b1808 +R 98fca67b285a824f5cacf5d0926743e5 U drh -Z b02c9deafbd857b68575d851608b8518 +Z 97d3cf4d3664df607159e68c652388e1 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index cd4b508973..3517c1b3ce 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fd328e52aee1dace12b1c2f44b6f7e9d15d8f77c8e9d9e3d85840a129a4b1808 \ No newline at end of file +29255664127a975e5b0d5767cd4e56d93ff2ea1994702cdfbdca1b700952502e \ No newline at end of file diff --git a/src/build.c b/src/build.c index e1051ab9f3..8ae263fc3e 100644 --- a/src/build.c +++ b/src/build.c @@ -5081,6 +5081,7 @@ void sqlite3SrcListFuncArgs(Parse *pParse, SrcList *p, ExprList *pList){ ** the left operand of at least one RIGHT JOIN. */ void sqlite3SrcListShiftJoinType(Parse *pParse, SrcList *p){ + (void)pParse; if( p && p->nSrc>1 ){ int i = p->nSrc-1; u8 allFlags = 0; diff --git a/src/vdbe.c b/src/vdbe.c index 65e843fd2b..087a837955 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1011,7 +1011,7 @@ case OP_Gosub: { /* jump */ case OP_Return: { /* in1 */ pIn1 = &aMem[pOp->p1]; if( pIn1->flags & MEM_Int ){ - if( pOp->p3 ) VdbeBranchTaken(1, 2); + if( pOp->p3 ){ VdbeBranchTaken(1, 2); } pOp = &aOp[pIn1->u.i]; }else if( ALWAYS(pOp->p3) ){ VdbeBranchTaken(0, 2); From abb4e7598c334d93931405333eb419582d95f94c Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 21 Apr 2022 23:01:24 +0000 Subject: [PATCH 200/259] Disable join8.test if the build lacks support for virtual tables. FossilOrigin-Name: 94e1916a2f594e6b8a54734027deb99688244d05cefb3c78f23afab49af1e08f --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/join8.test | 4 ++++ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index fdb180035e..8ae7416cf3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssupport\sfor\sRIGHT\sand\sFULL\sJOIN. -D 2022-04-21T19:38:17.167 +C Disable\sjoin8.test\sif\sthe\sbuild\slacks\ssupport\sfor\svirtual\stables. +D 2022-04-21T23:01:24.700 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1147,7 +1147,7 @@ F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test c4df54e2e204d7f1417bfbdd21ca324b4b07415c647595cc47798eacfddc96d3 F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c F test/join7.test 8e72de4b45e5e930d18c305c7efe86015fb2552731e4e03ea226353036b0dab0 -F test/join8.test f9b4e3be35d8546e934ea9e18244d3a26d6e22c51dadef9d721db7cd25c606b5 +F test/join8.test 085a47c160ba8bad31817a4dabaf0e0af00a2ad146ab95dc0b90e2f0166e701e F test/join9.test 9056ddd3b0c0f4f9d658f4521038d9a37dc23ead8ca9a505d0b0db2b6a471e05 F test/joinA.test 7eab225dc1c1ab258a5e62513a4ed7cabbd3db971d59d5d92f4fb6fa14c12f6a F test/joinB.test 1b2ba3fc8568b49411787fccbf540570c148e9b6a53a30f80691cb6268098ded @@ -1950,8 +1950,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 b870d2a2fa54ddab6ffc9b9d95f52420a5a6831aeb73dac75355ca1ab15a190e 29255664127a975e5b0d5767cd4e56d93ff2ea1994702cdfbdca1b700952502e -R aaacbf77275f81b4612909a20841ea0d +P f766dff012af0ea3c28a8ce4db850cd0205729a8283bce1e442992aded7c734b +R bd10217d64495c218e1b07751142aeb5 U drh -Z 33a15e5f0b37eabbe920c3340c278cbb +Z 41a5c71f636ea94dd40697c62df8b4a4 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 595714bef6..03a0a3df30 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f766dff012af0ea3c28a8ce4db850cd0205729a8283bce1e442992aded7c734b \ No newline at end of file +94e1916a2f594e6b8a54734027deb99688244d05cefb3c78f23afab49af1e08f \ No newline at end of file diff --git a/test/join8.test b/test/join8.test index fada516492..f025f7cf6d 100644 --- a/test/join8.test +++ b/test/join8.test @@ -14,6 +14,10 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +ifcapable !vtab { + finish_test +} + db null NULL do_execsql_test join8-10 { CREATE TABLE t1(a,b,c); From 1c69bc912d05bf1bf8acbda2abc4a2966d490e5b Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 21 Apr 2022 23:34:35 +0000 Subject: [PATCH 201/259] Previous fix to join8.test needs a return. FossilOrigin-Name: 7b4cd705a0339ddacad19564b07e50e4f68f54bf14dd2cd5d59b39314a4d2523 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/join8.test | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 8ae7416cf3..6279c85f81 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disable\sjoin8.test\sif\sthe\sbuild\slacks\ssupport\sfor\svirtual\stables. -D 2022-04-21T23:01:24.700 +C Previous\sfix\sto\sjoin8.test\sneeds\sa\sreturn. +D 2022-04-21T23:34:35.567 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1147,7 +1147,7 @@ F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test c4df54e2e204d7f1417bfbdd21ca324b4b07415c647595cc47798eacfddc96d3 F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c F test/join7.test 8e72de4b45e5e930d18c305c7efe86015fb2552731e4e03ea226353036b0dab0 -F test/join8.test 085a47c160ba8bad31817a4dabaf0e0af00a2ad146ab95dc0b90e2f0166e701e +F test/join8.test fdab1aef8bebced45b3664c869a43dc3eeff658e98d183edf513b262369703f6 F test/join9.test 9056ddd3b0c0f4f9d658f4521038d9a37dc23ead8ca9a505d0b0db2b6a471e05 F test/joinA.test 7eab225dc1c1ab258a5e62513a4ed7cabbd3db971d59d5d92f4fb6fa14c12f6a F test/joinB.test 1b2ba3fc8568b49411787fccbf540570c148e9b6a53a30f80691cb6268098ded @@ -1950,8 +1950,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 f766dff012af0ea3c28a8ce4db850cd0205729a8283bce1e442992aded7c734b -R bd10217d64495c218e1b07751142aeb5 +P 94e1916a2f594e6b8a54734027deb99688244d05cefb3c78f23afab49af1e08f +R 573150bf22fddc6433562bcb5d5bac98 U drh -Z 41a5c71f636ea94dd40697c62df8b4a4 +Z a95960d40040bb3ed2298fba0fa35ab1 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 03a0a3df30..c126036c75 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -94e1916a2f594e6b8a54734027deb99688244d05cefb3c78f23afab49af1e08f \ No newline at end of file +7b4cd705a0339ddacad19564b07e50e4f68f54bf14dd2cd5d59b39314a4d2523 \ No newline at end of file diff --git a/test/join8.test b/test/join8.test index f025f7cf6d..c23905845b 100644 --- a/test/join8.test +++ b/test/join8.test @@ -16,6 +16,7 @@ source $testdir/tester.tcl ifcapable !vtab { finish_test + return } db null NULL From 9c2d7aa7d060def8173e9b235bdb565b874b9205 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 22 Apr 2022 12:46:46 +0000 Subject: [PATCH 202/259] Minor simplification to the result-set wildcard expander for SF_NestedFrom. FossilOrigin-Name: d942530a6550a0cbe31790e462b0f0d57b9b4a896161878b7d45d11cbc1cb7a3 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 31 +++++++++++++++++-------------- 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 8fd84c938a..1c7c3c08b2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\slatest\strunk\sfixes\sinto\sthe\sright-join\sbranch. -D 2022-04-22T09:57:57.238 +C Minor\ssimplification\sto\sthe\sresult-set\swildcard\sexpander\sfor\sSF_NestedFrom. +D 2022-04-22T12:46:46.142 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -552,7 +552,7 @@ F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c f72bb13359dd5a74d440df25f320dc2c1baff5cde4fc9f0d1bc3feba90b8932a F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 51e8b778abdd89289e2f2a6733d5e7ac6082f6c56ca717fa15f64f202e66bf42 +F src/select.c cbfe750ec71cc103a0efbf7448323f5abca8e6208fb90a387a06aa79721e594c F src/shell.c.in ae0a6fae983caac6f8c824733f0599dfdf7b3a7e8efdef3cb5e3ab2e457ffc35 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1950,8 +1950,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 29255664127a975e5b0d5767cd4e56d93ff2ea1994702cdfbdca1b700952502e 7b4cd705a0339ddacad19564b07e50e4f68f54bf14dd2cd5d59b39314a4d2523 -R 573150bf22fddc6433562bcb5d5bac98 +P c74dc574c3b24a7d3533202f33b15341b043cfd89a80250563e6771ab6b6b8a7 +R eba1e6cacae696fe7d98ccb5196506b7 U drh -Z 6f92506738c5bfa628c9724dc6f28600 +Z 74811392752bd0fda66f61fdab9e1693 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 552535ae7d..39dacb875b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c74dc574c3b24a7d3533202f33b15341b043cfd89a80250563e6771ab6b6b8a7 \ No newline at end of file +d942530a6550a0cbe31790e462b0f0d57b9b4a896161878b7d45d11cbc1cb7a3 \ No newline at end of file diff --git a/src/select.c b/src/select.c index f0a3e58775..2b27eea630 100644 --- a/src/select.c +++ b/src/select.c @@ -5804,25 +5804,27 @@ static int selectExpander(Walker *pWalker, Select *p){ zTName = pE->pLeft->u.zToken; } for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ - Table *pTab = pFrom->pTab; - Select *pSub; - char *zTabName = pFrom->zAlias; - const char *zSchemaName = 0; - int iDb; - if( zTabName==0 ){ + Table *pTab = pFrom->pTab; /* Table for this data source */ + ExprList *pNestedFrom; /* Result-set of a nested FROM clause */ + char *zTabName; /* AS name for this data source */ + const char *zSchemaName = 0; /* Schema name for this data source */ + int iDb; /* Schema index for this data src */ + + if( (zTabName = pFrom->zAlias)==0 ){ zTabName = pTab->zName; } if( db->mallocFailed ) break; assert( pFrom->fg.isNestedFrom == IsNestedFrom(pFrom->pSelect) ); if( pFrom->fg.isNestedFrom ){ - pSub = pFrom->pSelect; - assert( pSub->pEList!=0 ); - assert( pSub->pEList->nExpr==pTab->nCol ); + assert( pFrom->pSelect!=0 ); + pNestedFrom = pFrom->pSelect->pEList; + assert( pNestedFrom!=0 ); + assert( pNestedFrom->nExpr==pTab->nCol ); }else{ - pSub = 0; if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){ continue; } + pNestedFrom = 0; iDb = sqlite3SchemaToIndex(db, pTab->pSchema); zSchemaName = iDb>=0 ? db->aDb[iDb].zDbSName : "*"; } @@ -5831,8 +5833,9 @@ static int selectExpander(Walker *pWalker, Select *p){ struct ExprList_item *pX; /* Newly added ExprList term */ assert( zName ); - if( zTName && pSub - && sqlite3MatchEName(&pSub->pEList->a[j], 0, zTName, 0)==0 + if( zTName + && pNestedFrom + && sqlite3MatchEName(&pNestedFrom->a[j], 0, zTName, 0)==0 ){ continue; } @@ -5885,8 +5888,8 @@ static int selectExpander(Walker *pWalker, Select *p){ pX = &pNew->a[pNew->nExpr-1]; assert( pX->zEName==0 ); if( (selFlags & SF_NestedFrom)!=0 && !IN_RENAME_OBJECT ){ - if( pSub ){ - pX->zEName = sqlite3DbStrDup(db, pSub->pEList->a[j].zEName); + if( pNestedFrom ){ + pX->zEName = sqlite3DbStrDup(db, pNestedFrom->a[j].zEName); testcase( pX->zEName==0 ); }else{ pX->zEName = sqlite3MPrintf(db, "%s.%s.%s", From 9b843f0ce0bae9a6a62edd0a006bcec436622cdf Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 22 Apr 2022 15:18:41 +0000 Subject: [PATCH 203/259] Add test cases to check the handling of SQLITE_BUSY in rbu. FossilOrigin-Name: 6fccc733c6041a2946fb3d37e4737ae37defae5c110225dd746cdc038cc64957 --- ext/rbu/rbubusy.test | 82 ++++++++++++++++++++++++++++++++++++++++++++ manifest | 13 +++---- manifest.uuid | 2 +- 3 files changed, 90 insertions(+), 7 deletions(-) create mode 100644 ext/rbu/rbubusy.test diff --git a/ext/rbu/rbubusy.test b/ext/rbu/rbubusy.test new file mode 100644 index 0000000000..a16b85ff96 --- /dev/null +++ b/ext/rbu/rbubusy.test @@ -0,0 +1,82 @@ +# 2014 August 30 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# + +source [file join [file dirname [info script]] rbu_common.tcl] +set ::testprefix rbubusy + +db close +sqlite3_shutdown +test_sqlite3_log xLog +reset_db + +set db_sql { + CREATE TABLE t1(a PRIMARY KEY, b, c); + INSERT INTO t1 VALUES(1000, 2000, 3000); +} + +set rbu_sql { + CREATE TABLE data_t1(a, b, c, rbu_control); + INSERT INTO data_t1 VALUES(1, 2, 3, 0); + INSERT INTO data_t1 VALUES(4, 5, 6, 0); + INSERT INTO data_t1 VALUES(7, 8, 9, 0); +} + +do_test 1.1 { + forcedelete rbu.db + sqlite3 rbu rbu.db + rbu eval $rbu_sql + rbu close + + db eval $db_sql +} {} + +do_execsql_test 1.2 { + BEGIN; + SELECT * FROM t1 +} {1000 2000 3000} + +do_test 1.3 { + sqlite3rbu rbu test.db rbu.db + rbu step +} {SQLITE_OK} + +do_test 1.4 { + while 1 { + set rc [rbu step] + if {$rc!="SQLITE_OK"} break + } + set rc +} {SQLITE_BUSY} + +do_test 1.5 { + rbu step +} {SQLITE_BUSY} + +do_test 1.6 { + db eval COMMIT + rbu step +} {SQLITE_BUSY} +catch { rbu close } + +do_test 1.7 { + sqlite3rbu rbu test.db rbu.db + while 1 { + set rc [rbu step] + if {$rc!="SQLITE_OK"} break + } + set rc +} {SQLITE_DONE} + +rbu close + +finish_test diff --git a/manifest b/manifest index 512b12406b..94e3d8eb50 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplification\sof\sdata\sstructures\sin\sthe\swildcard\sexpander\sfor\nSF_NestedFrom\squeries. -D 2022-04-22T13:34:45.273 +C Add\stest\scases\sto\scheck\sthe\shandling\sof\sSQLITE_BUSY\sin\srbu. +D 2022-04-22T15:18:41.615 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -358,6 +358,7 @@ F ext/rbu/rbuA.test b34a90cb495682c25b5fc03a9d5e7a4fc99541c29256f25e2e2a4f6542b4 F ext/rbu/rbuB.test 52b07158824c6927b7e25554ace92a695cdebfc296ae3d308ac386984aded9bc F ext/rbu/rbuC.test 80f1cc2fb74f44b1128fd0ed8eedab3a76fefeb72a947860e2869ef76fc8dc6b F ext/rbu/rbu_common.tcl 60d904133ff843fe72cc0514e9dd2486707181e6e0fbab20979da28c48d21de9 +F ext/rbu/rbubusy.test 35a6ad081b374281f728b26264ef4f0b0e7888ccb5ace1843aed30ed99c2e1ca F ext/rbu/rbucollate.test cac528a9a46318cba42e61258bb42660bbbf4fdb9a8c863de5a54ad0c658d197 F ext/rbu/rbucrash.test 000981a1fe8a6e4d9a684232f6a129e66a3ef595f5ed74655e2f9c68ffa613b4 F ext/rbu/rbucrash2.test efa143cc94228eb0266d3f1abfbee60a5838a84cef7cc3fcb8c145b74d96fd41 @@ -1950,8 +1951,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 7b4cd705a0339ddacad19564b07e50e4f68f54bf14dd2cd5d59b39314a4d2523 d942530a6550a0cbe31790e462b0f0d57b9b4a896161878b7d45d11cbc1cb7a3 -R eba1e6cacae696fe7d98ccb5196506b7 -U drh -Z 02284e5f70f7e0ce37132715f41fa694 +P f7c18262347ff430879d5afc7a118d2b9b0050c845c6b1fe6c047062ea2ba8fe +R a6d9f2b1d5400cca176b02195a3ac6f5 +U dan +Z ae29b1d7301d35ff4fb51acebf10a86c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9cdf45d0f6..cff6a3e513 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f7c18262347ff430879d5afc7a118d2b9b0050c845c6b1fe6c047062ea2ba8fe \ No newline at end of file +6fccc733c6041a2946fb3d37e4737ae37defae5c110225dd746cdc038cc64957 \ No newline at end of file From 67f70bea06eea1e20124c4e97d2f545b3f10b473 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 22 Apr 2022 16:15:48 +0000 Subject: [PATCH 204/259] Honor the MATERIALIZED keyword on a common table expression by not flattening the CTE into an outer query. FossilOrigin-Name: 8d631a6b9eb06b54b10eda595a4c588ca38f909b4afa653b24d1f720b55d72f7 --- manifest | 22 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 1 + src/select.c | 5 ++++ src/treeview.c | 4 +++ test/with1.test | 8 +++--- test/with6.test | 69 ++++++++++++++++++++++++++++++++++++++++++++++++- 7 files changed, 94 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 94e3d8eb50..e9a1cdbd7f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\scases\sto\scheck\sthe\shandling\sof\sSQLITE_BUSY\sin\srbu. -D 2022-04-22T15:18:41.615 +C Honor\sthe\sMATERIALIZED\skeyword\son\sa\scommon\stable\sexpression\sby\snot\sflattening\nthe\sCTE\sinto\san\souter\squery. +D 2022-04-22T16:15:48.995 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -504,7 +504,7 @@ F src/date.c 15082566229d4b1e5f24fdb490bf9bcc68824b911d70e3573ef075a1b9e2d26f F src/dbpage.c 90661a87e1db8bfbc8d2ebbdcd3749651ddb287c555c07a28fb17c7c591ffb68 F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d F src/delete.c a8e844af211a48b13b5b358be77a12c860c6a557c21990ad51a548e2536500ce -F src/expr.c 899c77da1cd4d836d93f94cf435fc761695938dda8932becfccfdb2eb7d6a7d9 +F src/expr.c 06dfbfb7f469c00eba3c8a7e282765969fe7c772f235a365f51bfffcaa69fe7f F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c d965ede15d8360c09ed59348940649ee647b192e784466837d7aefa836d1d91e F src/func.c a3407a6fbb0d4088d8d502e46f0ace63e0aeae7467ae23a9ca9815bbf9239761 @@ -553,7 +553,7 @@ F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c f72bb13359dd5a74d440df25f320dc2c1baff5cde4fc9f0d1bc3feba90b8932a F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c cbfe750ec71cc103a0efbf7448323f5abca8e6208fb90a387a06aa79721e594c +F src/select.c 0d0a82875c9b8617b9b8189eddc7cde3aac89fcafb866608fdc819c6b7cba06c F src/shell.c.in ae0a6fae983caac6f8c824733f0599dfdf7b3a7e8efdef3cb5e3ab2e457ffc35 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -618,7 +618,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98 -F src/treeview.c c834e0c9030b1f9971152e049f44e2f973625c680f10aed2fbcc956da2301d0b +F src/treeview.c 396c21e21c853ebc1830c194fa13f1161dbc76adad0b0a605172ddb78b3b4cdb F src/trigger.c 372ada38f667c6823a3db15749eb668338e65c793394e55a37e56a489f2d1b55 F src/update.c 2cfaded82ca80ff56afb8c3ae5e88284e0824bfd86119827cc22481959f96f92 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 @@ -1826,12 +1826,12 @@ F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387 F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b F test/windowfault.test 15094c1529424e62f798bc679e3fe9dfab6e8ba2f7dfe8c923b6248c31660a7c F test/windowpushd.test d8895d08870b7226f7693665bd292eb177e62ca06799184957b3ca7dc03067df -F test/with1.test 7bc5abfe4c80c0cef8a90f5a66d60b9982e8ccd7350c8eb70611323a3b8e07ba +F test/with1.test 9ad67fdeb2bbd808a5763c9060e214ea232f9b18d846ea3a59756dc38bdc3880 F test/with2.test a1df41b987198383b9b70bf5e5fda390582e46398653858dbc6ceb24253b28df F test/with3.test ad32d13ad50661e6fa305f62a0717649c348792e7b658bf2644976227a9e0373 F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f198205 F test/with5.test 6248213c41fab36290b5b73aa3f937309dfba337004d9d8434c3fabc8c7d4be8 -F test/with6.test 661d7e416bef6c0a2556b2c9f0c8178a5b15932bed65246abed99723a8d4e7c0 +F test/with6.test c18592592b5a1c5802fd4e933d506f7b34ebbe8fdd585229793e960ae58d433f F test/withM.test 693b61765f2b387b5e3e24a4536e2e82de15ff64 F test/without_rowid1.test a5210b8770dc4736bca4e74bc96588f43025ad03ad6a80f885afd36d9890e217 F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99 @@ -1951,8 +1951,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 f7c18262347ff430879d5afc7a118d2b9b0050c845c6b1fe6c047062ea2ba8fe -R a6d9f2b1d5400cca176b02195a3ac6f5 -U dan -Z ae29b1d7301d35ff4fb51acebf10a86c +P 6fccc733c6041a2946fb3d37e4737ae37defae5c110225dd746cdc038cc64957 +R 36a9cb28aa336cfdc994567486f634f5 +U drh +Z fdbd2379fdafb7d5c12821e010585320 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index cff6a3e513..628c9a3fd4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6fccc733c6041a2946fb3d37e4737ae37defae5c110225dd746cdc038cc64957 \ No newline at end of file +8d631a6b9eb06b54b10eda595a4c588ca38f909b4afa653b24d1f720b55d72f7 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index a300971345..1709876219 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1527,6 +1527,7 @@ With *sqlite3WithDup(sqlite3 *db, With *p){ pRet->a[i].pSelect = sqlite3SelectDup(db, p->a[i].pSelect, 0); pRet->a[i].pCols = sqlite3ExprListDup(db, p->a[i].pCols, 0); pRet->a[i].zName = sqlite3DbStrDup(db, p->a[i].zName); + pRet->a[i].eM10d = p->a[i].eM10d; } } } diff --git a/src/select.c b/src/select.c index 2b27eea630..26a3172aeb 100644 --- a/src/select.c +++ b/src/select.c @@ -4153,6 +4153,8 @@ static void renumberCursors( ** (27) The subquery may not contain a FULL or RIGHT JOIN unless it ** is the first element of the parent query. ** +** (28) The subquery is not a MATERIALIZED CTE. +** ** ** In this routine, the "p" parameter is a pointer to the outer query. ** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query @@ -4276,6 +4278,9 @@ static int flattenSubquery( if( iFrom>0 && (pSubSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ return 0; /* Restriction (27) */ } + if( pSubitem->fg.isCte && pSubitem->u2.pCteUse->eM10d==M10d_Yes ){ + return 0; /* (28) */ + } /* Restriction (17): If the sub-query is a compound SELECT, then it must ** use only the UNION ALL operator. And none of the simple select queries diff --git a/src/treeview.c b/src/treeview.c index 3ba8a63cd7..db73943f02 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -115,6 +115,10 @@ void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){ } sqlite3_str_appendf(&x, ")"); } + if( pCte->eM10d!=M10d_Any ){ + sqlite3_str_appendf(&x, " %sMATERIALIZED", + pCte->eM10d==M10d_No ? "NOT " : ""); + } if( pCte->pUse ){ sqlite3_str_appendf(&x, " (pUse=0x%p, nUse=%d)", pCte->pUse, pCte->pUse->nUse); diff --git a/test/with1.test b/test/with1.test index 5765399d10..91cbc79524 100644 --- a/test/with1.test +++ b/test/with1.test @@ -1075,10 +1075,10 @@ do_execsql_test 21.2 { # Make sure crazy nexted CTE joins terminate with an error quickly. # do_catchsql_test 22.1 { - WITH RECURSIVE c AS ( - WITH RECURSIVE c AS ( - WITH RECURSIVE c AS ( - WITH RECURSIVE c AS ( + WITH RECURSIVE c AS NOT MATERIALIZED ( + WITH RECURSIVE c AS NOT MATERIALIZED ( + WITH RECURSIVE c AS NOT MATERIALIZED ( + WITH RECURSIVE c AS NOT MATERIALIZED ( WITH c AS (VALUES(0)) SELECT 1 FROM c LEFT JOIN c ON ltrim(1) ) diff --git a/test/with6.test b/test/with6.test index 333147d8be..20e518b01a 100644 --- a/test/with6.test +++ b/test/with6.test @@ -229,10 +229,12 @@ do_eqp_test 211 { } { QUERY PLAN |--MATERIALIZE c1 - | |--MATERIALIZE c + | |--CO-ROUTINE c | | `--SCAN 3 CONSTANT ROWS | `--SCAN c |--MATERIALIZE c2 + | |--CO-ROUTINE c + | | `--SCAN 3 CONSTANT ROWS | `--SCAN c |--SCAN c1 |--SCAN c2 @@ -250,6 +252,71 @@ do_execsql_test 220 { SELECT y FROM t2 ORDER BY y; } {40404 40405 40406 40504 40505 40506 40604 40605 40606} +# 2022-04-22: Do not allow flattening of a MATERIALIZED CTE into +# an outer query. +# +reset_db +db null - +do_execsql_test 300 { + CREATE TABLE t2(a INT,b INT,d INT); INSERT INTO t2 VALUES(4,5,6),(7,8,9); + CREATE TABLE t3(a INT,b INT,e INT); INSERT INTO t3 VALUES(3,3,3),(8,8,8); +} {} +do_execsql_test 310 { + WITH t23 AS MATERIALIZED (SELECT * FROM t2 FULL JOIN t3 USING(b)) + SELECT * FROM t23; +} { + 4 5 6 - - + 7 8 9 8 8 + - 3 - 3 3 +} +do_eqp_test 311 { + WITH t23 AS MATERIALIZED (SELECT * FROM t2 FULL JOIN t3 USING(b)) + SELECT * FROM t23; +} { + QUERY PLAN + |--MATERIALIZE t23 + | |--SCAN t2 + | |--SCAN t3 LEFT-JOIN + | `--RIGHT-JOIN t3 + | `--SCAN t3 + `--SCAN t23 +} +do_execsql_test 320 { + WITH t23 AS NOT MATERIALIZED (SELECT * FROM t2 FULL JOIN t3 USING(b)) + SELECT * FROM t23; +} { + 4 5 6 - - + 7 8 9 8 8 + - 3 - 3 3 +} +do_eqp_test 321 { + WITH t23 AS NOT MATERIALIZED (SELECT * FROM t2 FULL JOIN t3 USING(b)) + SELECT * FROM t23; +} { + QUERY PLAN + |--SCAN t2 + |--SCAN t3 LEFT-JOIN + `--RIGHT-JOIN t3 + `--SCAN t3 +} +do_execsql_test 330 { + WITH t23 AS (SELECT * FROM t2 FULL JOIN t3 USING(b)) + SELECT * FROM t23; +} { + 4 5 6 - - + 7 8 9 8 8 + - 3 - 3 3 +} +do_eqp_test 331 { + WITH t23 AS (SELECT * FROM t2 FULL JOIN t3 USING(b)) + SELECT * FROM t23; +} { + QUERY PLAN + |--SCAN t2 + |--SCAN t3 LEFT-JOIN + `--RIGHT-JOIN t3 + `--SCAN t3 +} finish_test From da653b897db2b7cc9cb636a5089860fa1520bf12 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 22 Apr 2022 17:36:10 +0000 Subject: [PATCH 205/259] Improve EXPLAIN QUERY PLAN output and comments on bytecode listings by distinguishing between "subquery" and "join" and using consistent names across EQP and bytecode. FossilOrigin-Name: a2d3ee92420ec564e31eb0005367cf7ff3d00bfaed5a98ffdbe17c91c95d9d97 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/printf.c | 10 ++++++++-- src/select.c | 4 +++- test/eqp.test | 12 ++++++------ test/select1.test | 6 +++--- test/tester.tcl | 1 + 7 files changed, 32 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index e9a1cdbd7f..89136d4a97 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Honor\sthe\sMATERIALIZED\skeyword\son\sa\scommon\stable\sexpression\sby\snot\sflattening\nthe\sCTE\sinto\san\souter\squery. -D 2022-04-22T16:15:48.995 +C Improve\sEXPLAIN\sQUERY\sPLAN\soutput\sand\scomments\son\sbytecode\slistings\sby\ndistinguishing\sbetween\s"subquery"\sand\s"join"\sand\susing\sconsistent\snames\nacross\sEQP\sand\sbytecode. +D 2022-04-22T17:36:10.121 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -549,11 +549,11 @@ F src/pcache1.c 54881292a9a5db202b2c0ac541c5e3ef9a5e8c4f1c1383adb2601d5499a60e65 F src/pragma.c d1aead03e8418ff586c7cfca344c50a914b8eb06abd841e8e91a982d823671da F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c fd940149c691684e7c1073c3787a7170e44852b02d1275d2e30a5b58e89cfcaf -F src/printf.c 05d8dfd2018bc4fc3ddb8b37eb97ccef7abf985643fa1caebdcf2916ca90fa32 +F src/printf.c 512574910a45341c8ad244bd3d4939968ebdfde215645b676fff01cc46e90757 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c f72bb13359dd5a74d440df25f320dc2c1baff5cde4fc9f0d1bc3feba90b8932a F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 0d0a82875c9b8617b9b8189eddc7cde3aac89fcafb866608fdc819c6b7cba06c +F src/select.c 7b641cd9ca37e4ed75e0aadfbc56baed9a2b94b6ba5fdf59d3d852b6156b0c61 F src/shell.c.in ae0a6fae983caac6f8c824733f0599dfdf7b3a7e8efdef3cb5e3ab2e457ffc35 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -894,7 +894,7 @@ F test/enc.test 9a7be5479da985381d740b15f432800f65e2c87029ee57a318f42cb2eb43763a F test/enc2.test 848bf05f15b011719f478dddb7b5e9aea35e39e457493cba4c4eef75d849a5ec F test/enc3.test 6807f7a7740a00361ca8d0ccd66bc60c8dc5f2b6 F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020 -F test/eqp.test bfe979eb1f4b8ab7a3bd7db6d16c2e6c6be0e5a3aada2227716f3fd3a9d76b69 +F test/eqp.test 473aea9599b4b7af46614b55198cd78167e4eccd48e60812a40db47c5c41dea9 F test/errmsg.test eae9f091eb39ce7e20305de45d8e5d115b68fa856fba4ea6757b6ca3705ff7f9 F test/eval.test 73969a2d43a511bf44080c44485a8c4d796b6a4f038d19e491867081155692c0 F test/exclusive.test 7ff63be7503990921838d5c9f77f6e33e68e48ed1a9d48cd28745bf650bf0747 @@ -1363,7 +1363,7 @@ F test/schema6.test e4bd1f23d368695eb9e7b51ef6e02ca0642ea2ab4a52579959826b5e7dce F test/schemafault.test 1936bceca55ac82c5efbcc9fc91a1933e45c8d1e1d106b9a7e56c972a5a2a51e F test/securedel.test 2f70b2449186a1921bd01ec9da407fbfa98c3a7a5521854c300c194b2ff09384 F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5 -F test/select1.test 3d23f66bf9ba77570acfe2ca5f1540ece17037cc64ab1a00efec9758ac29c268 +F test/select1.test 692e84cfa29c405854c69e8a4027183d64c22952866a123fabbce741a379e889 F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56 F test/select3.test c49fbb758903f3718e2de5aa4655eda4838131cbea24a86db908f8b6889aa68c F test/select4.test f0684d3da3bccacbe2a1ebadf6fb49d9df6f53acb4c6ebc228a88d0d6054cc7b @@ -1480,7 +1480,7 @@ F test/temptable.test d2c9b87a54147161bcd1822e30c1d1cd891e5b30 F test/temptable2.test d2940417496e2b9548e01d09990763fbe88c316504033256d51493e1f1a5ce6a F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc -F test/tester.tcl f577d040078dd4fb56ea1ccaa71f6bfd0ebf0bd0ac373304db4269b5474f9cb7 +F test/tester.tcl 18448c7801d44cc5f2690f54f803da49ed994b3968f73a393cff329e55926679 F test/thread001.test b61a29dd87cf669f5f6ac96124a7c97d71b0c80d9012746072055877055cf9ef F test/thread002.test e630504f8a06c00bf8bbe68528774dd96aeb2e58 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -1951,8 +1951,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 6fccc733c6041a2946fb3d37e4737ae37defae5c110225dd746cdc038cc64957 -R 36a9cb28aa336cfdc994567486f634f5 +P 8d631a6b9eb06b54b10eda595a4c588ca38f909b4afa653b24d1f720b55d72f7 +R ac14f314793152059b0e1f854dbd012a U drh -Z fdbd2379fdafb7d5c12821e010585320 +Z d4ba1bca8076431eba8e72fffafad1d9 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 628c9a3fd4..13b574d647 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8d631a6b9eb06b54b10eda595a4c588ca38f909b4afa653b24d1f720b55d72f7 \ No newline at end of file +a2d3ee92420ec564e31eb0005367cf7ff3d00bfaed5a98ffdbe17c91c95d9d97 \ No newline at end of file diff --git a/src/printf.c b/src/printf.c index 7bf6f2aebb..f55b6ef660 100644 --- a/src/printf.c +++ b/src/printf.c @@ -884,8 +884,14 @@ void sqlite3_str_vappendf( sqlite3_str_appendall(pAccum, pItem->zName); }else if( pItem->zAlias ){ sqlite3_str_appendall(pAccum, pItem->zAlias); - }else if( ALWAYS(pItem->pSelect) ){ - sqlite3_str_appendf(pAccum, "SUBQUERY %u", pItem->pSelect->selId); + }else{ + Select *pSel = pItem->pSelect; + assert( pSel!=0 ); + if( pSel->selFlags & SF_NestedFrom ){ + sqlite3_str_appendf(pAccum, "(join-%u)", pSel->selId); + }else{ + sqlite3_str_appendf(pAccum, "(subquery-%u)", pSel->selId); + } } length = width = 0; break; diff --git a/src/select.c b/src/select.c index 26a3172aeb..5f2465da0d 100644 --- a/src/select.c +++ b/src/select.c @@ -5555,8 +5555,10 @@ int sqlite3ExpandSubquery(Parse *pParse, SrcItem *pFrom){ pTab->nTabRef = 1; if( pFrom->zAlias ){ pTab->zName = sqlite3DbStrDup(pParse->db, pFrom->zAlias); + }else if( pSel->selFlags & SF_NestedFrom ){ + pTab->zName = sqlite3MPrintf(pParse->db, "(join-%u)", pSel->selId); }else{ - pTab->zName = sqlite3MPrintf(pParse->db, "subquery_%u", pSel->selId); + pTab->zName = sqlite3MPrintf(pParse->db, "(subquery-%u)", pSel->selId); } while( pSel->pPrior ){ pSel = pSel->pPrior; } sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol); diff --git a/test/eqp.test b/test/eqp.test index 19d6ea91ae..eda95776f2 100644 --- a/test/eqp.test +++ b/test/eqp.test @@ -94,9 +94,9 @@ do_eqp_test 1.7.1 { SELECT * FROM t3 JOIN (SELECT 1) } { QUERY PLAN - |--MATERIALIZE SUBQUERY xxxxxx + |--MATERIALIZE (subquery-xxxxxx) | `--SCAN CONSTANT ROW - |--SCAN SUBQUERY xxxxxx + |--SCAN (subquery-xxxxxx) `--SCAN t3 } do_eqp_test 1.7.2 { @@ -123,13 +123,13 @@ do_eqp_test 1.8 { SELECT * FROM t3 JOIN (SELECT 1 UNION SELECT 2) } { QUERY PLAN - |--MATERIALIZE SUBQUERY xxxxxx + |--MATERIALIZE (subquery-xxxxxx) | `--COMPOUND QUERY | |--LEFT-MOST SUBQUERY | | `--SCAN CONSTANT ROW | `--UNION USING TEMP B-TREE | `--SCAN CONSTANT ROW - |--SCAN SUBQUERY xxxxxx + |--SCAN (subquery-xxxxxx) `--SCAN t3 } do_eqp_test 1.9 { @@ -282,10 +282,10 @@ det 3.2.1 { SELECT * FROM (SELECT * FROM t1 ORDER BY x LIMIT 10) ORDER BY y LIMIT 5 } { QUERY PLAN - |--CO-ROUTINE SUBQUERY xxxxxx + |--CO-ROUTINE (subquery-xxxxxx) | |--SCAN t1 | `--USE TEMP B-TREE FOR ORDER BY - |--SCAN SUBQUERY xxxxxx + |--SCAN (subquery-xxxxxx) `--USE TEMP B-TREE FOR ORDER BY } det 3.2.2 { diff --git a/test/select1.test b/test/select1.test index e22907da1e..44e63d252d 100644 --- a/test/select1.test +++ b/test/select1.test @@ -545,14 +545,14 @@ do_test select1-6.9.7 { set x [execsql2 { SELECT * FROM test1 a, (select 5, 6) LIMIT 1 }] - regsub -all {subquery_[0-9a-fA-F_]+} $x {subquery} x + regsub -all {subquery-\d+} $x {subquery-0} x set x -} {a.f1 11 a.f2 22 subquery.5 5 subquery.6 6} +} {a.f1 11 a.f2 22 (subquery-0).5 5 (subquery-0).6 6} do_test select1-6.9.8 { set x [execsql2 { SELECT * FROM test1 a, (select 5 AS x, 6 AS y) AS b LIMIT 1 }] - regsub -all {subquery_[0-9a-fA-F]+_} $x {subquery} x + regsub -all {subquery-\d+} $x {subquery-0} x set x } {a.f1 11 a.f2 22 b.x 5 b.y 6} do_test select1-6.9.9 { diff --git a/test/tester.tcl b/test/tester.tcl index bfcc831ff9..9d29fdb8df 100644 --- a/test/tester.tcl +++ b/test/tester.tcl @@ -1011,6 +1011,7 @@ proc query_plan_graph {sql} { append a [append_graph " " dx cx 0] regsub -all { 0x[A-F0-9]+\y} $a { xxxxxx} a regsub -all {(MATERIALIZE|CO-ROUTINE|SUBQUERY) \d+\y} $a {\1 xxxxxx} a + regsub -all {\((join|subquery)-\d+\)} $a {(\1-xxxxxx)} a return $a } From d6bb6000eff360f76d736d13331816354d880c5f Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 22 Apr 2022 18:07:38 +0000 Subject: [PATCH 206/259] Make use of the "%!S" format when running ExplainSubquery. FossilOrigin-Name: 9425d79cb407dedc259655625369e023d22a04ef7db606ea3eefe7e4d662be1a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 4 +--- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 89136d4a97..074c0369fa 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\sEXPLAIN\sQUERY\sPLAN\soutput\sand\scomments\son\sbytecode\slistings\sby\ndistinguishing\sbetween\s"subquery"\sand\s"join"\sand\susing\sconsistent\snames\nacross\sEQP\sand\sbytecode. -D 2022-04-22T17:36:10.121 +C Make\suse\sof\sthe\s"%!S"\sformat\swhen\srunning\sExplainSubquery. +D 2022-04-22T18:07:38.628 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -553,7 +553,7 @@ F src/printf.c 512574910a45341c8ad244bd3d4939968ebdfde215645b676fff01cc46e90757 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c f72bb13359dd5a74d440df25f320dc2c1baff5cde4fc9f0d1bc3feba90b8932a F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 7b641cd9ca37e4ed75e0aadfbc56baed9a2b94b6ba5fdf59d3d852b6156b0c61 +F src/select.c 92b3b250434de59fb87462dcdad79b456ae8ec82ae3194d4081ecb5af41ff0ec F src/shell.c.in ae0a6fae983caac6f8c824733f0599dfdf7b3a7e8efdef3cb5e3ab2e457ffc35 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1951,8 +1951,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 8d631a6b9eb06b54b10eda595a4c588ca38f909b4afa653b24d1f720b55d72f7 -R ac14f314793152059b0e1f854dbd012a +P a2d3ee92420ec564e31eb0005367cf7ff3d00bfaed5a98ffdbe17c91c95d9d97 +R d5faff9166fcd6ed79adddef328785e0 U drh -Z d4ba1bca8076431eba8e72fffafad1d9 +Z 718ee8ac0193a5ad27bc2f01dffb0763 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 13b574d647..dccfc73dae 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a2d3ee92420ec564e31eb0005367cf7ff3d00bfaed5a98ffdbe17c91c95d9d97 \ No newline at end of file +9425d79cb407dedc259655625369e023d22a04ef7db606ea3eefe7e4d662be1a \ No newline at end of file diff --git a/src/select.c b/src/select.c index 5f2465da0d..5e90781eff 100644 --- a/src/select.c +++ b/src/select.c @@ -5555,10 +5555,8 @@ int sqlite3ExpandSubquery(Parse *pParse, SrcItem *pFrom){ pTab->nTabRef = 1; if( pFrom->zAlias ){ pTab->zName = sqlite3DbStrDup(pParse->db, pFrom->zAlias); - }else if( pSel->selFlags & SF_NestedFrom ){ - pTab->zName = sqlite3MPrintf(pParse->db, "(join-%u)", pSel->selId); }else{ - pTab->zName = sqlite3MPrintf(pParse->db, "(subquery-%u)", pSel->selId); + pTab->zName = sqlite3MPrintf(pParse->db, "%!S", pFrom); } while( pSel->pPrior ){ pSel = pSel->pPrior; } sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol); From 45e41b7371e60c75356a5037f2ddd91261674967 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 22 Apr 2022 23:18:21 +0000 Subject: [PATCH 207/259] Add the ability to access the USING columns of the right or left tables of an OUTER JOIN even if the OUTER JOIN is in parentheses. Prototype code only. FossilOrigin-Name: c3a427575fe71de3061495059e253c72c7213e2925ee2873e4f59fc73bfae103 --- manifest | 21 ++++++++++++--------- manifest.uuid | 2 +- src/resolve.c | 1 + src/select.c | 34 +++++++++++++++++++++++++++++----- src/sqliteInt.h | 5 +++-- src/treeview.c | 3 ++- 6 files changed, 48 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 7a1705b659..2b8997de82 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\slatest\senhancements\sand\sfixes\sfrom\strunk\sonto\sthe\sright-join\sbranch. -D 2022-04-22T19:52:51.602 +C Add\sthe\sability\sto\saccess\sthe\sUSING\scolumns\sof\sthe\sright\sor\sleft\stables\nof\san\sOUTER\sJOIN\seven\sif\sthe\sOUTER\sJOIN\sis\sin\sparentheses.\s\sPrototype\scode\nonly. +D 2022-04-22T23:18:21.655 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -551,14 +551,14 @@ F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c fd940149c691684e7c1073c3787a7170e44852b02d1275d2e30a5b58e89cfcaf F src/printf.c 512574910a45341c8ad244bd3d4939968ebdfde215645b676fff01cc46e90757 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c -F src/resolve.c f72bb13359dd5a74d440df25f320dc2c1baff5cde4fc9f0d1bc3feba90b8932a +F src/resolve.c b14bf8a4a1e3cb01eefc48a7e4129b15bb6a18b56d16dd4eca676586464337d0 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 92b3b250434de59fb87462dcdad79b456ae8ec82ae3194d4081ecb5af41ff0ec +F src/select.c 18c2b25560e70da88d9283f96dafab28d4e584caf594df3a838bd993931a6657 F src/shell.c.in ae0a6fae983caac6f8c824733f0599dfdf7b3a7e8efdef3cb5e3ab2e457ffc35 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h 36b5d1cce15971fa71b53a950de3158197d85dbaf9b8b2f0bc6279347b09606a +F src/sqliteInt.h 6b76dd4bb8be4c8291f1ae79957b1ff89e0719b763ff015f2a11e7320ce364bf F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -618,7 +618,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98 -F src/treeview.c 396c21e21c853ebc1830c194fa13f1161dbc76adad0b0a605172ddb78b3b4cdb +F src/treeview.c 2fb6681614cfdf44c5df1a54a8d17c1fe31c2dbb226db99df8693dbd8c02f598 F src/trigger.c 372ada38f667c6823a3db15749eb668338e65c793394e55a37e56a489f2d1b55 F src/update.c 2cfaded82ca80ff56afb8c3ae5e88284e0824bfd86119827cc22481959f96f92 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 @@ -1951,8 +1951,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d942530a6550a0cbe31790e462b0f0d57b9b4a896161878b7d45d11cbc1cb7a3 9425d79cb407dedc259655625369e023d22a04ef7db606ea3eefe7e4d662be1a -R d5faff9166fcd6ed79adddef328785e0 +P 7f8983345d1e3ac28d736fce9f90772aa0e4654670a1db3dd0ee45b55e92f2e4 +R 1d384d62b00b1e8c4deeb5fe7e6e8acf +T *branch * right-join-colnames +T *sym-right-join-colnames * +T -sym-right-join * U drh -Z c29aa10c7d94195b4cb355a78538b541 +Z 2aa54e030eb9cab6d3b9ad83195a5d2e # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 440e936519..9e243718d4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7f8983345d1e3ac28d736fce9f90772aa0e4654670a1db3dd0ee45b55e92f2e4 \ No newline at end of file +c3a427575fe71de3061495059e253c72c7213e2925ee2873e4f59fc73bfae103 \ No newline at end of file diff --git a/src/resolve.c b/src/resolve.c index e9cfe9d9f1..7f99152cbb 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -361,6 +361,7 @@ static int lookupName( pExpr->iColumn = j; pEList->a[j].bUsed = 1; hit = 1; + if( pEList->a[j].bUsingTerm ) break; } if( hit || zTab==0 ) continue; } diff --git a/src/select.c b/src/select.c index 5e90781eff..63b22cf35f 100644 --- a/src/select.c +++ b/src/select.c @@ -2180,6 +2180,7 @@ int sqlite3ColumnsFromExprList( for(i=0, pCol=aCol; imallocFailed; i++, pCol++){ struct ExprList_item *pX = &pEList->a[i]; + struct ExprList_item *pCollide; /* Get an appropriate name for the column */ if( (zName = pX->zEName)!=0 && pX->eEName==ENAME_NAME ){ @@ -2216,7 +2217,10 @@ int sqlite3ColumnsFromExprList( ** append an integer to the name so that it becomes unique. */ cnt = 0; - while( zName && sqlite3HashFind(&ht, zName)!=0 ){ + while( zName && (pCollide = sqlite3HashFind(&ht, zName))!=0 ){ + if( pCollide->bUsingTerm ){ + pCol->colFlags |= COLFLAG_HIDDEN; + } nName = sqlite3Strlen30(zName); if( nName>0 ){ for(j=nName-1; j>0 && sqlite3Isdigit(zName[j]); j--){} @@ -2228,7 +2232,7 @@ int sqlite3ColumnsFromExprList( pCol->zCnName = zName; pCol->hName = sqlite3StrIHash(zName); sqlite3ColumnPropertiesFromName(0, pCol); - if( zName && sqlite3HashInsert(&ht, zName, pCol)==pCol ){ + if( zName && sqlite3HashInsert(&ht, zName, pX)==pX ){ sqlite3OomFault(db); } } @@ -5833,6 +5837,25 @@ static int selectExpander(Walker *pWalker, Select *p){ iDb = sqlite3SchemaToIndex(db, pTab->pSchema); zSchemaName = iDb>=0 ? db->aDb[iDb].zDbSName : "*"; } + if( i+1nSrc + && pFrom[1].fg.isUsing + && (selFlags & SF_NestedFrom)!=0 + ){ + int ii; + IdList *pUsing = pFrom[1].u3.pUsing; + for(ii=0; iinId; ii++){ + const char *zUName = pUsing->a[ii].zName; + pRight = sqlite3Expr(db, TK_ID, zUName); + pNew = sqlite3ExprListAppend(pParse, pNew, pRight); + if( pNew ){ + struct ExprList_item *pX = &pNew->a[pNew->nExpr-1]; + assert( pX->zEName==0 ); + pX->zEName = sqlite3MPrintf(db,"..%s", zUName); + pX->eEName = ENAME_TAB; + pX->bUsingTerm = 1; + } + } + } for(j=0; jnCol; j++){ char *zName = pTab->aCol[j].zCnName; struct ExprList_item *pX; /* Newly added ExprList term */ @@ -5849,14 +5872,14 @@ static int selectExpander(Walker *pWalker, Select *p){ ** result-set list unless the SELECT has the SF_IncludeHidden ** bit set. */ - if( (p->selFlags & SF_IncludeHidden)==0 - && IsHiddenColumn(&pTab->aCol[j]) + if( (selFlags & SF_IncludeHidden)==0 + && IsHiddenColumn(&pTab->aCol[j]) && zTName==0 ){ continue; } tableSeen = 1; - if( i>0 && zTName==0 ){ + if( i>0 && zTName==0 && (selFlags & SF_NestedFrom)==0 ){ if( pFrom->fg.isUsing && sqlite3IdListIndex(pFrom->u3.pUsing, zName)>=0 ){ @@ -5868,6 +5891,7 @@ static int selectExpander(Walker *pWalker, Select *p){ pRight = sqlite3Expr(db, TK_ID, zName); if( (pTabList->nSrc>1 && ( (pFrom->fg.jointype & JT_LTORJ)==0 + || (selFlags && SF_NestedFrom)!=0 || !inAnyUsingClause(zName,pFrom,pTabList->nSrc-i-1) ) ) diff --git a/src/sqliteInt.h b/src/sqliteInt.h index ec465cdb33..589a162a56 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3003,8 +3003,9 @@ struct ExprList { unsigned done :1; /* A flag to indicate when processing is finished */ unsigned reusable :1; /* Constant expression is reusable */ unsigned bSorterRef :1; /* Defer evaluation until after sorting */ - unsigned bNulls: 1; /* True if explicit "NULLS FIRST/LAST" */ - unsigned bUsed: 1; /* This column used in a SF_NestedFrom subquery */ + unsigned bNulls :1; /* True if explicit "NULLS FIRST/LAST" */ + unsigned bUsed :1; /* This column used in a SF_NestedFrom subquery */ + unsigned bUsingTerm:1; /* Term from the USING clause */ union { struct { /* Used by any ExprList other than Parse.pConsExpr */ u16 iOrderByCol; /* For ORDER BY, column number in result set */ diff --git a/src/treeview.c b/src/treeview.c index db73943f02..117e21f1af 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -810,7 +810,8 @@ void sqlite3TreeViewBareExprList( break; case ENAME_TAB: fprintf(stdout, "TABLE-ALIAS-NAME(\"%s\") ", zName); - if( pList->a[i].bUsed==0 ) fprintf(stdout, "(unused) "); + if( pList->a[i].bUsed ) fprintf(stdout, "(used) "); + if( pList->a[i].bUsingTerm ) fprintf(stdout, "(USING-term) "); break; case ENAME_SPAN: fprintf(stdout, "SPAN(\"%s\") ", zName); From ab843a51d3513508d805602a530f2fd2761aed71 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 23 Apr 2022 07:29:34 +0000 Subject: [PATCH 208/259] Fix minor problems with the new join table name resolution logic. FossilOrigin-Name: 3a6b0db4519072dbd41b1c105bf1a0c6b4dd90380e94a5662645d8d41483c707 --- manifest | 19 ++++++++----------- manifest.uuid | 2 +- src/expr.c | 1 + src/select.c | 17 ++++++++++++----- src/sqliteInt.h | 3 ++- 5 files changed, 24 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 2b8997de82..3cfaf242e9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sability\sto\saccess\sthe\sUSING\scolumns\sof\sthe\sright\sor\sleft\stables\nof\san\sOUTER\sJOIN\seven\sif\sthe\sOUTER\sJOIN\sis\sin\sparentheses.\s\sPrototype\scode\nonly. -D 2022-04-22T23:18:21.655 +C Fix\sminor\sproblems\swith\sthe\snew\sjoin\stable\sname\sresolution\slogic. +D 2022-04-23T07:29:34.810 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -504,7 +504,7 @@ F src/date.c 15082566229d4b1e5f24fdb490bf9bcc68824b911d70e3573ef075a1b9e2d26f F src/dbpage.c 90661a87e1db8bfbc8d2ebbdcd3749651ddb287c555c07a28fb17c7c591ffb68 F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d F src/delete.c a8e844af211a48b13b5b358be77a12c860c6a557c21990ad51a548e2536500ce -F src/expr.c 06dfbfb7f469c00eba3c8a7e282765969fe7c772f235a365f51bfffcaa69fe7f +F src/expr.c 6763de6e372ae113f4a079c5c155956ab18470d52c144ccf3ecb9d3df0704a4a F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c d965ede15d8360c09ed59348940649ee647b192e784466837d7aefa836d1d91e F src/func.c a3407a6fbb0d4088d8d502e46f0ace63e0aeae7467ae23a9ca9815bbf9239761 @@ -553,12 +553,12 @@ F src/printf.c 512574910a45341c8ad244bd3d4939968ebdfde215645b676fff01cc46e90757 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c b14bf8a4a1e3cb01eefc48a7e4129b15bb6a18b56d16dd4eca676586464337d0 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 18c2b25560e70da88d9283f96dafab28d4e584caf594df3a838bd993931a6657 +F src/select.c 3b3f8d2c51d6026bfbe26d8762f1844b995aa64d238100ffc86a04727fba134b F src/shell.c.in ae0a6fae983caac6f8c824733f0599dfdf7b3a7e8efdef3cb5e3ab2e457ffc35 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h 6b76dd4bb8be4c8291f1ae79957b1ff89e0719b763ff015f2a11e7320ce364bf +F src/sqliteInt.h 1805e812191a7b38bfcc3a05e532603b39764191231dc41b1ea29973b7f82743 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -1951,11 +1951,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 7f8983345d1e3ac28d736fce9f90772aa0e4654670a1db3dd0ee45b55e92f2e4 -R 1d384d62b00b1e8c4deeb5fe7e6e8acf -T *branch * right-join-colnames -T *sym-right-join-colnames * -T -sym-right-join * +P c3a427575fe71de3061495059e253c72c7213e2925ee2873e4f59fc73bfae103 +R 927028067d4c4ec54024cdb064902dd9 U drh -Z 2aa54e030eb9cab6d3b9ad83195a5d2e +Z 67d139aeb225244d863b58d002516737 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9e243718d4..47a744d138 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c3a427575fe71de3061495059e253c72c7213e2925ee2873e4f59fc73bfae103 \ No newline at end of file +3a6b0db4519072dbd41b1c105bf1a0c6b4dd90380e94a5662645d8d41483c707 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 1709876219..f532bba2eb 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1633,6 +1633,7 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, const ExprList *p, int flags){ pItem->done = 0; pItem->bNulls = pOldItem->bNulls; pItem->bUsed = pOldItem->bUsed; + pItem->bUsingTerm = pOldItem->bUsingTerm; pItem->bSorterRef = pOldItem->bSorterRef; pItem->u = pOldItem->u; } diff --git a/src/select.c b/src/select.c index 63b22cf35f..1211f268ae 100644 --- a/src/select.c +++ b/src/select.c @@ -2219,7 +2219,7 @@ int sqlite3ColumnsFromExprList( cnt = 0; while( zName && (pCollide = sqlite3HashFind(&ht, zName))!=0 ){ if( pCollide->bUsingTerm ){ - pCol->colFlags |= COLFLAG_HIDDEN; + pCol->colFlags |= COLFLAG_NOEXPAND; } nName = sqlite3Strlen30(zName); if( nName>0 ){ @@ -5872,10 +5872,17 @@ static int selectExpander(Walker *pWalker, Select *p){ ** result-set list unless the SELECT has the SF_IncludeHidden ** bit set. */ - if( (selFlags & SF_IncludeHidden)==0 - && IsHiddenColumn(&pTab->aCol[j]) && zTName==0 - ){ - continue; + if( pTab->aCol[j].colFlags & (COLFLAG_HIDDEN|COLFLAG_NOEXPAND) ){ + if( IsHiddenColumn(&pTab->aCol[j]) + && (selFlags & SF_IncludeHidden)==0 + ){ + continue; + } + if( (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)!=0 + && zTName==0 + ){ + continue; + } } tableSeen = 1; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 589a162a56..d9f5bc42ea 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2125,6 +2125,7 @@ struct Column { #define COLFLAG_NOTAVAIL 0x0080 /* STORED column not yet calculated */ #define COLFLAG_BUSY 0x0100 /* Blocks recursion on GENERATED columns */ #define COLFLAG_HASCOLL 0x0200 /* Has collating sequence name in zCnName */ +#define COLFLAG_NOEXPAND 0x0400 /* Omit this column when expanding "*" */ #define COLFLAG_GENERATED 0x0060 /* Combo: _STORED, _VIRTUAL */ #define COLFLAG_NOINSERT 0x0062 /* Combo: _HIDDEN, _STORED, _VIRTUAL */ @@ -3005,7 +3006,7 @@ struct ExprList { unsigned bSorterRef :1; /* Defer evaluation until after sorting */ unsigned bNulls :1; /* True if explicit "NULLS FIRST/LAST" */ unsigned bUsed :1; /* This column used in a SF_NestedFrom subquery */ - unsigned bUsingTerm:1; /* Term from the USING clause */ + unsigned bUsingTerm:1; /* Term from the USING clause of a NestedFrom */ union { struct { /* Used by any ExprList other than Parse.pConsExpr */ u16 iOrderByCol; /* For ORDER BY, column number in result set */ From d63c07e6c58d9c54346f1d7e0b48652991161f79 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 23 Apr 2022 14:30:22 +0000 Subject: [PATCH 209/259] Fix an operator typo - This indicates that the branch needs further investigation and verification. FossilOrigin-Name: f6ab67965b718b0c6d7faf769c7e47384cfd2ddbb03df518e0c5d367f8583387 --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/select.c | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 9853fc86d3..de9f757790 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Correctly\sresolve\sleft\sand\sright\sUSING\scolumns\sof\san\souter\sjoin\sin\sa\nparenthesized\ssubjoin. -D 2022-04-23T07:31:50.739 +C Fix\san\soperator\stypo\s-\sThis\sindicates\sthat\sthe\sbranch\sneeds\sfurther\ninvestigation\sand\sverification. +D 2022-04-23T14:30:22.661 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -553,7 +553,7 @@ F src/printf.c 512574910a45341c8ad244bd3d4939968ebdfde215645b676fff01cc46e90757 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c b14bf8a4a1e3cb01eefc48a7e4129b15bb6a18b56d16dd4eca676586464337d0 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 3b3f8d2c51d6026bfbe26d8762f1844b995aa64d238100ffc86a04727fba134b +F src/select.c 7236f3c4c1c27bd348dca60c746b1d48354c36d59223c673400c2115b871785e F src/shell.c.in ae0a6fae983caac6f8c824733f0599dfdf7b3a7e8efdef3cb5e3ab2e457ffc35 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1951,9 +1951,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 7f8983345d1e3ac28d736fce9f90772aa0e4654670a1db3dd0ee45b55e92f2e4 3a6b0db4519072dbd41b1c105bf1a0c6b4dd90380e94a5662645d8d41483c707 -R 927028067d4c4ec54024cdb064902dd9 -T +closed 3a6b0db4519072dbd41b1c105bf1a0c6b4dd90380e94a5662645d8d41483c707 +P ea91aba88c31a042f4e32d66dfa089f95d0f9d316ab26f298085eb34dbf73e86 +R 9549b2a87feb210cf9948c9189de46e6 U drh -Z 2bcffb18ae205ac6850b1eb45df4f967 +Z 18a2689e41cce135eac2a900bbfdf7c7 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 616ff463ee..3ea4478a45 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ea91aba88c31a042f4e32d66dfa089f95d0f9d316ab26f298085eb34dbf73e86 \ No newline at end of file +f6ab67965b718b0c6d7faf769c7e47384cfd2ddbb03df518e0c5d367f8583387 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 1211f268ae..df4ad43956 100644 --- a/src/select.c +++ b/src/select.c @@ -5898,7 +5898,7 @@ static int selectExpander(Walker *pWalker, Select *p){ pRight = sqlite3Expr(db, TK_ID, zName); if( (pTabList->nSrc>1 && ( (pFrom->fg.jointype & JT_LTORJ)==0 - || (selFlags && SF_NestedFrom)!=0 + || (selFlags & SF_NestedFrom)!=0 || !inAnyUsingClause(zName,pFrom,pTabList->nSrc-i-1) ) ) From b77c31295687dd33cc4b8955d29cd0b26fbae6a3 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 23 Apr 2022 18:04:31 +0000 Subject: [PATCH 210/259] For debug builds, if the RIGHT JOIN body subroutine contains a jump that escapes the subroutine, then abort the prepared statement with a descriptive error and SQLITE_INTERNAL. This extra sanity check causes many tests to fail. FossilOrigin-Name: 2c5bb2bff26cc70d8cac78ddd12d5ac37ab1472f5f88afbd975950a18ac2804d --- manifest | 23 +++++++------ manifest.uuid | 2 +- src/vdbe.h | 2 ++ src/vdbeaux.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++ src/where.c | 1 + src/whereInt.h | 1 + src/wherecode.c | 2 ++ 7 files changed, 112 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 074c0369fa..80f614183c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\suse\sof\sthe\s"%!S"\sformat\swhen\srunning\sExplainSubquery. -D 2022-04-22T18:07:38.628 +C For\sdebug\sbuilds,\sif\sthe\sRIGHT\sJOIN\sbody\ssubroutine\scontains\sa\sjump\sthat\nescapes\sthe\ssubroutine,\sthen\sabort\sthe\sprepared\sstatement\swith\sa\sdescriptive\nerror\sand\sSQLITE_INTERNAL.\s\sThis\sextra\ssanity\scheck\scauses\smany\stests\sto\nfail. +D 2022-04-23T18:04:31.226 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -626,10 +626,10 @@ F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 F src/vdbe.c 9527ab7f71c5b0291e5ed7727f213f4d7f6e0a82af019da5b365fd5a0f56bb96 -F src/vdbe.h 89f5edb1422c8783a0b29db836e409876f2b3e847f78e2b21b1fbcc48a93f85f +F src/vdbe.h 07641758ca8b4f4c6d81ea667ea167c541e6ece21f5574da11e3d21ec37e2662 F src/vdbeInt.h ef43f7fdc5fde29fc3fd29c506c12830f366178fdb4edbbf0cbc3dfbd1278b5f F src/vdbeapi.c 354c893f1500cf524cc45c32879b9c68893a28b77e3442c24668d6afe4236217 -F src/vdbeaux.c d1fce1d9c1045622d2a878ddcbec1c431eb186a17674b64ffe231e8d14db0451 +F src/vdbeaux.c 8bc10fd6c306ac7e86ea2419f7729886efc0957afa17597b551d5a20f862272e F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 7189090b72baa025f945a1ac8c61ee420c645254476e8a191d555db76dfea5d4 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 @@ -640,9 +640,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c 45102d682f6efd450d89c0c5f09b838be6d69c84c6105336730ee38d3b452fad -F src/whereInt.h eecce79edc6f7005f91f35be6b18b7053f794e1b50e95bcd06a2d537fc176734 -F src/wherecode.c 1bff158d8672524d0e9a398b01a8ed2d98fffb9ae38837a8335c7162500a1d8f +F src/where.c 4f3c9fe1d07f1a865969aed4fff732ef5e86a674c6ff027f2728d3fa307900ef +F src/whereInt.h 4db5a877a9d1f38b5c928c1c84297c07f30b9a3bc1f5f66214cf1a8ef90a0556 +F src/wherecode.c 55a33d9db1759970c30220904bcc628ba66a1ccb63b5437ef4642f7ea6267b03 F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 F src/window.c 924e04fd6e0e113d4dba18b78d43fcb8e42b8ebffc8fc728da52cf3ab014cf3c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1951,8 +1951,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a2d3ee92420ec564e31eb0005367cf7ff3d00bfaed5a98ffdbe17c91c95d9d97 -R d5faff9166fcd6ed79adddef328785e0 +P 9425d79cb407dedc259655625369e023d22a04ef7db606ea3eefe7e4d662be1a +R 8428b3472cd00a82f3a0cce7bac1b298 +T *branch * right-join-subrtn-check +T *sym-right-join-subrtn-check * +T -sym-trunk * U drh -Z 718ee8ac0193a5ad27bc2f01dffb0763 +Z cbfc5874b147218fb2a4bd50574bf5b9 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index dccfc73dae..1d427477e5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9425d79cb407dedc259655625369e023d22a04ef7db606ea3eefe7e4d662be1a \ No newline at end of file +2c5bb2bff26cc70d8cac78ddd12d5ac37ab1472f5f88afbd975950a18ac2804d \ No newline at end of file diff --git a/src/vdbe.h b/src/vdbe.h index e251dd666e..5909d3995d 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -198,8 +198,10 @@ void sqlite3VdbeEndCoroutine(Vdbe*,int); #endif #if defined(SQLITE_DEBUG) void sqlite3VdbeVerifyAbortable(Vdbe *p, int); + void sqlite3VdbeNoJumpsOutsideSubrtn(Vdbe*,int,int,int); #else # define sqlite3VdbeVerifyAbortable(A,B) +# define sqlite3VdbeNoJumpsOutsideSubrtn(A,B,C,D) #endif VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp,int iLineno); #ifndef SQLITE_OMIT_EXPLAIN diff --git a/src/vdbeaux.c b/src/vdbeaux.c index eaf5780ab1..3569fa994c 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -880,6 +880,98 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ assert( p->bIsReader!=0 || DbMaskAllZero(p->btreeMask) ); } +#ifdef SQLITE_DEBUG +/* +** Check to see if a subroutine contains a jump to a location outside of +** the subroutine. If a jump outside the subroutine is detected, add code +** that will cause the program to halt with an error message. +** +** The subroutine consists of opcodes between iFirst and iLast. Jumps to +** locations within the subroutine are acceptable. iRetReg is a register +** that contains the return address. Jumps to outside the range of iFirst +** through iLast are also acceptable as long as the jump destination is +** an OP_Return to iReturnAddr. +** +** A jump to an unresolved label is considered to be a jump outside of the +** subroutine. +** +** This routine only runs during debug builds. The purpose is (of course) +** to detect invalid escapes out of a subroutine. The OP_Halt opcode +** is generated rather than an assert() or other error, so that ".eqp full" +** will still work to show the original bytecode, to aid in debugging. +*/ +void sqlite3VdbeNoJumpsOutsideSubrtn( + Vdbe *v, /* The byte-code program under construction */ + int iFirst, /* First opcode of the subroutine */ + int iLast, /* Last opcode of the subroutine */ + int iRetReg /* Subroutine return address register */ +){ + VdbeOp *pOp; + Parse *pParse; + int i; + sqlite3_str *pErr = 0; + assert( v!=0 ); + pParse = v->pParse; + assert( pParse!=0 ); + if( pParse->nErr ) return; + assert( iLast>=iFirst ); + assert( iLastnOp ); + pOp = &v->aOp[iFirst]; + for(i=iFirst; i<=iLast; i++, pOp++){ + if( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 ){ + int iDest = pOp->p2; /* Jump destination */ + if( iDest==0 ) continue; + if( iDest<0 ){ + int j = ADDR(iDest); + assert( j>=0 ); + if( j>=-pParse->nLabel || pParse->aLabel[j]<0 ){ + if( pErr==0 ){ + pErr = sqlite3_str_new(0); + }else{ + sqlite3_str_appendchar(pErr, 1, '\n'); + } + sqlite3_str_appendf(pErr, + "Opcode at %d within the " + "subroutine at %d..%d jumps to an unresolved " + "address (%d)\n", + i, iFirst, iLast, iDest); + continue; + } + iDest = pParse->aLabel[j]; + } + if( iDestiLast ){ + int j = iDest; + for(; jnOp; j++){ + VdbeOp *pX = &v->aOp[j]; + if( pX->opcode==OP_Return ){ + if( pX->p1==iRetReg ) break; + continue; + } + if( pX->opcode==OP_Noop ) continue; + if( pX->opcode==OP_Explain ) continue; + if( pErr==0 ){ + pErr = sqlite3_str_new(0); + }else{ + sqlite3_str_appendchar(pErr, 1, '\n'); + } + sqlite3_str_appendf(pErr, + "Opcode at %d jumps to %d which is outside the " + "subroutine at %d..%d", + i, iDest, iFirst, iLast); + break; + } + } + } + } + if( pErr ){ + char *zErr = sqlite3_str_finish(pErr); + sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_INTERNAL, OE_Abort, 0, zErr, 0); + sqlite3_free(zErr); + sqlite3MayAbort(pParse); + } +} +#endif /* SQLITE_DEBUG */ + /* ** Return the address of the next instruction to be inserted. */ diff --git a/src/where.c b/src/where.c index 8526f7c5ab..a724419324 100644 --- a/src/where.c +++ b/src/where.c @@ -6024,6 +6024,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ WhereRightJoin *pRJ = pLevel->pRJ; sqlite3VdbeResolveLabel(v, pLevel->addrCont); pLevel->addrCont = 0; + pRJ->endSubrtn = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp3(v, OP_Return, pRJ->regReturn, pRJ->addrSubrtn, 1); VdbeCoverage(v); assert( pParse->withinRJSubrtn>0 ); diff --git a/src/whereInt.h b/src/whereInt.h index acc9ec3ddd..93ab937c88 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -52,6 +52,7 @@ struct WhereRightJoin { int regBloom; /* Bloom filter for iRJMatch */ int regReturn; /* Return register for the interior subroutine */ int addrSubrtn; /* Starting address for the interior subroutine */ + int endSubrtn; /* The last opcode in the interior subroutine */ }; /* diff --git a/src/wherecode.c b/src/wherecode.c index 4f525a8fbf..3ea6c5d8eb 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -2819,6 +2819,8 @@ SQLITE_NOINLINE void sqlite3WhereRightJoinLoop( int k; ExplainQueryPlan((pParse, 1, "RIGHT-JOIN %s", pTabItem->pTab->zName)); + sqlite3VdbeNoJumpsOutsideSubrtn(v, pRJ->addrSubrtn, pRJ->endSubrtn, + pRJ->regReturn); for(k=0; ka[k].pWLoop->maskSelf; From 6c7e89b48a3723ca6038a21170354fe3ad690b47 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 23 Apr 2022 18:34:55 +0000 Subject: [PATCH 211/259] Fix false-positives in sqlite3VdbeNoJumpsOutsideSubrtn(). All tests pass now. FossilOrigin-Name: 1300d978d5a072780e0f16722e42461dc983de9b4dfb2f5a7023c74c92ab9bc8 --- manifest | 15 ++++++--------- manifest.uuid | 2 +- src/vdbeaux.c | 16 ++++------------ 3 files changed, 11 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index 80f614183c..44068e70ea 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C For\sdebug\sbuilds,\sif\sthe\sRIGHT\sJOIN\sbody\ssubroutine\scontains\sa\sjump\sthat\nescapes\sthe\ssubroutine,\sthen\sabort\sthe\sprepared\sstatement\swith\sa\sdescriptive\nerror\sand\sSQLITE_INTERNAL.\s\sThis\sextra\ssanity\scheck\scauses\smany\stests\sto\nfail. -D 2022-04-23T18:04:31.226 +C Fix\sfalse-positives\sin\ssqlite3VdbeNoJumpsOutsideSubrtn().\s\sAll\stests\spass\snow. +D 2022-04-23T18:34:55.922 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -629,7 +629,7 @@ F src/vdbe.c 9527ab7f71c5b0291e5ed7727f213f4d7f6e0a82af019da5b365fd5a0f56bb96 F src/vdbe.h 07641758ca8b4f4c6d81ea667ea167c541e6ece21f5574da11e3d21ec37e2662 F src/vdbeInt.h ef43f7fdc5fde29fc3fd29c506c12830f366178fdb4edbbf0cbc3dfbd1278b5f F src/vdbeapi.c 354c893f1500cf524cc45c32879b9c68893a28b77e3442c24668d6afe4236217 -F src/vdbeaux.c 8bc10fd6c306ac7e86ea2419f7729886efc0957afa17597b551d5a20f862272e +F src/vdbeaux.c f406d8d8b461f260aeaa69d265c5d175ff0a9f84d6153c87975cdfbf9d681922 F src/vdbeblob.c 5e61ce31aca17db8fb60395407457a8c1c7fb471dde405e0cd675974611dcfcd F src/vdbemem.c 7189090b72baa025f945a1ac8c61ee420c645254476e8a191d555db76dfea5d4 F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 @@ -1951,11 +1951,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 9425d79cb407dedc259655625369e023d22a04ef7db606ea3eefe7e4d662be1a -R 8428b3472cd00a82f3a0cce7bac1b298 -T *branch * right-join-subrtn-check -T *sym-right-join-subrtn-check * -T -sym-trunk * +P 2c5bb2bff26cc70d8cac78ddd12d5ac37ab1472f5f88afbd975950a18ac2804d +R 1dad547c493f60bf8d226b9a1521fea3 U drh -Z cbfc5874b147218fb2a4bd50574bf5b9 +Z a750b57e12ed48042d97498102c6d29b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 1d427477e5..e9696b34fa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2c5bb2bff26cc70d8cac78ddd12d5ac37ab1472f5f88afbd975950a18ac2804d \ No newline at end of file +1300d978d5a072780e0f16722e42461dc983de9b4dfb2f5a7023c74c92ab9bc8 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 3569fa994c..9e702edcd5 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -892,8 +892,9 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ ** through iLast are also acceptable as long as the jump destination is ** an OP_Return to iReturnAddr. ** -** A jump to an unresolved label is considered to be a jump outside of the -** subroutine. +** A jump to an unresolved label means that the jump destination will be +** beyond the current address. That is normally a jump to an early +** termination and is consider acceptable. ** ** This routine only runs during debug builds. The purpose is (of course) ** to detect invalid escapes out of a subroutine. The OP_Halt opcode @@ -921,20 +922,11 @@ void sqlite3VdbeNoJumpsOutsideSubrtn( if( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 ){ int iDest = pOp->p2; /* Jump destination */ if( iDest==0 ) continue; + if( pOp->opcode==OP_Gosub ) continue; if( iDest<0 ){ int j = ADDR(iDest); assert( j>=0 ); if( j>=-pParse->nLabel || pParse->aLabel[j]<0 ){ - if( pErr==0 ){ - pErr = sqlite3_str_new(0); - }else{ - sqlite3_str_appendchar(pErr, 1, '\n'); - } - sqlite3_str_appendf(pErr, - "Opcode at %d within the " - "subroutine at %d..%d jumps to an unresolved " - "address (%d)\n", - i, iFirst, iLast, iDest); continue; } iDest = pParse->aLabel[j]; From ecb386b71fcb72afe5ee133e17ea6b540017f3ca Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 23 Apr 2022 19:21:47 +0000 Subject: [PATCH 212/259] Prevent the ORDER BY LIMIT optimization from running if the innermost loop is a right-join, as doing so will get an incorrect answer. FossilOrigin-Name: 3aefc874d31885c64a5e02868edb2aa56a2b4429252d494e67e4088a9298ce5b --- manifest | 15 +++++++-------- manifest.uuid | 2 +- src/where.c | 2 +- test/join8.test | 14 ++++++++++++++ 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 4bfdfd2706..1ca4bb0e33 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sdebug\sbuilds,\sadd\sextra\scode\sto\sverify\sthat\sthere\sare\sno\sjumps\sthat\stry\sto\nescape\sfrom\sthe\sright-join\sbody\ssubroutine. -D 2022-04-23T18:46:03.942 +C Prevent\sthe\sORDER\sBY\sLIMIT\soptimization\sfrom\srunning\sif\sthe\sinnermost\sloop\nis\sa\sright-join,\sas\sdoing\sso\swill\sget\san\sincorrect\sanswer. +D 2022-04-23T19:21:47.563 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -640,7 +640,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c 4f3c9fe1d07f1a865969aed4fff732ef5e86a674c6ff027f2728d3fa307900ef +F src/where.c bd4895fbb6ac9cc5b772d191b93dd5a240a505e3113be9aee0dc8c957568dd41 F src/whereInt.h 4db5a877a9d1f38b5c928c1c84297c07f30b9a3bc1f5f66214cf1a8ef90a0556 F src/wherecode.c 55a33d9db1759970c30220904bcc628ba66a1ccb63b5437ef4642f7ea6267b03 F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 @@ -1148,7 +1148,7 @@ F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test c4df54e2e204d7f1417bfbdd21ca324b4b07415c647595cc47798eacfddc96d3 F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c F test/join7.test 8e72de4b45e5e930d18c305c7efe86015fb2552731e4e03ea226353036b0dab0 -F test/join8.test fdab1aef8bebced45b3664c869a43dc3eeff658e98d183edf513b262369703f6 +F test/join8.test 8b1cc9592aa8f623fc2878353b16c81257591908de06d2a4916f7cbe3ca75ecd F test/join9.test 9056ddd3b0c0f4f9d658f4521038d9a37dc23ead8ca9a505d0b0db2b6a471e05 F test/joinA.test 7eab225dc1c1ab258a5e62513a4ed7cabbd3db971d59d5d92f4fb6fa14c12f6a F test/joinB.test 1b2ba3fc8568b49411787fccbf540570c148e9b6a53a30f80691cb6268098ded @@ -1951,9 +1951,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 9425d79cb407dedc259655625369e023d22a04ef7db606ea3eefe7e4d662be1a 1300d978d5a072780e0f16722e42461dc983de9b4dfb2f5a7023c74c92ab9bc8 -R 1dad547c493f60bf8d226b9a1521fea3 -T +closed 1300d978d5a072780e0f16722e42461dc983de9b4dfb2f5a7023c74c92ab9bc8 +P 45fe919266ba1843f3eeeb511ab43126069d4976c9fc64e57e0390c21f110b6e +R 0a0603ff6c95cefd37960887000d010b U drh -Z 840001b9eea636947972bab8a7341c16 +Z d51b97788760f2ddfc9cd009c0f034c0 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b9abdd3868..5f63056501 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -45fe919266ba1843f3eeeb511ab43126069d4976c9fc64e57e0390c21f110b6e \ No newline at end of file +3aefc874d31885c64a5e02868edb2aa56a2b4429252d494e67e4088a9298ce5b \ No newline at end of file diff --git a/src/where.c b/src/where.c index a724419324..d6c023941c 100644 --- a/src/where.c +++ b/src/where.c @@ -102,7 +102,7 @@ int sqlite3WhereOrderByLimitOptLabel(WhereInfo *pWInfo){ } pInner = &pWInfo->a[pWInfo->nLevel-1]; assert( pInner->addrNxt!=0 ); - return pInner->addrNxt; + return pInner->pRJ ? pWInfo->iContinue : pInner->addrNxt; } /* diff --git a/test/join8.test b/test/join8.test index c23905845b..48287b6bfa 100644 --- a/test/join8.test +++ b/test/join8.test @@ -142,4 +142,18 @@ do_execsql_test join8-4000 { SELECT a FROM t1 NATURAL RIGHT JOIN t1 WHERE a=5555 OR (1,b)==(SELECT 2 IN (2,2),4); } {5555} +# 2022-04-23 dbsqlfuzz c7ee5500e3abddec3557016de777713b80c790d3 +# Escape from the right-join body subroutine via the ORDER BY LIMIT optimization. +# +reset_db +db null - +do_catchsql_test join8-5000 { + CREATE TABLE t1(x); + INSERT INTO t1(x) VALUES(NULL),(NULL); + CREATE TABLE t2(c, d); + INSERT INTO t2(c,d) SELECT x, x FROM t1; + CREATE INDEX t2dc ON t2(d, c); + SELECT (SELECT c FROM sqlite_temp_schema FULL JOIN t2 ON d IN (1,2,3) ORDER BY d) AS x FROM t1; +} {0 {- -}} + finish_test From 1a6bac0d2f9f5730410a72c0f7639873fc7ff452 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 25 Apr 2022 10:43:19 +0000 Subject: [PATCH 213/259] Remove NEVER() on branches formerly thought to unreachable (see check-in [71272caff5874137]) in order to fix the first bug reported by [forum:/forumpost/28821db852|forum post 28821db852]. FossilOrigin-Name: bd6811d8110d5f00596e2eff6d4b02af8b6d8557d41990e6f50518ead0fa01fb --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/build.c | 8 ++------ 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 1ca4bb0e33..8fd0c5d678 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Prevent\sthe\sORDER\sBY\sLIMIT\soptimization\sfrom\srunning\sif\sthe\sinnermost\sloop\nis\sa\sright-join,\sas\sdoing\sso\swill\sget\san\sincorrect\sanswer. -D 2022-04-23T19:21:47.563 +C Remove\sNEVER()\son\sbranches\sformerly\sthought\sto\sunreachable\n(see\scheck-in\s[71272caff5874137])\sin\sorder\sto\sfix\sthe\sfirst\sbug\sreported\nby\s[forum:/forumpost/28821db852|forum\spost\s28821db852]. +D 2022-04-25T10:43:19.387 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -496,7 +496,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c df695e953c2ce78ce4878ee5016751df9bc9a921dc0500a0f53ab3bb3196e505 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482e -F src/build.c 470be339e458a48456cb317ad207ab3cb68ace8b2d76625d2a7eace660fc9674 +F src/build.c 97d466af241420c09ef173a3ffdce01c586b74f61e9442b8c4a2a4fe9bb9110d F src/callback.c 4c19af69835787bfe790ac560f3071a824eb629f34e41f97b52ce5235c77de1c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 026dbdcdbd8c3cde98a88483ee88310ff43150ab164ad768f12cc700a11495ad @@ -1951,8 +1951,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 45fe919266ba1843f3eeeb511ab43126069d4976c9fc64e57e0390c21f110b6e -R 0a0603ff6c95cefd37960887000d010b +P 3aefc874d31885c64a5e02868edb2aa56a2b4429252d494e67e4088a9298ce5b +R 6dba55261ae795532633c33f57ad1712 U drh -Z d51b97788760f2ddfc9cd009c0f034c0 +Z 6c6a697026f7f5ef57340e9f97a907a3 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5f63056501..52cb76b4ed 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3aefc874d31885c64a5e02868edb2aa56a2b4429252d494e67e4088a9298ce5b \ No newline at end of file +bd6811d8110d5f00596e2eff6d4b02af8b6d8557d41990e6f50518ead0fa01fb \ No newline at end of file diff --git a/src/build.c b/src/build.c index 8ae263fc3e..9468944ae1 100644 --- a/src/build.c +++ b/src/build.c @@ -172,9 +172,7 @@ void sqlite3FinishCoding(Parse *pParse){ int i; int reg; - if( NEVER(pReturning->nRetCol==0) ){ - assert( CORRUPT_DB ); - }else{ + if( pReturning->nRetCol ){ sqlite3VdbeAddOp0(v, OP_FkCheck); addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, pReturning->iRetCur); @@ -270,9 +268,7 @@ void sqlite3FinishCoding(Parse *pParse){ if( pParse->bReturning ){ Returning *pRet = pParse->u1.pReturning; - if( NEVER(pRet->nRetCol==0) ){ - assert( CORRUPT_DB ); - }else{ + if( pRet->nRetCol ){ sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRet->iRetCur, pRet->nRetCol); } } From 7f417569f7e8762d62993a14402ae1d14f248e8f Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 25 Apr 2022 14:49:48 +0000 Subject: [PATCH 214/259] Avoid unintended side-effects on Parse.nSelect in the sqlite3ViewGetColumnNames() routine. FossilOrigin-Name: 59789fe1e745bb6f81898176e7e9c6064ac9f4bbefb4dc3c8f3e4c1379568f69 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/build.c | 7 ++++--- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 8fd0c5d678..7a9ad1dd31 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sNEVER()\son\sbranches\sformerly\sthought\sto\sunreachable\n(see\scheck-in\s[71272caff5874137])\sin\sorder\sto\sfix\sthe\sfirst\sbug\sreported\nby\s[forum:/forumpost/28821db852|forum\spost\s28821db852]. -D 2022-04-25T10:43:19.387 +C Avoid\sunintended\sside-effects\son\sParse.nSelect\sin\sthe\nsqlite3ViewGetColumnNames()\sroutine. +D 2022-04-25T14:49:48.098 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -496,7 +496,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c df695e953c2ce78ce4878ee5016751df9bc9a921dc0500a0f53ab3bb3196e505 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482e -F src/build.c 97d466af241420c09ef173a3ffdce01c586b74f61e9442b8c4a2a4fe9bb9110d +F src/build.c e8e776b52bc145cbf4e9fb88b99830083880fc2b174c2f96518fff15cbc72396 F src/callback.c 4c19af69835787bfe790ac560f3071a824eb629f34e41f97b52ce5235c77de1c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 026dbdcdbd8c3cde98a88483ee88310ff43150ab164ad768f12cc700a11495ad @@ -1951,8 +1951,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 3aefc874d31885c64a5e02868edb2aa56a2b4429252d494e67e4088a9298ce5b -R 6dba55261ae795532633c33f57ad1712 +P bd6811d8110d5f00596e2eff6d4b02af8b6d8557d41990e6f50518ead0fa01fb +R 1736d98e99a4d046468766a1a31c6936 U drh -Z 6c6a697026f7f5ef57340e9f97a907a3 +Z b9e8c09744bf10f890ccfa1fbf1f1b9a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 52cb76b4ed..7e90177ba2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bd6811d8110d5f00596e2eff6d4b02af8b6d8557d41990e6f50518ead0fa01fb \ No newline at end of file +59789fe1e745bb6f81898176e7e9c6064ac9f4bbefb4dc3c8f3e4c1379568f69 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 9468944ae1..fbd633209f 100644 --- a/src/build.c +++ b/src/build.c @@ -3055,7 +3055,6 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ Table *pSelTab; /* A fake table from which we get the result set */ Select *pSel; /* Copy of the SELECT that implements the view */ int nErr = 0; /* Number of errors encountered */ - int n; /* Temporarily holds the number of cursors assigned */ sqlite3 *db = pParse->db; /* Database connection for malloc errors */ #ifndef SQLITE_OMIT_VIRTUALTABLE int rc; @@ -3113,8 +3112,9 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ pSel = sqlite3SelectDup(db, pTable->u.view.pSelect, 0); if( pSel ){ u8 eParseMode = pParse->eParseMode; + int nTab = pParse->nTab; + int nSelect = pParse->nSelect; pParse->eParseMode = PARSE_MODE_NORMAL; - n = pParse->nTab; sqlite3SrcListAssignCursors(pParse, pSel->pSrc); pTable->nCol = -1; DisableLookaside; @@ -3126,7 +3126,8 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ #else pSelTab = sqlite3ResultSetOfSelect(pParse, pSel, SQLITE_AFF_NONE); #endif - pParse->nTab = n; + pParse->nTab = nTab; + pParse->nSelect = nSelect; if( pSelTab==0 ){ pTable->nCol = 0; nErr++; From 95fe38f2fc7468be6165552f8ef6bc85bcf1f358 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 25 Apr 2022 14:59:59 +0000 Subject: [PATCH 215/259] Add a new optimizer disabling bit to disable just the UNION ALL branch of the query flattener. FossilOrigin-Name: c0f9ebab5455d8541a562122d3270b95ce571c3fd870b0048dda2b036c2b66c0 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 1 + src/sqliteInt.h | 1 + 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 7a9ad1dd31..b24cf29d3b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sunintended\sside-effects\son\sParse.nSelect\sin\sthe\nsqlite3ViewGetColumnNames()\sroutine. -D 2022-04-25T14:49:48.098 +C Add\sa\snew\soptimizer\sdisabling\sbit\sto\sdisable\sjust\sthe\sUNION\sALL\sbranch\sof\sthe\nquery\sflattener. +D 2022-04-25T14:59:59.150 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -553,12 +553,12 @@ F src/printf.c 512574910a45341c8ad244bd3d4939968ebdfde215645b676fff01cc46e90757 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c f72bb13359dd5a74d440df25f320dc2c1baff5cde4fc9f0d1bc3feba90b8932a F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 92b3b250434de59fb87462dcdad79b456ae8ec82ae3194d4081ecb5af41ff0ec +F src/select.c ea203cd4f5d07443d7d25ae30fc0fb11b04ab9bd46a047ff5ebcb0abef63b4e9 F src/shell.c.in ae0a6fae983caac6f8c824733f0599dfdf7b3a7e8efdef3cb5e3ab2e457ffc35 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h 36b5d1cce15971fa71b53a950de3158197d85dbaf9b8b2f0bc6279347b09606a +F src/sqliteInt.h 2ed6fde4c3cd0438816f2b4597634067b11e430028b0e27b4be27736930d1739 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -1951,8 +1951,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 bd6811d8110d5f00596e2eff6d4b02af8b6d8557d41990e6f50518ead0fa01fb -R 1736d98e99a4d046468766a1a31c6936 +P 59789fe1e745bb6f81898176e7e9c6064ac9f4bbefb4dc3c8f3e4c1379568f69 +R 5dab58ddb6f58a52bd1b258cb5165dfd U drh -Z b9e8c09744bf10f890ccfa1fbf1f1b9a +Z 6423624c0497dbe7560341f194996237 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 7e90177ba2..6154315b41 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -59789fe1e745bb6f81898176e7e9c6064ac9f4bbefb4dc3c8f3e4c1379568f69 \ No newline at end of file +c0f9ebab5455d8541a562122d3270b95ce571c3fd870b0048dda2b036c2b66c0 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 5e90781eff..111e995cf1 100644 --- a/src/select.c +++ b/src/select.c @@ -4325,6 +4325,7 @@ static int flattenSubquery( if( pSrc->nSrc>1 ){ if( pParse->nSelect>500 ) return 0; + if( OptimizationDisabled(db, SQLITE_FlttnUnionAll) ) return 0; aCsrMap = sqlite3DbMallocZero(db, ((i64)pParse->nTab+1)*sizeof(int)); if( aCsrMap ) aCsrMap[0] = pParse->nTab; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index ec465cdb33..d396f24650 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1780,6 +1780,7 @@ struct sqlite3 { #define SQLITE_BloomPulldown 0x00100000 /* Run Bloom filters early */ #define SQLITE_BalancedMerge 0x00200000 /* Balance multi-way merges */ #define SQLITE_ReleaseReg 0x00400000 /* Use OP_ReleaseReg for testing */ +#define SQLITE_FlttnUnionAll 0x00800000 /* Disable the UNION ALL flattener */ #define SQLITE_AllOpts 0xffffffff /* All optimizations */ /* From a9cdb90421423503bdfb6c7b8a85754dd495ea7f Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 25 Apr 2022 19:40:33 +0000 Subject: [PATCH 216/259] Fix a problem with automatic indexes introduced by check-in [664b461bb5063d980] and reported by [forum:/forumpost/0d3200f4f3bcd3a3|forum post 0d3200f4f3bcd3a3]. FossilOrigin-Name: 7ca3456c00998a429418ff29cf251b381586b330b88344c94a40c5df0b71da85 --- manifest | 20 ++++++++++---------- manifest.uuid | 2 +- src/expr.c | 36 ++++++++++++++++++++++++++++++++++++ src/select.c | 20 ++++++++++---------- src/sqliteInt.h | 1 + src/where.c | 6 ++---- test/autoindex1.test | 20 ++++++++++++++++++-- 7 files changed, 78 insertions(+), 27 deletions(-) diff --git a/manifest b/manifest index b24cf29d3b..d9200cb4ad 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\snew\soptimizer\sdisabling\sbit\sto\sdisable\sjust\sthe\sUNION\sALL\sbranch\sof\sthe\nquery\sflattener. -D 2022-04-25T14:59:59.150 +C Fix\sa\sproblem\swith\sautomatic\sindexes\sintroduced\sby\ncheck-in\s[664b461bb5063d980]\sand\sreported\sby\n[forum:/forumpost/0d3200f4f3bcd3a3|forum\spost\s0d3200f4f3bcd3a3]. +D 2022-04-25T19:40:33.982 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -504,7 +504,7 @@ F src/date.c 15082566229d4b1e5f24fdb490bf9bcc68824b911d70e3573ef075a1b9e2d26f F src/dbpage.c 90661a87e1db8bfbc8d2ebbdcd3749651ddb287c555c07a28fb17c7c591ffb68 F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d F src/delete.c a8e844af211a48b13b5b358be77a12c860c6a557c21990ad51a548e2536500ce -F src/expr.c 06dfbfb7f469c00eba3c8a7e282765969fe7c772f235a365f51bfffcaa69fe7f +F src/expr.c 5d4178f8462ca55a38cefcfcdf9635030607e3532649c96de471afafeca732c4 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c d965ede15d8360c09ed59348940649ee647b192e784466837d7aefa836d1d91e F src/func.c a3407a6fbb0d4088d8d502e46f0ace63e0aeae7467ae23a9ca9815bbf9239761 @@ -553,12 +553,12 @@ F src/printf.c 512574910a45341c8ad244bd3d4939968ebdfde215645b676fff01cc46e90757 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c f72bb13359dd5a74d440df25f320dc2c1baff5cde4fc9f0d1bc3feba90b8932a F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c ea203cd4f5d07443d7d25ae30fc0fb11b04ab9bd46a047ff5ebcb0abef63b4e9 +F src/select.c e5772fb9c1b56a3e9ca688ea27303fc115d1cf336d68561ceee4145dfa2f36d9 F src/shell.c.in ae0a6fae983caac6f8c824733f0599dfdf7b3a7e8efdef3cb5e3ab2e457ffc35 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h 2ed6fde4c3cd0438816f2b4597634067b11e430028b0e27b4be27736930d1739 +F src/sqliteInt.h 11cd60560cd14bb6eecd04d244faf4c1895417b97d89e2f50833f83c4611588d F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -640,7 +640,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c bd4895fbb6ac9cc5b772d191b93dd5a240a505e3113be9aee0dc8c957568dd41 +F src/where.c 43085b3a4ce2e56315fabb0b240a56e76667d9e03c79f287695bcae7b76152d5 F src/whereInt.h 4db5a877a9d1f38b5c928c1c84297c07f30b9a3bc1f5f66214cf1a8ef90a0556 F src/wherecode.c 55a33d9db1759970c30220904bcc628ba66a1ccb63b5437ef4642f7ea6267b03 F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 @@ -705,7 +705,7 @@ F test/auth2.test 9eb7fce9f34bf1f50d3f366fb3e606be5a2000a1 F test/auth3.test 76d20a7fa136d63bcfcf8bcb65c0b1455ed71078d81f22bcd0550d3eb18594ab F test/autoanalyze1.test b9cc3f32a990fa56669b668d237c6d53e983554ae80c0604992e18869a0b2dec F test/autoinc.test 997d6f185f138229dc4251583a1d04816423dddc2fc034871a01aeb1d728cb39 -F test/autoindex1.test 523b26034dc5e0c5ff0865055b4593f75863b82f17748dec9ca64bb8b267c502 +F test/autoindex1.test cdc336e80cfd586c0e09426d58bec412db7527ca22dfabe88eab690e3acbb406 F test/autoindex2.test 12ef578928102baaa0dc23ad397601a2f4ecb0df F test/autoindex3.test 2d13958a5617e987624a428d7aed91bf51f322b49b476e3573fadec697ce6da5 F test/autoindex4.test 5df39313526b6f22a26bd119bbd97ca69f28386ab3c671fc10568d921c41eb08 @@ -1951,8 +1951,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 59789fe1e745bb6f81898176e7e9c6064ac9f4bbefb4dc3c8f3e4c1379568f69 -R 5dab58ddb6f58a52bd1b258cb5165dfd +P c0f9ebab5455d8541a562122d3270b95ce571c3fd870b0048dda2b036c2b66c0 +R cb2c389ae944c4d6eaa6314dd1b0dc57 U drh -Z 6423624c0497dbe7560341f194996237 +Z 42d259eeea1f414b7f57e1057b3c3aee # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 6154315b41..a5c9464c8d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c0f9ebab5455d8541a562122d3270b95ce571c3fd870b0048dda2b036c2b66c0 \ No newline at end of file +7ca3456c00998a429418ff29cf251b381586b330b88344c94a40c5df0b71da85 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 1709876219..addd5794db 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2296,6 +2296,42 @@ int sqlite3ExprIsTableConstant(Expr *p, int iCur){ return exprIsConst(p, 3, iCur); } +/* +** Check pExpr to see if it is an invariant constraint on data source pSrc. +** This is an optimization. False negatives will perhaps cause slower +** queries, but false positives will yield incorrect answers. So when in +** double, return 0. +** +** To be an invariant constraint, the following must be true: +** +** (1) pExpr cannot refer to any table other than pSrc->iCursor. +** +** (2) pExpr cannot use subqueries or non-deterministic functions. +** +** (3) pSrc cannot be part of the left operand for a RIGHT JOIN. +** (Is there some way to relax this constraint?) +** +** (4) If pSrc is the right operand of a LEFT JOIN, then... +** (4a) pExpr must come from an ON clause.. + (4b) and specifically the ON clause associated with the LEFT JOIN. +** +** (5) If pSrc is not the right operand of a LEFT JOIN or the left +** operand of a RIGHT JOIN, then pExpr must be from the WHERE +** clause, not an ON clause. +*/ +int sqlite3ExprIsTableConstraint(Expr *pExpr, const SrcItem *pSrc){ + if( pSrc->fg.jointype & JT_LTORJ ){ + return 0; /* rule (3) */ + } + if( pSrc->fg.jointype & JT_LEFT ){ + if( !ExprHasProperty(pExpr, EP_FromJoin) ) return 0; /* rule (4a) */ + if( pExpr->w.iJoin!=pSrc->iCursor ) return 0; /* rule (4b) */ + }else{ + if( ExprHasProperty(pExpr, EP_FromJoin) ) return 0; /* rule (5) */ + } + return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor); /* rules (1), (2) */ +} + /* ** sqlite3WalkExpr() callback used by sqlite3ExprIsConstantOrGroupBy(). diff --git a/src/select.c b/src/select.c index 111e995cf1..5249c1f728 100644 --- a/src/select.c +++ b/src/select.c @@ -4954,8 +4954,7 @@ static int pushDownWhereTerms( Parse *pParse, /* Parse context (for malloc() and error reporting) */ Select *pSubq, /* The subquery whose WHERE clause is to be augmented */ Expr *pWhere, /* The WHERE clause of the outer query */ - int iCursor, /* Cursor number of the subquery */ - int isLeftJoin /* True if pSubq is the right term of a LEFT JOIN */ + SrcItem *pSrc /* The subquery term of the outer FROM clause */ ){ Expr *pNew; int nChng = 0; @@ -4990,10 +4989,11 @@ static int pushDownWhereTerms( return 0; /* restriction (3) */ } while( pWhere->op==TK_AND ){ - nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, - iCursor, isLeftJoin); + nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, pSrc); pWhere = pWhere->pLeft; } + +#if 0 /* Legacy code. Checks now done by sqlite3ExprIsTableConstraint() */ if( isLeftJoin && (ExprHasProperty(pWhere,EP_FromJoin)==0 || pWhere->w.iJoin!=iCursor) @@ -5005,7 +5005,9 @@ static int pushDownWhereTerms( ){ return 0; /* restriction (5) */ } - if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){ +#endif + + if( sqlite3ExprIsTableConstant(pWhere, pSrc->iCursor) ){ nChng++; pSubq->selFlags |= SF_PushDown; while( pSubq ){ @@ -5013,8 +5015,8 @@ static int pushDownWhereTerms( pNew = sqlite3ExprDup(pParse->db, pWhere, 0); unsetJoinExpr(pNew, -1); x.pParse = pParse; - x.iTable = iCursor; - x.iNewTable = iCursor; + x.iTable = pSrc->iCursor; + x.iNewTable = pSrc->iCursor; x.isOuterJoin = 0; x.pEList = pSubq->pEList; pNew = substExpr(&x, pNew); @@ -6840,9 +6842,7 @@ int sqlite3Select( if( OptimizationEnabled(db, SQLITE_PushDown) && (pItem->fg.isCte==0 || (pItem->u2.pCteUse->eM10d!=M10d_Yes && pItem->u2.pCteUse->nUse<2)) - && (pItem->fg.jointype & JT_RIGHT)==0 - && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor, - (pItem->fg.jointype & JT_OUTER)!=0) + && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem) ){ #if TREETRACE_ENABLED if( sqlite3TreeTrace & 0x100 ){ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index d396f24650..d799510fc0 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4752,6 +4752,7 @@ int sqlite3ExprIsConstantNotJoin(Expr*); int sqlite3ExprIsConstantOrFunction(Expr*, u8); int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*); int sqlite3ExprIsTableConstant(Expr*,int); +int sqlite3ExprIsTableConstraint(Expr*,const SrcItem*); #ifdef SQLITE_ENABLE_CURSOR_HINTS int sqlite3ExprContainsSubquery(Expr*); #endif diff --git a/src/where.c b/src/where.c index d6c023941c..2750d93584 100644 --- a/src/where.c +++ b/src/where.c @@ -832,9 +832,7 @@ static SQLITE_NOINLINE void constructAutomaticIndex( ** WHERE clause (or the ON clause of a LEFT join) that constrain which ** rows of the target table (pSrc) that can be used. */ if( (pTerm->wtFlags & TERM_VIRTUAL)==0 - && ((pSrc->fg.jointype&(JT_LEFT|JT_LTORJ))==0 - || ExprHasProperty(pExpr,EP_FromJoin)) - && sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor) + && sqlite3ExprIsTableConstraint(pExpr, pSrc) ){ pPartial = sqlite3ExprAnd(pParse, pPartial, sqlite3ExprDup(pParse->db, pExpr, 0)); @@ -1073,7 +1071,7 @@ static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( for(pTerm=pWInfo->sWC.a; pTermpExpr; if( (pTerm->wtFlags & TERM_VIRTUAL)==0 - && sqlite3ExprIsTableConstant(pExpr, iCur) + && sqlite3ExprIsTableConstraint(pExpr, pItem) ){ sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL); } diff --git a/test/autoindex1.test b/test/autoindex1.test index 2cd4900400..4b290c7961 100644 --- a/test/autoindex1.test +++ b/test/autoindex1.test @@ -542,7 +542,23 @@ do_execsql_test autoindex1-1020 { SELECT count(*) FROM t11 LEFT JOIN t12 WHERE t12.y IS t11.w; } 0 - - +# 2022-04-25 +# https://sqlite.org/forum/forumpost/0d3200f4f3bcd3a3 +# +reset_db +do_execsql_test autoindex-1100 { + CREATE TABLE t1(a INT, b INT); + CREATE TABLE t2(c INT, d INT); + CREATE TABLE t3(e TEXT, f TEXT); + INSERT INTO t1 VALUES(1, 1); + INSERT INTO t2 VALUES(1, 2); + INSERT INTO t3 VALUES('abc', 'def'); +} {} +do_execsql_test autoindex-1110 { + SELECT * FROM t1, t2 LEFT JOIN t3 ON (t2.d=1) WHERE t2.c = +t1.a; +} {1 1 1 2 {} {}} +do_execsql_test autoindex-1120 { + SELECT * FROM t1 LEFT JOIN t2 ON (t2.c=+t1.a) LEFT JOIN t3 ON (t2.d IS NULL); +} {1 1 1 2 {} {}} finish_test From 5eb6e09795507d7a435228229bee0aa90791aa18 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 25 Apr 2022 20:38:42 +0000 Subject: [PATCH 217/259] The pushDownWhereTerms() routine should be using sqlite3ExprIsTableConstraint(), not sqlite3ExprIsTableConstant(). This fixes many problems, but still an error persists in join7.test. FossilOrigin-Name: 10bf0e613809f71cc1a47ad40b517e2a66671212a6464e179c9d377e8b70d499 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index d9200cb4ad..83dab85af9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\sautomatic\sindexes\sintroduced\sby\ncheck-in\s[664b461bb5063d980]\sand\sreported\sby\n[forum:/forumpost/0d3200f4f3bcd3a3|forum\spost\s0d3200f4f3bcd3a3]. -D 2022-04-25T19:40:33.982 +C The\spushDownWhereTerms()\sroutine\sshould\sbe\susing\nsqlite3ExprIsTableConstraint(),\snot\ssqlite3ExprIsTableConstant().\s\sThis\sfixes\nmany\sproblems,\sbut\sstill\san\serror\spersists\sin\sjoin7.test. +D 2022-04-25T20:38:42.383 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -553,7 +553,7 @@ F src/printf.c 512574910a45341c8ad244bd3d4939968ebdfde215645b676fff01cc46e90757 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c f72bb13359dd5a74d440df25f320dc2c1baff5cde4fc9f0d1bc3feba90b8932a F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c e5772fb9c1b56a3e9ca688ea27303fc115d1cf336d68561ceee4145dfa2f36d9 +F src/select.c 0ee60363b0bc5e4c0cc9fc2e0a6d76e5d0d2eb756d691e302800bebf16439ec4 F src/shell.c.in ae0a6fae983caac6f8c824733f0599dfdf7b3a7e8efdef3cb5e3ab2e457ffc35 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1951,8 +1951,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 c0f9ebab5455d8541a562122d3270b95ce571c3fd870b0048dda2b036c2b66c0 -R cb2c389ae944c4d6eaa6314dd1b0dc57 +P 7ca3456c00998a429418ff29cf251b381586b330b88344c94a40c5df0b71da85 +R e383c06c18e315aa0b232a51b37bdb01 U drh -Z 42d259eeea1f414b7f57e1057b3c3aee +Z b20e944a61d9ac254d588d9faa898773 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a5c9464c8d..66d3596648 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7ca3456c00998a429418ff29cf251b381586b330b88344c94a40c5df0b71da85 \ No newline at end of file +10bf0e613809f71cc1a47ad40b517e2a66671212a6464e179c9d377e8b70d499 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 5249c1f728..356f6477b4 100644 --- a/src/select.c +++ b/src/select.c @@ -5007,7 +5007,7 @@ static int pushDownWhereTerms( } #endif - if( sqlite3ExprIsTableConstant(pWhere, pSrc->iCursor) ){ + if( sqlite3ExprIsTableConstraint(pWhere, pSrc) ){ nChng++; pSubq->selFlags |= SF_PushDown; while( pSubq ){ From 0e464b5f513bef5b08da17988a47c8baa8b34b90 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 25 Apr 2022 20:47:58 +0000 Subject: [PATCH 218/259] Do not allow the push-down optimization on the right table of a RIGHT JOIN. FossilOrigin-Name: 05917bfa02a7b6678c147d10fb53f55532ab15fd5d82d925ae921ae3759f0115 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 83dab85af9..18fad4225b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\spushDownWhereTerms()\sroutine\sshould\sbe\susing\nsqlite3ExprIsTableConstraint(),\snot\ssqlite3ExprIsTableConstant().\s\sThis\sfixes\nmany\sproblems,\sbut\sstill\san\serror\spersists\sin\sjoin7.test. -D 2022-04-25T20:38:42.383 +C Do\snot\sallow\sthe\spush-down\soptimization\son\sthe\sright\stable\sof\sa\sRIGHT\sJOIN. +D 2022-04-25T20:47:58.298 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -553,7 +553,7 @@ F src/printf.c 512574910a45341c8ad244bd3d4939968ebdfde215645b676fff01cc46e90757 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c f72bb13359dd5a74d440df25f320dc2c1baff5cde4fc9f0d1bc3feba90b8932a F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 0ee60363b0bc5e4c0cc9fc2e0a6d76e5d0d2eb756d691e302800bebf16439ec4 +F src/select.c cc1a7581403fc074eee85283ba8d81de50a831ae175cb65a5751be00f621c0d5 F src/shell.c.in ae0a6fae983caac6f8c824733f0599dfdf7b3a7e8efdef3cb5e3ab2e457ffc35 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1951,8 +1951,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 7ca3456c00998a429418ff29cf251b381586b330b88344c94a40c5df0b71da85 -R e383c06c18e315aa0b232a51b37bdb01 +P 10bf0e613809f71cc1a47ad40b517e2a66671212a6464e179c9d377e8b70d499 +R 8764866988e0da227134244ae6ff31d7 U drh -Z b20e944a61d9ac254d588d9faa898773 +Z bf16933ceb0da28b71dd4050f0adc6a6 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 66d3596648..361d84d949 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -10bf0e613809f71cc1a47ad40b517e2a66671212a6464e179c9d377e8b70d499 \ No newline at end of file +05917bfa02a7b6678c147d10fb53f55532ab15fd5d82d925ae921ae3759f0115 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 356f6477b4..e0f93a1012 100644 --- a/src/select.c +++ b/src/select.c @@ -4960,6 +4960,7 @@ static int pushDownWhereTerms( int nChng = 0; if( pWhere==0 ) return 0; if( pSubq->selFlags & (SF_Recursive|SF_MultiPart) ) return 0; + if( pSrc->fg.jointype & (JT_LTORJ|JT_RIGHT) ) return 0; #ifndef SQLITE_OMIT_WINDOWFUNC if( pSubq->pPrior ){ From 5487cdcc0a74b811c5ea50625943d83d0b4c052b Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 26 Apr 2022 19:16:11 +0000 Subject: [PATCH 219/259] Update corruptL.test so that it works with SQLITE_ENABLE_OVERSIZE_CELL_CHECK builds. FossilOrigin-Name: b1bec72043f798f4d4d30e6b60a45ed4dc521115c8a9f97bb8228e3f089deefb --- manifest | 15 +++++++-------- manifest.uuid | 2 +- test/corruptL.test | 6 +++++- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 53d80cd62f..9c6009d8db 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\sautomatic\sindexes\sintroduced\sby\ncheck-in\s[664b461bb5063d980]\sand\sreported\sby\n[forum:/forumpost/0d3200f4f3bcd3a3|forum\spost\s0d3200f4f3bcd3a3]. -D 2022-04-25T20:56:55.290 +C Update\scorruptL.test\sso\sthat\sit\sworks\swith\sSQLITE_ENABLE_OVERSIZE_CELL_CHECK\sbuilds. +D 2022-04-26T19:16:11.042 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -815,7 +815,7 @@ F test/corruptH.test 79801d97ec5c2f9f3c87739aa1ec2eb786f96454 F test/corruptI.test a17bbf54fdde78d43cf3cc34b0057719fd4a173a3d824285b67dc5257c064c7b F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4 F test/corruptK.test 5b4212fe346699831c5ad559a62c54e11c0611bdde1ea8423a091f9c01aa32af -F test/corruptL.test 21a951d1eb09120f3c1561af5bac30ed49be2d9dfcad039f71759c5d9e28a349 +F test/corruptL.test ecce40d7b9b909a670a42a45d86e30d927735d7e7f09041af438b19529d35532 F test/corruptM.test 7d574320e08c1b36caa3e47262061f186367d593a7e305d35f15289cc2c3e067 F test/corruptN.test 60b5a62944b4f0029ba07edaa5fd8e670539d6b0a8d99db26c068d435675cbfe F test/cost.test b11cdbf9f11ffe8ef99c9881bf390e61fe92baf2182bad1dbe6de59a7295c576 @@ -1951,9 +1951,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 c0f9ebab5455d8541a562122d3270b95ce571c3fd870b0048dda2b036c2b66c0 05917bfa02a7b6678c147d10fb53f55532ab15fd5d82d925ae921ae3759f0115 -R 8764866988e0da227134244ae6ff31d7 -T +closed 05917bfa02a7b6678c147d10fb53f55532ab15fd5d82d925ae921ae3759f0115 -U drh -Z 79f75ad88ffd5089cb0059313ed9c927 +P 134cfb18ff930e4bccc1a7412a02be353bf67c6d5080bc0673afaac81afa889c +R befb1f523df3bca906a42f846ff7dead +U dan +Z e8552be406f4e283f43139c97e8f16c9 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 75514fbf2b..8d5d3327b9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -134cfb18ff930e4bccc1a7412a02be353bf67c6d5080bc0673afaac81afa889c \ No newline at end of file +b1bec72043f798f4d4d30e6b60a45ed4dc521115c8a9f97bb8228e3f089deefb \ No newline at end of file diff --git a/test/corruptL.test b/test/corruptL.test index eef91b7747..7361a0b35e 100644 --- a/test/corruptL.test +++ b/test/corruptL.test @@ -1480,8 +1480,12 @@ do_execsql_test 19.1 { PRAGMA writable_schema=ON; } +set err "UNIQUE constraint failed: index 'a'" +ifcapable oversize_cell_check { + set err "database disk image is malformed" +} do_catchsql_test 19.2 { UPDATE t1 SET a=1; -} {1 {UNIQUE constraint failed: index 'a'}} +} [list 1 $err] finish_test From 9684d71081fd07cd79f2738f7bfd83cde3aa49a0 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 27 Apr 2022 13:33:48 +0000 Subject: [PATCH 220/259] Fix a test problem in rbubusy.test causing a crash under some circumstances. FossilOrigin-Name: bc5bbd9fa636cc9ef0cbbc0600b8fc1404b9732670ac4e7a8b5a230fbce758d5 --- ext/rbu/rbubusy.test | 5 +++++ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/ext/rbu/rbubusy.test b/ext/rbu/rbubusy.test index a16b85ff96..8cc47db8f9 100644 --- a/ext/rbu/rbubusy.test +++ b/ext/rbu/rbubusy.test @@ -79,4 +79,9 @@ do_test 1.7 { rbu close +db close +sqlite3_shutdown +test_sqlite3_log +sqlite3_initialize finish_test + diff --git a/manifest b/manifest index 9c6009d8db..5d25cfd023 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\scorruptL.test\sso\sthat\sit\sworks\swith\sSQLITE_ENABLE_OVERSIZE_CELL_CHECK\sbuilds. -D 2022-04-26T19:16:11.042 +C Fix\sa\stest\sproblem\sin\srbubusy.test\scausing\sa\scrash\sunder\ssome\scircumstances. +D 2022-04-27T13:33:48.684 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -358,7 +358,7 @@ F ext/rbu/rbuA.test b34a90cb495682c25b5fc03a9d5e7a4fc99541c29256f25e2e2a4f6542b4 F ext/rbu/rbuB.test 52b07158824c6927b7e25554ace92a695cdebfc296ae3d308ac386984aded9bc F ext/rbu/rbuC.test 80f1cc2fb74f44b1128fd0ed8eedab3a76fefeb72a947860e2869ef76fc8dc6b F ext/rbu/rbu_common.tcl 60d904133ff843fe72cc0514e9dd2486707181e6e0fbab20979da28c48d21de9 -F ext/rbu/rbubusy.test 35a6ad081b374281f728b26264ef4f0b0e7888ccb5ace1843aed30ed99c2e1ca +F ext/rbu/rbubusy.test f38ef557358564491b8a2ee70e4cad31e40fcea57a16f27bc56ba40a59bbde50 F ext/rbu/rbucollate.test cac528a9a46318cba42e61258bb42660bbbf4fdb9a8c863de5a54ad0c658d197 F ext/rbu/rbucrash.test 000981a1fe8a6e4d9a684232f6a129e66a3ef595f5ed74655e2f9c68ffa613b4 F ext/rbu/rbucrash2.test efa143cc94228eb0266d3f1abfbee60a5838a84cef7cc3fcb8c145b74d96fd41 @@ -1951,8 +1951,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 134cfb18ff930e4bccc1a7412a02be353bf67c6d5080bc0673afaac81afa889c -R befb1f523df3bca906a42f846ff7dead +P b1bec72043f798f4d4d30e6b60a45ed4dc521115c8a9f97bb8228e3f089deefb +R f8e9d661e065b7babfd72a5655e4ad71 U dan -Z e8552be406f4e283f43139c97e8f16c9 +Z 3cd41b751eccac6d73d356239c542a95 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8d5d3327b9..9b2e970b93 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b1bec72043f798f4d4d30e6b60a45ed4dc521115c8a9f97bb8228e3f089deefb \ No newline at end of file +bc5bbd9fa636cc9ef0cbbc0600b8fc1404b9732670ac4e7a8b5a230fbce758d5 \ No newline at end of file From 609959285bc035aa18da0d89bea484e1b5432105 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 27 Apr 2022 16:41:56 +0000 Subject: [PATCH 221/259] When computing STAT1 values using ANALYZE, if a ratio comes out to be between 1.0 and 1.1, then round it down to 1 rather than the using the default rounding rule of changing it to 2. The reduces the estimation error for the case where a column value is very nearly, but not quite unique. FossilOrigin-Name: eb59c46a5aed69bc6fd096997bf24c082e533c1085439f6ec1fbe5ff78e8b374 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/analyze.c | 8 +++++++- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 5d25cfd023..dcee977a82 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stest\sproblem\sin\srbubusy.test\scausing\sa\scrash\sunder\ssome\scircumstances. -D 2022-04-27T13:33:48.684 +C When\scomputing\sSTAT1\svalues\susing\sANALYZE,\sif\sa\sratio\scomes\sout\sto\sbe\sbetween\n1.0\sand\s1.1,\sthen\sround\sit\sdown\sto\s1\srather\sthan\sthe\susing\sthe\sdefault\srounding\nrule\sof\schanging\sit\sto\s2.\s\sThe\sreduces\sthe\sestimation\serror\sfor\sthe\ncase\swhere\sa\scolumn\svalue\sis\svery\snearly,\sbut\snot\squite\sunique. +D 2022-04-27T16:41:56.099 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -487,7 +487,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 9395ece9850ad57c6fbb453aeb5185be4bae3b159c4b37611425c565124ee849 -F src/analyze.c 3a119baeb03053c154029877454d41bb8fd79d4d1eb583392f2289b3554a75bc +F src/analyze.c aabdf3769c7fd9954a8ec508eb7041ae174b66f88d12c47199fabbea9a646467 F src/attach.c 4431f82f0247bf3aaf91589acafdff77d1882235c95407b36da1585c765fbbc8 F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf F src/backup.c a2891172438e385fdbe97c11c9745676bec54f518d4447090af97189fd8e52d7 @@ -1951,8 +1951,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 b1bec72043f798f4d4d30e6b60a45ed4dc521115c8a9f97bb8228e3f089deefb -R f8e9d661e065b7babfd72a5655e4ad71 -U dan -Z 3cd41b751eccac6d73d356239c542a95 +P bc5bbd9fa636cc9ef0cbbc0600b8fc1404b9732670ac4e7a8b5a230fbce758d5 +R 5515b70c241c679d58c02a7cda432aa8 +U drh +Z e146713923a218edc001415f7d000194 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 9b2e970b93..0444092686 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bc5bbd9fa636cc9ef0cbbc0600b8fc1404b9732670ac4e7a8b5a230fbce758d5 \ No newline at end of file +eb59c46a5aed69bc6fd096997bf24c082e533c1085439f6ec1fbe5ff78e8b374 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index e8699653f7..39009899ab 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -847,9 +847,14 @@ static void statGet( ** * "WHERE a=? AND b=?" matches 2 rows. ** ** If D is the count of distinct values and K is the total number of - ** rows, then each estimate is computed as: + ** rows, then each estimate is usually computed as: ** ** I = (K+D-1)/D + ** + ** In other words, I is K/D rounded up to the next whole integer. + ** However, if I is between 1.0 and 1.1 (in other words if I is + ** close to 1.0 but just a little larger) then do not round up but + ** instead keep the I value at 1.0. */ sqlite3_str sStat; /* Text of the constructed "stat" line */ int i; /* Loop counter */ @@ -860,6 +865,7 @@ static void statGet( for(i=0; inKeyCol; i++){ u64 nDistinct = p->current.anDLt[i] + 1; u64 iVal = (p->nRow + nDistinct - 1) / nDistinct; + if( iVal==2 && p->nRow*10 <= nDistinct*11 ) iVal = 1; sqlite3_str_appendf(&sStat, " %llu", iVal); assert( p->current.anEq[i] ); } From 22b541b55a12a137b533132396cbdf2e71e2f7d3 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 27 Apr 2022 18:38:46 +0000 Subject: [PATCH 222/259] Fix a harmless typo in a comment. FossilOrigin-Name: e1f4a115df34e45cf1bcf98961c699b582f564a58a979e95853b219bda06212c --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index dcee977a82..4b561cb6fc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\scomputing\sSTAT1\svalues\susing\sANALYZE,\sif\sa\sratio\scomes\sout\sto\sbe\sbetween\n1.0\sand\s1.1,\sthen\sround\sit\sdown\sto\s1\srather\sthan\sthe\susing\sthe\sdefault\srounding\nrule\sof\schanging\sit\sto\s2.\s\sThe\sreduces\sthe\sestimation\serror\sfor\sthe\ncase\swhere\sa\scolumn\svalue\sis\svery\snearly,\sbut\snot\squite\sunique. -D 2022-04-27T16:41:56.099 +C Fix\sa\sharmless\stypo\sin\sa\scomment. +D 2022-04-27T18:38:46.859 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -504,7 +504,7 @@ F src/date.c 15082566229d4b1e5f24fdb490bf9bcc68824b911d70e3573ef075a1b9e2d26f F src/dbpage.c 90661a87e1db8bfbc8d2ebbdcd3749651ddb287c555c07a28fb17c7c591ffb68 F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d F src/delete.c a8e844af211a48b13b5b358be77a12c860c6a557c21990ad51a548e2536500ce -F src/expr.c 5d4178f8462ca55a38cefcfcdf9635030607e3532649c96de471afafeca732c4 +F src/expr.c d8c520edd0edf0b9c0ca467aa44c864ff17f265fd1cebbd224b6d5c625b638c3 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c d965ede15d8360c09ed59348940649ee647b192e784466837d7aefa836d1d91e F src/func.c a3407a6fbb0d4088d8d502e46f0ace63e0aeae7467ae23a9ca9815bbf9239761 @@ -1951,8 +1951,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 bc5bbd9fa636cc9ef0cbbc0600b8fc1404b9732670ac4e7a8b5a230fbce758d5 -R 5515b70c241c679d58c02a7cda432aa8 +P eb59c46a5aed69bc6fd096997bf24c082e533c1085439f6ec1fbe5ff78e8b374 +R f499c3fddca86db7a0183d3ecdb0953b U drh -Z e146713923a218edc001415f7d000194 +Z 7426364b9684e9a6fe822d40fffa4b25 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0444092686..1daa831936 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -eb59c46a5aed69bc6fd096997bf24c082e533c1085439f6ec1fbe5ff78e8b374 \ No newline at end of file +e1f4a115df34e45cf1bcf98961c699b582f564a58a979e95853b219bda06212c \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index addd5794db..13bacb90ca 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2300,7 +2300,7 @@ int sqlite3ExprIsTableConstant(Expr *p, int iCur){ ** Check pExpr to see if it is an invariant constraint on data source pSrc. ** This is an optimization. False negatives will perhaps cause slower ** queries, but false positives will yield incorrect answers. So when in -** double, return 0. +** doubt, return 0. ** ** To be an invariant constraint, the following must be true: ** From 4bea8c6b564bf84005df34e4b7f318af6ba37189 Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 28 Apr 2022 17:35:58 +0000 Subject: [PATCH 223/259] Tweaks to the name resolution on parenthesized joins. A small number of tests fail now due to extra columns appearing in the expansion of "*". FossilOrigin-Name: c86804917e3fffcf0c19bbf11875667f7968275210fc768e650826bd9c87a5d2 --- manifest | 13 +- manifest.uuid | 2 +- src/select.c | 3 +- test/joinC.test | 4594 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 4604 insertions(+), 8 deletions(-) create mode 100644 test/joinC.test diff --git a/manifest b/manifest index 07395719f4..6940dc03a5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\strunk\senhancements\sinto\sthe\sright-join\sbranch. -D 2022-04-28T12:52:49.755 +C Tweaks\sto\sthe\sname\sresolution\son\sparenthesized\sjoins.\s\sA\ssmall\snumber\sof\ntests\sfail\snow\sdue\sto\sextra\scolumns\sappearing\sin\sthe\sexpansion\sof\s"*". +D 2022-04-28T17:35:58.976 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -553,7 +553,7 @@ F src/printf.c 512574910a45341c8ad244bd3d4939968ebdfde215645b676fff01cc46e90757 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c b14bf8a4a1e3cb01eefc48a7e4129b15bb6a18b56d16dd4eca676586464337d0 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c be3da92c2ba294d781facd4ea8a3e00de327354a44828e390716f60fd6b6c3d1 +F src/select.c b319bfcdf6c06841312f7e98c71f384d775f20138760855b8489aa6a05a70e72 F src/shell.c.in ae0a6fae983caac6f8c824733f0599dfdf7b3a7e8efdef3cb5e3ab2e457ffc35 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1152,6 +1152,7 @@ F test/join8.test 8b1cc9592aa8f623fc2878353b16c81257591908de06d2a4916f7cbe3ca75e F test/join9.test 9056ddd3b0c0f4f9d658f4521038d9a37dc23ead8ca9a505d0b0db2b6a471e05 F test/joinA.test 7eab225dc1c1ab258a5e62513a4ed7cabbd3db971d59d5d92f4fb6fa14c12f6a F test/joinB.test 1b2ba3fc8568b49411787fccbf540570c148e9b6a53a30f80691cb6268098ded +F test/joinC.test 1f1a602c2127f55f136e2cbd3bf2d26546614bf8cffe5902ec1ac9c07f87f207 F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -1951,8 +1952,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 2fb165cf8bd1e43248612aa2922bd311df30dcbb3c2f1daee73c363e409c501f e1f4a115df34e45cf1bcf98961c699b582f564a58a979e95853b219bda06212c -R faed2a835a5b5dfd45bc593080cb511f +P 3fd9706bba4a71cb5c7ce1341c3be0a7727941445820a073e7b2f0f32512e8ef +R 53c4a50b3b49e4ffda08971a28c23faf U drh -Z 3711ae6870270d64360e9cabb9baf423 +Z c38c4449faac7a680433a77b8e09acfd # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 20b51adb22..e930a0fcec 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3fd9706bba4a71cb5c7ce1341c3be0a7727941445820a073e7b2f0f32512e8ef \ No newline at end of file +c86804917e3fffcf0c19bbf11875667f7968275210fc768e650826bd9c87a5d2 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 3c59b5d5f6..ed0fc6e4c8 100644 --- a/src/select.c +++ b/src/select.c @@ -5878,12 +5878,13 @@ static int selectExpander(Walker *pWalker, Select *p){ */ if( pTab->aCol[j].colFlags & (COLFLAG_HIDDEN|COLFLAG_NOEXPAND) ){ if( IsHiddenColumn(&pTab->aCol[j]) - && (selFlags & SF_IncludeHidden)==0 + && (selFlags & (SF_IncludeHidden|SF_NestedFrom))==0 ){ continue; } if( (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)!=0 && zTName==0 + && (selFlags & (SF_NestedFrom))==0 ){ continue; } diff --git a/test/joinC.test b/test/joinC.test new file mode 100644 index 0000000000..a6f9395851 --- /dev/null +++ b/test/joinC.test @@ -0,0 +1,4594 @@ +# 2022-04-19 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file implements tests for JOINs. +# +# The test case output is all generated by PostgreSQL 14. This test module +# was created as follows: +# +# 1. Run a TCL script (included at the bottom of this file) that +# generates an input script for "psql" that will run man +# diverse tests on joins. +# +# 2. Run the script from step (1) through psql and collect the +# output. +# +# 3. Make a few minor global search-and-replace operations to convert +# the psql output into a form suitable for this test module. +# +# 4. Add this header, and the script content at the footer. +# +set testdir [file dirname $argv0] +source $testdir/tester.tcl +db nullvalue - +db eval { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t2; + DROP TABLE IF EXISTS t3; + DROP TABLE IF EXISTS t4; + DROP TABLE IF EXISTS t5; + CREATE TABLE t1(a INT, b INT, c INT); + CREATE TABLE t2(a INT, b INT, d INT); + CREATE TABLE t3(a INT, b INT, e INT); + CREATE TABLE t4(a INT, b INT, f INT); + CREATE TABLE t5(a INT, b INT, g INT); + INSERT INTO t1 VALUES(11,21,31),(12,22,32),(15,25,35),(17,27,37); + INSERT INTO t2 VALUES(12,22,32),(13,23,33),(15,25,35),(18,28,38), + (NULL,NULL,36); + INSERT INTO t4 VALUES(11,21,31),(13,23,33),(15,25,35),(19,29,39); + INSERT INTO t3 SELECT * FROM t1 UNION SELECT * FROM t2 UNION SELECT * FROM t4; + INSERT INTO t5 SELECT * FROM t3 WHERE a>=15; +} +do_execsql_test joinC-1 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 INNER JOIN ( + t3 INNER JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + +} +do_execsql_test joinC-2 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 INNER JOIN ( + t3 INNER JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + +} +do_execsql_test joinC-3 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 INNER JOIN ( + t3 INNER JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + +} +do_execsql_test joinC-4 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 INNER JOIN ( + t3 INNER JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + +} +do_execsql_test joinC-5 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 INNER JOIN ( + t3 LEFT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 12 - - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-6 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 INNER JOIN ( + t3 LEFT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 12 - - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-7 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 INNER JOIN ( + t3 LEFT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 12 - - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-8 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 INNER JOIN ( + t3 LEFT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 12 - - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-9 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 INNER JOIN ( + t3 RIGHT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + +} +do_execsql_test joinC-10 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 INNER JOIN ( + t3 RIGHT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + +} +do_execsql_test joinC-11 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 INNER JOIN ( + t3 RIGHT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + +} +do_execsql_test joinC-12 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 INNER JOIN ( + t3 RIGHT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + +} +do_execsql_test joinC-13 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 INNER JOIN ( + t3 FULL JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 12 - - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-14 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 INNER JOIN ( + t3 FULL JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 12 - - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-15 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 INNER JOIN ( + t3 FULL JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 12 - - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-16 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 INNER JOIN ( + t3 FULL JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 12 - - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-17 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 LEFT JOIN ( + t3 INNER JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 - - - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-18 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 LEFT JOIN ( + t3 INNER JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 - - - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-19 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 LEFT JOIN ( + t3 INNER JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 - - - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-20 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 LEFT JOIN ( + t3 INNER JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 - - - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-21 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 LEFT JOIN ( + t3 LEFT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 12 - - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-22 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 LEFT JOIN ( + t3 LEFT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 12 - - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-23 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 LEFT JOIN ( + t3 LEFT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 12 - - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-24 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 LEFT JOIN ( + t3 LEFT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 12 - - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-25 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 LEFT JOIN ( + t3 RIGHT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 - - - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-26 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 LEFT JOIN ( + t3 RIGHT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 - - - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-27 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 LEFT JOIN ( + t3 RIGHT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 - - - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-28 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 LEFT JOIN ( + t3 RIGHT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 - - - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-29 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 LEFT JOIN ( + t3 FULL JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 12 - - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-30 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 LEFT JOIN ( + t3 FULL JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 12 - - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-31 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 LEFT JOIN ( + t3 FULL JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 12 - - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-32 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 LEFT JOIN ( + t3 FULL JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 12 - - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-33 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 RIGHT JOIN ( + t3 INNER JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + +} +do_execsql_test joinC-34 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 RIGHT JOIN ( + t3 INNER JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-35 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 RIGHT JOIN ( + t3 INNER JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-36 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 RIGHT JOIN ( + t3 INNER JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-37 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 RIGHT JOIN ( + t3 LEFT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - - + +} +do_execsql_test joinC-38 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 RIGHT JOIN ( + t3 LEFT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - - + +} +do_execsql_test joinC-39 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 RIGHT JOIN ( + t3 LEFT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-40 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 RIGHT JOIN ( + t3 LEFT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-41 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 RIGHT JOIN ( + t3 RIGHT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + +} +do_execsql_test joinC-42 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 RIGHT JOIN ( + t3 RIGHT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-43 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 RIGHT JOIN ( + t3 RIGHT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-44 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 RIGHT JOIN ( + t3 RIGHT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-45 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 RIGHT JOIN ( + t3 FULL JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - - + +} +do_execsql_test joinC-46 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 RIGHT JOIN ( + t3 FULL JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - - + +} +do_execsql_test joinC-47 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 RIGHT JOIN ( + t3 FULL JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-48 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 RIGHT JOIN ( + t3 FULL JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-49 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 FULL JOIN ( + t3 INNER JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 - - - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-50 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 FULL JOIN ( + t3 INNER JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 - - - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-51 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 FULL JOIN ( + t3 INNER JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 - - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-52 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 FULL JOIN ( + t3 INNER JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 - - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-53 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 FULL JOIN ( + t3 LEFT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - - + +} +do_execsql_test joinC-54 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 FULL JOIN ( + t3 LEFT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - - + +} +do_execsql_test joinC-55 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 FULL JOIN ( + t3 LEFT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-56 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 FULL JOIN ( + t3 LEFT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-57 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 FULL JOIN ( + t3 RIGHT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 - - - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-58 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 FULL JOIN ( + t3 RIGHT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 - - - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-59 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 FULL JOIN ( + t3 RIGHT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 - - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-60 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 FULL JOIN ( + t3 RIGHT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 - - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-61 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 FULL JOIN ( + t3 FULL JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - - + +} +do_execsql_test joinC-62 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 FULL JOIN ( + t3 FULL JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - - + +} +do_execsql_test joinC-63 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 FULL JOIN ( + t3 FULL JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-64 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 INNER JOIN ( + t2 FULL JOIN ( + t3 FULL JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-65 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 INNER JOIN ( + t3 INNER JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 - - - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-66 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 INNER JOIN ( + t3 INNER JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 - - - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-67 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 INNER JOIN ( + t3 INNER JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 - - - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-68 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 INNER JOIN ( + t3 INNER JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 - - - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-69 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 INNER JOIN ( + t3 LEFT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-70 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 INNER JOIN ( + t3 LEFT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-71 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 INNER JOIN ( + t3 LEFT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-72 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 INNER JOIN ( + t3 LEFT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-73 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 INNER JOIN ( + t3 RIGHT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 - - - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-74 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 INNER JOIN ( + t3 RIGHT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 - - - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-75 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 INNER JOIN ( + t3 RIGHT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 - - - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-76 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 INNER JOIN ( + t3 RIGHT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 - - - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-77 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 INNER JOIN ( + t3 FULL JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-78 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 INNER JOIN ( + t3 FULL JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-79 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 INNER JOIN ( + t3 FULL JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-80 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 INNER JOIN ( + t3 FULL JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-81 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 LEFT JOIN ( + t3 INNER JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 - - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-82 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 LEFT JOIN ( + t3 INNER JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 - - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-83 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 LEFT JOIN ( + t3 INNER JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 - - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-84 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 LEFT JOIN ( + t3 INNER JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 - - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-85 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 LEFT JOIN ( + t3 LEFT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-86 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 LEFT JOIN ( + t3 LEFT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-87 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 LEFT JOIN ( + t3 LEFT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-88 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 LEFT JOIN ( + t3 LEFT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-89 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 LEFT JOIN ( + t3 RIGHT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 - - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-90 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 LEFT JOIN ( + t3 RIGHT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 - - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-91 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 LEFT JOIN ( + t3 RIGHT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 - - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-92 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 LEFT JOIN ( + t3 RIGHT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 - - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-93 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 LEFT JOIN ( + t3 FULL JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-94 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 LEFT JOIN ( + t3 FULL JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-95 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 LEFT JOIN ( + t3 FULL JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-96 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 LEFT JOIN ( + t3 FULL JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-97 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 RIGHT JOIN ( + t3 INNER JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 - - - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-98 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 RIGHT JOIN ( + t3 INNER JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 - - - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-99 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 RIGHT JOIN ( + t3 INNER JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 - - - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-100 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 RIGHT JOIN ( + t3 INNER JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 - - - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-101 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 RIGHT JOIN ( + t3 LEFT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - - + +} +do_execsql_test joinC-102 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 RIGHT JOIN ( + t3 LEFT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - - + +} +do_execsql_test joinC-103 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 RIGHT JOIN ( + t3 LEFT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-104 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 RIGHT JOIN ( + t3 LEFT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-105 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 RIGHT JOIN ( + t3 RIGHT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 - - - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-106 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 RIGHT JOIN ( + t3 RIGHT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 - - - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-107 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 RIGHT JOIN ( + t3 RIGHT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 - - - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-108 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 RIGHT JOIN ( + t3 RIGHT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 - - - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-109 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 RIGHT JOIN ( + t3 FULL JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - - + +} +do_execsql_test joinC-110 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 RIGHT JOIN ( + t3 FULL JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - - + +} +do_execsql_test joinC-111 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 RIGHT JOIN ( + t3 FULL JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-112 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 RIGHT JOIN ( + t3 FULL JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-113 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 FULL JOIN ( + t3 INNER JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 - - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-114 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 FULL JOIN ( + t3 INNER JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 - - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-115 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 FULL JOIN ( + t3 INNER JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 - - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-116 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 FULL JOIN ( + t3 INNER JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 - - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-117 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 FULL JOIN ( + t3 LEFT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - - + +} +do_execsql_test joinC-118 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 FULL JOIN ( + t3 LEFT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - - + +} +do_execsql_test joinC-119 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 FULL JOIN ( + t3 LEFT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-120 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 FULL JOIN ( + t3 LEFT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-121 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 FULL JOIN ( + t3 RIGHT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 - - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-122 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 FULL JOIN ( + t3 RIGHT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 - - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-123 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 FULL JOIN ( + t3 RIGHT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 - - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-124 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 FULL JOIN ( + t3 RIGHT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 - - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-125 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 FULL JOIN ( + t3 FULL JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - - + +} +do_execsql_test joinC-126 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 FULL JOIN ( + t3 FULL JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - - + +} +do_execsql_test joinC-127 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 FULL JOIN ( + t3 FULL JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 - - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-128 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 LEFT JOIN ( + t2 FULL JOIN ( + t3 FULL JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 12 12 - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + +} +do_execsql_test joinC-129 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 INNER JOIN ( + t3 INNER JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + +} +do_execsql_test joinC-130 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 INNER JOIN ( + t3 INNER JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 13 - 13 13 13 - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-131 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 INNER JOIN ( + t3 INNER JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 18 - 18 18 - 18 + +} +do_execsql_test joinC-132 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 INNER JOIN ( + t3 INNER JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 13 - 13 13 13 - + 15 15 15 15 15 15 + 18 - 18 18 - 18 + +} +do_execsql_test joinC-133 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 INNER JOIN ( + t3 LEFT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 18 - 18 18 - - + +} +do_execsql_test joinC-134 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 INNER JOIN ( + t3 LEFT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 18 - 18 18 - - + +} +do_execsql_test joinC-135 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 INNER JOIN ( + t3 LEFT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 18 - 18 18 - 18 + +} +do_execsql_test joinC-136 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 INNER JOIN ( + t3 LEFT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 18 - 18 18 - 18 + +} +do_execsql_test joinC-137 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 INNER JOIN ( + t3 RIGHT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + +} +do_execsql_test joinC-138 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 INNER JOIN ( + t3 RIGHT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 13 - 13 13 13 - + 15 15 15 15 15 15 + +} +do_execsql_test joinC-139 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 INNER JOIN ( + t3 RIGHT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 18 - 18 18 - 18 + +} +do_execsql_test joinC-140 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 INNER JOIN ( + t3 RIGHT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 13 - 13 13 13 - + 15 15 15 15 15 15 + 18 - 18 18 - 18 + +} +do_execsql_test joinC-141 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 INNER JOIN ( + t3 FULL JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 18 - 18 18 - - + +} +do_execsql_test joinC-142 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 INNER JOIN ( + t3 FULL JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 18 - 18 18 - - + +} +do_execsql_test joinC-143 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 INNER JOIN ( + t3 FULL JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 18 - 18 18 - 18 + +} +do_execsql_test joinC-144 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 INNER JOIN ( + t3 FULL JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 18 - 18 18 - 18 + +} +do_execsql_test joinC-145 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 LEFT JOIN ( + t3 INNER JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 12 12 12 - - - + 13 - 13 - - - + 15 15 15 15 15 15 + 18 - 18 - - - + +} +do_execsql_test joinC-146 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 LEFT JOIN ( + t3 INNER JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 12 12 12 - - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 18 - 18 - - - + +} +do_execsql_test joinC-147 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 LEFT JOIN ( + t3 INNER JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 12 12 12 - - - + 13 - 13 - - - + 15 15 15 15 15 15 + 18 - 18 18 - 18 + +} +do_execsql_test joinC-148 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 LEFT JOIN ( + t3 INNER JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 12 12 12 - - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 18 - 18 18 - 18 + +} +do_execsql_test joinC-149 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 LEFT JOIN ( + t3 LEFT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 18 - 18 18 - - + +} +do_execsql_test joinC-150 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 LEFT JOIN ( + t3 LEFT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 18 - 18 18 - - + +} +do_execsql_test joinC-151 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 LEFT JOIN ( + t3 LEFT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 18 - 18 18 - 18 + +} +do_execsql_test joinC-152 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 LEFT JOIN ( + t3 LEFT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 18 - 18 18 - 18 + +} +do_execsql_test joinC-153 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 LEFT JOIN ( + t3 RIGHT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 12 12 12 - - - + 13 - 13 - - - + 15 15 15 15 15 15 + 18 - 18 - - - + +} +do_execsql_test joinC-154 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 LEFT JOIN ( + t3 RIGHT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 12 12 12 - - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 18 - 18 - - - + +} +do_execsql_test joinC-155 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 LEFT JOIN ( + t3 RIGHT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 12 12 12 - - - + 13 - 13 - - - + 15 15 15 15 15 15 + 18 - 18 18 - 18 + +} +do_execsql_test joinC-156 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 LEFT JOIN ( + t3 RIGHT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 12 12 12 - - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 18 - 18 18 - 18 + +} +do_execsql_test joinC-157 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 LEFT JOIN ( + t3 FULL JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 18 - 18 18 - - + +} +do_execsql_test joinC-158 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 LEFT JOIN ( + t3 FULL JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 18 - 18 18 - - + +} +do_execsql_test joinC-159 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 LEFT JOIN ( + t3 FULL JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 18 - 18 18 - 18 + +} +do_execsql_test joinC-160 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 LEFT JOIN ( + t3 FULL JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 18 - 18 18 - 18 + +} +do_execsql_test joinC-161 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 RIGHT JOIN ( + t3 INNER JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 19 - - 19 19 19 + +} +do_execsql_test joinC-162 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 RIGHT JOIN ( + t3 INNER JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 19 - - 19 19 19 + +} +do_execsql_test joinC-163 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 RIGHT JOIN ( + t3 INNER JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +do_execsql_test joinC-164 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 RIGHT JOIN ( + t3 INNER JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +do_execsql_test joinC-165 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 RIGHT JOIN ( + t3 LEFT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 - - + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 17 17 - 17 - - + 18 - 18 18 - - + 19 - - 19 19 19 + +} +do_execsql_test joinC-166 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 RIGHT JOIN ( + t3 LEFT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - - + 18 - 18 18 - - + 19 - - 19 19 19 + +} +do_execsql_test joinC-167 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 RIGHT JOIN ( + t3 LEFT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 - - + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +do_execsql_test joinC-168 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 RIGHT JOIN ( + t3 LEFT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +do_execsql_test joinC-169 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 RIGHT JOIN ( + t3 RIGHT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 19 - - 19 19 19 + +} +do_execsql_test joinC-170 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 RIGHT JOIN ( + t3 RIGHT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 19 - - 19 19 19 + +} +do_execsql_test joinC-171 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 RIGHT JOIN ( + t3 RIGHT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +do_execsql_test joinC-172 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 RIGHT JOIN ( + t3 RIGHT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +do_execsql_test joinC-173 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 RIGHT JOIN ( + t3 FULL JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 - - + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 17 17 - 17 - - + 18 - 18 18 - - + 19 - - 19 19 19 + +} +do_execsql_test joinC-174 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 RIGHT JOIN ( + t3 FULL JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - - + 18 - 18 18 - - + 19 - - 19 19 19 + +} +do_execsql_test joinC-175 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 RIGHT JOIN ( + t3 FULL JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 - - + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +do_execsql_test joinC-176 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 RIGHT JOIN ( + t3 FULL JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +do_execsql_test joinC-177 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 FULL JOIN ( + t3 INNER JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 12 12 12 - - - + 13 - 13 - - - + 15 15 15 15 15 15 + 18 - 18 - - - + 19 - - 19 19 19 + +} +do_execsql_test joinC-178 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 FULL JOIN ( + t3 INNER JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 - - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 18 - 18 - - - + 19 - - 19 19 19 + +} +do_execsql_test joinC-179 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 FULL JOIN ( + t3 INNER JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 12 12 12 - - - + 13 - 13 - - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +do_execsql_test joinC-180 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 FULL JOIN ( + t3 INNER JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 - - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +do_execsql_test joinC-181 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 FULL JOIN ( + t3 LEFT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + - - - - - - + 11 11 - 11 - - + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 17 17 - 17 - - + 18 - 18 18 - - + 19 - - 19 19 19 + +} +do_execsql_test joinC-182 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 FULL JOIN ( + t3 LEFT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - - + 18 - 18 18 - - + 19 - - 19 19 19 + +} +do_execsql_test joinC-183 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 FULL JOIN ( + t3 LEFT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + - - - - - - + 11 11 - 11 - - + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +do_execsql_test joinC-184 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 FULL JOIN ( + t3 LEFT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +do_execsql_test joinC-185 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 FULL JOIN ( + t3 RIGHT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 12 12 12 - - - + 13 - 13 - - - + 15 15 15 15 15 15 + 18 - 18 - - - + 19 - - 19 19 19 + +} +do_execsql_test joinC-186 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 FULL JOIN ( + t3 RIGHT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 - - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 18 - 18 - - - + 19 - - 19 19 19 + +} +do_execsql_test joinC-187 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 FULL JOIN ( + t3 RIGHT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 12 12 12 - - - + 13 - 13 - - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +do_execsql_test joinC-188 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 FULL JOIN ( + t3 RIGHT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 - - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +do_execsql_test joinC-189 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 FULL JOIN ( + t3 FULL JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + - - - - - - + 11 11 - 11 - - + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 17 17 - 17 - - + 18 - 18 18 - - + 19 - - 19 19 19 + +} +do_execsql_test joinC-190 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 FULL JOIN ( + t3 FULL JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - - + 18 - 18 18 - - + 19 - - 19 19 19 + +} +do_execsql_test joinC-191 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 FULL JOIN ( + t3 FULL JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + - - - - - - + 11 11 - 11 - - + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +do_execsql_test joinC-192 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 RIGHT JOIN ( + t2 FULL JOIN ( + t3 FULL JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +do_execsql_test joinC-193 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 INNER JOIN ( + t3 INNER JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 - - - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-194 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 INNER JOIN ( + t3 INNER JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 - - - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-195 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 INNER JOIN ( + t3 INNER JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 - - - - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 18 - 18 + +} +do_execsql_test joinC-196 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 INNER JOIN ( + t3 INNER JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 - - - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 18 - 18 + +} +do_execsql_test joinC-197 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 INNER JOIN ( + t3 LEFT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 18 - - + +} +do_execsql_test joinC-198 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 INNER JOIN ( + t3 LEFT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 18 - - + +} +do_execsql_test joinC-199 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 INNER JOIN ( + t3 LEFT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 18 - 18 + +} +do_execsql_test joinC-200 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 INNER JOIN ( + t3 LEFT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 18 - 18 + +} +do_execsql_test joinC-201 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 INNER JOIN ( + t3 RIGHT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 - - - - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-202 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 INNER JOIN ( + t3 RIGHT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 - - - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - - - - + +} +do_execsql_test joinC-203 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 INNER JOIN ( + t3 RIGHT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 - - - - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 18 - 18 + +} +do_execsql_test joinC-204 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 INNER JOIN ( + t3 RIGHT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 - - - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 18 - 18 + +} +do_execsql_test joinC-205 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 INNER JOIN ( + t3 FULL JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 18 - - + +} +do_execsql_test joinC-206 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 INNER JOIN ( + t3 FULL JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 18 - - + +} +do_execsql_test joinC-207 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 INNER JOIN ( + t3 FULL JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 18 - 18 + +} +do_execsql_test joinC-208 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 INNER JOIN ( + t3 FULL JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 18 - 18 + +} +do_execsql_test joinC-209 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 LEFT JOIN ( + t3 INNER JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - - - - + 12 12 12 - - - + 13 - 13 - - - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 - - - + +} +do_execsql_test joinC-210 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 LEFT JOIN ( + t3 INNER JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - - - - + 12 12 12 - - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 - - - + +} +do_execsql_test joinC-211 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 LEFT JOIN ( + t3 INNER JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - - - - + 12 12 12 - - - + 13 - 13 - - - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 18 - 18 + +} +do_execsql_test joinC-212 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 LEFT JOIN ( + t3 INNER JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - - - - + 12 12 12 - - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 18 - 18 + +} +do_execsql_test joinC-213 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 LEFT JOIN ( + t3 LEFT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - - - - + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 18 - - + +} +do_execsql_test joinC-214 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 LEFT JOIN ( + t3 LEFT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - - - - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 18 - - + +} +do_execsql_test joinC-215 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 LEFT JOIN ( + t3 LEFT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - - - - + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 18 - 18 + +} +do_execsql_test joinC-216 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 LEFT JOIN ( + t3 LEFT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - - - - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 18 - 18 + +} +do_execsql_test joinC-217 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 LEFT JOIN ( + t3 RIGHT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - - - - + 12 12 12 - - - + 13 - 13 - - - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 - - - + +} +do_execsql_test joinC-218 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 LEFT JOIN ( + t3 RIGHT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - - - - + 12 12 12 - - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 - - - + +} +do_execsql_test joinC-219 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 LEFT JOIN ( + t3 RIGHT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - - - - + 12 12 12 - - - + 13 - 13 - - - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 18 - 18 + +} +do_execsql_test joinC-220 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 LEFT JOIN ( + t3 RIGHT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - - - - + 12 12 12 - - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 18 - 18 + +} +do_execsql_test joinC-221 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 LEFT JOIN ( + t3 FULL JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - - - - + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 18 - - + +} +do_execsql_test joinC-222 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 LEFT JOIN ( + t3 FULL JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - - - - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 18 - - + +} +do_execsql_test joinC-223 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 LEFT JOIN ( + t3 FULL JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - - - - + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 18 - 18 + +} +do_execsql_test joinC-224 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 LEFT JOIN ( + t3 FULL JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - - - - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 18 - 18 + +} +do_execsql_test joinC-225 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 RIGHT JOIN ( + t3 INNER JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 - - - - + 15 15 15 15 15 15 + 17 17 - - - - + 19 - - 19 19 19 + +} +do_execsql_test joinC-226 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 RIGHT JOIN ( + t3 INNER JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 - - - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - - - - + 19 - - 19 19 19 + +} +do_execsql_test joinC-227 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 RIGHT JOIN ( + t3 INNER JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 - - - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +do_execsql_test joinC-228 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 RIGHT JOIN ( + t3 INNER JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 - - - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +do_execsql_test joinC-229 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 RIGHT JOIN ( + t3 LEFT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 - - + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 17 17 - 17 - - + 18 - 18 18 - - + 19 - - 19 19 19 + +} +do_execsql_test joinC-230 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 RIGHT JOIN ( + t3 LEFT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - - + 18 - 18 18 - - + 19 - - 19 19 19 + +} +do_execsql_test joinC-231 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 RIGHT JOIN ( + t3 LEFT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 - - + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +do_execsql_test joinC-232 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 RIGHT JOIN ( + t3 LEFT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +do_execsql_test joinC-233 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 RIGHT JOIN ( + t3 RIGHT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 - - - - + 15 15 15 15 15 15 + 17 17 - - - - + 19 - - 19 19 19 + +} +do_execsql_test joinC-234 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 RIGHT JOIN ( + t3 RIGHT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 - - - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - - - - + 19 - - 19 19 19 + +} +do_execsql_test joinC-235 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 RIGHT JOIN ( + t3 RIGHT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - - - - + 12 12 - - - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +do_execsql_test joinC-236 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 RIGHT JOIN ( + t3 RIGHT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + 11 11 - 11 11 - + 12 12 - - - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +do_execsql_test joinC-237 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 RIGHT JOIN ( + t3 FULL JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 - - + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 17 17 - 17 - - + 18 - 18 18 - - + 19 - - 19 19 19 + +} +do_execsql_test joinC-238 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 RIGHT JOIN ( + t3 FULL JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - - + 18 - 18 18 - - + 19 - - 19 19 19 + +} +do_execsql_test joinC-239 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 RIGHT JOIN ( + t3 FULL JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 - - + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +do_execsql_test joinC-240 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 RIGHT JOIN ( + t3 FULL JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +do_execsql_test joinC-241 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 FULL JOIN ( + t3 INNER JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - - - - + 12 12 12 - - - + 13 - 13 - - - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 - - - + 19 - - 19 19 19 + +} +do_execsql_test joinC-242 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 FULL JOIN ( + t3 INNER JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 - - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 - - - + 19 - - 19 19 19 + +} +do_execsql_test joinC-243 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 FULL JOIN ( + t3 INNER JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - - - - + 12 12 12 - - - + 13 - 13 - - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +do_execsql_test joinC-244 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 FULL JOIN ( + t3 INNER JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 - - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +do_execsql_test joinC-245 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 FULL JOIN ( + t3 LEFT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + - - - - - - + 11 11 - 11 - - + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 17 17 - 17 - - + 18 - 18 18 - - + 19 - - 19 19 19 + +} +do_execsql_test joinC-246 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 FULL JOIN ( + t3 LEFT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - - + 18 - 18 18 - - + 19 - - 19 19 19 + +} +do_execsql_test joinC-247 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 FULL JOIN ( + t3 LEFT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + - - - - - - + 11 11 - 11 - - + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +do_execsql_test joinC-248 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 FULL JOIN ( + t3 LEFT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +do_execsql_test joinC-249 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 FULL JOIN ( + t3 RIGHT JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - - - - + 12 12 12 - - - + 13 - 13 - - - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 - - - + 19 - - 19 19 19 + +} +do_execsql_test joinC-250 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 FULL JOIN ( + t3 RIGHT JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 - - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - - - - + 18 - 18 - - - + 19 - - 19 19 19 + +} +do_execsql_test joinC-251 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 FULL JOIN ( + t3 RIGHT JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - - - - + 12 12 12 - - - + 13 - 13 - - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +do_execsql_test joinC-252 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 FULL JOIN ( + t3 RIGHT JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + 11 11 - 11 11 - + 12 12 12 - - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +do_execsql_test joinC-253 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 FULL JOIN ( + t3 FULL JOIN ( + t4 INNER JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + - - - - - - + 11 11 - 11 - - + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 17 17 - 17 - - + 18 - 18 18 - - + 19 - - 19 19 19 + +} +do_execsql_test joinC-254 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 FULL JOIN ( + t3 FULL JOIN ( + t4 LEFT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - - + 18 - 18 18 - - + 19 - - 19 19 19 + +} +do_execsql_test joinC-255 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 FULL JOIN ( + t3 FULL JOIN ( + t4 RIGHT JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + - - - - - - + 11 11 - 11 - - + 12 12 12 12 - - + 13 - 13 13 - - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +do_execsql_test joinC-256 { + SELECT a, t1.a, t2.a, t3.a, t4.a, t5.a + FROM t1 FULL JOIN ( + t2 FULL JOIN ( + t3 FULL JOIN ( + t4 FULL JOIN t5 USING(a) + ) USING(a) + ) USING(a) + ) USING(a) + ORDER BY 1 NULLS FIRST; +} { + - - - - - - + - - - - - - + 11 11 - 11 11 - + 12 12 12 12 - - + 13 - 13 13 13 - + 15 15 15 15 15 15 + 17 17 - 17 - 17 + 18 - 18 18 - 18 + 19 - - 19 19 19 + +} +finish_test From a087eb8f6d28a05f3dbe8a4eee9deb45b746865d Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 28 Apr 2022 18:17:51 +0000 Subject: [PATCH 224/259] In treeview.c, show the columns of the table associated with each SrcItem. FossilOrigin-Name: 3aafccb5c3c780c29090ee5eb428a6c3153627ce8bf834bbd392e79a30e9389b --- manifest | 14 ++++++------- manifest.uuid | 2 +- src/sqliteInt.h | 1 + src/treeview.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 60 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 6940dc03a5..e7f03310c2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Tweaks\sto\sthe\sname\sresolution\son\sparenthesized\sjoins.\s\sA\ssmall\snumber\sof\ntests\sfail\snow\sdue\sto\sextra\scolumns\sappearing\sin\sthe\sexpansion\sof\s"*". -D 2022-04-28T17:35:58.976 +C In\streeview.c,\sshow\sthe\scolumns\sof\sthe\stable\sassociated\swith\seach\sSrcItem. +D 2022-04-28T18:17:51.855 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -558,7 +558,7 @@ F src/shell.c.in ae0a6fae983caac6f8c824733f0599dfdf7b3a7e8efdef3cb5e3ab2e457ffc3 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h 0266967fa78be24d3c32c42bc2c4ab44a2a2c670cebaa9fd9fa22ad63c106fc6 +F src/sqliteInt.h 453038c918b337a708a73106cf51bdce5aa442ec705854449dba94832eafd5e5 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -618,7 +618,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98 -F src/treeview.c 2fb6681614cfdf44c5df1a54a8d17c1fe31c2dbb226db99df8693dbd8c02f598 +F src/treeview.c d9c5192f2c6b0a407a1ba08ca9e034cdedfcb0120a10d7a3fa8714c7df33cc0a F src/trigger.c 372ada38f667c6823a3db15749eb668338e65c793394e55a37e56a489f2d1b55 F src/update.c 2cfaded82ca80ff56afb8c3ae5e88284e0824bfd86119827cc22481959f96f92 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 @@ -1952,8 +1952,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 3fd9706bba4a71cb5c7ce1341c3be0a7727941445820a073e7b2f0f32512e8ef -R 53c4a50b3b49e4ffda08971a28c23faf +P c86804917e3fffcf0c19bbf11875667f7968275210fc768e650826bd9c87a5d2 +R 7f4fb98be4c8c890dd54dec76be25961 U drh -Z c38c4449faac7a680433a77b8e09acfd +Z 16a509b7728b4678c071207eaf46d79a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index e930a0fcec..8de9a84312 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c86804917e3fffcf0c19bbf11875667f7968275210fc768e650826bd9c87a5d2 \ No newline at end of file +3aafccb5c3c780c29090ee5eb428a6c3153627ce8bf834bbd392e79a30e9389b \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index eb8ad2abe9..f483cc4984 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4461,6 +4461,7 @@ char *sqlite3VMPrintf(sqlite3*,const char*, va_list); void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*); void sqlite3TreeViewBareIdList(TreeView*, const IdList*, const char*); void sqlite3TreeViewIdList(TreeView*, const IdList*, u8, const char*); + void sqlite3TreeViewColumnList(TreeView*, const Column*, int, u8); void sqlite3TreeViewSrcList(TreeView*, const SrcList*); void sqlite3TreeViewSelect(TreeView*, const Select*, u8); void sqlite3TreeViewWith(TreeView*, const With*, u8); diff --git a/src/treeview.c b/src/treeview.c index 117e21f1af..009ba27398 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -86,6 +86,51 @@ static void sqlite3TreeViewItem(TreeView *p, const char *zLabel,u8 moreFollows){ sqlite3TreeViewLine(p, "%s", zLabel); } +/* +** Show a list of Column objects in tree format. +*/ +void sqlite3TreeViewColumnList( + TreeView *pView, + const Column *aCol, + int nCol, + u8 moreToFollow +){ + int i; + sqlite3TreeViewPush(&pView, moreToFollow); + sqlite3TreeViewLine(pView, "COLUMNS"); + for(i=0; iu2.pCteUse); } sqlite3StrAccumFinish(&x); - sqlite3TreeViewItem(pView, zLine, inSrc-1); + sqlite3TreeViewItem(pView, zLine, inSrc-1); + if( pItem->pTab ){ + Table *pTab = pItem->pTab; + sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, + pItem->pSelect!=0); + } if( pItem->pSelect ){ assert( pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); sqlite3TreeViewSelect(pView, pItem->pSelect, 0); From 07fd1bf3235de9cd6ac53fd7e6466faa3c76f3e3 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 28 Apr 2022 18:33:02 +0000 Subject: [PATCH 225/259] Fix problem with SQLITE_OMIT_VIRTUALTABLE builds. FossilOrigin-Name: a99ee612b9bd6d75b63e557ef5bdac2143425a558cf023a0480cc28c8300a9a8 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/loadext.c | 8 ++++++++ 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 4b561cb6fc..a89e18bdd4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sharmless\stypo\sin\sa\scomment. -D 2022-04-27T18:38:46.859 +C Fix\sproblem\swith\sSQLITE_OMIT_VIRTUALTABLE\sbuilds. +D 2022-04-28T18:33:02.668 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -516,7 +516,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 173845e5a6bac96ae937409e4f876b631f26b31dabb9df8fd0eb3b130b2bb3a7 F src/json.c 7749b98c62f691697c7ee536b570c744c0583cab4a89200fdd0fc2aa8cc8cbd6 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa -F src/loadext.c 2ecb1441f9b1c22e9e022ee0776e67d259facf34b56ba892b206f0a294ee6f8c +F src/loadext.c 0705c2747212934183398f09891415d2f7f3113d0f543ccb205640210b20e617 F src/main.c 135858d2ede0b83d779e71b07ede9c1d6b6eaab7b77bc2a85729584152769faf F src/malloc.c a9127efdcef92d6934c6339ea9813075b90edc0ce2e5c723556381a3828fb720 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 @@ -1951,8 +1951,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 eb59c46a5aed69bc6fd096997bf24c082e533c1085439f6ec1fbe5ff78e8b374 -R f499c3fddca86db7a0183d3ecdb0953b -U drh -Z 7426364b9684e9a6fe822d40fffa4b25 +P e1f4a115df34e45cf1bcf98961c699b582f564a58a979e95853b219bda06212c +R 3b19b9ac79d036b17b28019016199748 +U dan +Z 4c18f3559ff049507c583c5510546b21 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 1daa831936..937575bb83 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e1f4a115df34e45cf1bcf98961c699b582f564a58a979e95853b219bda06212c \ No newline at end of file +a99ee612b9bd6d75b63e557ef5bdac2143425a558cf023a0480cc28c8300a9a8 \ No newline at end of file diff --git a/src/loadext.c b/src/loadext.c index cefe2eb94c..bba431096d 100644 --- a/src/loadext.c +++ b/src/loadext.c @@ -487,11 +487,19 @@ static const sqlite3_api_routines sqlite3Apis = { sqlite3_autovacuum_pages, /* Version 3.38.0 and later */ sqlite3_error_offset, +#ifndef SQLITE_OMIT_VIRTUALTABLE sqlite3_vtab_rhs_value, sqlite3_vtab_distinct, sqlite3_vtab_in, sqlite3_vtab_in_first, sqlite3_vtab_in_next, +#else + 0, + 0, + 0, + 0, + 0, +#endif /* Version 3.39.0 and later */ #ifndef SQLITE_OMIT_DESERIALIZE sqlite3_deserialize, From de7a820fd028aef290d8a0d4ffe0a2b080302acf Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 29 Apr 2022 12:09:43 +0000 Subject: [PATCH 226/259] Minor typo fix in a comment, for the benefit of broken IDE syntax highlighters. FossilOrigin-Name: 680ccecbc839373194ed2dcc1053e25512d9ea3f12f8c8963cb8fbd1a034d2f8 --- ext/fts5/fts5_index.c | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 6b88f31c02..d2ec9ad5a9 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -296,7 +296,7 @@ struct Fts5Index { sqlite3_stmt *pWriter; /* "INSERT ... %_data VALUES(?,?)" */ sqlite3_stmt *pDeleter; /* "DELETE FROM %_data ... id>=? AND id<=?" */ sqlite3_stmt *pIdxWriter; /* "INSERT ... %_idx VALUES(?,?,?,?)" */ - sqlite3_stmt *pIdxDeleter; /* "DELETE FROM %_idx WHERE segid=? */ + sqlite3_stmt *pIdxDeleter; /* "DELETE FROM %_idx WHERE segid=?" */ sqlite3_stmt *pIdxSelect; int nRead; /* Total number of blocks read */ diff --git a/manifest b/manifest index a89e18bdd4..f0a5bf60fe 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sproblem\swith\sSQLITE_OMIT_VIRTUALTABLE\sbuilds. -D 2022-04-28T18:33:02.668 +C Minor\stypo\sfix\sin\sa\scomment,\sfor\sthe\sbenefit\sof\sbroken\sIDE\ssyntax\shighlighters. +D 2022-04-29T12:09:43.642 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -119,7 +119,7 @@ F ext/fts5/fts5_buffer.c 3001fbabb585d6de52947b44b455235072b741038391f830d6b7292 F ext/fts5/fts5_config.c 501e7d3566bc92766b0e11c0109a7c5a6146bc41144195459af5422f6c2078aa F ext/fts5/fts5_expr.c 40174a64829d30cc86e8266306ad24980f6911edd5ca0b8c1ce7821ea1341b88 F ext/fts5/fts5_hash.c d4fb70940359f2120ccd1de7ffe64cc3efe65de9e8995b822cd536ff64c96982 -F ext/fts5/fts5_index.c fdfbc8a62827ec1d1b6f207a1e59c1c4986c3ce245592b5128ffe738867cfcd1 +F ext/fts5/fts5_index.c 3e47d9c56e4e9a6dee78bc32e006d6a28a3b5ec9ff84f3b8c381c78323201720 F ext/fts5/fts5_main.c 6078ae86d3b813753a4f1201054550aff21a3f660e97b30f200d2b1472874151 F ext/fts5/fts5_storage.c 76c6085239eb44424004c022e9da17a5ecd5aaec859fba90ad47d3b08f4c8082 F ext/fts5/fts5_tcl.c b1445cbe69908c411df8084a10b2485500ac70a9c747cdc8cda175a3da59d8ae @@ -1951,8 +1951,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 e1f4a115df34e45cf1bcf98961c699b582f564a58a979e95853b219bda06212c -R 3b19b9ac79d036b17b28019016199748 -U dan -Z 4c18f3559ff049507c583c5510546b21 +P a99ee612b9bd6d75b63e557ef5bdac2143425a558cf023a0480cc28c8300a9a8 +R f727db70a6530c6b0b6ca0186b0c1cb8 +U drh +Z 671faa44cd5bf3867df213bd33bc9ae5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 937575bb83..5954c9dc3f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a99ee612b9bd6d75b63e557ef5bdac2143425a558cf023a0480cc28c8300a9a8 \ No newline at end of file +680ccecbc839373194ed2dcc1053e25512d9ea3f12f8c8963cb8fbd1a034d2f8 \ No newline at end of file From 08e1a6a29b58ea62df1197a9e91f8c63b246cf25 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 29 Apr 2022 17:03:25 +0000 Subject: [PATCH 227/259] Show the USING clause as part of the tree-view display of SrcItem. FossilOrigin-Name: 9cba3ce577e442f83d7a2d6926e38ffe6bc45953c88ecdd384f3455890303cce --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/treeview.c | 14 +++++++++++--- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index e7f03310c2..ee8227b22f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\streeview.c,\sshow\sthe\scolumns\sof\sthe\stable\sassociated\swith\seach\sSrcItem. -D 2022-04-28T18:17:51.855 +C Show\sthe\sUSING\sclause\sas\spart\sof\sthe\stree-view\sdisplay\sof\sSrcItem. +D 2022-04-29T17:03:25.685 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -618,7 +618,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98 -F src/treeview.c d9c5192f2c6b0a407a1ba08ca9e034cdedfcb0120a10d7a3fa8714c7df33cc0a +F src/treeview.c 06fbe7bcd8703ff037c831251ca197c3e39801a2d4c75a278581413ec52b2bdd F src/trigger.c 372ada38f667c6823a3db15749eb668338e65c793394e55a37e56a489f2d1b55 F src/update.c 2cfaded82ca80ff56afb8c3ae5e88284e0824bfd86119827cc22481959f96f92 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 @@ -1952,8 +1952,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 c86804917e3fffcf0c19bbf11875667f7968275210fc768e650826bd9c87a5d2 -R 7f4fb98be4c8c890dd54dec76be25961 +P 3aafccb5c3c780c29090ee5eb428a6c3153627ce8bf834bbd392e79a30e9389b +R 8943973edba9ba4c2b994eff77854a7b U drh -Z 16a509b7728b4678c071207eaf46d79a +Z ac8b1738cb42dc17aee412492b492bec # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8de9a84312..80c0be0c08 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3aafccb5c3c780c29090ee5eb428a6c3153627ce8bf834bbd392e79a30e9389b \ No newline at end of file +9cba3ce577e442f83d7a2d6926e38ffe6bc45953c88ecdd384f3455890303cce \ No newline at end of file diff --git a/src/treeview.c b/src/treeview.c index 009ba27398..04ee80f7ac 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -186,6 +186,7 @@ void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ for(i=0; inSrc; i++){ const SrcItem *pItem = &pSrc->a[i]; StrAccum x; + int n = 0; char zLine[100]; sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); x.printfFlags |= SQLITE_PRINTF_INTERNAL; @@ -214,14 +215,21 @@ void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ } sqlite3StrAccumFinish(&x); sqlite3TreeViewItem(pView, zLine, inSrc-1); + n = 0; + if( pItem->pTab ) n++; + if( pItem->pSelect ) n++; + if( pItem->fg.isTabFunc ) n++; + if( pItem->fg.isUsing ) n++; + if( pItem->fg.isUsing ){ + sqlite3TreeViewIdList(pView, pItem->u3.pUsing, (--n)>0, "USING"); + } if( pItem->pTab ){ Table *pTab = pItem->pTab; - sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, - pItem->pSelect!=0); + sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, (--n)>0); } if( pItem->pSelect ){ assert( pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); - sqlite3TreeViewSelect(pView, pItem->pSelect, 0); + sqlite3TreeViewSelect(pView, pItem->pSelect, (--n)>0); } if( pItem->fg.isTabFunc ){ sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:"); From 0c0d0526dceb2a1aab97539d041e777a0cadcd89 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 29 Apr 2022 17:13:52 +0000 Subject: [PATCH 228/259] Multiple enhancements to the TreeView output for SrcItem, cherrypicked from the right-join experimental branch. FossilOrigin-Name: 293afa81112e824eec2557d004a27319d484276f796936e16d64243fe24f6b68 --- manifest | 16 +++++++------ manifest.uuid | 2 +- src/sqliteInt.h | 1 + src/treeview.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 73 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index f0a5bf60fe..1db87ff47d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\stypo\sfix\sin\sa\scomment,\sfor\sthe\sbenefit\sof\sbroken\sIDE\ssyntax\shighlighters. -D 2022-04-29T12:09:43.642 +C Multiple\senhancements\sto\sthe\sTreeView\soutput\sfor\sSrcItem,\scherrypicked\sfrom\nthe\sright-join\sexperimental\sbranch. +D 2022-04-29T17:13:52.271 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -558,7 +558,7 @@ F src/shell.c.in ae0a6fae983caac6f8c824733f0599dfdf7b3a7e8efdef3cb5e3ab2e457ffc3 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h 11cd60560cd14bb6eecd04d244faf4c1895417b97d89e2f50833f83c4611588d +F src/sqliteInt.h 4092f9f2395909ebf7da0a6e9907e92883cf98656bb751e1d919d2a0e475ae70 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -618,7 +618,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98 -F src/treeview.c 396c21e21c853ebc1830c194fa13f1161dbc76adad0b0a605172ddb78b3b4cdb +F src/treeview.c 330f396050a87e79025c35237b75f0feb8e11327c8b3f4ab7a858cf86336e270 F src/trigger.c 372ada38f667c6823a3db15749eb668338e65c793394e55a37e56a489f2d1b55 F src/update.c 2cfaded82ca80ff56afb8c3ae5e88284e0824bfd86119827cc22481959f96f92 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 @@ -1951,8 +1951,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a99ee612b9bd6d75b63e557ef5bdac2143425a558cf023a0480cc28c8300a9a8 -R f727db70a6530c6b0b6ca0186b0c1cb8 +P 680ccecbc839373194ed2dcc1053e25512d9ea3f12f8c8963cb8fbd1a034d2f8 +Q +3aafccb5c3c780c29090ee5eb428a6c3153627ce8bf834bbd392e79a30e9389b +Q +9cba3ce577e442f83d7a2d6926e38ffe6bc45953c88ecdd384f3455890303cce +R f351c482825f9cb2175ee0f0b69f0e4a U drh -Z 671faa44cd5bf3867df213bd33bc9ae5 +Z f1d3e45872b682fe27f7e5ce12e577b8 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5954c9dc3f..0fbdaafb80 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -680ccecbc839373194ed2dcc1053e25512d9ea3f12f8c8963cb8fbd1a034d2f8 \ No newline at end of file +293afa81112e824eec2557d004a27319d484276f796936e16d64243fe24f6b68 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index d799510fc0..e526a775cb 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4459,6 +4459,7 @@ char *sqlite3VMPrintf(sqlite3*,const char*, va_list); void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*); void sqlite3TreeViewBareIdList(TreeView*, const IdList*, const char*); void sqlite3TreeViewIdList(TreeView*, const IdList*, u8, const char*); + void sqlite3TreeViewColumnList(TreeView*, const Column*, int, u8); void sqlite3TreeViewSrcList(TreeView*, const SrcList*); void sqlite3TreeViewSelect(TreeView*, const Select*, u8); void sqlite3TreeViewWith(TreeView*, const With*, u8); diff --git a/src/treeview.c b/src/treeview.c index db73943f02..3aee7df675 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -86,6 +86,53 @@ static void sqlite3TreeViewItem(TreeView *p, const char *zLabel,u8 moreFollows){ sqlite3TreeViewLine(p, "%s", zLabel); } +/* +** Show a list of Column objects in tree format. +*/ +void sqlite3TreeViewColumnList( + TreeView *pView, + const Column *aCol, + int nCol, + u8 moreToFollow +){ + int i; + sqlite3TreeViewPush(&pView, moreToFollow); + sqlite3TreeViewLine(pView, "COLUMNS"); + for(i=0; inSrc; i++){ const SrcItem *pItem = &pSrc->a[i]; StrAccum x; + int n = 0; char zLine[100]; sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); x.printfFlags |= SQLITE_PRINTF_INTERNAL; @@ -168,10 +216,22 @@ void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ sqlite3_str_appendf(&x, " CteUse=0x%p", pItem->u2.pCteUse); } sqlite3StrAccumFinish(&x); - sqlite3TreeViewItem(pView, zLine, inSrc-1); + sqlite3TreeViewItem(pView, zLine, inSrc-1); + n = 0; + if( pItem->pTab ) n++; + if( pItem->pSelect ) n++; + if( pItem->fg.isTabFunc ) n++; + if( pItem->fg.isUsing ) n++; + if( pItem->fg.isUsing ){ + sqlite3TreeViewIdList(pView, pItem->u3.pUsing, (--n)>0, "USING"); + } + if( pItem->pTab ){ + Table *pTab = pItem->pTab; + sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, (--n)>0); + } if( pItem->pSelect ){ assert( pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); - sqlite3TreeViewSelect(pView, pItem->pSelect, 0); + sqlite3TreeViewSelect(pView, pItem->pSelect, (--n)>0); } if( pItem->fg.isTabFunc ){ sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:"); From 8e8e9de87e93f258a001dc9c8fdcef843b46aec1 Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 29 Apr 2022 17:45:39 +0000 Subject: [PATCH 229/259] With TreeView, only show the table columns for a SrcItem if the data source is a subquery rather than a persistent table. FossilOrigin-Name: 7b4a0d0fa1d8facaf5e550650d9b261eda7eb7a2a413627f2751f01c5477e1f3 --- manifest | 14 ++++++-------- manifest.uuid | 2 +- src/treeview.c | 9 ++++----- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 1db87ff47d..b2507fac8d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Multiple\senhancements\sto\sthe\sTreeView\soutput\sfor\sSrcItem,\scherrypicked\sfrom\nthe\sright-join\sexperimental\sbranch. -D 2022-04-29T17:13:52.271 +C With\sTreeView,\sonly\sshow\sthe\stable\scolumns\sfor\sa\sSrcItem\sif\sthe\sdata\ssource\nis\sa\ssubquery\srather\sthan\sa\spersistent\stable. +D 2022-04-29T17:45:39.378 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -618,7 +618,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98 -F src/treeview.c 330f396050a87e79025c35237b75f0feb8e11327c8b3f4ab7a858cf86336e270 +F src/treeview.c 9b4fcabab81fa0e6c93b70911b2e06012df03e230fef8b170bf77ab99e544dd8 F src/trigger.c 372ada38f667c6823a3db15749eb668338e65c793394e55a37e56a489f2d1b55 F src/update.c 2cfaded82ca80ff56afb8c3ae5e88284e0824bfd86119827cc22481959f96f92 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 @@ -1951,10 +1951,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 680ccecbc839373194ed2dcc1053e25512d9ea3f12f8c8963cb8fbd1a034d2f8 -Q +3aafccb5c3c780c29090ee5eb428a6c3153627ce8bf834bbd392e79a30e9389b -Q +9cba3ce577e442f83d7a2d6926e38ffe6bc45953c88ecdd384f3455890303cce -R f351c482825f9cb2175ee0f0b69f0e4a +P 293afa81112e824eec2557d004a27319d484276f796936e16d64243fe24f6b68 +R 28b9d27cf579722d7bb4ce1924ff221c U drh -Z f1d3e45872b682fe27f7e5ce12e577b8 +Z 77bba4f7ca9ae44652d512641bde86ff # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0fbdaafb80..16481a0f72 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -293afa81112e824eec2557d004a27319d484276f796936e16d64243fe24f6b68 \ No newline at end of file +7b4a0d0fa1d8facaf5e550650d9b261eda7eb7a2a413627f2751f01c5477e1f3 \ No newline at end of file diff --git a/src/treeview.c b/src/treeview.c index 3aee7df675..0ad3bd0eb8 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -218,18 +218,17 @@ void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ sqlite3StrAccumFinish(&x); sqlite3TreeViewItem(pView, zLine, inSrc-1); n = 0; - if( pItem->pTab ) n++; if( pItem->pSelect ) n++; if( pItem->fg.isTabFunc ) n++; if( pItem->fg.isUsing ) n++; if( pItem->fg.isUsing ){ sqlite3TreeViewIdList(pView, pItem->u3.pUsing, (--n)>0, "USING"); } - if( pItem->pTab ){ - Table *pTab = pItem->pTab; - sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, (--n)>0); - } if( pItem->pSelect ){ + if( pItem->pTab ){ + Table *pTab = pItem->pTab; + sqlite3TreeViewColumnList(pView, pTab->aCol, pTab->nCol, 1); + } assert( pItem->fg.isNestedFrom == IsNestedFrom(pItem->pSelect) ); sqlite3TreeViewSelect(pView, pItem->pSelect, (--n)>0); } From 3d5665366fd03752aa61ca365774239dff67512b Mon Sep 17 00:00:00 2001 From: drh <> Date: Fri, 29 Apr 2022 19:00:11 +0000 Subject: [PATCH 230/259] Enhance the codeEqualityTerm() routine inside the code generator so that it is able to reuse an IN operator that has an invariant subquery on its right-hand side while coding the non-matched loop of a RIGHT JOIN. dbsqlfuzz 19f1102a70cf966ab249de56d944fc20dbebcfcf FossilOrigin-Name: 56dd3065469e49320b13af039471b3f0b85e6f7368cfd97b1cdc0cf8fa8e1956 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/wherecode.c | 2 +- test/join8.test | 10 ++++++++++ 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index b2507fac8d..cdb521d4d0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C With\sTreeView,\sonly\sshow\sthe\stable\scolumns\sfor\sa\sSrcItem\sif\sthe\sdata\ssource\nis\sa\ssubquery\srather\sthan\sa\spersistent\stable. -D 2022-04-29T17:45:39.378 +C Enhance\sthe\scodeEqualityTerm()\sroutine\sinside\sthe\scode\sgenerator\sso\sthat\sit\sis\nable\sto\sreuse\san\sIN\soperator\sthat\shas\san\sinvariant\ssubquery\son\sits\sright-hand\nside\swhile\scoding\sthe\snon-matched\sloop\sof\sa\sRIGHT\sJOIN.\ndbsqlfuzz\s19f1102a70cf966ab249de56d944fc20dbebcfcf +D 2022-04-29T19:00:11.746 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -642,7 +642,7 @@ F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b F src/where.c 43085b3a4ce2e56315fabb0b240a56e76667d9e03c79f287695bcae7b76152d5 F src/whereInt.h 4db5a877a9d1f38b5c928c1c84297c07f30b9a3bc1f5f66214cf1a8ef90a0556 -F src/wherecode.c 55a33d9db1759970c30220904bcc628ba66a1ccb63b5437ef4642f7ea6267b03 +F src/wherecode.c c55aba3ea3106d40af88faa2b22de52821c48bfdcaa045b05f5c3767bfeaa1e0 F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 F src/window.c 924e04fd6e0e113d4dba18b78d43fcb8e42b8ebffc8fc728da52cf3ab014cf3c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1148,7 +1148,7 @@ F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test c4df54e2e204d7f1417bfbdd21ca324b4b07415c647595cc47798eacfddc96d3 F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c F test/join7.test 8e72de4b45e5e930d18c305c7efe86015fb2552731e4e03ea226353036b0dab0 -F test/join8.test 8b1cc9592aa8f623fc2878353b16c81257591908de06d2a4916f7cbe3ca75ecd +F test/join8.test 88ea7b26437d3141167895da4287c4f92e484a9a38bfc25c062144092ac1758f F test/join9.test 9056ddd3b0c0f4f9d658f4521038d9a37dc23ead8ca9a505d0b0db2b6a471e05 F test/joinA.test 7eab225dc1c1ab258a5e62513a4ed7cabbd3db971d59d5d92f4fb6fa14c12f6a F test/joinB.test 1b2ba3fc8568b49411787fccbf540570c148e9b6a53a30f80691cb6268098ded @@ -1951,8 +1951,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 293afa81112e824eec2557d004a27319d484276f796936e16d64243fe24f6b68 -R 28b9d27cf579722d7bb4ce1924ff221c +P 7b4a0d0fa1d8facaf5e550650d9b261eda7eb7a2a413627f2751f01c5477e1f3 +R 4eb952430e379b03f0039449da90c7c2 U drh -Z 77bba4f7ca9ae44652d512641bde86ff +Z 2b2aca42b8cf9c11b9fe920e009d7283 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 16481a0f72..536b89e2ae 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7b4a0d0fa1d8facaf5e550650d9b261eda7eb7a2a413627f2751f01c5477e1f3 \ No newline at end of file +56dd3065469e49320b13af039471b3f0b85e6f7368cfd97b1cdc0cf8fa8e1956 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 3ea6c5d8eb..2cd61a35b7 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -610,7 +610,7 @@ static int codeEqualityTerm( iTab = 0; if( !ExprUseXSelect(pX) || pX->x.pSelect->pEList->nExpr==1 ){ eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab); - }else{ + }else if( pTerm->pExpr->iTable==0 ){ sqlite3 *db = pParse->db; pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); diff --git a/test/join8.test b/test/join8.test index 48287b6bfa..7c4b8f601a 100644 --- a/test/join8.test +++ b/test/join8.test @@ -156,4 +156,14 @@ do_catchsql_test join8-5000 { SELECT (SELECT c FROM sqlite_temp_schema FULL JOIN t2 ON d IN (1,2,3) ORDER BY d) AS x FROM t1; } {0 {- -}} +# 2022-04-29 dbsqlfuzz 19f1102a70cf966ab249de56d944fc20dbebcfcf +# +reset_db +do_execsql_test join8-6000 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT, c TEXT, d REAL); + INSERT INTO t1 VALUES(1,'A','aa',2.5); + SELECT * FROM t1 AS t2 NATURAL RIGHT JOIN t1 AS t3 + WHERE (a,b) IN (SELECT rowid, b FROM t1); +} {1 A aa 2.5} + finish_test From c64f0e71c1e148c261970f79b213937ffc9866c5 Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 30 Apr 2022 00:05:37 +0000 Subject: [PATCH 231/259] Enhance the TreeView debugging output for Expr with opcode TK_IN so as to show the RHS table and the subroutine address. FossilOrigin-Name: aec1e4cd59ae874b66335e4f87322fbe31fbb752429e68bf41338db316d0a9ed --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/treeview.c | 12 +++++++++++- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index cdb521d4d0..7f234c8260 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\scodeEqualityTerm()\sroutine\sinside\sthe\scode\sgenerator\sso\sthat\sit\sis\nable\sto\sreuse\san\sIN\soperator\sthat\shas\san\sinvariant\ssubquery\son\sits\sright-hand\nside\swhile\scoding\sthe\snon-matched\sloop\sof\sa\sRIGHT\sJOIN.\ndbsqlfuzz\s19f1102a70cf966ab249de56d944fc20dbebcfcf -D 2022-04-29T19:00:11.746 +C Enhance\sthe\sTreeView\sdebugging\soutput\sfor\sExpr\swith\sopcode\sTK_IN\sso\sas\sto\nshow\sthe\sRHS\stable\sand\sthe\ssubroutine\saddress. +D 2022-04-30T00:05:37.975 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -618,7 +618,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98 -F src/treeview.c 9b4fcabab81fa0e6c93b70911b2e06012df03e230fef8b170bf77ab99e544dd8 +F src/treeview.c 7dd99cf420137d658492bbf3601d55fce9c34d4788606f43d83937b73474769c F src/trigger.c 372ada38f667c6823a3db15749eb668338e65c793394e55a37e56a489f2d1b55 F src/update.c 2cfaded82ca80ff56afb8c3ae5e88284e0824bfd86119827cc22481959f96f92 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 @@ -1951,8 +1951,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 7b4a0d0fa1d8facaf5e550650d9b261eda7eb7a2a413627f2751f01c5477e1f3 -R 4eb952430e379b03f0039449da90c7c2 +P 56dd3065469e49320b13af039471b3f0b85e6f7368cfd97b1cdc0cf8fa8e1956 +R a9c50a69f413cdbca9e2fe9cf049f583 U drh -Z 2b2aca42b8cf9c11b9fe920e009d7283 +Z 6276b679cc8e2417eedb1432e1dbcb3d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 536b89e2ae..c45d6e71b7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -56dd3065469e49320b13af039471b3f0b85e6f7368cfd97b1cdc0cf8fa8e1956 \ No newline at end of file +aec1e4cd59ae874b66335e4f87322fbe31fbb752429e68bf41338db316d0a9ed \ No newline at end of file diff --git a/src/treeview.c b/src/treeview.c index 0ad3bd0eb8..0f9b588f5a 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -712,7 +712,17 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ break; } case TK_IN: { - sqlite3TreeViewLine(pView, "IN flags=0x%x", pExpr->flags); + sqlite3_str *pStr = sqlite3_str_new(0); + char *z; + sqlite3_str_appendf(pStr, "IN flags=0x%x", pExpr->flags); + if( pExpr->iTable ) sqlite3_str_appendf(pStr, " iTable=%d",pExpr->iTable); + if( ExprHasProperty(pExpr, EP_Subrtn) ){ + sqlite3_str_appendf(pStr, " subrtn(%d,%d)", + pExpr->y.sub.regReturn, pExpr->y.sub.iAddr); + } + z = sqlite3_str_finish(pStr); + sqlite3TreeViewLine(pView, z); + sqlite3_free(z); sqlite3TreeViewExpr(pView, pExpr->pLeft, 1); if( ExprUseXSelect(pExpr) ){ sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); From a25bbaf74a697b0ba59d11a75fd78a349f3e581d Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 30 Apr 2022 00:06:52 +0000 Subject: [PATCH 232/259] Further improvements to codeEqualityTerm() for cases when an IN operator with a right-hand side subquery is used as a constraint that needs to be processed by the RIGHT JOIN non-matched logic. FossilOrigin-Name: bb2798be3fb5737827eec505db2d4c8cb510d227d98fc26ce748bf2da7e8b382 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/wherecode.c | 28 ++++++++++++++++++---------- test/join8.test | 7 +++++++ 4 files changed, 33 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 7f234c8260..3b6531af0d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\sthe\sTreeView\sdebugging\soutput\sfor\sExpr\swith\sopcode\sTK_IN\sso\sas\sto\nshow\sthe\sRHS\stable\sand\sthe\ssubroutine\saddress. -D 2022-04-30T00:05:37.975 +C Further\simprovements\sto\scodeEqualityTerm()\sfor\scases\swhen\san\sIN\soperator\swith\na\sright-hand\sside\ssubquery\sis\sused\sas\sa\sconstraint\sthat\sneeds\sto\sbe\sprocessed\nby\sthe\sRIGHT\sJOIN\snon-matched\slogic. +D 2022-04-30T00:06:52.768 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -642,7 +642,7 @@ F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b F src/where.c 43085b3a4ce2e56315fabb0b240a56e76667d9e03c79f287695bcae7b76152d5 F src/whereInt.h 4db5a877a9d1f38b5c928c1c84297c07f30b9a3bc1f5f66214cf1a8ef90a0556 -F src/wherecode.c c55aba3ea3106d40af88faa2b22de52821c48bfdcaa045b05f5c3767bfeaa1e0 +F src/wherecode.c c7e35e28f1b3f6e95c5dfaa94ce6f7a125db769220bd86c7a52744a1227b2778 F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 F src/window.c 924e04fd6e0e113d4dba18b78d43fcb8e42b8ebffc8fc728da52cf3ab014cf3c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1148,7 +1148,7 @@ F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test c4df54e2e204d7f1417bfbdd21ca324b4b07415c647595cc47798eacfddc96d3 F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c F test/join7.test 8e72de4b45e5e930d18c305c7efe86015fb2552731e4e03ea226353036b0dab0 -F test/join8.test 88ea7b26437d3141167895da4287c4f92e484a9a38bfc25c062144092ac1758f +F test/join8.test ecb51527fa3dedea1b9e816b1bc5a9effe73894bd3630936716ee5983dd99081 F test/join9.test 9056ddd3b0c0f4f9d658f4521038d9a37dc23ead8ca9a505d0b0db2b6a471e05 F test/joinA.test 7eab225dc1c1ab258a5e62513a4ed7cabbd3db971d59d5d92f4fb6fa14c12f6a F test/joinB.test 1b2ba3fc8568b49411787fccbf540570c148e9b6a53a30f80691cb6268098ded @@ -1951,8 +1951,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 56dd3065469e49320b13af039471b3f0b85e6f7368cfd97b1cdc0cf8fa8e1956 -R a9c50a69f413cdbca9e2fe9cf049f583 +P aec1e4cd59ae874b66335e4f87322fbe31fbb752429e68bf41338db316d0a9ed +R 3ef32004450fadb98cceaba22af0f147 U drh -Z 6276b679cc8e2417eedb1432e1dbcb3d +Z e12eec7e3b77f2bd28ff448aaa1d497c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c45d6e71b7..5a4c531708 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -aec1e4cd59ae874b66335e4f87322fbe31fbb752429e68bf41338db316d0a9ed \ No newline at end of file +bb2798be3fb5737827eec505db2d4c8cb510d227d98fc26ce748bf2da7e8b382 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 2cd61a35b7..5e6852f55c 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -610,17 +610,25 @@ static int codeEqualityTerm( iTab = 0; if( !ExprUseXSelect(pX) || pX->x.pSelect->pEList->nExpr==1 ){ eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab); - }else if( pTerm->pExpr->iTable==0 ){ - sqlite3 *db = pParse->db; - pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); - - if( !db->mallocFailed ){ - aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); - eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab); - pTerm->pExpr->iTable = iTab; + }else{ + Expr *pExpr = pTerm->pExpr; + if( pExpr->iTable==0 || !ExprHasProperty(pExpr, EP_Subrtn) ){ + sqlite3 *db = pParse->db; + pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); + if( !db->mallocFailed ){ + aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap,&iTab); + pExpr->iTable = iTab; + pExpr->op2 = eType; + } + sqlite3ExprDelete(db, pX); + }else{ + sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn, + pExpr->y.sub.iAddr); + iTab = pExpr->iTable; + eType = pExpr->op2; } - sqlite3ExprDelete(db, pX); - pX = pTerm->pExpr; + pX = pExpr; } if( eType==IN_INDEX_INDEX_DESC ){ diff --git a/test/join8.test b/test/join8.test index 7c4b8f601a..ca362d7333 100644 --- a/test/join8.test +++ b/test/join8.test @@ -165,5 +165,12 @@ do_execsql_test join8-6000 { SELECT * FROM t1 AS t2 NATURAL RIGHT JOIN t1 AS t3 WHERE (a,b) IN (SELECT rowid, b FROM t1); } {1 A aa 2.5} +do_execsql_test join8-6010 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(a INT PRIMARY KEY, b TEXT, c TEXT, d INT) WITHOUT ROWID; + INSERT INTO t1 VALUES(15,'xray','baker',42); + SELECT value, t1.* FROM json_each('7') NATURAL RIGHT JOIN t1 + WHERE (a,b) IN (SELECT a, b FROM t1); +} {7 15 xray baker 42} finish_test From 2aa1086cab4e8a9cb239882ba1ba042dafdd7e7a Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 30 Apr 2022 12:35:51 +0000 Subject: [PATCH 233/259] Preserve the COLLATE operator on an index on an expression when resolving the use of that expression into a reference to the index. See [forum:/info/7efabf4b03328e57|forum thread 7efabf4b03328e57] for details. FossilOrigin-Name: a8da85c57e07721dc1c918d67433d6c99ce48421e369123cc3194d855e55f7e8 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/wherecode.c | 1 + test/indexexpr1.test | 19 +++++++++++++++++++ 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 3b6531af0d..57c9658d48 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\simprovements\sto\scodeEqualityTerm()\sfor\scases\swhen\san\sIN\soperator\swith\na\sright-hand\sside\ssubquery\sis\sused\sas\sa\sconstraint\sthat\sneeds\sto\sbe\sprocessed\nby\sthe\sRIGHT\sJOIN\snon-matched\slogic. -D 2022-04-30T00:06:52.768 +C Preserve\sthe\sCOLLATE\soperator\son\san\sindex\son\san\sexpression\swhen\sresolving\nthe\suse\sof\sthat\sexpression\sinto\sa\sreference\sto\sthe\sindex.\s\sSee\n[forum:/info/7efabf4b03328e57|forum\sthread\s7efabf4b03328e57]\sfor\sdetails. +D 2022-04-30T12:35:51.942 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -642,7 +642,7 @@ F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b F src/where.c 43085b3a4ce2e56315fabb0b240a56e76667d9e03c79f287695bcae7b76152d5 F src/whereInt.h 4db5a877a9d1f38b5c928c1c84297c07f30b9a3bc1f5f66214cf1a8ef90a0556 -F src/wherecode.c c7e35e28f1b3f6e95c5dfaa94ce6f7a125db769220bd86c7a52744a1227b2778 +F src/wherecode.c 3c6f6ff594edb6eb3d7d38b9b922e43dcd15b31949718acbb4d6b51a66fef509 F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 F src/window.c 924e04fd6e0e113d4dba18b78d43fcb8e42b8ebffc8fc728da52cf3ab014cf3c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1116,7 +1116,7 @@ F test/index7.test b238344318e0b4e42126717f6554f0e7dfd0b39cecad4b736039b43e1e3b6 F test/index8.test caa097735c91dbc23d8a402f5e63a2a03c83840ba3928733ed7f9a03f8a912a3 F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721 F test/indexedby.test f21eca4f7a6ffe14c8500a7ad6cd53166666c99e5ccd311842a28bc94a195fe0 -F test/indexexpr1.test 8f7241410e351679010f14cd7cd30357622d04a784508ff54ba5ce99f64a2228 +F test/indexexpr1.test 3360c2a29a8844e7c4b13293567025281257f9e13a31854cfff6959cede11502 F test/indexexpr2.test 2c7abe3c48f8aaa5a448615ab4d13df3662185d28419c00999670834a3f0b484 F test/indexfault.test 98d78a8ff1f5335628b62f886a1cb7c7dac1ef6d48fa39c51ec871c87dce9811 F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 @@ -1951,8 +1951,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 aec1e4cd59ae874b66335e4f87322fbe31fbb752429e68bf41338db316d0a9ed -R 3ef32004450fadb98cceaba22af0f147 +P bb2798be3fb5737827eec505db2d4c8cb510d227d98fc26ce748bf2da7e8b382 +R 8ae07a550172cb86bf694a85b364f3bb U drh -Z e12eec7e3b77f2bd28ff448aaa1d497c +Z 620a3ae79bd73fe692219fff192dc087 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5a4c531708..375ab1598b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bb2798be3fb5737827eec505db2d4c8cb510d227d98fc26ce748bf2da7e8b382 \ No newline at end of file +a8da85c57e07721dc1c918d67433d6c99ce48421e369123cc3194d855e55f7e8 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 5e6852f55c..0d6030793a 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1255,6 +1255,7 @@ static void preserveExpr(IdxExprTrans *pTrans, Expr *pExpr){ static int whereIndexExprTransNode(Walker *p, Expr *pExpr){ IdxExprTrans *pX = p->u.pIdxTrans; if( sqlite3ExprCompare(0, pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){ + pExpr = sqlite3ExprSkipCollate(pExpr); preserveExpr(pX, pExpr); pExpr->affExpr = sqlite3ExprAffinity(pExpr); pExpr->op = TK_COLUMN; diff --git a/test/indexexpr1.test b/test/indexexpr1.test index 92dfc8689b..042132b81d 100644 --- a/test/indexexpr1.test +++ b/test/indexexpr1.test @@ -487,4 +487,23 @@ ifcapable like_match_blobs { } {2.0} } +# 2022-04-30 https://sqlite.org/forum/info/7efabf4b03328e57 +# Assertion fault during a DELETE INDEXED BY. +# +reset_db +do_execsql_test indexexpr-1900 { + CREATE TABLE t1(x TEXT PRIMARY KEY, y TEXT, z INT); + INSERT INTO t1(x,y,z) VALUES('alpha','ALPHA',1),('bravo','charlie',1); + CREATE INDEX i1 ON t1(+y COLLATE NOCASE); + SELECT * FROM t1; +} {alpha ALPHA 1 bravo charlie 1} +do_execsql_test indexexpr-1910 { + DELETE FROM t1 INDEXED BY i1 + WHERE x IS +y COLLATE NOCASE IN (SELECT z FROM t1) + RETURNING *; +} {alpha ALPHA 1} +do_execsql_test indexexpr-1920 { + SELECT * FROM t1; +} {bravo charlie 1} + finish_test From 7497364749e0c36740c7eef3ecd1ecc9160afd4b Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 30 Apr 2022 18:40:22 +0000 Subject: [PATCH 234/259] Simplified fix to the problem with subroutine reuse in the RIGHT JOIN no-match logic for a subquery on the right-hand side of an IN operator. The code still needs simplification. FossilOrigin-Name: a193749730d6cfba617f2a64e7254c78f92bbf29b109c19055fc33f6cc643d4c --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/wherecode.c | 7 +++++-- test/join8.test | 7 +++++++ 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 57c9658d48..7b6ffe4c91 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Preserve\sthe\sCOLLATE\soperator\son\san\sindex\son\san\sexpression\swhen\sresolving\nthe\suse\sof\sthat\sexpression\sinto\sa\sreference\sto\sthe\sindex.\s\sSee\n[forum:/info/7efabf4b03328e57|forum\sthread\s7efabf4b03328e57]\sfor\sdetails. -D 2022-04-30T12:35:51.942 +C Simplified\sfix\sto\sthe\sproblem\swith\ssubroutine\sreuse\sin\sthe\sRIGHT\sJOIN\sno-match\nlogic\sfor\sa\ssubquery\son\sthe\sright-hand\sside\sof\san\sIN\soperator.\s\sThe\scode\sstill\nneeds\ssimplification. +D 2022-04-30T18:40:22.156 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -642,7 +642,7 @@ F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b F src/where.c 43085b3a4ce2e56315fabb0b240a56e76667d9e03c79f287695bcae7b76152d5 F src/whereInt.h 4db5a877a9d1f38b5c928c1c84297c07f30b9a3bc1f5f66214cf1a8ef90a0556 -F src/wherecode.c 3c6f6ff594edb6eb3d7d38b9b922e43dcd15b31949718acbb4d6b51a66fef509 +F src/wherecode.c d629ba77a3601a979b2a30d1a21ca7ae283faff797c7cffe79fb9366a075db89 F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 F src/window.c 924e04fd6e0e113d4dba18b78d43fcb8e42b8ebffc8fc728da52cf3ab014cf3c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1148,7 +1148,7 @@ F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test c4df54e2e204d7f1417bfbdd21ca324b4b07415c647595cc47798eacfddc96d3 F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c F test/join7.test 8e72de4b45e5e930d18c305c7efe86015fb2552731e4e03ea226353036b0dab0 -F test/join8.test ecb51527fa3dedea1b9e816b1bc5a9effe73894bd3630936716ee5983dd99081 +F test/join8.test 9a4b2f53d5358abb29e6356e357c0cd40f4d8f282589300dcb76728dce050b51 F test/join9.test 9056ddd3b0c0f4f9d658f4521038d9a37dc23ead8ca9a505d0b0db2b6a471e05 F test/joinA.test 7eab225dc1c1ab258a5e62513a4ed7cabbd3db971d59d5d92f4fb6fa14c12f6a F test/joinB.test 1b2ba3fc8568b49411787fccbf540570c148e9b6a53a30f80691cb6268098ded @@ -1951,8 +1951,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 bb2798be3fb5737827eec505db2d4c8cb510d227d98fc26ce748bf2da7e8b382 -R 8ae07a550172cb86bf694a85b364f3bb +P a8da85c57e07721dc1c918d67433d6c99ce48421e369123cc3194d855e55f7e8 +R 8dafede96e6eddf2103c6fe2efc2c0f1 U drh -Z 620a3ae79bd73fe692219fff192dc087 +Z 677c686e7cbb46a3d1010c0d9d90814e # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 375ab1598b..0915dc636c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a8da85c57e07721dc1c918d67433d6c99ce48421e369123cc3194d855e55f7e8 \ No newline at end of file +a193749730d6cfba617f2a64e7254c78f92bbf29b109c19055fc33f6cc643d4c \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 0d6030793a..333295a48b 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -619,14 +619,17 @@ static int codeEqualityTerm( aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap,&iTab); pExpr->iTable = iTab; - pExpr->op2 = eType; } sqlite3ExprDelete(db, pX); }else{ + int j1; sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn, pExpr->y.sub.iAddr); + j1 = sqlite3VdbeAddOp0(v, OP_Goto); + aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap,&iTab); iTab = pExpr->iTable; - eType = pExpr->op2; + sqlite3VdbeJumpHere(v, j1); } pX = pExpr; } diff --git a/test/join8.test b/test/join8.test index ca362d7333..a33622d9bb 100644 --- a/test/join8.test +++ b/test/join8.test @@ -172,5 +172,12 @@ do_execsql_test join8-6010 { SELECT value, t1.* FROM json_each('7') NATURAL RIGHT JOIN t1 WHERE (a,b) IN (SELECT a, b FROM t1); } {7 15 xray baker 42} +do_execsql_test join8-6020 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(a INTEGER PRIMARY KEY,b); + INSERT INTO t1 VALUES(0,NULL),(1,2); + SELECT value, t1.* FROM json_each('17') NATURAL RIGHT JOIN t1 + WHERE (a,b) IN (SELECT rowid, b FROM t1); +} {17 1 2} finish_test From bae50d6719bd1a748ef3d826b96c38dc47c6d1df Mon Sep 17 00:00:00 2001 From: drh <> Date: Sat, 30 Apr 2022 19:55:28 +0000 Subject: [PATCH 235/259] Defensive code in sqlite3TreeViewWindow() to fix a compiler warning. FossilOrigin-Name: b250c218b4b6327a1cae3edbc037625ba998f89ee13a9bfbc2cefd1edfc4b768 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/treeview.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 7b6ffe4c91..73f80eb148 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplified\sfix\sto\sthe\sproblem\swith\ssubroutine\sreuse\sin\sthe\sRIGHT\sJOIN\sno-match\nlogic\sfor\sa\ssubquery\son\sthe\sright-hand\sside\sof\san\sIN\soperator.\s\sThe\scode\sstill\nneeds\ssimplification. -D 2022-04-30T18:40:22.156 +C Defensive\scode\sin\ssqlite3TreeViewWindow()\sto\sfix\sa\scompiler\swarning. +D 2022-04-30T19:55:28.101 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -618,7 +618,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98 -F src/treeview.c 7dd99cf420137d658492bbf3601d55fce9c34d4788606f43d83937b73474769c +F src/treeview.c a47e4246396118f3d5a1c524de15e6fffaf02036be192d4339e887a2a9bf36b1 F src/trigger.c 372ada38f667c6823a3db15749eb668338e65c793394e55a37e56a489f2d1b55 F src/update.c 2cfaded82ca80ff56afb8c3ae5e88284e0824bfd86119827cc22481959f96f92 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 @@ -1951,8 +1951,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 a8da85c57e07721dc1c918d67433d6c99ce48421e369123cc3194d855e55f7e8 -R 8dafede96e6eddf2103c6fe2efc2c0f1 +P a193749730d6cfba617f2a64e7254c78f92bbf29b109c19055fc33f6cc643d4c +R 1d2a81ecbf1d09fa752247278562e6d1 U drh -Z 677c686e7cbb46a3d1010c0d9d90814e +Z 7657291be748b0693bb1bbfc76537229 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0915dc636c..2ad4ff62c9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a193749730d6cfba617f2a64e7254c78f92bbf29b109c19055fc33f6cc643d4c \ No newline at end of file +b250c218b4b6327a1cae3edbc037625ba998f89ee13a9bfbc2cefd1edfc4b768 \ No newline at end of file diff --git a/src/treeview.c b/src/treeview.c index 0f9b588f5a..3d5bd7175b 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -397,6 +397,7 @@ void sqlite3TreeViewBound( */ void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){ int nElement = 0; + if( pWin==0 ) return; if( pWin->pFilter ){ sqlite3TreeViewItem(pView, "FILTER", 1); sqlite3TreeViewExpr(pView, pWin->pFilter, 0); From b94182bdc6235ce520322890d4b1567e6404d04f Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 2 May 2022 11:24:21 +0000 Subject: [PATCH 236/259] Bring the comments on sqlite3FindInIndex() into closer alignment with what that routine actually does. FossilOrigin-Name: 40f3274745b53bb72933c1052d0e85bc74be56d3a1068e9d54dc28763a2cfef9 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 9 +++++++-- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 73f80eb148..4b3f1993f6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Defensive\scode\sin\ssqlite3TreeViewWindow()\sto\sfix\sa\scompiler\swarning. -D 2022-04-30T19:55:28.101 +C Bring\sthe\scomments\son\ssqlite3FindInIndex()\sinto\scloser\salignment\swith\swhat\nthat\sroutine\sactually\sdoes. +D 2022-05-02T11:24:21.557 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -504,7 +504,7 @@ F src/date.c 15082566229d4b1e5f24fdb490bf9bcc68824b911d70e3573ef075a1b9e2d26f F src/dbpage.c 90661a87e1db8bfbc8d2ebbdcd3749651ddb287c555c07a28fb17c7c591ffb68 F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d F src/delete.c a8e844af211a48b13b5b358be77a12c860c6a557c21990ad51a548e2536500ce -F src/expr.c d8c520edd0edf0b9c0ca467aa44c864ff17f265fd1cebbd224b6d5c625b638c3 +F src/expr.c 926dccca86a8d02bf2a8533ba07c9b0c576148915844a1c2217d94c718e9699b F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c d965ede15d8360c09ed59348940649ee647b192e784466837d7aefa836d1d91e F src/func.c a3407a6fbb0d4088d8d502e46f0ace63e0aeae7467ae23a9ca9815bbf9239761 @@ -1951,8 +1951,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 a193749730d6cfba617f2a64e7254c78f92bbf29b109c19055fc33f6cc643d4c -R 1d2a81ecbf1d09fa752247278562e6d1 +P b250c218b4b6327a1cae3edbc037625ba998f89ee13a9bfbc2cefd1edfc4b768 +R b1223a28f05ca5a28b33b633588aeacf U drh -Z 7657291be748b0693bb1bbfc76537229 +Z 2fc59ad1d223e831e71b6ddeee2728d5 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2ad4ff62c9..d90599d53d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b250c218b4b6327a1cae3edbc037625ba998f89ee13a9bfbc2cefd1edfc4b768 \ No newline at end of file +40f3274745b53bb72933c1052d0e85bc74be56d3a1068e9d54dc28763a2cfef9 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 13bacb90ca..f8ee68dc2b 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2659,7 +2659,7 @@ static int sqlite3InRhsIsConstant(Expr *pIn){ ** all members of the RHS set, skipping duplicates. ** ** A cursor is opened on the b-tree object that is the RHS of the IN operator -** and pX->iTable is set to the index of that cursor. +** and the *piTab parameter is set to the index of that cursor. ** ** The returned value of this function indicates the b-tree type, as follows: ** @@ -2679,7 +2679,10 @@ static int sqlite3InRhsIsConstant(Expr *pIn){ ** If the RHS of the IN operator is a list or a more complex subquery, then ** an ephemeral table might need to be generated from the RHS and then ** pX->iTable made to point to the ephemeral table instead of an -** existing table. +** existing table. In this case, the creation and initialization of the +** ephmeral table might be put inside of a subroutine, the EP_Subrtn flag +** will be set on pX and the pX->y.sub fields will be set to show where +** the subroutine is coded. ** ** The inFlags parameter must contain, at a minimum, one of the bits ** IN_INDEX_MEMBERSHIP or IN_INDEX_LOOP but not both. If inFlags contains @@ -2911,6 +2914,8 @@ int sqlite3FindInIndex( && ExprUseXList(pX) && (!sqlite3InRhsIsConstant(pX) || pX->x.pList->nExpr<=2) ){ + pParse->nTab--; /* Back out the allocation of the unused cursor */ + iTab = -1; /* Cursor is not allocated */ eType = IN_INDEX_NOOP; } From 3a45d30ea5eff2c17c5ee1561e12f0865ad75b3e Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 2 May 2022 14:32:56 +0000 Subject: [PATCH 237/259] Improvement on check-in [a193749730d6cfba] so that the subroutine call to the IN operator right-hand side generator from the RIGHT JOIN no-match logic does not generate unreachable byte code. FossilOrigin-Name: cc458317bd77046c4328715ae9e3409f3f4cd422a01162cb33405ef3a142b0a3 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 11 +++++++++-- src/sqliteInt.h | 1 + src/wherecode.c | 9 ++------- 5 files changed, 21 insertions(+), 18 deletions(-) diff --git a/manifest b/manifest index 4b3f1993f6..3e37826c15 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Bring\sthe\scomments\son\ssqlite3FindInIndex()\sinto\scloser\salignment\swith\swhat\nthat\sroutine\sactually\sdoes. -D 2022-05-02T11:24:21.557 +C Improvement\son\scheck-in\s[a193749730d6cfba]\sso\sthat\sthe\ssubroutine\scall\sto\nthe\sIN\soperator\sright-hand\sside\sgenerator\sfrom\sthe\sRIGHT\sJOIN\sno-match\slogic\ndoes\snot\sgenerate\sunreachable\sbyte\scode. +D 2022-05-02T14:32:56.242 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -504,7 +504,7 @@ F src/date.c 15082566229d4b1e5f24fdb490bf9bcc68824b911d70e3573ef075a1b9e2d26f F src/dbpage.c 90661a87e1db8bfbc8d2ebbdcd3749651ddb287c555c07a28fb17c7c591ffb68 F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d F src/delete.c a8e844af211a48b13b5b358be77a12c860c6a557c21990ad51a548e2536500ce -F src/expr.c 926dccca86a8d02bf2a8533ba07c9b0c576148915844a1c2217d94c718e9699b +F src/expr.c 36acab0dde36ab805ed9c793c9a2bb864793999c8b4d4b0e758100eb0339b124 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c d965ede15d8360c09ed59348940649ee647b192e784466837d7aefa836d1d91e F src/func.c a3407a6fbb0d4088d8d502e46f0ace63e0aeae7467ae23a9ca9815bbf9239761 @@ -558,7 +558,7 @@ F src/shell.c.in ae0a6fae983caac6f8c824733f0599dfdf7b3a7e8efdef3cb5e3ab2e457ffc3 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h 4092f9f2395909ebf7da0a6e9907e92883cf98656bb751e1d919d2a0e475ae70 +F src/sqliteInt.h b076cfab9455b6ef1245667ff73dada79a204c750985f788e52469727f0d1c31 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -642,7 +642,7 @@ F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b F src/where.c 43085b3a4ce2e56315fabb0b240a56e76667d9e03c79f287695bcae7b76152d5 F src/whereInt.h 4db5a877a9d1f38b5c928c1c84297c07f30b9a3bc1f5f66214cf1a8ef90a0556 -F src/wherecode.c d629ba77a3601a979b2a30d1a21ca7ae283faff797c7cffe79fb9366a075db89 +F src/wherecode.c 9c2af255257287a50a2c884cc13d0cca4292d46ffa235fbfa1f2e9c67b071e7c F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 F src/window.c 924e04fd6e0e113d4dba18b78d43fcb8e42b8ebffc8fc728da52cf3ab014cf3c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1951,8 +1951,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 b250c218b4b6327a1cae3edbc037625ba998f89ee13a9bfbc2cefd1edfc4b768 -R b1223a28f05ca5a28b33b633588aeacf +P 40f3274745b53bb72933c1052d0e85bc74be56d3a1068e9d54dc28763a2cfef9 +R fa255f48eb3059bbcc1be1195343e4b6 U drh -Z 2fc59ad1d223e831e71b6ddeee2728d5 +Z e6ffd1955bb698b867fb285f4218f7e4 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d90599d53d..15adbbe53c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -40f3274745b53bb72933c1052d0e85bc74be56d3a1068e9d54dc28763a2cfef9 \ No newline at end of file +cc458317bd77046c4328715ae9e3409f3f4cd422a01162cb33405ef3a142b0a3 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index f8ee68dc2b..8e47578cc8 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2743,12 +2743,17 @@ int sqlite3FindInIndex( ){ Select *p; /* SELECT to the right of IN operator */ int eType = 0; /* Type of RHS table. IN_INDEX_* */ - int iTab = pParse->nTab++; /* Cursor of the RHS table */ + int iTab; /* Cursor of the RHS table */ int mustBeUnique; /* True if RHS must be unique */ Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ assert( pX->op==TK_IN ); mustBeUnique = (inFlags & IN_INDEX_LOOP)!=0; + if( pX->iTable && (inFlags & IN_INDEX_REUSE_CUR)!=0 ){ + iTab = pX->iTable; + }else{ + iTab = pParse->nTab++; + } /* If the RHS of this IN(...) operator is a SELECT, and if it matters ** whether or not the SELECT result contains NULL values, check whether @@ -3082,7 +3087,9 @@ void sqlite3CodeRhsOfIN( assert( ExprUseYSub(pExpr) ); sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn, pExpr->y.sub.iAddr); - sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable); + if( iTab!=pExpr->iTable ){ + sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable); + } sqlite3VdbeJumpHere(v, addrOnce); return; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index e526a775cb..e9f0af544a 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -5315,6 +5315,7 @@ const char *sqlite3JournalModename(int); #define IN_INDEX_NOOP_OK 0x0001 /* OK to return IN_INDEX_NOOP */ #define IN_INDEX_MEMBERSHIP 0x0002 /* IN operator used for membership test */ #define IN_INDEX_LOOP 0x0004 /* IN operator used as a loop */ +#define IN_INDEX_REUSE_CUR 0x0008 /* Reuse prior table cursor */ int sqlite3FindInIndex(Parse *, Expr *, u32, int*, int*, int*); int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int); diff --git a/src/wherecode.c b/src/wherecode.c index 333295a48b..d4470ac4df 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -612,7 +612,7 @@ static int codeEqualityTerm( eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab); }else{ Expr *pExpr = pTerm->pExpr; - if( pExpr->iTable==0 || !ExprHasProperty(pExpr, EP_Subrtn) ){ + if( pExpr->iTable==0 || !ExprHasProperty(pExpr, EP_Subrtn) ){ sqlite3 *db = pParse->db; pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); if( !db->mallocFailed ){ @@ -622,14 +622,9 @@ static int codeEqualityTerm( } sqlite3ExprDelete(db, pX); }else{ - int j1; - sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn, - pExpr->y.sub.iAddr); - j1 = sqlite3VdbeAddOp0(v, OP_Goto); aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); - eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap,&iTab); + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP|IN_INDEX_REUSE_CUR, 0, aiMap,&iTab); iTab = pExpr->iTable; - sqlite3VdbeJumpHere(v, j1); } pX = pExpr; } From 7a8809907f7ce3980ad4867865ea9c30f72b5c9f Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 2 May 2022 15:23:59 +0000 Subject: [PATCH 238/259] Fix a harmless compiler warning in sqlite3TreeViewWinFunc() (a routine that does not even appear in release builds). FossilOrigin-Name: daff6070039e45df7c47b323a8352e56d1264a7bfb065fe2d79c58454c95a262 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/treeview.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 3e37826c15..6331a9645d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvement\son\scheck-in\s[a193749730d6cfba]\sso\sthat\sthe\ssubroutine\scall\sto\nthe\sIN\soperator\sright-hand\sside\sgenerator\sfrom\sthe\sRIGHT\sJOIN\sno-match\slogic\ndoes\snot\sgenerate\sunreachable\sbyte\scode. -D 2022-05-02T14:32:56.242 +C Fix\sa\sharmless\scompiler\swarning\sin\ssqlite3TreeViewWinFunc()\s(a\sroutine\sthat\ndoes\snot\seven\sappear\sin\srelease\sbuilds). +D 2022-05-02T15:23:59.708 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -618,7 +618,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98 -F src/treeview.c a47e4246396118f3d5a1c524de15e6fffaf02036be192d4339e887a2a9bf36b1 +F src/treeview.c 5e81880b7c010fb25f5b40fb617136694544e18adef78b28057206f78cbbd1db F src/trigger.c 372ada38f667c6823a3db15749eb668338e65c793394e55a37e56a489f2d1b55 F src/update.c 2cfaded82ca80ff56afb8c3ae5e88284e0824bfd86119827cc22481959f96f92 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 @@ -1951,8 +1951,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 40f3274745b53bb72933c1052d0e85bc74be56d3a1068e9d54dc28763a2cfef9 -R fa255f48eb3059bbcc1be1195343e4b6 +P cc458317bd77046c4328715ae9e3409f3f4cd422a01162cb33405ef3a142b0a3 +R 7b2c26fca08c4096a6d6906e453b4c50 U drh -Z e6ffd1955bb698b867fb285f4218f7e4 +Z 76eb5c6ba92cbe3f261ef935a3f5fceb # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 15adbbe53c..86f5a5d2b9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cc458317bd77046c4328715ae9e3409f3f4cd422a01162cb33405ef3a142b0a3 \ No newline at end of file +daff6070039e45df7c47b323a8352e56d1264a7bfb065fe2d79c58454c95a262 \ No newline at end of file diff --git a/src/treeview.c b/src/treeview.c index 3d5bd7175b..9718eb716b 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -462,6 +462,7 @@ void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){ ** Generate a human-readable explanation for a Window Function object */ void sqlite3TreeViewWinFunc(TreeView *pView, const Window *pWin, u8 more){ + if( pWin==0 ) return; sqlite3TreeViewPush(&pView, more); sqlite3TreeViewLine(pView, "WINFUNC %s(%d)", pWin->pWFunc->zName, pWin->pWFunc->nArg); From c35f02d676bb990ef18354c4a5fa3cf75f267abc Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 2 May 2022 15:31:06 +0000 Subject: [PATCH 239/259] Document (in comments) that the SQLITE_FlttnUnionAll bit has a specific value needed by TH3. FossilOrigin-Name: bcaa4a44749d157c5953c6f54c88b1ba29b4035f4b21fce986b7efbea372e109 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqliteInt.h | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 6331a9645d..f4819dbeb5 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sharmless\scompiler\swarning\sin\ssqlite3TreeViewWinFunc()\s(a\sroutine\sthat\ndoes\snot\seven\sappear\sin\srelease\sbuilds). -D 2022-05-02T15:23:59.708 +C Document\s(in\scomments)\sthat\sthe\sSQLITE_FlttnUnionAll\sbit\shas\sa\sspecific\svalue\nneeded\sby\sTH3. +D 2022-05-02T15:31:06.026 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -558,7 +558,7 @@ F src/shell.c.in ae0a6fae983caac6f8c824733f0599dfdf7b3a7e8efdef3cb5e3ab2e457ffc3 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h b076cfab9455b6ef1245667ff73dada79a204c750985f788e52469727f0d1c31 +F src/sqliteInt.h 3247ce80347c99739850798a34b1179e396801c5fc0c8216892f7f134990672f F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -1951,8 +1951,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 cc458317bd77046c4328715ae9e3409f3f4cd422a01162cb33405ef3a142b0a3 -R 7b2c26fca08c4096a6d6906e453b4c50 +P daff6070039e45df7c47b323a8352e56d1264a7bfb065fe2d79c58454c95a262 +R 916db3a0a95e071bc97fd8372b15f4b3 U drh -Z 76eb5c6ba92cbe3f261ef935a3f5fceb +Z 75675c6853367abc92437cf9f7c9cc0c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 86f5a5d2b9..ee9d52391d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -daff6070039e45df7c47b323a8352e56d1264a7bfb065fe2d79c58454c95a262 \ No newline at end of file +bcaa4a44749d157c5953c6f54c88b1ba29b4035f4b21fce986b7efbea372e109 \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index e9f0af544a..37d9db8b6a 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1781,6 +1781,7 @@ struct sqlite3 { #define SQLITE_BalancedMerge 0x00200000 /* Balance multi-way merges */ #define SQLITE_ReleaseReg 0x00400000 /* Use OP_ReleaseReg for testing */ #define SQLITE_FlttnUnionAll 0x00800000 /* Disable the UNION ALL flattener */ + /* TH3 expects this value ^^^^^^^^^^ See flatten04.test */ #define SQLITE_AllOpts 0xffffffff /* All optimizations */ /* From 56f38db70037d5211cb9ec5a7acae51db16e6b77 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 2 May 2022 15:47:57 +0000 Subject: [PATCH 240/259] Remove a testcase() macro taht was made obsolete by [a8da85c57e07721d]. FossilOrigin-Name: 053cf45ecaa7eac8cc64c7b2672807f736a45575a84b426263b2e1feb060b401 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/wherecode.c | 1 - 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index f4819dbeb5..5c3330d792 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Document\s(in\scomments)\sthat\sthe\sSQLITE_FlttnUnionAll\sbit\shas\sa\sspecific\svalue\nneeded\sby\sTH3. -D 2022-05-02T15:31:06.026 +C Remove\sa\stestcase()\smacro\staht\swas\smade\sobsolete\sby\s[a8da85c57e07721d]. +D 2022-05-02T15:47:57.110 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -642,7 +642,7 @@ F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b F src/where.c 43085b3a4ce2e56315fabb0b240a56e76667d9e03c79f287695bcae7b76152d5 F src/whereInt.h 4db5a877a9d1f38b5c928c1c84297c07f30b9a3bc1f5f66214cf1a8ef90a0556 -F src/wherecode.c 9c2af255257287a50a2c884cc13d0cca4292d46ffa235fbfa1f2e9c67b071e7c +F src/wherecode.c dfc3fbb6b7cb14a5a8e022d22f4d2c6004807e458a7cd8278194fbef7c1670e1 F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 F src/window.c 924e04fd6e0e113d4dba18b78d43fcb8e42b8ebffc8fc728da52cf3ab014cf3c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1951,8 +1951,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 daff6070039e45df7c47b323a8352e56d1264a7bfb065fe2d79c58454c95a262 -R 916db3a0a95e071bc97fd8372b15f4b3 +P bcaa4a44749d157c5953c6f54c88b1ba29b4035f4b21fce986b7efbea372e109 +R e9ba3eaded9a5b3eaa4edaa039c7ca25 U drh -Z 75675c6853367abc92437cf9f7c9cc0c +Z 097076191b03601e3038661a0fda0c02 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index ee9d52391d..da0a44df88 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bcaa4a44749d157c5953c6f54c88b1ba29b4035f4b21fce986b7efbea372e109 \ No newline at end of file +053cf45ecaa7eac8cc64c7b2672807f736a45575a84b426263b2e1feb060b401 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index d4470ac4df..6f5a85386b 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1259,7 +1259,6 @@ static int whereIndexExprTransNode(Walker *p, Expr *pExpr){ pExpr->op = TK_COLUMN; pExpr->iTable = pX->iIdxCur; pExpr->iColumn = pX->iIdxCol; - testcase( ExprHasProperty(pExpr, EP_Skip) ); testcase( ExprHasProperty(pExpr, EP_Unlikely) ); ExprClearProperty(pExpr, EP_Skip|EP_Unlikely|EP_WinFunc|EP_Subrtn); pExpr->y.pTab = 0; From 72d620bdb1a4e3e7c8d405a56ec382a89202dcec Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 2 May 2022 19:59:03 +0000 Subject: [PATCH 241/259] Name resolution and "*" wildcard expansion for parenthesized FROM clauses seems to work the same as PG. The code is chaos, however, and needs some cleanup. FossilOrigin-Name: 6f9c0b07aadc5189c65c3ee4e6938aac10fc0d98f1cb06980f5e5d7b0308f237 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/expr.c | 1 + src/select.c | 15 ++++++++++++++- src/sqliteInt.h | 1 + src/treeview.c | 1 + 6 files changed, 27 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 7b19f35a1b..6fc11d7360 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sthe\slatest\strunk\sfixes\sand\senhancements\sinto\sthe\sright-join\sbranch. -D 2022-05-02T15:10:38.366 +C Name\sresolution\sand\s"*"\swildcard\sexpansion\sfor\sparenthesized\sFROM\sclauses\nseems\sto\swork\sthe\ssame\sas\sPG.\s\sThe\scode\sis\schaos,\showever,\sand\sneeds\ssome\ncleanup. +D 2022-05-02T19:59:03.190 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -504,7 +504,7 @@ F src/date.c 15082566229d4b1e5f24fdb490bf9bcc68824b911d70e3573ef075a1b9e2d26f F src/dbpage.c 90661a87e1db8bfbc8d2ebbdcd3749651ddb287c555c07a28fb17c7c591ffb68 F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d F src/delete.c a8e844af211a48b13b5b358be77a12c860c6a557c21990ad51a548e2536500ce -F src/expr.c efa37babe35dcf79933beb9df3aee0c6a2f60ac56645773c73c866fd9894d938 +F src/expr.c 495ff0219a5aa2161d33e10f20912ce7dcd55fc13459e0dc48abae52934bfadf F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c d965ede15d8360c09ed59348940649ee647b192e784466837d7aefa836d1d91e F src/func.c a3407a6fbb0d4088d8d502e46f0ace63e0aeae7467ae23a9ca9815bbf9239761 @@ -553,12 +553,12 @@ F src/printf.c 512574910a45341c8ad244bd3d4939968ebdfde215645b676fff01cc46e90757 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c b14bf8a4a1e3cb01eefc48a7e4129b15bb6a18b56d16dd4eca676586464337d0 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c b319bfcdf6c06841312f7e98c71f384d775f20138760855b8489aa6a05a70e72 +F src/select.c 41a371b0256c38e258a4265d55fe55e7cd6a197c586647faee9924341ee06b4f F src/shell.c.in ae0a6fae983caac6f8c824733f0599dfdf7b3a7e8efdef3cb5e3ab2e457ffc35 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h 3aaaf14804c77feadfd2ee241bb7e9ca4aa5be5cacddab8f9f7f2e8190a0c5b2 +F src/sqliteInt.h 73faf6b2222f70f7777624a08af799cc20822d4cc578306b1316088dddd47736 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -618,7 +618,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98 -F src/treeview.c 5c2a8d3bc6c91c3108cc63beba7b04ec5f2fdaefd1a2dc534fb4ef8f4a1d588a +F src/treeview.c c91eee716ac380fddd74c4cf3914562080f8d520a0e557d824d5919e131ac6e5 F src/trigger.c 372ada38f667c6823a3db15749eb668338e65c793394e55a37e56a489f2d1b55 F src/update.c 2cfaded82ca80ff56afb8c3ae5e88284e0824bfd86119827cc22481959f96f92 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 @@ -1952,8 +1952,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 9cba3ce577e442f83d7a2d6926e38ffe6bc45953c88ecdd384f3455890303cce cc458317bd77046c4328715ae9e3409f3f4cd422a01162cb33405ef3a142b0a3 -R 8c6adc25dedee0141892e4be83329645 +P afbcf075c1e09ae064c7b16e63501cd1d374711812664aef76bd35d02d64a2b6 +R 555aead77d8cae1693b8c4f6bc8f3e4c U drh -Z 8ddd04e8896d9f6869b3f2d45984a6f1 +Z 87ce52a531a5370a01dfeb75577a427b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index cef5ace71e..17cf9ee23f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -afbcf075c1e09ae064c7b16e63501cd1d374711812664aef76bd35d02d64a2b6 \ No newline at end of file +6f9c0b07aadc5189c65c3ee4e6938aac10fc0d98f1cb06980f5e5d7b0308f237 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 77b5e0ad6f..a93c6a1bc6 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1635,6 +1635,7 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, const ExprList *p, int flags){ pItem->bUsed = pOldItem->bUsed; pItem->bUsingTerm = pOldItem->bUsingTerm; pItem->bSorterRef = pOldItem->bSorterRef; + pItem->bNoExpand = pOldItem->bNoExpand; pItem->u = pOldItem->u; } return pNew; diff --git a/src/select.c b/src/select.c index ed0fc6e4c8..187d898887 100644 --- a/src/select.c +++ b/src/select.c @@ -2231,6 +2231,9 @@ int sqlite3ColumnsFromExprList( } pCol->zCnName = zName; pCol->hName = sqlite3StrIHash(zName); + if( pX->bNoExpand ){ + pCol->colFlags |= COLFLAG_NOEXPAND; + } sqlite3ColumnPropertiesFromName(0, pCol); if( zName && sqlite3HashInsert(&ht, zName, pX)==pX ){ sqlite3OomFault(db); @@ -5822,6 +5825,7 @@ static int selectExpander(Walker *pWalker, Select *p){ char *zTabName; /* AS name for this data source */ const char *zSchemaName = 0; /* Schema name for this data source */ int iDb; /* Schema index for this data src */ + IdList *pUsing; /* USING clause for this join */ if( (zTabName = pFrom->zAlias)==0 ){ zTabName = pTab->zName; @@ -5846,7 +5850,7 @@ static int selectExpander(Walker *pWalker, Select *p){ && (selFlags & SF_NestedFrom)!=0 ){ int ii; - IdList *pUsing = pFrom[1].u3.pUsing; + pUsing = pFrom[1].u3.pUsing; for(ii=0; iinId; ii++){ const char *zUName = pUsing->a[ii].zName; pRight = sqlite3Expr(db, TK_ID, zUName); @@ -5859,6 +5863,8 @@ static int selectExpander(Walker *pWalker, Select *p){ pX->bUsingTerm = 1; } } + }else{ + pUsing = 0; } for(j=0; jnCol; j++){ char *zName = pTab->aCol[j].zCnName; @@ -5938,6 +5944,13 @@ static int selectExpander(Walker *pWalker, Select *p){ testcase( pX->zEName==0 ); } pX->eEName = ENAME_TAB; + if( (pFrom->fg.isUsing + && sqlite3IdListIndex(pFrom->u3.pUsing, zName)>=0) + || (pUsing && sqlite3IdListIndex(pUsing, zName)>=0) + || (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)!=0 + ){ + pX->bNoExpand = 1; + } }else if( longNames ){ pX->zEName = sqlite3MPrintf(db, "%s.%s", zTabName, zName); pX->eEName = ENAME_NAME; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 0715cae3c2..f4c48c1128 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3008,6 +3008,7 @@ struct ExprList { unsigned bNulls :1; /* True if explicit "NULLS FIRST/LAST" */ unsigned bUsed :1; /* This column used in a SF_NestedFrom subquery */ unsigned bUsingTerm:1; /* Term from the USING clause of a NestedFrom */ + unsigned bNoExpand: 1; union { struct { /* Used by any ExprList other than Parse.pConsExpr */ u16 iOrderByCol; /* For ORDER BY, column number in result set */ diff --git a/src/treeview.c b/src/treeview.c index b498692ba3..b9d65e1ac1 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -882,6 +882,7 @@ void sqlite3TreeViewBareExprList( fprintf(stdout, "TABLE-ALIAS-NAME(\"%s\") ", zName); if( pList->a[i].bUsed ) fprintf(stdout, "(used) "); if( pList->a[i].bUsingTerm ) fprintf(stdout, "(USING-term) "); + if( pList->a[i].bNoExpand ) fprintf(stdout, "(NoExpand) "); break; case ENAME_SPAN: fprintf(stdout, "SPAN(\"%s\") ", zName); From 63879a2c995c637c14a8f3aa1cee4e84dace56d7 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 2 May 2022 20:04:34 +0000 Subject: [PATCH 242/259] Improved comments. FossilOrigin-Name: 158b80bed61ade793ccfd979f26a5231fabc8c14697ca0141bba61bc13e3b2ba --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 2 +- src/sqliteInt.h | 3 ++- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 6fc11d7360..c8660fea2f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Name\sresolution\sand\s"*"\swildcard\sexpansion\sfor\sparenthesized\sFROM\sclauses\nseems\sto\swork\sthe\ssame\sas\sPG.\s\sThe\scode\sis\schaos,\showever,\sand\sneeds\ssome\ncleanup. -D 2022-05-02T19:59:03.190 +C Improved\scomments. +D 2022-05-02T20:04:34.911 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -553,12 +553,12 @@ F src/printf.c 512574910a45341c8ad244bd3d4939968ebdfde215645b676fff01cc46e90757 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c b14bf8a4a1e3cb01eefc48a7e4129b15bb6a18b56d16dd4eca676586464337d0 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 41a371b0256c38e258a4265d55fe55e7cd6a197c586647faee9924341ee06b4f +F src/select.c 0c54305ca957ffe188dd5b042b81b44e0aeba3f3bcb73df81ddd740908655ff7 F src/shell.c.in ae0a6fae983caac6f8c824733f0599dfdf7b3a7e8efdef3cb5e3ab2e457ffc35 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h 73faf6b2222f70f7777624a08af799cc20822d4cc578306b1316088dddd47736 +F src/sqliteInt.h de084be0bcb1d149c4b12cf2f2bd56a4ca2896950fded97238f42d37e2ee9325 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -1952,8 +1952,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 afbcf075c1e09ae064c7b16e63501cd1d374711812664aef76bd35d02d64a2b6 -R 555aead77d8cae1693b8c4f6bc8f3e4c +P 6f9c0b07aadc5189c65c3ee4e6938aac10fc0d98f1cb06980f5e5d7b0308f237 +R d21fbd984ceaf34ad0e0f693bcafb15a U drh -Z 87ce52a531a5370a01dfeb75577a427b +Z 6aa37fa121875e3bd8722acc06f99751 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 17cf9ee23f..64ee70b31f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6f9c0b07aadc5189c65c3ee4e6938aac10fc0d98f1cb06980f5e5d7b0308f237 \ No newline at end of file +158b80bed61ade793ccfd979f26a5231fabc8c14697ca0141bba61bc13e3b2ba \ No newline at end of file diff --git a/src/select.c b/src/select.c index 187d898887..db84e22e45 100644 --- a/src/select.c +++ b/src/select.c @@ -5825,7 +5825,7 @@ static int selectExpander(Walker *pWalker, Select *p){ char *zTabName; /* AS name for this data source */ const char *zSchemaName = 0; /* Schema name for this data source */ int iDb; /* Schema index for this data src */ - IdList *pUsing; /* USING clause for this join */ + IdList *pUsing; /* USING clause for pFrom[1] */ if( (zTabName = pFrom->zAlias)==0 ){ zTabName = pTab->zName; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index f4c48c1128..c64aa3c016 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3008,7 +3008,8 @@ struct ExprList { unsigned bNulls :1; /* True if explicit "NULLS FIRST/LAST" */ unsigned bUsed :1; /* This column used in a SF_NestedFrom subquery */ unsigned bUsingTerm:1; /* Term from the USING clause of a NestedFrom */ - unsigned bNoExpand: 1; + unsigned bNoExpand: 1; /* Term is an auxiliary in NestedFrom and should + ** not be expanded by "*" in parent queries */ union { struct { /* Used by any ExprList other than Parse.pConsExpr */ u16 iOrderByCol; /* For ORDER BY, column number in result set */ From d88fd539893919c8dc247bf3703bcc4d5bc91be4 Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 2 May 2022 20:49:30 +0000 Subject: [PATCH 243/259] Organize the various flag bits of the ExprList_item object into a substructure so that the whole lot can be copied all at once. Faster and smaller code. FossilOrigin-Name: 5341d4bbe9a943f9cdbbdea829e18f108e98972ebb706396c50fc62fcc6a6328 --- manifest | 32 ++++++++++++++++---------------- manifest.uuid | 2 +- src/alter.c | 6 +++--- src/build.c | 10 +++++----- src/expr.c | 32 ++++++++++++++------------------ src/resolve.c | 18 +++++++++--------- src/select.c | 49 +++++++++++++++++++++++++------------------------ src/sqliteInt.h | 22 ++++++++++++---------- src/treeview.c | 8 ++++---- src/trigger.c | 4 ++-- src/where.c | 12 +++++++----- src/whereexpr.c | 2 +- src/window.c | 6 +++--- 13 files changed, 102 insertions(+), 101 deletions(-) diff --git a/manifest b/manifest index 4fa116639e..b104fa4288 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\strunk\sfixes\sinto\sthe\sright-join\sbranch. -D 2022-05-02T20:14:26.269 +C Organize\sthe\svarious\sflag\sbits\sof\sthe\sExprList_item\sobject\sinto\sa\ssubstructure\nso\sthat\sthe\swhole\slot\scan\sbe\scopied\sall\sat\sonce.\s\sFaster\sand\ssmaller\scode. +D 2022-05-02T20:49:30.890 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -486,7 +486,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a -F src/alter.c 9395ece9850ad57c6fbb453aeb5185be4bae3b159c4b37611425c565124ee849 +F src/alter.c d8872f9d1863d8e31c37475e318de746e1b5ca57c0e477e35042a9ebbb6e0298 F src/analyze.c aabdf3769c7fd9954a8ec508eb7041ae174b66f88d12c47199fabbea9a646467 F src/attach.c 4431f82f0247bf3aaf91589acafdff77d1882235c95407b36da1585c765fbbc8 F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf @@ -496,7 +496,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c df695e953c2ce78ce4878ee5016751df9bc9a921dc0500a0f53ab3bb3196e505 F src/btree.h 74d64b8f28cfa4a894d14d4ed64fa432cd697b98b61708d4351482ae15913e22 F src/btreeInt.h 8ce1332edd89dfd2461d561ac10a0ab5601c8e06200cb5230596c3caaf54482e -F src/build.c e8e776b52bc145cbf4e9fb88b99830083880fc2b174c2f96518fff15cbc72396 +F src/build.c 23f874642825d7eaaeeb7a3281b2b1a75e1d4c4dd9ae4dceddcd908266634214 F src/callback.c 4c19af69835787bfe790ac560f3071a824eb629f34e41f97b52ce5235c77de1c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 026dbdcdbd8c3cde98a88483ee88310ff43150ab164ad768f12cc700a11495ad @@ -504,7 +504,7 @@ F src/date.c 15082566229d4b1e5f24fdb490bf9bcc68824b911d70e3573ef075a1b9e2d26f F src/dbpage.c 90661a87e1db8bfbc8d2ebbdcd3749651ddb287c555c07a28fb17c7c591ffb68 F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d F src/delete.c a8e844af211a48b13b5b358be77a12c860c6a557c21990ad51a548e2536500ce -F src/expr.c 495ff0219a5aa2161d33e10f20912ce7dcd55fc13459e0dc48abae52934bfadf +F src/expr.c d955e8954e03e637c19033241806b04f6a937d0657f6261f2d9e4cdfe674b478 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c d965ede15d8360c09ed59348940649ee647b192e784466837d7aefa836d1d91e F src/func.c a3407a6fbb0d4088d8d502e46f0ace63e0aeae7467ae23a9ca9815bbf9239761 @@ -551,14 +551,14 @@ F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c fd940149c691684e7c1073c3787a7170e44852b02d1275d2e30a5b58e89cfcaf F src/printf.c 512574910a45341c8ad244bd3d4939968ebdfde215645b676fff01cc46e90757 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c -F src/resolve.c b14bf8a4a1e3cb01eefc48a7e4129b15bb6a18b56d16dd4eca676586464337d0 +F src/resolve.c e9ee235c4151d2b7fa47435a219bfd30bf516a804d2f004639858087ebf3137b F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 0c54305ca957ffe188dd5b042b81b44e0aeba3f3bcb73df81ddd740908655ff7 +F src/select.c 727e718482269f24e6db2850074498b14949ecf0778f065580f9ab0f2e76675e F src/shell.c.in ae0a6fae983caac6f8c824733f0599dfdf7b3a7e8efdef3cb5e3ab2e457ffc35 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e -F src/sqliteInt.h 850fea2046c4d333bf328164fd5bc19a2a04955fb4b2abc361317f07820f4de1 +F src/sqliteInt.h 7c8146fc57f2e009152eb93ad41eab28490f9c31691559f281a80f9077ec1f2a F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4a3da6d77eeb3531cb0dbdf7047772a2a1b99f98c69e90ce009c75fe6328b2c0 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -618,8 +618,8 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c a38f52058b517929e264094abd0b5fd1e8e145a1aa43bc6f6a72ae5218f96c98 -F src/treeview.c e33a0fa956469a7ba96f586beb12e601fb60412d71aca7a8d152e28b4cf86d7c -F src/trigger.c 372ada38f667c6823a3db15749eb668338e65c793394e55a37e56a489f2d1b55 +F src/treeview.c 4153f2f044d13a3216e64271dfd1e59a3fa40222a45e6da248708088634e6f06 +F src/trigger.c 4fe4c1ac811755aff49d669d2e52e414eb5dfa6e172e849ab7b6825e70a571c0 F src/update.c 2cfaded82ca80ff56afb8c3ae5e88284e0824bfd86119827cc22481959f96f92 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 @@ -640,11 +640,11 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c 43085b3a4ce2e56315fabb0b240a56e76667d9e03c79f287695bcae7b76152d5 +F src/where.c eb86c068e8e24a1e0a650beb20573bd5648fe1584f11d5bdffaf17ec3de52b5d F src/whereInt.h 4db5a877a9d1f38b5c928c1c84297c07f30b9a3bc1f5f66214cf1a8ef90a0556 F src/wherecode.c dfc3fbb6b7cb14a5a8e022d22f4d2c6004807e458a7cd8278194fbef7c1670e1 -F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 -F src/window.c 924e04fd6e0e113d4dba18b78d43fcb8e42b8ebffc8fc728da52cf3ab014cf3c +F src/whereexpr.c e036477ac8424de50ae5b36a71103405d3f86b33ba11125ec7a2a99d501b0622 +F src/window.c fff1b51757438c664e471d5184634e48dcdf8ea34b640f3b1b0810b1e06de18c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 F test/affinity3.test b5c19d504dec222c0dc66642673d23dce915d35737b68e74d9f237b80493eb53 @@ -1952,8 +1952,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 158b80bed61ade793ccfd979f26a5231fabc8c14697ca0141bba61bc13e3b2ba 053cf45ecaa7eac8cc64c7b2672807f736a45575a84b426263b2e1feb060b401 -R 4b24813532984e0e78854b2b4a0d231e +P e01f4c05c21e89dcc7985e00874f288d9ba5d5d932f7284f8d970bd3145ac0c2 +R 4390ecbce69667e0c74ca1d6573c2546 U drh -Z bcd7e0add8b57bb93082cd41d63cfefe +Z ec5e63ee49f22b25e0961585c1886f82 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 2551453021..942b4ff99c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e01f4c05c21e89dcc7985e00874f288d9ba5d5d932f7284f8d970bd3145ac0c2 \ No newline at end of file +5341d4bbe9a943f9cdbbdea829e18f108e98972ebb706396c50fc62fcc6a6328 \ No newline at end of file diff --git a/src/alter.c b/src/alter.c index 62075df759..538ba7d9f8 100644 --- a/src/alter.c +++ b/src/alter.c @@ -880,7 +880,7 @@ static int renameUnmapSelectCb(Walker *pWalker, Select *p){ if( ALWAYS(p->pEList) ){ ExprList *pList = p->pEList; for(i=0; inExpr; i++){ - if( pList->a[i].zEName && pList->a[i].eEName==ENAME_NAME ){ + if( pList->a[i].zEName && pList->a[i].fg.eEName==ENAME_NAME ){ sqlite3RenameTokenRemap(pParse, 0, (void*)pList->a[i].zEName); } } @@ -929,7 +929,7 @@ void sqlite3RenameExprlistUnmap(Parse *pParse, ExprList *pEList){ sWalker.xExprCallback = renameUnmapExprCb; sqlite3WalkExprList(&sWalker, pEList); for(i=0; inExpr; i++){ - if( ALWAYS(pEList->a[i].eEName==ENAME_NAME) ){ + if( ALWAYS(pEList->a[i].fg.eEName==ENAME_NAME) ){ sqlite3RenameTokenRemap(pParse, 0, (void*)pEList->a[i].zEName); } } @@ -1087,7 +1087,7 @@ static void renameColumnElistNames( int i; for(i=0; inExpr; i++){ const char *zName = pEList->a[i].zEName; - if( ALWAYS(pEList->a[i].eEName==ENAME_NAME) + if( ALWAYS(pEList->a[i].fg.eEName==ENAME_NAME) && ALWAYS(zName!=0) && 0==sqlite3_stricmp(zName, zOld) ){ diff --git a/src/build.c b/src/build.c index fbd633209f..e243e795fe 100644 --- a/src/build.c +++ b/src/build.c @@ -1890,7 +1890,7 @@ void sqlite3AddPrimaryKey( pTab->keyConf = (u8)onError; assert( autoInc==0 || autoInc==1 ); pTab->tabFlags |= autoInc*TF_Autoincrement; - if( pList ) pParse->iPkSortOrder = pList->a[0].sortFlags; + if( pList ) pParse->iPkSortOrder = pList->a[0].fg.sortFlags; (void)sqlite3HasExplicitNulls(pParse, pList); }else if( autoInc ){ #ifndef SQLITE_OMIT_AUTOINCREMENT @@ -2384,7 +2384,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ if( IN_RENAME_OBJECT ){ sqlite3RenameTokenRemap(pParse, pList->a[0].pExpr, &pTab->iPKey); } - pList->a[0].sortFlags = pParse->iPkSortOrder; + pList->a[0].fg.sortFlags = pParse->iPkSortOrder; assert( pParse->pNewTable==pTab ); pTab->iPKey = -1; sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0, @@ -3872,8 +3872,8 @@ int sqlite3HasExplicitNulls(Parse *pParse, ExprList *pList){ if( pList ){ int i; for(i=0; inExpr; i++){ - if( pList->a[i].bNulls ){ - u8 sf = pList->a[i].sortFlags; + if( pList->a[i].fg.bNulls ){ + u8 sf = pList->a[i].fg.sortFlags; sqlite3ErrorMsg(pParse, "unsupported use of NULLS %s", (sf==0 || sf==3) ? "FIRST" : "LAST" ); @@ -4226,7 +4226,7 @@ void sqlite3CreateIndex( goto exit_create_index; } pIndex->azColl[i] = zColl; - requestedSortOrder = pListItem->sortFlags & sortOrderMask; + requestedSortOrder = pListItem->fg.sortFlags & sortOrderMask; pIndex->aSortOrder[i] = (u8)requestedSortOrder; } diff --git a/src/expr.c b/src/expr.c index a93c6a1bc6..1ebc73be93 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1628,14 +1628,8 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, const ExprList *p, int flags){ } } pItem->zEName = sqlite3DbStrDup(db, pOldItem->zEName); - pItem->sortFlags = pOldItem->sortFlags; - pItem->eEName = pOldItem->eEName; - pItem->done = 0; - pItem->bNulls = pOldItem->bNulls; - pItem->bUsed = pOldItem->bUsed; - pItem->bUsingTerm = pOldItem->bUsingTerm; - pItem->bSorterRef = pOldItem->bSorterRef; - pItem->bNoExpand = pOldItem->bNoExpand; + pItem->fg = pOldItem->fg; + pItem->fg.done = 0; pItem->u = pOldItem->u; } return pNew; @@ -1935,16 +1929,16 @@ void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder, int eNulls){ ); pItem = &p->a[p->nExpr-1]; - assert( pItem->bNulls==0 ); + assert( pItem->fg.bNulls==0 ); if( iSortOrder==SQLITE_SO_UNDEFINED ){ iSortOrder = SQLITE_SO_ASC; } - pItem->sortFlags = (u8)iSortOrder; + pItem->fg.sortFlags = (u8)iSortOrder; if( eNulls!=SQLITE_SO_UNDEFINED ){ - pItem->bNulls = 1; + pItem->fg.bNulls = 1; if( iSortOrder!=eNulls ){ - pItem->sortFlags |= KEYINFO_ORDER_BIGNULL; + pItem->fg.sortFlags |= KEYINFO_ORDER_BIGNULL; } } } @@ -1970,7 +1964,7 @@ void sqlite3ExprListSetName( assert( pList->nExpr>0 ); pItem = &pList->a[pList->nExpr-1]; assert( pItem->zEName==0 ); - assert( pItem->eEName==ENAME_NAME ); + assert( pItem->fg.eEName==ENAME_NAME ); pItem->zEName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n); if( dequote ){ /* If dequote==0, then pName->z does not point to part of a DDL @@ -2005,7 +1999,7 @@ void sqlite3ExprListSetSpan( assert( pList->nExpr>0 ); if( pItem->zEName==0 ){ pItem->zEName = sqlite3DbSpanDup(db, zStart, zEnd); - pItem->eEName = ENAME_SPAN; + pItem->fg.eEName = ENAME_SPAN; } } } @@ -4831,7 +4825,9 @@ int sqlite3ExprCodeRunJustOnce( struct ExprList_item *pItem; int i; for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){ - if( pItem->reusable && sqlite3ExprCompare(0,pItem->pExpr,pExpr,-1)==0 ){ + if( pItem->fg.reusable + && sqlite3ExprCompare(0,pItem->pExpr,pExpr,-1)==0 + ){ return pItem->u.iConstExprReg; } } @@ -4854,7 +4850,7 @@ int sqlite3ExprCodeRunJustOnce( p = sqlite3ExprListAppend(pParse, p, pExpr); if( p ){ struct ExprList_item *pItem = &p->a[p->nExpr-1]; - pItem->reusable = regDest<0; + pItem->fg.reusable = regDest<0; if( regDest<0 ) regDest = ++pParse->nMem; pItem->u.iConstExprReg = regDest; } @@ -4988,7 +4984,7 @@ int sqlite3ExprCodeExprList( for(pItem=pList->a, i=0; ipExpr; #ifdef SQLITE_ENABLE_SORTER_REFERENCES - if( pItem->bSorterRef ){ + if( pItem->fg.bSorterRef ){ i--; n--; }else @@ -5613,7 +5609,7 @@ int sqlite3ExprListCompare(const ExprList *pA, const ExprList *pB, int iTab){ int res; Expr *pExprA = pA->a[i].pExpr; Expr *pExprB = pB->a[i].pExpr; - if( pA->a[i].sortFlags!=pB->a[i].sortFlags ) return 1; + if( pA->a[i].fg.sortFlags!=pB->a[i].fg.sortFlags ) return 1; if( (res = sqlite3ExprCompare(0, pExprA, pExprB, iTab)) ) return res; } return 0; diff --git a/src/resolve.c b/src/resolve.c index 7f99152cbb..d7e32911e9 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -130,7 +130,7 @@ int sqlite3MatchEName( ){ int n; const char *zSpan; - if( pItem->eEName!=ENAME_TAB ) return 0; + if( pItem->fg.eEName!=ENAME_TAB ) return 0; zSpan = pItem->zEName; for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){} if( zDb && (sqlite3StrNICmp(zSpan, zDb, n)!=0 || zDb[n]!=0) ){ @@ -359,9 +359,9 @@ static int lookupName( cntTab = 2; pMatch = pItem; pExpr->iColumn = j; - pEList->a[j].bUsed = 1; + pEList->a[j].fg.bUsed = 1; hit = 1; - if( pEList->a[j].bUsingTerm ) break; + if( pEList->a[j].fg.bUsingTerm ) break; } if( hit || zTab==0 ) continue; } @@ -584,7 +584,7 @@ static int lookupName( assert( pEList!=0 ); for(j=0; jnExpr; j++){ char *zAs = pEList->a[j].zEName; - if( pEList->a[j].eEName==ENAME_NAME + if( pEList->a[j].fg.eEName==ENAME_NAME && sqlite3_stricmp(zAs, zCol)==0 ){ Expr *pOrig; @@ -1337,7 +1337,7 @@ static int resolveAsName( assert( !ExprHasProperty(pE, EP_IntValue) ); zCol = pE->u.zToken; for(i=0; inExpr; i++){ - if( pEList->a[i].eEName==ENAME_NAME + if( pEList->a[i].fg.eEName==ENAME_NAME && sqlite3_stricmp(pEList->a[i].zEName, zCol)==0 ){ return i+1; @@ -1458,7 +1458,7 @@ static int resolveCompoundOrderBy( return 1; } for(i=0; inExpr; i++){ - pOrderBy->a[i].done = 0; + pOrderBy->a[i].fg.done = 0; } pSelect->pNext = 0; while( pSelect->pPrior ){ @@ -1473,7 +1473,7 @@ static int resolveCompoundOrderBy( for(i=0, pItem=pOrderBy->a; inExpr; i++, pItem++){ int iCol = -1; Expr *pE, *pDup; - if( pItem->done ) continue; + if( pItem->fg.done ) continue; pE = sqlite3ExprSkipCollateAndLikely(pItem->pExpr); if( NEVER(pE==0) ) continue; if( sqlite3ExprIsInteger(pE, &iCol) ){ @@ -1526,7 +1526,7 @@ static int resolveCompoundOrderBy( sqlite3ExprDelete(db, pE); pItem->u.x.iOrderByCol = (u16)iCol; } - pItem->done = 1; + pItem->fg.done = 1; }else{ moreToDo = 1; } @@ -1534,7 +1534,7 @@ static int resolveCompoundOrderBy( pSelect = pSelect->pNext; } for(i=0; inExpr; i++){ - if( pOrderBy->a[i].done==0 ){ + if( pOrderBy->a[i].fg.done==0 ){ sqlite3ErrorMsg(pParse, "%r ORDER BY term does not match any " "column in the result set", i+1); return 1; diff --git a/src/select.c b/src/select.c index db84e22e45..b6b897d3a9 100644 --- a/src/select.c +++ b/src/select.c @@ -331,7 +331,7 @@ void sqlite3SrcItemColumnUsed(SrcItem *pItem, int iCol){ pResults = pItem->pSelect->pEList; assert( pResults!=0 ); assert( iCol>=0 && iColnExpr ); - pResults->a[iCol].bUsed = 1; + pResults->a[iCol].fg.bUsed = 1; } } @@ -999,7 +999,7 @@ static void fixDistinctOpenEph( ** retrieved directly from table t1. If the values are very large, this ** can be more efficient than storing them directly in the sorter records. ** -** The ExprList_item.bSorterRef flag is set for each expression in pEList +** The ExprList_item.fg.fg.bSorterRef flag is set for each expression in pEList ** for which the sorter-reference optimization should be enabled. ** Additionally, the pSort->aDefer[] array is populated with entries ** for all cursors required to evaluate all selected expressions. Finally. @@ -1059,7 +1059,7 @@ static void selectExprDefer( nDefer++; } } - pItem->bSorterRef = 1; + pItem->fg.bSorterRef = 1; } } } @@ -1190,7 +1190,7 @@ static void selectInnerLoop( for(i=0; inExpr; i++){ if( pEList->a[i].u.x.iOrderByCol>0 #ifdef SQLITE_ENABLE_SORTER_REFERENCES - || pEList->a[i].bSorterRef + || pEList->a[i].fg.bSorterRef #endif ){ nResultCol--; @@ -1552,7 +1552,7 @@ KeyInfo *sqlite3KeyInfoFromExprList( assert( sqlite3KeyInfoIsWriteable(pInfo) ); for(i=iStart, pItem=pList->a+iStart; iaColl[i-iStart] = sqlite3ExprNNCollSeq(pParse, pItem->pExpr); - pInfo->aSortFlags[i-iStart] = pItem->sortFlags; + pInfo->aSortFlags[i-iStart] = pItem->fg.sortFlags; } } return pInfo; @@ -1691,7 +1691,7 @@ static void generateSortTail( } for(i=0, iCol=nKey+bSeq-1; i=0; i--){ #ifdef SQLITE_ENABLE_SORTER_REFERENCES - if( aOutEx[i].bSorterRef ){ + if( aOutEx[i].fg.bSorterRef ){ sqlite3ExprCode(pParse, aOutEx[i].pExpr, regRow+i); }else #endif @@ -2094,7 +2094,7 @@ void sqlite3GenerateColumnNames( assert( p->op!=TK_AGG_COLUMN ); /* Agg processing has not run yet */ assert( p->op!=TK_COLUMN || (ExprUseYTab(p) && p->y.pTab!=0) ); /* Covering idx not yet coded */ - if( pEList->a[i].zEName && pEList->a[i].eEName==ENAME_NAME ){ + if( pEList->a[i].zEName && pEList->a[i].fg.eEName==ENAME_NAME ){ /* An AS clause always takes first priority */ char *zName = pEList->a[i].zEName; sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT); @@ -2183,7 +2183,7 @@ int sqlite3ColumnsFromExprList( struct ExprList_item *pCollide; /* Get an appropriate name for the column */ - if( (zName = pX->zEName)!=0 && pX->eEName==ENAME_NAME ){ + if( (zName = pX->zEName)!=0 && pX->fg.eEName==ENAME_NAME ){ /* If the column contains an "AS " phrase, use as the name */ }else{ Expr *pColExpr = sqlite3ExprSkipCollateAndLikely(pX->pExpr); @@ -2218,7 +2218,7 @@ int sqlite3ColumnsFromExprList( */ cnt = 0; while( zName && (pCollide = sqlite3HashFind(&ht, zName))!=0 ){ - if( pCollide->bUsingTerm ){ + if( pCollide->fg.bUsingTerm ){ pCol->colFlags |= COLFLAG_NOEXPAND; } nName = sqlite3Strlen30(zName); @@ -2231,7 +2231,7 @@ int sqlite3ColumnsFromExprList( } pCol->zCnName = zName; pCol->hName = sqlite3StrIHash(zName); - if( pX->bNoExpand ){ + if( pX->fg.bNoExpand ){ pCol->colFlags |= COLFLAG_NOEXPAND; } sqlite3ColumnPropertiesFromName(0, pCol); @@ -2492,7 +2492,7 @@ static KeyInfo *multiSelectOrderByKeyInfo(Parse *pParse, Select *p, int nExtra){ } assert( sqlite3KeyInfoIsWriteable(pRet) ); pRet->aColl[i] = pColl; - pRet->aSortFlags[i] = pOrderBy->a[i].sortFlags; + pRet->aSortFlags[i] = pOrderBy->a[i].fg.sortFlags; } } @@ -5098,7 +5098,7 @@ static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){ } *ppMinMax = pOrderBy = sqlite3ExprListDup(db, pEList, 0); assert( pOrderBy!=0 || db->mallocFailed ); - if( pOrderBy ) pOrderBy->a[0].sortFlags = sortFlags; + if( pOrderBy ) pOrderBy->a[0].fg.sortFlags = sortFlags; return eRet; } @@ -5805,7 +5805,7 @@ static int selectExpander(Walker *pWalker, Select *p){ pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr); if( pNew ){ pNew->a[pNew->nExpr-1].zEName = a[k].zEName; - pNew->a[pNew->nExpr-1].eEName = a[k].eEName; + pNew->a[pNew->nExpr-1].fg.eEName = a[k].fg.eEName; a[k].zEName = 0; } a[k].pExpr = 0; @@ -5859,8 +5859,8 @@ static int selectExpander(Walker *pWalker, Select *p){ struct ExprList_item *pX = &pNew->a[pNew->nExpr-1]; assert( pX->zEName==0 ); pX->zEName = sqlite3MPrintf(db,"..%s", zUName); - pX->eEName = ENAME_TAB; - pX->bUsingTerm = 1; + pX->fg.eEName = ENAME_TAB; + pX->fg.bUsingTerm = 1; } } }else{ @@ -5943,20 +5943,20 @@ static int selectExpander(Walker *pWalker, Select *p){ zSchemaName, zTabName, zName); testcase( pX->zEName==0 ); } - pX->eEName = ENAME_TAB; + pX->fg.eEName = ENAME_TAB; if( (pFrom->fg.isUsing && sqlite3IdListIndex(pFrom->u3.pUsing, zName)>=0) || (pUsing && sqlite3IdListIndex(pUsing, zName)>=0) || (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)!=0 ){ - pX->bNoExpand = 1; + pX->fg.bNoExpand = 1; } }else if( longNames ){ pX->zEName = sqlite3MPrintf(db, "%s.%s", zTabName, zName); - pX->eEName = ENAME_NAME; + pX->fg.eEName = ENAME_NAME; }else{ pX->zEName = sqlite3DbStrDup(db, zName); - pX->eEName = ENAME_NAME; + pX->fg.eEName = ENAME_NAME; } } } @@ -7084,13 +7084,13 @@ int sqlite3Select( if( p->selFlags & SF_NestedFrom ){ /* Delete or NULL-out result columns that will never be used */ int ii; - for(ii=pEList->nExpr-1; ii>0 && pEList->a[ii].bUsed==0; ii--){ + for(ii=pEList->nExpr-1; ii>0 && pEList->a[ii].fg.bUsed==0; ii--){ sqlite3ExprDelete(db, pEList->a[ii].pExpr); sqlite3DbFree(db, pEList->a[ii].zEName); pEList->nExpr--; } for(ii=0; iinExpr; ii++){ - if( pEList->a[ii].bUsed==0 ) pEList->a[ii].pExpr->op = TK_NULL; + if( pEList->a[ii].fg.bUsed==0 ) pEList->a[ii].pExpr->op = TK_NULL; } } } @@ -7242,8 +7242,9 @@ int sqlite3Select( ** ORDER BY to maximize the chances of rows being delivered in an ** order that makes the ORDER BY redundant. */ for(ii=0; iinExpr; ii++){ - u8 sortFlags = sSort.pOrderBy->a[ii].sortFlags & KEYINFO_ORDER_DESC; - pGroupBy->a[ii].sortFlags = sortFlags; + u8 sortFlags; + sortFlags = sSort.pOrderBy->a[ii].fg.sortFlags & KEYINFO_ORDER_DESC; + pGroupBy->a[ii].fg.sortFlags = sortFlags; } if( sqlite3ExprListCompare(pGroupBy, sSort.pOrderBy, -1)==0 ){ orderByGrp = 1; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 90c931efe6..7cbdb46215 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3001,16 +3001,18 @@ struct ExprList { struct ExprList_item { /* For each expression in the list */ Expr *pExpr; /* The parse tree for this expression */ char *zEName; /* Token associated with this expression */ - u8 sortFlags; /* Mask of KEYINFO_ORDER_* flags */ - unsigned eEName :2; /* Meaning of zEName */ - unsigned done :1; /* A flag to indicate when processing is finished */ - unsigned reusable :1; /* Constant expression is reusable */ - unsigned bSorterRef :1; /* Defer evaluation until after sorting */ - unsigned bNulls :1; /* True if explicit "NULLS FIRST/LAST" */ - unsigned bUsed :1; /* This column used in a SF_NestedFrom subquery */ - unsigned bUsingTerm:1; /* Term from the USING clause of a NestedFrom */ - unsigned bNoExpand: 1; /* Term is an auxiliary in NestedFrom and should - ** not be expanded by "*" in parent queries */ + struct { + u8 sortFlags; /* Mask of KEYINFO_ORDER_* flags */ + unsigned eEName :2; /* Meaning of zEName */ + unsigned done :1; /* Indicates when processing is finished */ + unsigned reusable :1; /* Constant expression is reusable */ + unsigned bSorterRef :1; /* Defer evaluation until after sorting */ + unsigned bNulls :1; /* True if explicit "NULLS FIRST/LAST" */ + unsigned bUsed :1; /* This column used in a SF_NestedFrom subquery */ + unsigned bUsingTerm:1; /* Term from the USING clause of a NestedFrom */ + unsigned bNoExpand: 1; /* Term is an auxiliary in NestedFrom and should + ** not be expanded by "*" in parent queries */ + } fg; union { struct { /* Used by any ExprList other than Parse.pConsExpr */ u16 iOrderByCol; /* For ORDER BY, column number in result set */ diff --git a/src/treeview.c b/src/treeview.c index f314ea6721..3ff300c38b 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -875,15 +875,15 @@ void sqlite3TreeViewBareExprList( moreToFollow = 0; sqlite3TreeViewLine(pView, 0); if( zName ){ - switch( pList->a[i].eEName ){ + switch( pList->a[i].fg.eEName ){ default: fprintf(stdout, "AS %s ", zName); break; case ENAME_TAB: fprintf(stdout, "TABLE-ALIAS-NAME(\"%s\") ", zName); - if( pList->a[i].bUsed ) fprintf(stdout, "(used) "); - if( pList->a[i].bUsingTerm ) fprintf(stdout, "(USING-term) "); - if( pList->a[i].bNoExpand ) fprintf(stdout, "(NoExpand) "); + if( pList->a[i].fg.bUsed ) fprintf(stdout, "(used) "); + if( pList->a[i].fg.bUsingTerm ) fprintf(stdout, "(USING-term) "); + if( pList->a[i].fg.bNoExpand ) fprintf(stdout, "(NoExpand) "); break; case ENAME_SPAN: fprintf(stdout, "SPAN(\"%s\") ", zName); diff --git a/src/trigger.c b/src/trigger.c index 109d82cc22..42c76bcd93 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -905,7 +905,7 @@ static ExprList *sqlite3ExpandReturning( if( !db->mallocFailed ){ struct ExprList_item *pItem = &pNew->a[pNew->nExpr-1]; pItem->zEName = sqlite3DbStrDup(db, pTab->aCol[jj].zCnName); - pItem->eEName = ENAME_NAME; + pItem->fg.eEName = ENAME_NAME; } } }else{ @@ -914,7 +914,7 @@ static ExprList *sqlite3ExpandReturning( if( !db->mallocFailed && ALWAYS(pList->a[i].zEName!=0) ){ struct ExprList_item *pItem = &pNew->a[pNew->nExpr-1]; pItem->zEName = sqlite3DbStrDup(db, pList->a[i].zEName); - pItem->eEName = pList->a[i].eEName; + pItem->fg.eEName = pList->a[i].fg.eEName; } } } diff --git a/src/where.c b/src/where.c index 2750d93584..5ed10702f2 100644 --- a/src/where.c +++ b/src/where.c @@ -1206,7 +1206,7 @@ static sqlite3_index_info *allocateIndexInfo( } /* Virtual tables are unable to deal with NULLS FIRST */ - if( pOrderBy->a[i].sortFlags & KEYINFO_ORDER_BIGNULL ) break; + if( pOrderBy->a[i].fg.sortFlags & KEYINFO_ORDER_BIGNULL ) break; /* First case - a direct column references without a COLLATE operator */ if( pExpr->op==TK_COLUMN && pExpr->iTable==pSrc->iCursor ){ @@ -1318,7 +1318,7 @@ static sqlite3_index_info *allocateIndexInfo( || (pExpr->op==TK_COLLATE && pExpr->pLeft->op==TK_COLUMN && pExpr->iColumn==pExpr->pLeft->iColumn) ); pIdxOrderBy[j].iColumn = pExpr->iColumn; - pIdxOrderBy[j].desc = pOrderBy->a[i].sortFlags & KEYINFO_ORDER_DESC; + pIdxOrderBy[j].desc = pOrderBy->a[i].fg.sortFlags & KEYINFO_ORDER_DESC; j++; } pIdxInfo->nOrderBy = j; @@ -4457,16 +4457,18 @@ static i8 wherePathSatisfiesOrderBy( /* Make sure the sort order is compatible in an ORDER BY clause. ** Sort order is irrelevant for a GROUP BY clause. */ if( revSet ){ - if( (rev ^ revIdx)!=(pOrderBy->a[i].sortFlags&KEYINFO_ORDER_DESC) ){ + if( (rev ^ revIdx) + != (pOrderBy->a[i].fg.sortFlags&KEYINFO_ORDER_DESC) + ){ isMatch = 0; } }else{ - rev = revIdx ^ (pOrderBy->a[i].sortFlags & KEYINFO_ORDER_DESC); + rev = revIdx ^ (pOrderBy->a[i].fg.sortFlags & KEYINFO_ORDER_DESC); if( rev ) *pRevMask |= MASKBIT(iLoop); revSet = 1; } } - if( isMatch && (pOrderBy->a[i].sortFlags & KEYINFO_ORDER_BIGNULL) ){ + if( isMatch && (pOrderBy->a[i].fg.sortFlags & KEYINFO_ORDER_BIGNULL) ){ if( j==pLoop->u.btree.nEq ){ pLoop->wsFlags |= WHERE_BIGNULL_SORT; }else{ diff --git a/src/whereexpr.c b/src/whereexpr.c index 90c344806e..89c6a466ce 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -1616,7 +1616,7 @@ void sqlite3WhereAddLimit(WhereClause *pWC, Select *p){ Expr *pExpr = pOrderBy->a[ii].pExpr; if( pExpr->op!=TK_COLUMN ) return; if( pExpr->iTable!=iCsr ) return; - if( pOrderBy->a[ii].sortFlags & KEYINFO_ORDER_BIGNULL ) return; + if( pOrderBy->a[ii].fg.sortFlags & KEYINFO_ORDER_BIGNULL ) return; } } diff --git a/src/window.c b/src/window.c index 7db5f6f1c7..893668664f 100644 --- a/src/window.c +++ b/src/window.c @@ -916,7 +916,7 @@ static ExprList *exprListAppendList( } } pList = sqlite3ExprListAppend(pParse, pList, pDup); - if( pList ) pList->a[nInit+i].sortFlags = pAppend->a[i].sortFlags; + if( pList ) pList->a[nInit+i].fg.sortFlags = pAppend->a[i].fg.sortFlags; } } return pList; @@ -2117,7 +2117,7 @@ static void windowCodeRangeTest( assert( op==OP_Ge || op==OP_Gt || op==OP_Le ); assert( pOrderBy && pOrderBy->nExpr==1 ); - if( pOrderBy->a[0].sortFlags & KEYINFO_ORDER_DESC ){ + if( pOrderBy->a[0].fg.sortFlags & KEYINFO_ORDER_DESC ){ switch( op ){ case OP_Ge: op = OP_Le; break; case OP_Gt: op = OP_Lt; break; @@ -2150,7 +2150,7 @@ static void windowCodeRangeTest( ** Additionally, if either reg1 or reg2 are NULL but the jump to lbl is ** not taken, control jumps over the comparison operator coded below this ** block. */ - if( pOrderBy->a[0].sortFlags & KEYINFO_ORDER_BIGNULL ){ + if( pOrderBy->a[0].fg.sortFlags & KEYINFO_ORDER_BIGNULL ){ /* This block runs if reg1 contains a NULL. */ int addr = sqlite3VdbeAddOp1(v, OP_NotNull, reg1); VdbeCoverage(v); switch( op ){ From 207f6263569835b649b1f472e12dacba8ee6a21b Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 3 May 2022 12:11:16 +0000 Subject: [PATCH 244/259] Add assert()s to show that jumps always land an an instruction that is between 1 and Vdbe.nOp-1. Had these assert()s been in place before, they would have caused an assertion fault for the byte-code error reported by [forum:/forumpost/2482b32700|forum post 2482b32700]. FossilOrigin-Name: 8f8a58feb7047d19522ca32efbe42fd9ddf49aaf9064f7373eb56a88982406a2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 2 ++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 5c3330d792..6f5ed17f42 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\stestcase()\smacro\staht\swas\smade\sobsolete\sby\s[a8da85c57e07721d]. -D 2022-05-02T15:47:57.110 +C Add\sassert()s\sto\sshow\sthat\sjumps\salways\sland\san\san\sinstruction\sthat\sis\sbetween\n1\sand\sVdbe.nOp-1.\s\sHad\sthese\sassert()s\sbeen\sin\splace\sbefore,\sthey\swould\shave\ncaused\san\sassertion\sfault\sfor\sthe\sbyte-code\serror\sreported\sby\n[forum:/forumpost/2482b32700|forum\spost\s2482b32700]. +D 2022-05-03T12:11:16.206 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -625,7 +625,7 @@ F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 -F src/vdbe.c 9527ab7f71c5b0291e5ed7727f213f4d7f6e0a82af019da5b365fd5a0f56bb96 +F src/vdbe.c a6a20956fa128c0b8d3c5592a9a3db890a46cf626f46ffee0cab2ac5bf8d04b2 F src/vdbe.h 07641758ca8b4f4c6d81ea667ea167c541e6ece21f5574da11e3d21ec37e2662 F src/vdbeInt.h ef43f7fdc5fde29fc3fd29c506c12830f366178fdb4edbbf0cbc3dfbd1278b5f F src/vdbeapi.c 354c893f1500cf524cc45c32879b9c68893a28b77e3442c24668d6afe4236217 @@ -1951,8 +1951,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 bcaa4a44749d157c5953c6f54c88b1ba29b4035f4b21fce986b7efbea372e109 -R e9ba3eaded9a5b3eaa4edaa039c7ca25 +P 053cf45ecaa7eac8cc64c7b2672807f736a45575a84b426263b2e1feb060b401 +R ac9704868f7c1c02692fbf03e14bf6d3 U drh -Z 097076191b03601e3038661a0fda0c02 +Z 2799ccc42c2b61451a2da6d606baab94 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index da0a44df88..039e77d8b3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -053cf45ecaa7eac8cc64c7b2672807f736a45575a84b426263b2e1feb060b401 \ No newline at end of file +8f8a58feb7047d19522ca32efbe42fd9ddf49aaf9064f7373eb56a88982406a2 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 087a837955..589f5df9f5 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -1043,6 +1043,8 @@ case OP_InitCoroutine: { /* jump */ /* Most jump operations do a goto to this spot in order to update ** the pOp pointer. */ jump_to_p2: + assert( pOp->p2>0 ); /* There are never any jumps to instruction 0 */ + assert( pOp->p2nOp ); /* Jumps must be in range */ pOp = &aOp[pOp->p2 - 1]; break; } From 8aa7f4d8130fe6a8517c6e136ee929dbe2bf2bcf Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 3 May 2022 14:01:48 +0000 Subject: [PATCH 245/259] Fix the Bloom filter pull-down optimization so that it jumps to the correct place if it encounters a NULL key. Fix for the bug described by [forum:/forumpost/2482b32700384a0f|forum thread 2482b32700384a0f]. FossilOrigin-Name: 6eda9b1a7784cf6d58c8876551f67ab98e78a08e726a0579d4def5ba881985bb --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/wherecode.c | 3 +++ test/join5.test | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 6f5ed17f42..81a7fdb108 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sassert()s\sto\sshow\sthat\sjumps\salways\sland\san\san\sinstruction\sthat\sis\sbetween\n1\sand\sVdbe.nOp-1.\s\sHad\sthese\sassert()s\sbeen\sin\splace\sbefore,\sthey\swould\shave\ncaused\san\sassertion\sfault\sfor\sthe\sbyte-code\serror\sreported\sby\n[forum:/forumpost/2482b32700|forum\spost\s2482b32700]. -D 2022-05-03T12:11:16.206 +C Fix\sthe\sBloom\sfilter\spull-down\soptimization\sso\sthat\sit\sjumps\sto\sthe\scorrect\nplace\sif\sit\sencounters\sa\sNULL\skey.\s\sFix\sfor\sthe\sbug\sdescribed\sby\n[forum:/forumpost/2482b32700384a0f|forum\sthread\s2482b32700384a0f]. +D 2022-05-03T14:01:48.589 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -642,7 +642,7 @@ F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b F src/where.c 43085b3a4ce2e56315fabb0b240a56e76667d9e03c79f287695bcae7b76152d5 F src/whereInt.h 4db5a877a9d1f38b5c928c1c84297c07f30b9a3bc1f5f66214cf1a8ef90a0556 -F src/wherecode.c dfc3fbb6b7cb14a5a8e022d22f4d2c6004807e458a7cd8278194fbef7c1670e1 +F src/wherecode.c cd9da760d391a51013f9ab8bc8ca7ad67f3b96e4857efe0d1dd85f538b3494a6 F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 F src/window.c 924e04fd6e0e113d4dba18b78d43fcb8e42b8ebffc8fc728da52cf3ab014cf3c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1145,7 +1145,7 @@ F test/join.test e5f165dfd84fd46406ddae6614b0122c3bfa23a26ef62966442e1503c40d96a F test/join2.test 466b07233820f5deee66a6c3bf6e4500c8bbf7b83649e67606f5f649c07928c0 F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 -F test/join5.test c4df54e2e204d7f1417bfbdd21ca324b4b07415c647595cc47798eacfddc96d3 +F test/join5.test d22b6cba8fb59ab3f1c82701434c360705eb12d4ce200c449f37b018fc47681a F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c F test/join7.test 8e72de4b45e5e930d18c305c7efe86015fb2552731e4e03ea226353036b0dab0 F test/join8.test 9a4b2f53d5358abb29e6356e357c0cd40f4d8f282589300dcb76728dce050b51 @@ -1951,8 +1951,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 053cf45ecaa7eac8cc64c7b2672807f736a45575a84b426263b2e1feb060b401 -R ac9704868f7c1c02692fbf03e14bf6d3 +P 8f8a58feb7047d19522ca32efbe42fd9ddf49aaf9064f7373eb56a88982406a2 +R 48e95e8ad10915971573fc98c5fba3fb U drh -Z 2799ccc42c2b61451a2da6d606baab94 +Z 4d1d0f66bed5171c72952a11ac9180b2 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 039e77d8b3..b5b28cd857 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8f8a58feb7047d19522ca32efbe42fd9ddf49aaf9064f7373eb56a88982406a2 \ No newline at end of file +6eda9b1a7784cf6d58c8876551f67ab98e78a08e726a0579d4def5ba881985bb \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 6f5a85386b..0a4a0019cf 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1412,6 +1412,8 @@ static SQLITE_NOINLINE void filterPullDown( /* ,--- Because sqlite3ConstructBloomFilter() has will not have set ** vvvvv--' pLevel->regFilter if this were true. */ if( NEVER(pLoop->prereq & notReady) ) continue; + assert( pLevel->addrBrk==0 ); + pLevel->addrBrk = addrNxt; if( pLoop->wsFlags & WHERE_IPK ){ WhereTerm *pTerm = pLoop->aLTerm[0]; int regRowid; @@ -1438,6 +1440,7 @@ static SQLITE_NOINLINE void filterPullDown( VdbeCoverage(pParse->pVdbe); } pLevel->regFilter = 0; + pLevel->addrBrk = 0; } } diff --git a/test/join5.test b/test/join5.test index e4fd9cd871..2ffe3f8ace 100644 --- a/test/join5.test +++ b/test/join5.test @@ -393,6 +393,38 @@ do_execsql_test 11.4 { SELECT count(*) FROM t1 LEFT JOIN t2 ON c=b WHERE d>=300; } {2} +# 2022-05-03 https://sqlite.org/forum/forumpost/2482b32700384a0f +# Bloom-filter pull-down does not handle NOT NULL constraints correctly. +# +reset_db +do_execsql_test 12.1 { + CREATE TABLE t1(a INT, b INT, c INT); + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100) + INSERT INTO t1(a,b,c) SELECT x, x*1000, x*1000000 FROM c; + CREATE TABLE t2(b INT, x INT); + INSERT INTO t2(b,x) SELECT b, a FROM t1 WHERE a%3==0; + CREATE INDEX t2b ON t2(b); + CREATE TABLE t3(c INT, y INT); + INSERT INTO t3(c,y) SELECT c, a FROM t1 WHERE a%4==0; + CREATE INDEX t3c ON t3(c); + INSERT INTO t1(a,b,c) VALUES(200, 200000, NULL); + ANALYZE; +} {} +do_execsql_test 12.2 { + SELECT * FROM t1 NATURAL JOIN t2 NATURAL JOIN t3 WHERE x>0 AND y>0 + ORDER BY +a; +} { + 12 12000 12000000 12 12 + 24 24000 24000000 24 24 + 36 36000 36000000 36 36 + 48 48000 48000000 48 48 + 60 60000 60000000 60 60 + 72 72000 72000000 72 72 + 84 84000 84000000 84 84 + 96 96000 96000000 96 96 +} + + finish_test From 00e5d3d59e78a78b2a1762ac4d054f303174f456 Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 3 May 2022 16:18:25 +0000 Subject: [PATCH 246/259] Fix a typo in a comment. FossilOrigin-Name: c19c3c48698bf2543d775411c62d01e629791e2f3c5317970fdbb830eacafac6 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index b104fa4288..bc4459427d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Organize\sthe\svarious\sflag\sbits\sof\sthe\sExprList_item\sobject\sinto\sa\ssubstructure\nso\sthat\sthe\swhole\slot\scan\sbe\scopied\sall\sat\sonce.\s\sFaster\sand\ssmaller\scode. -D 2022-05-02T20:49:30.890 +C Fix\sa\stypo\sin\sa\scomment. +D 2022-05-03T16:18:25.563 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -553,7 +553,7 @@ F src/printf.c 512574910a45341c8ad244bd3d4939968ebdfde215645b676fff01cc46e90757 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c e9ee235c4151d2b7fa47435a219bfd30bf516a804d2f004639858087ebf3137b F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 727e718482269f24e6db2850074498b14949ecf0778f065580f9ab0f2e76675e +F src/select.c 151adca2c9ea6f51215e4351bb8eb4f0012bf98c3d5a5c991d4a019c7cbb143e F src/shell.c.in ae0a6fae983caac6f8c824733f0599dfdf7b3a7e8efdef3cb5e3ab2e457ffc35 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1952,8 +1952,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 e01f4c05c21e89dcc7985e00874f288d9ba5d5d932f7284f8d970bd3145ac0c2 -R 4390ecbce69667e0c74ca1d6573c2546 +P 5341d4bbe9a943f9cdbbdea829e18f108e98972ebb706396c50fc62fcc6a6328 +R 57e92245f83a453fc0fb383304aceb64 U drh -Z ec5e63ee49f22b25e0961585c1886f82 +Z acf0fb1e4a92d1326c45eaf045dbeceb # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 942b4ff99c..b6a3d3f753 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5341d4bbe9a943f9cdbbdea829e18f108e98972ebb706396c50fc62fcc6a6328 \ No newline at end of file +c19c3c48698bf2543d775411c62d01e629791e2f3c5317970fdbb830eacafac6 \ No newline at end of file diff --git a/src/select.c b/src/select.c index b6b897d3a9..4ae8f16d1e 100644 --- a/src/select.c +++ b/src/select.c @@ -999,7 +999,7 @@ static void fixDistinctOpenEph( ** retrieved directly from table t1. If the values are very large, this ** can be more efficient than storing them directly in the sorter records. ** -** The ExprList_item.fg.fg.bSorterRef flag is set for each expression in pEList +** The ExprList_item.fg.bSorterRef flag is set for each expression in pEList ** for which the sorter-reference optimization should be enabled. ** Additionally, the pSort->aDefer[] array is populated with entries ** for all cursors required to evaluate all selected expressions. Finally. From bc33519de608ee7e3a138536f99a892f17435a22 Mon Sep 17 00:00:00 2001 From: larrybr Date: Tue, 3 May 2022 21:58:24 +0000 Subject: [PATCH 247/259] Typos cleared from README.md FossilOrigin-Name: be3a1879c865cff85d8b1f0cc7b95295019c28cce67c687692a3210eeea6e314 --- README.md | 28 ++++++++++++++-------------- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 9e8bb2610e..7ad42061c1 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@

    SQLite Source Repository

    -This repository contains the complete source code for the -[SQLite database engine](https://sqlite.org/). Some test scripts +This repository contains the complete source code for the +[SQLite database engine](https://sqlite.org/). Some test scripts are also included. However, many other test scripts and most of the documentation are managed separately. @@ -15,7 +15,7 @@ The [Fossil repository](https://sqlite.org/src/timeline) contains the urtext. If you are reading this on GitHub or some other Git repository or service, then you are looking at a mirror. The names of check-ins and other artifacts in a Git mirror are different from the official -names for those objects. The offical names for check-ins are +names for those objects. The official names for check-ins are found in a footer on the check-in comment for authorized mirrors. The official check-in name can also be seen in the `manifest.uuid` file in the root of the tree. Always use the official name, not the @@ -30,7 +30,7 @@ verify its integrity, there are hints on how to do that in the If you do not want to use Fossil, you can download tarballs or ZIP archives or [SQLite archives](https://sqlite.org/cli.html#sqlar) as follows: - * Lastest trunk check-in as + * Latest trunk check-in as [Tarball](https://www.sqlite.org/src/tarball/sqlite.tar.gz), [ZIP-archive](https://www.sqlite.org/src/zip/sqlite.zip), or [SQLite-archive](https://www.sqlite.org/src/sqlar/sqlite.sqlar). @@ -47,11 +47,11 @@ archives or [SQLite archives](https://sqlite.org/cli.html#sqlar) as follows: then click on the "Tarball" or "ZIP Archive" links on the information page. -If you do want to use Fossil to check out the source tree, +If you do want to use Fossil to check out the source tree, first install Fossil version 2.0 or later. (Source tarballs and precompiled binaries available [here](https://www.fossil-scm.org/fossil/uv/download.html). Fossil is -a stand-alone program. To install, simply download or build the single +a stand-alone program. To install, simply download or build the single executable file and put that file someplace on your $PATH.) Then run commands like this: @@ -61,7 +61,7 @@ Then run commands like this: fossil open ~/Fossils/sqlite.fossil After setting up a repository using the steps above, you can always -update to the lastest version using: +update to the latest version using: fossil update trunk ;# latest trunk check-in fossil update release ;# latest official release @@ -136,7 +136,7 @@ the "tclsqlite.c" file which implements the extension and only later escaped to the wild as an independent library.) Test scripts and programs are found in the **test/** subdirectory. -Addtional test code is found in other source repositories. +Additional test code is found in other source repositories. See [How SQLite Is Tested](http://www.sqlite.org/testing.html) for additional information. @@ -170,7 +170,7 @@ at just the right spots. Note that comment text in the sqlite3.h file is used to generate much of the SQLite API documentation. The Tcl scripts used to generate that documentation are in a separate source repository. -The SQL language parser is **parse.c** which is generate from a grammar in +The SQL language parser is **parse.c** which is generated from a grammar in the src/parse.y file. The conversion of "parse.y" into "parse.c" is done by the [lemon](./doc/lemon.html) LALR(1) parser generator. The source code for lemon is at tool/lemon.c. Lemon uses the tool/lempar.c file as a @@ -180,7 +180,7 @@ generates parse.c. The **opcodes.h** header file contains macros that define the numbers corresponding to opcodes in the "VDBE" virtual machine. The opcodes.h -file is generated by the scanning the src/vdbe.c source file. The +file is generated by scanning the src/vdbe.c source file. The Tcl script at ./mkopcodeh.tcl does this scan and generates opcodes.h. A second Tcl script, ./mkopcodec.tcl, then scans opcodes.h to generate the **opcodes.c** source file, which contains a reverse mapping from @@ -237,7 +237,7 @@ prepared statements, the description of [how transactions work](http://www.sqlite.org/atomiccommit.html), and the [overview of the query planner](http://www.sqlite.org/optoverview.html). -Years of effort have gone into optimizating SQLite, both +Years of effort have gone into optimizing SQLite, both for small size and high performance. And optimizations tend to result in complex code. So there is a lot of complexity in the current SQLite implementation. It will not be the easiest library in the world to hack. @@ -294,11 +294,11 @@ Key files: building the "testfixture.exe" program. The testfixture.exe program is an enhanced Tcl shell. The testfixture.exe program runs scripts in the test/ folder to validate the core SQLite code. The testfixture program - (and some other test programs too) is build and run when you type + (and some other test programs too) is built and run when you type "make test". * **ext/misc/json1.c** - This file implements the various JSON functions - that are build into SQLite. + that are built into SQLite. There are many other source files. Each has a succinct header comment that describes its purpose and role within the larger system. @@ -307,7 +307,7 @@ describes its purpose and role within the larger system. ## Verifying Code Authenticity The `manifest` file at the root directory of the source tree -contains either a SHA3-256 hash (for newer files) or a SHA1 hash (for +contains either a SHA3-256 hash (for newer files) or a SHA1 hash (for older files) for every source file in the repository. The name of the version of the entire source tree is just the SHA3-256 hash of the `manifest` file itself, possibly with the diff --git a/manifest b/manifest index 81a7fdb108..6833c4893b 100644 --- a/manifest +++ b/manifest @@ -1,12 +1,12 @@ -C Fix\sthe\sBloom\sfilter\spull-down\soptimization\sso\sthat\sit\sjumps\sto\sthe\scorrect\nplace\sif\sit\sencounters\sa\sNULL\skey.\s\sFix\sfor\sthe\sbug\sdescribed\sby\n[forum:/forumpost/2482b32700384a0f|forum\sthread\s2482b32700384a0f]. -D 2022-05-03T14:01:48.589 +C Typos\scleared\sfrom\sREADME.md +D 2022-05-03T21:58:24.696 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F Makefile.in b210ad2733317f1a4353085dfb9d385ceec30b0e6a61d20a5accabecac6b1949 F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241 F Makefile.msc b28a8a7a977e7312f6859f560348e1eb110c21bd6cf9fab0d16537c0a514eef3 -F README.md 2dd87a5c1d108b224921f3dd47dea567973f706e1f6959386282a626f459a70c +F README.md 8b8df9ca852aeac4864eb1e400002633ee6db84065bd01b78c33817f97d31f5e F VERSION fa8e7d2d1cc962f9e14c6d410387cf75860ee139462763fda887c1be4261f824 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 @@ -1951,8 +1951,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 8f8a58feb7047d19522ca32efbe42fd9ddf49aaf9064f7373eb56a88982406a2 -R 48e95e8ad10915971573fc98c5fba3fb -U drh -Z 4d1d0f66bed5171c72952a11ac9180b2 +P 6eda9b1a7784cf6d58c8876551f67ab98e78a08e726a0579d4def5ba881985bb +R 488c5ef0a2e2c65a8876ebd84535d64a +U larrybr +Z b08bed53df46d6042a3906cc46d3517d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index b5b28cd857..d70921cc06 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6eda9b1a7784cf6d58c8876551f67ab98e78a08e726a0579d4def5ba881985bb \ No newline at end of file +be3a1879c865cff85d8b1f0cc7b95295019c28cce67c687692a3210eeea6e314 \ No newline at end of file From 367c146b09949a3500535e1f587782c7baa65c51 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 4 May 2022 02:01:49 +0000 Subject: [PATCH 248/259] In the query planner, do not let tables commute across any outer join. FossilOrigin-Name: 8cee5388232ade91ea627bb6857eb8937d7530b5ea519e0ae6da362c37c7ed35 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 4 +--- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 6833c4893b..68a0d988fb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Typos\scleared\sfrom\sREADME.md -D 2022-05-03T21:58:24.696 +C In\sthe\squery\splanner,\sdo\snot\slet\stables\scommute\sacross\sany\souter\sjoin. +D 2022-05-04T02:01:49.881 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -640,7 +640,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c 43085b3a4ce2e56315fabb0b240a56e76667d9e03c79f287695bcae7b76152d5 +F src/where.c b0f0c4b38d80530ff5e88fb8978e67555cb6392c8cedfd9f80d4d4d8e4106336 F src/whereInt.h 4db5a877a9d1f38b5c928c1c84297c07f30b9a3bc1f5f66214cf1a8ef90a0556 F src/wherecode.c cd9da760d391a51013f9ab8bc8ca7ad67f3b96e4857efe0d1dd85f538b3494a6 F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 @@ -1951,8 +1951,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 6eda9b1a7784cf6d58c8876551f67ab98e78a08e726a0579d4def5ba881985bb -R 488c5ef0a2e2c65a8876ebd84535d64a -U larrybr -Z b08bed53df46d6042a3906cc46d3517d +P be3a1879c865cff85d8b1f0cc7b95295019c28cce67c687692a3210eeea6e314 +R 0ad645b7afda1c7b5bfd909d3f6cbc01 +U drh +Z c5be1cebf65efa58a4f8d67d25367727 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index d70921cc06..06b2a13f36 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -be3a1879c865cff85d8b1f0cc7b95295019c28cce67c687692a3210eeea6e314 \ No newline at end of file +8cee5388232ade91ea627bb6857eb8937d7530b5ea519e0ae6da362c37c7ed35 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 2750d93584..c6fa56cdbd 100644 --- a/src/where.c +++ b/src/where.c @@ -4144,9 +4144,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ if( (pItem->fg.jointype & (JT_OUTER|JT_CROSS))!=0 ){ /* This condition is true when pItem is the FROM clause term on the ** right-hand-side of a OUTER or CROSS JOIN. */ - mPrereq = mPrior; - }else{ - mPrereq = 0; + mPrereq |= mPrior; } #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pItem->pTab) ){ From b55776230d0e8dddf8aef758a5ddd9ad6d08734f Mon Sep 17 00:00:00 2001 From: larrybr Date: Wed, 4 May 2022 03:45:32 +0000 Subject: [PATCH 249/259] Fix CLI use of wrong allocator for free(). FossilOrigin-Name: 9fb20a21feb8f6979812f45691e06aa3e297d7370cf0d5820523e817a4e97863 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c.in | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 68a0d988fb..2c27eceb6c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C In\sthe\squery\splanner,\sdo\snot\slet\stables\scommute\sacross\sany\souter\sjoin. -D 2022-05-04T02:01:49.881 +C Fix\sCLI\suse\sof\swrong\sallocator\sfor\sfree(). +D 2022-05-04T03:45:32.728 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -554,7 +554,7 @@ F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c f72bb13359dd5a74d440df25f320dc2c1baff5cde4fc9f0d1bc3feba90b8932a F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c cc1a7581403fc074eee85283ba8d81de50a831ae175cb65a5751be00f621c0d5 -F src/shell.c.in ae0a6fae983caac6f8c824733f0599dfdf7b3a7e8efdef3cb5e3ab2e457ffc35 +F src/shell.c.in d842e26a30fe9acab962a20b1d7dd27e6130f76fbea1be64bf73982a6d64bc71 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e @@ -1951,8 +1951,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 be3a1879c865cff85d8b1f0cc7b95295019c28cce67c687692a3210eeea6e314 -R 0ad645b7afda1c7b5bfd909d3f6cbc01 -U drh -Z c5be1cebf65efa58a4f8d67d25367727 +P 8cee5388232ade91ea627bb6857eb8937d7530b5ea519e0ae6da362c37c7ed35 +R 3c89c63aaa0653a254417d115718d7c3 +U larrybr +Z 111ff23023abfd8d38c72ec3de24a2fe # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 06b2a13f36..0ae4c52f89 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8cee5388232ade91ea627bb6857eb8937d7530b5ea519e0ae6da362c37c7ed35 \ No newline at end of file +9fb20a21feb8f6979812f45691e06aa3e297d7370cf0d5820523e817a4e97863 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 95a32f5247..0f9cf53446 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -3540,7 +3540,7 @@ columnar_end: nData = (nRow+1)*nColumn; for(i=0; i Date: Wed, 4 May 2022 11:49:26 +0000 Subject: [PATCH 250/259] New test cases using various join types and Bloom filters. Two cases differ from PG and need to be resolved. FossilOrigin-Name: befa8cbc0682bc3269f87e392a1f3d4baacf4db7c716ea84192bb9c13c99490b --- manifest | 16 +- manifest.uuid | 2 +- test/joinD.test | 2961 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 2972 insertions(+), 7 deletions(-) create mode 100644 test/joinD.test diff --git a/manifest b/manifest index 2c27eceb6c..b4b9177d61 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sCLI\suse\sof\swrong\sallocator\sfor\sfree(). -D 2022-05-04T03:45:32.728 +C New\stest\scases\susing\svarious\sjoin\stypes\sand\sBloom\sfilters.\s\sTwo\scases\ndiffer\sfrom\sPG\sand\sneed\sto\sbe\sresolved. +D 2022-05-04T11:49:26.461 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1152,6 +1152,7 @@ F test/join8.test 9a4b2f53d5358abb29e6356e357c0cd40f4d8f282589300dcb76728dce050b F test/join9.test 9056ddd3b0c0f4f9d658f4521038d9a37dc23ead8ca9a505d0b0db2b6a471e05 F test/joinA.test 7eab225dc1c1ab258a5e62513a4ed7cabbd3db971d59d5d92f4fb6fa14c12f6a F test/joinB.test 1b2ba3fc8568b49411787fccbf540570c148e9b6a53a30f80691cb6268098ded +F test/joinD.test 58fb0aae651798a2264128f3f6f6ee3c9b5d5548071a1044365511b10de4edd3 F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -1951,8 +1952,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 8cee5388232ade91ea627bb6857eb8937d7530b5ea519e0ae6da362c37c7ed35 -R 3c89c63aaa0653a254417d115718d7c3 -U larrybr -Z 111ff23023abfd8d38c72ec3de24a2fe +P 9fb20a21feb8f6979812f45691e06aa3e297d7370cf0d5820523e817a4e97863 +R 1cecd5f53d4f5e59729da8bc3d52cbbb +T *branch * joinD +T *sym-joinD * +T -sym-trunk * +U drh +Z fd017d0848e05371e5483ff3dffc569c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0ae4c52f89..e97130cfc5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9fb20a21feb8f6979812f45691e06aa3e297d7370cf0d5820523e817a4e97863 \ No newline at end of file +befa8cbc0682bc3269f87e392a1f3d4baacf4db7c716ea84192bb9c13c99490b \ No newline at end of file diff --git a/test/joinD.test b/test/joinD.test new file mode 100644 index 0000000000..9ac813ffab --- /dev/null +++ b/test/joinD.test @@ -0,0 +1,2961 @@ +# 2022-05-04 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file implements tests for JOINs that use Bloom filters. +# +# The test case output is all generated by PostgreSQL 14. This test module +# was created as follows: +# +# 1. Run a TCL script (included at the bottom of this file) that +# generates an input script for "psql" that will run man +# diverse tests on joins. +# +# 2. Run the script from step (1) through psql and collect the +# output. +# +# 3. Make a few minor global search-and-replace operations to convert +# the psql output into a form suitable for this test module. +# +# 4. Add this header, and the script content at the footer. +# +set testdir [file dirname $argv0] +source $testdir/tester.tcl +db nullvalue - +db eval { + CREATE TABLE t1(a INT, b INT, c INT, d INT); + WITH RECURSIVE c(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM c WHERE x<95) + INSERT INTO t1(a,b,c,d) SELECT x, x+100, x+200, x+300 FROM c; + CREATE TABLE t2(b INT, x INT); + INSERT INTO t2(b,x) SELECT b, a FROM t1 WHERE a%2=0; + CREATE INDEX t2b ON t2(b); + CREATE TABLE t3(c INT, y INT); + INSERT INTO t3(c,y) SELECT c, a FROM t1 WHERE a%3=0; + CREATE INDEX t3c ON t3(c); + CREATE TABLE t4(d INT, z INT); + INSERT INTO t4(d,z) SELECT d, a FROM t1 WHERE a%5=0; + CREATE INDEX t4d ON t4(d); + INSERT INTO t1(a,b,c,d) VALUES + (96,NULL,296,396), + (97,197,NULL,397), + (98,198,298,NULL), + (99,NULL,NULL,NULL); + ANALYZE; +} +do_execsql_test joinD-1 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 INNER JOIN t2 ON t1.b=t2.b AND t2.x>0 + INNER JOIN t3 ON t1.c=t3.c AND t3.y>0 + INNER JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 30 130 230 330 130 30 230 30 330 30 + 60 160 260 360 160 60 260 60 360 60 + 90 190 290 390 190 90 290 90 390 90 +} +do_execsql_test joinD-2 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 INNER JOIN t2 ON t1.b=t2.b AND t2.x>0 + INNER JOIN t3 ON t1.c=t3.c AND t3.y>0 + LEFT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 6 106 206 306 106 6 206 6 - - + 12 112 212 312 112 12 212 12 - - + 18 118 218 318 118 18 218 18 - - + 24 124 224 324 124 24 224 24 - - + 30 130 230 330 130 30 230 30 330 30 + 36 136 236 336 136 36 236 36 - - + 42 142 242 342 142 42 242 42 - - + 48 148 248 348 148 48 248 48 - - + 54 154 254 354 154 54 254 54 - - + 60 160 260 360 160 60 260 60 360 60 + 66 166 266 366 166 66 266 66 - - + 72 172 272 372 172 72 272 72 - - + 78 178 278 378 178 78 278 78 - - + 84 184 284 384 184 84 284 84 - - + 90 190 290 390 190 90 290 90 390 90 +} +do_execsql_test joinD-3 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 INNER JOIN t2 ON t1.b=t2.b AND t2.x>0 + INNER JOIN t3 ON t1.c=t3.c AND t3.y>0 + RIGHT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 30 130 230 330 130 30 230 30 330 30 + 60 160 260 360 160 60 260 60 360 60 + 90 190 290 390 190 90 290 90 390 90 + - - - - - - - - 300 0 + - - - - - - - - 305 5 + - - - - - - - - 310 10 + - - - - - - - - 315 15 + - - - - - - - - 320 20 + - - - - - - - - 325 25 + - - - - - - - - 335 35 + - - - - - - - - 340 40 + - - - - - - - - 345 45 + - - - - - - - - 350 50 + - - - - - - - - 355 55 + - - - - - - - - 365 65 + - - - - - - - - 370 70 + - - - - - - - - 375 75 + - - - - - - - - 380 80 + - - - - - - - - 385 85 + - - - - - - - - 395 95 +} +do_execsql_test joinD-4 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 INNER JOIN t2 ON t1.b=t2.b AND t2.x>0 + INNER JOIN t3 ON t1.c=t3.c AND t3.y>0 + FULL JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 6 106 206 306 106 6 206 6 - - + 12 112 212 312 112 12 212 12 - - + 18 118 218 318 118 18 218 18 - - + 24 124 224 324 124 24 224 24 - - + 30 130 230 330 130 30 230 30 330 30 + 36 136 236 336 136 36 236 36 - - + 42 142 242 342 142 42 242 42 - - + 48 148 248 348 148 48 248 48 - - + 54 154 254 354 154 54 254 54 - - + 60 160 260 360 160 60 260 60 360 60 + 66 166 266 366 166 66 266 66 - - + 72 172 272 372 172 72 272 72 - - + 78 178 278 378 178 78 278 78 - - + 84 184 284 384 184 84 284 84 - - + 90 190 290 390 190 90 290 90 390 90 + - - - - - - - - 300 0 + - - - - - - - - 305 5 + - - - - - - - - 310 10 + - - - - - - - - 315 15 + - - - - - - - - 320 20 + - - - - - - - - 325 25 + - - - - - - - - 335 35 + - - - - - - - - 340 40 + - - - - - - - - 345 45 + - - - - - - - - 350 50 + - - - - - - - - 355 55 + - - - - - - - - 365 65 + - - - - - - - - 370 70 + - - - - - - - - 375 75 + - - - - - - - - 380 80 + - - - - - - - - 385 85 + - - - - - - - - 395 95 +} +do_execsql_test joinD-5 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 INNER JOIN t2 ON t1.b=t2.b AND t2.x>0 + LEFT JOIN t3 ON t1.c=t3.c AND t3.y>0 + INNER JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 10 110 210 310 110 10 - - 310 10 + 20 120 220 320 120 20 - - 320 20 + 30 130 230 330 130 30 230 30 330 30 + 40 140 240 340 140 40 - - 340 40 + 50 150 250 350 150 50 - - 350 50 + 60 160 260 360 160 60 260 60 360 60 + 70 170 270 370 170 70 - - 370 70 + 80 180 280 380 180 80 - - 380 80 + 90 190 290 390 190 90 290 90 390 90 +} +do_execsql_test joinD-6 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 INNER JOIN t2 ON t1.b=t2.b AND t2.x>0 + LEFT JOIN t3 ON t1.c=t3.c AND t3.y>0 + LEFT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 2 102 202 302 102 2 - - - - + 4 104 204 304 104 4 - - - - + 6 106 206 306 106 6 206 6 - - + 8 108 208 308 108 8 - - - - + 10 110 210 310 110 10 - - 310 10 + 12 112 212 312 112 12 212 12 - - + 14 114 214 314 114 14 - - - - + 16 116 216 316 116 16 - - - - + 18 118 218 318 118 18 218 18 - - + 20 120 220 320 120 20 - - 320 20 + 22 122 222 322 122 22 - - - - + 24 124 224 324 124 24 224 24 - - + 26 126 226 326 126 26 - - - - + 28 128 228 328 128 28 - - - - + 30 130 230 330 130 30 230 30 330 30 + 32 132 232 332 132 32 - - - - + 34 134 234 334 134 34 - - - - + 36 136 236 336 136 36 236 36 - - + 38 138 238 338 138 38 - - - - + 40 140 240 340 140 40 - - 340 40 + 42 142 242 342 142 42 242 42 - - + 44 144 244 344 144 44 - - - - + 46 146 246 346 146 46 - - - - + 48 148 248 348 148 48 248 48 - - + 50 150 250 350 150 50 - - 350 50 + 52 152 252 352 152 52 - - - - + 54 154 254 354 154 54 254 54 - - + 56 156 256 356 156 56 - - - - + 58 158 258 358 158 58 - - - - + 60 160 260 360 160 60 260 60 360 60 + 62 162 262 362 162 62 - - - - + 64 164 264 364 164 64 - - - - + 66 166 266 366 166 66 266 66 - - + 68 168 268 368 168 68 - - - - + 70 170 270 370 170 70 - - 370 70 + 72 172 272 372 172 72 272 72 - - + 74 174 274 374 174 74 - - - - + 76 176 276 376 176 76 - - - - + 78 178 278 378 178 78 278 78 - - + 80 180 280 380 180 80 - - 380 80 + 82 182 282 382 182 82 - - - - + 84 184 284 384 184 84 284 84 - - + 86 186 286 386 186 86 - - - - + 88 188 288 388 188 88 - - - - + 90 190 290 390 190 90 290 90 390 90 + 92 192 292 392 192 92 - - - - + 94 194 294 394 194 94 - - - - +} +do_execsql_test joinD-7 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 INNER JOIN t2 ON t1.b=t2.b AND t2.x>0 + LEFT JOIN t3 ON t1.c=t3.c AND t3.y>0 + RIGHT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 10 110 210 310 110 10 - - 310 10 + 20 120 220 320 120 20 - - 320 20 + 30 130 230 330 130 30 230 30 330 30 + 40 140 240 340 140 40 - - 340 40 + 50 150 250 350 150 50 - - 350 50 + 60 160 260 360 160 60 260 60 360 60 + 70 170 270 370 170 70 - - 370 70 + 80 180 280 380 180 80 - - 380 80 + 90 190 290 390 190 90 290 90 390 90 + - - - - - - - - 300 0 + - - - - - - - - 305 5 + - - - - - - - - 315 15 + - - - - - - - - 325 25 + - - - - - - - - 335 35 + - - - - - - - - 345 45 + - - - - - - - - 355 55 + - - - - - - - - 365 65 + - - - - - - - - 375 75 + - - - - - - - - 385 85 + - - - - - - - - 395 95 +} +do_execsql_test joinD-8 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 INNER JOIN t2 ON t1.b=t2.b AND t2.x>0 + LEFT JOIN t3 ON t1.c=t3.c AND t3.y>0 + FULL JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 2 102 202 302 102 2 - - - - + 4 104 204 304 104 4 - - - - + 6 106 206 306 106 6 206 6 - - + 8 108 208 308 108 8 - - - - + 10 110 210 310 110 10 - - 310 10 + 12 112 212 312 112 12 212 12 - - + 14 114 214 314 114 14 - - - - + 16 116 216 316 116 16 - - - - + 18 118 218 318 118 18 218 18 - - + 20 120 220 320 120 20 - - 320 20 + 22 122 222 322 122 22 - - - - + 24 124 224 324 124 24 224 24 - - + 26 126 226 326 126 26 - - - - + 28 128 228 328 128 28 - - - - + 30 130 230 330 130 30 230 30 330 30 + 32 132 232 332 132 32 - - - - + 34 134 234 334 134 34 - - - - + 36 136 236 336 136 36 236 36 - - + 38 138 238 338 138 38 - - - - + 40 140 240 340 140 40 - - 340 40 + 42 142 242 342 142 42 242 42 - - + 44 144 244 344 144 44 - - - - + 46 146 246 346 146 46 - - - - + 48 148 248 348 148 48 248 48 - - + 50 150 250 350 150 50 - - 350 50 + 52 152 252 352 152 52 - - - - + 54 154 254 354 154 54 254 54 - - + 56 156 256 356 156 56 - - - - + 58 158 258 358 158 58 - - - - + 60 160 260 360 160 60 260 60 360 60 + 62 162 262 362 162 62 - - - - + 64 164 264 364 164 64 - - - - + 66 166 266 366 166 66 266 66 - - + 68 168 268 368 168 68 - - - - + 70 170 270 370 170 70 - - 370 70 + 72 172 272 372 172 72 272 72 - - + 74 174 274 374 174 74 - - - - + 76 176 276 376 176 76 - - - - + 78 178 278 378 178 78 278 78 - - + 80 180 280 380 180 80 - - 380 80 + 82 182 282 382 182 82 - - - - + 84 184 284 384 184 84 284 84 - - + 86 186 286 386 186 86 - - - - + 88 188 288 388 188 88 - - - - + 90 190 290 390 190 90 290 90 390 90 + 92 192 292 392 192 92 - - - - + 94 194 294 394 194 94 - - - - + - - - - - - - - 300 0 + - - - - - - - - 305 5 + - - - - - - - - 315 15 + - - - - - - - - 325 25 + - - - - - - - - 335 35 + - - - - - - - - 345 45 + - - - - - - - - 355 55 + - - - - - - - - 365 65 + - - - - - - - - 375 75 + - - - - - - - - 385 85 + - - - - - - - - 395 95 +} +do_execsql_test joinD-9 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 INNER JOIN t2 ON t1.b=t2.b AND t2.x>0 + RIGHT JOIN t3 ON t1.c=t3.c AND t3.y>0 + INNER JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 30 130 230 330 130 30 230 30 330 30 + 60 160 260 360 160 60 260 60 360 60 + 90 190 290 390 190 90 290 90 390 90 +} +do_execsql_test joinD-10 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 INNER JOIN t2 ON t1.b=t2.b AND t2.x>0 + RIGHT JOIN t3 ON t1.c=t3.c AND t3.y>0 + LEFT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 6 106 206 306 106 6 206 6 - - + 12 112 212 312 112 12 212 12 - - + 18 118 218 318 118 18 218 18 - - + 24 124 224 324 124 24 224 24 - - + 30 130 230 330 130 30 230 30 330 30 + 36 136 236 336 136 36 236 36 - - + 42 142 242 342 142 42 242 42 - - + 48 148 248 348 148 48 248 48 - - + 54 154 254 354 154 54 254 54 - - + 60 160 260 360 160 60 260 60 360 60 + 66 166 266 366 166 66 266 66 - - + 72 172 272 372 172 72 272 72 - - + 78 178 278 378 178 78 278 78 - - + 84 184 284 384 184 84 284 84 - - + 90 190 290 390 190 90 290 90 390 90 + - - - - - - 200 0 - - + - - - - - - 203 3 - - + - - - - - - 209 9 - - + - - - - - - 215 15 - - + - - - - - - 221 21 - - + - - - - - - 227 27 - - + - - - - - - 233 33 - - + - - - - - - 239 39 - - + - - - - - - 245 45 - - + - - - - - - 251 51 - - + - - - - - - 257 57 - - + - - - - - - 263 63 - - + - - - - - - 269 69 - - + - - - - - - 275 75 - - + - - - - - - 281 81 - - + - - - - - - 287 87 - - + - - - - - - 293 93 - - +} +do_execsql_test joinD-11 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 INNER JOIN t2 ON t1.b=t2.b AND t2.x>0 + RIGHT JOIN t3 ON t1.c=t3.c AND t3.y>0 + RIGHT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 30 130 230 330 130 30 230 30 330 30 + 60 160 260 360 160 60 260 60 360 60 + 90 190 290 390 190 90 290 90 390 90 + - - - - - - - - 300 0 + - - - - - - - - 305 5 + - - - - - - - - 310 10 + - - - - - - - - 315 15 + - - - - - - - - 320 20 + - - - - - - - - 325 25 + - - - - - - - - 335 35 + - - - - - - - - 340 40 + - - - - - - - - 345 45 + - - - - - - - - 350 50 + - - - - - - - - 355 55 + - - - - - - - - 365 65 + - - - - - - - - 370 70 + - - - - - - - - 375 75 + - - - - - - - - 380 80 + - - - - - - - - 385 85 + - - - - - - - - 395 95 +} +do_execsql_test joinD-12 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 INNER JOIN t2 ON t1.b=t2.b AND t2.x>0 + RIGHT JOIN t3 ON t1.c=t3.c AND t3.y>0 + FULL JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 6 106 206 306 106 6 206 6 - - + 12 112 212 312 112 12 212 12 - - + 18 118 218 318 118 18 218 18 - - + 24 124 224 324 124 24 224 24 - - + 30 130 230 330 130 30 230 30 330 30 + 36 136 236 336 136 36 236 36 - - + 42 142 242 342 142 42 242 42 - - + 48 148 248 348 148 48 248 48 - - + 54 154 254 354 154 54 254 54 - - + 60 160 260 360 160 60 260 60 360 60 + 66 166 266 366 166 66 266 66 - - + 72 172 272 372 172 72 272 72 - - + 78 178 278 378 178 78 278 78 - - + 84 184 284 384 184 84 284 84 - - + 90 190 290 390 190 90 290 90 390 90 + - - - - - - 200 0 - - + - - - - - - 203 3 - - + - - - - - - 209 9 - - + - - - - - - 215 15 - - + - - - - - - 221 21 - - + - - - - - - 227 27 - - + - - - - - - 233 33 - - + - - - - - - 239 39 - - + - - - - - - 245 45 - - + - - - - - - 251 51 - - + - - - - - - 257 57 - - + - - - - - - 263 63 - - + - - - - - - 269 69 - - + - - - - - - 275 75 - - + - - - - - - 281 81 - - + - - - - - - 287 87 - - + - - - - - - 293 93 - - + - - - - - - - - 300 0 + - - - - - - - - 305 5 + - - - - - - - - 310 10 + - - - - - - - - 315 15 + - - - - - - - - 320 20 + - - - - - - - - 325 25 + - - - - - - - - 335 35 + - - - - - - - - 340 40 + - - - - - - - - 345 45 + - - - - - - - - 350 50 + - - - - - - - - 355 55 + - - - - - - - - 365 65 + - - - - - - - - 370 70 + - - - - - - - - 375 75 + - - - - - - - - 380 80 + - - - - - - - - 385 85 + - - - - - - - - 395 95 +} +do_execsql_test joinD-13 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 INNER JOIN t2 ON t1.b=t2.b AND t2.x>0 + FULL JOIN t3 ON t1.c=t3.c AND t3.y>0 + INNER JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 10 110 210 310 110 10 - - 310 10 + 20 120 220 320 120 20 - - 320 20 + 30 130 230 330 130 30 230 30 330 30 + 40 140 240 340 140 40 - - 340 40 + 50 150 250 350 150 50 - - 350 50 + 60 160 260 360 160 60 260 60 360 60 + 70 170 270 370 170 70 - - 370 70 + 80 180 280 380 180 80 - - 380 80 + 90 190 290 390 190 90 290 90 390 90 +} +do_execsql_test joinD-14 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 INNER JOIN t2 ON t1.b=t2.b AND t2.x>0 + FULL JOIN t3 ON t1.c=t3.c AND t3.y>0 + LEFT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 2 102 202 302 102 2 - - - - + 4 104 204 304 104 4 - - - - + 6 106 206 306 106 6 206 6 - - + 8 108 208 308 108 8 - - - - + 10 110 210 310 110 10 - - 310 10 + 12 112 212 312 112 12 212 12 - - + 14 114 214 314 114 14 - - - - + 16 116 216 316 116 16 - - - - + 18 118 218 318 118 18 218 18 - - + 20 120 220 320 120 20 - - 320 20 + 22 122 222 322 122 22 - - - - + 24 124 224 324 124 24 224 24 - - + 26 126 226 326 126 26 - - - - + 28 128 228 328 128 28 - - - - + 30 130 230 330 130 30 230 30 330 30 + 32 132 232 332 132 32 - - - - + 34 134 234 334 134 34 - - - - + 36 136 236 336 136 36 236 36 - - + 38 138 238 338 138 38 - - - - + 40 140 240 340 140 40 - - 340 40 + 42 142 242 342 142 42 242 42 - - + 44 144 244 344 144 44 - - - - + 46 146 246 346 146 46 - - - - + 48 148 248 348 148 48 248 48 - - + 50 150 250 350 150 50 - - 350 50 + 52 152 252 352 152 52 - - - - + 54 154 254 354 154 54 254 54 - - + 56 156 256 356 156 56 - - - - + 58 158 258 358 158 58 - - - - + 60 160 260 360 160 60 260 60 360 60 + 62 162 262 362 162 62 - - - - + 64 164 264 364 164 64 - - - - + 66 166 266 366 166 66 266 66 - - + 68 168 268 368 168 68 - - - - + 70 170 270 370 170 70 - - 370 70 + 72 172 272 372 172 72 272 72 - - + 74 174 274 374 174 74 - - - - + 76 176 276 376 176 76 - - - - + 78 178 278 378 178 78 278 78 - - + 80 180 280 380 180 80 - - 380 80 + 82 182 282 382 182 82 - - - - + 84 184 284 384 184 84 284 84 - - + 86 186 286 386 186 86 - - - - + 88 188 288 388 188 88 - - - - + 90 190 290 390 190 90 290 90 390 90 + 92 192 292 392 192 92 - - - - + 94 194 294 394 194 94 - - - - + - - - - - - 200 0 - - + - - - - - - 203 3 - - + - - - - - - 209 9 - - + - - - - - - 215 15 - - + - - - - - - 221 21 - - + - - - - - - 227 27 - - + - - - - - - 233 33 - - + - - - - - - 239 39 - - + - - - - - - 245 45 - - + - - - - - - 251 51 - - + - - - - - - 257 57 - - + - - - - - - 263 63 - - + - - - - - - 269 69 - - + - - - - - - 275 75 - - + - - - - - - 281 81 - - + - - - - - - 287 87 - - + - - - - - - 293 93 - - +} +do_execsql_test joinD-15 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 INNER JOIN t2 ON t1.b=t2.b AND t2.x>0 + FULL JOIN t3 ON t1.c=t3.c AND t3.y>0 + RIGHT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 10 110 210 310 110 10 - - 310 10 + 20 120 220 320 120 20 - - 320 20 + 30 130 230 330 130 30 230 30 330 30 + 40 140 240 340 140 40 - - 340 40 + 50 150 250 350 150 50 - - 350 50 + 60 160 260 360 160 60 260 60 360 60 + 70 170 270 370 170 70 - - 370 70 + 80 180 280 380 180 80 - - 380 80 + 90 190 290 390 190 90 290 90 390 90 + - - - - - - - - 300 0 + - - - - - - - - 305 5 + - - - - - - - - 315 15 + - - - - - - - - 325 25 + - - - - - - - - 335 35 + - - - - - - - - 345 45 + - - - - - - - - 355 55 + - - - - - - - - 365 65 + - - - - - - - - 375 75 + - - - - - - - - 385 85 + - - - - - - - - 395 95 +} +do_execsql_test joinD-16 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 INNER JOIN t2 ON t1.b=t2.b AND t2.x>0 + FULL JOIN t3 ON t1.c=t3.c AND t3.y>0 + FULL JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 2 102 202 302 102 2 - - - - + 4 104 204 304 104 4 - - - - + 6 106 206 306 106 6 206 6 - - + 8 108 208 308 108 8 - - - - + 10 110 210 310 110 10 - - 310 10 + 12 112 212 312 112 12 212 12 - - + 14 114 214 314 114 14 - - - - + 16 116 216 316 116 16 - - - - + 18 118 218 318 118 18 218 18 - - + 20 120 220 320 120 20 - - 320 20 + 22 122 222 322 122 22 - - - - + 24 124 224 324 124 24 224 24 - - + 26 126 226 326 126 26 - - - - + 28 128 228 328 128 28 - - - - + 30 130 230 330 130 30 230 30 330 30 + 32 132 232 332 132 32 - - - - + 34 134 234 334 134 34 - - - - + 36 136 236 336 136 36 236 36 - - + 38 138 238 338 138 38 - - - - + 40 140 240 340 140 40 - - 340 40 + 42 142 242 342 142 42 242 42 - - + 44 144 244 344 144 44 - - - - + 46 146 246 346 146 46 - - - - + 48 148 248 348 148 48 248 48 - - + 50 150 250 350 150 50 - - 350 50 + 52 152 252 352 152 52 - - - - + 54 154 254 354 154 54 254 54 - - + 56 156 256 356 156 56 - - - - + 58 158 258 358 158 58 - - - - + 60 160 260 360 160 60 260 60 360 60 + 62 162 262 362 162 62 - - - - + 64 164 264 364 164 64 - - - - + 66 166 266 366 166 66 266 66 - - + 68 168 268 368 168 68 - - - - + 70 170 270 370 170 70 - - 370 70 + 72 172 272 372 172 72 272 72 - - + 74 174 274 374 174 74 - - - - + 76 176 276 376 176 76 - - - - + 78 178 278 378 178 78 278 78 - - + 80 180 280 380 180 80 - - 380 80 + 82 182 282 382 182 82 - - - - + 84 184 284 384 184 84 284 84 - - + 86 186 286 386 186 86 - - - - + 88 188 288 388 188 88 - - - - + 90 190 290 390 190 90 290 90 390 90 + 92 192 292 392 192 92 - - - - + 94 194 294 394 194 94 - - - - + - - - - - - 200 0 - - + - - - - - - 203 3 - - + - - - - - - 209 9 - - + - - - - - - 215 15 - - + - - - - - - 221 21 - - + - - - - - - 227 27 - - + - - - - - - 233 33 - - + - - - - - - 239 39 - - + - - - - - - 245 45 - - + - - - - - - 251 51 - - + - - - - - - 257 57 - - + - - - - - - 263 63 - - + - - - - - - 269 69 - - + - - - - - - 275 75 - - + - - - - - - 281 81 - - + - - - - - - 287 87 - - + - - - - - - 293 93 - - + - - - - - - - - 300 0 + - - - - - - - - 305 5 + - - - - - - - - 315 15 + - - - - - - - - 325 25 + - - - - - - - - 335 35 + - - - - - - - - 345 45 + - - - - - - - - 355 55 + - - - - - - - - 365 65 + - - - - - - - - 375 75 + - - - - - - - - 385 85 + - - - - - - - - 395 95 +} +do_execsql_test joinD-17 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 LEFT JOIN t2 ON t1.b=t2.b AND t2.x>0 + INNER JOIN t3 ON t1.c=t3.c AND t3.y>0 + INNER JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 15 115 215 315 - - 215 15 315 15 + 30 130 230 330 130 30 230 30 330 30 + 45 145 245 345 - - 245 45 345 45 + 60 160 260 360 160 60 260 60 360 60 + 75 175 275 375 - - 275 75 375 75 + 90 190 290 390 190 90 290 90 390 90 +} +do_execsql_test joinD-18 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 LEFT JOIN t2 ON t1.b=t2.b AND t2.x>0 + INNER JOIN t3 ON t1.c=t3.c AND t3.y>0 + LEFT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 3 103 203 303 - - 203 3 - - + 6 106 206 306 106 6 206 6 - - + 9 109 209 309 - - 209 9 - - + 12 112 212 312 112 12 212 12 - - + 15 115 215 315 - - 215 15 315 15 + 18 118 218 318 118 18 218 18 - - + 21 121 221 321 - - 221 21 - - + 24 124 224 324 124 24 224 24 - - + 27 127 227 327 - - 227 27 - - + 30 130 230 330 130 30 230 30 330 30 + 33 133 233 333 - - 233 33 - - + 36 136 236 336 136 36 236 36 - - + 39 139 239 339 - - 239 39 - - + 42 142 242 342 142 42 242 42 - - + 45 145 245 345 - - 245 45 345 45 + 48 148 248 348 148 48 248 48 - - + 51 151 251 351 - - 251 51 - - + 54 154 254 354 154 54 254 54 - - + 57 157 257 357 - - 257 57 - - + 60 160 260 360 160 60 260 60 360 60 + 63 163 263 363 - - 263 63 - - + 66 166 266 366 166 66 266 66 - - + 69 169 269 369 - - 269 69 - - + 72 172 272 372 172 72 272 72 - - + 75 175 275 375 - - 275 75 375 75 + 78 178 278 378 178 78 278 78 - - + 81 181 281 381 - - 281 81 - - + 84 184 284 384 184 84 284 84 - - + 87 187 287 387 - - 287 87 - - + 90 190 290 390 190 90 290 90 390 90 + 93 193 293 393 - - 293 93 - - +} +do_execsql_test joinD-19 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 LEFT JOIN t2 ON t1.b=t2.b AND t2.x>0 + INNER JOIN t3 ON t1.c=t3.c AND t3.y>0 + RIGHT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 15 115 215 315 - - 215 15 315 15 + 30 130 230 330 130 30 230 30 330 30 + 45 145 245 345 - - 245 45 345 45 + 60 160 260 360 160 60 260 60 360 60 + 75 175 275 375 - - 275 75 375 75 + 90 190 290 390 190 90 290 90 390 90 + - - - - - - - - 300 0 + - - - - - - - - 305 5 + - - - - - - - - 310 10 + - - - - - - - - 320 20 + - - - - - - - - 325 25 + - - - - - - - - 335 35 + - - - - - - - - 340 40 + - - - - - - - - 350 50 + - - - - - - - - 355 55 + - - - - - - - - 365 65 + - - - - - - - - 370 70 + - - - - - - - - 380 80 + - - - - - - - - 385 85 + - - - - - - - - 395 95 +} +do_execsql_test joinD-20 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 LEFT JOIN t2 ON t1.b=t2.b AND t2.x>0 + INNER JOIN t3 ON t1.c=t3.c AND t3.y>0 + FULL JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 3 103 203 303 - - 203 3 - - + 6 106 206 306 106 6 206 6 - - + 9 109 209 309 - - 209 9 - - + 12 112 212 312 112 12 212 12 - - + 15 115 215 315 - - 215 15 315 15 + 18 118 218 318 118 18 218 18 - - + 21 121 221 321 - - 221 21 - - + 24 124 224 324 124 24 224 24 - - + 27 127 227 327 - - 227 27 - - + 30 130 230 330 130 30 230 30 330 30 + 33 133 233 333 - - 233 33 - - + 36 136 236 336 136 36 236 36 - - + 39 139 239 339 - - 239 39 - - + 42 142 242 342 142 42 242 42 - - + 45 145 245 345 - - 245 45 345 45 + 48 148 248 348 148 48 248 48 - - + 51 151 251 351 - - 251 51 - - + 54 154 254 354 154 54 254 54 - - + 57 157 257 357 - - 257 57 - - + 60 160 260 360 160 60 260 60 360 60 + 63 163 263 363 - - 263 63 - - + 66 166 266 366 166 66 266 66 - - + 69 169 269 369 - - 269 69 - - + 72 172 272 372 172 72 272 72 - - + 75 175 275 375 - - 275 75 375 75 + 78 178 278 378 178 78 278 78 - - + 81 181 281 381 - - 281 81 - - + 84 184 284 384 184 84 284 84 - - + 87 187 287 387 - - 287 87 - - + 90 190 290 390 190 90 290 90 390 90 + 93 193 293 393 - - 293 93 - - + - - - - - - - - 300 0 + - - - - - - - - 305 5 + - - - - - - - - 310 10 + - - - - - - - - 320 20 + - - - - - - - - 325 25 + - - - - - - - - 335 35 + - - - - - - - - 340 40 + - - - - - - - - 350 50 + - - - - - - - - 355 55 + - - - - - - - - 365 65 + - - - - - - - - 370 70 + - - - - - - - - 380 80 + - - - - - - - - 385 85 + - - - - - - - - 395 95 +} +do_execsql_test joinD-21 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 LEFT JOIN t2 ON t1.b=t2.b AND t2.x>0 + LEFT JOIN t3 ON t1.c=t3.c AND t3.y>0 + INNER JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 5 105 205 305 - - - - 305 5 + 10 110 210 310 110 10 - - 310 10 + 15 115 215 315 - - 215 15 315 15 + 20 120 220 320 120 20 - - 320 20 + 25 125 225 325 - - - - 325 25 + 30 130 230 330 130 30 230 30 330 30 + 35 135 235 335 - - - - 335 35 + 40 140 240 340 140 40 - - 340 40 + 45 145 245 345 - - 245 45 345 45 + 50 150 250 350 150 50 - - 350 50 + 55 155 255 355 - - - - 355 55 + 60 160 260 360 160 60 260 60 360 60 + 65 165 265 365 - - - - 365 65 + 70 170 270 370 170 70 - - 370 70 + 75 175 275 375 - - 275 75 375 75 + 80 180 280 380 180 80 - - 380 80 + 85 185 285 385 - - - - 385 85 + 90 190 290 390 190 90 290 90 390 90 + 95 195 295 395 - - - - 395 95 +} +do_execsql_test joinD-22 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 LEFT JOIN t2 ON t1.b=t2.b AND t2.x>0 + LEFT JOIN t3 ON t1.c=t3.c AND t3.y>0 + LEFT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 0 100 200 300 - - - - - - + 1 101 201 301 - - - - - - + 2 102 202 302 102 2 - - - - + 3 103 203 303 - - 203 3 - - + 4 104 204 304 104 4 - - - - + 5 105 205 305 - - - - 305 5 + 6 106 206 306 106 6 206 6 - - + 7 107 207 307 - - - - - - + 8 108 208 308 108 8 - - - - + 9 109 209 309 - - 209 9 - - + 10 110 210 310 110 10 - - 310 10 + 11 111 211 311 - - - - - - + 12 112 212 312 112 12 212 12 - - + 13 113 213 313 - - - - - - + 14 114 214 314 114 14 - - - - + 15 115 215 315 - - 215 15 315 15 + 16 116 216 316 116 16 - - - - + 17 117 217 317 - - - - - - + 18 118 218 318 118 18 218 18 - - + 19 119 219 319 - - - - - - + 20 120 220 320 120 20 - - 320 20 + 21 121 221 321 - - 221 21 - - + 22 122 222 322 122 22 - - - - + 23 123 223 323 - - - - - - + 24 124 224 324 124 24 224 24 - - + 25 125 225 325 - - - - 325 25 + 26 126 226 326 126 26 - - - - + 27 127 227 327 - - 227 27 - - + 28 128 228 328 128 28 - - - - + 29 129 229 329 - - - - - - + 30 130 230 330 130 30 230 30 330 30 + 31 131 231 331 - - - - - - + 32 132 232 332 132 32 - - - - + 33 133 233 333 - - 233 33 - - + 34 134 234 334 134 34 - - - - + 35 135 235 335 - - - - 335 35 + 36 136 236 336 136 36 236 36 - - + 37 137 237 337 - - - - - - + 38 138 238 338 138 38 - - - - + 39 139 239 339 - - 239 39 - - + 40 140 240 340 140 40 - - 340 40 + 41 141 241 341 - - - - - - + 42 142 242 342 142 42 242 42 - - + 43 143 243 343 - - - - - - + 44 144 244 344 144 44 - - - - + 45 145 245 345 - - 245 45 345 45 + 46 146 246 346 146 46 - - - - + 47 147 247 347 - - - - - - + 48 148 248 348 148 48 248 48 - - + 49 149 249 349 - - - - - - + 50 150 250 350 150 50 - - 350 50 + 51 151 251 351 - - 251 51 - - + 52 152 252 352 152 52 - - - - + 53 153 253 353 - - - - - - + 54 154 254 354 154 54 254 54 - - + 55 155 255 355 - - - - 355 55 + 56 156 256 356 156 56 - - - - + 57 157 257 357 - - 257 57 - - + 58 158 258 358 158 58 - - - - + 59 159 259 359 - - - - - - + 60 160 260 360 160 60 260 60 360 60 + 61 161 261 361 - - - - - - + 62 162 262 362 162 62 - - - - + 63 163 263 363 - - 263 63 - - + 64 164 264 364 164 64 - - - - + 65 165 265 365 - - - - 365 65 + 66 166 266 366 166 66 266 66 - - + 67 167 267 367 - - - - - - + 68 168 268 368 168 68 - - - - + 69 169 269 369 - - 269 69 - - + 70 170 270 370 170 70 - - 370 70 + 71 171 271 371 - - - - - - + 72 172 272 372 172 72 272 72 - - + 73 173 273 373 - - - - - - + 74 174 274 374 174 74 - - - - + 75 175 275 375 - - 275 75 375 75 + 76 176 276 376 176 76 - - - - + 77 177 277 377 - - - - - - + 78 178 278 378 178 78 278 78 - - + 79 179 279 379 - - - - - - + 80 180 280 380 180 80 - - 380 80 + 81 181 281 381 - - 281 81 - - + 82 182 282 382 182 82 - - - - + 83 183 283 383 - - - - - - + 84 184 284 384 184 84 284 84 - - + 85 185 285 385 - - - - 385 85 + 86 186 286 386 186 86 - - - - + 87 187 287 387 - - 287 87 - - + 88 188 288 388 188 88 - - - - + 89 189 289 389 - - - - - - + 90 190 290 390 190 90 290 90 390 90 + 91 191 291 391 - - - - - - + 92 192 292 392 192 92 - - - - + 93 193 293 393 - - 293 93 - - + 94 194 294 394 194 94 - - - - + 95 195 295 395 - - - - 395 95 + 96 - 296 396 - - - - - - + 97 197 - 397 - - - - - - + 98 198 298 - - - - - - - + 99 - - - - - - - - - +} +do_execsql_test joinD-23 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 LEFT JOIN t2 ON t1.b=t2.b AND t2.x>0 + LEFT JOIN t3 ON t1.c=t3.c AND t3.y>0 + RIGHT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 5 105 205 305 - - - - 305 5 + 10 110 210 310 110 10 - - 310 10 + 15 115 215 315 - - 215 15 315 15 + 20 120 220 320 120 20 - - 320 20 + 25 125 225 325 - - - - 325 25 + 30 130 230 330 130 30 230 30 330 30 + 35 135 235 335 - - - - 335 35 + 40 140 240 340 140 40 - - 340 40 + 45 145 245 345 - - 245 45 345 45 + 50 150 250 350 150 50 - - 350 50 + 55 155 255 355 - - - - 355 55 + 60 160 260 360 160 60 260 60 360 60 + 65 165 265 365 - - - - 365 65 + 70 170 270 370 170 70 - - 370 70 + 75 175 275 375 - - 275 75 375 75 + 80 180 280 380 180 80 - - 380 80 + 85 185 285 385 - - - - 385 85 + 90 190 290 390 190 90 290 90 390 90 + 95 195 295 395 - - - - 395 95 + - - - - - - - - 300 0 +} +do_execsql_test joinD-24 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 LEFT JOIN t2 ON t1.b=t2.b AND t2.x>0 + LEFT JOIN t3 ON t1.c=t3.c AND t3.y>0 + FULL JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 0 100 200 300 - - - - - - + 1 101 201 301 - - - - - - + 2 102 202 302 102 2 - - - - + 3 103 203 303 - - 203 3 - - + 4 104 204 304 104 4 - - - - + 5 105 205 305 - - - - 305 5 + 6 106 206 306 106 6 206 6 - - + 7 107 207 307 - - - - - - + 8 108 208 308 108 8 - - - - + 9 109 209 309 - - 209 9 - - + 10 110 210 310 110 10 - - 310 10 + 11 111 211 311 - - - - - - + 12 112 212 312 112 12 212 12 - - + 13 113 213 313 - - - - - - + 14 114 214 314 114 14 - - - - + 15 115 215 315 - - 215 15 315 15 + 16 116 216 316 116 16 - - - - + 17 117 217 317 - - - - - - + 18 118 218 318 118 18 218 18 - - + 19 119 219 319 - - - - - - + 20 120 220 320 120 20 - - 320 20 + 21 121 221 321 - - 221 21 - - + 22 122 222 322 122 22 - - - - + 23 123 223 323 - - - - - - + 24 124 224 324 124 24 224 24 - - + 25 125 225 325 - - - - 325 25 + 26 126 226 326 126 26 - - - - + 27 127 227 327 - - 227 27 - - + 28 128 228 328 128 28 - - - - + 29 129 229 329 - - - - - - + 30 130 230 330 130 30 230 30 330 30 + 31 131 231 331 - - - - - - + 32 132 232 332 132 32 - - - - + 33 133 233 333 - - 233 33 - - + 34 134 234 334 134 34 - - - - + 35 135 235 335 - - - - 335 35 + 36 136 236 336 136 36 236 36 - - + 37 137 237 337 - - - - - - + 38 138 238 338 138 38 - - - - + 39 139 239 339 - - 239 39 - - + 40 140 240 340 140 40 - - 340 40 + 41 141 241 341 - - - - - - + 42 142 242 342 142 42 242 42 - - + 43 143 243 343 - - - - - - + 44 144 244 344 144 44 - - - - + 45 145 245 345 - - 245 45 345 45 + 46 146 246 346 146 46 - - - - + 47 147 247 347 - - - - - - + 48 148 248 348 148 48 248 48 - - + 49 149 249 349 - - - - - - + 50 150 250 350 150 50 - - 350 50 + 51 151 251 351 - - 251 51 - - + 52 152 252 352 152 52 - - - - + 53 153 253 353 - - - - - - + 54 154 254 354 154 54 254 54 - - + 55 155 255 355 - - - - 355 55 + 56 156 256 356 156 56 - - - - + 57 157 257 357 - - 257 57 - - + 58 158 258 358 158 58 - - - - + 59 159 259 359 - - - - - - + 60 160 260 360 160 60 260 60 360 60 + 61 161 261 361 - - - - - - + 62 162 262 362 162 62 - - - - + 63 163 263 363 - - 263 63 - - + 64 164 264 364 164 64 - - - - + 65 165 265 365 - - - - 365 65 + 66 166 266 366 166 66 266 66 - - + 67 167 267 367 - - - - - - + 68 168 268 368 168 68 - - - - + 69 169 269 369 - - 269 69 - - + 70 170 270 370 170 70 - - 370 70 + 71 171 271 371 - - - - - - + 72 172 272 372 172 72 272 72 - - + 73 173 273 373 - - - - - - + 74 174 274 374 174 74 - - - - + 75 175 275 375 - - 275 75 375 75 + 76 176 276 376 176 76 - - - - + 77 177 277 377 - - - - - - + 78 178 278 378 178 78 278 78 - - + 79 179 279 379 - - - - - - + 80 180 280 380 180 80 - - 380 80 + 81 181 281 381 - - 281 81 - - + 82 182 282 382 182 82 - - - - + 83 183 283 383 - - - - - - + 84 184 284 384 184 84 284 84 - - + 85 185 285 385 - - - - 385 85 + 86 186 286 386 186 86 - - - - + 87 187 287 387 - - 287 87 - - + 88 188 288 388 188 88 - - - - + 89 189 289 389 - - - - - - + 90 190 290 390 190 90 290 90 390 90 + 91 191 291 391 - - - - - - + 92 192 292 392 192 92 - - - - + 93 193 293 393 - - 293 93 - - + 94 194 294 394 194 94 - - - - + 95 195 295 395 - - - - 395 95 + 96 - 296 396 - - - - - - + 97 197 - 397 - - - - - - + 98 198 298 - - - - - - - + 99 - - - - - - - - - + - - - - - - - - 300 0 +} +do_execsql_test joinD-25 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 LEFT JOIN t2 ON t1.b=t2.b AND t2.x>0 + RIGHT JOIN t3 ON t1.c=t3.c AND t3.y>0 + INNER JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 15 115 215 315 - - 215 15 315 15 + 30 130 230 330 130 30 230 30 330 30 + 45 145 245 345 - - 245 45 345 45 + 60 160 260 360 160 60 260 60 360 60 + 75 175 275 375 - - 275 75 375 75 + 90 190 290 390 190 90 290 90 390 90 +} +do_execsql_test joinD-26 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 LEFT JOIN t2 ON t1.b=t2.b AND t2.x>0 + RIGHT JOIN t3 ON t1.c=t3.c AND t3.y>0 + LEFT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 3 103 203 303 - - 203 3 - - + 6 106 206 306 106 6 206 6 - - + 9 109 209 309 - - 209 9 - - + 12 112 212 312 112 12 212 12 - - + 15 115 215 315 - - 215 15 315 15 + 18 118 218 318 118 18 218 18 - - + 21 121 221 321 - - 221 21 - - + 24 124 224 324 124 24 224 24 - - + 27 127 227 327 - - 227 27 - - + 30 130 230 330 130 30 230 30 330 30 + 33 133 233 333 - - 233 33 - - + 36 136 236 336 136 36 236 36 - - + 39 139 239 339 - - 239 39 - - + 42 142 242 342 142 42 242 42 - - + 45 145 245 345 - - 245 45 345 45 + 48 148 248 348 148 48 248 48 - - + 51 151 251 351 - - 251 51 - - + 54 154 254 354 154 54 254 54 - - + 57 157 257 357 - - 257 57 - - + 60 160 260 360 160 60 260 60 360 60 + 63 163 263 363 - - 263 63 - - + 66 166 266 366 166 66 266 66 - - + 69 169 269 369 - - 269 69 - - + 72 172 272 372 172 72 272 72 - - + 75 175 275 375 - - 275 75 375 75 + 78 178 278 378 178 78 278 78 - - + 81 181 281 381 - - 281 81 - - + 84 184 284 384 184 84 284 84 - - + 87 187 287 387 - - 287 87 - - + 90 190 290 390 190 90 290 90 390 90 + 93 193 293 393 - - 293 93 - - + - - - - - - 200 0 - - +} +do_execsql_test joinD-27 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 LEFT JOIN t2 ON t1.b=t2.b AND t2.x>0 + RIGHT JOIN t3 ON t1.c=t3.c AND t3.y>0 + RIGHT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 15 115 215 315 - - 215 15 315 15 + 30 130 230 330 130 30 230 30 330 30 + 45 145 245 345 - - 245 45 345 45 + 60 160 260 360 160 60 260 60 360 60 + 75 175 275 375 - - 275 75 375 75 + 90 190 290 390 190 90 290 90 390 90 + - - - - - - - - 300 0 + - - - - - - - - 305 5 + - - - - - - - - 310 10 + - - - - - - - - 320 20 + - - - - - - - - 325 25 + - - - - - - - - 335 35 + - - - - - - - - 340 40 + - - - - - - - - 350 50 + - - - - - - - - 355 55 + - - - - - - - - 365 65 + - - - - - - - - 370 70 + - - - - - - - - 380 80 + - - - - - - - - 385 85 + - - - - - - - - 395 95 +} +do_execsql_test joinD-28 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 LEFT JOIN t2 ON t1.b=t2.b AND t2.x>0 + RIGHT JOIN t3 ON t1.c=t3.c AND t3.y>0 + FULL JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 3 103 203 303 - - 203 3 - - + 6 106 206 306 106 6 206 6 - - + 9 109 209 309 - - 209 9 - - + 12 112 212 312 112 12 212 12 - - + 15 115 215 315 - - 215 15 315 15 + 18 118 218 318 118 18 218 18 - - + 21 121 221 321 - - 221 21 - - + 24 124 224 324 124 24 224 24 - - + 27 127 227 327 - - 227 27 - - + 30 130 230 330 130 30 230 30 330 30 + 33 133 233 333 - - 233 33 - - + 36 136 236 336 136 36 236 36 - - + 39 139 239 339 - - 239 39 - - + 42 142 242 342 142 42 242 42 - - + 45 145 245 345 - - 245 45 345 45 + 48 148 248 348 148 48 248 48 - - + 51 151 251 351 - - 251 51 - - + 54 154 254 354 154 54 254 54 - - + 57 157 257 357 - - 257 57 - - + 60 160 260 360 160 60 260 60 360 60 + 63 163 263 363 - - 263 63 - - + 66 166 266 366 166 66 266 66 - - + 69 169 269 369 - - 269 69 - - + 72 172 272 372 172 72 272 72 - - + 75 175 275 375 - - 275 75 375 75 + 78 178 278 378 178 78 278 78 - - + 81 181 281 381 - - 281 81 - - + 84 184 284 384 184 84 284 84 - - + 87 187 287 387 - - 287 87 - - + 90 190 290 390 190 90 290 90 390 90 + 93 193 293 393 - - 293 93 - - + - - - - - - 200 0 - - + - - - - - - - - 300 0 + - - - - - - - - 305 5 + - - - - - - - - 310 10 + - - - - - - - - 320 20 + - - - - - - - - 325 25 + - - - - - - - - 335 35 + - - - - - - - - 340 40 + - - - - - - - - 350 50 + - - - - - - - - 355 55 + - - - - - - - - 365 65 + - - - - - - - - 370 70 + - - - - - - - - 380 80 + - - - - - - - - 385 85 + - - - - - - - - 395 95 +} +do_execsql_test joinD-29 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 LEFT JOIN t2 ON t1.b=t2.b AND t2.x>0 + FULL JOIN t3 ON t1.c=t3.c AND t3.y>0 + INNER JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 5 105 205 305 - - - - 305 5 + 10 110 210 310 110 10 - - 310 10 + 15 115 215 315 - - 215 15 315 15 + 20 120 220 320 120 20 - - 320 20 + 25 125 225 325 - - - - 325 25 + 30 130 230 330 130 30 230 30 330 30 + 35 135 235 335 - - - - 335 35 + 40 140 240 340 140 40 - - 340 40 + 45 145 245 345 - - 245 45 345 45 + 50 150 250 350 150 50 - - 350 50 + 55 155 255 355 - - - - 355 55 + 60 160 260 360 160 60 260 60 360 60 + 65 165 265 365 - - - - 365 65 + 70 170 270 370 170 70 - - 370 70 + 75 175 275 375 - - 275 75 375 75 + 80 180 280 380 180 80 - - 380 80 + 85 185 285 385 - - - - 385 85 + 90 190 290 390 190 90 290 90 390 90 + 95 195 295 395 - - - - 395 95 +} +do_execsql_test joinD-30 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 LEFT JOIN t2 ON t1.b=t2.b AND t2.x>0 + FULL JOIN t3 ON t1.c=t3.c AND t3.y>0 + LEFT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 0 100 200 300 - - - - - - + 1 101 201 301 - - - - - - + 2 102 202 302 102 2 - - - - + 3 103 203 303 - - 203 3 - - + 4 104 204 304 104 4 - - - - + 5 105 205 305 - - - - 305 5 + 6 106 206 306 106 6 206 6 - - + 7 107 207 307 - - - - - - + 8 108 208 308 108 8 - - - - + 9 109 209 309 - - 209 9 - - + 10 110 210 310 110 10 - - 310 10 + 11 111 211 311 - - - - - - + 12 112 212 312 112 12 212 12 - - + 13 113 213 313 - - - - - - + 14 114 214 314 114 14 - - - - + 15 115 215 315 - - 215 15 315 15 + 16 116 216 316 116 16 - - - - + 17 117 217 317 - - - - - - + 18 118 218 318 118 18 218 18 - - + 19 119 219 319 - - - - - - + 20 120 220 320 120 20 - - 320 20 + 21 121 221 321 - - 221 21 - - + 22 122 222 322 122 22 - - - - + 23 123 223 323 - - - - - - + 24 124 224 324 124 24 224 24 - - + 25 125 225 325 - - - - 325 25 + 26 126 226 326 126 26 - - - - + 27 127 227 327 - - 227 27 - - + 28 128 228 328 128 28 - - - - + 29 129 229 329 - - - - - - + 30 130 230 330 130 30 230 30 330 30 + 31 131 231 331 - - - - - - + 32 132 232 332 132 32 - - - - + 33 133 233 333 - - 233 33 - - + 34 134 234 334 134 34 - - - - + 35 135 235 335 - - - - 335 35 + 36 136 236 336 136 36 236 36 - - + 37 137 237 337 - - - - - - + 38 138 238 338 138 38 - - - - + 39 139 239 339 - - 239 39 - - + 40 140 240 340 140 40 - - 340 40 + 41 141 241 341 - - - - - - + 42 142 242 342 142 42 242 42 - - + 43 143 243 343 - - - - - - + 44 144 244 344 144 44 - - - - + 45 145 245 345 - - 245 45 345 45 + 46 146 246 346 146 46 - - - - + 47 147 247 347 - - - - - - + 48 148 248 348 148 48 248 48 - - + 49 149 249 349 - - - - - - + 50 150 250 350 150 50 - - 350 50 + 51 151 251 351 - - 251 51 - - + 52 152 252 352 152 52 - - - - + 53 153 253 353 - - - - - - + 54 154 254 354 154 54 254 54 - - + 55 155 255 355 - - - - 355 55 + 56 156 256 356 156 56 - - - - + 57 157 257 357 - - 257 57 - - + 58 158 258 358 158 58 - - - - + 59 159 259 359 - - - - - - + 60 160 260 360 160 60 260 60 360 60 + 61 161 261 361 - - - - - - + 62 162 262 362 162 62 - - - - + 63 163 263 363 - - 263 63 - - + 64 164 264 364 164 64 - - - - + 65 165 265 365 - - - - 365 65 + 66 166 266 366 166 66 266 66 - - + 67 167 267 367 - - - - - - + 68 168 268 368 168 68 - - - - + 69 169 269 369 - - 269 69 - - + 70 170 270 370 170 70 - - 370 70 + 71 171 271 371 - - - - - - + 72 172 272 372 172 72 272 72 - - + 73 173 273 373 - - - - - - + 74 174 274 374 174 74 - - - - + 75 175 275 375 - - 275 75 375 75 + 76 176 276 376 176 76 - - - - + 77 177 277 377 - - - - - - + 78 178 278 378 178 78 278 78 - - + 79 179 279 379 - - - - - - + 80 180 280 380 180 80 - - 380 80 + 81 181 281 381 - - 281 81 - - + 82 182 282 382 182 82 - - - - + 83 183 283 383 - - - - - - + 84 184 284 384 184 84 284 84 - - + 85 185 285 385 - - - - 385 85 + 86 186 286 386 186 86 - - - - + 87 187 287 387 - - 287 87 - - + 88 188 288 388 188 88 - - - - + 89 189 289 389 - - - - - - + 90 190 290 390 190 90 290 90 390 90 + 91 191 291 391 - - - - - - + 92 192 292 392 192 92 - - - - + 93 193 293 393 - - 293 93 - - + 94 194 294 394 194 94 - - - - + 95 195 295 395 - - - - 395 95 + 96 - 296 396 - - - - - - + 97 197 - 397 - - - - - - + 98 198 298 - - - - - - - + 99 - - - - - - - - - + - - - - - - 200 0 - - +} +do_execsql_test joinD-31 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 LEFT JOIN t2 ON t1.b=t2.b AND t2.x>0 + FULL JOIN t3 ON t1.c=t3.c AND t3.y>0 + RIGHT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 5 105 205 305 - - - - 305 5 + 10 110 210 310 110 10 - - 310 10 + 15 115 215 315 - - 215 15 315 15 + 20 120 220 320 120 20 - - 320 20 + 25 125 225 325 - - - - 325 25 + 30 130 230 330 130 30 230 30 330 30 + 35 135 235 335 - - - - 335 35 + 40 140 240 340 140 40 - - 340 40 + 45 145 245 345 - - 245 45 345 45 + 50 150 250 350 150 50 - - 350 50 + 55 155 255 355 - - - - 355 55 + 60 160 260 360 160 60 260 60 360 60 + 65 165 265 365 - - - - 365 65 + 70 170 270 370 170 70 - - 370 70 + 75 175 275 375 - - 275 75 375 75 + 80 180 280 380 180 80 - - 380 80 + 85 185 285 385 - - - - 385 85 + 90 190 290 390 190 90 290 90 390 90 + 95 195 295 395 - - - - 395 95 + - - - - - - - - 300 0 +} +do_execsql_test joinD-32 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 LEFT JOIN t2 ON t1.b=t2.b AND t2.x>0 + FULL JOIN t3 ON t1.c=t3.c AND t3.y>0 + FULL JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 0 100 200 300 - - - - - - + 1 101 201 301 - - - - - - + 2 102 202 302 102 2 - - - - + 3 103 203 303 - - 203 3 - - + 4 104 204 304 104 4 - - - - + 5 105 205 305 - - - - 305 5 + 6 106 206 306 106 6 206 6 - - + 7 107 207 307 - - - - - - + 8 108 208 308 108 8 - - - - + 9 109 209 309 - - 209 9 - - + 10 110 210 310 110 10 - - 310 10 + 11 111 211 311 - - - - - - + 12 112 212 312 112 12 212 12 - - + 13 113 213 313 - - - - - - + 14 114 214 314 114 14 - - - - + 15 115 215 315 - - 215 15 315 15 + 16 116 216 316 116 16 - - - - + 17 117 217 317 - - - - - - + 18 118 218 318 118 18 218 18 - - + 19 119 219 319 - - - - - - + 20 120 220 320 120 20 - - 320 20 + 21 121 221 321 - - 221 21 - - + 22 122 222 322 122 22 - - - - + 23 123 223 323 - - - - - - + 24 124 224 324 124 24 224 24 - - + 25 125 225 325 - - - - 325 25 + 26 126 226 326 126 26 - - - - + 27 127 227 327 - - 227 27 - - + 28 128 228 328 128 28 - - - - + 29 129 229 329 - - - - - - + 30 130 230 330 130 30 230 30 330 30 + 31 131 231 331 - - - - - - + 32 132 232 332 132 32 - - - - + 33 133 233 333 - - 233 33 - - + 34 134 234 334 134 34 - - - - + 35 135 235 335 - - - - 335 35 + 36 136 236 336 136 36 236 36 - - + 37 137 237 337 - - - - - - + 38 138 238 338 138 38 - - - - + 39 139 239 339 - - 239 39 - - + 40 140 240 340 140 40 - - 340 40 + 41 141 241 341 - - - - - - + 42 142 242 342 142 42 242 42 - - + 43 143 243 343 - - - - - - + 44 144 244 344 144 44 - - - - + 45 145 245 345 - - 245 45 345 45 + 46 146 246 346 146 46 - - - - + 47 147 247 347 - - - - - - + 48 148 248 348 148 48 248 48 - - + 49 149 249 349 - - - - - - + 50 150 250 350 150 50 - - 350 50 + 51 151 251 351 - - 251 51 - - + 52 152 252 352 152 52 - - - - + 53 153 253 353 - - - - - - + 54 154 254 354 154 54 254 54 - - + 55 155 255 355 - - - - 355 55 + 56 156 256 356 156 56 - - - - + 57 157 257 357 - - 257 57 - - + 58 158 258 358 158 58 - - - - + 59 159 259 359 - - - - - - + 60 160 260 360 160 60 260 60 360 60 + 61 161 261 361 - - - - - - + 62 162 262 362 162 62 - - - - + 63 163 263 363 - - 263 63 - - + 64 164 264 364 164 64 - - - - + 65 165 265 365 - - - - 365 65 + 66 166 266 366 166 66 266 66 - - + 67 167 267 367 - - - - - - + 68 168 268 368 168 68 - - - - + 69 169 269 369 - - 269 69 - - + 70 170 270 370 170 70 - - 370 70 + 71 171 271 371 - - - - - - + 72 172 272 372 172 72 272 72 - - + 73 173 273 373 - - - - - - + 74 174 274 374 174 74 - - - - + 75 175 275 375 - - 275 75 375 75 + 76 176 276 376 176 76 - - - - + 77 177 277 377 - - - - - - + 78 178 278 378 178 78 278 78 - - + 79 179 279 379 - - - - - - + 80 180 280 380 180 80 - - 380 80 + 81 181 281 381 - - 281 81 - - + 82 182 282 382 182 82 - - - - + 83 183 283 383 - - - - - - + 84 184 284 384 184 84 284 84 - - + 85 185 285 385 - - - - 385 85 + 86 186 286 386 186 86 - - - - + 87 187 287 387 - - 287 87 - - + 88 188 288 388 188 88 - - - - + 89 189 289 389 - - - - - - + 90 190 290 390 190 90 290 90 390 90 + 91 191 291 391 - - - - - - + 92 192 292 392 192 92 - - - - + 93 193 293 393 - - 293 93 - - + 94 194 294 394 194 94 - - - - + 95 195 295 395 - - - - 395 95 + 96 - 296 396 - - - - - - + 97 197 - 397 - - - - - - + 98 198 298 - - - - - - - + 99 - - - - - - - - - + - - - - - - 200 0 - - + - - - - - - - - 300 0 +} +do_execsql_test joinD-33 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 RIGHT JOIN t2 ON t1.b=t2.b AND t2.x>0 + INNER JOIN t3 ON t1.c=t3.c AND t3.y>0 + INNER JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 30 130 230 330 130 30 230 30 330 30 + 60 160 260 360 160 60 260 60 360 60 + 90 190 290 390 190 90 290 90 390 90 +} +do_execsql_test joinD-34 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 RIGHT JOIN t2 ON t1.b=t2.b AND t2.x>0 + INNER JOIN t3 ON t1.c=t3.c AND t3.y>0 + LEFT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 6 106 206 306 106 6 206 6 - - + 12 112 212 312 112 12 212 12 - - + 18 118 218 318 118 18 218 18 - - + 24 124 224 324 124 24 224 24 - - + 30 130 230 330 130 30 230 30 330 30 + 36 136 236 336 136 36 236 36 - - + 42 142 242 342 142 42 242 42 - - + 48 148 248 348 148 48 248 48 - - + 54 154 254 354 154 54 254 54 - - + 60 160 260 360 160 60 260 60 360 60 + 66 166 266 366 166 66 266 66 - - + 72 172 272 372 172 72 272 72 - - + 78 178 278 378 178 78 278 78 - - + 84 184 284 384 184 84 284 84 - - + 90 190 290 390 190 90 290 90 390 90 +} +do_execsql_test joinD-35 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 RIGHT JOIN t2 ON t1.b=t2.b AND t2.x>0 + INNER JOIN t3 ON t1.c=t3.c AND t3.y>0 + RIGHT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 30 130 230 330 130 30 230 30 330 30 + 60 160 260 360 160 60 260 60 360 60 + 90 190 290 390 190 90 290 90 390 90 + - - - - - - - - 300 0 + - - - - - - - - 305 5 + - - - - - - - - 310 10 + - - - - - - - - 315 15 + - - - - - - - - 320 20 + - - - - - - - - 325 25 + - - - - - - - - 335 35 + - - - - - - - - 340 40 + - - - - - - - - 345 45 + - - - - - - - - 350 50 + - - - - - - - - 355 55 + - - - - - - - - 365 65 + - - - - - - - - 370 70 + - - - - - - - - 375 75 + - - - - - - - - 380 80 + - - - - - - - - 385 85 + - - - - - - - - 395 95 +} +do_execsql_test joinD-36 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 RIGHT JOIN t2 ON t1.b=t2.b AND t2.x>0 + INNER JOIN t3 ON t1.c=t3.c AND t3.y>0 + FULL JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 6 106 206 306 106 6 206 6 - - + 12 112 212 312 112 12 212 12 - - + 18 118 218 318 118 18 218 18 - - + 24 124 224 324 124 24 224 24 - - + 30 130 230 330 130 30 230 30 330 30 + 36 136 236 336 136 36 236 36 - - + 42 142 242 342 142 42 242 42 - - + 48 148 248 348 148 48 248 48 - - + 54 154 254 354 154 54 254 54 - - + 60 160 260 360 160 60 260 60 360 60 + 66 166 266 366 166 66 266 66 - - + 72 172 272 372 172 72 272 72 - - + 78 178 278 378 178 78 278 78 - - + 84 184 284 384 184 84 284 84 - - + 90 190 290 390 190 90 290 90 390 90 + - - - - - - - - 300 0 + - - - - - - - - 305 5 + - - - - - - - - 310 10 + - - - - - - - - 315 15 + - - - - - - - - 320 20 + - - - - - - - - 325 25 + - - - - - - - - 335 35 + - - - - - - - - 340 40 + - - - - - - - - 345 45 + - - - - - - - - 350 50 + - - - - - - - - 355 55 + - - - - - - - - 365 65 + - - - - - - - - 370 70 + - - - - - - - - 375 75 + - - - - - - - - 380 80 + - - - - - - - - 385 85 + - - - - - - - - 395 95 +} +do_execsql_test joinD-37 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 RIGHT JOIN t2 ON t1.b=t2.b AND t2.x>0 + LEFT JOIN t3 ON t1.c=t3.c AND t3.y>0 + INNER JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 10 110 210 310 110 10 - - 310 10 + 20 120 220 320 120 20 - - 320 20 + 30 130 230 330 130 30 230 30 330 30 + 40 140 240 340 140 40 - - 340 40 + 50 150 250 350 150 50 - - 350 50 + 60 160 260 360 160 60 260 60 360 60 + 70 170 270 370 170 70 - - 370 70 + 80 180 280 380 180 80 - - 380 80 + 90 190 290 390 190 90 290 90 390 90 +} +do_execsql_test joinD-38 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 RIGHT JOIN t2 ON t1.b=t2.b AND t2.x>0 + LEFT JOIN t3 ON t1.c=t3.c AND t3.y>0 + LEFT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 2 102 202 302 102 2 - - - - + 4 104 204 304 104 4 - - - - + 6 106 206 306 106 6 206 6 - - + 8 108 208 308 108 8 - - - - + 10 110 210 310 110 10 - - 310 10 + 12 112 212 312 112 12 212 12 - - + 14 114 214 314 114 14 - - - - + 16 116 216 316 116 16 - - - - + 18 118 218 318 118 18 218 18 - - + 20 120 220 320 120 20 - - 320 20 + 22 122 222 322 122 22 - - - - + 24 124 224 324 124 24 224 24 - - + 26 126 226 326 126 26 - - - - + 28 128 228 328 128 28 - - - - + 30 130 230 330 130 30 230 30 330 30 + 32 132 232 332 132 32 - - - - + 34 134 234 334 134 34 - - - - + 36 136 236 336 136 36 236 36 - - + 38 138 238 338 138 38 - - - - + 40 140 240 340 140 40 - - 340 40 + 42 142 242 342 142 42 242 42 - - + 44 144 244 344 144 44 - - - - + 46 146 246 346 146 46 - - - - + 48 148 248 348 148 48 248 48 - - + 50 150 250 350 150 50 - - 350 50 + 52 152 252 352 152 52 - - - - + 54 154 254 354 154 54 254 54 - - + 56 156 256 356 156 56 - - - - + 58 158 258 358 158 58 - - - - + 60 160 260 360 160 60 260 60 360 60 + 62 162 262 362 162 62 - - - - + 64 164 264 364 164 64 - - - - + 66 166 266 366 166 66 266 66 - - + 68 168 268 368 168 68 - - - - + 70 170 270 370 170 70 - - 370 70 + 72 172 272 372 172 72 272 72 - - + 74 174 274 374 174 74 - - - - + 76 176 276 376 176 76 - - - - + 78 178 278 378 178 78 278 78 - - + 80 180 280 380 180 80 - - 380 80 + 82 182 282 382 182 82 - - - - + 84 184 284 384 184 84 284 84 - - + 86 186 286 386 186 86 - - - - + 88 188 288 388 188 88 - - - - + 90 190 290 390 190 90 290 90 390 90 + 92 192 292 392 192 92 - - - - + 94 194 294 394 194 94 - - - - + - - - - 100 0 - - - - +} +do_execsql_test joinD-39 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 RIGHT JOIN t2 ON t1.b=t2.b AND t2.x>0 + LEFT JOIN t3 ON t1.c=t3.c AND t3.y>0 + RIGHT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 10 110 210 310 110 10 - - 310 10 + 20 120 220 320 120 20 - - 320 20 + 30 130 230 330 130 30 230 30 330 30 + 40 140 240 340 140 40 - - 340 40 + 50 150 250 350 150 50 - - 350 50 + 60 160 260 360 160 60 260 60 360 60 + 70 170 270 370 170 70 - - 370 70 + 80 180 280 380 180 80 - - 380 80 + 90 190 290 390 190 90 290 90 390 90 + - - - - - - - - 300 0 + - - - - - - - - 305 5 + - - - - - - - - 315 15 + - - - - - - - - 325 25 + - - - - - - - - 335 35 + - - - - - - - - 345 45 + - - - - - - - - 355 55 + - - - - - - - - 365 65 + - - - - - - - - 375 75 + - - - - - - - - 385 85 + - - - - - - - - 395 95 +} +do_execsql_test joinD-40 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 RIGHT JOIN t2 ON t1.b=t2.b AND t2.x>0 + LEFT JOIN t3 ON t1.c=t3.c AND t3.y>0 + FULL JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 2 102 202 302 102 2 - - - - + 4 104 204 304 104 4 - - - - + 6 106 206 306 106 6 206 6 - - + 8 108 208 308 108 8 - - - - + 10 110 210 310 110 10 - - 310 10 + 12 112 212 312 112 12 212 12 - - + 14 114 214 314 114 14 - - - - + 16 116 216 316 116 16 - - - - + 18 118 218 318 118 18 218 18 - - + 20 120 220 320 120 20 - - 320 20 + 22 122 222 322 122 22 - - - - + 24 124 224 324 124 24 224 24 - - + 26 126 226 326 126 26 - - - - + 28 128 228 328 128 28 - - - - + 30 130 230 330 130 30 230 30 330 30 + 32 132 232 332 132 32 - - - - + 34 134 234 334 134 34 - - - - + 36 136 236 336 136 36 236 36 - - + 38 138 238 338 138 38 - - - - + 40 140 240 340 140 40 - - 340 40 + 42 142 242 342 142 42 242 42 - - + 44 144 244 344 144 44 - - - - + 46 146 246 346 146 46 - - - - + 48 148 248 348 148 48 248 48 - - + 50 150 250 350 150 50 - - 350 50 + 52 152 252 352 152 52 - - - - + 54 154 254 354 154 54 254 54 - - + 56 156 256 356 156 56 - - - - + 58 158 258 358 158 58 - - - - + 60 160 260 360 160 60 260 60 360 60 + 62 162 262 362 162 62 - - - - + 64 164 264 364 164 64 - - - - + 66 166 266 366 166 66 266 66 - - + 68 168 268 368 168 68 - - - - + 70 170 270 370 170 70 - - 370 70 + 72 172 272 372 172 72 272 72 - - + 74 174 274 374 174 74 - - - - + 76 176 276 376 176 76 - - - - + 78 178 278 378 178 78 278 78 - - + 80 180 280 380 180 80 - - 380 80 + 82 182 282 382 182 82 - - - - + 84 184 284 384 184 84 284 84 - - + 86 186 286 386 186 86 - - - - + 88 188 288 388 188 88 - - - - + 90 190 290 390 190 90 290 90 390 90 + 92 192 292 392 192 92 - - - - + 94 194 294 394 194 94 - - - - + - - - - 100 0 - - - - + - - - - - - - - 300 0 + - - - - - - - - 305 5 + - - - - - - - - 315 15 + - - - - - - - - 325 25 + - - - - - - - - 335 35 + - - - - - - - - 345 45 + - - - - - - - - 355 55 + - - - - - - - - 365 65 + - - - - - - - - 375 75 + - - - - - - - - 385 85 + - - - - - - - - 395 95 +} +do_execsql_test joinD-41 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 RIGHT JOIN t2 ON t1.b=t2.b AND t2.x>0 + RIGHT JOIN t3 ON t1.c=t3.c AND t3.y>0 + INNER JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 30 130 230 330 130 30 230 30 330 30 + 60 160 260 360 160 60 260 60 360 60 + 90 190 290 390 190 90 290 90 390 90 +} +do_execsql_test joinD-42 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 RIGHT JOIN t2 ON t1.b=t2.b AND t2.x>0 + RIGHT JOIN t3 ON t1.c=t3.c AND t3.y>0 + LEFT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 6 106 206 306 106 6 206 6 - - + 12 112 212 312 112 12 212 12 - - + 18 118 218 318 118 18 218 18 - - + 24 124 224 324 124 24 224 24 - - + 30 130 230 330 130 30 230 30 330 30 + 36 136 236 336 136 36 236 36 - - + 42 142 242 342 142 42 242 42 - - + 48 148 248 348 148 48 248 48 - - + 54 154 254 354 154 54 254 54 - - + 60 160 260 360 160 60 260 60 360 60 + 66 166 266 366 166 66 266 66 - - + 72 172 272 372 172 72 272 72 - - + 78 178 278 378 178 78 278 78 - - + 84 184 284 384 184 84 284 84 - - + 90 190 290 390 190 90 290 90 390 90 + - - - - - - 200 0 - - + - - - - - - 203 3 - - + - - - - - - 209 9 - - + - - - - - - 215 15 - - + - - - - - - 221 21 - - + - - - - - - 227 27 - - + - - - - - - 233 33 - - + - - - - - - 239 39 - - + - - - - - - 245 45 - - + - - - - - - 251 51 - - + - - - - - - 257 57 - - + - - - - - - 263 63 - - + - - - - - - 269 69 - - + - - - - - - 275 75 - - + - - - - - - 281 81 - - + - - - - - - 287 87 - - + - - - - - - 293 93 - - +} +do_execsql_test joinD-43 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 RIGHT JOIN t2 ON t1.b=t2.b AND t2.x>0 + RIGHT JOIN t3 ON t1.c=t3.c AND t3.y>0 + RIGHT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 30 130 230 330 130 30 230 30 330 30 + 60 160 260 360 160 60 260 60 360 60 + 90 190 290 390 190 90 290 90 390 90 + - - - - - - - - 300 0 + - - - - - - - - 305 5 + - - - - - - - - 310 10 + - - - - - - - - 315 15 + - - - - - - - - 320 20 + - - - - - - - - 325 25 + - - - - - - - - 335 35 + - - - - - - - - 340 40 + - - - - - - - - 345 45 + - - - - - - - - 350 50 + - - - - - - - - 355 55 + - - - - - - - - 365 65 + - - - - - - - - 370 70 + - - - - - - - - 375 75 + - - - - - - - - 380 80 + - - - - - - - - 385 85 + - - - - - - - - 395 95 +} +do_execsql_test joinD-44 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 RIGHT JOIN t2 ON t1.b=t2.b AND t2.x>0 + RIGHT JOIN t3 ON t1.c=t3.c AND t3.y>0 + FULL JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 6 106 206 306 106 6 206 6 - - + 12 112 212 312 112 12 212 12 - - + 18 118 218 318 118 18 218 18 - - + 24 124 224 324 124 24 224 24 - - + 30 130 230 330 130 30 230 30 330 30 + 36 136 236 336 136 36 236 36 - - + 42 142 242 342 142 42 242 42 - - + 48 148 248 348 148 48 248 48 - - + 54 154 254 354 154 54 254 54 - - + 60 160 260 360 160 60 260 60 360 60 + 66 166 266 366 166 66 266 66 - - + 72 172 272 372 172 72 272 72 - - + 78 178 278 378 178 78 278 78 - - + 84 184 284 384 184 84 284 84 - - + 90 190 290 390 190 90 290 90 390 90 + - - - - - - 200 0 - - + - - - - - - 203 3 - - + - - - - - - 209 9 - - + - - - - - - 215 15 - - + - - - - - - 221 21 - - + - - - - - - 227 27 - - + - - - - - - 233 33 - - + - - - - - - 239 39 - - + - - - - - - 245 45 - - + - - - - - - 251 51 - - + - - - - - - 257 57 - - + - - - - - - 263 63 - - + - - - - - - 269 69 - - + - - - - - - 275 75 - - + - - - - - - 281 81 - - + - - - - - - 287 87 - - + - - - - - - 293 93 - - + - - - - - - - - 300 0 + - - - - - - - - 305 5 + - - - - - - - - 310 10 + - - - - - - - - 315 15 + - - - - - - - - 320 20 + - - - - - - - - 325 25 + - - - - - - - - 335 35 + - - - - - - - - 340 40 + - - - - - - - - 345 45 + - - - - - - - - 350 50 + - - - - - - - - 355 55 + - - - - - - - - 365 65 + - - - - - - - - 370 70 + - - - - - - - - 375 75 + - - - - - - - - 380 80 + - - - - - - - - 385 85 + - - - - - - - - 395 95 +} +do_execsql_test joinD-45 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 RIGHT JOIN t2 ON t1.b=t2.b AND t2.x>0 + FULL JOIN t3 ON t1.c=t3.c AND t3.y>0 + INNER JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 10 110 210 310 110 10 - - 310 10 + 20 120 220 320 120 20 - - 320 20 + 30 130 230 330 130 30 230 30 330 30 + 40 140 240 340 140 40 - - 340 40 + 50 150 250 350 150 50 - - 350 50 + 60 160 260 360 160 60 260 60 360 60 + 70 170 270 370 170 70 - - 370 70 + 80 180 280 380 180 80 - - 380 80 + 90 190 290 390 190 90 290 90 390 90 +} +do_execsql_test joinD-46 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 RIGHT JOIN t2 ON t1.b=t2.b AND t2.x>0 + FULL JOIN t3 ON t1.c=t3.c AND t3.y>0 + LEFT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 2 102 202 302 102 2 - - - - + 4 104 204 304 104 4 - - - - + 6 106 206 306 106 6 206 6 - - + 8 108 208 308 108 8 - - - - + 10 110 210 310 110 10 - - 310 10 + 12 112 212 312 112 12 212 12 - - + 14 114 214 314 114 14 - - - - + 16 116 216 316 116 16 - - - - + 18 118 218 318 118 18 218 18 - - + 20 120 220 320 120 20 - - 320 20 + 22 122 222 322 122 22 - - - - + 24 124 224 324 124 24 224 24 - - + 26 126 226 326 126 26 - - - - + 28 128 228 328 128 28 - - - - + 30 130 230 330 130 30 230 30 330 30 + 32 132 232 332 132 32 - - - - + 34 134 234 334 134 34 - - - - + 36 136 236 336 136 36 236 36 - - + 38 138 238 338 138 38 - - - - + 40 140 240 340 140 40 - - 340 40 + 42 142 242 342 142 42 242 42 - - + 44 144 244 344 144 44 - - - - + 46 146 246 346 146 46 - - - - + 48 148 248 348 148 48 248 48 - - + 50 150 250 350 150 50 - - 350 50 + 52 152 252 352 152 52 - - - - + 54 154 254 354 154 54 254 54 - - + 56 156 256 356 156 56 - - - - + 58 158 258 358 158 58 - - - - + 60 160 260 360 160 60 260 60 360 60 + 62 162 262 362 162 62 - - - - + 64 164 264 364 164 64 - - - - + 66 166 266 366 166 66 266 66 - - + 68 168 268 368 168 68 - - - - + 70 170 270 370 170 70 - - 370 70 + 72 172 272 372 172 72 272 72 - - + 74 174 274 374 174 74 - - - - + 76 176 276 376 176 76 - - - - + 78 178 278 378 178 78 278 78 - - + 80 180 280 380 180 80 - - 380 80 + 82 182 282 382 182 82 - - - - + 84 184 284 384 184 84 284 84 - - + 86 186 286 386 186 86 - - - - + 88 188 288 388 188 88 - - - - + 90 190 290 390 190 90 290 90 390 90 + 92 192 292 392 192 92 - - - - + 94 194 294 394 194 94 - - - - + - - - - 100 0 - - - - + - - - - - - 200 0 - - + - - - - - - 203 3 - - + - - - - - - 209 9 - - + - - - - - - 215 15 - - + - - - - - - 221 21 - - + - - - - - - 227 27 - - + - - - - - - 233 33 - - + - - - - - - 239 39 - - + - - - - - - 245 45 - - + - - - - - - 251 51 - - + - - - - - - 257 57 - - + - - - - - - 263 63 - - + - - - - - - 269 69 - - + - - - - - - 275 75 - - + - - - - - - 281 81 - - + - - - - - - 287 87 - - + - - - - - - 293 93 - - +} +do_execsql_test joinD-47 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 RIGHT JOIN t2 ON t1.b=t2.b AND t2.x>0 + FULL JOIN t3 ON t1.c=t3.c AND t3.y>0 + RIGHT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 10 110 210 310 110 10 - - 310 10 + 20 120 220 320 120 20 - - 320 20 + 30 130 230 330 130 30 230 30 330 30 + 40 140 240 340 140 40 - - 340 40 + 50 150 250 350 150 50 - - 350 50 + 60 160 260 360 160 60 260 60 360 60 + 70 170 270 370 170 70 - - 370 70 + 80 180 280 380 180 80 - - 380 80 + 90 190 290 390 190 90 290 90 390 90 + - - - - - - - - 300 0 + - - - - - - - - 305 5 + - - - - - - - - 315 15 + - - - - - - - - 325 25 + - - - - - - - - 335 35 + - - - - - - - - 345 45 + - - - - - - - - 355 55 + - - - - - - - - 365 65 + - - - - - - - - 375 75 + - - - - - - - - 385 85 + - - - - - - - - 395 95 +} +do_execsql_test joinD-48 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 RIGHT JOIN t2 ON t1.b=t2.b AND t2.x>0 + FULL JOIN t3 ON t1.c=t3.c AND t3.y>0 + FULL JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 2 102 202 302 102 2 - - - - + 4 104 204 304 104 4 - - - - + 6 106 206 306 106 6 206 6 - - + 8 108 208 308 108 8 - - - - + 10 110 210 310 110 10 - - 310 10 + 12 112 212 312 112 12 212 12 - - + 14 114 214 314 114 14 - - - - + 16 116 216 316 116 16 - - - - + 18 118 218 318 118 18 218 18 - - + 20 120 220 320 120 20 - - 320 20 + 22 122 222 322 122 22 - - - - + 24 124 224 324 124 24 224 24 - - + 26 126 226 326 126 26 - - - - + 28 128 228 328 128 28 - - - - + 30 130 230 330 130 30 230 30 330 30 + 32 132 232 332 132 32 - - - - + 34 134 234 334 134 34 - - - - + 36 136 236 336 136 36 236 36 - - + 38 138 238 338 138 38 - - - - + 40 140 240 340 140 40 - - 340 40 + 42 142 242 342 142 42 242 42 - - + 44 144 244 344 144 44 - - - - + 46 146 246 346 146 46 - - - - + 48 148 248 348 148 48 248 48 - - + 50 150 250 350 150 50 - - 350 50 + 52 152 252 352 152 52 - - - - + 54 154 254 354 154 54 254 54 - - + 56 156 256 356 156 56 - - - - + 58 158 258 358 158 58 - - - - + 60 160 260 360 160 60 260 60 360 60 + 62 162 262 362 162 62 - - - - + 64 164 264 364 164 64 - - - - + 66 166 266 366 166 66 266 66 - - + 68 168 268 368 168 68 - - - - + 70 170 270 370 170 70 - - 370 70 + 72 172 272 372 172 72 272 72 - - + 74 174 274 374 174 74 - - - - + 76 176 276 376 176 76 - - - - + 78 178 278 378 178 78 278 78 - - + 80 180 280 380 180 80 - - 380 80 + 82 182 282 382 182 82 - - - - + 84 184 284 384 184 84 284 84 - - + 86 186 286 386 186 86 - - - - + 88 188 288 388 188 88 - - - - + 90 190 290 390 190 90 290 90 390 90 + 92 192 292 392 192 92 - - - - + 94 194 294 394 194 94 - - - - + - - - - 100 0 - - - - + - - - - - - 200 0 - - + - - - - - - 203 3 - - + - - - - - - 209 9 - - + - - - - - - 215 15 - - + - - - - - - 221 21 - - + - - - - - - 227 27 - - + - - - - - - 233 33 - - + - - - - - - 239 39 - - + - - - - - - 245 45 - - + - - - - - - 251 51 - - + - - - - - - 257 57 - - + - - - - - - 263 63 - - + - - - - - - 269 69 - - + - - - - - - 275 75 - - + - - - - - - 281 81 - - + - - - - - - 287 87 - - + - - - - - - 293 93 - - + - - - - - - - - 300 0 + - - - - - - - - 305 5 + - - - - - - - - 315 15 + - - - - - - - - 325 25 + - - - - - - - - 335 35 + - - - - - - - - 345 45 + - - - - - - - - 355 55 + - - - - - - - - 365 65 + - - - - - - - - 375 75 + - - - - - - - - 385 85 + - - - - - - - - 395 95 +} +do_execsql_test joinD-49 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 FULL JOIN t2 ON t1.b=t2.b AND t2.x>0 + INNER JOIN t3 ON t1.c=t3.c AND t3.y>0 + INNER JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 15 115 215 315 - - 215 15 315 15 + 30 130 230 330 130 30 230 30 330 30 + 45 145 245 345 - - 245 45 345 45 + 60 160 260 360 160 60 260 60 360 60 + 75 175 275 375 - - 275 75 375 75 + 90 190 290 390 190 90 290 90 390 90 +} +do_execsql_test joinD-50 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 FULL JOIN t2 ON t1.b=t2.b AND t2.x>0 + INNER JOIN t3 ON t1.c=t3.c AND t3.y>0 + LEFT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 3 103 203 303 - - 203 3 - - + 6 106 206 306 106 6 206 6 - - + 9 109 209 309 - - 209 9 - - + 12 112 212 312 112 12 212 12 - - + 15 115 215 315 - - 215 15 315 15 + 18 118 218 318 118 18 218 18 - - + 21 121 221 321 - - 221 21 - - + 24 124 224 324 124 24 224 24 - - + 27 127 227 327 - - 227 27 - - + 30 130 230 330 130 30 230 30 330 30 + 33 133 233 333 - - 233 33 - - + 36 136 236 336 136 36 236 36 - - + 39 139 239 339 - - 239 39 - - + 42 142 242 342 142 42 242 42 - - + 45 145 245 345 - - 245 45 345 45 + 48 148 248 348 148 48 248 48 - - + 51 151 251 351 - - 251 51 - - + 54 154 254 354 154 54 254 54 - - + 57 157 257 357 - - 257 57 - - + 60 160 260 360 160 60 260 60 360 60 + 63 163 263 363 - - 263 63 - - + 66 166 266 366 166 66 266 66 - - + 69 169 269 369 - - 269 69 - - + 72 172 272 372 172 72 272 72 - - + 75 175 275 375 - - 275 75 375 75 + 78 178 278 378 178 78 278 78 - - + 81 181 281 381 - - 281 81 - - + 84 184 284 384 184 84 284 84 - - + 87 187 287 387 - - 287 87 - - + 90 190 290 390 190 90 290 90 390 90 + 93 193 293 393 - - 293 93 - - +} +do_execsql_test joinD-51 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 FULL JOIN t2 ON t1.b=t2.b AND t2.x>0 + INNER JOIN t3 ON t1.c=t3.c AND t3.y>0 + RIGHT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 15 115 215 315 - - 215 15 315 15 + 30 130 230 330 130 30 230 30 330 30 + 45 145 245 345 - - 245 45 345 45 + 60 160 260 360 160 60 260 60 360 60 + 75 175 275 375 - - 275 75 375 75 + 90 190 290 390 190 90 290 90 390 90 + - - - - - - - - 300 0 + - - - - - - - - 305 5 + - - - - - - - - 310 10 + - - - - - - - - 320 20 + - - - - - - - - 325 25 + - - - - - - - - 335 35 + - - - - - - - - 340 40 + - - - - - - - - 350 50 + - - - - - - - - 355 55 + - - - - - - - - 365 65 + - - - - - - - - 370 70 + - - - - - - - - 380 80 + - - - - - - - - 385 85 + - - - - - - - - 395 95 +} +do_execsql_test joinD-52 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 FULL JOIN t2 ON t1.b=t2.b AND t2.x>0 + INNER JOIN t3 ON t1.c=t3.c AND t3.y>0 + FULL JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 3 103 203 303 - - 203 3 - - + 6 106 206 306 106 6 206 6 - - + 9 109 209 309 - - 209 9 - - + 12 112 212 312 112 12 212 12 - - + 15 115 215 315 - - 215 15 315 15 + 18 118 218 318 118 18 218 18 - - + 21 121 221 321 - - 221 21 - - + 24 124 224 324 124 24 224 24 - - + 27 127 227 327 - - 227 27 - - + 30 130 230 330 130 30 230 30 330 30 + 33 133 233 333 - - 233 33 - - + 36 136 236 336 136 36 236 36 - - + 39 139 239 339 - - 239 39 - - + 42 142 242 342 142 42 242 42 - - + 45 145 245 345 - - 245 45 345 45 + 48 148 248 348 148 48 248 48 - - + 51 151 251 351 - - 251 51 - - + 54 154 254 354 154 54 254 54 - - + 57 157 257 357 - - 257 57 - - + 60 160 260 360 160 60 260 60 360 60 + 63 163 263 363 - - 263 63 - - + 66 166 266 366 166 66 266 66 - - + 69 169 269 369 - - 269 69 - - + 72 172 272 372 172 72 272 72 - - + 75 175 275 375 - - 275 75 375 75 + 78 178 278 378 178 78 278 78 - - + 81 181 281 381 - - 281 81 - - + 84 184 284 384 184 84 284 84 - - + 87 187 287 387 - - 287 87 - - + 90 190 290 390 190 90 290 90 390 90 + 93 193 293 393 - - 293 93 - - + - - - - - - - - 300 0 + - - - - - - - - 305 5 + - - - - - - - - 310 10 + - - - - - - - - 320 20 + - - - - - - - - 325 25 + - - - - - - - - 335 35 + - - - - - - - - 340 40 + - - - - - - - - 350 50 + - - - - - - - - 355 55 + - - - - - - - - 365 65 + - - - - - - - - 370 70 + - - - - - - - - 380 80 + - - - - - - - - 385 85 + - - - - - - - - 395 95 +} +do_execsql_test joinD-53 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 FULL JOIN t2 ON t1.b=t2.b AND t2.x>0 + LEFT JOIN t3 ON t1.c=t3.c AND t3.y>0 + INNER JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 5 105 205 305 - - - - 305 5 + 10 110 210 310 110 10 - - 310 10 + 15 115 215 315 - - 215 15 315 15 + 20 120 220 320 120 20 - - 320 20 + 25 125 225 325 - - - - 325 25 + 30 130 230 330 130 30 230 30 330 30 + 35 135 235 335 - - - - 335 35 + 40 140 240 340 140 40 - - 340 40 + 45 145 245 345 - - 245 45 345 45 + 50 150 250 350 150 50 - - 350 50 + 55 155 255 355 - - - - 355 55 + 60 160 260 360 160 60 260 60 360 60 + 65 165 265 365 - - - - 365 65 + 70 170 270 370 170 70 - - 370 70 + 75 175 275 375 - - 275 75 375 75 + 80 180 280 380 180 80 - - 380 80 + 85 185 285 385 - - - - 385 85 + 90 190 290 390 190 90 290 90 390 90 + 95 195 295 395 - - - - 395 95 +} +do_execsql_test joinD-54 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 FULL JOIN t2 ON t1.b=t2.b AND t2.x>0 + LEFT JOIN t3 ON t1.c=t3.c AND t3.y>0 + LEFT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 0 100 200 300 - - - - - - + 1 101 201 301 - - - - - - + 2 102 202 302 102 2 - - - - + 3 103 203 303 - - 203 3 - - + 4 104 204 304 104 4 - - - - + 5 105 205 305 - - - - 305 5 + 6 106 206 306 106 6 206 6 - - + 7 107 207 307 - - - - - - + 8 108 208 308 108 8 - - - - + 9 109 209 309 - - 209 9 - - + 10 110 210 310 110 10 - - 310 10 + 11 111 211 311 - - - - - - + 12 112 212 312 112 12 212 12 - - + 13 113 213 313 - - - - - - + 14 114 214 314 114 14 - - - - + 15 115 215 315 - - 215 15 315 15 + 16 116 216 316 116 16 - - - - + 17 117 217 317 - - - - - - + 18 118 218 318 118 18 218 18 - - + 19 119 219 319 - - - - - - + 20 120 220 320 120 20 - - 320 20 + 21 121 221 321 - - 221 21 - - + 22 122 222 322 122 22 - - - - + 23 123 223 323 - - - - - - + 24 124 224 324 124 24 224 24 - - + 25 125 225 325 - - - - 325 25 + 26 126 226 326 126 26 - - - - + 27 127 227 327 - - 227 27 - - + 28 128 228 328 128 28 - - - - + 29 129 229 329 - - - - - - + 30 130 230 330 130 30 230 30 330 30 + 31 131 231 331 - - - - - - + 32 132 232 332 132 32 - - - - + 33 133 233 333 - - 233 33 - - + 34 134 234 334 134 34 - - - - + 35 135 235 335 - - - - 335 35 + 36 136 236 336 136 36 236 36 - - + 37 137 237 337 - - - - - - + 38 138 238 338 138 38 - - - - + 39 139 239 339 - - 239 39 - - + 40 140 240 340 140 40 - - 340 40 + 41 141 241 341 - - - - - - + 42 142 242 342 142 42 242 42 - - + 43 143 243 343 - - - - - - + 44 144 244 344 144 44 - - - - + 45 145 245 345 - - 245 45 345 45 + 46 146 246 346 146 46 - - - - + 47 147 247 347 - - - - - - + 48 148 248 348 148 48 248 48 - - + 49 149 249 349 - - - - - - + 50 150 250 350 150 50 - - 350 50 + 51 151 251 351 - - 251 51 - - + 52 152 252 352 152 52 - - - - + 53 153 253 353 - - - - - - + 54 154 254 354 154 54 254 54 - - + 55 155 255 355 - - - - 355 55 + 56 156 256 356 156 56 - - - - + 57 157 257 357 - - 257 57 - - + 58 158 258 358 158 58 - - - - + 59 159 259 359 - - - - - - + 60 160 260 360 160 60 260 60 360 60 + 61 161 261 361 - - - - - - + 62 162 262 362 162 62 - - - - + 63 163 263 363 - - 263 63 - - + 64 164 264 364 164 64 - - - - + 65 165 265 365 - - - - 365 65 + 66 166 266 366 166 66 266 66 - - + 67 167 267 367 - - - - - - + 68 168 268 368 168 68 - - - - + 69 169 269 369 - - 269 69 - - + 70 170 270 370 170 70 - - 370 70 + 71 171 271 371 - - - - - - + 72 172 272 372 172 72 272 72 - - + 73 173 273 373 - - - - - - + 74 174 274 374 174 74 - - - - + 75 175 275 375 - - 275 75 375 75 + 76 176 276 376 176 76 - - - - + 77 177 277 377 - - - - - - + 78 178 278 378 178 78 278 78 - - + 79 179 279 379 - - - - - - + 80 180 280 380 180 80 - - 380 80 + 81 181 281 381 - - 281 81 - - + 82 182 282 382 182 82 - - - - + 83 183 283 383 - - - - - - + 84 184 284 384 184 84 284 84 - - + 85 185 285 385 - - - - 385 85 + 86 186 286 386 186 86 - - - - + 87 187 287 387 - - 287 87 - - + 88 188 288 388 188 88 - - - - + 89 189 289 389 - - - - - - + 90 190 290 390 190 90 290 90 390 90 + 91 191 291 391 - - - - - - + 92 192 292 392 192 92 - - - - + 93 193 293 393 - - 293 93 - - + 94 194 294 394 194 94 - - - - + 95 195 295 395 - - - - 395 95 + 96 - 296 396 - - - - - - + 97 197 - 397 - - - - - - + 98 198 298 - - - - - - - + 99 - - - - - - - - - + - - - - 100 0 - - - - +} +do_execsql_test joinD-55 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 FULL JOIN t2 ON t1.b=t2.b AND t2.x>0 + LEFT JOIN t3 ON t1.c=t3.c AND t3.y>0 + RIGHT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 5 105 205 305 - - - - 305 5 + 10 110 210 310 110 10 - - 310 10 + 15 115 215 315 - - 215 15 315 15 + 20 120 220 320 120 20 - - 320 20 + 25 125 225 325 - - - - 325 25 + 30 130 230 330 130 30 230 30 330 30 + 35 135 235 335 - - - - 335 35 + 40 140 240 340 140 40 - - 340 40 + 45 145 245 345 - - 245 45 345 45 + 50 150 250 350 150 50 - - 350 50 + 55 155 255 355 - - - - 355 55 + 60 160 260 360 160 60 260 60 360 60 + 65 165 265 365 - - - - 365 65 + 70 170 270 370 170 70 - - 370 70 + 75 175 275 375 - - 275 75 375 75 + 80 180 280 380 180 80 - - 380 80 + 85 185 285 385 - - - - 385 85 + 90 190 290 390 190 90 290 90 390 90 + 95 195 295 395 - - - - 395 95 + - - - - - - - - 300 0 +} +do_execsql_test joinD-56 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 FULL JOIN t2 ON t1.b=t2.b AND t2.x>0 + LEFT JOIN t3 ON t1.c=t3.c AND t3.y>0 + FULL JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 0 100 200 300 - - - - - - + 1 101 201 301 - - - - - - + 2 102 202 302 102 2 - - - - + 3 103 203 303 - - 203 3 - - + 4 104 204 304 104 4 - - - - + 5 105 205 305 - - - - 305 5 + 6 106 206 306 106 6 206 6 - - + 7 107 207 307 - - - - - - + 8 108 208 308 108 8 - - - - + 9 109 209 309 - - 209 9 - - + 10 110 210 310 110 10 - - 310 10 + 11 111 211 311 - - - - - - + 12 112 212 312 112 12 212 12 - - + 13 113 213 313 - - - - - - + 14 114 214 314 114 14 - - - - + 15 115 215 315 - - 215 15 315 15 + 16 116 216 316 116 16 - - - - + 17 117 217 317 - - - - - - + 18 118 218 318 118 18 218 18 - - + 19 119 219 319 - - - - - - + 20 120 220 320 120 20 - - 320 20 + 21 121 221 321 - - 221 21 - - + 22 122 222 322 122 22 - - - - + 23 123 223 323 - - - - - - + 24 124 224 324 124 24 224 24 - - + 25 125 225 325 - - - - 325 25 + 26 126 226 326 126 26 - - - - + 27 127 227 327 - - 227 27 - - + 28 128 228 328 128 28 - - - - + 29 129 229 329 - - - - - - + 30 130 230 330 130 30 230 30 330 30 + 31 131 231 331 - - - - - - + 32 132 232 332 132 32 - - - - + 33 133 233 333 - - 233 33 - - + 34 134 234 334 134 34 - - - - + 35 135 235 335 - - - - 335 35 + 36 136 236 336 136 36 236 36 - - + 37 137 237 337 - - - - - - + 38 138 238 338 138 38 - - - - + 39 139 239 339 - - 239 39 - - + 40 140 240 340 140 40 - - 340 40 + 41 141 241 341 - - - - - - + 42 142 242 342 142 42 242 42 - - + 43 143 243 343 - - - - - - + 44 144 244 344 144 44 - - - - + 45 145 245 345 - - 245 45 345 45 + 46 146 246 346 146 46 - - - - + 47 147 247 347 - - - - - - + 48 148 248 348 148 48 248 48 - - + 49 149 249 349 - - - - - - + 50 150 250 350 150 50 - - 350 50 + 51 151 251 351 - - 251 51 - - + 52 152 252 352 152 52 - - - - + 53 153 253 353 - - - - - - + 54 154 254 354 154 54 254 54 - - + 55 155 255 355 - - - - 355 55 + 56 156 256 356 156 56 - - - - + 57 157 257 357 - - 257 57 - - + 58 158 258 358 158 58 - - - - + 59 159 259 359 - - - - - - + 60 160 260 360 160 60 260 60 360 60 + 61 161 261 361 - - - - - - + 62 162 262 362 162 62 - - - - + 63 163 263 363 - - 263 63 - - + 64 164 264 364 164 64 - - - - + 65 165 265 365 - - - - 365 65 + 66 166 266 366 166 66 266 66 - - + 67 167 267 367 - - - - - - + 68 168 268 368 168 68 - - - - + 69 169 269 369 - - 269 69 - - + 70 170 270 370 170 70 - - 370 70 + 71 171 271 371 - - - - - - + 72 172 272 372 172 72 272 72 - - + 73 173 273 373 - - - - - - + 74 174 274 374 174 74 - - - - + 75 175 275 375 - - 275 75 375 75 + 76 176 276 376 176 76 - - - - + 77 177 277 377 - - - - - - + 78 178 278 378 178 78 278 78 - - + 79 179 279 379 - - - - - - + 80 180 280 380 180 80 - - 380 80 + 81 181 281 381 - - 281 81 - - + 82 182 282 382 182 82 - - - - + 83 183 283 383 - - - - - - + 84 184 284 384 184 84 284 84 - - + 85 185 285 385 - - - - 385 85 + 86 186 286 386 186 86 - - - - + 87 187 287 387 - - 287 87 - - + 88 188 288 388 188 88 - - - - + 89 189 289 389 - - - - - - + 90 190 290 390 190 90 290 90 390 90 + 91 191 291 391 - - - - - - + 92 192 292 392 192 92 - - - - + 93 193 293 393 - - 293 93 - - + 94 194 294 394 194 94 - - - - + 95 195 295 395 - - - - 395 95 + 96 - 296 396 - - - - - - + 97 197 - 397 - - - - - - + 98 198 298 - - - - - - - + 99 - - - - - - - - - + - - - - 100 0 - - - - + - - - - - - - - 300 0 +} +do_execsql_test joinD-57 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 FULL JOIN t2 ON t1.b=t2.b AND t2.x>0 + RIGHT JOIN t3 ON t1.c=t3.c AND t3.y>0 + INNER JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 15 115 215 315 - - 215 15 315 15 + 30 130 230 330 130 30 230 30 330 30 + 45 145 245 345 - - 245 45 345 45 + 60 160 260 360 160 60 260 60 360 60 + 75 175 275 375 - - 275 75 375 75 + 90 190 290 390 190 90 290 90 390 90 +} +do_execsql_test joinD-58 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 FULL JOIN t2 ON t1.b=t2.b AND t2.x>0 + RIGHT JOIN t3 ON t1.c=t3.c AND t3.y>0 + LEFT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 3 103 203 303 - - 203 3 - - + 6 106 206 306 106 6 206 6 - - + 9 109 209 309 - - 209 9 - - + 12 112 212 312 112 12 212 12 - - + 15 115 215 315 - - 215 15 315 15 + 18 118 218 318 118 18 218 18 - - + 21 121 221 321 - - 221 21 - - + 24 124 224 324 124 24 224 24 - - + 27 127 227 327 - - 227 27 - - + 30 130 230 330 130 30 230 30 330 30 + 33 133 233 333 - - 233 33 - - + 36 136 236 336 136 36 236 36 - - + 39 139 239 339 - - 239 39 - - + 42 142 242 342 142 42 242 42 - - + 45 145 245 345 - - 245 45 345 45 + 48 148 248 348 148 48 248 48 - - + 51 151 251 351 - - 251 51 - - + 54 154 254 354 154 54 254 54 - - + 57 157 257 357 - - 257 57 - - + 60 160 260 360 160 60 260 60 360 60 + 63 163 263 363 - - 263 63 - - + 66 166 266 366 166 66 266 66 - - + 69 169 269 369 - - 269 69 - - + 72 172 272 372 172 72 272 72 - - + 75 175 275 375 - - 275 75 375 75 + 78 178 278 378 178 78 278 78 - - + 81 181 281 381 - - 281 81 - - + 84 184 284 384 184 84 284 84 - - + 87 187 287 387 - - 287 87 - - + 90 190 290 390 190 90 290 90 390 90 + 93 193 293 393 - - 293 93 - - + - - - - - - 200 0 - - +} +do_execsql_test joinD-59 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 FULL JOIN t2 ON t1.b=t2.b AND t2.x>0 + RIGHT JOIN t3 ON t1.c=t3.c AND t3.y>0 + RIGHT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 15 115 215 315 - - 215 15 315 15 + 30 130 230 330 130 30 230 30 330 30 + 45 145 245 345 - - 245 45 345 45 + 60 160 260 360 160 60 260 60 360 60 + 75 175 275 375 - - 275 75 375 75 + 90 190 290 390 190 90 290 90 390 90 + - - - - - - - - 300 0 + - - - - - - - - 305 5 + - - - - - - - - 310 10 + - - - - - - - - 320 20 + - - - - - - - - 325 25 + - - - - - - - - 335 35 + - - - - - - - - 340 40 + - - - - - - - - 350 50 + - - - - - - - - 355 55 + - - - - - - - - 365 65 + - - - - - - - - 370 70 + - - - - - - - - 380 80 + - - - - - - - - 385 85 + - - - - - - - - 395 95 +} +do_execsql_test joinD-60 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 FULL JOIN t2 ON t1.b=t2.b AND t2.x>0 + RIGHT JOIN t3 ON t1.c=t3.c AND t3.y>0 + FULL JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 3 103 203 303 - - 203 3 - - + 6 106 206 306 106 6 206 6 - - + 9 109 209 309 - - 209 9 - - + 12 112 212 312 112 12 212 12 - - + 15 115 215 315 - - 215 15 315 15 + 18 118 218 318 118 18 218 18 - - + 21 121 221 321 - - 221 21 - - + 24 124 224 324 124 24 224 24 - - + 27 127 227 327 - - 227 27 - - + 30 130 230 330 130 30 230 30 330 30 + 33 133 233 333 - - 233 33 - - + 36 136 236 336 136 36 236 36 - - + 39 139 239 339 - - 239 39 - - + 42 142 242 342 142 42 242 42 - - + 45 145 245 345 - - 245 45 345 45 + 48 148 248 348 148 48 248 48 - - + 51 151 251 351 - - 251 51 - - + 54 154 254 354 154 54 254 54 - - + 57 157 257 357 - - 257 57 - - + 60 160 260 360 160 60 260 60 360 60 + 63 163 263 363 - - 263 63 - - + 66 166 266 366 166 66 266 66 - - + 69 169 269 369 - - 269 69 - - + 72 172 272 372 172 72 272 72 - - + 75 175 275 375 - - 275 75 375 75 + 78 178 278 378 178 78 278 78 - - + 81 181 281 381 - - 281 81 - - + 84 184 284 384 184 84 284 84 - - + 87 187 287 387 - - 287 87 - - + 90 190 290 390 190 90 290 90 390 90 + 93 193 293 393 - - 293 93 - - + - - - - - - 200 0 - - + - - - - - - - - 300 0 + - - - - - - - - 305 5 + - - - - - - - - 310 10 + - - - - - - - - 320 20 + - - - - - - - - 325 25 + - - - - - - - - 335 35 + - - - - - - - - 340 40 + - - - - - - - - 350 50 + - - - - - - - - 355 55 + - - - - - - - - 365 65 + - - - - - - - - 370 70 + - - - - - - - - 380 80 + - - - - - - - - 385 85 + - - - - - - - - 395 95 +} +do_execsql_test joinD-61 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 FULL JOIN t2 ON t1.b=t2.b AND t2.x>0 + FULL JOIN t3 ON t1.c=t3.c AND t3.y>0 + INNER JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 5 105 205 305 - - - - 305 5 + 10 110 210 310 110 10 - - 310 10 + 15 115 215 315 - - 215 15 315 15 + 20 120 220 320 120 20 - - 320 20 + 25 125 225 325 - - - - 325 25 + 30 130 230 330 130 30 230 30 330 30 + 35 135 235 335 - - - - 335 35 + 40 140 240 340 140 40 - - 340 40 + 45 145 245 345 - - 245 45 345 45 + 50 150 250 350 150 50 - - 350 50 + 55 155 255 355 - - - - 355 55 + 60 160 260 360 160 60 260 60 360 60 + 65 165 265 365 - - - - 365 65 + 70 170 270 370 170 70 - - 370 70 + 75 175 275 375 - - 275 75 375 75 + 80 180 280 380 180 80 - - 380 80 + 85 185 285 385 - - - - 385 85 + 90 190 290 390 190 90 290 90 390 90 + 95 195 295 395 - - - - 395 95 +} +do_execsql_test joinD-62 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 FULL JOIN t2 ON t1.b=t2.b AND t2.x>0 + FULL JOIN t3 ON t1.c=t3.c AND t3.y>0 + LEFT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 0 100 200 300 - - - - - - + 1 101 201 301 - - - - - - + 2 102 202 302 102 2 - - - - + 3 103 203 303 - - 203 3 - - + 4 104 204 304 104 4 - - - - + 5 105 205 305 - - - - 305 5 + 6 106 206 306 106 6 206 6 - - + 7 107 207 307 - - - - - - + 8 108 208 308 108 8 - - - - + 9 109 209 309 - - 209 9 - - + 10 110 210 310 110 10 - - 310 10 + 11 111 211 311 - - - - - - + 12 112 212 312 112 12 212 12 - - + 13 113 213 313 - - - - - - + 14 114 214 314 114 14 - - - - + 15 115 215 315 - - 215 15 315 15 + 16 116 216 316 116 16 - - - - + 17 117 217 317 - - - - - - + 18 118 218 318 118 18 218 18 - - + 19 119 219 319 - - - - - - + 20 120 220 320 120 20 - - 320 20 + 21 121 221 321 - - 221 21 - - + 22 122 222 322 122 22 - - - - + 23 123 223 323 - - - - - - + 24 124 224 324 124 24 224 24 - - + 25 125 225 325 - - - - 325 25 + 26 126 226 326 126 26 - - - - + 27 127 227 327 - - 227 27 - - + 28 128 228 328 128 28 - - - - + 29 129 229 329 - - - - - - + 30 130 230 330 130 30 230 30 330 30 + 31 131 231 331 - - - - - - + 32 132 232 332 132 32 - - - - + 33 133 233 333 - - 233 33 - - + 34 134 234 334 134 34 - - - - + 35 135 235 335 - - - - 335 35 + 36 136 236 336 136 36 236 36 - - + 37 137 237 337 - - - - - - + 38 138 238 338 138 38 - - - - + 39 139 239 339 - - 239 39 - - + 40 140 240 340 140 40 - - 340 40 + 41 141 241 341 - - - - - - + 42 142 242 342 142 42 242 42 - - + 43 143 243 343 - - - - - - + 44 144 244 344 144 44 - - - - + 45 145 245 345 - - 245 45 345 45 + 46 146 246 346 146 46 - - - - + 47 147 247 347 - - - - - - + 48 148 248 348 148 48 248 48 - - + 49 149 249 349 - - - - - - + 50 150 250 350 150 50 - - 350 50 + 51 151 251 351 - - 251 51 - - + 52 152 252 352 152 52 - - - - + 53 153 253 353 - - - - - - + 54 154 254 354 154 54 254 54 - - + 55 155 255 355 - - - - 355 55 + 56 156 256 356 156 56 - - - - + 57 157 257 357 - - 257 57 - - + 58 158 258 358 158 58 - - - - + 59 159 259 359 - - - - - - + 60 160 260 360 160 60 260 60 360 60 + 61 161 261 361 - - - - - - + 62 162 262 362 162 62 - - - - + 63 163 263 363 - - 263 63 - - + 64 164 264 364 164 64 - - - - + 65 165 265 365 - - - - 365 65 + 66 166 266 366 166 66 266 66 - - + 67 167 267 367 - - - - - - + 68 168 268 368 168 68 - - - - + 69 169 269 369 - - 269 69 - - + 70 170 270 370 170 70 - - 370 70 + 71 171 271 371 - - - - - - + 72 172 272 372 172 72 272 72 - - + 73 173 273 373 - - - - - - + 74 174 274 374 174 74 - - - - + 75 175 275 375 - - 275 75 375 75 + 76 176 276 376 176 76 - - - - + 77 177 277 377 - - - - - - + 78 178 278 378 178 78 278 78 - - + 79 179 279 379 - - - - - - + 80 180 280 380 180 80 - - 380 80 + 81 181 281 381 - - 281 81 - - + 82 182 282 382 182 82 - - - - + 83 183 283 383 - - - - - - + 84 184 284 384 184 84 284 84 - - + 85 185 285 385 - - - - 385 85 + 86 186 286 386 186 86 - - - - + 87 187 287 387 - - 287 87 - - + 88 188 288 388 188 88 - - - - + 89 189 289 389 - - - - - - + 90 190 290 390 190 90 290 90 390 90 + 91 191 291 391 - - - - - - + 92 192 292 392 192 92 - - - - + 93 193 293 393 - - 293 93 - - + 94 194 294 394 194 94 - - - - + 95 195 295 395 - - - - 395 95 + 96 - 296 396 - - - - - - + 97 197 - 397 - - - - - - + 98 198 298 - - - - - - - + 99 - - - - - - - - - + - - - - 100 0 - - - - + - - - - - - 200 0 - - +} +do_execsql_test joinD-63 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 FULL JOIN t2 ON t1.b=t2.b AND t2.x>0 + FULL JOIN t3 ON t1.c=t3.c AND t3.y>0 + RIGHT JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 5 105 205 305 - - - - 305 5 + 10 110 210 310 110 10 - - 310 10 + 15 115 215 315 - - 215 15 315 15 + 20 120 220 320 120 20 - - 320 20 + 25 125 225 325 - - - - 325 25 + 30 130 230 330 130 30 230 30 330 30 + 35 135 235 335 - - - - 335 35 + 40 140 240 340 140 40 - - 340 40 + 45 145 245 345 - - 245 45 345 45 + 50 150 250 350 150 50 - - 350 50 + 55 155 255 355 - - - - 355 55 + 60 160 260 360 160 60 260 60 360 60 + 65 165 265 365 - - - - 365 65 + 70 170 270 370 170 70 - - 370 70 + 75 175 275 375 - - 275 75 375 75 + 80 180 280 380 180 80 - - 380 80 + 85 185 285 385 - - - - 385 85 + 90 190 290 390 190 90 290 90 390 90 + 95 195 295 395 - - - - 395 95 + - - - - - - - - 300 0 +} +do_execsql_test joinD-64 { + SELECT t1.*, t2.*, t3.*, t4.* + FROM t1 FULL JOIN t2 ON t1.b=t2.b AND t2.x>0 + FULL JOIN t3 ON t1.c=t3.c AND t3.y>0 + FULL JOIN t4 ON t1.d=t4.d AND t4.z>0 + ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0); +} { + 0 100 200 300 - - - - - - + 1 101 201 301 - - - - - - + 2 102 202 302 102 2 - - - - + 3 103 203 303 - - 203 3 - - + 4 104 204 304 104 4 - - - - + 5 105 205 305 - - - - 305 5 + 6 106 206 306 106 6 206 6 - - + 7 107 207 307 - - - - - - + 8 108 208 308 108 8 - - - - + 9 109 209 309 - - 209 9 - - + 10 110 210 310 110 10 - - 310 10 + 11 111 211 311 - - - - - - + 12 112 212 312 112 12 212 12 - - + 13 113 213 313 - - - - - - + 14 114 214 314 114 14 - - - - + 15 115 215 315 - - 215 15 315 15 + 16 116 216 316 116 16 - - - - + 17 117 217 317 - - - - - - + 18 118 218 318 118 18 218 18 - - + 19 119 219 319 - - - - - - + 20 120 220 320 120 20 - - 320 20 + 21 121 221 321 - - 221 21 - - + 22 122 222 322 122 22 - - - - + 23 123 223 323 - - - - - - + 24 124 224 324 124 24 224 24 - - + 25 125 225 325 - - - - 325 25 + 26 126 226 326 126 26 - - - - + 27 127 227 327 - - 227 27 - - + 28 128 228 328 128 28 - - - - + 29 129 229 329 - - - - - - + 30 130 230 330 130 30 230 30 330 30 + 31 131 231 331 - - - - - - + 32 132 232 332 132 32 - - - - + 33 133 233 333 - - 233 33 - - + 34 134 234 334 134 34 - - - - + 35 135 235 335 - - - - 335 35 + 36 136 236 336 136 36 236 36 - - + 37 137 237 337 - - - - - - + 38 138 238 338 138 38 - - - - + 39 139 239 339 - - 239 39 - - + 40 140 240 340 140 40 - - 340 40 + 41 141 241 341 - - - - - - + 42 142 242 342 142 42 242 42 - - + 43 143 243 343 - - - - - - + 44 144 244 344 144 44 - - - - + 45 145 245 345 - - 245 45 345 45 + 46 146 246 346 146 46 - - - - + 47 147 247 347 - - - - - - + 48 148 248 348 148 48 248 48 - - + 49 149 249 349 - - - - - - + 50 150 250 350 150 50 - - 350 50 + 51 151 251 351 - - 251 51 - - + 52 152 252 352 152 52 - - - - + 53 153 253 353 - - - - - - + 54 154 254 354 154 54 254 54 - - + 55 155 255 355 - - - - 355 55 + 56 156 256 356 156 56 - - - - + 57 157 257 357 - - 257 57 - - + 58 158 258 358 158 58 - - - - + 59 159 259 359 - - - - - - + 60 160 260 360 160 60 260 60 360 60 + 61 161 261 361 - - - - - - + 62 162 262 362 162 62 - - - - + 63 163 263 363 - - 263 63 - - + 64 164 264 364 164 64 - - - - + 65 165 265 365 - - - - 365 65 + 66 166 266 366 166 66 266 66 - - + 67 167 267 367 - - - - - - + 68 168 268 368 168 68 - - - - + 69 169 269 369 - - 269 69 - - + 70 170 270 370 170 70 - - 370 70 + 71 171 271 371 - - - - - - + 72 172 272 372 172 72 272 72 - - + 73 173 273 373 - - - - - - + 74 174 274 374 174 74 - - - - + 75 175 275 375 - - 275 75 375 75 + 76 176 276 376 176 76 - - - - + 77 177 277 377 - - - - - - + 78 178 278 378 178 78 278 78 - - + 79 179 279 379 - - - - - - + 80 180 280 380 180 80 - - 380 80 + 81 181 281 381 - - 281 81 - - + 82 182 282 382 182 82 - - - - + 83 183 283 383 - - - - - - + 84 184 284 384 184 84 284 84 - - + 85 185 285 385 - - - - 385 85 + 86 186 286 386 186 86 - - - - + 87 187 287 387 - - 287 87 - - + 88 188 288 388 188 88 - - - - + 89 189 289 389 - - - - - - + 90 190 290 390 190 90 290 90 390 90 + 91 191 291 391 - - - - - - + 92 192 292 392 192 92 - - - - + 93 193 293 393 - - 293 93 - - + 94 194 294 394 194 94 - - - - + 95 195 295 395 - - - - 395 95 + 96 - 296 396 - - - - - - + 97 197 - 397 - - - - - - + 98 198 298 - - - - - - - + 99 - - - - - - - - - + - - - - 100 0 - - - - + - - - - - - 200 0 - - + - - - - - - - - 300 0 +} +finish_test +############################################################################# +# This is the TCL script used to generate the psql script that generated +# the data above. +# +# puts " +# \\pset border off +# \\pset tuples_only on +# \\pset null - +# +# DROP TABLE IF EXISTS t1; +# DROP TABLE IF EXISTS t2; +# DROP TABLE IF EXISTS t3; +# DROP TABLE IF EXISTS t4; +# CREATE TABLE t1(a INT, b INT, c INT, d INT); +# WITH RECURSIVE c(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM c WHERE x<95) +# INSERT INTO t1(a,b,c,d) SELECT x, x+100, x+200, x+300 FROM c; +# CREATE TABLE t2(b INT, x INT); +# INSERT INTO t2(b,x) SELECT b, a FROM t1 WHERE a%2=0; +# CREATE INDEX t2b ON t2(b); +# CREATE TABLE t3(c INT, y INT); +# INSERT INTO t3(c,y) SELECT c, a FROM t1 WHERE a%3=0; +# CREATE INDEX t3c ON t3(c); +# CREATE TABLE t4(d INT, z INT); +# INSERT INTO t4(d,z) SELECT d, a FROM t1 WHERE a%5=0; +# CREATE INDEX t4d ON t4(d); +# INSERT INTO t1(a,b,c,d) VALUES +# (96,NULL,296,396), +# (97,197,NULL,397), +# (98,198,298,NULL), +# (99,NULL,NULL,NULL); +# " +# +# proc echo {prefix txt} { +# regsub -all {\n} $txt \n$prefix txt +# puts "$prefix$txt" +# } +# +# set n 0 +# set k 0 +# foreach j1 {INNER LEFT RIGHT FULL} { +# foreach j2 {INNER LEFT RIGHT FULL} { +# foreach j3 {INNER LEFT RIGHT FULL} { +# +# incr n +# incr k +# set q1 "" +# append q1 "SELECT t1.*, t2.*, t3.*, t4.*\n" +# append q1 " FROM t1 $j1 JOIN t2 ON t1.b=t2.b AND t2.x>0\n" +# append q1 " $j2 JOIN t3 ON t1.c=t3.c AND t3.y>0\n" +# append q1 " $j3 JOIN t4 ON t1.d=t4.d AND t4.z>0\n" +# append q1 " ORDER BY coalesce(t1.a,t2.b,t3.c,t4.d,0);" +# +# echo "\\qecho " "do_execsql_test joinB-$n \{" +# echo "\\qecho X " $q1 +# echo "\\qecho " "\} \{" +# puts $q1 +# echo "\\qecho " "\}" +# +# } +# } +# } From 11d63ebf2c02f83c777448522deea6cd98487500 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 4 May 2022 14:45:19 +0000 Subject: [PATCH 251/259] Fix ON-clause constraint usage for FULL and RIGHT JOINs. FossilOrigin-Name: 544268a723cafdf0460221f5f018e752836436bad0fac90852cec70e63d9dcde --- manifest | 16 +++++++------- manifest.uuid | 2 +- src/where.c | 2 +- test/join8.test | 57 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 2c27eceb6c..65831b7807 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sCLI\suse\sof\swrong\sallocator\sfor\sfree(). -D 2022-05-04T03:45:32.728 +C Fix\sON-clause\sconstraint\susage\sfor\sFULL\sand\sRIGHT\sJOINs. +D 2022-05-04T14:45:19.529 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -640,7 +640,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c b0f0c4b38d80530ff5e88fb8978e67555cb6392c8cedfd9f80d4d4d8e4106336 +F src/where.c 70eae5fd61a0dd2c613e1fbf84baa5f5cf95f974714538b27b3d45f0a00a16c8 F src/whereInt.h 4db5a877a9d1f38b5c928c1c84297c07f30b9a3bc1f5f66214cf1a8ef90a0556 F src/wherecode.c cd9da760d391a51013f9ab8bc8ca7ad67f3b96e4857efe0d1dd85f538b3494a6 F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 @@ -1148,7 +1148,7 @@ F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 F test/join5.test d22b6cba8fb59ab3f1c82701434c360705eb12d4ce200c449f37b018fc47681a F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c F test/join7.test 8e72de4b45e5e930d18c305c7efe86015fb2552731e4e03ea226353036b0dab0 -F test/join8.test 9a4b2f53d5358abb29e6356e357c0cd40f4d8f282589300dcb76728dce050b51 +F test/join8.test 68f5ec206cd88610c19ab8edb4789a174a55cdb1732619a95db8fd33dbb13783 F test/join9.test 9056ddd3b0c0f4f9d658f4521038d9a37dc23ead8ca9a505d0b0db2b6a471e05 F test/joinA.test 7eab225dc1c1ab258a5e62513a4ed7cabbd3db971d59d5d92f4fb6fa14c12f6a F test/joinB.test 1b2ba3fc8568b49411787fccbf540570c148e9b6a53a30f80691cb6268098ded @@ -1951,8 +1951,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 8cee5388232ade91ea627bb6857eb8937d7530b5ea519e0ae6da362c37c7ed35 -R 3c89c63aaa0653a254417d115718d7c3 -U larrybr -Z 111ff23023abfd8d38c72ec3de24a2fe +P 9fb20a21feb8f6979812f45691e06aa3e297d7370cf0d5820523e817a4e97863 +R d74d2aa039568ce071dd683a6739d947 +U drh +Z 8ab0a178246eeb862fc914300baceadc # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0ae4c52f89..d213c503ba 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9fb20a21feb8f6979812f45691e06aa3e297d7370cf0d5820523e817a4e97863 \ No newline at end of file +544268a723cafdf0460221f5f018e752836436bad0fac90852cec70e63d9dcde \ No newline at end of file diff --git a/src/where.c b/src/where.c index c6fa56cdbd..5902902458 100644 --- a/src/where.c +++ b/src/where.c @@ -2836,7 +2836,7 @@ static int whereLoopAddBtreeIndex( ** RIGHT JOIN. Only constraints in the ** ON clause are allowed. See tag-20191211-002 for the vtab equivalent. */ if( (pSrc->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 - && !ExprHasProperty(pTerm->pExpr, EP_FromJoin) + && !ExprHasProperty(pTerm->pExpr, EP_FromJoin|EP_InnerJoin) ){ continue; } diff --git a/test/join8.test b/test/join8.test index a33622d9bb..3a3b06a1c4 100644 --- a/test/join8.test +++ b/test/join8.test @@ -180,4 +180,61 @@ do_execsql_test join8-6020 { WHERE (a,b) IN (SELECT rowid, b FROM t1); } {17 1 2} +# Bloom filter usage by RIGHT and FULL JOIN +# +reset_db +do_execsql_test join8-7000 { +CREATE TABLE t1(a INT, b INT, c INT, d INT); + WITH RECURSIVE c(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM c WHERE x<10) + INSERT INTO t1(a,b,c,d) SELECT x, x+100, x+200, x+300 FROM c; + CREATE TABLE t2(b INT, x INT); + INSERT INTO t2(b,x) SELECT b, a FROM t1 WHERE a%2=0; + CREATE INDEX t2b ON t2(b); + CREATE TABLE t3(c INT, y INT); + INSERT INTO t3(c,y) SELECT c, a FROM t1 WHERE a%3=0; + CREATE INDEX t3c ON t3(c); + CREATE TABLE t4(d INT, z INT); + INSERT INTO t4(d,z) SELECT d, a FROM t1 WHERE a%5=0; + CREATE INDEX t4d ON t4(d); + INSERT INTO t1(a,b,c,d) VALUES + (96,NULL,296,396), + (97,197,NULL,397), + (98,198,298,NULL), + (99,NULL,NULL,NULL); + ANALYZE sqlite_schema; + INSERT INTO sqlite_stat1 VALUES('t4','t4d','20 1'); + INSERT INTO sqlite_stat1 VALUES('t3','t3c','32 1'); + INSERT INTO sqlite_stat1 VALUES('t2','t2b','48 1'); + INSERT INTO sqlite_stat1 VALUES('t1',NULL,'100'); + ANALYZE sqlite_schema; +} {} +db null - +do_execsql_test join8-7010 { + WITH t0 AS MATERIALIZED ( + SELECT t1.*, t2.*, t3.* + FROM t1 INNER JOIN t2 ON t1.b=t2.b AND t2.x>0 + RIGHT JOIN t3 ON t1.c=t3.c AND t3.y>0 + ) + SELECT * FROM t0 FULL JOIN t4 ON t0.a=t4.d AND t4.z>0 + ORDER BY coalesce(t0.a, t0.y+200, t4.d); +} { + 6 106 206 306 106 6 206 6 - - + - - - - - - 200 0 - - + - - - - - - 203 3 - - + - - - - - - 209 9 - - + - - - - - - - - 300 0 + - - - - - - - - 305 5 + - - - - - - - - 310 10 +} +do_execsql_test join8-7020 { + EXPLAIN QUERY PLAN + WITH t0 AS MATERIALIZED ( + SELECT t1.*, t2.*, t3.* + FROM t1 INNER JOIN t2 ON t1.b=t2.b AND t2.x>0 + RIGHT JOIN t3 ON t1.c=t3.c AND t3.y>0 + ) + SELECT * FROM t0 FULL JOIN t4 ON t0.a=t4.d AND t4.z>0 + ORDER BY coalesce(t0.a, t0.y+200, t4.d); +} {/.*BLOOM FILTER ON t2.*BLOOM FILTER ON t3.*BLOOM FILTER ON t4.*/} + finish_test From 95cb5ccf92cc390c4639e1ad3dd3426869034f38 Mon Sep 17 00:00:00 2001 From: drh <> Date: Wed, 4 May 2022 17:30:51 +0000 Subject: [PATCH 252/259] Code EP_InnerJoin constraints at the same time that EP_FromJoin constraints are coded. FossilOrigin-Name: b57033d2af2196e2f7e5305f3504fc20da5cadeb66026d38b999fe909cab8ac5 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/wherecode.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index d44ee42fff..41ccbb6c12 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sON-clause\sconstraint\susage\sfix\sfrom\strunk\sinto\sthe\sjoinD\sbranch. -D 2022-05-04T14:46:08.113 +C Code\sEP_InnerJoin\sconstraints\sat\sthe\ssame\stime\sthat\sEP_FromJoin\sconstraints\nare\scoded. +D 2022-05-04T17:30:51.826 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -642,7 +642,7 @@ F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b F src/where.c 70eae5fd61a0dd2c613e1fbf84baa5f5cf95f974714538b27b3d45f0a00a16c8 F src/whereInt.h 4db5a877a9d1f38b5c928c1c84297c07f30b9a3bc1f5f66214cf1a8ef90a0556 -F src/wherecode.c cd9da760d391a51013f9ab8bc8ca7ad67f3b96e4857efe0d1dd85f538b3494a6 +F src/wherecode.c 72f8eeed5527450c8e2258160a7bd04534a76c161230d100da0f43a86c6e29ac F src/whereexpr.c 174d4ad5be165c610c907abb779ef4a97974d22b84e1ce7898d2d9f6947249e5 F src/window.c 924e04fd6e0e113d4dba18b78d43fcb8e42b8ebffc8fc728da52cf3ab014cf3c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1952,8 +1952,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 befa8cbc0682bc3269f87e392a1f3d4baacf4db7c716ea84192bb9c13c99490b 544268a723cafdf0460221f5f018e752836436bad0fac90852cec70e63d9dcde -R 3fa9af57dc36108f156d9655a983b60c +P 0a20d4a85964fb5f2060b9522356ad2711f41d0d526ba3d2e58fc51029878298 +R 2b01a3d6c7b6f02d4e522e3ed6c45004 U drh -Z 77216fee7696ce64d1faeda84f2db610 +Z 351fa3d6764053a0a0ad8bba09a5f2d9 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 992ca0ebf8..932b6d24a5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0a20d4a85964fb5f2060b9522356ad2711f41d0d526ba3d2e58fc51029878298 \ No newline at end of file +b57033d2af2196e2f7e5305f3504fc20da5cadeb66026d38b999fe909cab8ac5 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 0a4a0019cf..a942e6e7fb 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -2621,7 +2621,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( pE = pTerm->pExpr; assert( pE!=0 ); if( (pTabItem->fg.jointype & (JT_LEFT|JT_LTORJ)) - && !ExprHasProperty(pE,EP_FromJoin) + && !ExprHasProperty(pE,EP_FromJoin|EP_InnerJoin) ){ continue; } From 744c17c482e074297c468171ab698facb61de8ec Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 5 May 2022 10:02:19 +0000 Subject: [PATCH 253/259] Backout check-in [9fb20a21feb8f697] which was incorrect. FossilOrigin-Name: 99225618a83b577efbd5d13c0d1ff73e9c5a71bb43c259d7c0f22cf3479c992f --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c.in | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 587e2c3ee7..edcbc1ee3c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sfor\sname\sresolution\sfor\sparenthsized\sjoins. -D 2022-05-04T18:43:39.623 +C Backout\scheck-in\s[9fb20a21feb8f697]\swhich\swas\sincorrect. +D 2022-05-05T10:02:19.031 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -554,7 +554,7 @@ F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c e9ee235c4151d2b7fa47435a219bfd30bf516a804d2f004639858087ebf3137b F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 151adca2c9ea6f51215e4351bb8eb4f0012bf98c3d5a5c991d4a019c7cbb143e -F src/shell.c.in d842e26a30fe9acab962a20b1d7dd27e6130f76fbea1be64bf73982a6d64bc71 +F src/shell.c.in ae0a6fae983caac6f8c824733f0599dfdf7b3a7e8efdef3cb5e3ab2e457ffc35 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h f49e28c25bd941e79794db5415fdf7b202deb3bc072ed6f1ed273d578703684e @@ -1953,9 +1953,9 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 67510354e69bab98bd8095f5bedd34aae619fe2c7885975d7a6a00b7df5ece4e 72131ad1bda3d087e59cd4a51d87f10f65a55e658645397e1ede15f9fb1f5143 -R d1fdc8a80f35786f357a6b126ffdd526 -T +closed 72131ad1bda3d087e59cd4a51d87f10f65a55e658645397e1ede15f9fb1f5143 +P 006b2d9c52201c9e836b649018519acfb47f793f70b968722440f00084e9d846 +Q -9fb20a21feb8f6979812f45691e06aa3e297d7370cf0d5820523e817a4e97863 +R b2f806b159cf5b7512b127e1bdd5f6f4 U drh -Z 4bfc6f14ecdde7d2ff2a0271486e7ca0 +Z 6ea7d4e8035c10ed72515b983b2301a9 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c7d874422e..c78998d188 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -006b2d9c52201c9e836b649018519acfb47f793f70b968722440f00084e9d846 \ No newline at end of file +99225618a83b577efbd5d13c0d1ff73e9c5a71bb43c259d7c0f22cf3479c992f \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 0f9cf53446..95a32f5247 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -3540,7 +3540,7 @@ columnar_end: nData = (nRow+1)*nColumn; for(i=0; i Date: Fri, 6 May 2022 00:43:06 +0000 Subject: [PATCH 254/259] Prevent an infinite loop on SQLITE_ERROR_RETRY when trying to modify a corrupt schema while PRAGMA writeable_schema=ON is active. dbsqlfuzz ded83609f475cc989c7339d45efb5151c1495501 FossilOrigin-Name: 217b33234dc3dc36b5b6add50c170869421057a56a7576d1a61767956248d5c9 --- manifest | 13 ++++++------- manifest.uuid | 2 +- src/prepare.c | 10 +++++++++- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index edcbc1ee3c..50e297d83a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Backout\scheck-in\s[9fb20a21feb8f697]\swhich\swas\sincorrect. -D 2022-05-05T10:02:19.031 +C Prevent\san\sinfinite\sloop\son\sSQLITE_ERROR_RETRY\swhen\strying\sto\smodify\sa\ncorrupt\sschema\swhile\sPRAGMA\swriteable_schema=ON\sis\sactive.\ndbsqlfuzz\sded83609f475cc989c7339d45efb5151c1495501 +D 2022-05-06T00:43:06.024 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -548,7 +548,7 @@ F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 54881292a9a5db202b2c0ac541c5e3ef9a5e8c4f1c1383adb2601d5499a60e65 F src/pragma.c d1aead03e8418ff586c7cfca344c50a914b8eb06abd841e8e91a982d823671da F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 -F src/prepare.c fd940149c691684e7c1073c3787a7170e44852b02d1275d2e30a5b58e89cfcaf +F src/prepare.c c62820c15dcb63013519c8e41d9f928d7478672cc902cfd0581c733c271dbf45 F src/printf.c 512574910a45341c8ad244bd3d4939968ebdfde215645b676fff01cc46e90757 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c e9ee235c4151d2b7fa47435a219bfd30bf516a804d2f004639858087ebf3137b @@ -1953,9 +1953,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 006b2d9c52201c9e836b649018519acfb47f793f70b968722440f00084e9d846 -Q -9fb20a21feb8f6979812f45691e06aa3e297d7370cf0d5820523e817a4e97863 -R b2f806b159cf5b7512b127e1bdd5f6f4 +P 99225618a83b577efbd5d13c0d1ff73e9c5a71bb43c259d7c0f22cf3479c992f +R 237342be5a3b7945b5f526c6ba0ad1f5 U drh -Z 6ea7d4e8035c10ed72515b983b2301a9 +Z 4736b1d65ba434838034b9038e83b4a0 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c78998d188..8fbe1d8985 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -99225618a83b577efbd5d13c0d1ff73e9c5a71bb43c259d7c0f22cf3479c992f \ No newline at end of file +217b33234dc3dc36b5b6add50c170869421057a56a7576d1a61767956248d5c9 \ No newline at end of file diff --git a/src/prepare.c b/src/prepare.c index d402da4a3a..f55ff72fcb 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -663,6 +663,14 @@ void sqlite3ParseObjectInit(Parse *pParse, sqlite3 *db){ if( db->mallocFailed ) sqlite3ErrorMsg(pParse, "out of memory"); } +/* +** Maximum number of times that we will try again to prepare a statement +** that returns SQLITE_ERROR_RETRY. +*/ +#ifndef SQLITE_MAX_PREPARE_RETRY +# define SQLITE_MAX_PREPARE_RETRY 25 +#endif + /* ** Compile the UTF-8 encoded SQL statement zSql into a statement handle. */ @@ -837,7 +845,7 @@ static int sqlite3LockAndPrepare( rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail); assert( rc==SQLITE_OK || *ppStmt==0 ); if( rc==SQLITE_OK || db->mallocFailed ) break; - }while( rc==SQLITE_ERROR_RETRY + }while( (rc==SQLITE_ERROR_RETRY && (cnt++) Date: Fri, 6 May 2022 22:29:45 +0000 Subject: [PATCH 255/259] Perserve the requested reserved-bytes size for the database file when doing a VACUUM. FossilOrigin-Name: dac6d87c71606f3ec7ce601be6d17357d323476ecb60dbb167030146783b62b2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vacuum.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 50e297d83a..7cf52986c1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Prevent\san\sinfinite\sloop\son\sSQLITE_ERROR_RETRY\swhen\strying\sto\smodify\sa\ncorrupt\sschema\swhile\sPRAGMA\swriteable_schema=ON\sis\sactive.\ndbsqlfuzz\sded83609f475cc989c7339d45efb5151c1495501 -D 2022-05-06T00:43:06.024 +C Perserve\sthe\srequested\sreserved-bytes\ssize\sfor\sthe\sdatabase\sfile\swhen\ndoing\sa\sVACUUM. +D 2022-05-06T22:29:45.170 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -624,7 +624,7 @@ F src/update.c 2cfaded82ca80ff56afb8c3ae5e88284e0824bfd86119827cc22481959f96f92 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 602fe229f32a96ceccae4f40824129669582096f7c355f53dbac156c9fecef23 -F src/vacuum.c 6c38ddc52f0619865c91dae9c441d4d48bf3040d7dc1bc5b22da1e45547ed0b3 +F src/vacuum.c bb346170b0b54c6683bba4a5983aea40485597fdf605c87ec8bc2e199fe88cd8 F src/vdbe.c a6a20956fa128c0b8d3c5592a9a3db890a46cf626f46ffee0cab2ac5bf8d04b2 F src/vdbe.h 07641758ca8b4f4c6d81ea667ea167c541e6ece21f5574da11e3d21ec37e2662 F src/vdbeInt.h ef43f7fdc5fde29fc3fd29c506c12830f366178fdb4edbbf0cbc3dfbd1278b5f @@ -1953,8 +1953,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 99225618a83b577efbd5d13c0d1ff73e9c5a71bb43c259d7c0f22cf3479c992f -R 237342be5a3b7945b5f526c6ba0ad1f5 +P 217b33234dc3dc36b5b6add50c170869421057a56a7576d1a61767956248d5c9 +R fb5b71dd78e91f00920386e6c95ee22a U drh -Z 4736b1d65ba434838034b9038e83b4a0 +Z 5c19e3fe26f9144dbbad9274556b129a # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8fbe1d8985..80d0655a95 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -217b33234dc3dc36b5b6add50c170869421057a56a7576d1a61767956248d5c9 \ No newline at end of file +dac6d87c71606f3ec7ce601be6d17357d323476ecb60dbb167030146783b62b2 \ No newline at end of file diff --git a/src/vacuum.c b/src/vacuum.c index bcab1de142..9899b63cf1 100644 --- a/src/vacuum.c +++ b/src/vacuum.c @@ -368,6 +368,7 @@ SQLITE_NOINLINE int sqlite3RunVacuum( assert( rc==SQLITE_OK ); if( pOut==0 ){ + nRes = sqlite3BtreeGetRequestedReserve(pTemp); rc = sqlite3BtreeSetPageSize(pMain, sqlite3BtreeGetPageSize(pTemp), nRes,1); } From 77874e782bbee07b2845842f87ac0bed3cc1c86c Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 9 May 2022 12:59:16 +0000 Subject: [PATCH 256/259] Simplify a branch in the "*" expansion logic. New test case for an INSTEAD OF trigger on a RIGHT and FULL outer join. FossilOrigin-Name: d2717348f43b571c7bb58498e0c723331abf85de174189e66aca2c438ca26d5f --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 2 +- test/joinD.test | 41 +++++++++++++++++++++++++++++++++++++++-- 4 files changed, 48 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 7cf52986c1..d7e3c3c844 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Perserve\sthe\srequested\sreserved-bytes\ssize\sfor\sthe\sdatabase\sfile\swhen\ndoing\sa\sVACUUM. -D 2022-05-06T22:29:45.170 +C Simplify\sa\sbranch\sin\sthe\s"*"\sexpansion\slogic.\s\sNew\stest\scase\sfor\san\nINSTEAD\sOF\strigger\son\sa\sRIGHT\sand\sFULL\souter\sjoin. +D 2022-05-09T12:59:16.562 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -553,7 +553,7 @@ F src/printf.c 512574910a45341c8ad244bd3d4939968ebdfde215645b676fff01cc46e90757 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c e9ee235c4151d2b7fa47435a219bfd30bf516a804d2f004639858087ebf3137b F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 151adca2c9ea6f51215e4351bb8eb4f0012bf98c3d5a5c991d4a019c7cbb143e +F src/select.c 625865ad9f8efec6bd3176461c5eeb36c8003f7a5366438d86e3f89f45df1f01 F src/shell.c.in ae0a6fae983caac6f8c824733f0599dfdf7b3a7e8efdef3cb5e3ab2e457ffc35 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1153,7 +1153,7 @@ F test/join9.test 9056ddd3b0c0f4f9d658f4521038d9a37dc23ead8ca9a505d0b0db2b6a471e F test/joinA.test 7eab225dc1c1ab258a5e62513a4ed7cabbd3db971d59d5d92f4fb6fa14c12f6a F test/joinB.test 1b2ba3fc8568b49411787fccbf540570c148e9b6a53a30f80691cb6268098ded F test/joinC.test 1f1a602c2127f55f136e2cbd3bf2d26546614bf8cffe5902ec1ac9c07f87f207 -F test/joinD.test 58fb0aae651798a2264128f3f6f6ee3c9b5d5548071a1044365511b10de4edd3 +F test/joinD.test 7f0f4dd1f2767330bf1fda5c9cc8a437015a54bcd2355036b4d04ddfc1519d76 F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e @@ -1953,8 +1953,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 217b33234dc3dc36b5b6add50c170869421057a56a7576d1a61767956248d5c9 -R fb5b71dd78e91f00920386e6c95ee22a +P dac6d87c71606f3ec7ce601be6d17357d323476ecb60dbb167030146783b62b2 +R d81ef2c896b333ba6ad03fd21ef90d06 U drh -Z 5c19e3fe26f9144dbbad9274556b129a +Z 1c1d5a324638d0fbf012275c6ac59a4c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 80d0655a95..a2209b5b33 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dac6d87c71606f3ec7ce601be6d17357d323476ecb60dbb167030146783b62b2 \ No newline at end of file +d2717348f43b571c7bb58498e0c723331abf85de174189e66aca2c438ca26d5f \ No newline at end of file diff --git a/src/select.c b/src/select.c index 4ae8f16d1e..232554a914 100644 --- a/src/select.c +++ b/src/select.c @@ -5884,7 +5884,7 @@ static int selectExpander(Walker *pWalker, Select *p){ */ if( pTab->aCol[j].colFlags & (COLFLAG_HIDDEN|COLFLAG_NOEXPAND) ){ if( IsHiddenColumn(&pTab->aCol[j]) - && (selFlags & (SF_IncludeHidden|SF_NestedFrom))==0 + && (selFlags & SF_IncludeHidden)==0 ){ continue; } diff --git a/test/joinD.test b/test/joinD.test index 9ac813ffab..aba1d62800 100644 --- a/test/joinD.test +++ b/test/joinD.test @@ -11,8 +11,8 @@ # # This file implements tests for JOINs that use Bloom filters. # -# The test case output is all generated by PostgreSQL 14. This test module -# was created as follows: +# The test case output is (mostly) all generated by PostgreSQL 14. This +# test module was created as follows: # # 1. Run a TCL script (included at the bottom of this file) that # generates an input script for "psql" that will run man @@ -26,6 +26,9 @@ # # 4. Add this header, and the script content at the footer. # +# A few extra tests that were not generated from postgresql output are +# added at the end. +# set testdir [file dirname $argv0] source $testdir/tester.tcl db nullvalue - @@ -2897,7 +2900,41 @@ do_execsql_test joinD-64 { - - - - - - 200 0 - - - - - - - - - - 300 0 } + +############################################################################# +# The following are extra tests added manually + +do_execsql_test joinD-1000 { + CREATE VIEW v1 AS + SELECT * + FROM t1 INNER JOIN t2 ON t1.b=t2.b AND t2.x>0 + RIGHT JOIN t3 ON t1.c=t3.c AND t3.y>0 + LEFT JOIN t4 ON t1.d=t4.d AND t4.z>0; + CREATE TRIGGER v1r1 INSTEAD OF UPDATE OF c ON v1 BEGIN + UPDATE t1 SET c=new.c WHERE (a,b,c,d) IS (old.a,old.b,old.c,old.d); + UPDATE t3 SET c=new.c WHERE (c,y) IS (old.c,old.y); + END; + SELECT * FROM v1 WHERE y BETWEEN 30 AND 40 ORDER BY y; +} { + 30 130 230 330 130 30 230 30 330 30 + - - - - - - 233 33 - - + 36 136 236 336 136 36 236 36 - - + - - - - - - 239 39 - - +} +do_execsql_test joinD-1010 { + BEGIN; + UPDATE v1 SET c=c+1000 WHERE y BETWEEN 30 and 40; + SELECT * FROM v1 WHERE y BETWEEN 30 AND 40 ORDER BY y; + ROLLBACK; +} { + 30 130 1230 330 130 30 1230 30 330 30 + - - - - - - 233 33 - - + 36 136 1236 336 136 36 1236 36 - - + - - - - - - 239 39 - - +} + finish_test + ############################################################################# # This is the TCL script used to generate the psql script that generated # the data above. From 4077b006adaa157b5c1bb3a6ec751aeca7191baf Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 9 May 2022 16:29:53 +0000 Subject: [PATCH 257/259] Add ALWAYS() on two unreachable branches in the * expander. FossilOrigin-Name: 387c852375bba62df040330944c9e979a6993f95ece3443597c5fc66e34263ca --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index d7e3c3c844..9453487b65 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplify\sa\sbranch\sin\sthe\s"*"\sexpansion\slogic.\s\sNew\stest\scase\sfor\san\nINSTEAD\sOF\strigger\son\sa\sRIGHT\sand\sFULL\souter\sjoin. -D 2022-05-09T12:59:16.562 +C Add\sALWAYS()\son\stwo\sunreachable\sbranches\sin\sthe\s*\sexpander. +D 2022-05-09T16:29:53.023 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -553,7 +553,7 @@ F src/printf.c 512574910a45341c8ad244bd3d4939968ebdfde215645b676fff01cc46e90757 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c e9ee235c4151d2b7fa47435a219bfd30bf516a804d2f004639858087ebf3137b F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 625865ad9f8efec6bd3176461c5eeb36c8003f7a5366438d86e3f89f45df1f01 +F src/select.c 6c0fba59d2a74bf606065f23e3bb6a8f29106c84f90ec34290ac4245e83b918c F src/shell.c.in ae0a6fae983caac6f8c824733f0599dfdf7b3a7e8efdef3cb5e3ab2e457ffc35 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1953,8 +1953,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 dac6d87c71606f3ec7ce601be6d17357d323476ecb60dbb167030146783b62b2 -R d81ef2c896b333ba6ad03fd21ef90d06 +P d2717348f43b571c7bb58498e0c723331abf85de174189e66aca2c438ca26d5f +R bfa78738985cc250c9ab2a579702f4b0 U drh -Z 1c1d5a324638d0fbf012275c6ac59a4c +Z 4ad8291fd7545a4052c6d83a014b41b4 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index a2209b5b33..5a40556588 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d2717348f43b571c7bb58498e0c723331abf85de174189e66aca2c438ca26d5f \ No newline at end of file +387c852375bba62df040330944c9e979a6993f95ece3443597c5fc66e34263ca \ No newline at end of file diff --git a/src/select.c b/src/select.c index 232554a914..7390d24f2b 100644 --- a/src/select.c +++ b/src/select.c @@ -5884,11 +5884,11 @@ static int selectExpander(Walker *pWalker, Select *p){ */ if( pTab->aCol[j].colFlags & (COLFLAG_HIDDEN|COLFLAG_NOEXPAND) ){ if( IsHiddenColumn(&pTab->aCol[j]) - && (selFlags & SF_IncludeHidden)==0 + && ALWAYS((selFlags & SF_IncludeHidden)==0) ){ continue; } - if( (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)!=0 + if( ALWAYS((pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)!=0) && zTName==0 && (selFlags & (SF_NestedFrom))==0 ){ From f71b8123df5c0d1913e2b5e148c2a26d319f8fde Mon Sep 17 00:00:00 2001 From: drh <> Date: Mon, 9 May 2022 17:55:34 +0000 Subject: [PATCH 258/259] Minor STAT4 test case change due to the ANALYZE enhancement of [eb59c46a5aed69bc|check-in eb59c46a5aed69bc]. FossilOrigin-Name: 8ce2fecb580da53fc01c53d8de10e2cc99499094215429ba925e777717e369b2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/analyze9.test | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 9453487b65..9377830496 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sALWAYS()\son\stwo\sunreachable\sbranches\sin\sthe\s*\sexpander. -D 2022-05-09T16:29:53.023 +C Minor\sSTAT4\stest\scase\schange\sdue\sto\sthe\sANALYZE\senhancement\sof\n[eb59c46a5aed69bc|check-in\seb59c46a5aed69bc]. +D 2022-05-09T17:55:34.846 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -679,7 +679,7 @@ F test/analyze5.test fa5131952303ac4146aba101b116b9c8cb89e2637531c334a6df7f7d19d F test/analyze6.test 028f5bdfc9e5b5294768fa9a7185b8cd1d019aa7aab5b2f8ee42d7271d9a3b28 F test/analyze7.test 079d17c495e396bdbd6cc6a083112788a6fbfb3b95c42e760e4270a53c9ead8f F test/analyze8.test 29ef237d8a59b39cc31c3310134fefe96a690b195e3deed5ecb652839089f15c -F test/analyze9.test 162cd40d713310fbe7a63a5ecff5d3a013777d86809618838177d9b2af4dd09c +F test/analyze9.test 30e1cb99336045a384a11d97900720184333c88174b3b89bc07444ea39e7df19 F test/analyzeC.test 1111830ad355d29a294a5dda654dd5f6a8622c6a223a4f7b7b3d091df7a7a42b F test/analyzeD.test 485f621cfd2ef0a8f8ac79672586651bfa495bd899db50461bb4b558400ab3c1 F test/analyzeE.test 69d130f9ba78c9853dcd5a18317e81f462a72d704cec0c4c30afb220213acd29 @@ -1953,8 +1953,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 d2717348f43b571c7bb58498e0c723331abf85de174189e66aca2c438ca26d5f -R bfa78738985cc250c9ab2a579702f4b0 +P 387c852375bba62df040330944c9e979a6993f95ece3443597c5fc66e34263ca +R cbb8544fd969bd1dbd19e4e7428f857d U drh -Z 4ad8291fd7545a4052c6d83a014b41b4 +Z 4859f8d06796c35fb9e8207cbbd745d2 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 5a40556588..24609f9f4b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -387c852375bba62df040330944c9e979a6993f95ece3443597c5fc66e34263ca \ No newline at end of file +8ce2fecb580da53fc01c53d8de10e2cc99499094215429ba925e777717e369b2 \ No newline at end of file diff --git a/test/analyze9.test b/test/analyze9.test index a7f9b5deae..b2121fd07b 100644 --- a/test/analyze9.test +++ b/test/analyze9.test @@ -399,7 +399,7 @@ do_test 9.2 { for {set i 0} {$i < 100} {incr i} { execsql "INSERT INTO t1 VALUES('x', 'y', 'z', $i, [expr $i/2])" } - for {set i 0} {$i < 20} {incr i} { + for {set i 0} {$i < 21} {incr i} { execsql "INSERT INTO t1 VALUES('x', 'y', 'z', 101, $i)" } for {set i 102} {$i < 200} {incr i} { From adef15986a6054a96bb503102327a57b25d64c7d Mon Sep 17 00:00:00 2001 From: drh <> Date: Tue, 10 May 2022 00:24:01 +0000 Subject: [PATCH 259/259] Simplified "hidden" and "no-expand" handling in the *-expander. FossilOrigin-Name: c6c3115f3a008cf9b0d7c5c812f17e38c8a75a904032c5f05f0bea03a7340527 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 22 ++++++++++------------ 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/manifest b/manifest index 9377830496..e7fde4d1c6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\sSTAT4\stest\scase\schange\sdue\sto\sthe\sANALYZE\senhancement\sof\n[eb59c46a5aed69bc|check-in\seb59c46a5aed69bc]. -D 2022-05-09T17:55:34.846 +C Simplified\s"hidden"\sand\s"no-expand"\shandling\sin\sthe\s*-expander. +D 2022-05-10T00:24:01.438 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -553,7 +553,7 @@ F src/printf.c 512574910a45341c8ad244bd3d4939968ebdfde215645b676fff01cc46e90757 F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c e9ee235c4151d2b7fa47435a219bfd30bf516a804d2f004639858087ebf3137b F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 6c0fba59d2a74bf606065f23e3bb6a8f29106c84f90ec34290ac4245e83b918c +F src/select.c cd17de0cab436f0efc4cfeeeef1b8e03c41c40335ec757eff68e341e6a3f763f F src/shell.c.in ae0a6fae983caac6f8c824733f0599dfdf7b3a7e8efdef3cb5e3ab2e457ffc35 F src/sqlite.h.in 2a35f62185eb5e7ecc64a2f68442b538ce9be74f80f28a00abc24837edcf1c17 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1953,8 +1953,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 387c852375bba62df040330944c9e979a6993f95ece3443597c5fc66e34263ca -R cbb8544fd969bd1dbd19e4e7428f857d +P 8ce2fecb580da53fc01c53d8de10e2cc99499094215429ba925e777717e369b2 +R 1d734b9b8260c8ccdbe3f05b6dc084ca U drh -Z 4859f8d06796c35fb9e8207cbbd745d2 +Z 5869ac2082a6ad38c03068b658209d1b # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 24609f9f4b..cc85684e99 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8ce2fecb580da53fc01c53d8de10e2cc99499094215429ba925e777717e369b2 \ No newline at end of file +c6c3115f3a008cf9b0d7c5c812f17e38c8a75a904032c5f05f0bea03a7340527 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 7390d24f2b..b53c0c9151 100644 --- a/src/select.c +++ b/src/select.c @@ -5882,18 +5882,16 @@ static int selectExpander(Walker *pWalker, Select *p){ ** result-set list unless the SELECT has the SF_IncludeHidden ** bit set. */ - if( pTab->aCol[j].colFlags & (COLFLAG_HIDDEN|COLFLAG_NOEXPAND) ){ - if( IsHiddenColumn(&pTab->aCol[j]) - && ALWAYS((selFlags & SF_IncludeHidden)==0) - ){ - continue; - } - if( ALWAYS((pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)!=0) - && zTName==0 - && (selFlags & (SF_NestedFrom))==0 - ){ - continue; - } + if( (p->selFlags & SF_IncludeHidden)==0 + && IsHiddenColumn(&pTab->aCol[j]) + ){ + continue; + } + if( (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)!=0 + && zTName==0 + && (selFlags & (SF_NestedFrom))==0 + ){ + continue; } tableSeen = 1;