]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Updates to sqlite3BtreeKeyFetch() and sqlite3BtreeDataFetch(). (CVS 1347)
authordrh <drh@noemail.net>
Tue, 11 May 2004 00:58:56 +0000 (00:58 +0000)
committerdrh <drh@noemail.net>
Tue, 11 May 2004 00:58:56 +0000 (00:58 +0000)
FossilOrigin-Name: a675ac49882887dfcbf671e9092a29aca9eb694e

manifest
manifest.uuid
src/btree.c
src/btree.h
src/test3.c
src/vdbeaux.c
test/btree5.test

index e4b253aca190278faa19f566f58b0bd87b13f658..7f2c312a8f9bd245853d4fdf8e1f7eb8cedf3e54 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Change\sto\sOP_PutIntKey\sto\suse\snew\sbtree\sAPI.\s(CVS\s1346)
-D 2004-05-11T00:28:43
+C Updates\sto\ssqlite3BtreeKeyFetch()\sand\ssqlite3BtreeDataFetch().\s(CVS\s1347)
+D 2004-05-11T00:58:56
 F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -23,8 +23,8 @@ F sqlite.def fc4f5734786fe4743cfe2aa98eb2da4b089edb5f
 F sqlite.pc.in 30552343140c53304c2a658c080fbe810cd09ca2
 F src/attach.c fa9a58234406d84eeb900517d0c0adc4b2da051a
 F src/auth.c 5c2f0bea4729c98c2be3b69d6b466fc51448fe79
-F src/btree.c 38cff183ac4f1d1a2e3079c9eeda7137d103e06e
-F src/btree.h 91343fe6893b8bc35f496bbcecec095a803e5763
+F src/btree.c ac2de2cfaf183e15ae6e58e52530b37a7de02a0f
+F src/btree.h 578dc465c801cf4e7666efbb0fa1c46a54758008
 F src/btree_rb.c 9d7973e266ee6f9c61ce592f68742ce9cd5b10e5
 F src/build.c 8d9965b3ce5dcc1bd4dac60bd0f14524fea269cb
 F src/copy.c 4d2038602fd0549d80c59bda27d96f13ea9b5e29
@@ -54,7 +54,7 @@ F src/table.c af14284fa36c8d41f6829e3f2819dce07d3e2de2
 F src/tclsqlite.c a38bf2263a097fcc9603e818c291151de1782c11
 F src/test1.c 79956f70dddd1a28f8577bbd61c8cf28e5875eb8
 F src/test2.c 6195a1ca2c8d0d2d93644e86da3289b403486872
-F src/test3.c bcc9a49e8d2cb7864efb964974e1807f3e0c30c4
+F src/test3.c e238a8ded4d7842cb369a7e03ab1fd0bcee5f15a
 F src/test4.c b3fab9aea7a8940a8a7386ce1c7e2157b09bd296
 F src/test5.c eb39aac8fed61bd930b92613cd705c145244074a
 F src/tokenize.c e7536dd31205d5afb76c1bdc832dea009c7a3847
@@ -66,7 +66,7 @@ F src/vacuum.c c134702e023db8778e6be59ac0ea7b02315b5476
 F src/vdbe.c c6c763868eec22a5d7b23357a89fa7792cc9575b
 F src/vdbe.h 2dc4d1161b64f5684faa6a2d292e318a185ecb2e
 F src/vdbeInt.h d5786e1c4f7dadac24e3baeed9847dbfed3016de
-F src/vdbeaux.c 943484a2437b6cf40d1ffd3d62e48b5c9a043c5a
+F src/vdbeaux.c 7162f1390620257e25070da1ac2b4ec83e472752
 F src/where.c 487e55b1f64c8fbf0f46a9a90c2247fc45ae6a9a
 F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
 F test/attach.test 76f096f384221f775cc0a856e51d5a35f9ee1541
@@ -78,7 +78,7 @@ F test/bind.test 56a57043b42c4664ca705f6050e56717a8a6699a
 F test/btree.test ed5781db83b6c1de02e62781d44915a9abe3450a
 F test/btree2.test aa4a6d05b1ea90b1acaf83ba89039dd302a88635
 F test/btree4.test 3797b4305694c7af6828675b0f4b1424b8ca30e4
-F test/btree5.test a677d181b3995dc07a6da12c2abdcd4c37ab7a3d
+F test/btree5.test 56977bd84ec64a8bc6ffdaa36b6621c2103c10e2
 F test/capi2.test ec96e0e235d87b53cbaef3d8e3e0f8ccf32c71ca
 F test/conflict.test 0911bb2f079046914a6e9c3341b36658c4e2103e
 F test/copy.test f07ea8d60878da7a67416ab62f78e9706b9d3c45
@@ -188,7 +188,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604
 F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
 F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P bc5a2dafa1df74ba6403b4751ac1c33b0fee2884
-R 8e699e3ea26654772e1f0482b7621587
-U danielk1977
-Z e970f7cae661bb80a4780d6bbbd8aa7f
+P c080fed7b58e754bb34afe597ff3b2f399c7d313
+R 8d721f5b30f9e9c24be64343355846eb
+U drh
+Z c086113e1e7bdfbe291de2f300b02c98
index a481e23249e47e7c322332265c2202c09b8812ad..19cf852f7246f731535f169a488a29e86676ccdb 100644 (file)
@@ -1 +1 @@
-c080fed7b58e754bb34afe597ff3b2f399c7d313
\ No newline at end of file
+a675ac49882887dfcbf671e9092a29aca9eb694e
\ No newline at end of file
index 7daab2a7c5ad0310273aafb8b8cf1a6152dcd99f..78bf7b2e051c3c75363556687c97152087e94c73 100644 (file)
@@ -9,7 +9,7 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** $Id: btree.c,v 1.124 2004/05/10 23:29:49 drh Exp $
+** $Id: btree.c,v 1.125 2004/05/11 00:58:56 drh Exp $
 **
 ** This file implements a external (disk-based) database using BTrees.
 ** For a detailed discussion of BTrees, refer to
@@ -1416,6 +1416,41 @@ int sqlite3BtreeKeySize(BtCursor *pCur, u64 *pSize){
   return SQLITE_OK;
 }
 
+/*
+** Set *pSize to the number of bytes of data in the entry the
+** cursor currently points to.  Always return SQLITE_OK.
+** Failure is not possible.  If the cursor is not currently
+** pointing to an entry (which can happen, for example, if
+** the database is empty) then *pSize is set to 0.
+*/
+int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
+  MemPage *pPage;
+  unsigned char *cell;
+  u64 size;
+
+  if( !pCur->isValid ){
+    return pCur->status ? pCur->status : SQLITE_INTERNAL;
+  }
+  pPage = pCur->pPage;
+  assert( pPage!=0 );
+  assert( pPage->isInit );
+  pageIntegrity(pPage);
+  if( pPage->zeroData ){
+    *pSize = 0;
+  }else{
+    assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
+    cell = pPage->aCell[pCur->idx];
+    cell += 2;   /* Skip the offset to the next cell */
+    if( !pPage->leaf ){
+      cell += 4;  /* Skip the child pointer */
+    }
+    getVarint(cell, &size);
+    assert( (size & 0x00000000ffffffff)==size );
+    *pSize = (u32)size;
+  }
+  return SQLITE_OK;
+}
+
 /*
 ** Read payload information from the entry that the pCur cursor is
 ** pointing to.  Begin reading the payload at "offset" and read
@@ -1534,111 +1569,119 @@ int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
 }
 
 /*
-** Return a pointer to the key of record that cursor pCur
-** is point to if the entire key is in contiguous memory.
-** If the key is split up among multiple tables, return 0.
-** If pCur is not pointing to a valid entry return 0.
+** Read part of the data associated with cursor pCur.  Exactly
+** "amt" bytes will be transfered into pBuf[].  The transfer
+** begins at "offset".
 **
-** The pointer returned is ephemeral.  The key may move
-** or be destroyed on the next call to any Btree routine.
+** Return SQLITE_OK on success or an error code if anything goes
+** wrong.  An error is returned if "offset+amt" is larger than
+** the available payload.
+*/
+int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
+  if( !pCur->isValid ){
+    return pCur->status ? pCur->status : SQLITE_INTERNAL;
+  }
+  assert( amt>=0 );
+  assert( offset>=0 );
+  assert( pCur->pPage!=0 );
+  assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
+  return getPayload(pCur, offset, amt, pBuf, 1);
+}
+
+/*
+** Return a pointer to payload information from the entry that the 
+** pCur cursor is pointing to.  The pointer is to the beginning of
+** the key if skipKey==0 and it points to the beginning of data if
+** skipKey==1.
+**
+** At least amt bytes of information must be available on the local
+** page or else this routine returns NULL.  If amt<0 then the entire
+** key/data must be available.
 **
-** This routine is used to do quick key comparisons in the
-** common case where the entire key fits in the payload area
-** of a cell and does not overflow onto secondary pages.  If
-** this routine returns 0 for a valid cursor, the caller will
-** need to allocate a buffer big enough to hold the whole key
-** then use sqlite3BtreeKey() to copy the key value into the
-** buffer.  That is substantially slower.  But fortunately,
-** most keys are small enough to fit in the payload area so
-** the slower method is rarely needed.
-*/
-void *sqlite3BtreeKeyFetch(BtCursor *pCur){
+** This routine is an optimization.  It is common for the entire key
+** and data to fit on the local page and for there to be no overflow
+** pages.  When that is so, this routine can be used to access the
+** key and data without making a copy.  If the key and/or data spills
+** onto overflow pages, then getPayload() must be used to reassembly
+** the key/data and copy it into a preallocated buffer.
+**
+** The pointer returned by this routine looks directly into the cached
+** page of the database.  The data might change or move the next time
+** any btree routine is called.
+*/
+static const unsigned char *fetchPayload(
+  BtCursor *pCur,      /* Cursor pointing to entry to read from */
+  int amt,             /* Amount requested */
+  int skipKey          /* read beginning at data if this is true */
+){
   unsigned char *aPayload;
   MemPage *pPage;
   Btree *pBt;
   u64 nData, nKey;
+  int maxLocal;
 
-  assert( pCur!=0 );
-  if( !pCur->isValid ){
-    return 0;
-  }
-  assert( pCur->pPage!=0 );
-  assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
+  assert( pCur!=0 && pCur->pPage!=0 );
+  assert( pCur->isValid );
   pBt = pCur->pBt;
   pPage = pCur->pPage;
   pageIntegrity(pPage);
   assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
-  assert( pPage->intKey==0 );
   aPayload = pPage->aCell[pCur->idx];
   aPayload += 2;  /* Skip the next cell index */
   if( !pPage->leaf ){
     aPayload += 4;  /* Skip the child pointer */
   }
-  if( !pPage->zeroData ){
+  if( pPage->zeroData ){
+    nData = 0;
+  }else{
     aPayload += getVarint(aPayload, &nData);
   }
   aPayload += getVarint(aPayload, &nKey);
-  if( nKey>pBt->maxLocal ){
-    return 0;
-  }
-  return aPayload;
-}
-
-
-/*
-** Set *pSize to the number of bytes of data in the entry the
-** cursor currently points to.  Always return SQLITE_OK.
-** Failure is not possible.  If the cursor is not currently
-** pointing to an entry (which can happen, for example, if
-** the database is empty) then *pSize is set to 0.
-*/
-int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
-  MemPage *pPage;
-  unsigned char *cell;
-  u64 size;
-
-  if( !pCur->isValid ){
-    return pCur->status ? pCur->status : SQLITE_INTERNAL;
+  if( pPage->intKey ){
+    nKey = 0;
   }
-  pPage = pCur->pPage;
-  assert( pPage!=0 );
-  assert( pPage->isInit );
-  pageIntegrity(pPage);
-  if( pPage->zeroData ){
-    *pSize = 0;
+  maxLocal = pBt->maxLocal;
+  if( skipKey ){
+    aPayload += nKey;
+    maxLocal -= nKey;
+    if( amt<0 ) amt = nData;
+    assert( amt<=nData );
   }else{
-    assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
-    cell = pPage->aCell[pCur->idx];
-    cell += 2;   /* Skip the offset to the next cell */
-    if( !pPage->leaf ){
-      cell += 4;  /* Skip the child pointer */
-    }
-    getVarint(cell, &size);
-    assert( (size & 0x00000000ffffffff)==size );
-    *pSize = (u32)size;
+    if( amt<0 ) amt = nKey;
+    assert( amt<=nKey );
   }
-  return SQLITE_OK;
+  if( amt>maxLocal ){
+    return 0;  /* If any of the data is not local, return nothing */
+  }
+  return aPayload;
 }
 
+
 /*
-** Read part of the data associated with cursor pCur.  Exactly
-** "amt" bytes will be transfered into pBuf[].  The transfer
-** begins at "offset".
+** Return a pointer to the first amt bytes of the key or data
+** for record that cursor pCur is point to if the entire request
+** exists in contiguous memory on the main tree page.  If any
+** any part of the request is on an overflow page, return 0.
+** If pCur is not pointing to a valid entry return 0.
 **
-** Return SQLITE_OK on success or an error code if anything goes
-** wrong.  An error is returned if "offset+amt" is larger than
-** the available payload.
+** If amt<0 then return the entire key or data.
+**
+** The pointer returned is ephemeral.  The key/data may move
+** or be destroyed on the next call to any Btree routine.
+**
+** These routines is used to get quick access to key and data
+** in the common case where no overflow pages are used.
+**
+** It is a fatal error to call these routines with amt values that
+** are larger than the key/data size.
 */
-int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
-  if( !pCur->isValid ){
-    return pCur->status ? pCur->status : SQLITE_INTERNAL;
-  }
-  assert( amt>=0 );
-  assert( offset>=0 );
-  assert( pCur->pPage!=0 );
-  assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
-  return getPayload(pCur, offset, amt, pBuf, 1);
+const void *sqlite3BtreeKeyFetch(BtCursor *pCur, int amt){
+  return (const void*)fetchPayload(pCur, amt, 0);
 }
+const void *sqlite3BtreeDataFetch(BtCursor *pCur, int amt){
+  return (const void*)fetchPayload(pCur, amt, 1);
+}
+
 
 /*
 ** Move the cursor down to a new child page.  The newPgno argument is the
@@ -1907,7 +1950,7 @@ int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, u64 nKey, int *pRes){
     upr = pPage->nCell-1;
     pageIntegrity(pPage);
     while( lwr<=upr ){
-      void *pCellKey;
+      const void *pCellKey;
       u64 nCellKey;
       pCur->idx = (lwr+upr)/2;
       sqlite3BtreeKeySize(pCur, &nCellKey);
@@ -1919,10 +1962,10 @@ int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, u64 nKey, int *pRes){
         }else{
           c = 0;
         }
-      }else if( (pCellKey = sqlite3BtreeKeyFetch(pCur))!=0 ){
+      }else if( (pCellKey = sqlite3BtreeKeyFetch(pCur, nCellKey))!=0 ){
         c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey);
       }else{
-        pCellKey = sqliteMalloc( nCellKey );
+        u8 *pCellKey = sqliteMalloc( nCellKey );
         if( pCellKey==0 ) return SQLITE_NOMEM;
         rc = sqlite3BtreeKey(pCur, 0, nCellKey, pCellKey);
         c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey);
index 625084fc365ead8da32d6e88ab57f97959853fb8..a43d15238391d807df46d2abfa2a0f85485e521a 100644 (file)
@@ -13,7 +13,7 @@
 ** subsystem.  See comments in the source code for a detailed description
 ** of what each interface routine does.
 **
-** @(#) $Id: btree.h,v 1.44 2004/05/10 23:29:50 drh Exp $
+** @(#) $Id: btree.h,v 1.45 2004/05/11 00:58:56 drh Exp $
 */
 #ifndef _BTREE_H_
 #define _BTREE_H_
@@ -85,7 +85,8 @@ int sqlite3BtreeFlags(BtCursor*);
 int sqlite3BtreePrevious(BtCursor*, int *pRes);
 int sqlite3BtreeKeySize(BtCursor*, u64 *pSize);
 int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*);
-void *sqlite3BtreeKeyFetch(BtCursor*);
+const void *sqlite3BtreeKeyFetch(BtCursor*, int amt);
+const void *sqlite3BtreeDataFetch(BtCursor*, int amt);
 int sqlite3BtreeDataSize(BtCursor*, u32 *pSize);
 int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*);
 
index fe250eb2ccf219998f1d7389ff532601197e2cf6..711857ce61e342f8332dfb4c8926b60942a7f170 100644 (file)
@@ -13,7 +13,7 @@
 ** is not included in the SQLite library.  It is used for automated
 ** testing of the SQLite library.
 **
-** $Id: test3.c,v 1.34 2004/05/10 16:18:48 drh Exp $
+** $Id: test3.c,v 1.35 2004/05/11 00:58:56 drh Exp $
 */
 #include "sqliteInt.h"
 #include "pager.h"
@@ -863,7 +863,8 @@ static int btree_eof(
 /*
 ** Usage:   btree_keysize ID
 **
-** Return the number of bytes of key.  
+** Return the number of bytes of key.  For an INTKEY table, this
+** returns the key itself.
 */
 static int btree_keysize(
   void *NotUsed,
@@ -963,6 +964,80 @@ static int btree_data(
   return SQLITE_OK;
 }
 
+/*
+** Usage:   btree_fetch_key ID AMT
+**
+** Use the sqlite3BtreeKeyFetch() routine to get AMT bytes of the key.
+** If sqlite3BtreeKeyFetch() fails, return an empty string.
+*/
+static int btree_fetch_key(
+  void *NotUsed,
+  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
+  int argc,              /* Number of arguments */
+  const char **argv      /* Text of each argument */
+){
+  BtCursor *pCur;
+  int n;
+  u64 nKey;
+  const char *zBuf;
+  char zStatic[1000];
+
+  if( argc!=3 ){
+    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+       " ID AMT\"", 0);
+    return TCL_ERROR;
+  }
+  if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
+  if( Tcl_GetInt(interp, argv[2], &n) ) return TCL_ERROR;
+  sqlite3BtreeKeySize(pCur, &nKey);
+  zBuf = sqlite3BtreeKeyFetch(pCur, n);
+  if( zBuf ){
+    assert( nKey<sizeof(zStatic) );
+    if( n>0 ) nKey = n;
+    memcpy(zStatic, zBuf, (int)nKey); 
+    zStatic[nKey] = 0;
+    Tcl_AppendResult(interp, zStatic, 0);
+  }
+  return TCL_OK;
+}
+
+/*
+** Usage:   btree_fetch_data ID AMT
+**
+** Use the sqlite3BtreeDataFetch() routine to get AMT bytes of the key.
+** If sqlite3BtreeDataFetch() fails, return an empty string.
+*/
+static int btree_fetch_data(
+  void *NotUsed,
+  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
+  int argc,              /* Number of arguments */
+  const char **argv      /* Text of each argument */
+){
+  BtCursor *pCur;
+  int n;
+  u32 nData;
+  const char *zBuf;
+  char zStatic[1000];
+
+  if( argc!=3 ){
+    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+       " ID AMT\r\"", 0);
+    return TCL_ERROR;
+  }
+  if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
+  if( Tcl_GetInt(interp, argv[2], &n) ) return TCL_ERROR;
+  sqlite3BtreeDataSize(pCur, &nData);
+  zBuf = sqlite3BtreeDataFetch(pCur, n);
+  if( zBuf ){
+    assert( nData<sizeof(zStatic) );
+    if( n>0 ) nData = n;
+    memcpy(zStatic, zBuf, (int)nData); 
+    zStatic[nData] = 0;
+    Tcl_AppendResult(interp, zStatic, 0);
+  }
+  return TCL_OK;
+}
+
 /*
 ** Usage:   btree_payload_size ID
 **
@@ -1096,6 +1171,8 @@ int Sqlitetest3_Init(Tcl_Interp *interp){
      { "btree_keysize",            (Tcl_CmdProc*)btree_keysize            },
      { "btree_key",                (Tcl_CmdProc*)btree_key                },
      { "btree_data",               (Tcl_CmdProc*)btree_data               },
+     { "btree_fetch_key",          (Tcl_CmdProc*)btree_fetch_key          },
+     { "btree_fetch_data",         (Tcl_CmdProc*)btree_fetch_data         },
      { "btree_payload_size",       (Tcl_CmdProc*)btree_payload_size       },
      { "btree_first",              (Tcl_CmdProc*)btree_first              },
      { "btree_last",               (Tcl_CmdProc*)btree_last               },
index d6f3c2fdbe44ca63054d6cc6906594a657f2c6da..16ff2d71953600309d1fb6bfd6c87682d4a4e8be 100644 (file)
@@ -1073,7 +1073,8 @@ int sqlite2BtreeKeyCompare(
   int nIgnore,          /* Ignore this many bytes at the end of pCur */
   int *pResult          /* Write the result here */
 ){
-  void *pCellKey;
+  const void *pCellKey;
+  void *pMallocedKey;
   u64 nCellKey;
   int rc;
 
@@ -1084,18 +1085,18 @@ int sqlite2BtreeKeyCompare(
     return SQLITE_OK;
   }
 
-  pCellKey = sqlite3BtreeKeyFetch(pCur);
+  pCellKey = sqlite3BtreeKeyFetch(pCur, nCellKey);
   if( pCellKey ){
     *pResult = memcmp(pCellKey, pKey, nKey>nCellKey?nCellKey:nKey);
     return SQLITE_OK;
   }
 
-  pCellKey = sqliteMalloc( nCellKey );
-  if( pCellKey==0 ) return SQLITE_NOMEM;
+  pMallocedKey = sqliteMalloc( nCellKey );
+  if( pMallocedKey==0 ) return SQLITE_NOMEM;
 
-  rc = sqlite3BtreeKey(pCur, 0, nCellKey, pCellKey);
-  *pResult = memcmp(pCellKey, pKey, nKey>nCellKey?nCellKey:nKey);
-  sqliteFree(pCellKey);
+  rc = sqlite3BtreeKey(pCur, 0, nCellKey, pMallocedKey);
+  *pResult = memcmp(pMallocedKey, pKey, nKey>nCellKey?nCellKey:nKey);
+  sqliteFree(pMallocedKey);
 
   return rc;
 }
@@ -1246,7 +1247,7 @@ int sqlite3VdbeDeserialize(
     pMem->i = 0;
 
     for(ii=0; ii<bytes; ii++){
-      pMem->i = pMem->i<<8 + zBuf[ii+ret];
+      pMem->i = (pMem->i<<8) + zBuf[ii+ret];
     }
 
     /* If this is a 1, 2 or 4 byte integer, extend the sign-bit if need be. */
index 9c3310990b85882243e12c084b18527967437ab7..f89ccf8ae5673e43d9db1a78b84bcdd5920e313b 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements regression tests for SQLite library.  The
 # focus of this script is btree database backend
 #
-# $Id: btree5.test,v 1.1 2004/05/10 18:45:10 drh Exp $
+# $Id: btree5.test,v 1.2 2004/05/11 00:58:56 drh Exp $
 
 
 set testdir [file dirname $argv0]
@@ -116,9 +116,25 @@ proc check_table {N} {
   btree_first $c1
   set cnt 0
   while {![btree_eof $c1]} {
-    if {[btree_data $c1] ne "data-for-[btree_key $c1]"} {
+    if {[set data [btree_data $c1]] ne "data-for-[btree_key $c1]"} {
       return "wrong data for entry $cnt"
     }
+    set n [string length $data]
+    set fdata1 [btree_fetch_data $c1 $n]
+    set fdata2 [btree_fetch_data $c1 -1]
+    if {$fdata1 ne "" && $fdata1 ne $data} {
+puts "fdata1=[list $fdata1] data=[list $data]"
+      return "DataFetch returned the wrong value with amt=$n"
+    }
+    if {$fdata1 ne $fdata2} {
+      return "DataFetch returned the wrong value when amt=-1"
+    }
+    if {$n>10} {
+      set fdata3 [btree_fetch_data $c1 10]
+      if {$fdata3 ne [string range $data 0 9]} {
+        return "DataFetch returned the wrong value when amt=10"
+      }
+    }
     incr cnt
     btree_next $c1
   }