From: danielk1977 Date: Thu, 19 Mar 2009 07:58:31 +0000 (+0000) Subject: Change sqlite3_step() to return SQLITE_LOCKED if a statement cannot be re-compiled... X-Git-Tag: version-3.6.15~391 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=65a2ea1155db05aba2f5ac8f765ce996c8fdd52f;p=thirdparty%2Fsqlite.git Change sqlite3_step() to return SQLITE_LOCKED if a statement cannot be re-compiled due to locks on the shared-cache schema. Also add a blocking wrapper of sqlite3_prepare_v2() to the test code. (CVS 6359) FossilOrigin-Name: e8be1af922098e298902820730f8b28603bd6fae --- diff --git a/manifest b/manifest index 001d6f7916..a251af1de7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\scrash\sthat\scould\soccur\swhen\screating\san\sindex\sin\sshared-cache\smode\swith\slookaside\senabled.\s(CVS\s6358) -D 2009-03-18T18:43:36 +C Change\ssqlite3_step()\sto\sreturn\sSQLITE_LOCKED\sif\sa\sstatement\scannot\sbe\sre-compiled\sdue\sto\slocks\son\sthe\sshared-cache\sschema.\sAlso\sadd\sa\sblocking\swrapper\sof\ssqlite3_prepare_v2()\sto\sthe\stest\scode.\s(CVS\s6359) +D 2009-03-19T07:58:31 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 583e87706abc3026960ed759aff6371faf84c211 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -150,7 +150,7 @@ F src/pcache.c fcf7738c83c4d3e9d45836b2334c8a368cc41274 F src/pcache.h 9b927ccc5a538e31b4c3bc7eec4f976db42a1324 F src/pcache1.c f12518540ba776df3051215c4244e9cdc06b09cd F src/pragma.c 22ed04836aab8ce134c53be1ca896f3ad20fabdb -F src/prepare.c ebd40f8c6a33c52bfea2db710394d6e82c7e594b +F src/prepare.c 8c6ef35c30aa6b59a39b975efa4f90a66a5afb81 F src/printf.c 9866a9a9c4a90f6d4147407f373df3fd5d5f9b6f F src/random.c 676b9d7ac820fe81e6fb2394ac8c10cff7f38628 F src/resolve.c 094e44450371fb27869eb8bf679aacbe51fdc56d @@ -192,7 +192,7 @@ F src/test_pcache.c 29464896d9c67832e4eef916c0682b98d7283d00 F src/test_schema.c 4b4bf7bb329326458c491b0e6facd4c8c4c5b479 F src/test_server.c f0a403b5f699c09bd2b1236b6f69830fd6221f6b F src/test_tclvar.c 9e42fa59d3d2f064b7ab8628e7ab2dc8a9fe93d4 -F src/test_thread.c 6805d05c3b7e08d51b31662b148cf2f51b9ca4cc +F src/test_thread.c 870a862d9c740d083b93ed30a0b5c0b491b30f43 F src/test_wsd.c c297d7d6b8a990239e1bd25935e81d612d8ae31d F src/tokenize.c 6987fb7f0d6a87ac53499aee568cabb05eb4bea8 F src/trigger.c 21f39db410cdc32166a94900ac1b3df98ea560e6 @@ -203,7 +203,7 @@ F src/vacuum.c 4929a585ef0fb1dfaf46302f8a9c4aa30c2d9cf5 F src/vdbe.c f8164c2830f82714a77b1f2a97c2e9c4efbcb3bb F src/vdbe.h d70a68bee196ab228914a3902c79dbd24342a0f2 F src/vdbeInt.h 53a2f4696871712646c77351904576cca6ad9752 -F src/vdbeapi.c ffd5d8b493590da6e09fd54b1bea1a9d38247f11 +F src/vdbeapi.c e50f5f6dbd0c5354da25ee52fa5fa4bc0758ba40 F src/vdbeaux.c e9b76cf2ca8f78b692be984381cc4b27defc902a F src/vdbeblob.c 2852bae14c87129835938db58a77c3121e3ae962 F src/vdbemem.c 543a79d722734d2f8b7ad70f08218c30bcc5bbf5 @@ -479,7 +479,7 @@ F test/mutex1.test 1e5c196d5170bbe3a7d8370b1b905e8c86a9e07c F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660 F test/nan.test c627d79b3d36ea892563fd67584b3e8a18f0618a F test/notify1.test 9a985a94f34de1b24daf25fd86b6d5033ba532d0 -F test/notify2.test 828511802c3e899d91f753771cefbe1d41dcb854 +F test/notify2.test 0c350ad8ff7d7d6ceb24ac84f33df0ce481f86e1 F test/notnull.test 44d600f916b770def8b095a9962dbe3be5a70d82 F test/null.test a8b09b8ed87852742343b33441a9240022108993 F test/openv2.test f5dd6b23e4dce828eb211649b600763c42a668df @@ -709,7 +709,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e -P d82e8cd43f46dda15fd15b567901a7dbb2276287 -R c8deeec50bc2cb39d7ab6042bd53185b +P 097737e3689b9a7e32815fe9c6fc6eed796ae53c +R 32a96214111535313729ca99d5be6662 U danielk1977 -Z b4dedc49427fc75b7d301c2f3f28656d +Z 02acbb631daf9f43302bd19b0b92f600 diff --git a/manifest.uuid b/manifest.uuid index a510e9165f..ac2aac9fc4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -097737e3689b9a7e32815fe9c6fc6eed796ae53c \ No newline at end of file +e8be1af922098e298902820730f8b28603bd6fae \ No newline at end of file diff --git a/src/prepare.c b/src/prepare.c index 0142af557f..0b9e747dd7 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -13,7 +13,7 @@ ** interface, and routines that contribute to loading the database schema ** from disk. ** -** $Id: prepare.c,v 1.109 2009/03/16 13:19:36 danielk1977 Exp $ +** $Id: prepare.c,v 1.110 2009/03/19 07:58:31 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -688,8 +688,11 @@ static int sqlite3LockAndPrepare( /* ** Rerun the compilation of a statement after a schema change. -** Return true if the statement was recompiled successfully. -** Return false if there is an error of some kind. +** +** If the statement is successfully recompiled, return SQLITE_OK. Otherwise, +** if the statement cannot be recompiled because another connection has +** locked the sqlite3_master table, return SQLITE_LOCKED. If any other error +** occurs, return SQLITE_SCHEMA. */ int sqlite3Reprepare(Vdbe *p){ int rc; @@ -708,7 +711,7 @@ int sqlite3Reprepare(Vdbe *p){ db->mallocFailed = 1; } assert( pNew==0 ); - return 0; + return (rc==SQLITE_LOCKED) ? SQLITE_LOCKED : SQLITE_SCHEMA; }else{ assert( pNew!=0 ); } @@ -716,7 +719,7 @@ int sqlite3Reprepare(Vdbe *p){ sqlite3TransferBindings(pNew, (sqlite3_stmt*)p); sqlite3VdbeResetStepResult((Vdbe*)pNew); sqlite3VdbeFinalize((Vdbe*)pNew); - return 1; + return SQLITE_OK; } diff --git a/src/test_thread.c b/src/test_thread.c index 156f896ce8..20fcf73a23 100644 --- a/src/test_thread.c +++ b/src/test_thread.c @@ -14,7 +14,7 @@ ** test that sqlite3 database handles may be concurrently accessed by ** multiple threads. Right now this only works on unix. ** -** $Id: test_thread.c,v 1.11 2009/03/16 13:19:36 danielk1977 Exp $ +** $Id: test_thread.c,v 1.12 2009/03/19 07:58:31 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -56,8 +56,16 @@ struct EvalEvent { static Tcl_ObjCmdProc sqlthread_proc; static Tcl_ObjCmdProc clock_seconds_proc; static Tcl_ObjCmdProc blocking_step_proc; +static Tcl_ObjCmdProc blocking_prepare_v2_proc; int Sqlitetest1_Init(Tcl_Interp *); +/* Functions from test1.c */ +void *sqlite3TestTextToPtr(const char *); +const char *sqlite3TestErrorName(int); +int getDbPointer(Tcl_Interp *, const char *, sqlite3 **); +int sqlite3TestMakePointerStr(Tcl_Interp *, char *, void *); +int sqlite3TestErrCode(Tcl_Interp *, sqlite3 *, int); + /* ** Handler for events of type EvalEvent. */ @@ -109,6 +117,8 @@ static Tcl_ThreadCreateType tclScriptThread(ClientData pSqlThread){ Tcl_CreateObjCommand(interp, "sqlthread", sqlthread_proc, pSqlThread, 0); #if defined(OS_UNIX) && defined(SQLITE_ENABLE_UNLOCK_NOTIFY) Tcl_CreateObjCommand(interp, "sqlite3_blocking_step", blocking_step_proc,0,0); + Tcl_CreateObjCommand( + interp, "sqlite3_blocking_prepare_v2", blocking_prepare_v2_proc,0,0); #endif Sqlitetest1_Init(interp); Sqlitetest_mutex_Init(interp); @@ -396,7 +406,7 @@ struct UnlockNotification { /* ** This function is an unlock-notify callback registered with SQLite. */ -static void blocking_step_notify(void **apArg, int nArg){ +static void unlock_notify_cb(void **apArg, int nArg){ int i; for(i=0; i=5?&zTail : 0); + assert(rc==SQLITE_OK || pStmt==0); + if( zTail && objc>=5 ){ + if( bytes>=0 ){ + bytes = bytes - (zTail-zSql); + } + Tcl_ObjSetVar2(interp, objv[4], 0, Tcl_NewStringObj(zTail, bytes), 0); + } + if( rc!=SQLITE_OK ){ + assert( pStmt==0 ); + sprintf(zBuf, "%s ", (char *)sqlite3TestErrorName(rc)); + Tcl_AppendResult(interp, zBuf, sqlite3_errmsg(db), 0); + return TCL_ERROR; + } + + if( pStmt ){ + if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR; + Tcl_AppendResult(interp, zBuf, 0); + } + return TCL_OK; +} + #endif /* ** End of implementation of [sqlite3_blocking_step]. @@ -513,6 +603,8 @@ int SqlitetestThread_Init(Tcl_Interp *interp){ Tcl_CreateObjCommand(interp, "clock_seconds", clock_seconds_proc, 0, 0); #if defined(OS_UNIX) && defined(SQLITE_ENABLE_UNLOCK_NOTIFY) Tcl_CreateObjCommand(interp, "sqlite3_blocking_step", blocking_step_proc,0,0); + Tcl_CreateObjCommand( + interp, "sqlite3_blocking_prepare_v2", blocking_prepare_v2_proc,0,0); #endif return TCL_OK; } diff --git a/src/vdbeapi.c b/src/vdbeapi.c index 91d85ecf27..f0c0e0674c 100644 --- a/src/vdbeapi.c +++ b/src/vdbeapi.c @@ -13,7 +13,7 @@ ** This file contains code use to implement APIs that are part of the ** VDBE. ** -** $Id: vdbeapi.c,v 1.153 2009/03/05 04:23:47 shane Exp $ +** $Id: vdbeapi.c,v 1.154 2009/03/19 07:58:31 danielk1977 Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" @@ -544,7 +544,7 @@ int sqlite3_step(sqlite3_stmt *pStmt){ sqlite3_mutex_enter(db->mutex); while( (rc = sqlite3Step(v))==SQLITE_SCHEMA && cnt++ < 5 - && vdbeReprepare(v) ){ + && (rc = vdbeReprepare(v))==SQLITE_OK ){ sqlite3_reset(pStmt); v->expired = 0; } diff --git a/test/notify2.test b/test/notify2.test index c6df6e53aa..8b508b2bc4 100644 --- a/test/notify2.test +++ b/test/notify2.test @@ -9,7 +9,7 @@ # #*********************************************************************** # -# $Id: notify2.test,v 1.1 2009/03/16 13:19:36 danielk1977 Exp $ +# $Id: notify2.test,v 1.2 2009/03/19 07:58:31 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -63,7 +63,7 @@ set ThreadProgram { set rc SQLITE_OK while {$rc=="SQLITE_OK" && $zSql ne ""} { - set STMT [sqlite3_prepare_v2 $db $zSql -1 zSql] + set STMT [$::xPrepare $db $zSql -1 zSql] while {[set rc [$::xStep $STMT]] eq "SQLITE_ROW"} { for {set i 0} {$i < [sqlite3_column_count $STMT]} {incr i} { lappend lRes [sqlite3_column_text $STMT 0] @@ -99,14 +99,22 @@ set ThreadProgram { # each operation. # for {set ii 1} {$ii <= 3} {incr ii} { - set SQL($ii) [string map [list xxx [select_one t1 t2 t3]] [select_one { + foreach {tbl database} [select_one {t1 main} {t2 aux2} {t3 aux3}] {} + + set SQL($ii) [string map [list xxx $tbl yyy $database] [select_one { SELECT (SELECT b FROM xxx WHERE a=(SELECT max(a) FROM xxx))==total(a) FROM xxx WHERE a!=(SELECT max(a) FROM xxx); } { DELETE FROM xxx WHERE a<(SELECT max(a)-100 FROM xxx); INSERT INTO xxx SELECT NULL, total(a) FROM xxx; - }]] + } +# { +# CREATE INDEX IF NOT EXISTS yyy.xxx_i ON xxx(b); +# } { +# DROP INDEX IF EXISTS yyy.xxx_i; +# } + ]] } # Execute the SQL transaction. @@ -140,10 +148,13 @@ set ThreadProgram { expr 0 } -foreach {iTest xStep} {1 sqlite3_blocking_step 2 sqlite3_step} { +foreach {iTest xStep xPrepare} { + 1 sqlite3_blocking_step sqlite3_blocking_prepare_v2 + 2 sqlite3_step sqlite3_prepare_v2 +} { file delete -force test.db test2.db test3.db - set ThreadSetup "set xStep $xStep ; set nSecond $nSecond" + set ThreadSetup "set xStep $xStep;set xPrepare $xPrepare;set nSecond $nSecond" # Set up the database schema used by this test. Each thread opens file # test.db as the main database, then attaches files test2.db and test3.db