From: drh <> Date: Wed, 15 Mar 2023 18:05:02 +0000 (+0000) Subject: Disallow the one-pass optimization for DELETE if the WHERE clause contains X-Git-Tag: version-3.41.2~15 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1a7d1ab06e6286705d03abb93606b9aaacc496bb;p=thirdparty%2Fsqlite.git Disallow the one-pass optimization for DELETE if the WHERE clause contains a subquery. FossilOrigin-Name: 25e1831885e8de370482a1e9f664f1590fa49995048fb16e1f948acd2a29c3e3 --- diff --git a/manifest b/manifest index 8d1d6f3ec8..bc35330427 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sBloom\sfilters\son\san\sexpression\sindex. -D 2023-03-14T20:16:48.299 +C Disallow\sthe\sone-pass\soptimization\sfor\sDELETE\sif\sthe\sWHERE\sclause\scontains\na\ssubquery. +D 2023-03-15T18:05:02.324 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -570,7 +570,7 @@ F src/ctime.c 20507cc0b0a6c19cd882fcd0eaeda32ae6a4229fb4b024cfdf3183043d9b703d F src/date.c f21815ca7172ce073db3163ac54c8d9f2841077165c1a6123b4d1c376a0c7ec7 F src/dbpage.c d47549716549311f79dc39fe5c8fb19390a6eb2c960f8e37c89a9c4de0c1052e F src/dbstat.c ec92074baa61d883de58c945162d9e666c13cd7cf3a23bc38b4d1c4d0b2c2bef -F src/delete.c 86573edae75e3d3e9a8b590d87db8e47222103029df4f3e11fa56044459b514e +F src/delete.c 201fe0763c52783d205c8c13cdd9d55c1bd5cb21c1f036753f99103b43284b90 F src/expr.c 0bb501fd89d30dcb2569c7e479d765c2b92d969cf36c9dc5aa54db3d35c55d2a F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 722f20779f5342a787922deded3628d8c74b5249cab04098cf17ee2f2aaff002 @@ -619,14 +619,14 @@ F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 F src/prepare.c ce87a08cfddd45a147150db34190b1986f2d4a0e0828858cb6bd908c78fb02e3 F src/printf.c ff4b05e38bf928ff1b80d3dda4f977b10fe39ecbfe69c018224c7e5594fb2455 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c -F src/resolve.c 4233c3030341bf1a21cea90890e6b3d3531721acc62ede147e899d36ffad8238 +F src/resolve.c 6a0253379cc15b3f80321362a61f487a8ef7cd2487fe62e1eb2317b3f871c61f F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 9c6f537469c54af6e5b981d68ac18714562c497e6ff57782f338bb17b3ec9777 F src/shell.c.in 6f36f5ca05f1bebf74935a7fcf2dce983016e807a09cbd752a673583ad7da087 F src/sqlite.h.in 662a2fa083d093896b92560c871dea6d86792b49dc4bf7b4e8dbeca8e7171488 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h da473ce2b3d0ae407a6300c4a164589b9a6bfdbec9462688a8593ff16f3bb6e4 -F src/sqliteInt.h 107157709ddfb05583343b69f14b0fa159f3ff8899ae2115415977a64815b364 +F src/sqliteInt.h e6f8331d9d78cee8f3d9b0f424680a4dbafaa72401b6ab3b92a3bd699aaafa7f F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -924,7 +924,7 @@ F test/dbstatus.test 4a4221a883025ffd39696b3d1b3910b928fb097d77e671351acb35f3aed F test/dbstatus2.test f5fe0afed3fa45e57cfa70d1147606c20d2ba23feac78e9a172f2fe8ab5b78ef F test/decimal.test fcf403fd5585f47342234e153c4a4338cd737b8e0884ac66fc484df47dbcf1a7 F test/default.test 9687cfb16717e4b8238c191697c98be88c0b16e568dd5368cd9284154097ef50 -F test/delete.test 31832b0c45ecb51a54348c68db173be462985901e6ed7f403d6d7a8f70ab4ef0 +F test/delete.test f66581a22960dae89b05f14755a576d935dcb94aa3aeacc0005b29bdbaa9949c F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa F test/delete3.test 555e84a00a99230b7d049d477a324a631126a6ab F test/delete4.test 51fafebe9503a40796d1aae1565c60524cada720e50eecac01b7fd0419d9ea0b @@ -2045,9 +2045,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 6d6d95fcedbc8758ab284d3014ae4a97af6247003bb3d0a7056f2e6bffa6cae4 -Q +c028fb669a5ae34dbaf50fffab1ae49bc568b994435cf02e145d24da3cfb48d7 -R dcdf38ad3013ce771821ecfbfb219809 +P 11e0256b8c6f29bd2e60a0820f740e9927112bf6a0814751b7a73896298b4826 +Q +73f0036f045bf37193b6e87ae45b578c5831614c530488257c69666178da3aa5 +R 2cd55a1efd71979f677dd69b07b32a06 U drh -Z d6b69aca9364487c409ab687d0cabf73 +Z 60bb5fb96b693c918389f608d5ae659c # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 56882271c0..6141b8a796 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -11e0256b8c6f29bd2e60a0820f740e9927112bf6a0814751b7a73896298b4826 \ No newline at end of file +25e1831885e8de370482a1e9f664f1590fa49995048fb16e1f948acd2a29c3e3 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index 704a3c7110..22ef7ab658 100644 --- a/src/delete.c +++ b/src/delete.c @@ -483,7 +483,7 @@ void sqlite3DeleteFrom( #endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */ { u16 wcf = WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK; - if( sNC.ncFlags & NC_VarSelect ) bComplex = 1; + if( sNC.ncFlags & NC_Subquery ) bComplex = 1; wcf |= (bComplex ? 0 : WHERE_ONEPASS_MULTIROW); if( HasRowid(pTab) ){ /* For a rowid table, initialize the RowSet to an empty set */ diff --git a/src/resolve.c b/src/resolve.c index dfb3434396..4b36ecca34 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -1252,8 +1252,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ assert( pNC->nRef>=nRef ); if( nRef!=pNC->nRef ){ ExprSetProperty(pExpr, EP_VarSelect); - pNC->ncFlags |= NC_VarSelect; } + pNC->ncFlags |= NC_Subquery; } break; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 59637eb9e4..b7cf1c85c8 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3341,7 +3341,7 @@ struct NameContext { #define NC_HasAgg 0x000010 /* One or more aggregate functions seen */ #define NC_IdxExpr 0x000020 /* True if resolving columns of CREATE INDEX */ #define NC_SelfRef 0x00002e /* Combo: PartIdx, isCheck, GenCol, and IdxExpr */ -#define NC_VarSelect 0x000040 /* A correlated subquery has been seen */ +#define NC_Subquery 0x000040 /* A subquery has been seen */ #define NC_UEList 0x000080 /* True if uNC.pEList is used */ #define NC_UAggInfo 0x000100 /* True if uNC.pAggInfo is used */ #define NC_UUpsert 0x000200 /* True if uNC.pUpsert is used */ diff --git a/test/delete.test b/test/delete.test index a448e52dd2..cdf6798ea6 100644 --- a/test/delete.test +++ b/test/delete.test @@ -416,4 +416,25 @@ do_execsql_test delete-11.1 { } {6 2 12 4 18 6 19 23 20 40} +# 2023-03-15 +# https://sqlite.org/forum/forumpost/e61252062c9d286d +# +# When the WHERE clause of a DELETE statement contains a subquery +# which uses the table that is being deleted from and there is a +# short-circuit operator of some kind in the WHERE clause such that +# the subquery might not run right away, then the subquery might +# run after one or more rows have been deleted, which can change +# the result of the subquery, and result in the wrong answer. +# +reset_db +do_execsql_test delete-12.0 { + CREATE TABLE t0(vkey INTEGER, pkey INTEGER,c1 INTEGER); + INSERT INTO t0 VALUES(2,1,-20),(2,2,NULL),(2,3,0),(8,4,95); + DELETE FROM t0 WHERE NOT ( + (t0.vkey <= t0.c1) AND + (t0.vkey <> (SELECT vkey FROM t0 ORDER BY vkey LIMIT 1 OFFSET 2)) + ); + SELECT * FROM t0; +} {8 4 95} + finish_test