aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/btree.c14
-rw-r--r--src/btree.h3
-rw-r--r--src/prepare.c20
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) ){