diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/vdbe.c | 37 | ||||
-rw-r--r-- | src/vdbeInt.h | 13 | ||||
-rw-r--r-- | src/vdbeaux.c | 3 |
3 files changed, 32 insertions, 21 deletions
diff --git a/src/vdbe.c b/src/vdbe.c index ec113e434..fd1d94222 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.515 2006/01/07 18:10:33 drh Exp $ +** $Id: vdbe.c,v 1.516 2006/01/07 18:48:26 drh Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -879,6 +879,9 @@ case OP_Callback: { /* no-push */ Deephemeralize(pMem); } + /* Invalidate all ephemeral cursor row caches */ + p->cacheCtr = (p->cacheCtr + 2)|1; + /* Make sure the results of the current row are \000 terminated ** and have an assigned type. The results are deephemeralized as ** as side effect. @@ -1908,7 +1911,7 @@ case OP_Column: { pCrsr = pC->pCursor; if( pC->nullRow ){ payloadSize = 0; - }else if( pC->cacheValid ){ + }else if( pC->cacheStatus==p->cacheCtr ){ payloadSize = pC->payloadSize; zRec = (char*)pC->aRow; }else if( pC->isIndex ){ @@ -1924,7 +1927,7 @@ case OP_Column: { /* The record is the sole entry of a pseudo-table */ payloadSize = pC->nData; zRec = pC->pData; - pC->cacheValid = 0; + pC->cacheStatus = CACHE_STALE; assert( payloadSize==0 || zRec!=0 ); nField = pC->nField; pCrsr = 0; @@ -1947,7 +1950,7 @@ case OP_Column: { /* Read and parse the table header. Store the results of the parse ** into the record header cache fields of the cursor. */ - if( pC && pC->cacheValid ){ + if( pC && pC->cacheStatus==p->cacheCtr ){ aType = pC->aType; aOffset = pC->aOffset; }else{ @@ -2042,7 +2045,7 @@ case OP_Column: { pC->payloadSize = payloadSize; pC->aType = aType; pC->aOffset = aOffset; - pC->cacheValid = 1; + pC->cacheStatus = p->cacheCtr; } } @@ -2805,7 +2808,7 @@ case OP_MoveGt: { /* no-push */ pC->rowidIsValid = 0; } pC->deferredMoveto = 0; - pC->cacheValid = 0; + pC->cacheStatus = CACHE_STALE; *pC->pIncrKey = 0; sqlite3_search_count++; if( oc==OP_MoveGe || oc==OP_MoveGt ){ @@ -2906,7 +2909,7 @@ case OP_Found: { /* no-push */ rx = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res); alreadyExists = rx==SQLITE_OK && res==0; pC->deferredMoveto = 0; - pC->cacheValid = 0; + pC->cacheStatus = CACHE_STALE; } if( pOp->opcode==OP_Found ){ if( alreadyExists ) pc = pOp->p2 - 1; @@ -2980,7 +2983,7 @@ case OP_IsUnique: { /* no-push */ ** If there is no such entry, jump immediately to P2. */ assert( pCx->deferredMoveto==0 ); - pCx->cacheValid = 0; + pCx->cacheStatus = CACHE_STALE; rc = sqlite3BtreeMoveto(pCrsr, zKey, len, &res); if( rc!=SQLITE_OK ) goto abort_due_to_error; if( res<0 ){ @@ -3053,7 +3056,7 @@ case OP_NotExists: { /* no-push */ pC->lastRowid = pTos->i; pC->rowidIsValid = res==0; pC->nullRow = 0; - pC->cacheValid = 0; + pC->cacheStatus = CACHE_STALE; if( res!=0 ){ pc = pOp->p2 - 1; pC->rowidIsValid = 0; @@ -3229,7 +3232,7 @@ case OP_NewRowid: { } pC->rowidIsValid = 0; pC->deferredMoveto = 0; - pC->cacheValid = 0; + pC->cacheStatus = CACHE_STALE; } pTos++; pTos->i = v; @@ -3303,7 +3306,7 @@ case OP_Insert: { /* no-push */ pC->rowidIsValid = 0; pC->deferredMoveto = 0; - pC->cacheValid = 0; + pC->cacheStatus = CACHE_STALE; /* Invoke the update-hook if required. */ if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p3 ){ @@ -3363,7 +3366,7 @@ case OP_Delete: { /* no-push */ if( rc ) goto abort_due_to_error; rc = sqlite3BtreeDelete(pC->pCursor); pC->nextRowidValid = 0; - pC->cacheValid = 0; + pC->cacheStatus = CACHE_STALE; /* Invoke the update-hook if required. */ if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p3 ){ @@ -3541,7 +3544,7 @@ case OP_Last: { /* no-push */ rc = sqlite3BtreeLast(pCrsr, &res); pC->nullRow = res; pC->deferredMoveto = 0; - pC->cacheValid = 0; + pC->cacheStatus = CACHE_STALE; if( res && pOp->p2>0 ){ pc = pOp->p2 - 1; } @@ -3590,7 +3593,7 @@ case OP_Rewind: { /* no-push */ rc = sqlite3BtreeFirst(pCrsr, &res); pC->atFirst = res==0; pC->deferredMoveto = 0; - pC->cacheValid = 0; + pC->cacheStatus = CACHE_STALE; }else{ res = 1; } @@ -3635,7 +3638,7 @@ case OP_Next: { /* no-push */ rc = pOp->opcode==OP_Next ? sqlite3BtreeNext(pCrsr, &res) : sqlite3BtreePrevious(pCrsr, &res); pC->nullRow = res; - pC->cacheValid = 0; + pC->cacheStatus = CACHE_STALE; } if( res==0 ){ pc = pOp->p2 - 1; @@ -3672,7 +3675,7 @@ case OP_IdxInsert: { /* no-push */ assert( pC->isTable==0 ); rc = sqlite3BtreeInsert(pCrsr, zKey, nKey, "", 0); assert( pC->deferredMoveto==0 ); - pC->cacheValid = 0; + pC->cacheStatus = CACHE_STALE; } Release(pTos); pTos--; @@ -3699,7 +3702,7 @@ case OP_IdxDelete: { /* no-push */ rc = sqlite3BtreeDelete(pCrsr); } assert( pC->deferredMoveto==0 ); - pC->cacheValid = 0; + pC->cacheStatus = CACHE_STALE; } Release(pTos); pTos--; diff --git a/src/vdbeInt.h b/src/vdbeInt.h index 5871bf296..10c5be787 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -86,9 +86,10 @@ struct Cursor { /* Cached information about the header for the data record that the ** cursor is currently pointing to. Only valid if cacheValid is true. - ** zRow might point to (ephemeral) data for the current row, or it might - ** be NULL. */ - Bool cacheValid; /* True if the cache is valid */ + ** aRow might point to (ephemeral) data for the current row, or it might + ** be NULL. + */ + int cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */ int payloadSize; /* Total number of bytes in the record */ u32 *aType; /* Type values for all entries in the record */ u32 *aOffset; /* Cached offsets to the start of each columns data */ @@ -104,6 +105,11 @@ typedef struct Cursor Cursor; #define NBFS 32 /* +** A value for Cursor.cacheValid that means the cache is always invalid. +*/ +#define CACHE_STALE 0 + +/* ** Internally, the vdbe manipulates nearly all SQL values as Mem ** structures. Each Mem struct may cache multiple representations (string, ** integer etc.) of the same value. A value (and therefore Mem structure) @@ -287,6 +293,7 @@ struct Vdbe { int nMem; /* Number of memory locations currently allocated */ Mem *aMem; /* The memory locations */ int nCallback; /* Number of callbacks invoked so far */ + int cacheCtr; /* Cursor row cache generation counter */ Fifo sFifo; /* A list of ROWIDs */ int contextStackTop; /* Index of top element in the context stack */ int contextStackDepth; /* The size of the "context" stack */ diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 5967533dd..a1302dc98 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -782,6 +782,7 @@ void sqlite3VdbeMakeReady( p->explain |= isExplain; p->magic = VDBE_MAGIC_RUN; p->nChange = 0; + p->cacheCtr = 1; p->minWriteFileFormat = 255; #ifdef VDBE_PROFILE { @@ -1453,7 +1454,7 @@ int sqlite3VdbeCursorMoveto(Cursor *p){ } sqlite3_search_count++; p->deferredMoveto = 0; - p->cacheValid = 0; + p->cacheStatus = CACHE_STALE; } return SQLITE_OK; } |