mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Do not use the one-pass optimization on an UPDATE if there is a subquery
in the WHERE clause, since if the subquery is hidden behind a short-circuit operator, the subquery might not be evaluated until after one or more rows have been updated. Fix for the problem reported by [forum:/forumpost/0007d1fdb1|forum post 0007d1fdb1]. This is the same problem that was fixed by [73f0036f045bf371] only for UPDATE instead of DELETE. FossilOrigin-Name: 2c56b984a0bd3be5ec326a2109ea7b8f1d4ef63c8fc325caac9663cf2479eaff
This commit is contained in:
18
manifest
18
manifest
@ -1,5 +1,5 @@
|
|||||||
C Remove\sa\sNEVER()\sfrom\sbtreeNext()\sthat\sdbsqlfuzz\s460aa158f9a2c41145831cc924296cde1f312b3f\nfound\scould\ssometimes\sbe\sreached.\s\sI\swill\sfind\sa\sway\sto\stest\sthat\sbranch\nlater.
|
C Do\snot\suse\sthe\sone-pass\soptimization\son\san\sUPDATE\sif\sthere\sis\sa\ssubquery\nin\sthe\sWHERE\sclause,\ssince\sif\sthe\ssubquery\sis\shidden\sbehind\sa\sshort-circuit\noperator,\sthe\ssubquery\smight\snot\sbe\sevaluated\suntil\safter\sone\sor\smore\srows\nhave\sbeen\supdated.\s\sFix\sfor\sthe\sproblem\sreported\sby\n[forum:/forumpost/0007d1fdb1|forum\spost\s0007d1fdb1].\s\sThis\sis\sthe\ssame\nproblem\sthat\swas\sfixed\sby\s[73f0036f045bf371]\sonly\sfor\sUPDATE\sinstead\sof\nDELETE.
|
||||||
D 2023-03-16T09:07:46.644
|
D 2023-03-16T10:17:30.566
|
||||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||||
@ -690,7 +690,7 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
|
|||||||
F src/tokenize.c 1305797eab3542a0896b552c6e7669c972c1468e11e92b370533c1f37a37082b
|
F src/tokenize.c 1305797eab3542a0896b552c6e7669c972c1468e11e92b370533c1f37a37082b
|
||||||
F src/treeview.c fccf3b8c517c1f55cb380c1522febe6921fcb2bd800c16c78cab571d0eb0ccbd
|
F src/treeview.c fccf3b8c517c1f55cb380c1522febe6921fcb2bd800c16c78cab571d0eb0ccbd
|
||||||
F src/trigger.c 6072c531d9bcc3980528150a1b03fda2e85a08c10023fafb42f93ffd68607ffe
|
F src/trigger.c 6072c531d9bcc3980528150a1b03fda2e85a08c10023fafb42f93ffd68607ffe
|
||||||
F src/update.c f118e51768d2c1309e3c81e9f91141b22b8a1339cbc5969b1b2d810feaa25b22
|
F src/update.c 76664e1beae86e8e961983ebe19a4ee9ebd7e26683ead2b288ba08f81fc7ba4e
|
||||||
F src/upsert.c 5303dc6c518fa7d4b280ec65170f465c7a70b7ac2b22491598f6d0b4875b3145
|
F src/upsert.c 5303dc6c518fa7d4b280ec65170f465c7a70b7ac2b22491598f6d0b4875b3145
|
||||||
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
|
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
|
||||||
F src/util.c 3ff7bc2b48dd425b1448304bb86273b05da1621f136d51dbb9789f8803559a1f
|
F src/util.c 3ff7bc2b48dd425b1448304bb86273b05da1621f136d51dbb9789f8803559a1f
|
||||||
@ -890,7 +890,7 @@ F test/corruptH.test 79801d97ec5c2f9f3c87739aa1ec2eb786f96454
|
|||||||
F test/corruptI.test a17bbf54fdde78d43cf3cc34b0057719fd4a173a3d824285b67dc5257c064c7b
|
F test/corruptI.test a17bbf54fdde78d43cf3cc34b0057719fd4a173a3d824285b67dc5257c064c7b
|
||||||
F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4
|
F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4
|
||||||
F test/corruptK.test 5b4212fe346699831c5ad559a62c54e11c0611bdde1ea8423a091f9c01aa32af
|
F test/corruptK.test 5b4212fe346699831c5ad559a62c54e11c0611bdde1ea8423a091f9c01aa32af
|
||||||
F test/corruptL.test 9d1a0055c8db19baccd12f22ac36a33ec7d63afb59e82eb30835aea8f89b94df
|
F test/corruptL.test b42978028afc5eefc8b51d8d7cd6a9344ba7362d7ed4511ee2070f56e06d5a1c
|
||||||
F test/corruptM.test 7d574320e08c1b36caa3e47262061f186367d593a7e305d35f15289cc2c3e067
|
F test/corruptM.test 7d574320e08c1b36caa3e47262061f186367d593a7e305d35f15289cc2c3e067
|
||||||
F test/corruptN.test 7c099d153a554001b4fb829c799b01f2ea6276cbc32479131e0db0da4efd9cc4
|
F test/corruptN.test 7c099d153a554001b4fb829c799b01f2ea6276cbc32479131e0db0da4efd9cc4
|
||||||
F test/cost.test b11cdbf9f11ffe8ef99c9881bf390e61fe92baf2182bad1dbe6de59a7295c576
|
F test/cost.test b11cdbf9f11ffe8ef99c9881bf390e61fe92baf2182bad1dbe6de59a7295c576
|
||||||
@ -928,7 +928,7 @@ F test/dbstatus.test 4a4221a883025ffd39696b3d1b3910b928fb097d77e671351acb35f3aed
|
|||||||
F test/dbstatus2.test f5fe0afed3fa45e57cfa70d1147606c20d2ba23feac78e9a172f2fe8ab5b78ef
|
F test/dbstatus2.test f5fe0afed3fa45e57cfa70d1147606c20d2ba23feac78e9a172f2fe8ab5b78ef
|
||||||
F test/decimal.test fcf403fd5585f47342234e153c4a4338cd737b8e0884ac66fc484df47dbcf1a7
|
F test/decimal.test fcf403fd5585f47342234e153c4a4338cd737b8e0884ac66fc484df47dbcf1a7
|
||||||
F test/default.test 9687cfb16717e4b8238c191697c98be88c0b16e568dd5368cd9284154097ef50
|
F test/default.test 9687cfb16717e4b8238c191697c98be88c0b16e568dd5368cd9284154097ef50
|
||||||
F test/delete.test f66581a22960dae89b05f14755a576d935dcb94aa3aeacc0005b29bdbaa9949c
|
F test/delete.test 2686e1c98d552ef37d79ad55b17b93fe96fad9737786917ce3839767f734c48f
|
||||||
F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa
|
F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa
|
||||||
F test/delete3.test 555e84a00a99230b7d049d477a324a631126a6ab
|
F test/delete3.test 555e84a00a99230b7d049d477a324a631126a6ab
|
||||||
F test/delete4.test 51fafebe9503a40796d1aae1565c60524cada720e50eecac01b7fd0419d9ea0b
|
F test/delete4.test 51fafebe9503a40796d1aae1565c60524cada720e50eecac01b7fd0419d9ea0b
|
||||||
@ -1774,7 +1774,7 @@ F test/unique.test 93f8b2ef5ea51b9495f8d6493429b1fd0f465264
|
|||||||
F test/unique2.test 3674e9f2a3f1fbbfd4772ac74b7a97090d0f77d2
|
F test/unique2.test 3674e9f2a3f1fbbfd4772ac74b7a97090d0f77d2
|
||||||
F test/unixexcl.test d936ba2b06794018e136418addd59a2354eeae97
|
F test/unixexcl.test d936ba2b06794018e136418addd59a2354eeae97
|
||||||
F test/unordered.test 0edaf3411d300693bca595897c5201421c6c5ec787990a1dfe2f7f60ae93f1e2
|
F test/unordered.test 0edaf3411d300693bca595897c5201421c6c5ec787990a1dfe2f7f60ae93f1e2
|
||||||
F test/update.test eb7f4eb172ce270e51bb67d7867521f33a63635bb671e261bbafccaef3bd6db2
|
F test/update.test 90772ede84cfc779fc3d31884a84ec4c74deb501eeb09a1c6c91c03d8e94c0d8
|
||||||
F test/update2.test 67455bc61fcbcf96923c45b3bc4f87bc72be7d67575ad35f134906148c7b06d3
|
F test/update2.test 67455bc61fcbcf96923c45b3bc4f87bc72be7d67575ad35f134906148c7b06d3
|
||||||
F test/upfrom1.tcl 8859d9d437f03b44174c4524a7a734a391fd4526fcff65be08285dafc9dc9041
|
F test/upfrom1.tcl 8859d9d437f03b44174c4524a7a734a391fd4526fcff65be08285dafc9dc9041
|
||||||
F test/upfrom1.test 8cb06689e99cd707d884faa16da0e8eb26ff658bb01c47ddf72fadade666e6e1
|
F test/upfrom1.test 8cb06689e99cd707d884faa16da0e8eb26ff658bb01c47ddf72fadade666e6e1
|
||||||
@ -2050,8 +2050,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P 73f0036f045bf37193b6e87ae45b578c5831614c530488257c69666178da3aa5
|
P 1dffeffe150fff6777cf26bc960326ca4e4190d25d05bb066b082d1e1c8eb374
|
||||||
R 416ca2e38e88837ddad74173b91b3e6d
|
R 5410b321a0481083a3d313d81510e3fc
|
||||||
U drh
|
U drh
|
||||||
Z 476a952efa83c3a1b612460afea7cd08
|
Z eea9af84fd6b98bd366cd12ed13a97d2
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@ -1 +1 @@
|
|||||||
1dffeffe150fff6777cf26bc960326ca4e4190d25d05bb066b082d1e1c8eb374
|
2c56b984a0bd3be5ec326a2109ea7b8f1d4ef63c8fc325caac9663cf2479eaff
|
20
src/update.c
20
src/update.c
@ -727,12 +727,22 @@ void sqlite3Update(
|
|||||||
/* Begin the database scan.
|
/* Begin the database scan.
|
||||||
**
|
**
|
||||||
** Do not consider a single-pass strategy for a multi-row update if
|
** Do not consider a single-pass strategy for a multi-row update if
|
||||||
** there are any triggers or foreign keys to process, or rows may
|
** there is anything that might disrupt the cursor being used to do
|
||||||
** be deleted as a result of REPLACE conflict handling. Any of these
|
** the UPDATE:
|
||||||
** things might disturb a cursor being used to scan through the table
|
** (1) This is a nested UPDATE
|
||||||
** or index, causing a single-pass approach to malfunction. */
|
** (2) There are triggers
|
||||||
|
** (3) There are FOREIGN KEY constraints
|
||||||
|
** (4) There are REPLACE conflict handlers
|
||||||
|
** (5) There are subqueries in the WHERE clause
|
||||||
|
*/
|
||||||
flags = WHERE_ONEPASS_DESIRED;
|
flags = WHERE_ONEPASS_DESIRED;
|
||||||
if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){
|
if( !pParse->nested
|
||||||
|
&& !pTrigger
|
||||||
|
&& !hasFK
|
||||||
|
&& !chngKey
|
||||||
|
&& !bReplace
|
||||||
|
&& (sNC.ncFlags & NC_Subquery)==0
|
||||||
|
){
|
||||||
flags |= WHERE_ONEPASS_MULTIROW;
|
flags |= WHERE_ONEPASS_MULTIROW;
|
||||||
}
|
}
|
||||||
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere,0,0,0,flags,iIdxCur);
|
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere,0,0,0,flags,iIdxCur);
|
||||||
|
@ -1269,11 +1269,14 @@ do_test 15.0 {
|
|||||||
}]} {}
|
}]} {}
|
||||||
|
|
||||||
extra_schema_checks 0
|
extra_schema_checks 0
|
||||||
do_execsql_test 15.1 {
|
do_catchsql_test 15.1 {
|
||||||
PRAGMA cell_size_check = 0;
|
PRAGMA cell_size_check = 0;
|
||||||
UPDATE c1 SET c= NOT EXISTS(SELECT 1 FROM c1 ORDER BY (SELECT 1 FROM c1 ORDER BY a)) +10 WHERE d BETWEEN 4 AND 7;
|
UPDATE c1 SET c= NOT EXISTS(SELECT 1 FROM c1 ORDER BY (SELECT 1 FROM c1 ORDER BY a)) +10 WHERE d BETWEEN 4 AND 7;
|
||||||
} {}
|
} {1 {database disk image is malformed}}
|
||||||
extra_schema_checks 1
|
extra_schema_checks 1
|
||||||
|
do_execsql_test 15.2 {
|
||||||
|
PRAGMA integrity_check;
|
||||||
|
} {/in database main/}
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
reset_db
|
reset_db
|
||||||
|
@ -426,6 +426,9 @@ do_execsql_test delete-11.1 {
|
|||||||
# run after one or more rows have been deleted, which can change
|
# run after one or more rows have been deleted, which can change
|
||||||
# the result of the subquery, and result in the wrong answer.
|
# the result of the subquery, and result in the wrong answer.
|
||||||
#
|
#
|
||||||
|
# Similar problem for UPDATE tested by update-21.4
|
||||||
|
# https://sqlite.org/forum/forumpost/0007d1fdb1
|
||||||
|
#
|
||||||
reset_db
|
reset_db
|
||||||
do_execsql_test delete-12.0 {
|
do_execsql_test delete-12.0 {
|
||||||
CREATE TABLE t0(vkey INTEGER, pkey INTEGER,c1 INTEGER);
|
CREATE TABLE t0(vkey INTEGER, pkey INTEGER,c1 INTEGER);
|
||||||
|
@ -732,4 +732,37 @@ do_execsql_test update-20.30 {
|
|||||||
PRAGMA integrity_check;
|
PRAGMA integrity_check;
|
||||||
} {ok}
|
} {ok}
|
||||||
|
|
||||||
|
# 2023-03-16 https://sqlite.org/forum/forumpost/0007d1fdb1
|
||||||
|
# A subquery in the WHERE clause of an UPDATE and behind a
|
||||||
|
# short-circuit evaluation caused problems because multi-row
|
||||||
|
# single-pass was selected.
|
||||||
|
#
|
||||||
|
# Similar problem for DELETE tested by delete-12.0.
|
||||||
|
# https://sqlite.org/src/info/73f0036f045bf371
|
||||||
|
#
|
||||||
|
reset_db
|
||||||
|
do_execsql_test update-21.1 {
|
||||||
|
CREATE TABLE t1 (vkey INTEGER, c5 INTEGER);
|
||||||
|
INSERT INTO t1 VALUES(3,NULL),(6,-54);
|
||||||
|
}
|
||||||
|
db null NULL
|
||||||
|
do_execsql_test update-21.2 {
|
||||||
|
BEGIN;
|
||||||
|
UPDATE t1 SET vkey = 100 WHERE c5 is null;
|
||||||
|
SELECT * FROM t1 ORDER BY vkey, c5;
|
||||||
|
ROLLBACK;
|
||||||
|
} {6 -54 100 NULL}
|
||||||
|
do_execsql_test update-21.3 {
|
||||||
|
BEGIN;
|
||||||
|
UPDATE t1 SET vkey = 100 WHERE NOT (-10*(select min(vkey) from t1) >= c5);
|
||||||
|
SELECT * FROM t1 ORDER BY vkey, c5;
|
||||||
|
ROLLBACK;
|
||||||
|
} {3 NULL 6 -54}
|
||||||
|
do_execsql_test update-21.4 {
|
||||||
|
BEGIN;
|
||||||
|
UPDATE t1 SET vkey = 100 WHERE c5 is null OR NOT (-10*(select min(vkey) from t1) >= c5);
|
||||||
|
SELECT * FROM t1 ORDER BY vkey, c5;
|
||||||
|
ROLLBACK;
|
||||||
|
} {6 -54 100 NULL}
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
Reference in New Issue
Block a user