diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/build.c | 39 | ||||
-rw-r--r-- | src/callback.c | 2 | ||||
-rw-r--r-- | src/prepare.c | 3 | ||||
-rw-r--r-- | src/sqliteInt.h | 2 |
4 files changed, 27 insertions, 19 deletions
diff --git a/src/build.c b/src/build.c index cb3172e07..d64eac009 100644 --- a/src/build.c +++ b/src/build.c @@ -514,28 +514,26 @@ void sqlite3CollapseDatabaseArray(sqlite3 *db){ /* ** Reset the schema for the database at index iDb. Also reset the -** TEMP schema. +** TEMP schema. The reset is deferred if db->nSchemaLock is not zero. +** Deferred resets may be run by calling with iDb<0. */ void sqlite3ResetOneSchema(sqlite3 *db, int iDb){ - Db *pDb; + int i; assert( iDb<db->nDb ); - /* Case 1: Reset the single schema identified by iDb */ - pDb = &db->aDb[iDb]; - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - assert( pDb->pSchema!=0 ); - sqlite3SchemaClear(pDb->pSchema); + if( iDb>=0 ){ + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + DbSetProperty(db, iDb, DB_ResetWanted); + DbSetProperty(db, 1, DB_ResetWanted); + } - /* If any database other than TEMP is reset, then also reset TEMP - ** since TEMP might be holding triggers that reference tables in the - ** other database. - */ - if( iDb!=1 ){ - pDb = &db->aDb[1]; - assert( pDb->pSchema!=0 ); - sqlite3SchemaClear(pDb->pSchema); + if( db->nSchemaLock==0 ){ + for(i=0; i<db->nDb; i++){ + if( DbHasProperty(db, i, DB_ResetWanted) ){ + sqlite3SchemaClear(db->aDb[i].pSchema); + } + } } - return; } /* @@ -545,6 +543,7 @@ void sqlite3ResetOneSchema(sqlite3 *db, int iDb){ void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){ int i; sqlite3BtreeEnterAll(db); + assert( db->nSchemaLock==0 ); for(i=0; i<db->nDb; i++){ Db *pDb = &db->aDb[i]; if( pDb->pSchema ){ @@ -2155,6 +2154,9 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ int nErr = 0; /* Number of errors encountered */ int n; /* Temporarily holds the number of cursors assigned */ sqlite3 *db = pParse->db; /* Database connection for malloc errors */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + int rc; +#endif #ifndef SQLITE_OMIT_AUTHORIZATION sqlite3_xauth xAuth; /* Saved xAuth pointer */ #endif @@ -2162,7 +2164,10 @@ int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ assert( pTable ); #ifndef SQLITE_OMIT_VIRTUALTABLE - if( sqlite3VtabCallConnect(pParse, pTable) ){ + db->nSchemaLock++; + rc = sqlite3VtabCallConnect(pParse, pTable); + db->nSchemaLock--; + if( rc ){ return SQLITE_ERROR; } if( IsVirtual(pTable) ) return 0; diff --git a/src/callback.c b/src/callback.c index 10505414c..e08924b2c 100644 --- a/src/callback.c +++ b/src/callback.c @@ -457,8 +457,8 @@ void sqlite3SchemaClear(void *p){ pSchema->pSeqTab = 0; if( pSchema->schemaFlags & DB_SchemaLoaded ){ pSchema->iGeneration++; - pSchema->schemaFlags &= ~DB_SchemaLoaded; } + pSchema->schemaFlags &= ~(DB_SchemaLoaded|DB_ResetWanted); } /* diff --git a/src/prepare.c b/src/prepare.c index 4fa59e5be..c31b81082 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -686,7 +686,8 @@ static int sqlite3LockAndPrepare( sqlite3_mutex_enter(db->mutex); sqlite3BtreeEnterAll(db); rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail); - if( rc==SQLITE_SCHEMA ){ + if( rc==SQLITE_SCHEMA && db->nSchemaLock==0 ){ + sqlite3ResetOneSchema(db, -1); sqlite3_finalize(*ppStmt); rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail); } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index c457b5401..8aa9832e8 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1213,6 +1213,7 @@ struct Schema { #define DB_SchemaLoaded 0x0001 /* The schema has been loaded */ #define DB_UnresetViews 0x0002 /* Some views have defined column names */ #define DB_Empty 0x0004 /* The file is empty (length 0 bytes) */ +#define DB_ResetWanted 0x0008 /* Reset the schema when nSchemaLock==0 */ /* ** The number of different kinds of things that can be limited @@ -1329,6 +1330,7 @@ struct sqlite3 { u32 flags; /* flags settable by pragmas. See below */ i64 lastRowid; /* ROWID of most recent insert (see above) */ i64 szMmap; /* Default mmap_size setting */ + u32 nSchemaLock; /* Do not reset the schema when non-zero */ unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */ int errCode; /* Most recent error code (SQLITE_*) */ int errMask; /* & result codes with this before returning */ |