From cd1499f47b1de7c6ca9eb9e68e169218a203c5df Mon Sep 17 00:00:00 2001 From: drh <> Date: Thu, 20 May 2021 00:44:04 +0000 Subject: [PATCH] Replace [0f0959c6f95046e8] with a new and better solution that also fixes the CTE name resolution problem described in [forum:/forumpost/8590e3f6dc|forum post 8590e3f6dc]. Test cases for both problems added. FossilOrigin-Name: 5614279daff5007d6e047c5c1b3cc82ba80a5c91c529525b0fe68b79ee82dd2c --- manifest | 25 ++++++++++++------------- manifest.uuid | 2 +- src/attach.c | 17 ++++++++++------- src/build.c | 2 +- src/select.c | 8 ++++++++ src/sqliteInt.h | 1 + src/update.c | 5 +---- test/upfrom1.test | 16 ++++++++++++++++ test/with1.test | 24 ++++++++++++++++++++++++ 9 files changed, 74 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index a362d211aa..999e001c67 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fixes\sand\simprovements\sto\sPRAGMA\scompile_options. -D 2021-05-20T00:10:24.906 +C Replace\s[0f0959c6f95046e8]\swith\sa\snew\sand\sbetter\ssolution\sthat\salso\sfixes\sthe\nCTE\sname\sresolution\sproblem\sdescribed\sin\n[forum:/forumpost/8590e3f6dc|forum\spost\s8590e3f6dc].\nTest\scases\sfor\sboth\sproblems\sadded. +D 2021-05-20T00:44:04.904 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -479,7 +479,7 @@ F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c df53c39fd4f32528fc7ad8188b3bf2b506e1a8b3bb975b14f16a1bc6e901950f F src/analyze.c 01c6c6765cb4d40b473b71d85535093730770bb186f2f473abac25f07fcdee5c -F src/attach.c 42774f1f26f6970aef07a206f0afa5d73fea5d2bb84d5a8f687a7f56f00f2a3a +F src/attach.c a514e81758ba7b3a3a0501faf70af6cfc509de8810235db726cfc9f25165e929 F src/auth.c 08954fdc4cc2da5264ba5b75cfd90b67a6fc7d1710a02ccf917c38eadec77853 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 @@ -487,7 +487,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 51ba86095316fceb3e25bc61617d673d84627e79f4ace83f8722910f33eedef3 F src/btree.h 096cc53baa58be22b02c896d1cf933c38cfc6d65f9253c1367ece8cc88a24de5 F src/btreeInt.h 7bc15a24a02662409ebcd6aeaa1065522d14b7fda71573a2b0568b458f514ae0 -F src/build.c 65b87a05331914cf90bde90ae3d4797c0a18642bd13bb4ea1553a6238fd771ec +F src/build.c 4e13b92f77d3f6dc1285c3636a2ba7c6af5cbb793e52075a762fbcebcd36e968 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 3052b6b05ed9ef547a3dd66b8e01bfa9d582e78752ad6ed327da84652641e038 @@ -543,12 +543,12 @@ F src/printf.c 78fabb49b9ac9a12dd1c89d744abdc9b67fd3205e62967e158f78b965a29ec4b F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 40e216d9a72e52841a9c8e0aec7d367bade8e2df17b804653b539b20c1ab5660 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 09acd5a12c4229238919e38816d0d5c90b24015ef495afb825dc1b3f2a8cf18a +F src/select.c 3ca67cb4f1ccfb12366d8036fab2db4cda11e554906a32cb31d929bc8ab16f3f F src/shell.c.in 1b32ba2918ede13b68df47c7b92b72ba0d06e68d384e78bb9d7456527271d400 F src/sqlite.h.in 5c950066775ca9efdaa49077c05d38d0bef6418f3bd07d2dce0210f1d2f3c326 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 61b38c073d5e1e96a3d45271b257aef27d0d13da2bea5347692ae579475cd95e -F src/sqliteInt.h 16d132f4380f9f4ebf9db6b803ddde641aa2c917964b028404d09459cf83533f +F src/sqliteInt.h f859750f2e9ce43cdf38dba4da32734465c36f3ace4d7973c95dc4469242d250 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -610,7 +610,7 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c bae853ad129d1129c063de8630a3e99e306283bc40146f359b1bb91be2c08f1e F src/treeview.c e483aeedf6f207000db1f90eb6abd816350493314c30e8749d319bdb9ab3b08c F src/trigger.c e0fd347b2571a2d956318cdc6d011ccca7ce862d10a0ca04188a37920ef5440c -F src/update.c 5902d1830e99fcc6d1d03f9bf93ec08b7830cc7569e0e75b4a2ba7849e8261ba +F src/update.c 56fa0458b1ffc1042629f926443e8ed44203983df3ab2b0db2ba556e6ceed68c F src/upsert.c df8f1727d62b5987c4fd302cd4d7c0c84ae57cd65683c5a34a740dfe24039235 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 F src/util.c 41c7a72da1df47864faa378a1c720b38adb288c6838cb6be5594511b6287a048 @@ -1656,7 +1656,7 @@ F test/unordered.test 0edaf3411d300693bca595897c5201421c6c5ec787990a1dfe2f7f60ae F test/update.test e906ca7cb1dc6f52af1ea243e08f727edfa79f924c2691f2f9e72481f847310d F test/update2.test 67455bc61fcbcf96923c45b3bc4f87bc72be7d67575ad35f134906148c7b06d3 F test/upfrom1.tcl 8859d9d437f03b44174c4524a7a734a391fd4526fcff65be08285dafc9dc9041 -F test/upfrom1.test d18f69f7c691bc791e7f31bf0e354eeff04cf2f44edc32d6b1928bad71697073 +F test/upfrom1.test 03bf329c01d78736abe7b70d1d040d9710428dc1fb3d4853a3988654506d1787 F test/upfrom2.test f92e47bfc35e9410d3e8716ee626384e89ad026c55fd6148508ca9d707521673 F test/upfrom3.test 6130f24ebf97f5ea865e5d2a14a2d543fe5428a62e87cc60f62d875e45c1f5f0 F test/upfromfault.test 3a10075a0043f0c4fad6614b2c371f88a8ba5a4acab68b907438413865d6a8d6 @@ -1790,7 +1790,7 @@ F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387 F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b F test/windowfault.test 21919e601f20b976ea2a73aa401220c89ed0e8d203c4f69476ea55bce3726496 F test/windowpushd.test d8895d08870b7226f7693665bd292eb177e62ca06799184957b3ca7dc03067df -F test/with1.test b231edbf0f7c1d94bc14365cd9f33e197b2f0aa16add927ee121649fce014c15 +F test/with1.test 8a4f82b10447a672cd1a7032bbe026c41070a26936f7625425e6989149b133d8 F test/with2.test 000fb95f1f29dae868cea0f41505eb5126077d49eb967ff88f9ee46212ad8863 F test/with3.test ad32d13ad50661e6fa305f62a0717649c348792e7b658bf2644976227a9e0373 F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f198205 @@ -1913,8 +1913,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0f0959c6f95046e8e7887716e0a7de95da18d1e926ab1f919527083a56541db5 b70587cca9e4f0116621e27362186e9329bcea8016c6565cd3ec5a9bf4a99d46 -R 2a77c710da1274e5e7a53dc09e421364 -T +closed b70587cca9e4f0116621e27362186e9329bcea8016c6565cd3ec5a9bf4a99d46 +P 34579549a3bc1c2cfbf47a4770c1d7abc97869ba57bcd3ab1515765ca505ea05 +R c15d075f9e4ae67875b0e31adc3c6940 U drh -Z 6300f10b23774a093facbde1d7138060 +Z 78f6695751cf87d51e05323e72bdbac5 diff --git a/manifest.uuid b/manifest.uuid index fd7c6d876e..9fec0088b5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -34579549a3bc1c2cfbf47a4770c1d7abc97869ba57bcd3ab1515765ca505ea05 \ No newline at end of file +5614279daff5007d6e047c5c1b3cc82ba80a5c91c529525b0fe68b79ee82dd2c \ No newline at end of file diff --git a/src/attach.c b/src/attach.c index 6d178b6ba3..2fc84e5b84 100644 --- a/src/attach.c +++ b/src/attach.c @@ -464,14 +464,17 @@ static int fixSelectCb(Walker *p, Select *pSelect){ if( NEVER(pList==0) ) return WRC_Continue; for(i=0, pItem=pList->a; inSrc; i++, pItem++){ if( pFix->bTemp==0 ){ - if( pItem->zDatabase && iDb!=sqlite3FindDbName(db, pItem->zDatabase) ){ - sqlite3ErrorMsg(pFix->pParse, - "%s %T cannot reference objects in database %s", - pFix->zType, pFix->pName, pItem->zDatabase); - return WRC_Abort; + if( pItem->zDatabase ){ + if( iDb!=sqlite3FindDbName(db, pItem->zDatabase) ){ + sqlite3ErrorMsg(pFix->pParse, + "%s %T cannot reference objects in database %s", + pFix->zType, pFix->pName, pItem->zDatabase); + return WRC_Abort; + } + sqlite3DbFree(db, pItem->zDatabase); + pItem->zDatabase = 0; + pItem->fg.notCte = 1; } - sqlite3DbFree(db, pItem->zDatabase); - pItem->zDatabase = 0; pItem->pSchema = pFix->pSchema; pItem->fg.fromDDL = 1; } diff --git a/src/build.c b/src/build.c index cf952ce091..25954b4d44 100644 --- a/src/build.c +++ b/src/build.c @@ -492,7 +492,7 @@ Table *sqlite3LocateTableItem( SrcItem *p ){ const char *zDb; - /* assert( p->pSchema==0 || p->zDatabase==0 ); FIX-ME */ + assert( p->pSchema==0 || p->zDatabase==0 ); if( p->pSchema ){ int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema); zDb = pParse->db->aDb[iDb].zDbSName; diff --git a/src/select.c b/src/select.c index aeb63d99d6..1ac25c5de2 100644 --- a/src/select.c +++ b/src/select.c @@ -5071,6 +5071,14 @@ static int resolveFromTermToCte( ** it cannot possibly be a CTE reference. */ return 0; } + if( pFrom->fg.notCte ){ + /* The FROM term is specifically excluded from matching a CTE. + ** (1) It is part of a trigger that used to have zDatabase but had + ** zDatabase removed by sqlite3FixTriggerStep(). + ** (2) This is the first term in the FROM clause of an UPDATE. + */ + return 0; + } pCte = searchWith(pParse->pWith, pFrom, &pWith); if( pCte ){ sqlite3 *db = pParse->db; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7eafdd2b40..1bdccddec6 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2948,6 +2948,7 @@ struct SrcItem { unsigned isRecursive :1; /* True for recursive reference in WITH */ unsigned fromDDL :1; /* Comes from sqlite_schema */ unsigned isCte :1; /* This is a CTE */ + unsigned notCte :1; /* This item may not match a CTE */ } fg; int iCursor; /* The VDBE cursor number used to access this table */ Expr *pOn; /* The ON clause of a join */ diff --git a/src/update.c b/src/update.c index a72c02a52f..132232724a 100644 --- a/src/update.c +++ b/src/update.c @@ -220,10 +220,7 @@ static void updateFromSelect( assert( pTabList->nSrc>1 ); if( pSrc ){ - if( pSrc->a[0].zDatabase==0 ){ - int iSchema = sqlite3SchemaToIndex(db, pTab->pSchema); - pSrc->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iSchema].zDbSName); - } + pSrc->a[0].fg.notCte = 1; pSrc->a[0].iCursor = -1; pSrc->a[0].pTab->nTabRef--; pSrc->a[0].pTab = 0; diff --git a/test/upfrom1.test b/test/upfrom1.test index 7996f97702..c0a10c51a1 100644 --- a/test/upfrom1.test +++ b/test/upfrom1.test @@ -175,4 +175,20 @@ do_execsql_test 3.1 { SELECT * FROM t0, t1; } {} +# Problem described by forum post https://sqlite.org/forum/forumpost/a274248080 +# +reset_db +do_execsql_test 4.1 { + CREATE TABLE t1(x INT); INSERT INTO t1 VALUES(1); + CREATE TABLE t2(y INT); INSERT INTO t2 VALUES(2); + WITH t1 AS (SELECT y+100 AS x FROM t2) + UPDATE t1 SET x=(SELECT x FROM t1); + SELECT x, y FROM t1, t2; +} {102 2} +do_execsql_test 4.2 { + WITH t1 AS (SELECT y+100 AS x FROM t2) + UPDATE t1 SET x=x+y FROM t2; + SELECT x, y FROM t1, t2; +} {104 2} + finish_test diff --git a/test/with1.test b/test/with1.test index 08ef8919ad..ba0438d15d 100644 --- a/test/with1.test +++ b/test/with1.test @@ -1207,4 +1207,28 @@ do_execsql_test 26.3 { SELECT * FROM cte ORDER BY +label, +step; } {a 1 a 2 a 3 b 1 b 2 b 3} +# 2021-05-20 +# forum post https://sqlite.org/forum/forumpost/8590e3f6dc +# +reset_db +do_execsql_test 27.1 { + CREATE TABLE t1(k); + CREATE TABLE log(k, cte_map, main_map); + CREATE TABLE map(k, v); + INSERT INTO map VALUES(1, 'main1'), (2, 'main2'); + + CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN + INSERT INTO log + WITH map(k,v) AS (VALUES(1,'cte1'),(2,'cte2')) + SELECT + new.k, + (SELECT v FROM map WHERE k=new.k), + (SELECT v FROM main.map WHERE k=new.k); + END; + + INSERT INTO t1 VALUES(1); + INSERT INTO t1 VALUES(2); + SELECT k, cte_map, main_map, '|' FROM log ORDER BY k; +} {1 cte1 main1 | 2 cte2 main2 |} + finish_test