Cause incremental-blob read/write operations lock shared-cache tables in the same way as normal SQL read/writes. Add complex assert statements to make sure tehe correct shared-cache locks are held when accessing the database. Eliminate some redundant checks from btree.c. (CVS 6830)
FossilOrigin-Name: f17ef37897da9bcaf20b5acdce6840522c0a0b16
diff --git a/src/vdbeblob.c b/src/vdbeblob.c
index d60a0d9..b08cec3 100644
--- a/src/vdbeblob.c
+++ b/src/vdbeblob.c
@@ -12,7 +12,7 @@
**
** This file contains code used to implement incremental BLOB I/O.
**
-** $Id: vdbeblob.c,v 1.33 2009/06/01 19:53:31 drh Exp $
+** $Id: vdbeblob.c,v 1.34 2009/06/29 06:00:37 danielk1977 Exp $
*/
#include "sqliteInt.h"
@@ -66,19 +66,18 @@
static const VdbeOpList openBlob[] = {
{OP_Transaction, 0, 0, 0}, /* 0: Start a transaction */
{OP_VerifyCookie, 0, 0, 0}, /* 1: Check the schema cookie */
+ {OP_TableLock, 0, 0, 0}, /* 2: Acquire a read or write lock */
- /* One of the following two instructions is replaced by an
- ** OP_Noop before exection.
- */
- {OP_OpenRead, 0, 0, 0}, /* 2: Open cursor 0 for reading */
- {OP_OpenWrite, 0, 0, 0}, /* 3: Open cursor 0 for read/write */
+ /* One of the following two instructions is replaced by an OP_Noop. */
+ {OP_OpenRead, 0, 0, 0}, /* 3: Open cursor 0 for reading */
+ {OP_OpenWrite, 0, 0, 0}, /* 4: Open cursor 0 for read/write */
- {OP_Variable, 1, 1, 1}, /* 4: Push the rowid to the stack */
- {OP_NotExists, 0, 8, 1}, /* 5: Seek the cursor */
- {OP_Column, 0, 0, 1}, /* 6 */
- {OP_ResultRow, 1, 0, 0}, /* 7 */
- {OP_Close, 0, 0, 0}, /* 8 */
- {OP_Halt, 0, 0, 0}, /* 9 */
+ {OP_Variable, 1, 1, 1}, /* 5: Push the rowid to the stack */
+ {OP_NotExists, 0, 9, 1}, /* 6: Seek the cursor */
+ {OP_Column, 0, 0, 1}, /* 7 */
+ {OP_ResultRow, 1, 0, 0}, /* 8 */
+ {OP_Close, 0, 0, 0}, /* 9 */
+ {OP_Halt, 0, 0, 0}, /* 10 */
};
Vdbe *v = 0;
@@ -170,10 +169,11 @@
if( v ){
int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
sqlite3VdbeAddOpList(v, sizeof(openBlob)/sizeof(VdbeOpList), openBlob);
+ flags = !!flags; /* flags = (flags ? 1 : 0); */
/* Configure the OP_Transaction */
sqlite3VdbeChangeP1(v, 0, iDb);
- sqlite3VdbeChangeP2(v, 0, (flags ? 1 : 0));
+ sqlite3VdbeChangeP2(v, 0, flags);
/* Configure the OP_VerifyCookie */
sqlite3VdbeChangeP1(v, 1, iDb);
@@ -182,13 +182,17 @@
/* Make sure a mutex is held on the table to be accessed */
sqlite3VdbeUsesBtree(v, iDb);
+ /* Configure the OP_TableLock instruction */
+ sqlite3VdbeChangeP1(v, 2, iDb);
+ sqlite3VdbeChangeP2(v, 2, pTab->tnum);
+ sqlite3VdbeChangeP3(v, 2, flags);
+ sqlite3VdbeChangeP4(v, 2, pTab->zName, P4_TRANSIENT);
+
/* Remove either the OP_OpenWrite or OpenRead. Set the P2
- ** parameter of the other to pTab->tnum.
- */
- flags = !!flags;
- sqlite3VdbeChangeToNoop(v, 3 - flags, 1);
- sqlite3VdbeChangeP2(v, 2 + flags, pTab->tnum);
- sqlite3VdbeChangeP3(v, 2 + flags, iDb);
+ ** parameter of the other to pTab->tnum. */
+ sqlite3VdbeChangeToNoop(v, 4 - flags, 1);
+ sqlite3VdbeChangeP2(v, 3 + flags, pTab->tnum);
+ sqlite3VdbeChangeP3(v, 3 + flags, iDb);
/* Configure the number of columns. Configure the cursor to
** think that the table has one more column than it really
@@ -197,8 +201,8 @@
** we can invoke OP_Column to fill in the vdbe cursors type
** and offset cache without causing any IO.
*/
- sqlite3VdbeChangeP4(v, 2+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32);
- sqlite3VdbeChangeP2(v, 6, pTab->nCol);
+ sqlite3VdbeChangeP4(v, 3+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32);
+ sqlite3VdbeChangeP2(v, 7, pTab->nCol);
if( !db->mallocFailed ){
sqlite3VdbeMakeReady(v, 1, 1, 1, 0);
}