aboutsummaryrefslogtreecommitdiff
path: root/src/update.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/update.c')
-rw-r--r--src/update.c25
1 files changed, 11 insertions, 14 deletions
diff --git a/src/update.c b/src/update.c
index 52ae8a030..8ff92daea 100644
--- a/src/update.c
+++ b/src/update.c
@@ -191,6 +191,7 @@ void sqlite3Update(
int iPk = 0; /* First of nPk cells holding PRIMARY KEY value */
i16 nPk = 0; /* Number of components of the PRIMARY KEY */
int bReplace = 0; /* True if REPLACE conflict resolution might happen */
+ int bFinishSeek = 1; /* The OP_FinishSeek opcode is needed */
/* Register Allocations */
int regRowCount = 0; /* A count of rows changed */
@@ -524,6 +525,7 @@ void sqlite3Update(
pWInfo = 0;
eOnePass = ONEPASS_SINGLE;
sqlite3ExprIfFalse(pParse, pWhere, labelBreak, SQLITE_JUMPIFNULL);
+ bFinishSeek = 0;
}else{
/* Begin the database scan.
**
@@ -550,6 +552,7 @@ void sqlite3Update(
** strategy that uses an index for which one or more columns are being
** updated. */
eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
+ bFinishSeek = sqlite3WhereUsesDeferredSeek(pWInfo);
if( eOnePass!=ONEPASS_SINGLE ){
sqlite3MultiWrite(pParse);
if( eOnePass==ONEPASS_MULTI ){
@@ -713,6 +716,7 @@ void sqlite3Update(
testcase( i==31 );
testcase( i==32 );
sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, k);
+ bFinishSeek = 0;
}else{
sqlite3VdbeAddOp2(v, OP_Null, 0, k);
}
@@ -800,21 +804,14 @@ void sqlite3Update(
/* Delete the index entries associated with the current record. */
sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx, -1);
-#ifndef SQLITE_OMIT_GENERATED_COLUMNS
- /* If pTab contains one or more virtual columns, then it is possible
- ** (though unlikely) that no OP_Column opcodes have been run against
- ** the table since the OP_SeekDeferred, meaning that there has not been
- ** a seek against the cursor yet. The OP_Delete opcode and OP_Insert
- ** opcodes that follow will be needing this seek, so code a bogus
- ** OP_Column just to make sure the seek has been done.
- ** See ticket ec8abb025e78f40c 2019-12-26
- */
- if( eOnePass!=ONEPASS_OFF && (pTab->tabFlags & TF_HasVirtual)!=0 ){
- int r1 = sqlite3GetTempReg(pParse);
- sqlite3VdbeAddOp3(v, OP_Column, iDataCur, 0, r1);
- sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
+ /* We must run the OP_FinishSeek opcode to resolve a prior
+ ** OP_DeferredSeek if there is any possibility that there have been
+ ** no OP_Column opcodes since the OP_DeferredSeek was issued. But
+ ** we want to avoid the OP_FinishSeek if possible, as running it
+ ** costs CPU cycles. */
+ if( bFinishSeek ){
+ sqlite3VdbeAddOp1(v, OP_FinishSeek, iDataCur);
}
-#endif /* SQLITE_OMIT_GENERATED_COLUMNS */
/* If changing the rowid value, or if there are foreign key constraints
** to process, delete the old record. Otherwise, add a noop OP_Delete