]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Invalidate all VDBE cursor row caches in between calls to sqlite3_step()
authordrh <drh@noemail.net>
Sat, 7 Jan 2006 18:48:26 +0000 (18:48 +0000)
committerdrh <drh@noemail.net>
Sat, 7 Jan 2006 18:48:26 +0000 (18:48 +0000)
since the emphemeral content that those caches point to might change if
the statement is READ UNCOMMITTED. (CVS 2886)

FossilOrigin-Name: 0ae461313c1642a49a9f6cda608c42c7c0053ce4

manifest
manifest.uuid
src/vdbe.c
src/vdbeInt.h
src/vdbeaux.c

index e614b3f43360b6a12f36f3bdf46d5e11c23dd5ec..ee076b812536d3c564b6a988b71da09095b23dd9 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Continued\sprogress\stoward\sa\sworking\swince\sbackend.\s(CVS\s2885)
-D 2006-01-07T18:14:48
+C Invalidate\sall\sVDBE\scursor\srow\scaches\sin\sbetween\scalls\sto\ssqlite3_step()\nsince\sthe\semphemeral\scontent\sthat\sthose\scaches\spoint\sto\smight\schange\sif\nthe\sstatement\sis\sREAD\sUNCOMMITTED.\s(CVS\s2886)
+D 2006-01-07T18:48:26
 F Makefile.in c79fbdaa264c6afcd435f2fb492551de5a8cf80d
 F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -84,11 +84,11 @@ F src/update.c 29ba0385c8639803cd8e6e616e99096a0bc10443
 F src/utf.c b7bffac4260177ae7f83c01d025fe0f5ed70ce71
 F src/util.c 8a3ef3c1b345cdadcee33ce4537c63bb0fda0ed8
 F src/vacuum.c a7301804d4f849da0ce9d869219c71c6d621c34e
-F src/vdbe.c b0617790673c64b78740b7c1fc9c3e247e05612a
+F src/vdbe.c 87a796e2889283b681be71076fa6b6318561f2bd
 F src/vdbe.h 8729a4ee16ff9aeab2af9667df3cf300ff978e13
-F src/vdbeInt.h 9b78ba00cc006bff17e04a54ba3ded9fc7810a10
+F src/vdbeInt.h 5451cf71f229e366ac543607c0a17f36e5737ea9
 F src/vdbeapi.c 7335569b1bad946ba53892384b4b1534e877b1ee
-F src/vdbeaux.c a4eea656afebc6161771ddfa7a9c91186a5d7888
+F src/vdbeaux.c cb57a0b6aef5ff002b42baf366c85e389509b2d7
 F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5
 F src/vdbemem.c deba8d6e3727643924b210a8c531a496c2b8d386
 F src/where.c de22a3a84c595ca1ad206dd19818f65f950e79f8
@@ -335,7 +335,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
 F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
 F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
-P 19f71a6d1982e986f5436bff71ef38b1bcc2e11d
-R 90bcf273c8a689d05bbbb1a9b9eb146b
+P 15fda14ee0c0524d3064d767f48edd689c090d95
+R 8b6ba0a7cf083b8ec0fb5215eb91310f
 U drh
-Z fc0de77c4da0e5b5eb0148bbd35f7f04
+Z c1686b0c208bc7bdd63ff2b9442034c8
index c0039a101e5e379de7a3cbad1f7df3641dbe7cec..7f3a78821a19f3bf4eee6a054b80470db004d50f 100644 (file)
@@ -1 +1 @@
-15fda14ee0c0524d3064d767f48edd689c090d95
\ No newline at end of file
+0ae461313c1642a49a9f6cda608c42c7c0053ce4
\ No newline at end of file
index ec113e434e22af6240e716720c6db7fde099221c..fd1d94222650af30daad484d1932c099a26aa02b 100644 (file)
@@ -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--;
index 5871bf296d06764772cd33aaf3d8280d68be159d..10c5be78711a3bf6b96922335c1868eaa0bb7323 100644 (file)
@@ -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 */
@@ -103,6 +104,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,
@@ -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 */
index 5967533ddd72ea54b35ac41ad80a453bd322b9f2..a1302dc98b4382983d7920d0f04a880791acce4e 100644 (file)
@@ -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;
 }