mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Simplify the way the read-uncommitted flag is handled to facilitate test coverage. (CVS 6841)
FossilOrigin-Name: e2112d6160a82ccd4b6a1c798d2064d0f1b086eb
This commit is contained in:
16
manifest
16
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Make\sexplicit\sthe\srestrictions\son\sUPDATE,\sDELETE,\sand\sINSERT\sstatement\ssyntax\nwithin\striggers.\s\sTicket\s#3947.\s(CVS\s6840)
|
C Simplify\sthe\sway\sthe\sread-uncommitted\sflag\sis\shandled\sto\sfacilitate\stest\scoverage.\s(CVS\s6841)
|
||||||
D 2009-07-03T15:37:28
|
D 2009-07-03T16:25:07
|
||||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||||
F Makefile.in 8b8fb7823264331210cddf103831816c286ba446
|
F Makefile.in 8b8fb7823264331210cddf103831816c286ba446
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@@ -106,7 +106,7 @@ F src/auth.c 802a9439dfa0b8c208b10055cba400e82ef18025
|
|||||||
F src/backup.c 97a3859d8585eb4fcb1e81a795cf4b3fdd82f30f
|
F src/backup.c 97a3859d8585eb4fcb1e81a795cf4b3fdd82f30f
|
||||||
F src/bitvec.c 0ef0651714728055d43de7a4cdd95e703fac0119
|
F src/bitvec.c 0ef0651714728055d43de7a4cdd95e703fac0119
|
||||||
F src/btmutex.c 9b899c0d8df3bd68f527b0afe03088321b696d3c
|
F src/btmutex.c 9b899c0d8df3bd68f527b0afe03088321b696d3c
|
||||||
F src/btree.c 8a3f74aeea07833a7dd62ccd60c5486a17b2044c
|
F src/btree.c b7f75130f8699903fe3b699d0591493dc26c4454
|
||||||
F src/btree.h 8cae6364735a5cb2d577ddb23fa6d0e655a4b931
|
F src/btree.h 8cae6364735a5cb2d577ddb23fa6d0e655a4b931
|
||||||
F src/btreeInt.h b31e5ac04181c7e2892c33ab06228c551df6233c
|
F src/btreeInt.h b31e5ac04181c7e2892c33ab06228c551df6233c
|
||||||
F src/build.c 867028ee9f63f7bc8eb8d4a720bb98cf9b9a12b4
|
F src/build.c 867028ee9f63f7bc8eb8d4a720bb98cf9b9a12b4
|
||||||
@@ -203,7 +203,7 @@ F src/update.c a1bbe774bce495d62dce3df3f42a5f04c1de173a
|
|||||||
F src/utf.c 9541d28f40441812c0b40f00334372a0542c00ff
|
F src/utf.c 9541d28f40441812c0b40f00334372a0542c00ff
|
||||||
F src/util.c 861d5b5c58be4921f0a254489ea94cb15f550ef8
|
F src/util.c 861d5b5c58be4921f0a254489ea94cb15f550ef8
|
||||||
F src/vacuum.c 3fe0eebea6d2311c1c2ab2962887d11f7a4dcfb0
|
F src/vacuum.c 3fe0eebea6d2311c1c2ab2962887d11f7a4dcfb0
|
||||||
F src/vdbe.c 7e5781773b62c4ef1569e58340f2ca9a034a08b5
|
F src/vdbe.c bdf25930bddbf57b18a0be7b1127b357306d2094
|
||||||
F src/vdbe.h 35a648bc3279a120da24f34d9a25213ec15daf8a
|
F src/vdbe.h 35a648bc3279a120da24f34d9a25213ec15daf8a
|
||||||
F src/vdbeInt.h 831c254a6eef237ef4664c8381a0137586567007
|
F src/vdbeInt.h 831c254a6eef237ef4664c8381a0137586567007
|
||||||
F src/vdbeapi.c 0ab8ada7260b32031ca97f338caecf0812460624
|
F src/vdbeapi.c 0ab8ada7260b32031ca97f338caecf0812460624
|
||||||
@@ -739,7 +739,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
|||||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
F tool/vdbe-compress.tcl 672f81d693a03f80f5ae60bfefacd8a349e76746
|
F tool/vdbe-compress.tcl 672f81d693a03f80f5ae60bfefacd8a349e76746
|
||||||
P 304c5110ad958b2cc1ddff30e68c8791109128b5
|
P c8bf40df7be728b11bb633516d1988c6064a9d70
|
||||||
R 23c00185520dd16e8ecfdeb38c15386d
|
R 736933d9248a6cfe52584a62da904241
|
||||||
U drh
|
U danielk1977
|
||||||
Z eccd19ba4bfa8e991ddfacf0b5d84154
|
Z 07814554177b18b70ae436ac81d295ec
|
||||||
|
@@ -1 +1 @@
|
|||||||
c8bf40df7be728b11bb633516d1988c6064a9d70
|
e2112d6160a82ccd4b6a1c798d2064d0f1b086eb
|
86
src/btree.c
86
src/btree.c
@@ -9,7 +9,7 @@
|
|||||||
** May you share freely, never taking more than you give.
|
** 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.
|
** This file implements a external (disk-based) database using BTrees.
|
||||||
** See the header comment on "btreeInt.h" for additional information.
|
** See the header comment on "btreeInt.h" for additional information.
|
||||||
@@ -202,6 +202,7 @@ static int querySharedCacheTableLock(Btree *p, Pgno iTab, u8 eLock){
|
|||||||
assert( sqlite3BtreeHoldsMutex(p) );
|
assert( sqlite3BtreeHoldsMutex(p) );
|
||||||
assert( eLock==READ_LOCK || eLock==WRITE_LOCK );
|
assert( eLock==READ_LOCK || eLock==WRITE_LOCK );
|
||||||
assert( p->db!=0 );
|
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
|
/* 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
|
** transaction on this file. And, obviously, for this to be so there
|
||||||
@@ -223,47 +224,25 @@ static int querySharedCacheTableLock(Btree *p, Pgno iTab, u8 eLock){
|
|||||||
return SQLITE_LOCKED_SHAREDCACHE;
|
return SQLITE_LOCKED_SHAREDCACHE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This (along with setSharedCacheTableLock()) is where
|
for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
|
||||||
** the ReadUncommitted flag is dealt with.
|
/* The condition (pIter->eLock!=eLock) in the following if(...)
|
||||||
** If the caller is querying for a read-lock on any table
|
** statement is a simplification of:
|
||||||
** 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
|
** (eLock==WRITE_LOCK || pIter->eLock==WRITE_LOCK)
|
||||||
** on the table. If a write-lock is requested, the ReadUncommitted flag
|
**
|
||||||
** is not considered.
|
** 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
|
||||||
** In function setSharedCacheTableLock(), if a read-lock is demanded and the
|
** only be a single writer).
|
||||||
** ReadUncommitted flag is set, no entry is added to the locks list
|
*/
|
||||||
** (BtShared.pLock).
|
assert( pIter->eLock==READ_LOCK || pIter->eLock==WRITE_LOCK );
|
||||||
**
|
assert( eLock==READ_LOCK || pIter->pBtree==p || pIter->eLock==READ_LOCK);
|
||||||
** To summarize: If the ReadUncommitted flag is set, then read cursors
|
if( pIter->pBtree!=p && pIter->iTable==iTab && pIter->eLock!=eLock ){
|
||||||
** on non-schema tables do not create or respect table locks. The locking
|
sqlite3ConnectionBlocked(p->db, pIter->pBtree->db);
|
||||||
** procedure for a write-cursor does not change.
|
if( eLock==WRITE_LOCK ){
|
||||||
*/
|
assert( p==pBt->pWriter );
|
||||||
if(
|
pBt->isPending = 1;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
return SQLITE_LOCKED_SHAREDCACHE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
@@ -288,6 +267,12 @@ static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){
|
|||||||
assert( eLock==READ_LOCK || eLock==WRITE_LOCK );
|
assert( eLock==READ_LOCK || eLock==WRITE_LOCK );
|
||||||
assert( p->db!=0 );
|
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 */
|
/* This is a no-op if the shared-cache is not enabled */
|
||||||
if( !p->sharable ){
|
if( !p->sharable ){
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
@@ -295,20 +280,6 @@ static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){
|
|||||||
|
|
||||||
assert( SQLITE_OK==querySharedCacheTableLock(p, iTable, eLock) );
|
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. */
|
/* First search the list for an existing lock on this table. */
|
||||||
for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
|
for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
|
||||||
if( pIter->iTable==iTable && pIter->pBtree==p ){
|
if( pIter->iTable==iTable && pIter->pBtree==p ){
|
||||||
@@ -395,6 +366,9 @@ static void clearAllSharedCacheTableLocks(Btree *p){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** This function changes all write-locks held by connection p to read-locks.
|
||||||
|
*/
|
||||||
static void downgradeAllSharedCacheTableLocks(Btree *p){
|
static void downgradeAllSharedCacheTableLocks(Btree *p){
|
||||||
BtShared *pBt = p->pBt;
|
BtShared *pBt = p->pBt;
|
||||||
if( pBt->pWriter==p ){
|
if( pBt->pWriter==p ){
|
||||||
@@ -7032,7 +7006,7 @@ void sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){
|
|||||||
|
|
||||||
sqlite3BtreeEnter(p);
|
sqlite3BtreeEnter(p);
|
||||||
assert( p->inTrans>TRANS_NONE );
|
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( pBt->pPage1 );
|
||||||
assert( idx>=0 && idx<=15 );
|
assert( idx>=0 && idx<=15 );
|
||||||
|
|
||||||
|
25
src/vdbe.c
25
src/vdbe.c
@@ -43,7 +43,7 @@
|
|||||||
** in this file for details. If in doubt, do not deviate from existing
|
** in this file for details. If in doubt, do not deviate from existing
|
||||||
** commenting and indentation practices when changing or adding code.
|
** 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 "sqliteInt.h"
|
||||||
#include "vdbeInt.h"
|
#include "vdbeInt.h"
|
||||||
@@ -5003,18 +5003,17 @@ case OP_Expire: {
|
|||||||
** used to generate an error message if the lock cannot be obtained.
|
** used to generate an error message if the lock cannot be obtained.
|
||||||
*/
|
*/
|
||||||
case OP_TableLock: {
|
case OP_TableLock: {
|
||||||
int p1;
|
u8 isWriteLock = (u8)pOp->p3;
|
||||||
u8 isWriteLock;
|
if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommitted) ){
|
||||||
|
int p1 = pOp->p1;
|
||||||
p1 = pOp->p1;
|
assert( p1>=0 && p1<db->nDb );
|
||||||
isWriteLock = (u8)pOp->p3;
|
assert( (p->btreeMask & (1<<p1))!=0 );
|
||||||
assert( p1>=0 && p1<db->nDb );
|
assert( isWriteLock==0 || isWriteLock==1 );
|
||||||
assert( (p->btreeMask & (1<<p1))!=0 );
|
rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock);
|
||||||
assert( isWriteLock==0 || isWriteLock==1 );
|
if( (rc&0xFF)==SQLITE_LOCKED ){
|
||||||
rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock);
|
const char *z = pOp->p4.z;
|
||||||
if( (rc&0xFF)==SQLITE_LOCKED ){
|
sqlite3SetString(&p->zErrMsg, db, "database table is locked: %s", z);
|
||||||
const char *z = pOp->p4.z;
|
}
|
||||||
sqlite3SetString(&p->zErrMsg, db, "database table is locked: %s", z);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user