From 7a9698456dfb800878cb4414238927fc86907f93 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 9 Dec 2019 14:34:37 +0000 Subject: [PATCH] Fix a gramfuzz find. If a partial index that does not reference any column of its table is used by an UPDATE statement in one-pass mode, then avoid the use of OP_DeferredSeek since the seek might not be resolved prior to the OP_Delete and OP_Insert that implement the UPDATE. FossilOrigin-Name: e3398c5ffb060b2b26334b8598e2c63953741e2d6f5124dbd6bdfc8e94742539 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/wherecode.c | 8 ++++---- test/update.test | 17 +++++++++++++++++ 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 39c8f9b321..6bd9a3ad38 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sinfinite\srecursion\sin\sthe\sALTER\sTABLE\scode\swhen\sa\sview\scontains\san\sunused\sCTE\sthat\sreferences,\sdirectly\sor\sindirectly,\sthe\sview\sitself. -D 2019-12-09T08:13:43.318 +C Fix\sa\sgramfuzz\sfind.\s\sIf\sa\spartial\sindex\sthat\sdoes\snot\sreference\sany\scolumn\nof\sits\stable\sis\sused\sby\san\sUPDATE\sstatement\sin\sone-pass\smode,\sthen\savoid\sthe\nuse\sof\sOP_DeferredSeek\ssince\sthe\sseek\smight\snot\sbe\sresolved\sprior\sto\sthe\nOP_Delete\sand\sOP_Insert\sthat\simplement\sthe\sUPDATE. +D 2019-12-09T14:34:37.171 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -615,7 +615,7 @@ F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c a137468bf36c92e64d2275caa80c83902e3a0fc59273591b96c6416d3253d05d F src/where.c bb2d3c08de9ae57f6ff17459cefd9e38e82d3e7aaa544bc49503b6fdaaf2c800 F src/whereInt.h 4a296fd4fa79fdcbc2b5e8c1b898901617655811223e1082b899c23ecb092217 -F src/wherecode.c 909325b98d5cb313f24e5c8cb304a3e3c73ca6631cdb19cfa1f580dde182fedb +F src/wherecode.c 7efa97f4dc2f95548611deba68f0210ab357725899a9bae5391a525e48271875 F src/whereexpr.c 39b6a538804c6e1248c22b33e09d00f89ae6a099c849c4d841ce3995562287b4 F src/window.c a77f12078dd4b10e655d4ba5a73ca32dbe00e0206018305185c7e86445d3f429 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1604,7 +1604,7 @@ F test/unique.test 93f8b2ef5ea51b9495f8d6493429b1fd0f465264 F test/unique2.test 3674e9f2a3f1fbbfd4772ac74b7a97090d0f77d2 F test/unixexcl.test d936ba2b06794018e136418addd59a2354eeae97 F test/unordered.test ffeea7747d5ba962a8009a20b7e53d68cbae05b063604c68702c5998eb50c981 -F test/update.test 1148de8d913e9817717990603aadeca07aab9ddbb10a30f167cbfd8d3a3ccb60 +F test/update.test 6a1193fbcb4546b4467d24635b1504b8e746b41d3b66dc6ace07581a62ce58fb F test/update2.test 67455bc61fcbcf96923c45b3bc4f87bc72be7d67575ad35f134906148c7b06d3 F test/upsert1.test 0b740c8488fd2f5a06ac317c9913f7ef1eda8282f2db58b544b89480c51efab3 F test/upsert2.test 9c3cdbb1a890227f6504ce4b0e3de68f4cdfa16bb21d8641208a9239896c5a09 @@ -1852,7 +1852,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 c5d44143599f3fe98492b2b900fa3d77925c7be545096251055ceeab899a41f1 -R 22fd1a654a96a45bd7c185276aceb3b2 -U dan -Z 7090efa7effe7e9fcfeaeecdf4e29b8c +P 1d2e53a39b87e364685e21de137655b6eee725e4c6d27fc90865072d7c5892b5 +R 73f9d074ffb019cac59a96d55cf2c0bc +U drh +Z 9b8f81a17115c4850191512c3ac99432 diff --git a/manifest.uuid b/manifest.uuid index 5ae7f863d6..146af5fbe7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1d2e53a39b87e364685e21de137655b6eee725e4c6d27fc90865072d7c5892b5 \ No newline at end of file +e3398c5ffb060b2b26334b8598e2c63953741e2d6f5124dbd6bdfc8e94742539 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 893ba7b8e8..59546c43c9 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1854,10 +1854,10 @@ Bitmask sqlite3WhereCodeOneLoopStart( if( omitTable ){ /* pIdx is a covering index. No need to access the main table. */ }else if( HasRowid(pIdx->pTable) ){ - if( (pWInfo->wctrlFlags & WHERE_SEEK_TABLE) || ( - (pWInfo->wctrlFlags & WHERE_SEEK_UNIQ_TABLE) - && (pWInfo->eOnePass==ONEPASS_SINGLE) - )){ + if( (pWInfo->wctrlFlags & WHERE_SEEK_TABLE) + || ( (pWInfo->wctrlFlags & WHERE_SEEK_UNIQ_TABLE)!=0 + && (pWInfo->eOnePass==ONEPASS_SINGLE || pLoop->nLTerm==0) ) + ){ iRowidReg = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg); sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, iRowidReg); diff --git a/test/update.test b/test/update.test index 99fff45818..76aba65cda 100644 --- a/test/update.test +++ b/test/update.test @@ -641,4 +641,21 @@ do_execsql_test update-16.1 { SELECT * FROM t16 ORDER BY +a; } {1 2 3 4 5 6} +# 2019-12-09 gramfuzz find +# If a partial index that does not reference any column of its table (which is you +# must admit is a very strange index, but one that is allowed) is used by an UPDATE +# statement, void the use of OP_DeferredSeek on the main loop, as the seek will not +# be resolved prior to the OP_Delete. +# +do_execsql_test update-17.10 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(x,y); + INSERT INTO t1(x) VALUES(1); + CREATE INDEX t1x1 ON t1(1) WHERE 3; + UPDATE t1 SET x=2, y=3 WHERE 3; + SELECT * FROM t1; +} {2 3} + + + finish_test -- 2.47.2