-C Add\stest\sfile\stest/count.test\sfor\stesting\s"SELECT\scount(*)"\sstatements.\sIt\sis\snot\sproperly\spopulated\syet.\s(CVS\s6318)
-D 2009-02-24T10:48:28
+C Enhanced\scomments\son\stable\slocking\slogic\sas\sit\srelates\sto\spreparing\snew\nstatements.\s\sAdded\sassert()\sand\stestcase()\sbut\sno\sother\schanges\sto\scode.\s(CVS\s6319)
+D 2009-02-24T16:18:05
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in d64baddbf55cdf33ff030e14da837324711a4ef7
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
F src/backup.c 2d3f31148d7b086c5c72d9edcd04fc2751b0aa6e
F src/bitvec.c 44f7059ac1f874d364b34af31b9617e52223ba75
F src/btmutex.c 63c5cc4ad5715690767ffcb741e185d7bc35ec1a
-F src/btree.c e0178d6fb69c8f332f3fba96cfc0b08275ad5e76
+F src/btree.c 8b8697ab5e8ca9aad12221bb9abfee1aed7a5cd1
F src/btree.h 96a019c9f28da38e79940512d7800e419cd8c702
F src/btreeInt.h 0a4884e6152d7cae9c741e91b830064c19fd2c05
F src/build.c a1db48aec62c95049d783f231195812ff97ae268
F src/pcache.h 9b927ccc5a538e31b4c3bc7eec4f976db42a1324
F src/pcache1.c dabb8ab14827e090321f17150ce96fda172974e8
F src/pragma.c 22ed04836aab8ce134c53be1ca896f3ad20fabdb
-F src/prepare.c d0bbb4b1a8b9c1db6d13788929839bb63764680e
+F src/prepare.c 1ede93a00f1835a10b3d3aad968e8f8ecd2c98dd
F src/printf.c 9866a9a9c4a90f6d4147407f373df3fd5d5f9b6f
F src/random.c 676b9d7ac820fe81e6fb2394ac8c10cff7f38628
F src/resolve.c dea005135845acbbfae1f2968c0deb6b2e3d580c
F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
-P 0e7c369c23a8767b4d3e5cdd47c14716992fb71a
-R 71f287412eb030dfd9b14d26e52b17fb
-U danielk1977
-Z e2d5b34166a5d213f9445c572c8e416e
+P a195d74ff9ce836447dba4da7edcc6f1cdae5574
+R 7311b1fa9b7b5c3d12ba433576f5510b
+U drh
+Z 99368cf9c56a6d99659a698dff53e252
-a195d74ff9ce836447dba4da7edcc6f1cdae5574
\ No newline at end of file
+4a12f5b818b769d7518c942ff3dedf453dde698e
\ No newline at end of file
** May you share freely, never taking more than you give.
**
*************************************************************************
-** $Id: btree.c,v 1.567 2009/02/24 10:01:52 danielk1977 Exp $
+** $Id: btree.c,v 1.568 2009/02/24 16:18:05 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** See the header comment on "btreeInt.h" for additional information.
}
/* This (along with lockTable()) is where the ReadUncommitted flag is
- ** dealt with. If the caller is querying for a read-lock and the flag is
- ** set, it is unconditionally granted - even if there are write-locks
+ ** dealt with. If the caller is querying for a read-lock on any table
+ ** other than the sqlite_master table (table 1) and if the ReadUncommitted
+ ** flag is set, then the lock granted even if there are write-locks
** on the table. If a write-lock is requested, the ReadUncommitted flag
** is not considered.
**
** ReadUncommitted flag is set, no entry is added to the locks list
** (BtShared.pLock).
**
- ** To summarize: If the ReadUncommitted flag is set, then read cursors do
- ** not create or respect table locks. The locking procedure for a
- ** write-cursor does not change.
+ ** To summarize: If the ReadUncommitted flag is set, then read cursors
+ ** on non-schema tables do not create or respect table locks. The locking
+ ** procedure for a write-cursor does not change.
*/
if(
0==(p->db->flags&SQLITE_ReadUncommitted) ||
assert( SQLITE_OK==queryTableLock(p, iTable, eLock) );
- /* If the read-uncommitted flag is set and a read-lock is requested,
- ** return early without adding an entry to the BtShared.pLock list. See
+ /* If the read-uncommitted flag is set and a read-lock is requested on
+ ** a non-schema table, then the lock is always granted. Return early
+ ** without adding an entry to the BtShared.pLock list. See
** comment in function queryTableLock() for more info on handling
** the ReadUncommitted flag.
*/
** interface, and routines that contribute to loading the database schema
** from disk.
**
-** $Id: prepare.c,v 1.106 2009/02/19 14:39:25 danielk1977 Exp $
+** $Id: prepare.c,v 1.107 2009/02/24 16:18:05 drh Exp $
*/
#include "sqliteInt.h"
assert( !db->mallocFailed );
assert( sqlite3_mutex_held(db->mutex) );
- /* If any attached database schemas are locked, do not proceed with
- ** compilation. Instead return SQLITE_LOCKED immediately.
+ /* Check to verify that it is possible to get a read lock on all
+ ** database schemas. The inability to get a read lock indicates that
+ ** some other database connection is holding a write-lock, which in
+ ** turn means that the other connection has made uncommitted changes
+ ** to the schema.
+ **
+ ** Were we to proceed and prepare the statement against the uncommitted
+ ** schema changes and if those schema changes are subsequently rolled
+ ** back and different changes are made in their place, then when this
+ ** prepared statement goes to run the schema cookie would fail to detect
+ ** the schema change. Disaster would follow.
+ **
+ ** This thread is currently holding mutexes on all Btrees (because
+ ** of the sqlite3BtreeEnterAll() in sqlite3LockAndPrepare()) so it
+ ** is not possible for another thread to start a new schema change
+ ** while this routine is running. Hence, we do not need to hold
+ ** locks on the schema, we just need to make sure nobody else is
+ ** holding them.
+ **
+ ** Note that setting READ_UNCOMMITTED overrides most lock detection,
+ ** but it does *not* override schema lock detection, so this all still
+ ** works even if READ_UNCOMMITTED is set.
*/
for(i=0; i<db->nDb; i++) {
Btree *pBt = db->aDb[i].pBt;
if( pBt ){
+ assert( sqlite3BtreeHoldsMutex(pBt) );
rc = sqlite3BtreeSchemaLocked(pBt);
if( rc ){
const char *zDb = db->aDb[i].zName;
sqlite3Error(db, SQLITE_LOCKED, "database schema is locked: %s", zDb);
(void)sqlite3SafetyOff(db);
+ testcase( db->flags & SQLITE_ReadUncommitted );
return sqlite3ApiExit(db, SQLITE_LOCKED);
}
}