From: drh Date: Mon, 22 Jun 2009 19:05:40 +0000 (+0000) Subject: Simplifications to vdbe.c and it service routines in support of coverage X-Git-Tag: cvs-to-fossil-cutover~173 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9a65f2cd7d0911fef8a1f5aa1081038454213136;p=thirdparty%2Fsqlite.git Simplifications to vdbe.c and it service routines in support of coverage testing. (CVS 6799) FossilOrigin-Name: 308f2e61520ac7440700d93ca5bab4a844f2dc17 --- diff --git a/manifest b/manifest index 54380829bf..8bb4405ff7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\scondition\sthat\sis\salways\strue\sfrom\sbtree.c.\s(CVS\s6798) -D 2009-06-22T18:03:52 +C Simplifications\sto\svdbe.c\sand\sit\sservice\sroutines\sin\ssupport\sof\scoverage\ntesting.\s(CVS\s6799) +D 2009-06-22T19:05:41 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 8b8fb7823264331210cddf103831816c286ba446 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -203,13 +203,13 @@ F src/update.c 6ae6c26adff8dc34532d578f66e6cfde04b5d177 F src/utf.c 9541d28f40441812c0b40f00334372a0542c00ff F src/util.c a7e981e032c3c9c0887d50d7e658a33cb355b43d F src/vacuum.c 0e14f371ea3326c6b8cfba257286d798cd20db59 -F src/vdbe.c e92e2f4136e33041145a87c056a5d09972add6de +F src/vdbe.c c5a0a208432e4faf6590201ace57c7c873143089 F src/vdbe.h 35a648bc3279a120da24f34d9a25213ec15daf8a F src/vdbeInt.h 7823eac611229163c6a5df0e9e0d54ffcda527e7 F src/vdbeapi.c 73bd1d2c57b953bc688d1d8c84b24c2084c2aec7 -F src/vdbeaux.c 516b7e123ece051e93ab1aa96c2ff04578b3b465 +F src/vdbeaux.c 6f0e3680b7b235d7f012de84936f1b7c5320f0c3 F src/vdbeblob.c c25d7e7bc6d5917feeb17270bd275fa771f26e5c -F src/vdbemem.c ba39c0afa609595c7c23dfc2ac929d9414faa59f +F src/vdbemem.c d244e09b5ca8afc3e1cea3ccf0b1a3fa48926614 F src/vtab.c 98fbffc5efe68d8107511dec0a650efc7daa9446 F src/walker.c 1edca756275f158b80f20eb6f104c8d3fcc96a04 F src/where.c cf0d091748c2fa6f7df96e5b08d2db26fd2eb437 @@ -736,7 +736,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl 672f81d693a03f80f5ae60bfefacd8a349e76746 -P bda38f5e86db45234c2dbb0f8d1a81f6ff6d04e4 -R e49401abe650f38b382c2f4526e14814 -U danielk1977 -Z d013caf2ebacc662cceed0c56ce2e6b5 +P 3ec8b37a89fdb2436d312439715414fae2cd20a8 +R 64e6f4c2a51e80727de7b90d6d047386 +U drh +Z e09666ff70680840d2021686d00144b7 diff --git a/manifest.uuid b/manifest.uuid index 4be5ea34e1..3af465c995 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3ec8b37a89fdb2436d312439715414fae2cd20a8 \ No newline at end of file +308f2e61520ac7440700d93ca5bab4a844f2dc17 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 01b5961e29..a594001631 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -43,7 +43,7 @@ ** 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.860 2009/06/22 12:05:10 drh Exp $ +** $Id: vdbe.c,v 1.861 2009/06/22 19:05:41 drh Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" @@ -2065,8 +2065,7 @@ case OP_Column: { sqlite3BtreeDataSize(pCrsr, &payloadSize); } nField = pC->nField; - }else{ - assert( pC->pseudoTable ); + }else if( pC->pseudoTable ){ /* The record is the sole entry of a pseudo-table */ payloadSize = pC->nData; zRec = pC->pData; @@ -2074,6 +2073,9 @@ case OP_Column: { assert( payloadSize==0 || zRec!=0 ); nField = pC->nField; pCrsr = 0; + }else{ + /* Consider the row to be NULL */ + payloadSize = 0; } /* If payloadSize is 0, then just store a NULL */ @@ -2939,6 +2941,10 @@ case OP_OpenWrite: { pIn2 = &p->aMem[p2]; sqlite3VdbeMemIntegerify(pIn2); p2 = (int)pIn2->u.i; + /* The p2 value always comes from a prior OP_CreateTable opcode and + ** 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; @@ -3817,8 +3823,17 @@ case OP_Delete: { iKey = pC->lastRowid; } + /* The OP_Delete opcode always follows an OP_NotExists or OP_Last or + ** OP_Column on the same table without any intervening operations that + ** might move or invalidate the cursor. Hence cursor pC is always pointing + ** to the row to be deleted and the sqlite3VdbeCursorMoveto() operation + ** below is always a no-op and cannot fail. We will run it anyhow, though, + ** to guard against future changes to the code generator. + **/ + assert( pC->deferredMoveto==0 ); rc = sqlite3VdbeCursorMoveto(pC); - if( rc ) goto abort_due_to_error; + if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; + sqlite3BtreeSetCachedRowid(pC->pCursor, 0); rc = sqlite3BtreeDelete(pC->pCursor); pC->cacheStatus = CACHE_STALE; @@ -3888,8 +3903,16 @@ case OP_RowData: { assert( pC->pseudoTable==0 ); assert( pC->pCursor!=0 ); pCrsr = pC->pCursor; + + /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or + ** OP_Rewind/Op_Next with no intervening instructions that might invalidate + ** the cursor. Hence the following sqlite3VdbeCursorMoveto() call is always + ** a no-op and can never fail. But we leave it in place as a safety. + */ + assert( pC->deferredMoveto==0 ); rc = sqlite3VdbeCursorMoveto(pC); - if( rc ) goto abort_due_to_error; + if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; + if( pC->isIndex ){ assert( !pC->isTable ); sqlite3BtreeKeySize(pCrsr, &n64); @@ -4007,13 +4030,16 @@ case OP_Last: { /* jump */ pC = p->apCsr[pOp->p1]; assert( pC!=0 ); pCrsr = pC->pCursor; - assert( pCrsr!=0 ); - rc = sqlite3BtreeLast(pCrsr, &res); + if( pCrsr==0 ){ + res = 1; + }else{ + rc = sqlite3BtreeLast(pCrsr, &res); + } pC->nullRow = (u8)res; pC->deferredMoveto = 0; pC->rowidIsValid = 0; pC->cacheStatus = CACHE_STALE; - if( res && pOp->p2>0 ){ + if( pOp->p2>0 && res ){ pc = pOp->p2 - 1; } break; @@ -4106,7 +4132,10 @@ case OP_Next: { /* jump */ break; /* See ticket #2273 */ } pCrsr = pC->pCursor; - assert( pCrsr ); + if( pCrsr==0 ){ + pC->nullRow = 1; + break; + } res = 1; assert( pC->deferredMoveto==0 ); rc = pOp->opcode==OP_Next ? sqlite3BtreeNext(pCrsr, &res) : @@ -4147,7 +4176,7 @@ case OP_IdxInsert: { /* in2 */ assert( pC!=0 ); assert( pIn2->flags & MEM_Blob ); pCrsr = pC->pCursor; - if( pCrsr!=0 ){ + if( ALWAYS(pCrsr!=0) ){ assert( pC->isTable==0 ); rc = ExpandBlob(pIn2); if( rc==SQLITE_OK ){ @@ -4172,6 +4201,8 @@ case OP_IdxInsert: { /* in2 */ case OP_IdxDelete: { VdbeCursor *pC; BtCursor *pCrsr; + int res; + UnpackedRecord r; assert( pOp->p3>0 ); assert( pOp->p2>0 && pOp->p2+pOp->p3<=p->nMem+1 ); @@ -4179,9 +4210,7 @@ case OP_IdxDelete: { pC = p->apCsr[pOp->p1]; assert( pC!=0 ); pCrsr = pC->pCursor; - if( pCrsr!=0 ){ - int res; - UnpackedRecord r; + if( ALWAYS(pCrsr!=0) ){ r.pKeyInfo = pC->pKeyInfo; r.nField = (u16)pOp->p3; r.flags = 0; @@ -4213,9 +4242,9 @@ case OP_IdxRowid: { /* out2-prerelease */ pC = p->apCsr[pOp->p1]; assert( pC!=0 ); pCrsr = pC->pCursor; - if( pCrsr!=0 ){ + if( ALWAYS(pCrsr!=0) ){ rc = sqlite3VdbeCursorMoveto(pC); - if( rc ) goto abort_due_to_error; + if( NEVER(rc) ) goto abort_due_to_error; assert( pC->deferredMoveto==0 ); assert( pC->isTable==0 ); if( !pC->nullRow ){ @@ -4265,7 +4294,7 @@ case OP_IdxGE: { /* jump, in3 */ assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); - if( pC->pCursor!=0 ){ + if( ALWAYS(pC->pCursor!=0) ){ assert( pC->deferredMoveto==0 ); assert( pOp->p5==0 || pOp->p5==1 ); assert( pOp->p4type==P4_INT32 ); @@ -4469,7 +4498,7 @@ case OP_ParseSchema: { */ assert( sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); sqlite3BtreeEnterAll(db); - if( pOp->p2 || DbHasProperty(db, iDb, DB_SchemaLoaded) ){ + if( pOp->p2 || ALWAYS(DbHasProperty(db, iDb, DB_SchemaLoaded)) ){ zMaster = SCHEMA_TABLE(iDb); initData.db = db; initData.iDb = pOp->p1; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 33f8d60d51..109fca2e50 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -14,7 +14,7 @@ ** to version 2.8.7, all this code was combined into the vdbe.c source file. ** But that file was getting too big so this subroutines were split out. ** -** $Id: vdbeaux.c,v 1.462 2009/06/22 00:55:31 drh Exp $ +** $Id: vdbeaux.c,v 1.463 2009/06/22 19:05:41 drh Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" @@ -2014,9 +2014,17 @@ void sqlite3VdbeDelete(Vdbe *p){ } /* +** Make sure the cursor p is ready to read or write the row to which it +** was last positioned. Return an error code if an OOM fault or I/O error +** prevents us from positioning the cursor to its correct position. +** ** If a MoveTo operation is pending on the given cursor, then do that -** MoveTo now. Return an error code. If no MoveTo is pending, this -** routine does nothing and returns SQLITE_OK. +** MoveTo now. If no move is pending, check to see if the row has been +** deleted out from under the cursor and if it has, mark the row as +** a NULL row. +** +** If the cursor is already pointing to the correct row and that row has +** not been deleted out from under the cursor, then this routine is a no-op. */ int sqlite3VdbeCursorMoveto(VdbeCursor *p){ if( p->deferredMoveto ){ diff --git a/src/vdbemem.c b/src/vdbemem.c index 80516ccef6..d92b496ea7 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -15,7 +15,7 @@ ** only within the VDBE. Interface routines refer to a Mem using the ** name sqlite_value ** -** $Id: vdbemem.c,v 1.148 2009/06/17 16:20:04 drh Exp $ +** $Id: vdbemem.c,v 1.149 2009/06/22 19:05:41 drh Exp $ */ #include "sqliteInt.h" #include "vdbeInt.h" @@ -637,6 +637,12 @@ void sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){ ** string is copied into a (possibly existing) buffer managed by the ** Mem structure. Otherwise, any existing buffer is freed and the ** pointer copied. +** +** If the string is too large (if it exceeds the SQLITE_LIMIT_LENGTH +** size limit) then no memory allocation occurs. If the string can be +** stored without allocating memory, then it is. If a memory allocation +** is required to store the string, then value of pMem is unchanged. In +** either case, SQLITE_TOOBIG is returned. */ int sqlite3VdbeMemSetStr( Mem *pMem, /* Memory cell to set to string value */ @@ -700,9 +706,6 @@ int sqlite3VdbeMemSetStr( pMem->xDel = xDel; flags |= ((xDel==SQLITE_STATIC)?MEM_Static:MEM_Dyn); } - if( nByte>iLimit ){ - return SQLITE_TOOBIG; - } pMem->n = nByte; pMem->flags = flags; @@ -715,6 +718,10 @@ int sqlite3VdbeMemSetStr( } #endif + if( nByte>iLimit ){ + return SQLITE_TOOBIG; + } + return SQLITE_OK; }