diff options
author | drh <drh@noemail.net> | 2011-04-02 16:28:52 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2011-04-02 16:28:52 +0000 |
commit | c7792fa052499f7ff04adaa787a957eb3f6b5e47 (patch) | |
tree | 534a9364433a4b5cfa8c6366c4107e492b08365e /src | |
parent | 6c15487b7edf747b7b08cf6eb311f503adb0cd6a (diff) | |
download | sqlite-c7792fa052499f7ff04adaa787a957eb3f6b5e47.tar.gz sqlite-c7792fa052499f7ff04adaa787a957eb3f6b5e47.zip |
Begin a series of changes designed to reduce the scope and frequency of
invalidating schemas. Design goals are that the internal schema should
never be deleted out from under a prepared statement that is running and
that all prepared statements should be expired if the schema is invalidated.
At the same time, minimize the number of schema invalidations. This change
merely revises the sqlite3ResetInternalSchema() function to use -1 as the
wildcard for "all" rather than 0, so that we can reset the main schema
independently of all the others.
FossilOrigin-Name: 6a8ad6e31e0d2b8a5ace38faf0efd805155ee5f3
Diffstat (limited to 'src')
-rw-r--r-- | src/attach.c | 4 | ||||
-rw-r--r-- | src/backup.c | 2 | ||||
-rw-r--r-- | src/build.c | 24 | ||||
-rw-r--r-- | src/main.c | 6 | ||||
-rw-r--r-- | src/pragma.c | 2 | ||||
-rw-r--r-- | src/prepare.c | 4 | ||||
-rw-r--r-- | src/vacuum.c | 3 | ||||
-rw-r--r-- | src/vdbe.c | 4 | ||||
-rw-r--r-- | src/vdbeaux.c | 2 | ||||
-rw-r--r-- | src/vtab.c | 2 |
10 files changed, 31 insertions, 22 deletions
diff --git a/src/attach.c b/src/attach.c index 37b61935f..fe88aa73c 100644 --- a/src/attach.c +++ b/src/attach.c @@ -200,7 +200,7 @@ static void attachFunc( db->aDb[iDb].pBt = 0; db->aDb[iDb].pSchema = 0; } - sqlite3ResetInternalSchema(db, 0); + sqlite3ResetInternalSchema(db, -1); db->nDb = iDb; if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ db->mallocFailed = 1; @@ -272,7 +272,7 @@ static void detachFunc( sqlite3BtreeClose(pDb->pBt); pDb->pBt = 0; pDb->pSchema = 0; - sqlite3ResetInternalSchema(db, 0); + sqlite3ResetInternalSchema(db, -1); return; detach_error: diff --git a/src/backup.c b/src/backup.c index 82be9635b..c062744c5 100644 --- a/src/backup.c +++ b/src/backup.c @@ -401,7 +401,7 @@ int sqlite3_backup_step(sqlite3_backup *p, int nPage){ int nDestTruncate; if( p->pDestDb ){ - sqlite3ResetInternalSchema(p->pDestDb, 0); + sqlite3ResetInternalSchema(p->pDestDb, -1); } /* Set nDestTruncate to the final number of pages in the destination diff --git a/src/build.c b/src/build.c index bf3273fc8..c7cd6363d 100644 --- a/src/build.c +++ b/src/build.c @@ -393,26 +393,34 @@ void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char *zIdxName){ ** if there were schema changes during the transaction or if a ** schema-cookie mismatch occurs. ** -** If iDb==0 then reset the internal schema tables for all database -** files. If iDb>=1 then reset the internal schema for only the +** If iDb<0 then reset the internal schema tables for all database +** files. If iDb>=0 then reset the internal schema for only the ** single file indicated. */ void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){ int i, j; - assert( iDb>=0 && iDb<db->nDb ); + assert( iDb<db->nDb ); - if( iDb==0 ){ - sqlite3BtreeEnterAll(db); + if( iDb>=0 ){ + /* Case 1: Reset the single schema identified by iDb */ + Db *pDb = &db->aDb[iDb]; + if( pDb->pSchema ){ + assert(iDb==1 || (pDb->pBt && sqlite3BtreeHoldsMutex(pDb->pBt))); + sqlite3SchemaFree(pDb->pSchema); + } + return; } - for(i=iDb; i<db->nDb; i++){ + /* Case 2 (from here to the end): Reset all schemas for all attached + ** databases. */ + assert( iDb<0 ); + sqlite3BtreeEnterAll(db); + for(i=0; i<db->nDb; i++){ Db *pDb = &db->aDb[i]; if( pDb->pSchema ){ assert(i==1 || (pDb->pBt && sqlite3BtreeHoldsMutex(pDb->pBt))); sqlite3SchemaFree(pDb->pSchema); } - if( iDb>0 ) return; } - assert( iDb==0 ); db->flags &= ~SQLITE_InternChanges; sqlite3VtabUnlockList(db); sqlite3BtreeLeaveAll(db); diff --git a/src/main.c b/src/main.c index 03097498c..ca862edc7 100644 --- a/src/main.c +++ b/src/main.c @@ -687,7 +687,7 @@ int sqlite3_close(sqlite3 *db){ } sqlite3_mutex_enter(db->mutex); - sqlite3ResetInternalSchema(db, 0); + sqlite3ResetInternalSchema(db, -1); /* If a transaction is open, the ResetInternalSchema() call above ** will not have called the xDisconnect() method on any virtual @@ -730,7 +730,7 @@ int sqlite3_close(sqlite3 *db){ } } } - sqlite3ResetInternalSchema(db, 0); + sqlite3ResetInternalSchema(db, -1); /* Tell the code in notify.c that the connection no longer holds any ** locks and does not require any further unlock-notify callbacks. @@ -821,7 +821,7 @@ void sqlite3RollbackAll(sqlite3 *db){ if( db->flags&SQLITE_InternChanges ){ sqlite3ExpirePreparedStatements(db); - sqlite3ResetInternalSchema(db, 0); + sqlite3ResetInternalSchema(db, -1); } /* Any deferred constraint violations have now been resolved. */ diff --git a/src/pragma.c b/src/pragma.c index db55e4bb4..0a092e8c3 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -115,7 +115,7 @@ static int invalidateTempStorage(Parse *pParse){ } sqlite3BtreeClose(db->aDb[1].pBt); db->aDb[1].pBt = 0; - sqlite3ResetInternalSchema(db, 0); + sqlite3ResetInternalSchema(db, -1); } return SQLITE_OK; } diff --git a/src/prepare.c b/src/prepare.c index 45654ecfc..0687ddea4 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -338,7 +338,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ } if( db->mallocFailed ){ rc = SQLITE_NOMEM; - sqlite3ResetInternalSchema(db, 0); + sqlite3ResetInternalSchema(db, -1); } if( rc==SQLITE_OK || (db->flags&SQLITE_RecoveryMode)){ /* Black magic: If the SQLITE_RecoveryMode flag is set, then consider @@ -613,7 +613,7 @@ static int sqlite3Prepare( schemaIsValid(pParse); } if( pParse->rc==SQLITE_SCHEMA ){ - sqlite3ResetInternalSchema(db, 0); + sqlite3ResetInternalSchema(db, -1); } if( db->mallocFailed ){ pParse->rc = SQLITE_NOMEM; diff --git a/src/vacuum.c b/src/vacuum.c index 4babf5b40..5ca39ae1e 100644 --- a/src/vacuum.c +++ b/src/vacuum.c @@ -335,8 +335,9 @@ end_of_vacuum: pDb->pSchema = 0; } - sqlite3ResetInternalSchema(db, 0); + sqlite3ResetInternalSchema(db, -1); return rc; } + #endif /* SQLITE_OMIT_VACUUM && SQLITE_OMIT_ATTACH */ diff --git a/src/vdbe.c b/src/vdbe.c index ddf507ee9..0c790d650 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2649,7 +2649,7 @@ case OP_Savepoint: { } if( p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){ sqlite3ExpirePreparedStatements(db); - sqlite3ResetInternalSchema(db, 0); + sqlite3ResetInternalSchema(db, -1); db->flags = (db->flags | SQLITE_InternChanges); } } @@ -5946,7 +5946,7 @@ vdbe_error_halt: sqlite3VdbeHalt(p); if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1; rc = SQLITE_ERROR; - if( resetSchemaOnFault ) sqlite3ResetInternalSchema(db, 0); + if( resetSchemaOnFault ) sqlite3ResetInternalSchema(db, -1); /* This is the only way out of this procedure. We have to ** release the mutexes on btrees that were acquired at the diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 7cab12f78..a2f4a2b48 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -2191,7 +2191,7 @@ int sqlite3VdbeHalt(Vdbe *p){ /* Rollback or commit any schema changes that occurred. */ if( p->rc!=SQLITE_OK && db->flags&SQLITE_InternChanges ){ - sqlite3ResetInternalSchema(db, 0); + sqlite3ResetInternalSchema(db, -1); db->flags = (db->flags | SQLITE_InternChanges); } diff --git a/src/vtab.c b/src/vtab.c index b9f1e6f34..30e302dea 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -48,7 +48,7 @@ static int createModule( if( pDel==pMod ){ db->mallocFailed = 1; } - sqlite3ResetInternalSchema(db, 0); + sqlite3ResetInternalSchema(db, -1); }else if( xDestroy ){ xDestroy(pAux); } |