diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/btree.c | 14 | ||||
-rw-r--r-- | src/btree.h | 3 | ||||
-rw-r--r-- | src/prepare.c | 20 |
3 files changed, 30 insertions, 7 deletions
diff --git a/src/btree.c b/src/btree.c index 79de82c8d..c1032f509 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree.c,v 1.281 2006/01/06 06:33:12 danielk1977 Exp $ +** $Id: btree.c,v 1.282 2006/01/06 13:00:29 danielk1977 Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to @@ -601,7 +601,7 @@ static int restoreCursorPosition(BtCursor *pCur, int doSeek){ ** Query to see if btree handle p may obtain a lock of type eLock ** (READ_LOCK or WRITE_LOCK) on the table with root-page iTab. Return ** SQLITE_OK if the lock may be obtained (by calling lockTable()), or -** SQLITE_BUSY if not. +** SQLITE_LOCKED if not. */ static int queryTableLock(Btree *p, Pgno iTab, u8 eLock){ BtShared *pBt = p->pBt; @@ -635,7 +635,7 @@ static int queryTableLock(Btree *p, Pgno iTab, u8 eLock){ for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){ if( pIter->pBtree!=p && pIter->iTable==iTab && (pIter->eLock!=eLock || eLock!=READ_LOCK) ){ - return SQLITE_BUSY; + return SQLITE_LOCKED; } } } @@ -6484,6 +6484,14 @@ void *sqlite3BtreeSchema(Btree *p, int nBytes, void(*xFree)(void *)){ return pBt->pSchema; } +/* +** Return true if another user of the same shared btree as the argument +** handle holds an exclusive lock on the sqlite_master table. +*/ +int sqlite3BtreeSchemaLocked(Btree *p){ + return (queryTableLock(p, MASTER_ROOT, READ_LOCK)!=SQLITE_OK); +} + #ifndef SQLITE_OMIT_SHARED_CACHE /* ** Enable the shared pager and schema features. diff --git a/src/btree.h b/src/btree.h index 69eb34fbf..6a65813c9 100644 --- a/src/btree.h +++ b/src/btree.h @@ -13,7 +13,7 @@ ** subsystem. See comments in the source code for a detailed description ** of what each interface routine does. ** -** @(#) $Id: btree.h,v 1.67 2006/01/05 11:34:34 danielk1977 Exp $ +** @(#) $Id: btree.h,v 1.68 2006/01/06 13:00:30 danielk1977 Exp $ */ #ifndef _BTREE_H_ #define _BTREE_H_ @@ -77,6 +77,7 @@ int sqlite3BtreeIsInTrans(Btree*); int sqlite3BtreeIsInStmt(Btree*); int sqlite3BtreeSync(Btree*, const char *zMaster); void *sqlite3BtreeSchema(Btree *, int, void(*)(void *)); +int sqlite3BtreeSchemaLocked(Btree *); const char *sqlite3BtreeGetFilename(Btree *); const char *sqlite3BtreeGetDirname(Btree *); diff --git a/src/prepare.c b/src/prepare.c index 6a75aa2ff..564aff53b 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.13 2006/01/05 11:34:34 danielk1977 Exp $ +** $Id: prepare.c,v 1.14 2006/01/06 13:00:30 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -436,8 +436,9 @@ int sqlite3_prepare( Parse sParse; char *zErrMsg = 0; int rc = SQLITE_OK; + int i; - assert(!sqlite3Tsd()->mallocFailed); + assert( !sqlite3Tsd()->mallocFailed ); assert( ppStmt ); *ppStmt = 0; @@ -445,6 +446,19 @@ int sqlite3_prepare( return SQLITE_MISUSE; } + /* If any attached database schemas are locked, do not proceed with + ** compilation. Instead return SQLITE_LOCKED immediately. + */ + for(i=0; i<db->nDb; i++) { + Btree *pBt = db->aDb[i].pBt; + if( pBt && sqlite3BtreeSchemaLocked(pBt) ){ + const char *zDb = db->aDb[i].zName; + sqlite3Error(db, SQLITE_LOCKED, "database schema is locked: %s", zDb); + sqlite3SafetyOff(db); + return SQLITE_LOCKED; + } + } + memset(&sParse, 0, sizeof(sParse)); sParse.db = db; sqlite3RunParser(&sParse, zSql, &zErrMsg); @@ -524,7 +538,7 @@ int sqlite3_prepare16( ** tricky bit is figuring out the pointer to return in *pzTail. */ char *zSql8 = 0; - char *zTail8 = 0; + const char *zTail8 = 0; int rc; if( sqlite3SafetyCheck(db) ){ |