Fix up all VDBE opcodes so that they cause an immediate exit on any kind of

error, and thereby eliminate the need to test "rc" at the top of the loop.
Resulting code is a little smaller and faster.

FossilOrigin-Name: a444633a827642bcf4d02a461e7e5f66769d39fd
This commit is contained in:
drh 2016-02-17 18:44:11 +00:00
parent b5a55ce77d
commit 9467abf3dd
3 changed files with 140 additions and 101 deletions

View File

@ -1,5 +1,5 @@
C Bump\sthe\sversion\snumber\sto\s3.12.0.
D 2016-02-17T15:01:18.374
C Fix\sup\sall\sVDBE\sopcodes\sso\sthat\sthey\scause\san\simmediate\sexit\son\sany\skind\sof\nerror,\sand\sthereby\seliminate\sthe\sneed\sto\stest\s"rc"\sat\sthe\stop\sof\sthe\sloop.\nResulting\scode\sis\sa\slittle\ssmaller\sand\sfaster.
D 2016-02-17T18:44:11.129
F Makefile.in 4e90dc1521879022aa9479268a4cd141d1771142
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 30f075dc4f27a07abb76088946b2944178d85347
@ -414,7 +414,7 @@ F src/update.c a7eeeaffad59c6506f01303a071dac11de8269ca
F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
F src/util.c 8073bbdab9cc7209f6741bd44264ede606cbadc6
F src/vacuum.c feb1eabb20987983d9350cad98299b21fa811f52
F src/vdbe.c ad4d5b7ad65793886b09c925fb5d1d74ac78f1a4
F src/vdbe.c 4eef77da4b81763a25992cc060506c001ebd4e3d
F src/vdbe.h c743791f723049db94f009e3e30958952bc2d512
F src/vdbeInt.h 4b69d5451bcadd473e745af53ef1e8abfdce0a79
F src/vdbeapi.c bfc06382d5089944388a90e4f90bb1e975b3613d
@ -1428,7 +1428,10 @@ F tool/vdbe_profile.tcl 246d0da094856d72d2c12efec03250d71639d19f
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh a98af506df552f3b3c0d904f94e4cdc4e1a6d598
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 87e6e225aea3a4d10476d16eab4a6403a4a128c9
R c239316472226b2429c7b466d6a49ed7
P c17d7276b8c114df5fe6e9ea14d59758443c281b
R 99549bba2f02d5e0c4a44abe6153e853
T *branch * vdbe-performance
T *sym-vdbe-performance *
T -sym-trunk *
U drh
Z 28d335fbd5135b0e539f7ad24d2e095e
Z 63c3fbdaa7e2321f71ac02a9835490a1

View File

@ -1 +1 @@
c17d7276b8c114df5fe6e9ea14d59758443c281b
a444633a827642bcf4d02a461e7e5f66769d39fd

View File

@ -627,7 +627,11 @@ int sqlite3VdbeExec(
}
sqlite3EndBenignMalloc();
#endif
for(pOp=&aOp[p->pc]; rc==SQLITE_OK; pOp++){
for(pOp=&aOp[p->pc]; 1; pOp++){
/* Errors are detected by individual opcodes, with an immediate
** jumps to abort_due_to_error. */
assert( rc==SQLITE_OK );
assert( pOp>=aOp && pOp<&aOp[p->nOp]);
#ifdef VDBE_PROFILE
start = sqlite3Hwtime();
@ -774,7 +778,7 @@ check_for_interrupt:
nProgressLimit = nVmStep + db->nProgressOps - (nVmStep%db->nProgressOps);
if( db->xProgress(db->pProgressArg) ){
rc = SQLITE_INTERRUPT;
goto vdbe_error_halt;
goto abort_due_to_error;
}
}
#endif
@ -1053,7 +1057,10 @@ case OP_String8: { /* same as TK_STRING, out2 */
#ifndef SQLITE_OMIT_UTF16
if( encoding!=SQLITE_UTF8 ){
rc = sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC);
if( rc==SQLITE_TOOBIG ) goto too_big;
if( rc ){
assert( rc==SQLITE_TOOBIG ); /* This is the only possible error here */
goto too_big;
}
if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem;
assert( pOut->szMalloc>0 && pOut->zMalloc==pOut->z );
assert( VdbeMemDynamic(pOut)==0 );
@ -1319,7 +1326,7 @@ case OP_ResultRow: {
&& db->xProgress(db->pProgressArg)!=0
){
rc = SQLITE_INTERRUPT;
goto vdbe_error_halt;
goto abort_due_to_error;
}
#endif
@ -1329,7 +1336,7 @@ case OP_ResultRow: {
if( SQLITE_OK!=(rc = sqlite3VdbeCheckFk(p, 0)) ){
assert( db->flags&SQLITE_CountRows );
assert( p->usesStmtJournal );
break;
goto abort_due_to_error;
}
/* If the SQLITE_CountRows flag is set in sqlite3.flags mask, then
@ -1349,9 +1356,7 @@ case OP_ResultRow: {
*/
assert( p->iStatement==0 || db->flags&SQLITE_CountRows );
rc = sqlite3VdbeCloseStatement(p, SAVEPOINT_RELEASE);
if( NEVER(rc!=SQLITE_OK) ){
break;
}
assert( rc==SQLITE_OK );
/* Invalidate all ephemeral cursor row caches */
p->cacheCtr = (p->cacheCtr + 2)|1;
@ -1675,6 +1680,7 @@ case OP_Function: {
rc = pCtx->isError;
}
sqlite3VdbeDeleteAuxData(p, pCtx->iOp, pOp->p1);
if( rc ) goto abort_due_to_error;
}
/* Copy the result of the function into register P3 */
@ -1858,6 +1864,7 @@ case OP_Cast: { /* in1 */
rc = ExpandBlob(pIn1);
sqlite3VdbeMemCast(pIn1, pOp->p2, encoding);
UPDATE_MAX_BLOBSIZE(pIn1);
if( rc ) goto abort_due_to_error;
break;
}
#endif /* SQLITE_OMIT_CAST */
@ -2467,7 +2474,7 @@ case OP_Column: {
*/
if( offset > 98307 || offset > pC->payloadSize ){
rc = SQLITE_CORRUPT_BKPT;
goto op_column_error;
goto abort_due_to_error;
}
}
@ -2492,7 +2499,7 @@ case OP_Column: {
if( pC->aRow==0 ){
memset(&sMem, 0, sizeof(sMem));
rc = sqlite3VdbeMemFromBtree(pCrsr, 0, aOffset[0], !pC->isTable, &sMem);
if( rc!=SQLITE_OK ) goto op_column_error;
if( rc!=SQLITE_OK ) goto abort_due_to_error;
zData = (u8*)sMem.z;
}else{
zData = pC->aRow;
@ -2528,7 +2535,7 @@ case OP_Column: {
|| (offset64 > pC->payloadSize)
){
rc = SQLITE_CORRUPT_BKPT;
goto op_column_error;
goto abort_due_to_error;
}
}else{
t = 0;
@ -2601,15 +2608,13 @@ case OP_Column: {
}else{
rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, !pC->isTable,
pDest);
if( rc==SQLITE_OK ){
sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest);
pDest->flags &= ~MEM_Ephem;
}
if( rc!=SQLITE_OK ) goto abort_due_to_error;
sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest);
pDest->flags &= ~MEM_Ephem;
}
}
op_column_out:
op_column_error:
UPDATE_MAX_BLOBSIZE(pDest);
REGISTER_TRACE(pOp->p3, pDest);
break;
@ -2814,6 +2819,7 @@ case OP_Count: { /* out2 */
assert( pCrsr );
nEntry = 0; /* Not needed. Only used to silence a warning. */
rc = sqlite3BtreeCount(pCrsr, &nEntry);
if( rc ) goto abort_due_to_error;
pOut = out2Prerelease(p, pOp);
pOut->u.i = nEntry;
break;
@ -2991,6 +2997,7 @@ case OP_Savepoint: {
}
}
}
if( rc ) goto abort_due_to_error;
break;
}
@ -3027,7 +3034,7 @@ case OP_AutoCommit: {
sqlite3VdbeError(p, "cannot commit transaction - "
"SQL statements in progress");
rc = SQLITE_BUSY;
break;
goto abort_due_to_error;
}else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
goto vdbe_return;
}else{
@ -3054,6 +3061,7 @@ case OP_AutoCommit: {
"cannot commit - no transaction is active"));
rc = SQLITE_ERROR;
goto abort_due_to_error;
}
break;
}
@ -3176,6 +3184,7 @@ case OP_Transaction: {
p->expired = 1;
rc = SQLITE_SCHEMA;
}
if( rc ) goto abort_due_to_error;
break;
}
@ -3245,6 +3254,7 @@ case OP_SetCookie: {
sqlite3ExpirePreparedStatements(db);
p->expired = 0;
}
if( rc ) goto abort_due_to_error;
break;
}
@ -3342,7 +3352,7 @@ case OP_OpenWrite:
if( p->expired ){
rc = SQLITE_ABORT_ROLLBACK;
break;
goto abort_due_to_error;
}
nField = 0;
@ -3376,10 +3386,7 @@ case OP_OpenWrite:
** that opcode will always set the p2 value to 2 or more or else fail.
** If there were a failure, the prepared statement would have halted
** before reaching this instruction. */
if( NEVER(p2<2) ) {
rc = SQLITE_CORRUPT_BKPT;
goto abort_due_to_error;
}
assert( p2>=2 );
}
if( pOp->p4type==P4_KEYINFO ){
pKeyInfo = pOp->p4.pKeyInfo;
@ -3417,6 +3424,7 @@ open_cursor_set_hints:
#endif
sqlite3BtreeCursorHintFlags(pCur->uc.pCursor,
(pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ)));
if( rc ) goto abort_due_to_error;
break;
}
@ -3493,6 +3501,7 @@ case OP_OpenEphemeral: {
pCx->isTable = 1;
}
}
if( rc ) goto abort_due_to_error;
pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
break;
}
@ -3518,6 +3527,7 @@ case OP_SorterOpen: {
assert( pCx->pKeyInfo->db==db );
assert( pCx->pKeyInfo->enc==ENC(db) );
rc = sqlite3VdbeSorterInit(db, pOp->p3, pCx);
if( rc ) goto abort_due_to_error;
break;
}
@ -3980,7 +3990,7 @@ case OP_Found: { /* jump, in3 */
rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, pIdxKey, 0, 0, &res);
sqlite3DbFree(db, pFree);
if( rc!=SQLITE_OK ){
break;
goto abort_due_to_error;
}
pC->seekResult = res;
alreadyExists = (res==0);
@ -4052,6 +4062,7 @@ case OP_NotExists: { /* jump, in3 */
goto jump_to_p2;
}
}
if( rc ) goto abort_due_to_error;
break;
}
@ -4194,7 +4205,8 @@ case OP_NewRowid: { /* out2 */
0, &res))==SQLITE_OK)
&& (res==0)
&& (++cnt<100));
if( rc==SQLITE_OK && res==0 ){
if( rc ) goto abort_due_to_error;
if( res==0 ){
rc = SQLITE_FULL; /* IMP: R-38219-53002 */
goto abort_due_to_error;
}
@ -4308,7 +4320,8 @@ case OP_InsertInt: {
pC->cacheStatus = CACHE_STALE;
/* Invoke the update-hook if required. */
if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
if( rc ) goto abort_due_to_error;
if( db->xUpdateCallback && pOp->p4.z ){
zDb = db->aDb[pC->iDb].zName;
zTbl = pOp->p4.z;
op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
@ -4398,7 +4411,8 @@ case OP_Delete: {
pC->cacheStatus = CACHE_STALE;
/* Invoke the update-hook if required. */
if( rc==SQLITE_OK && hasUpdateCallback ){
if( rc ) goto abort_due_to_error;
if( hasUpdateCallback ){
db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE,
db->aDb[pC->iDb].zName, pOp->p4.z, pC->movetoTarget);
assert( pC->iDb>=0 );
@ -4447,6 +4461,7 @@ case OP_SorterCompare: {
res = 0;
rc = sqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res);
VdbeBranchTaken(res!=0,2);
if( rc ) goto abort_due_to_error;
if( res ) goto jump_to_p2;
break;
};
@ -4472,6 +4487,7 @@ case OP_SorterData: {
rc = sqlite3VdbeSorterRowkey(pC, pOut);
assert( rc!=SQLITE_OK || (pOut->flags & MEM_Blob) );
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
if( rc ) goto abort_due_to_error;
p->apCsr[pOp->p3]->cacheStatus = CACHE_STALE;
break;
}
@ -4560,6 +4576,7 @@ case OP_RowData: {
}else{
rc = sqlite3BtreeData(pCrsr, 0, n, pOut->z);
}
if( rc ) goto abort_due_to_error;
pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */
UPDATE_MAX_BLOBSIZE(pOut);
REGISTER_TRACE(pOp->p2, pOut);
@ -4600,6 +4617,7 @@ case OP_Rowid: { /* out2 */
assert( pModule->xRowid );
rc = pModule->xRowid(pC->uc.pVCur, &v);
sqlite3VtabImportErrmsg(p, pVtab);
if( rc ) goto abort_due_to_error;
#endif /* SQLITE_OMIT_VIRTUALTABLE */
}else{
assert( pC->eCurType==CURTYPE_BTREE );
@ -4670,6 +4688,7 @@ case OP_Last: { /* jump */
#ifdef SQLITE_DEBUG
pC->seekOp = OP_Last;
#endif
if( rc ) goto abort_due_to_error;
if( pOp->p2>0 ){
VdbeBranchTaken(res!=0,2);
if( res ) goto jump_to_p2;
@ -4734,6 +4753,7 @@ case OP_Rewind: { /* jump */
pC->deferredMoveto = 0;
pC->cacheStatus = CACHE_STALE;
}
if( rc ) goto abort_due_to_error;
pC->nullRow = (u8)res;
assert( pOp->p2>0 && pOp->p2<p->nOp );
VdbeBranchTaken(res!=0,2);
@ -4846,6 +4866,7 @@ case OP_Next: /* jump */
next_tail:
pC->cacheStatus = CACHE_STALE;
VdbeBranchTaken(res==0,2);
if( rc ) goto abort_due_to_error;
if( res==0 ){
pC->nullRow = 0;
p->aCounter[pOp->p5]++;
@ -4896,19 +4917,19 @@ case OP_IdxInsert: { /* in2 */
assert( pC->eCurType==CURTYPE_BTREE || pOp->opcode==OP_SorterInsert );
assert( pC->isTable==0 );
rc = ExpandBlob(pIn2);
if( rc==SQLITE_OK ){
if( pOp->opcode==OP_SorterInsert ){
rc = sqlite3VdbeSorterWrite(pC, pIn2);
}else{
nKey = pIn2->n;
zKey = pIn2->z;
rc = sqlite3BtreeInsert(pC->uc.pCursor, zKey, nKey, "", 0, 0, pOp->p3,
((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0)
);
assert( pC->deferredMoveto==0 );
pC->cacheStatus = CACHE_STALE;
}
if( rc ) goto abort_due_to_error;
if( pOp->opcode==OP_SorterInsert ){
rc = sqlite3VdbeSorterWrite(pC, pIn2);
}else{
nKey = pIn2->n;
zKey = pIn2->z;
rc = sqlite3BtreeInsert(pC->uc.pCursor, zKey, nKey, "", 0, 0, pOp->p3,
((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0)
);
assert( pC->deferredMoveto==0 );
pC->cacheStatus = CACHE_STALE;
}
if( rc) goto abort_due_to_error;
break;
}
@ -4939,8 +4960,10 @@ case OP_IdxDelete: {
r.default_rc = 0;
r.aMem = &aMem[pOp->p2];
rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res);
if( rc==SQLITE_OK && res==0 ){
if( rc ) goto abort_due_to_error;
if( res==0 ){
rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE);
if( rc ) goto abort_due_to_error;
}
assert( pC->deferredMoveto==0 );
pC->cacheStatus = CACHE_STALE;
@ -5115,6 +5138,7 @@ case OP_IdxGE: { /* jump */
res++;
}
VdbeBranchTaken(res>0,2);
if( rc ) goto abort_due_to_error;
if( res>0 ) goto jump_to_p2;
break;
}
@ -5150,6 +5174,7 @@ case OP_Destroy: { /* out2 */
if( db->nVdbeRead > db->nVDestroy+1 ){
rc = SQLITE_LOCKED;
p->errorAction = OE_Abort;
goto abort_due_to_error;
}else{
iDb = pOp->p3;
assert( DbMaskTest(p->btreeMask, iDb) );
@ -5157,8 +5182,9 @@ case OP_Destroy: { /* out2 */
rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved);
pOut->flags = MEM_Int;
pOut->u.i = iMoved;
if( rc ) goto abort_due_to_error;
#ifndef SQLITE_OMIT_AUTOVACUUM
if( rc==SQLITE_OK && iMoved!=0 ){
if( iMoved!=0 ){
sqlite3RootPageMoved(db, iDb, iMoved, pOp->p1);
/* All OP_Destroy operations occur on the same btree */
assert( resetSchemaOnFault==0 || resetSchemaOnFault==iDb+1 );
@ -5204,6 +5230,7 @@ case OP_Clear: {
aMem[pOp->p3].u.i += nChange;
}
}
if( rc ) goto abort_due_to_error;
break;
}
@ -5227,6 +5254,7 @@ case OP_ResetSorter: {
assert( pC->eCurType==CURTYPE_BTREE );
assert( pC->isEphemeral );
rc = sqlite3BtreeClearTableOfCursor(pC->uc.pCursor);
if( rc ) goto abort_due_to_error;
}
break;
}
@ -5275,6 +5303,7 @@ case OP_CreateTable: { /* out2 */
flags = BTREE_BLOBKEY;
}
rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, flags);
if( rc ) goto abort_due_to_error;
pOut->u.i = pgno;
break;
}
@ -5327,9 +5356,12 @@ case OP_ParseSchema: {
db->init.busy = 0;
}
}
if( rc ) sqlite3ResetAllSchemasOfConnection(db);
if( rc==SQLITE_NOMEM ){
goto no_mem;
if( rc ){
sqlite3ResetAllSchemasOfConnection(db);
if( rc==SQLITE_NOMEM ){
goto no_mem;
}
goto abort_due_to_error;
}
break;
}
@ -5344,6 +5376,7 @@ case OP_ParseSchema: {
case OP_LoadAnalysis: {
assert( pOp->p1>=0 && pOp->p1<db->nDb );
rc = sqlite3AnalysisLoad(db, pOp->p1);
if( rc ) goto abort_due_to_error;
break;
}
#endif /* !defined(SQLITE_OMIT_ANALYZE) */
@ -5603,7 +5636,7 @@ case OP_Program: { /* jump */
if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){
rc = SQLITE_ERROR;
sqlite3VdbeError(p, "too many levels of trigger recursion");
break;
goto abort_due_to_error;
}
/* Register pRt is used to store the memory required to save the state
@ -5967,6 +6000,7 @@ case OP_AggStep: {
rc = pCtx->isError;
}
sqlite3VdbeMemRelease(&t);
if( rc ) goto abort_due_to_error;
}else{
assert( t.flags==MEM_Null );
}
@ -5999,6 +6033,7 @@ case OP_AggFinal: {
rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc);
if( rc ){
sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem));
goto abort_due_to_error;
}
sqlite3VdbeChangeEncoding(pMem, encoding);
UPDATE_MAX_BLOBSIZE(pMem);
@ -6034,7 +6069,8 @@ case OP_Checkpoint: {
|| pOp->p2==SQLITE_CHECKPOINT_TRUNCATE
);
rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &aRes[1], &aRes[2]);
if( rc==SQLITE_BUSY ){
if( rc ){
if( rc!=SQLITE_BUSY ) goto abort_due_to_error;
rc = SQLITE_OK;
aRes[0] = 1;
}
@ -6107,7 +6143,7 @@ case OP_JournalMode: { /* out2 */
"cannot change %s wal mode from within a transaction",
(eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of")
);
break;
goto abort_due_to_error;
}else{
if( eOld==PAGER_JOURNALMODE_WAL ){
@ -6137,9 +6173,7 @@ case OP_JournalMode: { /* out2 */
}
#endif /* ifndef SQLITE_OMIT_WAL */
if( rc ){
eNew = eOld;
}
if( rc ) eNew = eOld;
eNew = sqlite3PagerSetJournalMode(pPager, eNew);
pOut->flags = MEM_Str|MEM_Static|MEM_Term;
@ -6147,6 +6181,7 @@ case OP_JournalMode: { /* out2 */
pOut->n = sqlite3Strlen30(pOut->z);
pOut->enc = SQLITE_UTF8;
sqlite3VdbeChangeEncoding(pOut, encoding);
if( rc ) goto abort_due_to_error;
break;
};
#endif /* SQLITE_OMIT_PRAGMA */
@ -6161,6 +6196,7 @@ case OP_JournalMode: { /* out2 */
case OP_Vacuum: {
assert( p->readOnly==0 );
rc = sqlite3RunVacuum(&p->zErrMsg, db);
if( rc ) goto abort_due_to_error;
break;
}
#endif
@ -6181,7 +6217,8 @@ case OP_IncrVacuum: { /* jump */
pBt = db->aDb[pOp->p1].pBt;
rc = sqlite3BtreeIncrVacuum(pBt);
VdbeBranchTaken(rc==SQLITE_DONE,2);
if( rc==SQLITE_DONE ){
if( rc ){
if( rc!=SQLITE_DONE ) goto abort_due_to_error;
rc = SQLITE_OK;
goto jump_to_p2;
}
@ -6232,9 +6269,12 @@ case OP_TableLock: {
assert( DbMaskTest(p->btreeMask, p1) );
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;
sqlite3VdbeError(p, "database table is locked: %s", z);
if( rc ){
if( (rc&0xFF)==SQLITE_LOCKED ){
const char *z = pOp->p4.z;
sqlite3VdbeError(p, "database table is locked: %s", z);
}
goto abort_due_to_error;
}
}
break;
@ -6256,6 +6296,7 @@ case OP_VBegin: {
pVTab = pOp->p4.pVtab;
rc = sqlite3VtabBegin(db, pVTab);
if( pVTab ) sqlite3VtabImportErrmsg(p, pVTab->pVtab);
if( rc ) goto abort_due_to_error;
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@ -6284,6 +6325,7 @@ case OP_VCreate: {
rc = sqlite3VtabCallCreate(db, pOp->p1, zTab, &p->zErrMsg);
}
sqlite3VdbeMemRelease(&sMem);
if( rc ) goto abort_due_to_error;
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@ -6298,6 +6340,7 @@ case OP_VDestroy: {
db->nVDestroy++;
rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p4.z);
db->nVDestroy--;
if( rc ) goto abort_due_to_error;
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@ -6321,25 +6364,25 @@ case OP_VOpen: {
pVtab = pOp->p4.pVtab->pVtab;
if( pVtab==0 || NEVER(pVtab->pModule==0) ){
rc = SQLITE_LOCKED;
break;
goto abort_due_to_error;
}
pModule = pVtab->pModule;
rc = pModule->xOpen(pVtab, &pVCur);
sqlite3VtabImportErrmsg(p, pVtab);
if( SQLITE_OK==rc ){
/* Initialize sqlite3_vtab_cursor base class */
pVCur->pVtab = pVtab;
if( rc ) goto abort_due_to_error;
/* Initialize vdbe cursor object */
pCur = allocateCursor(p, pOp->p1, 0, -1, CURTYPE_VTAB);
if( pCur ){
pCur->uc.pVCur = pVCur;
pVtab->nRef++;
}else{
assert( db->mallocFailed );
pModule->xClose(pVCur);
goto no_mem;
}
/* Initialize sqlite3_vtab_cursor base class */
pVCur->pVtab = pVtab;
/* Initialize vdbe cursor object */
pCur = allocateCursor(p, pOp->p1, 0, -1, CURTYPE_VTAB);
if( pCur ){
pCur->uc.pVCur = pVCur;
pVtab->nRef++;
}else{
assert( db->mallocFailed );
pModule->xClose(pVCur);
goto no_mem;
}
break;
}
@ -6401,9 +6444,8 @@ case OP_VFilter: { /* jump */
}
rc = pModule->xFilter(pVCur, iQuery, pOp->p4.z, nArg, apArg);
sqlite3VtabImportErrmsg(p, pVtab);
if( rc==SQLITE_OK ){
res = pModule->xEof(pVCur);
}
if( rc ) goto abort_due_to_error;
res = pModule->xEof(pVCur);
pCur->nullRow = 0;
VdbeBranchTaken(res!=0,2);
if( res ) goto jump_to_p2;
@ -6452,6 +6494,7 @@ case OP_VColumn: {
if( sqlite3VdbeMemTooBig(pDest) ){
goto too_big;
}
if( rc ) goto abort_due_to_error;
break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */
@ -6487,9 +6530,8 @@ case OP_VNext: { /* jump */
*/
rc = pModule->xNext(pCur->uc.pVCur);
sqlite3VtabImportErrmsg(p, pVtab);
if( rc==SQLITE_OK ){
res = pModule->xEof(pCur->uc.pVCur);
}
if( rc ) goto abort_due_to_error;
res = pModule->xEof(pCur->uc.pVCur);
VdbeBranchTaken(!res,2);
if( !res ){
/* If there is data, jump to P2 */
@ -6521,11 +6563,11 @@ case OP_VRename: {
testcase( pName->enc==SQLITE_UTF16BE );
testcase( pName->enc==SQLITE_UTF16LE );
rc = sqlite3VdbeChangeEncoding(pName, SQLITE_UTF8);
if( rc==SQLITE_OK ){
rc = pVtab->pModule->xRename(pVtab, pName->z);
sqlite3VtabImportErrmsg(p, pVtab);
p->expired = 0;
}
if( rc ) goto abort_due_to_error;
rc = pVtab->pModule->xRename(pVtab, pName->z);
sqlite3VtabImportErrmsg(p, pVtab);
p->expired = 0;
if( rc ) goto abort_due_to_error;
break;
}
#endif
@ -6574,7 +6616,7 @@ case OP_VUpdate: {
pVtab = pOp->p4.pVtab->pVtab;
if( pVtab==0 || NEVER(pVtab->pModule==0) ){
rc = SQLITE_LOCKED;
break;
goto abort_due_to_error;
}
pModule = pVtab->pModule;
nArg = pOp->p2;
@ -6606,6 +6648,7 @@ case OP_VUpdate: {
}else{
p->nChange++;
}
if( rc ) goto abort_due_to_error;
}
break;
}
@ -6777,8 +6820,12 @@ default: { /* This is really OP_Noop and OP_Explain */
/* If we reach this point, it means that execution is finished with
** an error of some kind.
*/
vdbe_error_halt:
abort_due_to_error:
if( db->mallocFailed ) rc = SQLITE_NOMEM_BKPT;
assert( rc );
if( p->zErrMsg==0 && rc!=SQLITE_IOERR_NOMEM ){
sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
}
p->rc = rc;
testcase( sqlite3GlobalConfig.xLog!=0 );
sqlite3_log(rc, "statement aborts at %d: [%s] %s",
@ -6809,7 +6856,7 @@ vdbe_return:
too_big:
sqlite3VdbeError(p, "string or blob too big");
rc = SQLITE_TOOBIG;
goto vdbe_error_halt;
goto abort_due_to_error;
/* Jump to here if a malloc() fails.
*/
@ -6817,18 +6864,7 @@ no_mem:
sqlite3OomFault(db);
sqlite3VdbeError(p, "out of memory");
rc = SQLITE_NOMEM_BKPT;
goto vdbe_error_halt;
/* Jump to here for any other kind of fatal error. The "rc" variable
** should hold the error number.
*/
abort_due_to_error:
assert( p->zErrMsg==0 );
if( db->mallocFailed ) rc = SQLITE_NOMEM_BKPT;
if( rc!=SQLITE_IOERR_NOMEM ){
sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
}
goto vdbe_error_halt;
goto abort_due_to_error;
/* Jump to here if the sqlite3_interrupt() API sets the interrupt
** flag.
@ -6838,5 +6874,5 @@ abort_due_to_interrupt:
rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT;
p->rc = rc;
sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
goto vdbe_error_halt;
goto abort_due_to_error;
}