From: drh Date: Mon, 2 May 2016 12:18:56 +0000 (+0000) Subject: Disable the multi-row one-pass DELETE optimization when the WHERE clause X-Git-Tag: version-3.13.0~46 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=57a07ba9a938ead154cc629a8357cb025b14a7b1;p=thirdparty%2Fsqlite.git Disable the multi-row one-pass DELETE optimization when the WHERE clause contains a subquery. Fix for ticket [dc6ebeda9396087]. FossilOrigin-Name: 3f221f592a9a19009076e568566c59801cd3fc32 --- diff --git a/manifest b/manifest index 4b7ff45c68..1b3f03c036 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sthe\sway\sthe\sLIKE\soptimization\sis\simplemented,\sresulting\sin\nslightly\ssmaller\sand\sfaster\scode\sthat\sis\seasier\sto\stest. -D 2016-05-02T10:25:42.392 +C Disable\sthe\smulti-row\sone-pass\sDELETE\soptimization\swhen\sthe\sWHERE\sclause\ncontains\sa\ssubquery.\s\sFix\sfor\sticket\s[dc6ebeda9396087]. +D 2016-05-02T12:18:56.634 F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836 @@ -330,7 +330,7 @@ F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 60e135af364d777a9ab41c97e5e89cd224da6198 F src/date.c 1cc9fb516ec9932c6fd4d2a0d2f8bc4480145c39 F src/dbstat.c c845548d4346e606e2f2b7d2e714ace2b8a7dd1b -F src/delete.c 78eb999114ec04fcf1b7d123ccedb4b5b734930e +F src/delete.c 362f89f8e6783e672c4ab06b90fca0177f9a576d F src/expr.c 8796c0739b2ad091e6779253f62aad6e767e2be1 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c 4c0bd09e602b8ae8d36d81e31e4872d0b53c87bb @@ -617,7 +617,7 @@ F test/default.test 0cb49b1c315a0d81c81d775e407f66906a2a604d F test/delete.test e1bcdf8926234e27aac24b346ad83d3329ec8b6f F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa F test/delete3.test 555e84a00a99230b7d049d477a324a631126a6ab -F test/delete4.test 738044ee892ee0c84e0848e36ba92c55f907d52b +F test/delete4.test 21d2113217eeaacac2d99defe14fe6611615ae86 F test/descidx1.test 6d03b44c8538fe0eb4924e19fba10cdd8f3c9240 F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2 @@ -1486,7 +1486,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 820c57bb24ad3d8663ca512e4022268b940bb2ee -R c58e65d0f2e2d03ddd82d7f66bccab45 +P 54c63b329288729031f45b7778752552cd90e226 +R 31fbd50c446b686ccdad6a76f26cbea2 U drh -Z 38f3015d7db64980369a2f7c9273004f +Z 89acbaae560b0638ea30c0a72d46ae74 diff --git a/manifest.uuid b/manifest.uuid index d98c57c9ad..a267b82408 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -54c63b329288729031f45b7778752552cd90e226 \ No newline at end of file +3f221f592a9a19009076e568566c59801cd3fc32 \ No newline at end of file diff --git a/src/delete.c b/src/delete.c index e3af2d7a78..258b39cc3e 100644 --- a/src/delete.c +++ b/src/delete.c @@ -239,11 +239,12 @@ void sqlite3DeleteFrom( int addrBypass = 0; /* Address of jump over the delete logic */ int addrLoop = 0; /* Top of the delete loop */ int addrEphOpen = 0; /* Instruction to open the Ephemeral table */ + int bComplex; /* True if there are triggers or FKs or or + ** subqueries in the WHERE clause */ #ifndef SQLITE_OMIT_TRIGGER int isView; /* True if attempting to delete from a view */ Trigger *pTrigger; /* List of table triggers, if required */ - int bComplex; /* True if there are either triggers or FKs */ #endif memset(&sContext, 0, sizeof(sContext)); @@ -271,7 +272,6 @@ void sqlite3DeleteFrom( #else # define pTrigger 0 # define isView 0 -# define bComplex 0 #endif #ifdef SQLITE_OMIT_VIEW # undef isView @@ -374,6 +374,7 @@ void sqlite3DeleteFrom( #endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */ { u16 wcf = WHERE_ONEPASS_DESIRED|WHERE_DUPLICATES_OK; + if( pWhere && ExprHasProperty(pWhere, EP_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/test/delete4.test b/test/delete4.test index 7622b7525e..34ba9aaef8 100644 --- a/test/delete4.test +++ b/test/delete4.test @@ -161,4 +161,27 @@ do_execsql_test 5.0 { SELECT a FROM t1 WHERE b=2; } {} +# 2016-05-02 +# Ticket https://www.sqlite.org/src/tktview/dc6ebeda93960877 +# A subquery in the WHERE clause of a one-pass DELETE can cause an +# incorrect answer. +# +db close +forcedelete test.db +sqlite3 db test.db +do_execsql_test 6.0 { + CREATE TABLE t2(x INT); + INSERT INTO t2(x) VALUES(1),(2),(3),(4),(5); + DELETE FROM t2 WHERE EXISTS(SELECT 1 FROM t2 AS v WHERE v.x=t2.x-1); + SELECT x FROM t2; +} {1} +do_execsql_test 6.1 { + DROP TABLE IF EXISTS t2; + CREATE TABLE t2(x INT); + INSERT INTO t2(x) VALUES(1),(2),(3),(4),(5); + DELETE FROM t2 WHERE EXISTS(SELECT 1 FROM t2 AS v WHERE v.x=t2.x+1); + SELECT x FROM t2; +} {5} + + finish_test