-C Make\sexplicit\sthe\srestrictions\son\sUPDATE,\sDELETE,\sand\sINSERT\sstatement\ssyntax\nwithin\striggers.\s\sTicket\s#3947.\s(CVS\s6840)
-D 2009-07-03T15:37:28
+C Simplify\sthe\sway\sthe\sread-uncommitted\sflag\sis\shandled\sto\sfacilitate\stest\scoverage.\s(CVS\s6841)
+D 2009-07-03T16:25:07
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in 8b8fb7823264331210cddf103831816c286ba446
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
F src/backup.c 97a3859d8585eb4fcb1e81a795cf4b3fdd82f30f
F src/bitvec.c 0ef0651714728055d43de7a4cdd95e703fac0119
F src/btmutex.c 9b899c0d8df3bd68f527b0afe03088321b696d3c
-F src/btree.c 8a3f74aeea07833a7dd62ccd60c5486a17b2044c
+F src/btree.c b7f75130f8699903fe3b699d0591493dc26c4454
F src/btree.h 8cae6364735a5cb2d577ddb23fa6d0e655a4b931
F src/btreeInt.h b31e5ac04181c7e2892c33ab06228c551df6233c
F src/build.c 867028ee9f63f7bc8eb8d4a720bb98cf9b9a12b4
F src/utf.c 9541d28f40441812c0b40f00334372a0542c00ff
F src/util.c 861d5b5c58be4921f0a254489ea94cb15f550ef8
F src/vacuum.c 3fe0eebea6d2311c1c2ab2962887d11f7a4dcfb0
-F src/vdbe.c 7e5781773b62c4ef1569e58340f2ca9a034a08b5
+F src/vdbe.c bdf25930bddbf57b18a0be7b1127b357306d2094
F src/vdbe.h 35a648bc3279a120da24f34d9a25213ec15daf8a
F src/vdbeInt.h 831c254a6eef237ef4664c8381a0137586567007
F src/vdbeapi.c 0ab8ada7260b32031ca97f338caecf0812460624
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl 672f81d693a03f80f5ae60bfefacd8a349e76746
-P 304c5110ad958b2cc1ddff30e68c8791109128b5
-R 23c00185520dd16e8ecfdeb38c15386d
-U drh
-Z eccd19ba4bfa8e991ddfacf0b5d84154
+P c8bf40df7be728b11bb633516d1988c6064a9d70
+R 736933d9248a6cfe52584a62da904241
+U danielk1977
+Z 07814554177b18b70ae436ac81d295ec
** May you share freely, never taking more than you give.
**
*************************************************************************
-** $Id: btree.c,v 1.649 2009/07/02 17:21:58 danielk1977 Exp $
+** $Id: btree.c,v 1.650 2009/07/03 16:25:07 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** See the header comment on "btreeInt.h" for additional information.
assert( sqlite3BtreeHoldsMutex(p) );
assert( eLock==READ_LOCK || eLock==WRITE_LOCK );
assert( p->db!=0 );
+ assert( !(p->db->flags&SQLITE_ReadUncommitted)||eLock==WRITE_LOCK||iTab==1 );
/* If requesting a write-lock, then the Btree must have an open write
** transaction on this file. And, obviously, for this to be so there
return SQLITE_LOCKED_SHAREDCACHE;
}
- /* This (along with setSharedCacheTableLock()) is where
- ** the ReadUncommitted flag is 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.
- **
- ** In function setSharedCacheTableLock(), if a read-lock is demanded and the
- ** 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
- ** 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) ||
- eLock==WRITE_LOCK ||
- iTab==MASTER_ROOT
- ){
- for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
- /* The condition (pIter->eLock!=eLock) in the following if(...)
- ** statement is a simplification of:
- **
- ** (eLock==WRITE_LOCK || pIter->eLock==WRITE_LOCK)
- **
- ** since we know that if eLock==WRITE_LOCK, then no other connection
- ** may hold a WRITE_LOCK on any table in this file (since there can
- ** only be a single writer).
- */
- assert( pIter->eLock==READ_LOCK || pIter->eLock==WRITE_LOCK );
- assert( eLock==READ_LOCK || pIter->pBtree==p || pIter->eLock==READ_LOCK);
- if( pIter->pBtree!=p && pIter->iTable==iTab && pIter->eLock!=eLock ){
- sqlite3ConnectionBlocked(p->db, pIter->pBtree->db);
- if( eLock==WRITE_LOCK ){
- assert( p==pBt->pWriter );
- pBt->isPending = 1;
- }
- return SQLITE_LOCKED_SHAREDCACHE;
+ for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
+ /* The condition (pIter->eLock!=eLock) in the following if(...)
+ ** statement is a simplification of:
+ **
+ ** (eLock==WRITE_LOCK || pIter->eLock==WRITE_LOCK)
+ **
+ ** since we know that if eLock==WRITE_LOCK, then no other connection
+ ** may hold a WRITE_LOCK on any table in this file (since there can
+ ** only be a single writer).
+ */
+ assert( pIter->eLock==READ_LOCK || pIter->eLock==WRITE_LOCK );
+ assert( eLock==READ_LOCK || pIter->pBtree==p || pIter->eLock==READ_LOCK);
+ if( pIter->pBtree!=p && pIter->iTable==iTab && pIter->eLock!=eLock ){
+ sqlite3ConnectionBlocked(p->db, pIter->pBtree->db);
+ if( eLock==WRITE_LOCK ){
+ assert( p==pBt->pWriter );
+ pBt->isPending = 1;
}
+ return SQLITE_LOCKED_SHAREDCACHE;
}
}
return SQLITE_OK;
assert( eLock==READ_LOCK || eLock==WRITE_LOCK );
assert( p->db!=0 );
+ /* A connection with the read-uncommitted flag set will never try to
+ ** obtain a read-lock using this function. The only read-lock obtained
+ ** by a connection in read-uncommitted mode is on the sqlite_master
+ ** table, and that lock is obtained in BtreeBeginTrans(). */
+ assert( 0==(p->db->flags&SQLITE_ReadUncommitted) || eLock==WRITE_LOCK );
+
/* This is a no-op if the shared-cache is not enabled */
if( !p->sharable ){
return SQLITE_OK;
assert( SQLITE_OK==querySharedCacheTableLock(p, iTable, eLock) );
- /* 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 querySharedCacheTableLock() for more info
- ** on handling the ReadUncommitted flag.
- */
- if(
- (p->db->flags&SQLITE_ReadUncommitted) &&
- (eLock==READ_LOCK) &&
- iTable!=MASTER_ROOT
- ){
- return SQLITE_OK;
- }
-
/* First search the list for an existing lock on this table. */
for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
if( pIter->iTable==iTable && pIter->pBtree==p ){
}
}
+/*
+** This function changes all write-locks held by connection p to read-locks.
+*/
static void downgradeAllSharedCacheTableLocks(Btree *p){
BtShared *pBt = p->pBt;
if( pBt->pWriter==p ){
sqlite3BtreeEnter(p);
assert( p->inTrans>TRANS_NONE );
- assert( SQLITE_OK==querySharedCacheTableLock(p, 1, READ_LOCK) );
+ assert( SQLITE_OK==querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK) );
assert( pBt->pPage1 );
assert( idx>=0 && idx<=15 );
** in this file for details. If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
-** $Id: vdbe.c,v 1.868 2009/07/02 07:47:33 danielk1977 Exp $
+** $Id: vdbe.c,v 1.869 2009/07/03 16:25:07 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "vdbeInt.h"
** used to generate an error message if the lock cannot be obtained.
*/
case OP_TableLock: {
- int p1;
- u8 isWriteLock;
-
- p1 = pOp->p1;
- isWriteLock = (u8)pOp->p3;
- assert( p1>=0 && p1<db->nDb );
- assert( (p->btreeMask & (1<<p1))!=0 );
- assert( isWriteLock==0 || isWriteLock==1 );
- rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock);
- if( (rc&0xFF)==SQLITE_LOCKED ){
- const char *z = pOp->p4.z;
- sqlite3SetString(&p->zErrMsg, db, "database table is locked: %s", z);
+ u8 isWriteLock = (u8)pOp->p3;
+ if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommitted) ){
+ int p1 = pOp->p1;
+ assert( p1>=0 && p1<db->nDb );
+ assert( (p->btreeMask & (1<<p1))!=0 );
+ assert( isWriteLock==0 || isWriteLock==1 );
+ rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock);
+ if( (rc&0xFF)==SQLITE_LOCKED ){
+ const char *z = pOp->p4.z;
+ sqlite3SetString(&p->zErrMsg, db, "database table is locked: %s", z);
+ }
}
break;
}