-C Work\saround\sa\sbug\sin\sthe\sBorland\sC++\scompiler.\s\sTicket\s#881.\s(CVS\s1927)
-D 2004-09-01T16:12:25
+C Transactions\scommit\son\sthe\slast\ssqlite3_step(),\snot\son\ssqlite3_finalize().\nThis\sallows\sthe\ssqlite3_step()\sto\sreturn\sSQLITE_BUSY\sif\sthe\scommit\sis\nblocked\sby\sa\slock.\s\sTicket\s#885.\s(CVS\s1928)
+D 2004-09-02T14:57:08
F Makefile.in 65a7c43fcaf9a710d62f120b11b6e435eeb4a450
F Makefile.linux-gcc a9e5a0d309fa7c38e7c14d3ecf7690879d3a5457
F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
F src/insert.c fc1ce65a0fe68f226143de9b43c3582164a92aff
F src/legacy.c 2f3617c61bcdcd1d776154a9cfebf99facda8ad8
-F src/main.c b92d44c72298d31e08700b1483ef8827468dac9f
+F src/main.c c42b3c1c9e0e401a490ed8f8ce789eb7302a9b69
F src/md5.c 7ae1c39044b95de2f62e066f47bb1deb880a1070
F src/os.h d1780e0db95cad01f213d48da22ab490eb4fd345
F src/os_common.h cd7eb025fdab7dc91e0e97bf6310f1648205857f
F src/os_unix.h f3097815e041e82e24d92505e1ff61ba24172d13
F src/os_win.c 9e2887825b1a32f0ceb1b73b93ffe29a112cd86f
F src/os_win.h babd4e912967c6b09088cfe38a45e8005a07ba44
-F src/pager.c 616563dc510993ab67baa54fc6a2ddacc05175ca
+F src/pager.c ae06c85de0db43f61a7a3e5eacad3fd5615daf59
F src/pager.h 67739fe649f33be55dba522ca8a9cc4e42d14f71
F src/parse.y 581a2ce014b843506805b2470c02b7865ad034d5
F src/pragma.c b39177b96bb5f7354511468c933357ce65a0dd4c
F src/utf.c 328890099db492dda5620ee5f924e244c6e57ff7
F src/util.c d5aaf211543fb6e285654fada50252c857ac78aa
F src/vacuum.c 9978a5760c2c430bc5b5e66505a02dad76f25813
-F src/vdbe.c 28b0ea2a8c534fc39e15e41db0437fcc3b5f2e9b
+F src/vdbe.c 45f659497b479f001c2f4e8251474aba3975b9f8
F src/vdbe.h e081c72cd0f7c19d49b1927460aeefcf0fbc85ac
-F src/vdbeInt.h aadadddc8cfad6aa5a5445c849f70d881276fe34
+F src/vdbeInt.h f8df57a9dc272967991f806e612628e0aa57e705
F src/vdbeapi.c 854732720c2cfc6ff76b28eef6253ac84a5408bc
-F src/vdbeaux.c 022c484dba235d2dcbb1faca0f1943702f4232ed
+F src/vdbeaux.c 77eaaf62b8b3acad4a2ef351e3c44ecffc67faf6
F src/vdbemem.c ef9ac7d32acfe4bce5c5b408b1294c8d9e0cdb56
F src/where.c a84eee276cd072158224da6b5f30733df2d56027
F test/all.test 929bfa932b55e75c96fe2203f7650ba451c1862c
F test/attach.test feb2ce54e78688df4c84553416d5aec3b2a0112e
-F test/attach2.test 9be9656bc1e929b224861960299920c76d45b14d
+F test/attach2.test 32ca2c1a5a347a7404219a11f9f84739a63d2582
F test/attach3.test 6d060986ff004ebb89e1876a331d96c6bb62269e
F test/auth.test e74b015545f608c06d5b84d17acdf7146eb818af
F test/bigfile.test 62722ac4b420dfbcdceb137b8634e2cf2865fe27
F test/btree5.test 8e5ff32c02e685d36516c6499add9375fe1377f2
F test/btree6.test a5ede6bfbbb2ec8b27e62813612c0f28e8f3e027
F test/btree7.test 429b96cfef5b51a7d512cfb4b5b3e453384af293
-F test/capi2.test 78f2c486689fcc80394a24c2cc32725330ab6299
-F test/capi3.test e2d47b59c1ca5be2e5986fb77f716a7fdd228e25
+F test/capi2.test 53e3f399074d5654f26d55b32ccaca7b5b619933
+F test/capi3.test 9258ca75fc98d89477015dcd70aa3d2757b142b8
+F test/capi3b.test 458044d8c250c129ddfd77c6265a6923bc008b5e
F test/collate1.test f79736d2ebf5492167ee4d1f4ab4c09dda776b03
F test/collate2.test c1a3b41f761b28853c5696037f92de928f93233b
F test/collate3.test e60b428e07ec945492ba90ff1c895902ee3a8a50
F test/pragma.test 66a66b7f3b273b93325c9a5794acb418f52fdcbf
F test/printf.test 5a30fb0d736148fca64cb1b7ed0390be7414e024
F test/progress.test 76c722f090b1ccb575e7e4e203a71608c5763beb x
-F test/quick.test 2e9af7203555ea894af654adf0794157434928fb
+F test/quick.test 212a9cd4c40c72c7c4780fef1c2fbe5d1cb34ce6
F test/quote.test 6d75cf635d93ba2484dc9cb378d88cbae9dc2c62
F test/rollback.test 4097328d44510277244ef4fa51b22b2f11d7ef4c
F test/rowid.test b3d059f5c8d8874fa1c31030e0636f67405d20ea
F www/vdbe.tcl 59288db1ac5c0616296b26dce071c36cb611dfe9
F www/version3.tcl 092a01f5ef430d2c4acc0ae558d74c4bb89638a0
F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P 9c411c3c8dde2061c98513a413ef58c5c2de45af
-R 54ca511e52d24afac36ea482ae4bc8ec
+P 18af6ba580a5ad50a20955bfe2ebce8e30b1d39e
+R 8124409cd5ad134f1cc0a6f820ab9a66
U drh
-Z 888aa66dde2c6dec44c62c3082b0fba4
+Z 68ff020543a01eac2435ebdc5d559c02
-18af6ba580a5ad50a20955bfe2ebce8e30b1d39e
\ No newline at end of file
+d1b29156558f1c576002cdb2544dffaa693da39b
\ No newline at end of file
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
-** $Id: main.c,v 1.256 2004/08/29 20:08:59 drh Exp $
+** $Id: main.c,v 1.257 2004/09/02 14:57:08 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
}
}
sqlite3ResetInternalSchema(db, 0);
- /* sqlite3RollbackInternalChanges(db); */
}
/*
** Make a copy of that part of the SQL string since zSQL is const
** and we must pass a zero terminated string to the trace function
** The copy is unnecessary if the tail pointer is pointing at the
- ** beginnig or end of the SQL string.
+ ** beginning or end of the SQL string.
*/
if( sParse.zTail && sParse.zTail!=zSql && *sParse.zTail ){
char *tmpSql = sqliteStrNDup(zSql, sParse.zTail - zSql);
** file simultaneously, or one process from reading the database while
** another is writing.
**
-** @(#) $Id: pager.c,v 1.161 2004/08/30 16:52:18 drh Exp $
+** @(#) $Id: pager.c,v 1.162 2004/09/02 14:57:08 drh Exp $
*/
#include "os.h" /* Must be first to enable large file support */
#include "sqliteInt.h"
/* Jump here if anything goes wrong during the commit process.
*/
commit_abort:
- rc = sqlite3pager_rollback(pPager);
- if( rc==SQLITE_OK ){
- rc = SQLITE_FULL;
- }
+ sqlite3pager_rollback(pPager);
return rc;
}
** 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.412 2004/08/31 13:45:12 drh Exp $
+** $Id: vdbe.c,v 1.413 2004/09/02 14:57:09 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
** Exit immediately. All open cursors, Lists, Sorts, etc are closed
** automatically.
**
-** P1 is the result code returned by sqlite3_exec(). For a normal
-** halt, this should be SQLITE_OK (0). For errors, it can be some
-** other value. If P1!=0 then P2 will determine whether or not to
-** rollback the current transaction. Do not rollback if P2==OE_Fail.
-** Do the rollback if P2==OE_Rollback. If P2==OE_Abort, then back
-** out all changes that have occurred during this execution of the
+** P1 is the result code returned by sqlite3_exec(), sqlite3_reset(),
+** or sqlite3_finalize(). For a normal halt, this should be SQLITE_OK (0).
+** For errors, it can be some other value. If P1!=0 then P2 will determine
+** whether or not to rollback the current transaction. Do not rollback
+** if P2==OE_Fail. Do the rollback if P2==OE_Rollback. If P2==OE_Abort,
+** then back out all changes that have occurred during this execution of the
** VDBE, but do not rollback the transaction.
**
** There is an implied "Halt 0 0 0" instruction inserted at the very end of
** is the same as executing Halt.
*/
case OP_Halt: {
- p->magic = VDBE_MAGIC_HALT;
p->pTos = pTos;
- if( pOp->p1!=SQLITE_OK ){
- p->rc = pOp->p1;
- p->errorAction = pOp->p2;
+ p->rc = pOp->p1;
+ p->pc = pc;
+ p->errorAction = pOp->p2;
+ if( pOp->p3 ){
sqlite3SetString(&p->zErrMsg, pOp->p3, (char*)0);
- return SQLITE_ERROR;
- }else{
- p->rc = SQLITE_OK;
- return SQLITE_DONE;
}
+ rc = sqlite3VdbeHalt(p);
+ if( rc==SQLITE_BUSY ){
+ p->rc = SQLITE_BUSY;
+ return SQLITE_BUSY;
+ }else if( rc!=SQLITE_OK ){
+ p->rc = rc;
+ }
+ return p->rc ? SQLITE_ERROR : SQLITE_DONE;
}
/* Opcode: Integer P1 * P3
** Set the database auto-commit flag to P1 (1 or 0). If P2 is true, roll
** back any currently active btree transactions. If there are any active
** VMs (apart from this one), then the COMMIT or ROLLBACK statement fails.
+**
+** This instruction causes the VM to halt.
*/
case OP_AutoCommit: {
u8 i = pOp->p1;
assert( i==1 || i==0 );
assert( i==1 || rollback==0 );
- assert( db->activeVdbeCnt>0 );
+ assert( db->activeVdbeCnt>0 ); /* At least this one VM is active */
if( db->activeVdbeCnt>1 && i && !db->autoCommit ){
/* If this instruction implements a COMMIT or ROLLBACK, other VMs are
rc = SQLITE_ERROR;
}else if( i!=db->autoCommit ){
db->autoCommit = i;
- p->autoCommitOn |= i;
if( pOp->p2 ){
+ assert( i==1 );
sqlite3RollbackAll(db);
+ }else if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
+ p->pTos = pTos;
+ p->pc = pc;
+ db->autoCommit = 1-i;
+ p->rc = SQLITE_BUSY;
+ return SQLITE_BUSY;
}
+ return SQLITE_DONE;
}else{
sqlite3SetString(&p->zErrMsg,
(!i)?"cannot start a transaction within a transaction":(
}else{
rc = SQLITE_DONE;
}
- p->magic = VDBE_MAGIC_HALT;
+ sqlite3VdbeHalt(p);
p->pTos = pTos;
return rc;
char *zErrMsg; /* Error message written here */
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 */
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 */
int sqlite3VdbeIdxRowidLen(int,const u8*);
int sqlite3VdbeExec(Vdbe*);
int sqlite3VdbeList(Vdbe*);
+int sqlite3VdbeHalt(Vdbe*);
int sqlite3VdbeChangeEncoding(Mem *, int);
int sqlite3VdbeMemCopy(Mem*, const Mem*);
void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int);
** as allocating stack space and initializing the program counter.
** After the VDBE has be prepped, it can be executed by one or more
** calls to sqlite3VdbeExec().
+**
+** This is the only way to move a VDBE from VDBE_MAGIC_INIT to
+** VDBE_MAGIC_RUN.
*/
void sqlite3VdbeMakeReady(
Vdbe *p, /* The VDBE */
/* If there are any write-transactions at all, invoke the commit hook */
if( needXcommit && db->xCommitCallback ){
- if( db->xCommitCallback(db->pCommitArg) ){
+ int rc;
+ sqlite3SafetyOff(db);
+ rc = db->xCommitCallback(db->pCommitArg);
+ sqlite3SafetyOn(db);
+ if( rc ){
return SQLITE_CONSTRAINT;
}
}
** This routine checks that the sqlite3.activeVdbeCnt count variable
** matches the number of vdbe's in the list sqlite3.pVdbe that are
** currently active. An assertion fails if the two counts do not match.
+** This is an internal self-check only - it is not an essential processing
+** step.
**
** This is a no-op if NDEBUG is defined.
*/
static void checkActiveVdbeCnt(sqlite *db){
Vdbe *p;
int cnt = 0;
-
p = db->pVdbe;
while( p ){
- if( (p->magic==VDBE_MAGIC_RUN && p->pc>=0) || p->magic==VDBE_MAGIC_HALT ){
+ if( p->magic==VDBE_MAGIC_RUN && p->pc>=0 ){
cnt++;
}
p = p->pNext;
}
-
assert( cnt==db->activeVdbeCnt );
}
#else
#endif
/*
-** Clean up a VDBE after execution but do not delete the VDBE just yet.
-** Write any error messages into *pzErrMsg. Return the result code.
+** This routine is called the when a VDBE tries to halt. If the VDBE
+** has made changes and is in autocommit mode, then commit those
+** changes. If a rollback is needed, then do the rollback.
**
-** After this routine is run, the VDBE should be ready to be executed
-** again.
+** This routine is the only way to move the state of a VM from
+** SQLITE_MAGIC_RUN to SQLITE_MAGIC_HALT.
+**
+** Return an error code. If the commit could not complete because of
+** lock contention, return SQLITE_BUSY. If SQLITE_BUSY is returned, it
+** means the close did not happen and needs to be repeated.
*/
-int sqlite3VdbeReset(Vdbe *p){
+int sqlite3VdbeHalt(Vdbe *p){
sqlite *db = p->db;
int i;
int (*xFunc)(Btree *pBt) = 0; /* Function to call on each btree backend */
- if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){
- sqlite3Error(p->db, SQLITE_MISUSE, 0 ,0);
- return SQLITE_MISUSE;
- }
- if( p->zErrMsg ){
- sqlite3Error(p->db, p->rc, "%s", p->zErrMsg, 0);
- sqliteFree(p->zErrMsg);
- p->zErrMsg = 0;
- }else if( p->rc ){
- sqlite3Error(p->db, p->rc, 0);
- }else{
- sqlite3Error(p->db, SQLITE_OK, 0);
+ if( p->magic!=VDBE_MAGIC_RUN ){
+ /* Already halted. Nothing to do. */
+ assert( p->magic==VDBE_MAGIC_HALT );
+ return SQLITE_OK;
}
- Cleanup(p);
-
- /* What is done now depends on the exit status of the vdbe, the value of
- ** the sqlite.autoCommit flag and whether or not there are any other
- ** queries in progress. A transaction or statement transaction may need
- ** to be committed or rolled back on each open database file.
- */
+ closeAllCursors(p);
checkActiveVdbeCnt(db);
if( db->autoCommit && db->activeVdbeCnt==1 ){
if( p->rc==SQLITE_OK || p->errorAction==OE_Fail ){
/* The auto-commit flag is true, there are no other active queries
** using this handle and the vdbe program was successful or hit an
- ** 'OR FAIL' constraint. This means a commit is required, which is
- ** handled a little differently from the other options.
+ ** 'OR FAIL' constraint. This means a commit is required.
*/
- p->rc = vdbeCommit(db);
- if( p->rc!=SQLITE_OK ){
- sqlite3Error(p->db, p->rc, 0);
- if( p->rc==SQLITE_BUSY && p->autoCommitOn ){
- /* If we just now have turned autocommit on (meaning we just have
- ** finished executing a COMMIT command) but the commit fails due
- ** to lock contention, autocommit back off. This gives the user
- ** the opportunity to try again after the lock that was preventing
- ** the commit has cleared. */
- db->autoCommit = 0;
- }else{
- /* If the command just executed was not a COMMIT command, then
- ** rollback whatever the results of that command were */
- xFunc = sqlite3BtreeRollback;
- }
+ int rc = vdbeCommit(db);
+ if( rc==SQLITE_BUSY ){
+ return SQLITE_BUSY;
+ }else if( rc!=SQLITE_OK ){
+ p->rc = rc;
+ xFunc = sqlite3BtreeRollback;
}
}else{
xFunc = sqlite3BtreeRollback;
abortOtherActiveVdbes(p);
}
}
- p->autoCommitOn = 0;
/* If xFunc is not NULL, then it is one of sqlite3BtreeRollback,
** sqlite3BtreeRollbackStmt or sqlite3BtreeCommitStmt. Call it once on
p->nChange = 0;
}
+ /* Rollback or commit any schema changes that occurred. */
if( p->rc!=SQLITE_OK ){
sqlite3RollbackInternalChanges(db);
}else if( db->flags & SQLITE_InternChanges ){
sqlite3CommitInternalChanges(db);
}
- if( (p->magic==VDBE_MAGIC_RUN && p->pc>=0) || p->magic==VDBE_MAGIC_HALT ){
+ /* We have successfully halted and closed the VM. Record this fact. */
+ if( p->pc>=0 ){
db->activeVdbeCnt--;
}
+ p->magic = VDBE_MAGIC_HALT;
+ checkActiveVdbeCnt(db);
+
+ return SQLITE_OK;
+}
+
+/*
+** Clean up a VDBE after execution but do not delete the VDBE just yet.
+** Write any error messages into *pzErrMsg. Return the result code.
+**
+** After this routine is run, the VDBE should be ready to be executed
+** again.
+**
+** To look at it another way, this routine resets the state of the
+** virtual machine from VDBE_MAGIC_RUN or VDBE_MAGIC_HALT back to
+** VDBE_MAGIC_INIT.
+*/
+int sqlite3VdbeReset(Vdbe *p){
+ if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){
+ sqlite3Error(p->db, SQLITE_MISUSE, 0 ,0);
+ return SQLITE_MISUSE;
+ }
+ /* If the VM did not run to completion or if it encountered an
+ ** error, then it might not have been halted properly. So halt
+ ** it now.
+ */
+ sqlite3VdbeHalt(p);
+
+ /* Transfer the error code and error message from the VDBE into the
+ ** main database structure.
+ */
+ if( p->zErrMsg ){
+ sqlite3Error(p->db, p->rc, "%s", p->zErrMsg, 0);
+ sqliteFree(p->zErrMsg);
+ p->zErrMsg = 0;
+ }else if( p->rc ){
+ sqlite3Error(p->db, p->rc, 0);
+ }else{
+ sqlite3Error(p->db, SQLITE_OK, 0);
+ }
+
+ /* Reclaim all memory used by the VDBE
+ */
+ Cleanup(p);
+
+ /* Save profiling information from this VDBE run.
+ */
assert( p->pTos<&p->aStack[p->pc<0?0:p->pc] || sqlite3_malloc_failed==1 );
#ifdef VDBE_PROFILE
{
p->aborted = 0;
return p->rc;
}
-
+
/*
** Clean up and delete a VDBE after execution. Return an integer which is
** the result code. Write any error message text into *pzErrMsg.
# focus of this script is testing the ATTACH and DETACH commands
# and related functionality.
#
-# $Id: attach2.test,v 1.25 2004/08/18 16:05:20 drh Exp $
+# $Id: attach2.test,v 1.26 2004/09/02 14:57:09 drh Exp $
#
set testdir [file dirname $argv0]
lock_status 4.9.1 db {main shared temp closed file2 shared}
lock_status 4.9.2 db2 {main reserved temp closed file2 reserved}
-btree_breakpoint
do_test attach2-4.10 {
# We cannot commit db2 while db is holding a read-lock
catchsql {COMMIT} db2
lock_status 4.10.2 db2 {main pending temp closed file2 reserved}
set sqlite_os_trace 0
-btree_breakpoint
do_test attach2-4.11 {
# db is able to commit.
catchsql {COMMIT}
# 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.18 2004/06/30 06:30:26 danielk1977 Exp $
+# $Id: capi2.test,v 1.19 2004/09/02 14:57:09 drh Exp $
#
set testdir [file dirname $argv0]
# Update for v3 - the change has not actually happened until the query is
# finalized. Is this going to cause trouble for anyone? Lee Nelson maybe?
-do_test capi2-3.10b {db changes} {0}
+# (Later:) The change now happens just before SQLITE_DONE is returned.
+do_test capi2-3.10b {db changes} {1}
do_test capi2-3.11 {
sqlite3_finalize $VM
} {SQLITE_OK}
} {SQLITE_ERROR 0 {} {}}
# Update for v3: Preparing a statement does not affect the change counter.
-# (Test result changes from 0 to 1).
-do_test capi2-3.13b {db changes} {1}
+# (Test result changes from 0 to 1). (Later:) change counter updates occur
+# when sqlite3_step returns, not at finalize time.
+do_test capi2-3.13b {db changes} {0}
do_test capi2-3.14 {
list [sqlite3_finalize $VM] [sqlite3_errmsg $DB]
# 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.20 2004/07/22 15:02:26 drh Exp $
+# $Id: capi3.test,v 1.21 2004/09/02 14:57:09 drh Exp $
#
set testdir [file dirname $argv0]
btree_close_cursor $::bc
btree_commit $::bt
btree_close $::bt
- } {}
+ } {};
do_test capi3-8.5 {
db close
sqlite3 db test.db
--- /dev/null
+# 2004 September 2
+#
+# 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 script testing the callback-free C/C++ API and in
+# particular the behavior of sqlite3_step() when trying to commit
+# with lock contention.
+#
+# $Id: capi3b.test,v 1.1 2004/09/02 14:57:09 drh Exp $
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+
+db close
+set DB [sqlite3 db test.db]
+set DB2 [sqlite3 db2 test.db]
+
+# Create some data in the database
+#
+do_test capi3b-1.1 {
+ execsql {
+ CREATE TABLE t1(x);
+ INSERT INTO t1 VALUES(1);
+ INSERT INTO t1 VALUES(2);
+ SELECT * FROM t1
+ }
+} {1 2}
+
+# Make sure the second database connection can see the data
+#
+do_test capi3b-1.2 {
+ execsql {
+ SELECT * FROM t1
+ } db2
+} {1 2}
+
+# First database connection acquires a shared lock
+#
+do_test capi3b-1.3 {
+ execsql {
+ BEGIN;
+ SELECT * FROM t1;
+ }
+} {1 2}
+
+# Second database connection tries to write. The sqlite3_step()
+# function returns SQLITE_BUSY because it cannot commit.
+#
+do_test capi3b-1.4 {
+ set VM [sqlite3_prepare $DB2 {INSERT INTO t1 VALUES(3)} -1 TAIL]
+ sqlite3_step $VM
+} SQLITE_BUSY
+
+# The sqlite3_step call can be repeated multiple times.
+#
+do_test capi3b-1.5.1 {
+ sqlite3_step $VM
+} SQLITE_BUSY
+do_test capi3b-1.5.2 {
+ sqlite3_step $VM
+} SQLITE_BUSY
+
+# The first connection closes its transaction. This allows the second
+# connections sqlite3_step to succeed.
+#
+do_test capi3b-1.6 {
+ execsql COMMIT
+ sqlite3_step $VM
+} SQLITE_DONE
+do_test capi3b-1.7 {
+ sqlite3_finalize $VM
+} SQLITE_OK
+do_test capi3b-1.8 {
+ execsql {SELECT * FROM t1} db2
+} {1 2 3}
+do_test capi3b-1.9 {
+ execsql {SELECT * FROM t1}
+} {1 2 3}
+
+catch {db2 close}
+finish_test
#***********************************************************************
# This file runs all tests.
#
-# $Id: quick.test,v 1.29 2004/08/30 16:52:19 drh Exp $
+# $Id: quick.test,v 1.30 2004/09/02 14:57:09 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set EXCLUDE {
all.test
btree2.test
+ btree3.test
+ btree4.test
+ btree5.test
+ btree6.test
corrupt.test
crash.test
malloc.test