/ Check-in [8e2f3f75]
Login

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

Overview
Comment:Separate columns in keys using nulls instead of tabs. (CVS 249)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:8e2f3f751ea342372c94977ff27baaff5126009a
User & Date: drh 2001-09-15 14:43:39
Context
2001-09-16
00:13
Disclaimed copyright. Preparing for release 2.0. (CVS 250) check-in: 4e926efe user: drh tags: trunk
2001-09-15
14:43
Separate columns in keys using nulls instead of tabs. (CVS 249) check-in: 8e2f3f75 user: drh tags: trunk
13:15
Limit the total data in a single row to 2^16-1 bytes. (CVS 248) check-in: 8fdec4d8 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/sqliteInt.h.

    19     19   ** Author contact information:
    20     20   **   drh@hwaci.com
    21     21   **   http://www.hwaci.com/drh/
    22     22   **
    23     23   *************************************************************************
    24     24   ** Internal interface definitions for SQLite.
    25     25   **
    26         -** @(#) $Id: sqliteInt.h,v 1.49 2001/09/15 13:15:13 drh Exp $
           26  +** @(#) $Id: sqliteInt.h,v 1.50 2001/09/15 14:43:39 drh Exp $
    27     27   */
    28     28   #include "sqlite.h"
    29     29   #include "vdbe.h"
    30     30   #include "parse.h"
    31     31   #include "btree.h"
    32     32   #include <stdio.h>
    33     33   #include <stdlib.h>
................................................................................
    45     45   ** Integers of known sizes.  These typedefs much change for architectures
    46     46   ** where the sizes very.
    47     47   */
    48     48   typedef unsigned int u32;             /* 4-byte unsigned integer */
    49     49   typedef unsigned short int u16;       /* 2-byte unsigned integer */
    50     50   typedef unsigned char u8;             /* 1-byte unsigned integer */
    51     51   
           52  +/*
           53  +** The maximum number of bytes of data that can be put into a single
           54  +** row of a single table.
           55  +*/
           56  +#define MAX_BYTES_PER_ROW  65535
           57  +
    52     58   /*
    53     59   ** If memory allocation problems are found, recompile with
    54     60   **
    55     61   **      -DMEMORY_DEBUG=1
    56     62   **
    57     63   ** to enable some sanity checking on malloc() and free().  To
    58     64   ** check for memory leaks, recompile with

Changes to src/vdbe.c.

    37     37   ** inplicit conversion from one type to the other occurs as necessary.
    38     38   ** 
    39     39   ** Most of the code in this file is taken up by the sqliteVdbeExec()
    40     40   ** function which does the work of interpreting a VDBE program.
    41     41   ** But other routines are also provided to help in building up
    42     42   ** a program instruction by instruction.
    43     43   **
    44         -** $Id: vdbe.c,v 1.68 2001/09/15 13:15:13 drh Exp $
           44  +** $Id: vdbe.c,v 1.69 2001/09/15 14:43:39 drh Exp $
    45     45   */
    46     46   #include "sqliteInt.h"
    47     47   #include <ctype.h>
    48     48   #include <unistd.h>
    49     49   
    50     50   /*
    51     51   ** SQL is translated into a sequence of instructions to be
................................................................................
  1799   1799     for(i=p->tos-nField+1; i<=p->tos; i++){
  1800   1800       if( (aStack[i].flags & STK_Null)==0 ){
  1801   1801         if( Stringify(p, i) ) goto no_mem;
  1802   1802         nByte += aStack[i].n;
  1803   1803       }
  1804   1804     }
  1805   1805     nByte += sizeof(addr)*nField;
  1806         -  if( nByte>65535 ){
         1806  +  if( nByte>MAX_BYTES_PER_ROW ){
  1807   1807       rc = SQLITE_TOOBIG;
  1808   1808       goto abort_due_to_error;
  1809   1809     }
  1810   1810     zNewRecord = sqliteMalloc( nByte );
  1811   1811     if( zNewRecord==0 ) goto no_mem;
  1812   1812     j = 0;
  1813   1813     addr = sizeof(addr)*nField;
................................................................................
  1833   1833     break;
  1834   1834   }
  1835   1835   
  1836   1836   /* Opcode: MakeKey P1 P2 *
  1837   1837   **
  1838   1838   ** Convert the top P1 entries of the stack into a single entry suitable
  1839   1839   ** for use as the key in an index or a sort.  The top P1 records are
  1840         -** concatenated with a tab character (ASCII 0x09) used as a record
  1841         -** separator.  The entire concatenation is null-terminated.  The
  1842         -** lowest entry in the stack is the first field and the top of the
         1840  +** converted to strings and merged.  The null-terminator on each string
         1841  +** is retained and used as a separator.  The entire string is also
         1842  +** null-terminated.
         1843  +** The lowest entry in the stack is the first field and the top of the
  1843   1844   ** stack becomes the last.
  1844   1845   **
  1845   1846   ** If P2 is not zero, then the original entries remain on the stack
  1846   1847   ** and the new key is pushed on top.  If P2 is zero, the original
  1847   1848   ** data is popped off the stack first then the new key is pushed
  1848   1849   ** back in its place.
  1849   1850   **
................................................................................
  1861   1862     for(i=p->tos-nField+1; i<=p->tos; i++){
  1862   1863       if( aStack[i].flags & STK_Null ){
  1863   1864         nByte++;
  1864   1865       }else{
  1865   1866         if( Stringify(p, i) ) goto no_mem;
  1866   1867         nByte += aStack[i].n;
  1867   1868       }
         1869  +  }
         1870  +  if( nByte+sizeof(u32)>MAX_BYTES_PER_ROW ){
         1871  +    rc = SQLITE_TOOBIG;
         1872  +    goto abort_due_to_error;
  1868   1873     }
  1869   1874     zNewKey = sqliteMalloc( nByte );
  1870   1875     if( zNewKey==0 ) goto no_mem;
  1871   1876     j = 0;
  1872   1877     for(i=p->tos-nField+1; i<=p->tos; i++){
  1873         -    if( (aStack[i].flags & STK_Null)==0 ){
  1874         -      memcpy(&zNewKey[j], zStack[i], aStack[i].n-1);
  1875         -      j += aStack[i].n-1;
         1878  +    if( aStack[i].flags & STK_Null ){
         1879  +      zNewKey[j++] = 0;
         1880  +    }else{
         1881  +      memcpy(&zNewKey[j], zStack[i], aStack[i].n);
         1882  +      j += aStack[i].n;
  1876   1883       }
  1877         -    if( i<p->tos ) zNewKey[j++] = '\t';
  1878   1884     }
  1879         -  zNewKey[j] = 0;
  1880   1885     if( pOp->p2==0 ) PopStack(p, nField);
  1881   1886     VERIFY( NeedStack(p, p->tos+1); )
  1882   1887     p->tos++;
  1883   1888     aStack[p->tos].n = nByte;
  1884   1889     aStack[p->tos].flags = STK_Str|STK_Dyn;
  1885   1890     zStack[p->tos] = zNewKey;
  1886   1891     break;
................................................................................
  1893   1898   ** off of the stack, treat that integer as a four-byte record number, and
  1894   1899   ** append the four bytes to the key.  Thus a total of P1+1 entries are
  1895   1900   ** popped from the stack for this instruction and a single entry is pushed
  1896   1901   ** back.  The first P1 entries that are popped are strings and the last
  1897   1902   ** entry (the lowest on the stack) is an integer record number.
  1898   1903   **
  1899   1904   ** The converstion of the first P1 string entries occurs just like in
  1900         -** MakeKey.  Each entry is separated from the others by a tab (ASCII 0x09).
         1905  +** MakeKey.  Each entry is separated from the others by a null.
  1901   1906   ** The entire concatenation is null-terminated.  The lowest entry
  1902   1907   ** in the stack is the first field and the top of the stack becomes the
  1903   1908   ** last.
  1904   1909   **
  1905   1910   ** See also:  MakeKey, SortMakeKey
  1906   1911   */
  1907   1912   case OP_MakeIdxKey: {
................................................................................
  1916   1921     for(i=p->tos-nField+1; i<=p->tos; i++){
  1917   1922       if( aStack[i].flags & STK_Null ){
  1918   1923         nByte++;
  1919   1924       }else{
  1920   1925         if( Stringify(p, i) ) goto no_mem;
  1921   1926         nByte += aStack[i].n;
  1922   1927       }
         1928  +  }
         1929  +  if( nByte>MAX_BYTES_PER_ROW ){
         1930  +    rc = SQLITE_TOOBIG;
         1931  +    goto abort_due_to_error;
  1923   1932     }
  1924   1933     zNewKey = sqliteMalloc( nByte );
  1925   1934     if( zNewKey==0 ) goto no_mem;
  1926   1935     j = 0;
  1927   1936     for(i=p->tos-nField+1; i<=p->tos; i++){
  1928         -    if( (aStack[i].flags & STK_Null)==0 ){
  1929         -      memcpy(&zNewKey[j], zStack[i], aStack[i].n-1);
  1930         -      j += aStack[i].n-1;
         1937  +    if( aStack[i].flags & STK_Null ){
         1938  +      zNewKey[j++] = 0;
         1939  +    }else{
         1940  +      memcpy(&zNewKey[j], zStack[i], aStack[i].n);
         1941  +      j += aStack[i].n;
  1931   1942       }
  1932         -    if( i<p->tos ) zNewKey[j++] = '\t';
  1933   1943     }
  1934         -  zNewKey[j++] = 0;
  1935   1944     Integerify(p, p->tos-nField);
  1936   1945     memcpy(&zNewKey[j], &aStack[p->tos-nField].i, sizeof(u32));
  1937   1946     PopStack(p, nField+1);
  1938   1947     VERIFY( NeedStack(p, p->tos+1); )
  1939   1948     p->tos++;
  1940   1949     aStack[p->tos].n = nByte;
  1941   1950     aStack[p->tos].flags = STK_Str|STK_Dyn;
................................................................................
  2577   2586   ** record numbers onto the stack until all records with the same key
  2578   2587   ** have been returned.
  2579   2588   **
  2580   2589   ** Note that the key for this opcode should be built using MakeKey
  2581   2590   ** but the key used for PutIdx and DeleteIdx should be built using
  2582   2591   ** MakeIdxKey.  The difference is that MakeIdxKey adds a 4-bytes
  2583   2592   ** record number to the end of the key in order to specify a particular
  2584         -** entry in the index.  MakeKey specifies zero or more entries in the
  2585         -** index that all have common values.
         2593  +** entry in the index.  MakeKey omits the 4-byte record number.
         2594  +** The search that this BeginIdx instruction initiates will span all
         2595  +** entries in the index where the MakeKey generated key matches all
         2596  +** but the last four bytes of the MakeIdxKey generated key.
  2586   2597   */
  2587   2598   case OP_BeginIdx: {
  2588   2599     int i = pOp->p1;
  2589   2600     int tos = p->tos;
  2590   2601     int res, rx;
  2591   2602     Cursor *pCrsr;
  2592   2603     VERIFY( if( tos<0 ) goto not_enough_stack; )
  2593   2604     if( i>=0 && i<p->nCursor && (pCrsr = &p->aCsr[i])->pCursor!=0 ){
  2594   2605       if( Stringify(p, tos) ) goto no_mem;
  2595   2606       if( pCrsr->zKey ) sqliteFree(pCrsr->zKey);
  2596   2607       pCrsr->nKey = aStack[tos].n;
  2597         -    pCrsr->zKey = sqliteMalloc( 2*(pCrsr->nKey + 1) );
         2608  +    pCrsr->zKey = sqliteMalloc( 2*pCrsr->nKey );
  2598   2609       if( pCrsr->zKey==0 ) goto no_mem;
  2599         -    pCrsr->zBuf = &pCrsr->zKey[pCrsr->nKey+1];
  2600         -    strncpy(pCrsr->zKey, zStack[tos], aStack[tos].n);
         2610  +    pCrsr->zBuf = &pCrsr->zKey[pCrsr->nKey];
         2611  +    memcpy(pCrsr->zKey, zStack[tos], aStack[tos].n);
  2601   2612       pCrsr->zKey[aStack[tos].n] = 0;
  2602   2613       rx = sqliteBtreeMoveto(pCrsr->pCursor, zStack[tos], aStack[tos].n, &res);
  2603   2614       pCrsr->atFirst = rx==SQLITE_OK && res>0;
  2604   2615       pCrsr->recnoIsValid = 0;
  2605   2616     }
  2606   2617     POPSTACK;
  2607   2618     break;
  2608   2619   }
  2609   2620   
  2610   2621   /* Opcode: NextIdx P1 P2 *
  2611   2622   **
  2612   2623   ** The P1 cursor points to an SQL index for which a BeginIdx operation
  2613         -** has been issued.  This operation retrieves the next record number and
  2614         -** pushes that record number onto the stack.  Or, if there are no more
  2615         -** record numbers for the given key, this opcode pushes nothing onto the
  2616         -** stack but instead jumps to instruction P2.
         2624  +** has been issued.  This operation retrieves the next record from that
         2625  +** cursor and verifies that the key on the record matches the key that
         2626  +** was pulled from the stack by the BeginIdx instruction.  If they do
         2627  +** match, then the last 4 bytes of the key on the record hold a record
         2628  +** number and that record number is extracted and pushed on the stack.
         2629  +** If the keys do not match, there is an immediate jump to instruction P2.
  2617   2630   */
  2618   2631   case OP_NextIdx: {
  2619   2632     int i = pOp->p1;
  2620   2633     int tos = ++p->tos;
  2621   2634     Cursor *pCrsr;
  2622   2635     BtCursor *pCur;
  2623   2636     int rx, res, size;
................................................................................
  2632   2645       }else{
  2633   2646         rx = sqliteBtreeNext(pCur, &res);
  2634   2647         if( rx!=SQLITE_OK ) goto abort_due_to_error;
  2635   2648       }
  2636   2649       sqliteBtreeKeySize(pCur, &size);
  2637   2650       if( res>0 || size!=pCrsr->nKey+sizeof(u32) ||
  2638   2651         sqliteBtreeKey(pCur, 0, pCrsr->nKey, pCrsr->zBuf)!=pCrsr->nKey ||
  2639         -      strncmp(pCrsr->zKey, pCrsr->zBuf, pCrsr->nKey)!=0
         2652  +      memcmp(pCrsr->zKey, pCrsr->zBuf, pCrsr->nKey)!=0
  2640   2653       ){
  2641   2654         pc = pOp->p2 - 1;
  2642   2655         POPSTACK;
  2643   2656       }else{
  2644   2657         int recno;
  2645   2658         sqliteBtreeKey(pCur, pCrsr->nKey, sizeof(u32), (char*)&recno);
  2646   2659         p->aCsr[i].lastRecno = aStack[tos].i = recno;
................................................................................
  3782   3795           }else if( aStack[i].flags & STK_Real ){
  3783   3796             fprintf(p->trace, " r:%g", aStack[i].r);
  3784   3797           }else if( aStack[i].flags & STK_Str ){
  3785   3798             int j, k;
  3786   3799             char zBuf[100];
  3787   3800             zBuf[0] = ' ';
  3788   3801             zBuf[1] = (aStack[i].flags & STK_Dyn)!=0 ? 'z' : 's';
  3789         -          zBuf[2] = ':';
         3802  +          zBuf[2] = '[';
  3790   3803             k = 3;
  3791         -          for(j=0; j<15 && j<aStack[i].n; j++){
         3804  +          for(j=0; j<20 && j<aStack[i].n; j++){
  3792   3805               int c = zStack[i][j];
  3793   3806               if( c==0 && j==aStack[i].n-1 ) break;
  3794   3807               if( isprint(c) && !isspace(c) ){
  3795   3808                 zBuf[k++] = c;
  3796   3809               }else{
  3797   3810                 zBuf[k++] = '.';
  3798   3811               }
  3799   3812             }
         3813  +          zBuf[k++] = ']';
  3800   3814             zBuf[k++] = 0;
  3801   3815             fprintf(p->trace, "%s", zBuf);
  3802   3816           }else{
  3803   3817             fprintf(p->trace, " ???");
  3804   3818           }
  3805   3819         }
  3806   3820         fprintf(p->trace,"\n");