Add some tests for overlapping SELECT, COMMIT and ROLLBACK commands. (CVS 1774)
FossilOrigin-Name: d256c14943968e7adf4b73988cac6af941c9b12d
This commit is contained in:
parent
9d213ef022
commit
46c43edd39
20
manifest
20
manifest
@ -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
|
||||
|
@ -1 +1 @@
|
||||
68ac32213766c5e83de54373b90030a458538017
|
||||
d256c14943968e7adf4b73988cac6af941c9b12d
|
24
src/vacuum.c
24
src/vacuum.c
@ -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;
|
||||
}
|
||||
|
17
src/vdbe.c
17
src/vdbe.c
@ -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 ){
|
||||
|
@ -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] \
|
||||
|
165
test/capi3.test
165
test/capi3.test
@ -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
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user