When a statement causes a ROLLBACK due to an ON CONFLICT clause, other active

VMs abort. (CVS 1778)

FossilOrigin-Name: 0fedf74e30026afe2c8caacff3d62cf5c1b1f528
This commit is contained in:
drh 2004-06-30 11:14:18 +00:00
parent 05056307fd
commit 91b48aa1af
6 changed files with 110 additions and 11 deletions

View File

@ -1,5 +1,5 @@
C Make\ssure\svacuum.test\scloses\sall\sfiles.\s(CVS\s1777)
D 2004-06-30T10:54:30
C When\sa\sstatement\scauses\sa\sROLLBACK\sdue\sto\san\sON\sCONFLICT\sclause,\sother\sactive\nVMs\sabort.\s(CVS\s1778)
D 2004-06-30T11:14:19
F Makefile.in cb7a9889c38723f72b2506c4236ff30a05ff172b
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@ -75,9 +75,9 @@ F src/util.c b267d0fe10cffa3301fe9fab6592a6808a38bce6
F src/vacuum.c b8546f4921719458cc537b9e736df52a8256399c
F src/vdbe.c 4629151c9995b8b6a895c42de8808df1969bdcc7
F src/vdbe.h 75b241c02431b9c0f16eaa9cdbb34146c6287f52
F src/vdbeInt.h d83fd7389838453d8392915c21f432014afc99cf
F src/vdbeapi.c ba3722f45db3d3c3509bf5d24f4f868f4c64449d
F src/vdbeaux.c f9b1b3d4d2f1c31f6db1ae1536e17e4eb5454205
F src/vdbeInt.h 7160653a006b6d2c4a00d204112a095bdf842ab6
F src/vdbeapi.c 7c3c3d818fad427881b65c51999d06bf393ebeaf
F src/vdbeaux.c f97b4b5e922fe74152e084bcea7b4468156bde50
F src/vdbemem.c 053f8adcb644bca1c1e4ad08f4016cb7ee6bf1b8
F src/where.c 6507074d8ce3f78e7a4cd33f667f11e62020553e
F test/all.test 3b692eb43583b52c99c344b2fa8934512d179016
@ -147,6 +147,7 @@ F test/printf.test 5ed2e033a0b47f901764096bf1907915d6e39406
F test/progress.test 76c722f090b1ccb575e7e4e203a71608c5763beb x
F test/quick.test bbe4abf7f434d71c0de26626c8cbb4858e1bcb18
F test/quote.test 08f23385c685d3dc7914ec760d492cacea7f6e3d
F test/rollback.test 4097328d44510277244ef4fa51b22b2f11d7ef4c
F test/rowid.test b3d059f5c8d8874fa1c31030e0636f67405d20ea
F test/select1.test 813a270ac7996b31ff228e8109cd2d1e8c3fa255
F test/select2.test 91a2225926039b0d1687840735c284dbbf89f0bc
@ -232,7 +233,7 @@ F www/tclsqlite.tcl 19191cf2a1010eaeff74c51d83fd5f5a4d899075
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
F www/version3.tcl 563ba3ac02f64da27ab17f3edbe8e56bfd0293fb
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
P 152e9940b919a53fcd0da4091dbf75ab8ef15b38
R 7c0d14b9c00314801ef156d50cb14232
U danielk1977
Z 744e63435b1a53bb66bf937c6227be06
P 4077f9a30b0c30a8749a596031aa4f7adc3a4891
R c74b8042375ac1ecced768631e1e7c90
U drh
Z bbd3e84a33ffc460275952232aa91883

View File

@ -1 +1 @@
4077f9a30b0c30a8749a596031aa4f7adc3a4891
0fedf74e30026afe2c8caacff3d62cf5c1b1f528

View File

@ -342,8 +342,9 @@ struct Vdbe {
u8 resOnStack; /* True if there are result values on the stack */
u8 explain; /* True if EXPLAIN present on SQL command */
u8 autoCommitOn; /* True if autocommit got turned on by this program */
int nChange; /* Number of db changes made since last reset */
u8 changeCntOn; /* True to update the change-counter */
u8 aborted; /* True if ROLLBACK in another VM causes an abort */
int nChange; /* Number of db changes made since last reset */
};
/*

View File

@ -149,6 +149,9 @@ int sqlite3_step(sqlite3_stmt *pStmt){
if( p->magic!=VDBE_MAGIC_RUN ){
return SQLITE_MISUSE;
}
if( p->aborted ){
return SQLITE_ABORT;
}
db = p->db;
if( sqlite3SafetyOn(db) ){
p->rc = SQLITE_MISUSE;

View File

@ -1090,6 +1090,20 @@ static int vdbeCommit(sqlite *db){
return rc;
}
/*
** Find every active VM other than pVdbe and change its status to
** aborted. This happens when on VM causes a rollback.
*/
static void abortOtherActiveVdbes(Vdbe *pVdbe){
Vdbe *pOther;
for(pOther=pVdbe->db->pVdbe; pOther; pOther=pOther->pNext){
if( pOther==pVdbe ) continue;
if( pOther->magic!=VDBE_MAGIC_RUN || pOther->pc<0 ) continue;
closeAllCursors(pOther);
pOther->aborted = 1;
}
}
/*
** This routine checks that the sqlite3.activeVdbeCnt count variable
** matches the number of vdbe's in the list sqlite3.pVdbe that are
@ -1183,6 +1197,7 @@ int sqlite3VdbeReset(Vdbe *p){
}else{
xFunc = sqlite3BtreeRollback;
db->autoCommit = 1;
abortOtherActiveVdbes(p);
}
}
p->autoCommitOn = 0;
@ -1245,6 +1260,7 @@ int sqlite3VdbeReset(Vdbe *p){
}
#endif
p->magic = VDBE_MAGIC_INIT;
p->aborted = 0;
return p->rc;
}

78
test/rollback.test Normal file
View File

@ -0,0 +1,78 @@
# 2004 June 30
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. The
# focus of this file is verifying that a rollback in one statement
# caused by an ON CONFLICT ROLLBACK clause aborts any other pending
# statements.
#
# $Id: rollback.test,v 1.1 2004/06/30 11:14:19 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
db close
set DB [sqlite3 db test.db]
do_test rollback-1.1 {
execsql {
CREATE TABLE t1(a);
INSERT INTO t1 VALUES(1);
INSERT INTO t1 VALUES(2);
INSERT INTO t1 VALUES(3);
INSERT INTO t1 VALUES(4);
SELECT * FROM t1;
}
} {1 2 3 4}
do_test rollback-1.2 {
execsql {
CREATE TABLE t3(a unique on conflict rollback);
INSERT INTO t3 SELECT a FROM t1;
BEGIN;
INSERT INTO t1 SELECT * FROM t1;
}
} {}
do_test rollback-1.3 {
set STMT [sqlite3_prepare $DB "SELECT a FROM t1" -1 TAIL]
sqlite3_step $STMT
} {SQLITE_ROW}
# This causes a ROLLBACK, which deletes the table out from underneath the
# SELECT statement.
#
do_test rollback-1.4 {
catchsql {
INSERT INTO t3 SELECT a FROM t1;
}
} {1 {column a is not unique}}
# Try to continue with the SELECT statement
#
do_test rollback-1.5 {
sqlite3_step $STMT
} {SQLITE_ABORT}
# Restart the SELECT statement
#
do_test rollback-1.6 {
sqlite3_reset $STMT
} {}
do_test rollback-1.7 {
sqlite3_step $STMT
} {SQLITE_ROW}
do_test rollback-1.8 {
sqlite3_step $STMT
} {SQLITE_ROW}
do_test rollback-1.9 {
sqlite3_finalize $STMT
} {SQLITE_OK}
finish_test