aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2019-12-26 23:16:18 +0000
committerdrh <drh@noemail.net>2019-12-26 23:16:18 +0000
commitd3ee3ad12fd53f0db78a2c07917fb4fc310ca72a (patch)
tree8d52aef31d4aa6321afb8ee6c6d53850ca4e7f39 /src
parente752040c099f4137c7cbab3c4a51c684ed8173be (diff)
downloadsqlite-d3ee3ad12fd53f0db78a2c07917fb4fc310ca72a.tar.gz
sqlite-d3ee3ad12fd53f0db78a2c07917fb4fc310ca72a.zip
An UPDATE of a table that is indexed by a constant virtual column that uses
the one-pass optimization might cause the table seek to be omitted before reaching row DELETE/INSERT. Fix this by coding an extra OP_Column in that circumstance. Ticket [ec8abb025e78f40c] FossilOrigin-Name: e54560495926fbb8a2ce829c677a2dd0066e46b7a8d4ada9d8a34a3426959836
Diffstat (limited to 'src')
-rw-r--r--src/update.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/src/update.c b/src/update.c
index 935e1d937..52ae8a030 100644
--- a/src/update.c
+++ b/src/update.c
@@ -800,6 +800,22 @@ 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);
+ }
+#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
** to invoke the pre-update hook.