/ Check-in [e6798871]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Detect when a VdbeCursor is still pointing at a valid row but that row has moved, and invalidated the return from prior sqlite3BtreeDataFetch() or sqlite3BtreeKeyFetch() calls.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:e6798871ce94961135762669af418cd78540c121
User & Date: drh 2014-03-25 11:00:21
Context
2014-03-25
14:54
Add an ORDER BY test case to speedtest1.c check-in: 58812264 user: drh tags: trunk
13:17
Merge all fixes and enhancements from trunk. check-in: b415dfb6 user: drh tags: threads
11:00
Detect when a VdbeCursor is still pointing at a valid row but that row has moved, and invalidated the return from prior sqlite3BtreeDataFetch() or sqlite3BtreeKeyFetch() calls. check-in: e6798871 user: drh tags: trunk
2014-03-24
16:30
Remove unused variables Parse.nColCache and Parse.iColCache. check-in: 4d7551ce user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

   742    742   
   743    743   /*
   744    744   ** Determine whether or not a cursor has moved from the position it
   745    745   ** was last placed at.  Cursors can move when the row they are pointing
   746    746   ** at is deleted out from under them.
   747    747   **
   748    748   ** This routine returns an error code if something goes wrong.  The
   749         -** integer *pHasMoved is set to one if the cursor has moved and 0 if not.
          749  +** integer *pHasMoved is set as follows:
          750  +**
          751  +**    0:   The cursor is unchanged
          752  +**    1:   The cursor is still pointing at the same row, but the pointers
          753  +**         returned by sqlite3BtreeKeyFetch() or sqlite3BtreeDataFetch()
          754  +**         might now be invalid because of a balance() or other change to the
          755  +**         b-tree.
          756  +**    2:   The cursor is no longer pointing to the row.  The row might have
          757  +**         been deleted out from under the cursor.
   750    758   */
   751    759   int sqlite3BtreeCursorHasMoved(BtCursor *pCur, int *pHasMoved){
   752    760     int rc;
   753    761   
          762  +  if( pCur->eState==CURSOR_VALID ){
          763  +    *pHasMoved = 0;
          764  +    return SQLITE_OK;
          765  +  }
   754    766     rc = restoreCursorPosition(pCur);
   755    767     if( rc ){
   756         -    *pHasMoved = 1;
          768  +    *pHasMoved = 2;
   757    769       return rc;
   758    770     }
   759    771     if( pCur->eState!=CURSOR_VALID || NEVER(pCur->skipNext!=0) ){
          772  +    *pHasMoved = 2;
          773  +  }else{
   760    774       *pHasMoved = 1;
   761         -  }else{
   762         -    *pHasMoved = 0;
   763    775     }
   764    776     return SQLITE_OK;
   765    777   }
   766    778   
   767    779   #ifndef SQLITE_OMIT_AUTOVACUUM
   768    780   /*
   769    781   ** Given a page number of a regular database page, return the page
................................................................................
  4184   4196     u32 *pAmt            /* Write the number of available bytes here */
  4185   4197   ){
  4186   4198     assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]);
  4187   4199     assert( pCur->eState==CURSOR_VALID );
  4188   4200     assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
  4189   4201     assert( cursorHoldsMutex(pCur) );
  4190   4202     assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
         4203  +  assert( pCur->info.nSize>0 );
         4204  +#if 0
  4191   4205     if( pCur->info.nSize==0 ){
  4192   4206       btreeParseCell(pCur->apPage[pCur->iPage], pCur->aiIdx[pCur->iPage],
  4193   4207                      &pCur->info);
  4194   4208     }
         4209  +#endif
  4195   4210     *pAmt = pCur->info.nLocal;
  4196   4211     return (void*)(pCur->info.pCell + pCur->info.nHeader);
  4197   4212   }
  4198   4213   
  4199   4214   
  4200   4215   /*
  4201   4216   ** For the entry that cursor pCur is point to, return as

Changes to src/vdbeaux.c.

  2731   2731       p->cacheStatus = CACHE_STALE;
  2732   2732     }else if( p->pCursor ){
  2733   2733       int hasMoved;
  2734   2734       int rc = sqlite3BtreeCursorHasMoved(p->pCursor, &hasMoved);
  2735   2735       if( rc ) return rc;
  2736   2736       if( hasMoved ){
  2737   2737         p->cacheStatus = CACHE_STALE;
  2738         -      p->nullRow = 1;
         2738  +      if( hasMoved==2 ) p->nullRow = 1;
  2739   2739       }
  2740   2740     }
  2741   2741     return SQLITE_OK;
  2742   2742   }
  2743   2743   
  2744   2744   /*
  2745   2745   ** The following functions: