Add some tests for overlapping SELECT, COMMIT and ROLLBACK commands. (CVS 1774)

FossilOrigin-Name: d256c14943968e7adf4b73988cac6af941c9b12d
This commit is contained in:
danielk1977 2004-06-30 06:30:25 +00:00
parent 9d213ef022
commit 46c43edd39
6 changed files with 212 additions and 32 deletions

View File

@ -1,5 +1,5 @@
C Improve\stest\scoverage\sof\sutil.c\s(CVS\s1773)
D 2004-06-30T04:02:12
C Add\ssome\stests\sfor\soverlapping\sSELECT,\sCOMMIT\sand\sROLLBACK\scommands.\s(CVS\s1774)
D 2004-06-30T06:30:26
F Makefile.in cb7a9889c38723f72b2506c4236ff30a05ff172b
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@ -72,8 +72,8 @@ F src/trigger.c 6aaf6d79cc2157c70a06031dd1531707d644cfb4
F src/update.c b66b1896c9da54678ba3eff2bf0b4d291a95986a
F src/utf.c f03535db72bfa09e24202ccdd245f21d2fc65f0a
F src/util.c b267d0fe10cffa3301fe9fab6592a6808a38bce6
F src/vacuum.c 353c7f69dbeb6738434d81798465cc0698844640
F src/vdbe.c 32039b08701f1c19fcd9b684366cefaa8fabaa72
F src/vacuum.c 4aede0a7048d8b71a43f45cc15359e16eddc8a2e
F src/vdbe.c 6950e25d93346b03404d2fc383883ff9fa2e5966
F src/vdbe.h 75b241c02431b9c0f16eaa9cdbb34146c6287f52
F src/vdbeInt.h d83fd7389838453d8392915c21f432014afc99cf
F src/vdbeapi.c ba3722f45db3d3c3509bf5d24f4f868f4c64449d
@ -95,8 +95,8 @@ F test/btree4.test 3797b4305694c7af6828675b0f4b1424b8ca30e4
F test/btree5.test 8e5ff32c02e685d36516c6499add9375fe1377f2
F test/btree6.test a5ede6bfbbb2ec8b27e62813612c0f28e8f3e027
F test/btree7.test 429b96cfef5b51a7d512cfb4b5b3e453384af293
F test/capi2.test fe61f341e953f73c29bacfcbdaf688cd7b0e0d38
F test/capi3.test 3a7f759ce26a300ecdd288be901fcb0727f8773a
F test/capi2.test 78f2c486689fcc80394a24c2cc32725330ab6299
F test/capi3.test 85c4445cd9bd1fa0cd9d8af56a4fae361b57c553
F test/collate1.test 2ee4fa3a47a652ccf56c5ddf65dcc44d9bad82ef
F test/collate2.test c1a3b41f761b28853c5696037f92de928f93233b
F test/collate3.test e60b428e07ec945492ba90ff1c895902ee3a8a50
@ -232,7 +232,7 @@ F www/tclsqlite.tcl 19191cf2a1010eaeff74c51d83fd5f5a4d899075
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
F www/version3.tcl 563ba3ac02f64da27ab17f3edbe8e56bfd0293fb
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
P 0c999f28137bd82ba24dd263bab30d22329eed73
R aac9bef2959b49a3b21126dff36eb51a
U drh
Z d9d34e7eed57c4c6a384e0a609787172
P 68ac32213766c5e83de54373b90030a458538017
R 744bf93dd2f36513077a290ed8b8aa9f
U danielk1977
Z aa9871afb1977e06c76a2d6bc3030445

View File

@ -1 +1 @@
68ac32213766c5e83de54373b90030a458538017
d256c14943968e7adf4b73988cac6af941c9b12d

View File

@ -14,7 +14,7 @@
** Most of the code in this file may be omitted by defining the
** SQLITE_OMIT_VACUUM macro.
**
** $Id: vacuum.c,v 1.24 2004/06/26 08:38:25 danielk1977 Exp $
** $Id: vacuum.c,v 1.25 2004/06/30 06:30:26 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@ -97,9 +97,7 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite *db){
char *zTemp = 0; /* a temporary file in same directory as zFilename */
int i; /* Loop counter */
Btree *pTemp;
char *zSql = 0;
sqlite3_stmt *pStmt = 0;
if( !db->autoCommit ){
sqlite3SetString(pzErrMsg, "cannot VACUUM from within a transaction",
@ -129,8 +127,16 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite *db){
if( !sqlite3OsFileExists(zTemp) ) break;
}
/* Attach the temporary database as 'vacuum' */
/* Attach the temporary database as 'vacuum_db'. The synchronous pragma
** can be set to 'off' for this file, as it is not recovered if a crash
** occurs anyway. The integrity of the database is maintained by a
** (possibly synchronous) transaction opened on the main database before
** sqlite3BtreeCopyFile() is called.
**
** An optimisation would be to use a non-journaled pager.
*/
zSql = sqlite3MPrintf("ATTACH '%s' AS vacuum_db;", zTemp);
execSql(db, "PRAGMA vacuum_db.synchronous = off;");
if( !zSql ){
rc = SQLITE_NOMEM;
goto end_of_vacuum;
@ -217,14 +223,20 @@ int sqlite3RunVacuum(char **pzErrMsg, sqlite *db){
}
end_of_vacuum:
execSql(db, "ROLLBACK;");
/* Currently there is an SQL level transaction open on the vacuum
** database. No locks are held on any other files (since the main file
** was committed at the btree level). So it safe to end the transaction
** by manually setting the autoCommit flag to true and detaching the
** vacuum database. The vacuum_db journal file is deleted when the pager
** is closed by the DETACH.
*/
db->autoCommit = 1;
execSql(db, "DETACH vacuum_db;");
if( zTemp ){
sqlite3OsDelete(zTemp);
sqliteFree(zTemp);
}
if( zSql ) sqliteFree( zSql );
if( pStmt ) sqlite3_finalize( pStmt );
#endif
return rc;
}

View File

@ -43,7 +43,7 @@
** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.396 2004/06/30 02:43:38 danielk1977 Exp $
** $Id: vdbe.c,v 1.397 2004/06/30 06:30:26 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
@ -2212,7 +2212,8 @@ case OP_Statement: {
/* Opcode: AutoCommit P1 P2 *
**
** Set the database auto-commit flag to P1 (1 or 0). If P2 is true, roll
** back any currently active btree transactions.
** back any currently active btree transactions. If there are any active
** VMs (apart from this one), then the COMMIT or ROLLBACK statement fails.
*/
case OP_AutoCommit: {
u8 i = pOp->p1;
@ -2221,7 +2222,17 @@ case OP_AutoCommit: {
assert( i==1 || i==0 );
assert( i==1 || rollback==0 );
if( i!=db->autoCommit ){
assert( db->activeVdbeCnt>0 );
if( db->activeVdbeCnt>1 && i && !db->autoCommit ){
/* If this instruction implements a COMMIT or ROLLBACK, other VMs are
** still running, and a transaction is active, return an error indicating
** that the other VMs must complete first.
*/
sqlite3SetString(&p->zErrMsg, "cannot ", rollback?"rollback":"commit",
" transaction - SQL statements in progress", 0);
rc = SQLITE_ERROR;
}else if( i!=db->autoCommit ){
db->autoCommit = i;
p->autoCommitOn |= i;
if( pOp->p2 ){

View File

@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The
# focus of this script testing the callback-free C/C++ API.
#
# $Id: capi2.test,v 1.17 2004/06/26 09:50:12 danielk1977 Exp $
# $Id: capi2.test,v 1.18 2004/06/30 06:30:26 danielk1977 Exp $
#
set testdir [file dirname $argv0]
@ -484,18 +484,18 @@ do_test capi2-6.20 {
[get_row_values $VM1] \
[get_column_names $VM1]
} {SQLITE_ROW 1 9 {x counter}}
do_test capi2-6.21 {
execsql {ROLLBACK; SELECT * FROM t1}
} {1 2 3}
#do_test capi2-6.21 {
# execsql {ROLLBACK; SELECT * FROM t1}
#} {1 2 3}
do_test capi2-6.22 {
list [sqlite3_step $VM1] \
[sqlite3_column_count $VM1] \
[get_row_values $VM1] \
[get_column_names $VM1]
} {SQLITE_ROW 1 10 {x counter}}
do_test capi2-6.23 {
execsql {BEGIN TRANSACTION;}
} {}
#do_test capi2-6.23 {
# execsql {BEGIN TRANSACTION;}
#} {}
do_test capi2-6.24 {
list [sqlite3_step $VM1] \
[sqlite3_column_count $VM1] \
@ -507,7 +507,7 @@ do_test capi2-6.25 {
INSERT INTO t1 VALUES(2,3,4);
SELECT * FROM t1;
}
} {1 2 3 2 3 4}
} {1 3 3 2 3 4}
do_test capi2-6.26 {
list [sqlite3_step $VM1] \
[sqlite3_column_count $VM1] \

View File

@ -11,7 +11,7 @@
# This file implements regression tests for SQLite library. The
# focus of this script testing the callback-free C/C++ API.
#
# $Id: capi3.test,v 1.18 2004/06/30 02:35:51 danielk1977 Exp $
# $Id: capi3.test,v 1.19 2004/06/30 06:30:26 danielk1977 Exp $
#
set testdir [file dirname $argv0]
@ -498,7 +498,7 @@ do_test capi3-8.2 {
# Build a 5-field row record consisting of 5 null records. This is
# officially black magic.
unset data
catch {unset data}
set data [binary format c6 {6 0 0 0 0 0}]
btree_insert $::bc 5 $data
@ -601,7 +601,164 @@ db close
sqlite_malloc_fail 0
}
# The following tests - capi3-11.* - test that a COMMIT or ROLLBACK
# statement issued while there are still outstanding VMs that are part of
# the transaction fails.
set DB [sqlite3 db test.db]
sqlite_register_test_function $DB func
do_test capi3-11.1 {
execsql {
BEGIN;
CREATE TABLE t1(a, b);
INSERT INTO t1 VALUES(1, 'int');
INSERT INTO t1 VALUES(2, 'notatype');
}
} {}
do_test capi3-11.2 {
set STMT [sqlite3_prepare $DB "SELECT func(b, a) FROM t1" -1 TAIL]
sqlite3_step $STMT
} {SQLITE_ROW}
do_test capi3-11.3 {
catchsql {
COMMIT;
}
} {1 {cannot commit transaction - SQL statements in progress}}
do_test capi3-11.4 {
sqlite3_step $STMT
} {SQLITE_ERROR}
do_test capi3-11.5 {
sqlite3_finalize $STMT
} {SQLITE_ERROR}
do_test capi3-11.6 {
catchsql {
SELECT * FROM t1;
}
} {0 {1 int 2 notatype}}
do_test capi3-11.7 {
catchsql {
COMMIT;
}
} {0 {}}
do_test capi3-11.8 {
execsql {
CREATE TABLE t2(a);
INSERT INTO t2 VALUES(1);
INSERT INTO t2 VALUES(2);
BEGIN;
INSERT INTO t2 VALUES(3);
}
} {}
do_test capi3-11.9 {
set STMT [sqlite3_prepare $DB "SELECT a FROM t2" -1 TAIL]
sqlite3_step $STMT
} {SQLITE_ROW}
do_test capi3-11.3 {
catchsql {
ROLLBACK;
}
} {1 {cannot rollback transaction - SQL statements in progress}}
do_test capi3-11.10 {
sqlite3_step $STMT
} {SQLITE_ROW}
do_test capi3-11.11 {
sqlite3_step $STMT
} {SQLITE_ROW}
do_test capi3-11.12 {
sqlite3_step $STMT
} {SQLITE_DONE}
do_test capi3-11.13 {
sqlite3_finalize $STMT
} {SQLITE_OK}
do_test capi3-11.14 {
execsql {
SELECT a FROM t2;
}
} {1 2 3}
do_test capi3-11.15 {
catchsql {
ROLLBACK;
}
} {0 {}}
do_test capi3-11.16 {
execsql {
SELECT a FROM t2;
}
} {1 2}
# Sanity check on the definition of 'outstanding VM'. This means any VM
# that has had sqlite3_step() called more recently than sqlite3_finalize() or
# sqlite3_reset(). So a VM that has just been prepared or reset does not
# count as an active VM.
do_test capi3-11.17 {
execsql {
BEGIN;
}
} {}
do_test capi3-11.18 {
set STMT [sqlite3_prepare $DB "SELECT a FROM t1" -1 TAIL]
catchsql {
COMMIT;
}
} {0 {}}
do_test capi3-11.19 {
sqlite3_step $STMT
} {SQLITE_ROW}
do_test capi3-11.20 {
catchsql {
BEGIN;
COMMIT;
}
} {1 {cannot commit transaction - SQL statements in progress}}
do_test capi3-11.20 {
sqlite3_reset $STMT
catchsql {
COMMIT;
}
} {0 {}}
do_test capi3-11.21 {
sqlite3_finalize $STMT
} {SQLITE_OK}
# The following tests - capi3-12.* - check that it's Ok to start a
# transaction while other VMs are active, and that it's Ok to execute
# atomic updates in the same situation (so long as they are on a different
# table).
do_test capi3-12.1 {
set STMT [sqlite3_prepare $DB "SELECT a FROM t2" -1 TAIL]
sqlite3_step $STMT
} {SQLITE_ROW}
do_test capi3-12.2 {
catchsql {
INSERT INTO t1 VALUES(3, NULL);
}
} {0 {}}
do_test capi3-12.3 {
catchsql {
INSERT INTO t2 VALUES(4);
}
} {1 {database table is locked}}
do_test capi3-12.4 {
catchsql {
BEGIN;
INSERT INTO t1 VALUES(4, NULL);
}
} {0 {}}
do_test capi3-12.5 {
sqlite3_step $STMT
} {SQLITE_ROW}
do_test capi3-12.6 {
sqlite3_step $STMT
} {SQLITE_DONE}
do_test capi3-12.7 {
sqlite3_finalize $STMT
} {SQLITE_OK}
do_test capi3-12.8 {
execsql {
COMMIT;
SELECT a FROM t1;
}
} {1 2 3 4}
finish_test