/ Check-in [0242c9e4]
Login

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

Overview
Comment:Change the table record format to support manifest typing. (CVS 1361)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 0242c9e4f7c85e9c911cf30d90b0cdb1015f3d7d
User & Date: danielk1977 2004-05-12 07:33:33
Context
2004-05-12
11:24
Add some more code to support manifest typing in indices. Not activated yet. (CVS 1362) check-in: 2f16c9ef user: danielk1977 tags: trunk
07:33
Change the table record format to support manifest typing. (CVS 1361) check-in: 0242c9e4 user: danielk1977 tags: trunk
2004-05-11
10:04
Change sqlite_ to sqlite3_ in the attach2.test test script. (CVS 1360) check-in: 98f756e6 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/printf.c.

   354    354           if( longvalue==0 ) flag_alternateform = 0;
   355    355   #else
   356    356           /* More sensible: turn off the prefix for octal (to prevent "00"),
   357    357           ** but leave the prefix for hex. */
   358    358           if( longvalue==0 && infop->base==8 ) flag_alternateform = 0;
   359    359   #endif
   360    360           if( infop->flags & FLAG_SIGNED ){
   361         -          if( *(long*)&longvalue<0 ){
   362         -            longvalue = -*(long*)&longvalue;
   363         -            prefix = '-';
   364         -          }else if( flag_plussign )  prefix = '+';
   365         -          else if( flag_blanksign )  prefix = ' ';
   366         -          else                       prefix = 0;
          361  +          if( flag_longlong ){
          362  +            if( *(i64*)&longvalue<0 ){
          363  +              longvalue = -*(i64*)&longvalue;
          364  +              prefix = '-';
          365  +            }else if( flag_plussign )  prefix = '+';
          366  +            else if( flag_blanksign )  prefix = ' ';
          367  +            else                       prefix = 0;
          368  +          }else{
          369  +            if( *(long*)&longvalue<0 ){
          370  +              longvalue = -*(long*)&longvalue;
          371  +              prefix = '-';
          372  +            }else if( flag_plussign )  prefix = '+';
          373  +            else if( flag_blanksign )  prefix = ' ';
          374  +            else                       prefix = 0;
          375  +          }
   367    376           }else                        prefix = 0;
   368    377           if( flag_zeropad && precision<width-(prefix!=0) ){
   369    378             precision = width-(prefix!=0);
   370    379           }
   371    380           bufpt = &buf[etBUFSIZE-1];
   372    381           {
   373    382             register char *cset;      /* Use registers for speed */

Changes to src/sqliteInt.h.

     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     12   ** Internal interface definitions for SQLite.
    13     13   **
    14         -** @(#) $Id: sqliteInt.h,v 1.229 2004/05/10 23:29:50 drh Exp $
           14  +** @(#) $Id: sqliteInt.h,v 1.230 2004/05/12 07:33:33 danielk1977 Exp $
    15     15   */
    16     16   #include "config.h"
    17     17   #include "sqlite.h"
    18     18   #include "hash.h"
    19     19   #include "parse.h"
    20     20   #include <stdio.h>
    21     21   #include <stdlib.h>
................................................................................
  1284   1284   void *sqlite3utf8to16be(const unsigned char *pIn, int N);
  1285   1285   void *sqlite3utf8to16le(const unsigned char *pIn, int N);
  1286   1286   void sqlite3utf16to16le(void *pData, int N);
  1287   1287   void sqlite3utf16to16be(void *pData, int N);
  1288   1288   int sqlite3PutVarint(unsigned char *, u64);
  1289   1289   int sqlite3GetVarint(const unsigned char *, u64 *);
  1290   1290   int sqlite3VarintLen(u64 v);
         1291  +
         1292  +

Changes to src/vdbe.c.

    39     39   **
    40     40   ** Various scripts scan this source file in order to generate HTML
    41     41   ** documentation, headers files, or other derived files.  The formatting
    42     42   ** of the code in this file is, therefore, important.  See other comments
    43     43   ** in this file for details.  If in doubt, do not deviate from existing
    44     44   ** commenting and indentation practices when changing or adding code.
    45     45   **
    46         -** $Id: vdbe.c,v 1.282 2004/05/11 09:57:35 drh Exp $
           46  +** $Id: vdbe.c,v 1.283 2004/05/12 07:33:33 danielk1977 Exp $
    47     47   */
    48     48   #include "sqliteInt.h"
    49     49   #include "os.h"
    50     50   #include <ctype.h>
    51     51   #include "vdbeInt.h"
    52     52   
    53     53   /*
................................................................................
   195    195   */
   196    196   #define Stringify(P) if(((P)->flags & MEM_Str)==0){hardStringify(P);}
   197    197   static int hardStringify(Mem *pStack){
   198    198     int fg = pStack->flags;
   199    199     if( fg & MEM_Real ){
   200    200       sqlite3_snprintf(sizeof(pStack->zShort),pStack->zShort,"%.15g",pStack->r);
   201    201     }else if( fg & MEM_Int ){
   202         -    sqlite3_snprintf(sizeof(pStack->zShort),pStack->zShort,"%d",pStack->i);
          202  +    sqlite3_snprintf(sizeof(pStack->zShort),pStack->zShort,"%lld",pStack->i);
   203    203     }else{
   204    204       pStack->zShort[0] = 0;
   205    205     }
   206    206     pStack->z = pStack->zShort;
   207    207     pStack->n = strlen(pStack->zShort)+1;
   208    208     pStack->flags = MEM_Str | MEM_Short;
   209    209     return 0;
................................................................................
  1010   1010     assert( pNos>=p->aStack );
  1011   1011     if( ((pTos->flags | pNos->flags) & MEM_Null)!=0 ){
  1012   1012       Release(pTos);
  1013   1013       pTos--;
  1014   1014       Release(pTos);
  1015   1015       pTos->flags = MEM_Null;
  1016   1016     }else if( (pTos->flags & pNos->flags & MEM_Int)==MEM_Int ){
  1017         -    int a, b;
         1017  +    i64 a, b;
  1018   1018       a = pTos->i;
  1019   1019       b = pNos->i;
  1020   1020       switch( pOp->opcode ){
  1021   1021         case OP_Add:         b += a;       break;
  1022   1022         case OP_Subtract:    b -= a;       break;
  1023   1023         case OP_Multiply:    b *= a;       break;
  1024   1024         case OP_Divide: {
................................................................................
  1807   1807     if( i>=cnt ) pc = pOp->p2-1;
  1808   1808     if( pOp->p1>0 ) popStack(&pTos, cnt);
  1809   1809     break;
  1810   1810   }
  1811   1811   
  1812   1812   /* Opcode: Column3 P1 P2 *
  1813   1813   **
  1814         -** This opcode (not yet in use) is a replacement for the current
  1815         -** OP_Column3 that supports the SQLite3 manifest typing feature.
  1816         -**
  1817         -** Interpret the data that cursor P1 points to as
  1818         -** a structure built using the MakeRecord instruction.
  1819         -** (See the MakeRecord opcode for additional information about
  1820         -** the format of the data.)
  1821         -** Push onto the stack the value of the P2-th column contained
  1822         -** in the data.
  1823         -**
  1824         -** If the KeyAsData opcode has previously executed on this cursor,
  1825         -** then the field might be extracted from the key rather than the
  1826         -** data.
  1827         -**
  1828         -** If P1 is negative, then the record is stored on the stack rather
  1829         -** than in a table.  For P1==-1, the top of the stack is used.
  1830         -** For P1==-2, the next on the stack is used.  And so forth.  The
  1831         -** value pushed is always just a pointer into the record which is
  1832         -** stored further down on the stack.  The column value is not copied.
  1833         -*/
  1834         -case OP_Column3: {
  1835         -  int payloadSize;
  1836         -  int i = pOp->p1;
  1837         -  int p2 = pOp->p2;
         1814  +** This opcode (not yet in use) is a replacement for the current OP_Column3
         1815  +** that supports the SQLite3 manifest typing feature.
         1816  +**
         1817  +** Interpret the data that cursor P1 points to as a structure built using
         1818  +** the MakeRecord instruction.  (See the MakeRecord opcode for additional
         1819  +** information about the format of the data.) Push onto the stack the value
         1820  +** of the P2-th column contained in the data.
         1821  +**
         1822  +** If the KeyAsData opcode has previously executed on this cursor, then the
         1823  +** field might be extracted from the key rather than the data.
         1824  +**
         1825  +** If P1 is negative, then the record is stored on the stack rather than in
         1826  +** a table.  For P1==-1, the top of the stack is used.  For P1==-2, the
         1827  +** next on the stack is used.  And so forth.  The value pushed is always
         1828  +** just a pointer into the record which is stored further down on the
         1829  +** stack.  The column value is not copied.
         1830  +*/
         1831  +case OP_Column: {
         1832  +  int payloadSize;   /* Number of bytes in the record */
         1833  +  int i = pOp->p1;
         1834  +  int p2 = pOp->p2;  /* column number to retrieve */
  1838   1835     Cursor *pC;
  1839         -  char *zRec;
         1836  +  char *zRec;        /* Pointer to record-data from stack or pseudo-table. */
  1840   1837     BtCursor *pCrsr;
  1841   1838   
  1842         -  char *zHdr = 0;
  1843         -  int freeZHdr = 0;
  1844         -  int dataOffsetLen;
  1845         -  u64 dataOffset;
  1846         -  char *zIdx = 0;
  1847         -  int cnt;
  1848         -  u64 idxN;
  1849         -  u64 idxN1;
         1839  +  char *zData;       
         1840  +  int freeZdata = 0; /* zData requires sqliteFree() */
         1841  +
         1842  +  u64 nFields;       /* number of fields in the record */
         1843  +  u64 *aTypes;       /* An array of serial types (size nFields) */
         1844  +
         1845  +  int len;           /* The length of the serialized data for the column */
         1846  +  int offset;
         1847  +  int nn;
  1850   1848   
  1851   1849     assert( i<p->nCursor );
  1852   1850     pTos++;
         1851  +
         1852  +  /* This block sets the variable payloadSize, and if the data is coming
         1853  +  ** from the stack or from a pseudo-table zRec. If the data is coming
         1854  +  ** from a real cursor, then zRec is left as NULL.
         1855  +  */
  1853   1856     if( i<0 ){
  1854   1857       assert( &pTos[i]>=p->aStack );
  1855   1858       assert( pTos[i].flags & MEM_Str );
  1856   1859       zRec = pTos[i].z;
  1857   1860       payloadSize = pTos[i].n;
  1858   1861     }else if( (pC = &p->aCsr[i])->pCursor!=0 ){
  1859   1862       sqlite3VdbeCursorMoveto(pC);
................................................................................
  1878   1881   
  1879   1882     /* If payloadSize is 0, then just push a NULL onto the stack. */
  1880   1883     if( payloadSize==0 ){
  1881   1884       pTos->flags = MEM_Null;
  1882   1885       break;
  1883   1886     }
  1884   1887   
  1885         -  /* Read the data-offset for this record */
  1886         -  if( zRec ){
  1887         -    dataOffsetLen = sqlite3GetVarint(zRec, &dataOffset);
  1888         -  }else{
  1889         -    unsigned char zDataOffset[9];
  1890         -    if( pC->keyAsData ){
  1891         -      sqlite3BtreeKey(pCrsr, 0, 9, zDataOffset);
  1892         -    }else{
  1893         -      sqlite3BtreeData(pCrsr, 0, 9, zDataOffset);
  1894         -    }
  1895         -    dataOffsetLen = sqlite3GetVarint(zDataOffset, &dataOffset);
  1896         -  }
  1897         -
  1898         -  /* Set zHdr to point at the start of the Idx() fields of the
  1899         -  ** record. Set freeZHdr to 1 if we need to sqliteFree(zHdr) later.
         1888  +  /* Read the number of fields for the record.
         1889  +  ** FIX ME: The Cursor object should cache this data and the array of
         1890  +  ** field types for subsequent OP_Column instructions.
  1900   1891     */
  1901   1892     if( zRec ){
  1902         -    zHdr = zRec + dataOffsetLen;
         1893  +    zData = zRec;
  1903   1894     }else{
  1904         -    zHdr = sqliteMalloc(dataOffset);
  1905         -    if( !zHdr ){
  1906         -      rc = SQLITE_NOMEM;
  1907         -      goto abort_due_to_error;
  1908         -    }
  1909         -    freeZHdr = 1;
         1895  +    /* We can assume that 9 bytes (maximum length of a varint) fits
         1896  +    ** on the main page in all cases.
         1897  +    */
  1910   1898       if( pC->keyAsData ){
  1911         -      sqlite3BtreeKey(pCrsr, dataOffsetLen, dataOffset, zHdr);
  1912         -    }else{
  1913         -      sqlite3BtreeData(pCrsr, dataOffsetLen, dataOffset, zHdr);
  1914         -    }
  1915         -  }
  1916         -
  1917         -  /* Find the Nth byte of zHdr that does not have the 0x80
  1918         -  ** bit set. The byte after this one is the start of the Idx(N)
  1919         -  ** varint. Then read Idx(N) and Idx(N+1)
  1920         -  */
  1921         -  cnt = p2;
  1922         -  zIdx = zHdr;
  1923         -  while( cnt>0 ){
  1924         -    assert( (zIdx-zHdr)<dataOffset );
  1925         -    if( !(*zIdx & 0x80) ) cnt--;
  1926         -    zIdx++;
  1927         -  }
  1928         -  zIdx += sqlite3GetVarint(zIdx, &idxN);
  1929         -  sqlite3GetVarint(zIdx, &idxN1);
  1930         -
  1931         -  /* Set zHdr to point at the field data */
  1932         -  if( freeZHdr ){
  1933         -    sqliteFree(zHdr);
  1934         -    freeZHdr = 0;
  1935         -  }
  1936         -  if( zRec ){
  1937         -    zHdr = zRec + (dataOffsetLen + dataOffset + idxN);
  1938         -  }else{
  1939         -    cnt = idxN1 - idxN;
  1940         -    assert( cnt>0 );
  1941         -    zHdr = sqliteMalloc(cnt);
  1942         -    if( !zHdr ){
  1943         -      rc = SQLITE_NOMEM;
  1944         -      goto abort_due_to_error;
  1945         -    }
  1946         -    freeZHdr = 1;
         1899  +      zData = (char *)sqlite3BtreeKeyFetch(pCrsr, 9>payloadSize?payloadSize:9);
         1900  +    }else{
         1901  +      zData = (char *)sqlite3BtreeDataFetch(pCrsr, 9>payloadSize?payloadSize:9);
         1902  +    }
         1903  +    assert( zData );
         1904  +  }
         1905  +  offset = sqlite3GetVarint(zData, &nFields);
         1906  +
         1907  +  if( !zRec ){
         1908  +    /* If the record is stored in a table, see if enough of it is on
         1909  +    ** the main page to use sqlite3BtreeDataFetch() to get the data
         1910  +    ** containing the nFields serial types (varints). This will almost
         1911  +    ** always work, but if it doesn't sqliteMalloc() space and use
         1912  +    ** sqlite3BtreeData().
         1913  +    **
         1914  +    ** Estimate the maximum space required by the nFields varints by
         1915  +    ** assuming the maximum space for each is the length required to store:
         1916  +    **
         1917  +    **     (<record length> * 2) + 13
         1918  +    **
         1919  +    ** This is the serial-type for a text object as long as the record
         1920  +    ** itself. In all cases the length required to store this is three
         1921  +    ** bytes or less. 
         1922  +    */
         1923  +    int max_space = sqlite3VarintLen((((u64)payloadSize)<<1)+13)*nFields;
         1924  +    max_space += offset;
         1925  +    if( max_space>payloadSize ){
         1926  +      max_space = payloadSize;
         1927  +    }
         1928  +
  1947   1929       if( pC->keyAsData ){
  1948         -      sqlite3BtreeKey(pCrsr, dataOffsetLen+dataOffset+idxN, cnt, zHdr);
         1930  +      zData = (char *)sqlite3BtreeKeyFetch(pCrsr, max_space);
  1949   1931       }else{
  1950         -      sqlite3BtreeData(pCrsr, dataOffsetLen+dataOffset+idxN, cnt, zHdr);
         1932  +      zData = (char *)sqlite3BtreeDataFetch(pCrsr, max_space);
         1933  +    }
         1934  +    if( !zData ){
         1935  +      /* This code will run very infrequently (e.g. tables with several
         1936  +      ** hundred columns).
         1937  +      */
         1938  +      zData = (char *)sqliteMalloc(offset+max_space);
         1939  +      if( !zData ){
         1940  +        rc = SQLITE_NOMEM;
         1941  +        goto abort_due_to_error;
         1942  +      }
         1943  +      if( pC->keyAsData ){
         1944  +        rc = sqlite3BtreeKey(pCrsr, 0, max_space, zData);
         1945  +      }else{
         1946  +        rc = sqlite3BtreeData(pCrsr, 0, max_space, zData);
         1947  +      }
         1948  +      if( rc!=SQLITE_OK ){
         1949  +        sqliteFree(zData);
         1950  +        goto abort_due_to_error;
         1951  +      }
         1952  +      freeZdata = 1;
  1951   1953       }
  1952   1954     }
  1953   1955   
  1954         -  /* Deserialize the field value directory into the top of the
  1955         -  ** stack. If the deserialized length does not match the expected
  1956         -  ** length, this indicates corruption.
         1956  +  /* Dynamically allocate space for the aTypes array. and read all
         1957  +  ** the serial types for the record. At the end of this block variable
         1958  +  ** offset is set to the offset to the start of Data0 in the record.
  1957   1959     */
  1958         -  if( (idxN1-idxN)!=sqlite3VdbeDeserialize(pTos, zHdr) ){
  1959         -    if( freeZHdr ){
  1960         -      sqliteFree(zHdr);
         1960  +  aTypes = (u64 *)sqliteMalloc(sizeof(u64)*nFields);
         1961  +  if( !aTypes ){
         1962  +    if( freeZdata ){
         1963  +      sqliteFree(zData);
         1964  +      freeZdata = 0;
  1961   1965       }
  1962         -    rc = SQLITE_CORRUPT;
         1966  +    rc = SQLITE_NOMEM;
  1963   1967       goto abort_due_to_error;
  1964   1968     }
         1969  +  for(nn=0; nn<nFields; nn++){
         1970  +    offset += sqlite3GetVarint(&zData[offset], &aTypes[nn]);
         1971  +  }
         1972  + 
         1973  +  if( freeZdata ){
         1974  +    freeZdata = 0;
         1975  +    sqliteFree(zData);
         1976  +  }
  1965   1977   
  1966         -  if( freeZHdr ){
  1967         -    sqliteFree(zHdr);
         1978  +  for(nn=0; nn<p2; nn++){
         1979  +    offset += sqlite3VdbeSerialTypeLen(aTypes[nn]);
         1980  +  }
         1981  +  len = sqlite3VdbeSerialTypeLen(aTypes[p2]);
         1982  +
         1983  +  if( !zRec ){
         1984  +    /* If the record is stored in a table, see if enough of it
         1985  +    ** is on the main page to read our column using
         1986  +    ** sqlite3BtreeDataFetch(). If not sqliteMalloc() space and read data
         1987  +    ** with sqlite3BtreeData().
         1988  +    */
         1989  +    if( pC->keyAsData ){
         1990  +      zData = (char *)sqlite3BtreeKeyFetch(pCrsr, offset+len);
         1991  +    }else{
         1992  +      zData = (char *)sqlite3BtreeDataFetch(pCrsr, offset+len);
         1993  +    }
         1994  +    if( !zData && len>0 ){
         1995  +      zData = (char *)sqliteMalloc(len);
         1996  +      if( !zData ){
         1997  +        sqliteFree(aTypes);
         1998  +        rc = SQLITE_NOMEM;
         1999  +        goto abort_due_to_error;
         2000  +      }
         2001  +      if( pC->keyAsData ){
         2002  +        rc = sqlite3BtreeKey(pCrsr, offset, len, zData);
         2003  +      }else{
         2004  +        rc = sqlite3BtreeData(pCrsr, offset, len, zData);
         2005  +      }
         2006  +      if( rc!=SQLITE_OK ){
         2007  +        sqliteFree( aTypes );
         2008  +        sqliteFree( zData );
         2009  +        goto abort_due_to_error;
         2010  +      }
         2011  +      freeZdata = 1;
         2012  +      offset = 0;
         2013  +    }
         2014  +  }
         2015  +
         2016  +  /* Deserialize the value directly into the top of the stack */
         2017  +  sqlite3VdbeSerialGet(&zData[offset], aTypes[p2], pTos);
         2018  +
         2019  +  sqliteFree(aTypes);
         2020  +  if( freeZdata ){
         2021  +    sqliteFree(zData);
  1968   2022     }
  1969   2023     break;
  1970   2024   }
  1971   2025   
  1972   2026   /* Opcode MakeRecord3 P1 * *
  1973   2027   **
  1974   2028   ** This opcode (not yet in use) is a replacement for the current
................................................................................
  1977   2031   **
  1978   2032   ** Convert the top P1 entries of the stack into a single entry
  1979   2033   ** suitable for use as a data record in a database table.  The
  1980   2034   ** details of the format are irrelavant as long as the OP_Column
  1981   2035   ** opcode can decode the record later.  Refer to source code
  1982   2036   ** comments for the details of the record format.
  1983   2037   */
  1984         -case OP_MakeRecord3: {
         2038  +case OP_MakeRecord: {
  1985   2039     /* Assuming the record contains N fields, the record format looks
  1986   2040     ** like this:
  1987   2041     **
  1988   2042     ** --------------------------------------------------------------------------
  1989         -  ** | data-offset | idx1 | ... | idx(N-1) | idx(N) | data0 | ... | data(N-1) |
         2043  +  ** | num-fields | type 0 | type 1 | ... | type N-1 | data0 | ... | data N-1 | 
  1990   2044     ** --------------------------------------------------------------------------
  1991   2045     **
  1992   2046     ** Data(0) is taken from the lowest element of the stack and data(N-1) is
  1993   2047     ** the top of the stack.
  1994   2048     **
  1995         -  ** The data-offset and each of the idx() entries is stored as a 1-9 
  1996         -  ** byte variable-length integer (see comments in btree.c). The
  1997         -  ** data-offset contains the offset from the end of itself to the start 
  1998         -  ** of data(0).
         2049  +  ** Each type field is a varint representing the serial type of the 
         2050  +  ** corresponding data element (see sqlite3VdbeSerialType()). The
         2051  +  ** num-fields field is also a varint storing N.
  1999   2052     ** 
  2000         -  ** Idx(k) contains the offset from the start of data(0) to the first 
  2001         -  ** byte of data(k). Idx(0) is implicitly 0. Hence:
  2002         -  ** 
  2003         -  **    sizeof(data-offset) + data-offset + Idx(N) 
  2004         -  **
  2005         -  ** is the number of bytes in the record. The offset to start of data(X)
  2006         -  ** is sizeof(data-offset) + data-offset + Idx(X
  2007         -  **
  2008   2053     ** TODO: Even when the record is short enough for Mem::zShort, this opcode
  2009   2054     **   allocates it dynamically.
  2010   2055     */
  2011         -  int nDataLen = 0;
  2012         -  int nHdrLen = 0;
  2013         -  int data_offset = 0;
  2014   2056     int nField = pOp->p1;
  2015   2057     unsigned char *zNewRecord;
  2016         -  unsigned char *zHdr;
         2058  +  unsigned char *zCsr;
  2017   2059     Mem *pRec;
         2060  +  int nBytes;    /* Space required for this record */
  2018   2061   
  2019   2062     Mem *pData0 = &pTos[1-nField];
  2020   2063     assert( pData0>=p->aStack );
  2021   2064   
  2022         -  /* Loop through the elements that will make up the record, determining
  2023         -  ** the aggregate length of the Data() segments and the data_offset.
         2065  +  /* Loop through the elements that will make up the record to figure
         2066  +  ** out how much space is required for the new record.
  2024   2067     */
  2025         -  for(pRec=pData0; pRec!=pTos; pRec++){
  2026         -    nDataLen += sqlite3VdbeSerialLen(pRec);
  2027         -    data_offset += sqlite3VarintLen(nDataLen);
  2028         -  }
  2029         - 
  2030         -  /* The size of the header is the data-offset + the size of the
  2031         -  ** data-offset as a varint. If the size of the header combined with
  2032         -  ** the size of the Data() segments is greater than MAX_BYTES_PER_ROW, 
  2033         -  ** report an error.
  2034         -  */
  2035         -  nHdrLen = data_offset + sqlite3VarintLen(data_offset);
  2036         -  if( (nHdrLen+nDataLen)>MAX_BYTES_PER_ROW ){
  2037         -    rc = SQLITE_TOOBIG;
  2038         -    goto abort_due_to_error;
         2068  +  nBytes = sqlite3VarintLen(nField);
         2069  +  for(pRec=pData0; pRec<=pTos; pRec++){
         2070  +    u64 serial_type = sqlite3VdbeSerialType(pRec);
         2071  +    nBytes += sqlite3VdbeSerialTypeLen(serial_type);
         2072  +    nBytes += sqlite3VarintLen(serial_type);
  2039   2073     }
  2040   2074   
  2041         -  /* Allocate space for the new row. */
  2042         -  zNewRecord = sqliteMalloc(nHdrLen+nDataLen);
         2075  +  /* Allocate space for the new record. */
         2076  +  zNewRecord = sqliteMalloc(nBytes);
  2043   2077     if( !zNewRecord ){
  2044   2078       rc = SQLITE_NOMEM;
  2045   2079       goto abort_due_to_error;
  2046   2080     }
  2047   2081   
  2048         -  /* Write the data offset */
  2049         -  zHdr = zNewRecord;
  2050         -  zHdr += sqlite3PutVarint(zHdr, data_offset);
         2082  +  /* Write the record */
         2083  +  zCsr = zNewRecord;
         2084  +  zCsr += sqlite3PutVarint(zCsr, nField);             /* number of fields */
         2085  +  for(pRec=pData0; pRec<=pTos; pRec++){
         2086  +    u64 serial_type = sqlite3VdbeSerialType(pRec);
         2087  +    zCsr += sqlite3PutVarint(zCsr, serial_type);      /* serial type */
         2088  +  }
         2089  +  for(pRec=pData0; pRec<=pTos; pRec++){
         2090  +    zCsr += sqlite3VdbeSerialPut(zCsr, pRec);  /* serial data */
         2091  +  }
  2051   2092   
  2052         -  /* Loop through the values on the stack writing both the serialized value
  2053         -  ** and the the Idx() offset for each.
         2093  +  /* If zCsr has not been advanced exactly nBytes bytes, then one
         2094  +  ** of the sqlite3PutVarint() or sqlite3VdbeSerialPut() calls above
         2095  +  ** failed. This indicates a corrupted memory cell or code bug.
  2054   2096     */
  2055         -  nDataLen = 0;
  2056         -  for(pRec=pData0; pRec!=pTos; pRec++){
  2057         -    nDataLen += sqlite3VdbeSerialize(pRec, &zNewRecord[nDataLen]);
  2058         -    zHdr += sqlite3PutVarint(zHdr, nDataLen);
         2097  +  if( zCsr!=(zNewRecord+nBytes) ){
         2098  +    rc = SQLITE_INTERNAL;
         2099  +    goto abort_due_to_error;
  2059   2100     }
  2060   2101   
  2061   2102     /* Pop nField entries from the stack and push the new entry on */
  2062   2103     popStack(&pTos, nField);
  2063   2104     pTos++;
  2064         -  pTos->n = nDataLen+nHdrLen;
         2105  +  pTos->n = nBytes;
  2065   2106     pTos->z = zNewRecord;
  2066   2107     pTos->flags = MEM_Str | MEM_Dyn;
  2067   2108   
  2068         -  break;
  2069         -}
  2070         -
  2071         -/* Opcode: MakeRecord P1 P2 *
  2072         -**
  2073         -** Convert the top P1 entries of the stack into a single entry
  2074         -** suitable for use as a data record in a database table.  The
  2075         -** details of the format are irrelavant as long as the OP_Column
  2076         -** opcode can decode the record later.  Refer to source code
  2077         -** comments for the details of the record format.
  2078         -**
  2079         -** If P2 is true (non-zero) and one or more of the P1 entries
  2080         -** that go into building the record is NULL, then add some extra
  2081         -** bytes to the record to make it distinct for other entries created
  2082         -** during the same run of the VDBE.  The extra bytes added are a
  2083         -** counter that is reset with each run of the VDBE, so records
  2084         -** created this way will not necessarily be distinct across runs.
  2085         -** But they should be distinct for transient tables (created using
  2086         -** OP_OpenTemp) which is what they are intended for.
  2087         -**
  2088         -** (Later:) The P2==1 option was intended to make NULLs distinct
  2089         -** for the UNION operator.  But I have since discovered that NULLs
  2090         -** are indistinct for UNION.  So this option is never used.
  2091         -*/
  2092         -case OP_MakeRecord: {
  2093         -  char *zNewRecord;
  2094         -  int nByte;
  2095         -  int nField;
  2096         -  int i, j;
  2097         -  int idxWidth;
  2098         -  u32 addr;
  2099         -  Mem *pRec;
  2100         -  int addUnique = 0;   /* True to cause bytes to be added to make the
  2101         -                       ** generated record distinct */
  2102         -  char zTemp[NBFS];    /* Temp space for small records */
  2103         -
  2104         -  /* Assuming the record contains N fields, the record format looks
  2105         -  ** like this:
  2106         -  **
  2107         -  **   -------------------------------------------------------------------
  2108         -  **   | idx0 | idx1 | ... | idx(N-1) | idx(N) | data0 | ... | data(N-1) |
  2109         -  **   -------------------------------------------------------------------
  2110         -  **
  2111         -  ** All data fields are converted to strings before being stored and
  2112         -  ** are stored with their null terminators.  NULL entries omit the
  2113         -  ** null terminator.  Thus an empty string uses 1 byte and a NULL uses
  2114         -  ** zero bytes.  Data(0) is taken from the lowest element of the stack
  2115         -  ** and data(N-1) is the top of the stack.
  2116         -  **
  2117         -  ** Each of the idx() entries is either 1, 2, or 3 bytes depending on
  2118         -  ** how big the total record is.  Idx(0) contains the offset to the start
  2119         -  ** of data(0).  Idx(k) contains the offset to the start of data(k).
  2120         -  ** Idx(N) contains the total number of bytes in the record.
  2121         -  */
  2122         -  nField = pOp->p1;
  2123         -  pRec = &pTos[1-nField];
  2124         -  assert( pRec>=p->aStack );
  2125         -  nByte = 0;
  2126         -  for(i=0; i<nField; i++, pRec++){
  2127         -    if( pRec->flags & MEM_Null ){
  2128         -      addUnique = pOp->p2;
  2129         -    }else{
  2130         -      Stringify(pRec);
  2131         -      nByte += pRec->n;
  2132         -    }
  2133         -  }
  2134         -  if( addUnique ) nByte += sizeof(p->uniqueCnt);
  2135         -  if( nByte + nField + 1 < 256 ){
  2136         -    idxWidth = 1;
  2137         -  }else if( nByte + 2*nField + 2 < 65536 ){
  2138         -    idxWidth = 2;
  2139         -  }else{
  2140         -    idxWidth = 3;
  2141         -  }
  2142         -  nByte += idxWidth*(nField + 1);
  2143         -  if( nByte>MAX_BYTES_PER_ROW ){
  2144         -    rc = SQLITE_TOOBIG;
  2145         -    goto abort_due_to_error;
  2146         -  }
  2147         -  if( nByte<=NBFS ){
  2148         -    zNewRecord = zTemp;
  2149         -  }else{
  2150         -    zNewRecord = sqliteMallocRaw( nByte );
  2151         -    if( zNewRecord==0 ) goto no_mem;
  2152         -  }
  2153         -  j = 0;
  2154         -  addr = idxWidth*(nField+1) + addUnique*sizeof(p->uniqueCnt);
  2155         -  for(i=0, pRec=&pTos[1-nField]; i<nField; i++, pRec++){
  2156         -    zNewRecord[j++] = addr & 0xff;
  2157         -    if( idxWidth>1 ){
  2158         -      zNewRecord[j++] = (addr>>8)&0xff;
  2159         -      if( idxWidth>2 ){
  2160         -        zNewRecord[j++] = (addr>>16)&0xff;
  2161         -      }
  2162         -    }
  2163         -    if( (pRec->flags & MEM_Null)==0 ){
  2164         -      addr += pRec->n;
  2165         -    }
  2166         -  }
  2167         -  zNewRecord[j++] = addr & 0xff;
  2168         -  if( idxWidth>1 ){
  2169         -    zNewRecord[j++] = (addr>>8)&0xff;
  2170         -    if( idxWidth>2 ){
  2171         -      zNewRecord[j++] = (addr>>16)&0xff;
  2172         -    }
  2173         -  }
  2174         -  if( addUnique ){
  2175         -    memcpy(&zNewRecord[j], &p->uniqueCnt, sizeof(p->uniqueCnt));
  2176         -    p->uniqueCnt++;
  2177         -    j += sizeof(p->uniqueCnt);
  2178         -  }
  2179         -  for(i=0, pRec=&pTos[1-nField]; i<nField; i++, pRec++){
  2180         -    if( (pRec->flags & MEM_Null)==0 ){
  2181         -      memcpy(&zNewRecord[j], pRec->z, pRec->n);
  2182         -      j += pRec->n;
  2183         -    }
  2184         -  }
  2185         -  popStack(&pTos, nField);
  2186         -  pTos++;
  2187         -  pTos->n = nByte;
  2188         -  if( nByte<=NBFS ){
  2189         -    assert( zNewRecord==zTemp );
  2190         -    memcpy(pTos->zShort, zTemp, nByte);
  2191         -    pTos->z = pTos->zShort;
  2192         -    pTos->flags = MEM_Str | MEM_Short;
  2193         -  }else{
  2194         -    assert( zNewRecord!=zTemp );
  2195         -    pTos->z = zNewRecord;
  2196         -    pTos->flags = MEM_Str | MEM_Dyn;
  2197         -  }
  2198   2109     break;
  2199   2110   }
  2200   2111   
  2201   2112   /* Opcode: MakeKey P1 P2 P3
  2202   2113   **
  2203   2114   ** Convert the top P1 entries of the stack into a single entry suitable
  2204   2115   ** for use as the key in an index.  The top P1 records are
................................................................................
  3395   3306     }else if( pC->pseudoTable ){
  3396   3307       pTos->n = pC->nData;
  3397   3308       pTos->z = pC->pData;
  3398   3309       pTos->flags = MEM_Str|MEM_Ephem;
  3399   3310     }else{
  3400   3311       pTos->flags = MEM_Null;
  3401   3312     }
  3402         -  break;
  3403         -}
  3404         -
  3405         -/* Opcode: Column P1 P2 *
  3406         -**
  3407         -** Interpret the data that cursor P1 points to as
  3408         -** a structure built using the MakeRecord instruction.
  3409         -** (See the MakeRecord opcode for additional information about
  3410         -** the format of the data.)
  3411         -** Push onto the stack the value of the P2-th column contained
  3412         -** in the data.
  3413         -**
  3414         -** If the KeyAsData opcode has previously executed on this cursor,
  3415         -** then the field might be extracted from the key rather than the
  3416         -** data.
  3417         -**
  3418         -** If P1 is negative, then the record is stored on the stack rather
  3419         -** than in a table.  For P1==-1, the top of the stack is used.
  3420         -** For P1==-2, the next on the stack is used.  And so forth.  The
  3421         -** value pushed is always just a pointer into the record which is
  3422         -** stored further down on the stack.  The column value is not copied.
  3423         -*/
  3424         -case OP_Column: {
  3425         -  int amt, offset, end, payloadSize;
  3426         -  int i = pOp->p1;
  3427         -  int p2 = pOp->p2;
  3428         -  Cursor *pC;
  3429         -  char *zRec;
  3430         -  BtCursor *pCrsr;
  3431         -  int idxWidth;
  3432         -  unsigned char aHdr[10];
  3433         -
  3434         -  assert( i<p->nCursor );
  3435         -  pTos++;
  3436         -  if( i<0 ){
  3437         -    assert( &pTos[i]>=p->aStack );
  3438         -    assert( pTos[i].flags & MEM_Str );
  3439         -    zRec = pTos[i].z;
  3440         -    payloadSize = pTos[i].n;
  3441         -  }else if( (pC = &p->aCsr[i])->pCursor!=0 ){
  3442         -    sqlite3VdbeCursorMoveto(pC);
  3443         -    zRec = 0;
  3444         -    pCrsr = pC->pCursor;
  3445         -    if( pC->nullRow ){
  3446         -      payloadSize = 0;
  3447         -    }else if( pC->keyAsData ){
  3448         -      u64 pl64;
  3449         -      assert( !pC->intKey );
  3450         -      sqlite3BtreeKeySize(pCrsr, &pl64);
  3451         -      payloadSize = pl64;
  3452         -    }else{
  3453         -      sqlite3BtreeDataSize(pCrsr, &payloadSize);
  3454         -    }
  3455         -  }else if( pC->pseudoTable ){
  3456         -    payloadSize = pC->nData;
  3457         -    zRec = pC->pData;
  3458         -    assert( payloadSize==0 || zRec!=0 );
  3459         -  }else{
  3460         -    payloadSize = 0;
  3461         -  }
  3462         -
  3463         -  /* Figure out how many bytes in the column data and where the column
  3464         -  ** data begins.
  3465         -  */
  3466         -  if( payloadSize==0 ){
  3467         -    pTos->flags = MEM_Null;
  3468         -    break;
  3469         -  }else if( payloadSize<256 ){
  3470         -    idxWidth = 1;
  3471         -  }else if( payloadSize<65536 ){
  3472         -    idxWidth = 2;
  3473         -  }else{
  3474         -    idxWidth = 3;
  3475         -  }
  3476         -
  3477         -  /* Figure out where the requested column is stored and how big it is.
  3478         -  */
  3479         -  if( payloadSize < idxWidth*(p2+1) ){
  3480         -    rc = SQLITE_CORRUPT;
  3481         -    goto abort_due_to_error;
  3482         -  }
  3483         -  if( zRec ){
  3484         -    memcpy(aHdr, &zRec[idxWidth*p2], idxWidth*2);
  3485         -  }else if( pC->keyAsData ){
  3486         -    sqlite3BtreeKey(pCrsr, idxWidth*p2, idxWidth*2, (char*)aHdr);
  3487         -  }else{
  3488         -    sqlite3BtreeData(pCrsr, idxWidth*p2, idxWidth*2, (char*)aHdr);
  3489         -  }
  3490         -  offset = aHdr[0];
  3491         -  end = aHdr[idxWidth];
  3492         -  if( idxWidth>1 ){
  3493         -    offset |= aHdr[1]<<8;
  3494         -    end |= aHdr[idxWidth+1]<<8;
  3495         -    if( idxWidth>2 ){
  3496         -      offset |= aHdr[2]<<16;
  3497         -      end |= aHdr[idxWidth+2]<<16;
  3498         -    }
  3499         -  }
  3500         -  amt = end - offset;
  3501         -  if( amt<0 || offset<0 || end>payloadSize ){
  3502         -    rc = SQLITE_CORRUPT;
  3503         -    goto abort_due_to_error;
  3504         -  }
  3505         -
  3506         -  /* amt and offset now hold the offset to the start of data and the
  3507         -  ** amount of data.  Go get the data and put it on the stack.
  3508         -  */
  3509         -  pTos->n = amt;
  3510         -  if( amt==0 ){
  3511         -    pTos->flags = MEM_Null;
  3512         -  }else if( zRec ){
  3513         -    pTos->flags = MEM_Str | MEM_Ephem;
  3514         -    pTos->z = &zRec[offset];
  3515         -  }else{
  3516         -    if( amt<=NBFS ){
  3517         -      pTos->flags = MEM_Str | MEM_Short;
  3518         -      pTos->z = pTos->zShort;
  3519         -    }else{
  3520         -      char *z = sqliteMallocRaw( amt );
  3521         -      if( z==0 ) goto no_mem;
  3522         -      pTos->flags = MEM_Str | MEM_Dyn;
  3523         -      pTos->z = z;
  3524         -    }
  3525         -    if( pC->keyAsData ){
  3526         -      sqlite3BtreeKey(pCrsr, offset, amt, pTos->z);
  3527         -    }else{
  3528         -      sqlite3BtreeData(pCrsr, offset, amt, pTos->z);
  3529         -    }
  3530         -  }
  3531   3313     break;
  3532   3314   }
  3533   3315   
  3534   3316   /* Opcode: Recno P1 * *
  3535   3317   **
  3536   3318   ** Push onto the stack an integer which is the first 4 bytes of the
  3537   3319   ** the key to the current entry in a sequential scan of the database

Changes to src/vdbeInt.h.

   313    313   void sqlite3VdbeKeylistFree(Keylist*);
   314    314   void sqliteVdbePopStack(Vdbe*,int);
   315    315   int sqlite3VdbeCursorMoveto(Cursor*);
   316    316   int sqlite3VdbeByteSwap(int);
   317    317   #if !defined(NDEBUG) || defined(VDBE_PROFILE)
   318    318   void sqlite3VdbePrintOp(FILE*, int, Op*);
   319    319   #endif
   320         -int sqlite3VdbeSerialize(const Mem *, unsigned char *);
   321         -int sqlite3VdbeSerialLen(const Mem *);
   322         -int sqlite3VdbeDeserialize(Mem *, const unsigned char *);
          320  +int sqlite3VdbeSerialTypeLen(u64);
          321  +u64 sqlite3VdbeSerialType(const Mem *);
          322  +int sqlite3VdbeSerialPut(unsigned char *, const Mem *);
          323  +int sqlite3VdbeSerialGet(const unsigned char *, u64, Mem *);
   323    324   
   324    325   int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);

Changes to src/vdbeaux.c.

  1103   1103     *pResult = memcmp(pMallocedKey, pKey, nKey>nCellKey?nCellKey:nKey);
  1104   1104     sqliteFree(pMallocedKey);
  1105   1105   
  1106   1106     return rc;
  1107   1107   }
  1108   1108   
  1109   1109   /*
  1110         -** The following three functions:
         1110  +** The following functions:
  1111   1111   **
  1112         -** sqlite3VdbeSerialize()
         1112  +** sqlite3VdbeSerialType()
         1113  +** sqlite3VdbeSerialTypeLen()
         1114  +** sqlite3VdbeSerialRead()
  1113   1115   ** sqlite3VdbeSerialLen()
  1114         -** sqlite3VdbeDeserialize()
         1116  +** sqlite3VdbeSerialWrite()
  1115   1117   **
  1116   1118   ** encapsulate the code that serializes values for storage in SQLite
  1117         -** databases. Each serialized value consists of a variable length integer
  1118         -** followed by type specific storage.
         1119  +** data and index records. Each serialized value consists of a
         1120  +** 'serial-type' and a blob of data. The serial type is an 8-byte unsigned
         1121  +** integer, stored as a varint.
         1122  +**
         1123  +** In an SQLite index record, the serial type is stored directly before
         1124  +** the blob of data that it corresponds to. In a table record, all serial
         1125  +** types are stored at the start of the record, and the blobs of data at
         1126  +** the end. Hence these functions allow the caller to handle the
         1127  +** serial-type and data blob seperately.
         1128  +**
         1129  +** The following table describes the various storage classes for data:
  1119   1130   **
  1120         -**   initial varint     bytes to follow    type
         1131  +**   serial type        bytes of data      type
  1121   1132   **   --------------     ---------------    ---------------
  1122   1133   **      0                     0            NULL
  1123   1134   **      1                     1            signed integer
  1124   1135   **      2                     2            signed integer
  1125   1136   **      3                     4            signed integer
  1126   1137   **      4                     8            signed integer
  1127   1138   **      5                     8            IEEE float
................................................................................
  1128   1139   **     6..12                               reserved for expansion
  1129   1140   **    N>=12 and even       (N-12)/2        BLOB
  1130   1141   **    N>=13 and odd        (N-13)/2        text
  1131   1142   **
  1132   1143   */
  1133   1144   
  1134   1145   /*
  1135         -** Write the serialized form of the value held by pMem into zBuf. Return
  1136         -** the number of bytes written.
         1146  +** Return the serial-type for the value stored in pMem.
  1137   1147   */
  1138         -int sqlite3VdbeSerialize(
  1139         -  const Mem *pMem,      /* Pointer to vdbe value to serialize */
  1140         -  unsigned char *zBuf   /* Buffer to write to */
  1141         -){
  1142         -  if( pMem->flags&MEM_Null ){
  1143         -    return sqlite3PutVarint(zBuf, 0);
  1144         -  }
         1148  +u64 sqlite3VdbeSerialType(const Mem *pMem){
         1149  +  int flags = pMem->flags;
  1145   1150   
  1146         -  if( pMem->flags&MEM_Real ){
  1147         -    assert(!"TODO: float");
         1151  +  if( flags&MEM_Null ){
         1152  +    return 0;
         1153  +  }
         1154  +  if( flags&MEM_Int ){
         1155  +    /* Figure out whether to use 1, 2, 4 or 8 bytes. */
         1156  +    i64 i = pMem->i;
         1157  +    if( i>=-127 && i<=127 ) return 1;
         1158  +    if( i>=-32767 && i<=32767 ) return 2;
         1159  +    if( i>=-2147483647 && i<=2147483647 ) return 3;
         1160  +    return 4;
         1161  +  }
         1162  +  if( flags&MEM_Real ){
         1163  +    return 5;
         1164  +  }
         1165  +  if( flags&MEM_Str ){
         1166  +    return (pMem->n*2 + 13);
  1148   1167     }
  1149         -
  1150         -  if( pMem->flags&MEM_Str ){
  1151         -    int data_type_len;
  1152         -    u64 data_type = (pMem->n*2+31);
  1153         -
  1154         -    data_type_len = sqlite3PutVarint(zBuf, data_type); 
  1155         -    memcpy(&zBuf[data_type_len], pMem->z, pMem->n);
  1156         -    return pMem->n + data_type_len;
         1168  +  if( flags&MEM_Blob ){
         1169  +    return (pMem->n*2 + 12);
  1157   1170     }
  1158         -
  1159         -  if( pMem->flags& MEM_Int ){
  1160         -    u64 absval;
  1161         -    int size = 8;
  1162         -    int ii;
         1171  +  return 0;
         1172  +}
  1163   1173   
  1164         -    if( pMem->i<0 ){
  1165         -      absval = pMem->i * -1;
  1166         -    }else{
  1167         -      absval = pMem->i;
  1168         -    }
  1169         -    if( absval<=127 ){
  1170         -      size = 1;
  1171         -      sqlite3PutVarint(zBuf, 1);
  1172         -    }else if( absval<=32767 ){
  1173         -      size = 2;
  1174         -      sqlite3PutVarint(zBuf, 2);
  1175         -    }else if( absval<=2147483647 ){
  1176         -      size = 4;
  1177         -      sqlite3PutVarint(zBuf, 3);
  1178         -    }else{
  1179         -      size = 8;
  1180         -      sqlite3PutVarint(zBuf, 4);
  1181         -    }
  1182         -
  1183         -    for(ii=0; ii<size; ii++){
  1184         -      zBuf[ii+1] = (pMem->i >> (8*ii)) & 0xFF;
  1185         -    }
  1186         -    if( pMem->i<0 ){
  1187         -      zBuf[size] = zBuf[size] & 0x80;
  1188         -    }
  1189         -
  1190         -    return size+1;
         1174  +/*
         1175  +** Return the length of the data corresponding to the supplied serial-type.
         1176  +*/
         1177  +int sqlite3VdbeSerialTypeLen(u64 serial_type){
         1178  +  switch(serial_type){
         1179  +    case 0: return 0;                  /* NULL */
         1180  +    case 1: return 1;                  /* 1 byte integer */
         1181  +    case 2: return 2;                  /* 2 byte integer */
         1182  +    case 3: return 4;                  /* 4 byte integer */
         1183  +    case 4: return 8;                  /* 8 byte integer */
         1184  +    case 5: return 8;                  /* 8 byte float */
  1191   1185     }
  1192         -
  1193         -  return -1;
         1186  +  assert( serial_type>=12 );
         1187  +  return ((serial_type-12)>>1);        /* text or blob */
  1194   1188   }
  1195   1189   
  1196   1190   /*
  1197         -** Return the number of bytes that would be consumed by the serialized
  1198         -** form of the value held by pMem. Return negative if an error occurs.
  1199         -*/
  1200         -int sqlite3VdbeSerialLen(const Mem *pMem){
  1201         -  if( pMem->flags&MEM_Null ){
  1202         -    return 1; /* Varint 0 is 1 byte */
  1203         -  }
  1204         -  if( pMem->flags&MEM_Real ){
  1205         -    return 9; /* Varing 5 (1 byte) + 8 bytes IEEE float */    
  1206         -  }
  1207         -  if( pMem->flags&MEM_Str ){
  1208         -    return pMem->n + sqlite3VarintLen((pMem->n*2)+13);
         1191  +** Write the serialized data blob for the value stored in pMem into 
         1192  +** buf. It is assumed that the caller has allocated sufficient space.
         1193  +** Return the number of bytes written.
         1194  +*/ 
         1195  +int sqlite3VdbeSerialPut(unsigned char *buf, const Mem *pMem){
         1196  +  u64 serial_type = sqlite3VdbeSerialType(pMem);
         1197  +  int len;
         1198  + 
         1199  +  /* NULL */
         1200  +  if( serial_type==0 ){
         1201  +    return 0;
  1209   1202     }
  1210         -  if( pMem->flags& MEM_Int ){
  1211         -    u64 absval;
  1212         -    if( pMem->i<0 ){
  1213         -      absval = pMem->i * -1;
  1214         -    }else{
  1215         -      absval = pMem->i;
         1203  + 
         1204  +  /* Integer */
         1205  +  if( serial_type<5 ){
         1206  +    i64 i = pMem->i;
         1207  +    len = sqlite3VdbeSerialTypeLen(serial_type);
         1208  +    while( len-- ){
         1209  +      buf[len] = (i&0xFF);
         1210  +      i = i >> 8;
  1216   1211       }
  1217         -    if( absval<=127 ) return 2;        /* 1 byte integer */
  1218         -    if( absval<=32767 ) return 3;      /* 2 byte integer */
  1219         -    if( absval<=2147483647 ) return 5; /* 4 byte integer */
  1220         -    return 9;                         /* 8 byte integer */
         1212  +    return sqlite3VdbeSerialTypeLen(serial_type);
  1221   1213     }
  1222   1214   
  1223         -  return -1;
         1215  +  /* Float */
         1216  +  if( serial_type==5 ){
         1217  +    /* TODO: byte ordering? */
         1218  +    assert( sizeof(double)==8 );
         1219  +    memcpy(buf, &pMem->r, 8);
         1220  +    return 8;
         1221  +  }
         1222  +  
         1223  +  /* String or blob */
         1224  +  assert( serial_type>=12 );
         1225  +  len = sqlite3VdbeSerialTypeLen(serial_type);
         1226  +  memcpy(buf, pMem->z, len);
         1227  +  return len;
  1224   1228   }
  1225   1229   
  1226   1230   /*
  1227         -** Deserialize a value from zBuf and store it in *pMem. Return the number
  1228         -** of bytes written, or negative if an error occurs.
  1229         -*/
  1230         -int sqlite3VdbeDeserialize(
  1231         -  Mem *pMem,                   /* structure to write new value to */
  1232         -  const unsigned char *zBuf    /* Buffer to read from */
  1233         -){
  1234         -  u64 data_type;
  1235         -  int ret;
         1231  +** Deserialize the data blob pointed to by buf as serial type serial_type
         1232  +** and store the result in pMem.  Return the number of bytes read.
         1233  +*/ 
         1234  +int sqlite3VdbeSerialGet(const unsigned char *buf, u64 serial_type, Mem *pMem){
  1236   1235     int len;
  1237   1236   
  1238         -  memset(pMem, 0, sizeof(Mem));
  1239         -  ret = sqlite3GetVarint(zBuf, &data_type);
         1237  +  /* memset(pMem, 0, sizeof(pMem)); */
         1238  +  pMem->flags = 0;
         1239  +  pMem->z = 0;
  1240   1240   
  1241         -  if( data_type==0 ){  /* NULL */
         1241  +  /* NULL */
         1242  +  if( serial_type==0 ){
  1242   1243       pMem->flags = MEM_Null;
  1243         -    return ret;
         1244  +    return 0;
  1244   1245     }
  1245         -
  1246         -  /* FIX ME: update for 8-byte integers */
  1247         -  if( data_type>0 && data_type<5 ){  /* 1, 2, 4 or 8 byte integer */
  1248         -    int ii;
  1249         -    int bytes = 1 << (data_type-1);
  1250         -
  1251         -    pMem->flags = MEM_Int;
  1252         -    pMem->i = 0;
         1246  + 
         1247  +  /* Integer */
         1248  +  if( serial_type<5 ){
         1249  +    i64 i = 0;
         1250  +    int n;
         1251  +    len = sqlite3VdbeSerialTypeLen(serial_type);
  1253   1252   
  1254         -    for(ii=0; ii<bytes; ii++){
  1255         -      pMem->i = (pMem->i<<8) + zBuf[ii+ret];
         1253  +    if( buf[0]&0x80 ){
         1254  +      for(n=0; n<(8-len); n++){
         1255  +        i = (i<<8)+0xFF;
         1256  +      }
  1256   1257       }
  1257         -
  1258         -    /* If this is a 1, 2 or 4 byte integer, extend the sign-bit if need be. */
  1259         -    if( bytes<8 && pMem->i & (1<<(bytes*8-1)) ){
  1260         -      pMem->i = pMem->i - (1<<(bytes*8));
         1258  +    for(n=0; n<len; n++){
         1259  +      i = i << 8;
         1260  +      i = i + buf[n];
  1261   1261       }
  1262         -
  1263         -    return ret+bytes;
         1262  +    pMem->flags = MEM_Int;
         1263  +    pMem->i = i;
         1264  +    return sqlite3VdbeSerialTypeLen(serial_type);
  1264   1265     }
  1265   1266   
  1266         -  if( data_type==5 ){ /* IEEE float */
  1267         -    assert(!"TODO: float");
         1267  +  /* Float */
         1268  +  if( serial_type==5 ){
         1269  +    /* TODO: byte ordering? */
         1270  +    assert( sizeof(double)==8 );
         1271  +    memcpy(&pMem->r, buf, 8);
         1272  +    pMem->flags = MEM_Real;
         1273  +    return 8;
         1274  +  }
         1275  +  
         1276  +  /* String or blob */
         1277  +  assert( serial_type>=12 );
         1278  +  if( serial_type&0x01 ){
         1279  +    pMem->flags = MEM_Str;
         1280  +  }else{
         1281  +    pMem->flags = MEM_Blob;
  1268   1282     }
  1269         -
  1270         -  /* Must be text or a blob */
  1271         -  assert( data_type>=12 );
  1272         -  len = (data_type-12)/2;
  1273         -  pMem->flags = MEM_Str;  /* FIX ME: there should be a MEM_Blob or similar */
  1274         -
  1275         -  /* If the length of the text or blob is greater than NBFS, use space
  1276         -  ** dynamically allocated. Otherwise, store the value in Mem::zShort.
  1277         -  */
         1283  +  len = sqlite3VdbeSerialTypeLen(serial_type);
         1284  +  pMem->n = len;
  1278   1285     if( len>NBFS ){
  1279   1286       pMem->z = sqliteMalloc( len );
  1280   1287       if( !pMem->z ){
  1281   1288         return -1;
  1282   1289       }
  1283   1290       pMem->flags |= MEM_Dyn;
  1284   1291     }else{
  1285   1292       pMem->z = pMem->zShort;
  1286   1293       pMem->flags |= MEM_Short;
  1287   1294     }
  1288         -  memcpy(pMem->z, &zBuf[ret], len); 
  1289         -  ret += len;
         1295  +  memcpy(pMem->z, buf, len); 
  1290   1296   
  1291         -  return ret;
         1297  +  return len;
  1292   1298   }
  1293   1299   
  1294   1300   /*
  1295   1301   ** The following is the comparison function for (non-integer)
  1296   1302   ** keys in the btrees.  This function returns negative, zero, or
  1297   1303   ** positive if the first key is less than, equal to, or greater than
  1298   1304   ** the second.

Changes to test/quick.test.

     6      6   #    May you do good and not evil.
     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 runs all tests.
    12     12   #
    13         -# $Id: quick.test,v 1.6 2004/02/11 02:18:07 drh Exp $
           13  +# $Id: quick.test,v 1.7 2004/05/12 07:33:34 danielk1977 Exp $
    14     14   
    15     15   set testdir [file dirname $argv0]
    16     16   source $testdir/tester.tcl
    17     17   rename finish_test really_finish_test
    18     18   proc finish_test {} {}
    19     19   set ISQUICK 1
    20     20   
................................................................................
    22     22     all.test
    23     23     quick.test
    24     24     btree2.test
    25     25     malloc.test
    26     26     memleak.test
    27     27     misuse.test
    28     28   }
           29  +
           30  +lappend EXCLUDE \
           31  +  auth.test \
           32  +  bind.test \
           33  +  capi2.test \
           34  +  conflict.test \
           35  +  copy.test \
           36  +  format3.test \
           37  +  func.test \
           38  +  index.test \
           39  +  interrupt.test \
           40  +  intpkey.test \
           41  +  ioerr.test \
           42  +  memdb.test \
           43  +  minmax.test \
           44  +  misc1.test \
           45  +  misc2.test \
           46  +  misc3.test \
           47  +  null.test \
           48  +  pragma.test \
           49  +  printf.test \
           50  +  rowid.test \
           51  +  table.test \
           52  +  tableapi.test \
           53  +  trans.test \
           54  +  trigger1.test \
           55  +  trigger2.test \
           56  +  unique.test \
           57  +  update.test \
           58  +  utf.test \
           59  +  vacuum.test \
           60  +  version.test \
           61  +
    29     62   
    30     63   if {[sqlite -has-codec]} {
    31     64     lappend EXCLUDE \
    32     65       attach.test \
    33     66       attach2.test \
    34     67       auth.test \
    35     68       format3.test \
................................................................................
    43     76     catch {db close}
    44     77     if {$sqlite_open_file_count>0} {
    45     78       puts "$tail did not close all files: $sqlite_open_file_count"
    46     79       incr nErr
    47     80       lappend ::failList $tail
    48     81     }
    49     82   }
    50         -source $testdir/misuse.test
           83  +# source $testdir/misuse.test
    51     84   
    52     85   set sqlite_open_file_count 0
    53     86   really_finish_test