aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/vdbe.c37
-rw-r--r--src/vdbeInt.h13
-rw-r--r--src/vdbeaux.c3
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;
}