Index: third_party/sqlite/src/src/vdbeblob.c |
diff --git a/third_party/sqlite/src/src/vdbeblob.c b/third_party/sqlite/src/src/vdbeblob.c |
index 18fdd465ae013996cfcfcdef18d04f39c9864228..71bd8816d5a22b0d623d55e01e70653390dd630e 100644 |
--- a/third_party/sqlite/src/src/vdbeblob.c |
+++ b/third_party/sqlite/src/src/vdbeblob.c |
@@ -64,7 +64,8 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){ |
rc = sqlite3_step(p->pStmt); |
if( rc==SQLITE_ROW ){ |
- u32 type = v->apCsr[0]->aType[p->iCol]; |
+ VdbeCursor *pC = v->apCsr[0]; |
+ u32 type = pC->aType[p->iCol]; |
if( type<12 ){ |
zErr = sqlite3MPrintf(p->db, "cannot open value of type %s", |
type==0?"null": type==7?"real": "integer" |
@@ -73,12 +74,10 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){ |
sqlite3_finalize(p->pStmt); |
p->pStmt = 0; |
}else{ |
- p->iOffset = v->apCsr[0]->aOffset[p->iCol]; |
+ p->iOffset = pC->aType[p->iCol + pC->nField]; |
p->nByte = sqlite3VdbeSerialTypeLen(type); |
- p->pCsr = v->apCsr[0]->pCursor; |
- sqlite3BtreeEnterCursor(p->pCsr); |
- sqlite3BtreeCacheOverflow(p->pCsr); |
- sqlite3BtreeLeaveCursor(p->pCsr); |
+ p->pCsr = pC->pCursor; |
+ sqlite3BtreeIncrblobCursor(p->pCsr); |
} |
} |
@@ -132,22 +131,20 @@ int sqlite3_blob_open( |
** which closes the b-tree cursor and (possibly) commits the |
** transaction. |
*/ |
+ static const int iLn = VDBE_OFFSET_LINENO(4); |
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 */ |
- |
+ /* {OP_Transaction, 0, 0, 0}, // 0: Inserted separately */ |
+ {OP_TableLock, 0, 0, 0}, /* 1: Acquire a read or write lock */ |
/* 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}, /* 5: Push the rowid to the stack */ |
- {OP_NotExists, 0, 10, 1}, /* 6: Seek the cursor */ |
- {OP_Column, 0, 0, 1}, /* 7 */ |
- {OP_ResultRow, 1, 0, 0}, /* 8 */ |
- {OP_Goto, 0, 5, 0}, /* 9 */ |
- {OP_Close, 0, 0, 0}, /* 10 */ |
- {OP_Halt, 0, 0, 0}, /* 11 */ |
+ {OP_OpenRead, 0, 0, 0}, /* 2: Open cursor 0 for reading */ |
+ {OP_OpenWrite, 0, 0, 0}, /* 3: Open cursor 0 for read/write */ |
+ {OP_Variable, 1, 1, 1}, /* 4: Push the rowid to the stack */ |
+ {OP_NotExists, 0, 10, 1}, /* 5: Seek the cursor */ |
+ {OP_Column, 0, 0, 1}, /* 6 */ |
+ {OP_ResultRow, 1, 0, 0}, /* 7 */ |
+ {OP_Goto, 0, 4, 0}, /* 8 */ |
+ {OP_Close, 0, 0, 0}, /* 9 */ |
+ {OP_Halt, 0, 0, 0}, /* 10 */ |
}; |
int rc = SQLITE_OK; |
@@ -178,6 +175,10 @@ int sqlite3_blob_open( |
pTab = 0; |
sqlite3ErrorMsg(pParse, "cannot open virtual table: %s", zTable); |
} |
+ if( pTab && !HasRowid(pTab) ){ |
+ pTab = 0; |
+ sqlite3ErrorMsg(pParse, "cannot open table without rowid: %s", zTable); |
+ } |
#ifndef SQLITE_OMIT_VIEW |
if( pTab && pTab->pSelect ){ |
pTab = 0; |
@@ -235,7 +236,7 @@ int sqlite3_blob_open( |
#endif |
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
int j; |
- for(j=0; j<pIdx->nColumn; j++){ |
+ for(j=0; j<pIdx->nKeyCol; j++){ |
if( pIdx->aiColumn[j]==iCol ){ |
zFault = "indexed"; |
} |
@@ -250,42 +251,37 @@ int sqlite3_blob_open( |
} |
} |
- pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(db); |
+ pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(pParse); |
assert( pBlob->pStmt || db->mallocFailed ); |
if( pBlob->pStmt ){ |
Vdbe *v = (Vdbe *)pBlob->pStmt; |
int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); |
- sqlite3VdbeAddOpList(v, sizeof(openBlob)/sizeof(VdbeOpList), openBlob); |
- |
- /* Configure the OP_Transaction */ |
- sqlite3VdbeChangeP1(v, 0, iDb); |
- sqlite3VdbeChangeP2(v, 0, flags); |
- |
- /* Configure the OP_VerifyCookie */ |
- sqlite3VdbeChangeP1(v, 1, iDb); |
- sqlite3VdbeChangeP2(v, 1, pTab->pSchema->schema_cookie); |
- sqlite3VdbeChangeP3(v, 1, pTab->pSchema->iGeneration); |
+ sqlite3VdbeAddOp4Int(v, OP_Transaction, iDb, flags, |
+ pTab->pSchema->schema_cookie, |
+ pTab->pSchema->iGeneration); |
+ sqlite3VdbeChangeP5(v, 1); |
+ sqlite3VdbeAddOpList(v, ArraySize(openBlob), openBlob, iLn); |
/* Make sure a mutex is held on the table to be accessed */ |
sqlite3VdbeUsesBtree(v, iDb); |
/* Configure the OP_TableLock instruction */ |
#ifdef SQLITE_OMIT_SHARED_CACHE |
- sqlite3VdbeChangeToNoop(v, 2, 1); |
+ sqlite3VdbeChangeToNoop(v, 1); |
#else |
- sqlite3VdbeChangeP1(v, 2, iDb); |
- sqlite3VdbeChangeP2(v, 2, pTab->tnum); |
- sqlite3VdbeChangeP3(v, 2, flags); |
- sqlite3VdbeChangeP4(v, 2, pTab->zName, P4_TRANSIENT); |
+ sqlite3VdbeChangeP1(v, 1, iDb); |
+ sqlite3VdbeChangeP2(v, 1, pTab->tnum); |
+ sqlite3VdbeChangeP3(v, 1, flags); |
+ sqlite3VdbeChangeP4(v, 1, pTab->zName, P4_TRANSIENT); |
#endif |
/* Remove either the OP_OpenWrite or OpenRead. Set the P2 |
** parameter of the other to pTab->tnum. */ |
- sqlite3VdbeChangeToNoop(v, 4 - flags, 1); |
- sqlite3VdbeChangeP2(v, 3 + flags, pTab->tnum); |
- sqlite3VdbeChangeP3(v, 3 + flags, iDb); |
+ sqlite3VdbeChangeToNoop(v, 3 - flags); |
+ sqlite3VdbeChangeP2(v, 2 + flags, pTab->tnum); |
+ sqlite3VdbeChangeP3(v, 2 + flags, iDb); |
/* Configure the number of columns. Configure the cursor to |
** think that the table has one more column than it really |
@@ -294,10 +290,13 @@ int sqlite3_blob_open( |
** we can invoke OP_Column to fill in the vdbe cursors type |
** and offset cache without causing any IO. |
*/ |
- sqlite3VdbeChangeP4(v, 3+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32); |
- sqlite3VdbeChangeP2(v, 7, pTab->nCol); |
+ sqlite3VdbeChangeP4(v, 2+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32); |
+ sqlite3VdbeChangeP2(v, 6, pTab->nCol); |
if( !db->mallocFailed ){ |
- sqlite3VdbeMakeReady(v, 1, 1, 1, 0, 0, 0); |
+ pParse->nVar = 1; |
+ pParse->nMem = 1; |
+ pParse->nTab = 1; |
+ sqlite3VdbeMakeReady(v, pParse); |
} |
} |
@@ -310,7 +309,7 @@ int sqlite3_blob_open( |
} |
sqlite3_bind_int64(pBlob->pStmt, 1, iRow); |
rc = blobSeekToRow(pBlob, iRow, &zErr); |
- } while( (++nAttempt)<5 && rc==SQLITE_SCHEMA ); |
+ } while( (++nAttempt)<SQLITE_MAX_SCHEMA_RETRY && rc==SQLITE_SCHEMA ); |
blob_open_out: |
if( rc==SQLITE_OK && db->mallocFailed==0 ){ |
@@ -319,8 +318,9 @@ blob_open_out: |
if( pBlob && pBlob->pStmt ) sqlite3VdbeFinalize((Vdbe *)pBlob->pStmt); |
sqlite3DbFree(db, pBlob); |
} |
- sqlite3Error(db, rc, (zErr ? "%s" : 0), zErr); |
+ sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr); |
sqlite3DbFree(db, zErr); |
+ sqlite3ParserReset(pParse); |
sqlite3StackFree(db, pParse); |
rc = sqlite3ApiExit(db, rc); |
sqlite3_mutex_leave(db->mutex); |
@@ -371,7 +371,7 @@ static int blobReadWrite( |
if( n<0 || iOffset<0 || (iOffset+n)>p->nByte ){ |
/* Request is out of range. Return a transient error. */ |
rc = SQLITE_ERROR; |
- sqlite3Error(db, SQLITE_ERROR, 0); |
+ sqlite3Error(db, SQLITE_ERROR); |
}else if( v==0 ){ |
/* If there is no statement handle, then the blob-handle has |
** already been invalidated. Return SQLITE_ABORT in this case. |
@@ -451,7 +451,7 @@ int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){ |
char *zErr; |
rc = blobSeekToRow(p, iRow, &zErr); |
if( rc!=SQLITE_OK ){ |
- sqlite3Error(db, rc, (zErr ? "%s" : 0), zErr); |
+ sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr); |
sqlite3DbFree(db, zErr); |
} |
assert( rc!=SQLITE_SCHEMA ); |