/ Check-in [a675ac49]
Login

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

Overview
Comment:Updates to sqlite3BtreeKeyFetch() and sqlite3BtreeDataFetch(). (CVS 1347)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: a675ac49882887dfcbf671e9092a29aca9eb694e
User & Date: drh 2004-05-11 00:58:56
Context
2004-05-11
01:18
Update the main.mk makefile so that it builds everything again. (CVS 1348) check-in: e6e52fc2 user: drh tags: trunk
00:58
Updates to sqlite3BtreeKeyFetch() and sqlite3BtreeDataFetch(). (CVS 1347) check-in: a675ac49 user: drh tags: trunk
00:28
Change to OP_PutIntKey to use new btree API. (CVS 1346) check-in: c080fed7 user: danielk1977 tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

     5      5   ** a legal notice, here is a blessing:
     6      6   **
     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12         -** $Id: btree.c,v 1.124 2004/05/10 23:29:49 drh Exp $
           12  +** $Id: btree.c,v 1.125 2004/05/11 00:58:56 drh Exp $
    13     13   **
    14     14   ** This file implements a external (disk-based) database using BTrees.
    15     15   ** For a detailed discussion of BTrees, refer to
    16     16   **
    17     17   **     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
    18     18   **     "Sorting And Searching", pages 473-480. Addison-Wesley
    19     19   **     Publishing Company, Reading, Massachusetts.
................................................................................
  1411   1411       if( !pPage->zeroData ){
  1412   1412         while( (0x80&*(cell++))!=0 ){}  /* Skip the data size number */
  1413   1413       }
  1414   1414       getVarint(cell, pSize);
  1415   1415     }
  1416   1416     return SQLITE_OK;
  1417   1417   }
         1418  +
         1419  +/*
         1420  +** Set *pSize to the number of bytes of data in the entry the
         1421  +** cursor currently points to.  Always return SQLITE_OK.
         1422  +** Failure is not possible.  If the cursor is not currently
         1423  +** pointing to an entry (which can happen, for example, if
         1424  +** the database is empty) then *pSize is set to 0.
         1425  +*/
         1426  +int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
         1427  +  MemPage *pPage;
         1428  +  unsigned char *cell;
         1429  +  u64 size;
         1430  +
         1431  +  if( !pCur->isValid ){
         1432  +    return pCur->status ? pCur->status : SQLITE_INTERNAL;
         1433  +  }
         1434  +  pPage = pCur->pPage;
         1435  +  assert( pPage!=0 );
         1436  +  assert( pPage->isInit );
         1437  +  pageIntegrity(pPage);
         1438  +  if( pPage->zeroData ){
         1439  +    *pSize = 0;
         1440  +  }else{
         1441  +    assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
         1442  +    cell = pPage->aCell[pCur->idx];
         1443  +    cell += 2;   /* Skip the offset to the next cell */
         1444  +    if( !pPage->leaf ){
         1445  +      cell += 4;  /* Skip the child pointer */
         1446  +    }
         1447  +    getVarint(cell, &size);
         1448  +    assert( (size & 0x00000000ffffffff)==size );
         1449  +    *pSize = (u32)size;
         1450  +  }
         1451  +  return SQLITE_OK;
         1452  +}
  1418   1453   
  1419   1454   /*
  1420   1455   ** Read payload information from the entry that the pCur cursor is
  1421   1456   ** pointing to.  Begin reading the payload at "offset" and read
  1422   1457   ** a total of "amt" bytes.  Put the result in zBuf.
  1423   1458   **
  1424   1459   ** This routine does not make a distinction between key and data.
................................................................................
  1529   1564     }
  1530   1565     assert( pCur->pPage!=0 );
  1531   1566     assert( pCur->pPage->intKey==0 );
  1532   1567     assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
  1533   1568     return getPayload(pCur, offset, amt, (unsigned char*)pBuf, 0);
  1534   1569   }
  1535   1570   
  1536         -/*
  1537         -** Return a pointer to the key of record that cursor pCur
  1538         -** is point to if the entire key is in contiguous memory.
  1539         -** If the key is split up among multiple tables, return 0.
  1540         -** If pCur is not pointing to a valid entry return 0.
  1541         -**
  1542         -** The pointer returned is ephemeral.  The key may move
  1543         -** or be destroyed on the next call to any Btree routine.
  1544         -**
  1545         -** This routine is used to do quick key comparisons in the
  1546         -** common case where the entire key fits in the payload area
  1547         -** of a cell and does not overflow onto secondary pages.  If
  1548         -** this routine returns 0 for a valid cursor, the caller will
  1549         -** need to allocate a buffer big enough to hold the whole key
  1550         -** then use sqlite3BtreeKey() to copy the key value into the
  1551         -** buffer.  That is substantially slower.  But fortunately,
  1552         -** most keys are small enough to fit in the payload area so
  1553         -** the slower method is rarely needed.
  1554         -*/
  1555         -void *sqlite3BtreeKeyFetch(BtCursor *pCur){
  1556         -  unsigned char *aPayload;
  1557         -  MemPage *pPage;
  1558         -  Btree *pBt;
  1559         -  u64 nData, nKey;
  1560         -
  1561         -  assert( pCur!=0 );
  1562         -  if( !pCur->isValid ){
  1563         -    return 0;
  1564         -  }
  1565         -  assert( pCur->pPage!=0 );
  1566         -  assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
  1567         -  pBt = pCur->pBt;
  1568         -  pPage = pCur->pPage;
  1569         -  pageIntegrity(pPage);
  1570         -  assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
  1571         -  assert( pPage->intKey==0 );
  1572         -  aPayload = pPage->aCell[pCur->idx];
  1573         -  aPayload += 2;  /* Skip the next cell index */
  1574         -  if( !pPage->leaf ){
  1575         -    aPayload += 4;  /* Skip the child pointer */
  1576         -  }
  1577         -  if( !pPage->zeroData ){
  1578         -    aPayload += getVarint(aPayload, &nData);
  1579         -  }
  1580         -  aPayload += getVarint(aPayload, &nKey);
  1581         -  if( nKey>pBt->maxLocal ){
  1582         -    return 0;
  1583         -  }
  1584         -  return aPayload;
  1585         -}
  1586         -
  1587         -
  1588         -/*
  1589         -** Set *pSize to the number of bytes of data in the entry the
  1590         -** cursor currently points to.  Always return SQLITE_OK.
  1591         -** Failure is not possible.  If the cursor is not currently
  1592         -** pointing to an entry (which can happen, for example, if
  1593         -** the database is empty) then *pSize is set to 0.
  1594         -*/
  1595         -int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
  1596         -  MemPage *pPage;
  1597         -  unsigned char *cell;
  1598         -  u64 size;
  1599         -
  1600         -  if( !pCur->isValid ){
  1601         -    return pCur->status ? pCur->status : SQLITE_INTERNAL;
  1602         -  }
  1603         -  pPage = pCur->pPage;
  1604         -  assert( pPage!=0 );
  1605         -  assert( pPage->isInit );
  1606         -  pageIntegrity(pPage);
  1607         -  if( pPage->zeroData ){
  1608         -    *pSize = 0;
  1609         -  }else{
  1610         -    assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
  1611         -    cell = pPage->aCell[pCur->idx];
  1612         -    cell += 2;   /* Skip the offset to the next cell */
  1613         -    if( !pPage->leaf ){
  1614         -      cell += 4;  /* Skip the child pointer */
  1615         -    }
  1616         -    getVarint(cell, &size);
  1617         -    assert( (size & 0x00000000ffffffff)==size );
  1618         -    *pSize = (u32)size;
  1619         -  }
  1620         -  return SQLITE_OK;
  1621         -}
  1622         -
  1623   1571   /*
  1624   1572   ** Read part of the data associated with cursor pCur.  Exactly
  1625   1573   ** "amt" bytes will be transfered into pBuf[].  The transfer
  1626   1574   ** begins at "offset".
  1627   1575   **
  1628   1576   ** Return SQLITE_OK on success or an error code if anything goes
  1629   1577   ** wrong.  An error is returned if "offset+amt" is larger than
................................................................................
  1635   1583     }
  1636   1584     assert( amt>=0 );
  1637   1585     assert( offset>=0 );
  1638   1586     assert( pCur->pPage!=0 );
  1639   1587     assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
  1640   1588     return getPayload(pCur, offset, amt, pBuf, 1);
  1641   1589   }
         1590  +
         1591  +/*
         1592  +** Return a pointer to payload information from the entry that the 
         1593  +** pCur cursor is pointing to.  The pointer is to the beginning of
         1594  +** the key if skipKey==0 and it points to the beginning of data if
         1595  +** skipKey==1.
         1596  +**
         1597  +** At least amt bytes of information must be available on the local
         1598  +** page or else this routine returns NULL.  If amt<0 then the entire
         1599  +** key/data must be available.
         1600  +**
         1601  +** This routine is an optimization.  It is common for the entire key
         1602  +** and data to fit on the local page and for there to be no overflow
         1603  +** pages.  When that is so, this routine can be used to access the
         1604  +** key and data without making a copy.  If the key and/or data spills
         1605  +** onto overflow pages, then getPayload() must be used to reassembly
         1606  +** the key/data and copy it into a preallocated buffer.
         1607  +**
         1608  +** The pointer returned by this routine looks directly into the cached
         1609  +** page of the database.  The data might change or move the next time
         1610  +** any btree routine is called.
         1611  +*/
         1612  +static const unsigned char *fetchPayload(
         1613  +  BtCursor *pCur,      /* Cursor pointing to entry to read from */
         1614  +  int amt,             /* Amount requested */
         1615  +  int skipKey          /* read beginning at data if this is true */
         1616  +){
         1617  +  unsigned char *aPayload;
         1618  +  MemPage *pPage;
         1619  +  Btree *pBt;
         1620  +  u64 nData, nKey;
         1621  +  int maxLocal;
         1622  +
         1623  +  assert( pCur!=0 && pCur->pPage!=0 );
         1624  +  assert( pCur->isValid );
         1625  +  pBt = pCur->pBt;
         1626  +  pPage = pCur->pPage;
         1627  +  pageIntegrity(pPage);
         1628  +  assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
         1629  +  aPayload = pPage->aCell[pCur->idx];
         1630  +  aPayload += 2;  /* Skip the next cell index */
         1631  +  if( !pPage->leaf ){
         1632  +    aPayload += 4;  /* Skip the child pointer */
         1633  +  }
         1634  +  if( pPage->zeroData ){
         1635  +    nData = 0;
         1636  +  }else{
         1637  +    aPayload += getVarint(aPayload, &nData);
         1638  +  }
         1639  +  aPayload += getVarint(aPayload, &nKey);
         1640  +  if( pPage->intKey ){
         1641  +    nKey = 0;
         1642  +  }
         1643  +  maxLocal = pBt->maxLocal;
         1644  +  if( skipKey ){
         1645  +    aPayload += nKey;
         1646  +    maxLocal -= nKey;
         1647  +    if( amt<0 ) amt = nData;
         1648  +    assert( amt<=nData );
         1649  +  }else{
         1650  +    if( amt<0 ) amt = nKey;
         1651  +    assert( amt<=nKey );
         1652  +  }
         1653  +  if( amt>maxLocal ){
         1654  +    return 0;  /* If any of the data is not local, return nothing */
         1655  +  }
         1656  +  return aPayload;
         1657  +}
         1658  +
         1659  +
         1660  +/*
         1661  +** Return a pointer to the first amt bytes of the key or data
         1662  +** for record that cursor pCur is point to if the entire request
         1663  +** exists in contiguous memory on the main tree page.  If any
         1664  +** any part of the request is on an overflow page, return 0.
         1665  +** If pCur is not pointing to a valid entry return 0.
         1666  +**
         1667  +** If amt<0 then return the entire key or data.
         1668  +**
         1669  +** The pointer returned is ephemeral.  The key/data may move
         1670  +** or be destroyed on the next call to any Btree routine.
         1671  +**
         1672  +** These routines is used to get quick access to key and data
         1673  +** in the common case where no overflow pages are used.
         1674  +**
         1675  +** It is a fatal error to call these routines with amt values that
         1676  +** are larger than the key/data size.
         1677  +*/
         1678  +const void *sqlite3BtreeKeyFetch(BtCursor *pCur, int amt){
         1679  +  return (const void*)fetchPayload(pCur, amt, 0);
         1680  +}
         1681  +const void *sqlite3BtreeDataFetch(BtCursor *pCur, int amt){
         1682  +  return (const void*)fetchPayload(pCur, amt, 1);
         1683  +}
         1684  +
  1642   1685   
  1643   1686   /*
  1644   1687   ** Move the cursor down to a new child page.  The newPgno argument is the
  1645   1688   ** page number of the child page in the byte order of the disk image.
  1646   1689   */
  1647   1690   static int moveToChild(BtCursor *pCur, u32 newPgno){
  1648   1691     int rc;
................................................................................
  1903   1946       Pgno chldPg;
  1904   1947       MemPage *pPage = pCur->pPage;
  1905   1948       int c = -1;  /* pRes return if table is empty must be -1 */
  1906   1949       lwr = 0;
  1907   1950       upr = pPage->nCell-1;
  1908   1951       pageIntegrity(pPage);
  1909   1952       while( lwr<=upr ){
  1910         -      void *pCellKey;
         1953  +      const void *pCellKey;
  1911   1954         u64 nCellKey;
  1912   1955         pCur->idx = (lwr+upr)/2;
  1913   1956         sqlite3BtreeKeySize(pCur, &nCellKey);
  1914   1957         if( pPage->intKey ){
  1915   1958           if( nCellKey<nKey ){
  1916   1959             c = -1;
  1917   1960           }else if( nCellKey>nKey ){
  1918   1961             c = +1;
  1919   1962           }else{
  1920   1963             c = 0;
  1921   1964           }
  1922         -      }else if( (pCellKey = sqlite3BtreeKeyFetch(pCur))!=0 ){
         1965  +      }else if( (pCellKey = sqlite3BtreeKeyFetch(pCur, nCellKey))!=0 ){
  1923   1966           c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey);
  1924   1967         }else{
  1925         -        pCellKey = sqliteMalloc( nCellKey );
         1968  +        u8 *pCellKey = sqliteMalloc( nCellKey );
  1926   1969           if( pCellKey==0 ) return SQLITE_NOMEM;
  1927   1970           rc = sqlite3BtreeKey(pCur, 0, nCellKey, pCellKey);
  1928   1971           c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey);
  1929   1972           sqliteFree(pCellKey);
  1930   1973           if( rc ) return rc;
  1931   1974         }
  1932   1975         if( c==0 ){

Changes to src/btree.h.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This header file defines the interface that the sqlite B-Tree file
    13     13   ** subsystem.  See comments in the source code for a detailed description
    14     14   ** of what each interface routine does.
    15     15   **
    16         -** @(#) $Id: btree.h,v 1.44 2004/05/10 23:29:50 drh Exp $
           16  +** @(#) $Id: btree.h,v 1.45 2004/05/11 00:58:56 drh Exp $
    17     17   */
    18     18   #ifndef _BTREE_H_
    19     19   #define _BTREE_H_
    20     20   
    21     21   /* TODO: This definition is just included so other modules compile. It
    22     22   ** needs to be revisited.
    23     23   */
................................................................................
    81     81   int sqlite3BtreeLast(BtCursor*, int *pRes);
    82     82   int sqlite3BtreeNext(BtCursor*, int *pRes);
    83     83   int sqlite3BtreeEof(BtCursor*);
    84     84   int sqlite3BtreeFlags(BtCursor*);
    85     85   int sqlite3BtreePrevious(BtCursor*, int *pRes);
    86     86   int sqlite3BtreeKeySize(BtCursor*, u64 *pSize);
    87     87   int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*);
    88         -void *sqlite3BtreeKeyFetch(BtCursor*);
           88  +const void *sqlite3BtreeKeyFetch(BtCursor*, int amt);
           89  +const void *sqlite3BtreeDataFetch(BtCursor*, int amt);
    89     90   int sqlite3BtreeDataSize(BtCursor*, u32 *pSize);
    90     91   int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*);
    91     92   
    92     93   char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot);
    93     94   struct Pager *sqlite3BtreePager(Btree*);
    94     95   
    95     96   

Changes to src/test3.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Code for testing the btree.c module in SQLite.  This code
    13     13   ** is not included in the SQLite library.  It is used for automated
    14     14   ** testing of the SQLite library.
    15     15   **
    16         -** $Id: test3.c,v 1.34 2004/05/10 16:18:48 drh Exp $
           16  +** $Id: test3.c,v 1.35 2004/05/11 00:58:56 drh Exp $
    17     17   */
    18     18   #include "sqliteInt.h"
    19     19   #include "pager.h"
    20     20   #include "btree.h"
    21     21   #include "tcl.h"
    22     22   #include <stdlib.h>
    23     23   #include <string.h>
................................................................................
   859    859     Tcl_AppendResult(interp, zBuf, 0);
   860    860     return SQLITE_OK;
   861    861   }
   862    862   
   863    863   /*
   864    864   ** Usage:   btree_keysize ID
   865    865   **
   866         -** Return the number of bytes of key.  
          866  +** Return the number of bytes of key.  For an INTKEY table, this
          867  +** returns the key itself.
   867    868   */
   868    869   static int btree_keysize(
   869    870     void *NotUsed,
   870    871     Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
   871    872     int argc,              /* Number of arguments */
   872    873     const char **argv      /* Text of each argument */
   873    874   ){
................................................................................
   958    959       return TCL_ERROR;
   959    960     }
   960    961     zBuf[n] = 0;
   961    962     Tcl_AppendResult(interp, zBuf, 0);
   962    963     free(zBuf);
   963    964     return SQLITE_OK;
   964    965   }
          966  +
          967  +/*
          968  +** Usage:   btree_fetch_key ID AMT
          969  +**
          970  +** Use the sqlite3BtreeKeyFetch() routine to get AMT bytes of the key.
          971  +** If sqlite3BtreeKeyFetch() fails, return an empty string.
          972  +*/
          973  +static int btree_fetch_key(
          974  +  void *NotUsed,
          975  +  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
          976  +  int argc,              /* Number of arguments */
          977  +  const char **argv      /* Text of each argument */
          978  +){
          979  +  BtCursor *pCur;
          980  +  int n;
          981  +  u64 nKey;
          982  +  const char *zBuf;
          983  +  char zStatic[1000];
          984  +
          985  +  if( argc!=3 ){
          986  +    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
          987  +       " ID AMT\"", 0);
          988  +    return TCL_ERROR;
          989  +  }
          990  +  if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
          991  +  if( Tcl_GetInt(interp, argv[2], &n) ) return TCL_ERROR;
          992  +  sqlite3BtreeKeySize(pCur, &nKey);
          993  +  zBuf = sqlite3BtreeKeyFetch(pCur, n);
          994  +  if( zBuf ){
          995  +    assert( nKey<sizeof(zStatic) );
          996  +    if( n>0 ) nKey = n;
          997  +    memcpy(zStatic, zBuf, (int)nKey); 
          998  +    zStatic[nKey] = 0;
          999  +    Tcl_AppendResult(interp, zStatic, 0);
         1000  +  }
         1001  +  return TCL_OK;
         1002  +}
         1003  +
         1004  +/*
         1005  +** Usage:   btree_fetch_data ID AMT
         1006  +**
         1007  +** Use the sqlite3BtreeDataFetch() routine to get AMT bytes of the key.
         1008  +** If sqlite3BtreeDataFetch() fails, return an empty string.
         1009  +*/
         1010  +static int btree_fetch_data(
         1011  +  void *NotUsed,
         1012  +  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
         1013  +  int argc,              /* Number of arguments */
         1014  +  const char **argv      /* Text of each argument */
         1015  +){
         1016  +  BtCursor *pCur;
         1017  +  int n;
         1018  +  u32 nData;
         1019  +  const char *zBuf;
         1020  +  char zStatic[1000];
         1021  +
         1022  +  if( argc!=3 ){
         1023  +    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
         1024  +       " ID AMT
\"", 0);
         1025  +    return TCL_ERROR;
         1026  +  }
         1027  +  if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
         1028  +  if( Tcl_GetInt(interp, argv[2], &n) ) return TCL_ERROR;
         1029  +  sqlite3BtreeDataSize(pCur, &nData);
         1030  +  zBuf = sqlite3BtreeDataFetch(pCur, n);
         1031  +  if( zBuf ){
         1032  +    assert( nData<sizeof(zStatic) );
         1033  +    if( n>0 ) nData = n;
         1034  +    memcpy(zStatic, zBuf, (int)nData); 
         1035  +    zStatic[nData] = 0;
         1036  +    Tcl_AppendResult(interp, zStatic, 0);
         1037  +  }
         1038  +  return TCL_OK;
         1039  +}
   965   1040   
   966   1041   /*
   967   1042   ** Usage:   btree_payload_size ID
   968   1043   **
   969   1044   ** Return the number of bytes of payload
   970   1045   */
   971   1046   static int btree_payload_size(
................................................................................
  1092   1167        { "btree_insert",             (Tcl_CmdProc*)btree_insert             },
  1093   1168        { "btree_next",               (Tcl_CmdProc*)btree_next               },
  1094   1169        { "btree_prev",               (Tcl_CmdProc*)btree_prev               },
  1095   1170        { "btree_eof",                (Tcl_CmdProc*)btree_eof                },
  1096   1171        { "btree_keysize",            (Tcl_CmdProc*)btree_keysize            },
  1097   1172        { "btree_key",                (Tcl_CmdProc*)btree_key                },
  1098   1173        { "btree_data",               (Tcl_CmdProc*)btree_data               },
         1174  +     { "btree_fetch_key",          (Tcl_CmdProc*)btree_fetch_key          },
         1175  +     { "btree_fetch_data",         (Tcl_CmdProc*)btree_fetch_data         },
  1099   1176        { "btree_payload_size",       (Tcl_CmdProc*)btree_payload_size       },
  1100   1177        { "btree_first",              (Tcl_CmdProc*)btree_first              },
  1101   1178        { "btree_last",               (Tcl_CmdProc*)btree_last               },
  1102   1179        { "btree_cursor_info",        (Tcl_CmdProc*)btree_cursor_info        },
  1103   1180        { "btree_cursor_list",        (Tcl_CmdProc*)btree_cursor_list        },
  1104   1181        { "btree_integrity_check",    (Tcl_CmdProc*)btree_integrity_check    },
  1105   1182        { "btree_breakpoint",         (Tcl_CmdProc*)btree_breakpoint         },

Changes to src/vdbeaux.c.

  1069   1069   int sqlite2BtreeKeyCompare(
  1070   1070     BtCursor *pCur,       /* Pointer to entry to compare against */
  1071   1071     const void *pKey,     /* Key to compare against entry that pCur points to */
  1072   1072     int nKey,             /* Number of bytes in pKey */
  1073   1073     int nIgnore,          /* Ignore this many bytes at the end of pCur */
  1074   1074     int *pResult          /* Write the result here */
  1075   1075   ){
  1076         -  void *pCellKey;
         1076  +  const void *pCellKey;
         1077  +  void *pMallocedKey;
  1077   1078     u64 nCellKey;
  1078   1079     int rc;
  1079   1080   
  1080   1081     sqlite3BtreeKeySize(pCur, &nCellKey);
  1081   1082     nCellKey = nCellKey - nIgnore;
  1082   1083     if( nCellKey<=0 ){
  1083   1084       *pResult = 0;
  1084   1085       return SQLITE_OK;
  1085   1086     }
  1086   1087   
  1087         -  pCellKey = sqlite3BtreeKeyFetch(pCur);
         1088  +  pCellKey = sqlite3BtreeKeyFetch(pCur, nCellKey);
  1088   1089     if( pCellKey ){
  1089   1090       *pResult = memcmp(pCellKey, pKey, nKey>nCellKey?nCellKey:nKey);
  1090   1091       return SQLITE_OK;
  1091   1092     }
  1092   1093   
  1093         -  pCellKey = sqliteMalloc( nCellKey );
  1094         -  if( pCellKey==0 ) return SQLITE_NOMEM;
         1094  +  pMallocedKey = sqliteMalloc( nCellKey );
         1095  +  if( pMallocedKey==0 ) return SQLITE_NOMEM;
  1095   1096   
  1096         -  rc = sqlite3BtreeKey(pCur, 0, nCellKey, pCellKey);
  1097         -  *pResult = memcmp(pCellKey, pKey, nKey>nCellKey?nCellKey:nKey);
  1098         -  sqliteFree(pCellKey);
         1097  +  rc = sqlite3BtreeKey(pCur, 0, nCellKey, pMallocedKey);
         1098  +  *pResult = memcmp(pMallocedKey, pKey, nKey>nCellKey?nCellKey:nKey);
         1099  +  sqliteFree(pMallocedKey);
  1099   1100   
  1100   1101     return rc;
  1101   1102   }
  1102   1103   
  1103   1104   /*
  1104   1105   ** The following three functions:
  1105   1106   **
................................................................................
  1242   1243       int ii;
  1243   1244       int bytes = 1 << (data_type-1);
  1244   1245   
  1245   1246       pMem->flags = MEM_Int;
  1246   1247       pMem->i = 0;
  1247   1248   
  1248   1249       for(ii=0; ii<bytes; ii++){
  1249         -      pMem->i = pMem->i<<8 + zBuf[ii+ret];
         1250  +      pMem->i = (pMem->i<<8) + zBuf[ii+ret];
  1250   1251       }
  1251   1252   
  1252   1253       /* If this is a 1, 2 or 4 byte integer, extend the sign-bit if need be. */
  1253   1254       if( bytes<8 && pMem->i & (1<<(bytes*8-1)) ){
  1254   1255         pMem->i = pMem->i - (1<<(bytes*8));
  1255   1256       }
  1256   1257   

Changes to test/btree5.test.

     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this script is btree database backend
    13     13   #
    14         -# $Id: btree5.test,v 1.1 2004/05/10 18:45:10 drh Exp $
           14  +# $Id: btree5.test,v 1.2 2004/05/11 00:58:56 drh Exp $
    15     15   
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
    19     19   
    20     20   # Attempting to read table 1 of an empty file gives an SQLITE_EMPTY
    21     21   # error.
................................................................................
   112    112   # each entry agrees with its key.
   113    113   #
   114    114   proc check_table {N} {
   115    115     global c1
   116    116     btree_first $c1
   117    117     set cnt 0
   118    118     while {![btree_eof $c1]} {
   119         -    if {[btree_data $c1] ne "data-for-[btree_key $c1]"} {
          119  +    if {[set data [btree_data $c1]] ne "data-for-[btree_key $c1]"} {
   120    120         return "wrong data for entry $cnt"
          121  +    }
          122  +    set n [string length $data]
          123  +    set fdata1 [btree_fetch_data $c1 $n]
          124  +    set fdata2 [btree_fetch_data $c1 -1]
          125  +    if {$fdata1 ne "" && $fdata1 ne $data} {
          126  +puts "fdata1=[list $fdata1] data=[list $data]"
          127  +      return "DataFetch returned the wrong value with amt=$n"
          128  +    }
          129  +    if {$fdata1 ne $fdata2} {
          130  +      return "DataFetch returned the wrong value when amt=-1"
          131  +    }
          132  +    if {$n>10} {
          133  +      set fdata3 [btree_fetch_data $c1 10]
          134  +      if {$fdata3 ne [string range $data 0 9]} {
          135  +        return "DataFetch returned the wrong value when amt=10"
          136  +      }
   121    137       }
   122    138       incr cnt
   123    139       btree_next $c1
   124    140     }
   125    141     if {$cnt!=$N} {
   126    142       return "wrong number of entries"
   127    143     }