1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02: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:
drh
2023-03-16 10:17:30 +00:00
parent 5531316dd0
commit 7d5a549121
6 changed files with 66 additions and 17 deletions

View File

@@ -727,12 +727,22 @@ void sqlite3Update(
/* Begin the database scan.
**
** 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
** be deleted as a result of REPLACE conflict handling. Any of these
** things might disturb a cursor being used to scan through the table
** or index, causing a single-pass approach to malfunction. */
** there is anything that might disrupt the cursor being used to do
** the UPDATE:
** (1) This is a nested UPDATE
** (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;
if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){
if( !pParse->nested
&& !pTrigger
&& !hasFK
&& !chngKey
&& !bReplace
&& (sNC.ncFlags & NC_Subquery)==0
){
flags |= WHERE_ONEPASS_MULTIROW;
}
pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere,0,0,0,flags,iIdxCur);