-C Should\sbe\s'memjournal.lo'\sinstead\sof\s'memjournal.o'.\s\s\sTicket\s#3480.\s(CVS\s5863)
-D 2008-11-04T21:51:03
+C The\sCOMMIT\scommand\snow\sworks\seven\sif\sthere\sare\spending\squeries,\sas\slong\nas\sthe\spending\squeries\sare\sreading\sand\snot\swriting\sthe\sdatabase.\s(CVS\s5864)
+D 2008-11-05T16:37:35
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in 48172b58e444a9725ec482e0c022a564749acab4
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
F src/shell.c d83b578a8ccdd3e0e7fef4388a0887ce9f810967
F src/sqlite.h.in 2e1df3481504c85e3575e959685a8a748d1760c6
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
-F src/sqliteInt.h 926279c94cdf21e53fc66badb8541d94aed25018
+F src/sqliteInt.h e32c2dbd6d2e53c2a4d137ce977313a38df38f8a
F src/sqliteLimit.h f435e728c6b620ef7312814d660a81f9356eb5c8
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
F src/table.c 22744786199c9195720c15a7a42cb97b2e2728d8
F src/utf.c c63e6f69082f85c19ab88d62dedaf91d71ac1a50
F src/util.c afe659ccc05d1f8af9e8631dabfec3ee3a7144af
F src/vacuum.c fd77433d0c26d3ff1eb96eab017a1787ac5aa642
-F src/vdbe.c d2c9b71d0a996d87508ec841583ae50d23c9a3db
+F src/vdbe.c b6b989bbd0e306581695f8914c4246905a5c0d14
F src/vdbe.h 03516f28bf5aca00a53c4dccd6c313f96adb94f6
-F src/vdbeInt.h 1fd87002786828b75046dcfbc942cf97036b8433
-F src/vdbeapi.c 6798c70cf176d23594ec557db88190ca8c7fa860
-F src/vdbeaux.c 3c6ebfba16fdc58d868bfc5a2f95fae9417130a6
+F src/vdbeInt.h c9400778d6f801c2cb8ebe6151c909e19dd2d793
+F src/vdbeapi.c ea22e171704906632cd971668359b8c0c5053001
+F src/vdbeaux.c ec1ee5ac4c9aa3ac42c5e5c340960d29f3ec640e
F src/vdbeblob.c b0dcebfafedcf9c0addc7901ad98f6f986c08935
F src/vdbefifo.c 20fda2a7c4c0bcee1b90eb7e545fefcdbf2e1de7
F src/vdbemem.c c0e9d9947db8968762c7621369f821bb181c1c86
F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0
F test/cache.test 3ff445c445742a7b6b9ba6e1d62a25263f9424b9
F test/capi2.test 36f87803c811b5986dd31eb5492cb704552776b4
-F test/capi3.test 74089bd93dc5bbc9f80854b02a594aba0c730e9a
+F test/capi3.test 4d9c110e8c78fdfe0ea61171a17609e627630ca6
F test/capi3b.test 664eb55318132f292f2c436f90906f578cad6b97
-F test/capi3c.test db9310ac62766ab09b9282468f910ecd5b8014b8
+F test/capi3c.test ce0fcbbaccfc9703fb247ea9ac5ada96dc9ca047
F test/capi3d.test 57d83b690d7364bde02cddbf8339a4b50d80ce23
F test/cast.test ce8f14fc80f70b30ed984480cc0d8914a459e8f9
F test/check.test 024ed399600b799160378cf9d9f436bdf5dfd184
F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75
F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0
F test/in4.test c043f75147295e9f6ad5040a5cda2c485736c2c8
-F test/incrblob.test 4040ac885090f147345bedb89bf5e9b5eee1c1f0
+F test/incrblob.test 4b9437bbb38724343dadbbcca6356bc2a9b435d1
F test/incrblob2.test 5cca1c3cb29064c504b3b0cc3e2cd43e8053cfdf
F test/incrblob_err.test c577c91d4ed9e8336cdb188b15d6ee2a6fe9604e
F test/incrvacuum.test 9a6346c56ffa141024054ae7ba6c8655edf2d137
F test/tkt2920.test a8737380e4ae6424e00c0273dc12775704efbebf
F test/tkt2927.test 4752868b9eeeb07a217f7f19f4cbaac98d6d086d
F test/tkt2942.test c5c87d179799ca6d1fbe83c815510b87cd5ec7ce
-F test/tkt3080.test 31a02e87a4c80ed443831c2c5b0e8216ff95ac14
+F test/tkt3080.test 1bca7579260920a66b4dd7e196e807c0f25ff804
F test/tkt3093.test fbdbc5b4969244ad11f540759003e361fcaf391f
F test/tkt3121.test 536df66a02838c26a12fe98639354ca1290ca68b
F test/tkt3201.test 607d433ad2c1f6a8cb1af55aaca427f63c83191b
F test/trace.test 951cd0f5f571e7f36bf7bfe04be70f90fb16fb00
F test/trans.test 2fd24cd7aa0b879d49a224cbd647d698f1e7ac5c
F test/trans2.test d5337e61de45e66b1fcbf9db833fa8c82e624b22
-F test/trans3.test b084fce94d4c9957b01715cc9b6923c573562cdd
+F test/trans3.test d728abaa318ca364dc370e06576aa7e5fbed7e97
F test/trigger1.test 53342dfd582155a599518f1918fdc997e9413177
F test/trigger2.test 33bf8ae9b788013be194efe5f66c04a202facbb4
F test/trigger3.test 501b8489eb6b9cb5b005f60b071583c01a3c3041
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
-P f818e8e5cb20c51922d0b5424f17649e0692f273
-R 33a4e04827727d093ba82c38fb736d9a
-U shane
-Z 2d06f5434ad6fc28624fe3e64e613019
+P 8b868604217571cf2f60cdf46adb9721ca071bf9
+R d0a748defad0c6542a6b42006bda2301
+U drh
+Z 8362aa5d8251e71533ab4c0ad20b06f7
-8b868604217571cf2f60cdf46adb9721ca071bf9
\ No newline at end of file
+51f04aaff2803487933b9dfcf39f27a249f18a98
\ No newline at end of file
*************************************************************************
** Internal interface definitions for SQLite.
**
-** @(#) $Id: sqliteInt.h,v 1.787 2008/10/28 18:58:20 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.788 2008/11/05 16:37:35 drh Exp $
*/
#ifndef _SQLITEINT_H_
#define _SQLITEINT_H_
void **aExtension; /* Array of shared libraray handles */
struct Vdbe *pVdbe; /* List of active virtual machines */
int activeVdbeCnt; /* Number of vdbes currently executing */
+ int writeVdbeCnt; /* Number of active VDBEs that are writing */
void (*xTrace)(void*,const char*); /* Trace function */
void *pTraceArg; /* Argument to the trace function */
void (*xProfile)(void*,const char*,u64); /* Profiling function */
** 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.785 2008/11/03 20:55:07 drh Exp $
+** $Id: vdbe.c,v 1.786 2008/11/05 16:37:35 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
** This instruction causes the VM to halt.
*/
case OP_AutoCommit: {
- u8 i = pOp->p1;
- u8 rollback = pOp->p2;
+ int desiredAutoCommit = pOp->p1;
+ int rollback = pOp->p2;
+ int turnOnAC = desiredAutoCommit && !db->autoCommit;
- assert( i==1 || i==0 );
- assert( i==1 || rollback==0 );
+ assert( desiredAutoCommit==1 || desiredAutoCommit==0 );
+ assert( desiredAutoCommit==1 || rollback==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
+ if( turnOnAC && rollback && db->activeVdbeCnt>1 ){
+ /* If this instruction implements a ROLLBACK and other VMs are
** still running, and a transaction is active, return an error indicating
** that the other VMs must complete first.
*/
- sqlite3SetString(&p->zErrMsg, db, "cannot %s transaction - "
- "SQL statements in progress",
- rollback ? "rollback" : "commit");
+ sqlite3SetString(&p->zErrMsg, db, "cannot rollback transaction - "
+ "SQL statements in progress");
rc = SQLITE_BUSY;
- }else if( i!=db->autoCommit ){
+ }else if( turnOnAC && !rollback && db->writeVdbeCnt>1 ){
+ /* If this instruction implements a COMMIT and other VMs are writing
+ ** return an error indicating that the other VMs must complete first.
+ */
+ sqlite3SetString(&p->zErrMsg, db, "cannot commit transaction - "
+ "SQL statements in progress");
+ rc = SQLITE_BUSY;
+ }else if( desiredAutoCommit!=db->autoCommit ){
if( pOp->p2 ){
- assert( i==1 );
+ assert( desiredAutoCommit==1 );
sqlite3RollbackAll(db);
db->autoCommit = 1;
}else{
- db->autoCommit = i;
+ db->autoCommit = desiredAutoCommit;
if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
p->pc = pc;
- db->autoCommit = 1-i;
+ db->autoCommit = 1-desiredAutoCommit;
p->rc = rc = SQLITE_BUSY;
goto vdbe_return;
}
goto vdbe_return;
}else{
sqlite3SetString(&p->zErrMsg, db,
- (!i)?"cannot start a transaction within a transaction":(
+ (!desiredAutoCommit)?"cannot start a transaction within a transaction":(
(rollback)?"cannot rollback - no transaction is active":
"cannot commit - no transaction is active"));
** 6000 lines long) it was split up into several smaller files and
** this header information was factored out.
**
-** $Id: vdbeInt.h,v 1.156 2008/11/03 20:55:07 drh Exp $
+** $Id: vdbeInt.h,v 1.157 2008/11/05 16:37:35 drh Exp $
*/
#ifndef _VDBEINT_H_
#define _VDBEINT_H_
u8 expired; /* True if the VM needs to be recompiled */
u8 minWriteFileFormat; /* Minimum file format for writable database files */
u8 inVtabMethod; /* See comments above */
+ u8 usesStmtJournal; /* True if uses a statement journal */
+ u8 readOnly; /* True for read-only statements */
int nChange; /* Number of db changes made since last reset */
i64 startTime; /* Time when query started - used for profiling */
int btreeMask; /* Bitmask of db->aDb[] entries referenced */
** This file contains code use to implement APIs that are part of the
** VDBE.
**
-** $Id: vdbeapi.c,v 1.147 2008/10/13 10:37:50 danielk1977 Exp $
+** $Id: vdbeapi.c,v 1.148 2008/11/05 16:37:35 drh Exp $
*/
#include "sqliteInt.h"
#include "vdbeInt.h"
#endif
db->activeVdbeCnt++;
+ if( p->readOnly==0 ) db->writeVdbeCnt++;
p->pc = 0;
stmtLruRemove(p);
}
** to version 2.8.7, all this code was combined into the vdbe.c source file.
** But that file was getting too big so this subroutines were split out.
**
-** $Id: vdbeaux.c,v 1.416 2008/11/04 14:25:06 drh Exp $
+** $Id: vdbeaux.c,v 1.417 2008/11/05 16:37:35 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
int *aLabel = p->aLabel;
int doesStatementRollback = 0;
int hasStatementBegin = 0;
+ p->readOnly = 1;
+ p->usesStmtJournal = 0;
for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
u8 opcode = pOp->opcode;
}
}else if( opcode==OP_Statement ){
hasStatementBegin = 1;
+ p->usesStmtJournal = 1;
}else if( opcode==OP_Destroy ){
doesStatementRollback = 1;
+ }else if( opcode==OP_Transaction && pOp->p2!=0 ){
+ p->readOnly = 0;
#ifndef SQLITE_OMIT_VIRTUALTABLE
}else if( opcode==OP_VUpdate || opcode==OP_VRename ){
doesStatementRollback = 1;
** which can be expensive on some platforms.
*/
if( hasStatementBegin && !doesStatementRollback ){
+ p->usesStmtJournal = 0;
for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
if( pOp->opcode==OP_Statement ){
pOp->opcode = OP_Noop;
static void checkActiveVdbeCnt(sqlite3 *db){
Vdbe *p;
int cnt = 0;
+ int nWrite = 0;
p = db->pVdbe;
while( p ){
if( p->magic==VDBE_MAGIC_RUN && p->pc>=0 ){
cnt++;
+ if( p->readOnly==0 ) nWrite++;
}
p = p->pNext;
}
assert( cnt==db->activeVdbeCnt );
+ assert( nWrite==db->writeVdbeCnt );
}
#else
#define checkActiveVdbeCnt(x)
isSpecialError = mrc==SQLITE_NOMEM || mrc==SQLITE_IOERR
|| mrc==SQLITE_INTERRUPT || mrc==SQLITE_FULL;
if( isSpecialError ){
- /* This loop does static analysis of the query to see which of the
- ** following three categories it falls into:
- **
- ** Read-only
- ** Query with statement journal
- ** Query without statement journal
- **
- ** We could do something more elegant than this static analysis (i.e.
- ** store the type of query as part of the compliation phase), but
- ** handling malloc() or IO failure is a fairly obscure edge case so
- ** this is probably easier. Todo: Might be an opportunity to reduce
- ** code size a very small amount though...
- */
- int notReadOnly = 0;
- int isStatement = 0;
- assert(p->aOp || p->nOp==0);
- for(i=0; i<p->nOp; i++){
- switch( p->aOp[i].opcode ){
- case OP_Transaction:
- notReadOnly |= p->aOp[i].p2;
- break;
- case OP_Statement:
- isStatement = 1;
- break;
- }
- }
-
-
/* If the query was read-only, we need do no rollback at all. Otherwise,
** proceed with the special handling.
*/
- if( notReadOnly || mrc!=SQLITE_INTERRUPT ){
- if( p->rc==SQLITE_IOERR_BLOCKED && isStatement ){
+ if( !p->readOnly || mrc!=SQLITE_INTERRUPT ){
+ if( p->rc==SQLITE_IOERR_BLOCKED && p->usesStmtJournal ){
xFunc = sqlite3BtreeRollbackStmt;
p->rc = SQLITE_BUSY;
- } else if( (mrc==SQLITE_NOMEM || mrc==SQLITE_FULL) && isStatement ){
+ }else if( (mrc==SQLITE_NOMEM || mrc==SQLITE_FULL)
+ && p->usesStmtJournal ){
xFunc = sqlite3BtreeRollbackStmt;
}else{
/* We are forced to roll back the active transaction. Before doing
** we do either a commit or rollback of the current transaction.
**
** Note: This block also runs if one of the special errors handled
- ** above has occured.
+ ** above has occurred.
*/
- if( db->autoCommit && db->activeVdbeCnt==1 ){
+ if( db->autoCommit && db->writeVdbeCnt==(p->readOnly==0) ){
if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){
/* The auto-commit flag is true, and the vdbe program was
** successful or hit an 'OR FAIL' constraint. This means a commit
/* We have successfully halted and closed the VM. Record this fact. */
if( p->pc>=0 ){
db->activeVdbeCnt--;
+ if( !p->readOnly ){
+ db->writeVdbeCnt--;
+ }
+ assert( db->activeVdbeCnt>=db->writeVdbeCnt );
}
p->magic = VDBE_MAGIC_HALT;
checkActiveVdbeCnt(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.68 2008/10/30 15:03:16 drh Exp $
+# $Id: capi3.test,v 1.69 2008/11/05 16:37:35 drh Exp $
#
set testdir [file dirname $argv0]
set STMT [sqlite3_prepare $DB "SELECT func(b, a) FROM t1" -1 TAIL]
sqlite3_step $STMT
} {SQLITE_ROW}
+
+# As of 3.6.5 a COMMIT is OK during while a query is still running -
+# as long as it is a read-only query and not an incremental BLOB write.
+#
do_test capi3-11.3.1 {
catchsql {
COMMIT;
}
-} {1 {cannot commit transaction - SQL statements in progress}}
+} {0 {}}
do_test capi3-11.3.2 {
sqlite3_extended_errcode $DB
-} {SQLITE_BUSY}
+} {SQLITE_OK}
do_test capi3-11.3.3 {
sqlite3_get_autocommit $DB
-} 0
+} 1
+do_test capi3-11.3.4 {
+ db eval {PRAGMA lock_status}
+} {main shared temp closed}
+
do_test capi3-11.4 {
sqlite3_step $STMT
} {SQLITE_ERROR}
SELECT * FROM t1;
}
} {0 {1 int 2 notatype}}
-do_test capi3-11.6.1 {
- sqlite3_get_autocommit $DB
-} 0
do_test capi3-11.7 {
- catchsql {
- COMMIT;
- }
-} {0 {}}
-do_test capi3-11.7.1 {
sqlite3_get_autocommit $DB
} 1
do_test capi3-11.8 {
BEGIN;
COMMIT;
}
-} {1 {cannot commit transaction - SQL statements in progress}}
+} {0 {}}
do_test capi3-11.20 {
sqlite3_reset $STMT
catchsql {
COMMIT;
}
-} {0 {}}
+} {1 {cannot commit - no transaction is active}}
do_test capi3-11.21 {
sqlite3_finalize $STMT
} {SQLITE_OK}
# This is a copy of the capi3.test file that has been adapted to
# test the new sqlite3_prepare_v2 interface.
#
-# $Id: capi3c.test,v 1.21 2008/10/30 15:03:16 drh Exp $
+# $Id: capi3c.test,v 1.22 2008/11/05 16:37:35 drh Exp $
#
set testdir [file dirname $argv0]
set STMT [sqlite3_prepare_v2 $DB "SELECT func(b, a) FROM t1" -1 TAIL]
sqlite3_step $STMT
} {SQLITE_ROW}
-do_test capi3c-11.3 {
+
+# As of 3.6.5 a COMMIT is OK during while a query is still running -
+# as long as it is a read-only query and not an incremental BLOB write.
+#
+do_test capi3-11.3.1 {
catchsql {
COMMIT;
}
-} {1 {cannot commit transaction - SQL statements in progress}}
-do_test capi3c-11.3.1 {
+} {0 {}}
+do_test capi3-11.3.2 {
+ sqlite3_extended_errcode $DB
+} {SQLITE_OK}
+do_test capi3-11.3.3 {
sqlite3_get_autocommit $DB
-} 0
+} 1
+do_test capi3-11.3.4 {
+ db eval {PRAGMA lock_status}
+} {main shared temp closed}
+
do_test capi3c-11.4 {
sqlite3_step $STMT
} {SQLITE_ERROR}
SELECT * FROM t1;
}
} {0 {1 int 2 notatype}}
-do_test capi3c-11.6.1 {
- sqlite3_get_autocommit $DB
-} 0
do_test capi3c-11.7 {
- catchsql {
- COMMIT;
- }
-} {0 {}}
-do_test capi3c-11.7.1 {
sqlite3_get_autocommit $DB
} 1
do_test capi3c-11.8 {
BEGIN;
COMMIT;
}
-} {1 {cannot commit transaction - SQL statements in progress}}
+} {0 {}}
do_test capi3c-11.20 {
sqlite3_reset $STMT
catchsql {
COMMIT;
}
-} {0 {}}
+} {1 {cannot commit - no transaction is active}}
do_test capi3c-11.21 {
sqlite3_finalize $STMT
} {SQLITE_OK}
#
#***********************************************************************
#
-# $Id: incrblob.test,v 1.22 2008/10/02 14:49:02 danielk1977 Exp $
+# $Id: incrblob.test,v 1.23 2008/11/05 16:37:35 drh Exp $
#
set testdir [file dirname $argv0]
flush $::blob
} {}
-# At this point rollback or commit should be illegal (because
-# there is an open blob channel).
+# At this point rollback should be illegal (because
+# there is an open blob channel). But commit is allowed because
+# the blob is read-only.
+#
do_test incrblob-6.10 {
catchsql {
ROLLBACK;
catchsql {
COMMIT;
} db2
-} {1 {cannot commit transaction - SQL statements in progress}}
+} {0 {}}
do_test incrblob-6.12 {
execsql {
} {}
do_test incrblob-6.13 {
close $::blob
- execsql {
- COMMIT;
- } db2
} {}
do_test incrblob-6.14 {
execsql {
# Make sure that application-defined functions are able to recursively
# invoke SQL statements that create and drop virtual tables.
#
-# $Id: tkt3080.test,v 1.1 2008/04/28 17:12:11 drh Exp $
+# $Id: tkt3080.test,v 1.2 2008/11/05 16:37:35 drh Exp $
#
set testdir [file dirname $argv0]
db eval {
SELECT name FROM sqlite_master;
}
-} {t1 t2}
+} {t1 t2 t3}
ifcapable vtab {
register_echo_module [sqlite3_connection_pointer db]
SELECT execsql(x) FROM t1
}
execsql {SELECT name FROM sqlite_master}
- } {t1 t2}
+ } {t1 t2 t3}
do_test tkt3080.11 {
execsql {SELECT * FROM t2}
} {123}
# focus of this script is the response of COMMIT and ROLLBACK when
# statements are still pending.
#
-# $Id: trans3.test,v 1.1 2008/11/03 21:40:00 drh Exp $
+# $Id: trans3.test,v 1.2 2008/11/05 16:37:35 drh Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
db eval {INSERT INTO t1 VALUES(4);}
set ::ecode {}
set x [catch {
- db eval {SELECT * FROM t1} {
+ db eval {SELECT * FROM t1 LIMIT 1} {
if {[catch {db eval COMMIT} errmsg]} {
set ::ecode [sqlite3_extended_errcode db]
error $errmsg
}
} errmsg]
lappend x $errmsg
-} {1 {cannot commit transaction - SQL statements in progress}}
+} {0 {}}
do_test trans3-1.3 {
set ::ecode
-} {SQLITE_BUSY}
+} {}
+do_test trans3-1.3.1 {
+ sqlite3_get_autocommit db
+} 1
do_test trans3-1.4 {
- db eval COMMIT
db eval {SELECT * FROM t1}
} {1 2 3 4}
do_test trans3-1.5 {