diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.c | 20 | ||||
-rw-r--r-- | src/os_win.c | 4 | ||||
-rw-r--r-- | src/resolve.c | 2 | ||||
-rw-r--r-- | src/test1.c | 25 |
4 files changed, 42 insertions, 9 deletions
diff --git a/src/main.c b/src/main.c index d53503aec..39ef5bfb5 100644 --- a/src/main.c +++ b/src/main.c @@ -848,12 +848,6 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){ return SQLITE_BUSY; } - /* If a transaction is open, roll it back. This also ensures that if - ** any database schemas have been modified by the current transaction - ** they are reset. And that the required b-tree mutex is held to make - ** the the pager rollback and schema reset an atomic operation. */ - sqlite3RollbackAll(db, SQLITE_OK); - #ifdef SQLITE_ENABLE_SQLLOG if( sqlite3GlobalConfig.xSqllog ){ /* Closing the handle. Fourth parameter is passed the value 2. */ @@ -908,6 +902,12 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){ ** go ahead and free all resources. */ + /* If a transaction is open, roll it back. This also ensures that if + ** any database schemas have been modified by an uncommitted transaction + ** they are reset. And that the required b-tree mutex is held to make + ** the pager rollback and schema reset an atomic operation. */ + sqlite3RollbackAll(db, SQLITE_OK); + /* Free any outstanding Savepoint structures. */ sqlite3CloseSavepoints(db); @@ -1008,7 +1008,15 @@ void sqlite3RollbackAll(sqlite3 *db, int tripCode){ int inTrans = 0; assert( sqlite3_mutex_held(db->mutex) ); sqlite3BeginBenignMalloc(); + + /* Obtain all b-tree mutexes before making any calls to BtreeRollback(). + ** This is important in case the transaction being rolled back has + ** modified the database schema. If the b-tree mutexes are not taken + ** here, then another shared-cache connection might sneak in between + ** the database rollback and schema reset, which can cause false + ** corruption reports in some cases. */ sqlite3BtreeEnterAll(db); + for(i=0; i<db->nDb; i++){ Btree *p = db->aDb[i].pBt; if( p ){ diff --git a/src/os_win.c b/src/os_win.c index 66f070387..fe47207d5 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -2937,8 +2937,6 @@ static int winDeviceCharacteristics(sqlite3_file *id){ ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0); } -#ifndef SQLITE_OMIT_WAL - /* ** Windows will only let you create file view mappings ** on allocation size granularity boundaries. @@ -2947,6 +2945,8 @@ static int winDeviceCharacteristics(sqlite3_file *id){ */ SYSTEM_INFO winSysInfo; +#ifndef SQLITE_OMIT_WAL + /* ** Helper functions to obtain and relinquish the global mutex. The ** global mutex is used to protect the winLockInfo objects used by diff --git a/src/resolve.c b/src/resolve.c index a8e196926..91efcaa1a 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -1159,8 +1159,8 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ ** re-evaluated for each reference to it. */ sNC.pEList = p->pEList; - if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort; sNC.ncFlags |= NC_AsMaybe; + if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort; if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort; sNC.ncFlags &= ~NC_AsMaybe; diff --git a/src/test1.c b/src/test1.c index 59de1db8e..a638e480a 100644 --- a/src/test1.c +++ b/src/test1.c @@ -682,6 +682,30 @@ static int sqlite_test_close( } /* +** Usage: sqlite3_close_v2 DB +** +** Closes the database opened by sqlite3_open. +*/ +static int sqlite_test_close_v2( + void *NotUsed, + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ + int argc, /* Number of arguments */ + char **argv /* Text of each argument */ +){ + sqlite3 *db; + int rc; + if( argc!=2 ){ + Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], + " FILENAME\"", 0); + return TCL_ERROR; + } + if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; + rc = sqlite3_close_v2(db); + Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC); + return TCL_OK; +} + +/* ** Implementation of the x_coalesce() function. ** Return the first argument non-NULL argument. */ @@ -6077,6 +6101,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "sqlite3_get_table_printf", (Tcl_CmdProc*)test_get_table_printf }, #endif { "sqlite3_close", (Tcl_CmdProc*)sqlite_test_close }, + { "sqlite3_close_v2", (Tcl_CmdProc*)sqlite_test_close_v2 }, { "sqlite3_create_function", (Tcl_CmdProc*)test_create_function }, { "sqlite3_create_aggregate", (Tcl_CmdProc*)test_create_aggregate }, { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func }, |