/ Check-in [7dd58fad]
Login

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

Overview
Comment:Increase maximum row size to 1MB. (CVS 300)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:7dd58fad398253608f55867cf1c7749eef005657
User & Date: drh 2001-11-04 18:32:47
Context
2001-11-06
04:00
Implement indices that occur in sort order and the LIMIT...OFFSET clause of SELECT statements. (CVS 301) check-in: eb07768a user: drh tags: trunk
2001-11-04
18:32
Increase maximum row size to 1MB. (CVS 300) check-in: 7dd58fad user: drh tags: trunk
00:00
Version 2.0.8 (CVS 462) check-in: 0fd28742 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/btree.c.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
..
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
...
171
172
173
174
175
176
177


178
179


180
181
182
183
184
185
186
...
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
...
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
....
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
....
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
....
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
....
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
....
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
....
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
....
1527
1528
1529
1530
1531
1532
1533
1534

1535

1536
1537
1538
1539
1540
1541
1542
....
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
....
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.36 2001/11/01 13:52:53 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
**     "Sorting And Searching", pages 473-480. Addison-Wesley
**     Publishing Company, Reading, Massachusetts.
................................................................................
#define ROUNDUP(X)  ((X+3) & ~3)

/*
** This is a magic string that appears at the beginning of every
** SQLite database in order to identify the file as a real database.
*/
static const char zMagicHeader[] = 
   "** This file contains an SQLite 2.0 database **";
#define MAGIC_SIZE (sizeof(zMagicHeader))

/*
** This is a magic integer also used to test the integrity of the database
** file.  This integer is used in addition to the string above so that
** if the file is written on a little-endian architecture and read
** on a big-endian architectures (or vice versa) we can detect the
................................................................................
** header for the cell must be defined first in order to do some
** of the sizing #defines that follow.
*/
struct CellHdr {
  Pgno leftChild; /* Child page that comes before this cell */
  u16 nKey;       /* Number of bytes in the key */
  u16 iNext;      /* Index in MemPage.u.aDisk[] of next cell in sorted order */


  u32 nData;      /* Number of bytes of data */
};



/*
** The minimum size of a complete Cell.  The Cell must contain a header
** and at least 4 bytes of payload.
*/
#define MIN_CELL_SIZE  (sizeof(CellHdr)+4)

................................................................................
** Compute the total number of bytes that a Cell needs on the main
** database page.  The number returned includes the Cell header,
** local payload storage, and the pointer to overflow pages (if
** applicable).  Additional space allocated on overflow pages
** is NOT included in the value returned from this routine.
*/
static int cellSize(Cell *pCell){
  int n = pCell->h.nKey + pCell->h.nData;
  if( n>MX_LOCAL_PAYLOAD ){
    n = MX_LOCAL_PAYLOAD + sizeof(Pgno);
  }else{
    n = ROUNDUP(n);
  }
  n += sizeof(CellHdr);
  return n;
................................................................................
  MemPage *pPage;

  pPage = pCur->pPage;
  if( pPage==0 || pCur->idx >= pPage->nCell ){
    *pSize = 0;
  }else{
    pCell = pPage->apCell[pCur->idx];
    *pSize = pCell->h.nKey;
  }
  return SQLITE_OK;
}

/*
** Read payload information from the entry that the pCur cursor is
** pointing to.  Begin reading the payload at "offset" and read
................................................................................
  if( amt==0 ) return 0;
  pPage = pCur->pPage;
  if( pPage==0 ) return 0;
  if( pCur->idx >= pPage->nCell ){
    return 0;
  }
  pCell = pPage->apCell[pCur->idx];
  if( amt+offset > pCell->h.nKey ){
    amt = pCell->h.nKey - offset;
    if( amt<=0 ){
      return 0;
    }
  }
  getPayload(pCur, offset, amt, zBuf);
  return amt;
}
................................................................................
  MemPage *pPage;

  pPage = pCur->pPage;
  if( pPage==0 || pCur->idx >= pPage->nCell ){
    *pSize = 0;
  }else{
    pCell = pPage->apCell[pCur->idx];
    *pSize = pCell->h.nData;
  }
  return SQLITE_OK;
}

/*
** Read part of the data associated with cursor pCur.  A maximum
** of "amt" bytes will be transfered into zBuf[].  The transfer
................................................................................
  if( offset<0 ) return 0;
  if( amt==0 ) return 0;
  pPage = pCur->pPage;
  if( pPage==0 || pCur->idx >= pPage->nCell ){
    return 0;
  }
  pCell = pPage->apCell[pCur->idx];
  if( amt+offset > pCell->h.nData ){
    amt = pCell->h.nData - offset;
    if( amt<=0 ){
      return 0;
    }
  }
  getPayload(pCur, offset + pCell->h.nKey, amt, zBuf);
  return amt;
}

/*
** Compare the first nKey bytes of the key of the entry that pCur
** points to against the first nKey bytes of pKey.  Set *pRes to
** show the comparison results:
................................................................................
  int n, c, rc;
  Cell *pCell;
  const char *zKey  = (const char*)pKey;

  assert( pCur->pPage );
  assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
  pCell = pCur->pPage->apCell[pCur->idx];
  if( nKey > pCell->h.nKey ){
    nKey = pCell->h.nKey;
  }
  n = nKey;
  if( n>MX_LOCAL_PAYLOAD ){
    n = MX_LOCAL_PAYLOAD;
  }
  c = memcmp(pCell->aPayload, zKey, n);
  if( c!=0 ){
................................................................................
  rc = sqliteBtreeKeyCompare(pCur, pKey, nKeyOrig, &c);
  if( rc!=SQLITE_OK ) return rc;
  if( c==0 ){
    Cell *pCell;
    assert( pCur->pPage );
    assert( pCur->pPage->nCell>pCur->idx && pCur->idx>=0 );
    pCell = pCur->pPage->apCell[pCur->idx];
    c = pCell->h.nKey - nKeyOrig;
  }
  *pResult = c;
  return SQLITE_OK;
}

/*
** Move the cursor down to a new child page.
................................................................................
*/
static int clearCell(Btree *pBt, Cell *pCell){
  Pager *pPager = pBt->pPager;
  OverflowPage *pOvfl;
  Pgno ovfl, nextOvfl;
  int rc;

  if( pCell->h.nKey + pCell->h.nData <= MX_LOCAL_PAYLOAD ){
    return SQLITE_OK;
  }
  ovfl = pCell->ovfl;
  pCell->ovfl = 0;
  while( ovfl ){
    rc = sqlitepager_get(pPager, ovfl, (void**)&pOvfl);
    if( rc ) return rc;
................................................................................
  int spaceLeft;
  int n, rc;
  int nPayload;
  const char *pPayload;
  char *pSpace;

  pCell->h.leftChild = 0;
  pCell->h.nKey = nKey;

  pCell->h.nData = nData;

  pCell->h.iNext = 0;

  pNext = &pCell->ovfl;
  pSpace = pCell->aPayload;
  spaceLeft = MX_LOCAL_PAYLOAD;
  pPayload = pKey;
  pKey = 0;
................................................................................
  if( recursive ) printf("PAGE %d:\n", pgno);
  i = 0;
  idx = pPage->u.hdr.firstCell;
  while( idx>0 && idx<=SQLITE_PAGE_SIZE-MIN_CELL_SIZE ){
    Cell *pCell = (Cell*)&pPage->u.aDisk[idx];
    int sz = cellSize(pCell);
    sprintf(range,"%d..%d", idx, idx+sz-1);
    sz = pCell->h.nKey + pCell->h.nData;
    if( sz>sizeof(payload)-1 ) sz = sizeof(payload)-1;
    memcpy(payload, pCell->aPayload, sz);
    for(j=0; j<sz; j++){
      if( payload[j]<0x20 || payload[j]>0x7f ) payload[j] = '.';
    }
    payload[sz] = 0;
    printf(
      "cell %2d: i=%-10s chld=%-4d nk=%-4d nd=%-4d payload=%s\n",
      i, range, (int)pCell->h.leftChild, pCell->h.nKey, pCell->h.nData,
      payload
    );
    if( pPage->isInit && pPage->apCell[i]!=pCell ){
      printf("**** apCell[%d] does not match on prior entry ****\n", i);
    }
    i++;
    idx = pCell->h.iNext;
................................................................................
  cur.pBt = pCheck->pBt;
  for(i=0; i<pPage->nCell; i++){
    Cell *pCell = pPage->apCell[i];
    int sz;

    /* Check payload overflow pages
    */
    sz = pCell->h.nKey + pCell->h.nData;
    sprintf(zContext, "On page %d cell %d: ", iPage, i);
    if( sz>MX_LOCAL_PAYLOAD ){
      int nPage = (sz - MX_LOCAL_PAYLOAD + OVERFLOW_SIZE - 1)/OVERFLOW_SIZE;
      checkList(pCheck, pCell->ovfl, nPage, zContext);
    }

    /* Check that keys are in the right order
    */
    cur.idx = i;
    zKey2 = sqliteMalloc( pCell->h.nKey+1 );
    getPayload(&cur, 0, pCell->h.nKey, zKey2);
    if( zKey1 && strcmp(zKey1,zKey2)>=0 ){
      checkAppendMsg(pCheck, zContext, "Key is out of order");
    }

    /* Check sanity of left child page.
    */
    pgno = (int)pCell->h.leftChild;







|







 







|







 







>
>
|

>
>







 







|







 







|







 







|
|







 







|







 







|
|




|







 







|
|







 







|







 







|







 







|
>
|
>







 







|








|







 







|









|
|







5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
..
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
...
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
...
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
...
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
....
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
....
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
....
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
....
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
....
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
....
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
....
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
....
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
....
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** $Id: btree.c,v 1.37 2001/11/04 18:32:47 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
**     "Sorting And Searching", pages 473-480. Addison-Wesley
**     Publishing Company, Reading, Massachusetts.
................................................................................
#define ROUNDUP(X)  ((X+3) & ~3)

/*
** This is a magic string that appears at the beginning of every
** SQLite database in order to identify the file as a real database.
*/
static const char zMagicHeader[] = 
   "** This file contains an SQLite 2.1 database **";
#define MAGIC_SIZE (sizeof(zMagicHeader))

/*
** This is a magic integer also used to test the integrity of the database
** file.  This integer is used in addition to the string above so that
** if the file is written on a little-endian architecture and read
** on a big-endian architectures (or vice versa) we can detect the
................................................................................
** header for the cell must be defined first in order to do some
** of the sizing #defines that follow.
*/
struct CellHdr {
  Pgno leftChild; /* Child page that comes before this cell */
  u16 nKey;       /* Number of bytes in the key */
  u16 iNext;      /* Index in MemPage.u.aDisk[] of next cell in sorted order */
  u8 nKeyHi;
  u8 nDataHi;
  u16 nData;      /* Number of bytes of data */
};
#define NKEY(h)  (h.nKey + h.nKeyHi*65536)
#define NDATA(h) (h.nData + h.nDataHi*65536)

/*
** The minimum size of a complete Cell.  The Cell must contain a header
** and at least 4 bytes of payload.
*/
#define MIN_CELL_SIZE  (sizeof(CellHdr)+4)

................................................................................
** Compute the total number of bytes that a Cell needs on the main
** database page.  The number returned includes the Cell header,
** local payload storage, and the pointer to overflow pages (if
** applicable).  Additional space allocated on overflow pages
** is NOT included in the value returned from this routine.
*/
static int cellSize(Cell *pCell){
  int n = NKEY(pCell->h) + NDATA(pCell->h);
  if( n>MX_LOCAL_PAYLOAD ){
    n = MX_LOCAL_PAYLOAD + sizeof(Pgno);
  }else{
    n = ROUNDUP(n);
  }
  n += sizeof(CellHdr);
  return n;
................................................................................
  MemPage *pPage;

  pPage = pCur->pPage;
  if( pPage==0 || pCur->idx >= pPage->nCell ){
    *pSize = 0;
  }else{
    pCell = pPage->apCell[pCur->idx];
    *pSize = NKEY(pCell->h);
  }
  return SQLITE_OK;
}

/*
** Read payload information from the entry that the pCur cursor is
** pointing to.  Begin reading the payload at "offset" and read
................................................................................
  if( amt==0 ) return 0;
  pPage = pCur->pPage;
  if( pPage==0 ) return 0;
  if( pCur->idx >= pPage->nCell ){
    return 0;
  }
  pCell = pPage->apCell[pCur->idx];
  if( amt+offset > NKEY(pCell->h) ){
    amt = NKEY(pCell->h) - offset;
    if( amt<=0 ){
      return 0;
    }
  }
  getPayload(pCur, offset, amt, zBuf);
  return amt;
}
................................................................................
  MemPage *pPage;

  pPage = pCur->pPage;
  if( pPage==0 || pCur->idx >= pPage->nCell ){
    *pSize = 0;
  }else{
    pCell = pPage->apCell[pCur->idx];
    *pSize = NDATA(pCell->h);
  }
  return SQLITE_OK;
}

/*
** Read part of the data associated with cursor pCur.  A maximum
** of "amt" bytes will be transfered into zBuf[].  The transfer
................................................................................
  if( offset<0 ) return 0;
  if( amt==0 ) return 0;
  pPage = pCur->pPage;
  if( pPage==0 || pCur->idx >= pPage->nCell ){
    return 0;
  }
  pCell = pPage->apCell[pCur->idx];
  if( amt+offset > NDATA(pCell->h) ){
    amt = NDATA(pCell->h) - offset;
    if( amt<=0 ){
      return 0;
    }
  }
  getPayload(pCur, offset + NKEY(pCell->h), amt, zBuf);
  return amt;
}

/*
** Compare the first nKey bytes of the key of the entry that pCur
** points to against the first nKey bytes of pKey.  Set *pRes to
** show the comparison results:
................................................................................
  int n, c, rc;
  Cell *pCell;
  const char *zKey  = (const char*)pKey;

  assert( pCur->pPage );
  assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
  pCell = pCur->pPage->apCell[pCur->idx];
  if( nKey > NKEY(pCell->h) ){
    nKey = NKEY(pCell->h);
  }
  n = nKey;
  if( n>MX_LOCAL_PAYLOAD ){
    n = MX_LOCAL_PAYLOAD;
  }
  c = memcmp(pCell->aPayload, zKey, n);
  if( c!=0 ){
................................................................................
  rc = sqliteBtreeKeyCompare(pCur, pKey, nKeyOrig, &c);
  if( rc!=SQLITE_OK ) return rc;
  if( c==0 ){
    Cell *pCell;
    assert( pCur->pPage );
    assert( pCur->pPage->nCell>pCur->idx && pCur->idx>=0 );
    pCell = pCur->pPage->apCell[pCur->idx];
    c = NKEY(pCell->h) - nKeyOrig;
  }
  *pResult = c;
  return SQLITE_OK;
}

/*
** Move the cursor down to a new child page.
................................................................................
*/
static int clearCell(Btree *pBt, Cell *pCell){
  Pager *pPager = pBt->pPager;
  OverflowPage *pOvfl;
  Pgno ovfl, nextOvfl;
  int rc;

  if( NKEY(pCell->h) + NDATA(pCell->h) <= MX_LOCAL_PAYLOAD ){
    return SQLITE_OK;
  }
  ovfl = pCell->ovfl;
  pCell->ovfl = 0;
  while( ovfl ){
    rc = sqlitepager_get(pPager, ovfl, (void**)&pOvfl);
    if( rc ) return rc;
................................................................................
  int spaceLeft;
  int n, rc;
  int nPayload;
  const char *pPayload;
  char *pSpace;

  pCell->h.leftChild = 0;
  pCell->h.nKey = nKey & 0xffff;
  pCell->h.nKeyHi = nKey >> 16;
  pCell->h.nData = nData & 0xffff;
  pCell->h.nDataHi = nData >> 16;
  pCell->h.iNext = 0;

  pNext = &pCell->ovfl;
  pSpace = pCell->aPayload;
  spaceLeft = MX_LOCAL_PAYLOAD;
  pPayload = pKey;
  pKey = 0;
................................................................................
  if( recursive ) printf("PAGE %d:\n", pgno);
  i = 0;
  idx = pPage->u.hdr.firstCell;
  while( idx>0 && idx<=SQLITE_PAGE_SIZE-MIN_CELL_SIZE ){
    Cell *pCell = (Cell*)&pPage->u.aDisk[idx];
    int sz = cellSize(pCell);
    sprintf(range,"%d..%d", idx, idx+sz-1);
    sz = NKEY(pCell->h) + NDATA(pCell->h);
    if( sz>sizeof(payload)-1 ) sz = sizeof(payload)-1;
    memcpy(payload, pCell->aPayload, sz);
    for(j=0; j<sz; j++){
      if( payload[j]<0x20 || payload[j]>0x7f ) payload[j] = '.';
    }
    payload[sz] = 0;
    printf(
      "cell %2d: i=%-10s chld=%-4d nk=%-4d nd=%-4d payload=%s\n",
      i, range, (int)pCell->h.leftChild, NKEY(pCell->h), NDATA(pCell->h),
      payload
    );
    if( pPage->isInit && pPage->apCell[i]!=pCell ){
      printf("**** apCell[%d] does not match on prior entry ****\n", i);
    }
    i++;
    idx = pCell->h.iNext;
................................................................................
  cur.pBt = pCheck->pBt;
  for(i=0; i<pPage->nCell; i++){
    Cell *pCell = pPage->apCell[i];
    int sz;

    /* Check payload overflow pages
    */
    sz = NKEY(pCell->h) + NDATA(pCell->h);
    sprintf(zContext, "On page %d cell %d: ", iPage, i);
    if( sz>MX_LOCAL_PAYLOAD ){
      int nPage = (sz - MX_LOCAL_PAYLOAD + OVERFLOW_SIZE - 1)/OVERFLOW_SIZE;
      checkList(pCheck, pCell->ovfl, nPage, zContext);
    }

    /* Check that keys are in the right order
    */
    cur.idx = i;
    zKey2 = sqliteMalloc( NKEY(pCell->h)+1 );
    getPayload(&cur, 0, NKEY(pCell->h), zKey2);
    if( zKey1 && strcmp(zKey1,zKey2)>=0 ){
      checkAppendMsg(pCheck, zContext, "Key is out of order");
    }

    /* Check sanity of left child page.
    */
    pgno = (int)pCell->h.leftChild;

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
36
37
38
39
40
41
42
43






44
45
46
47
48
49
50
51
52
...
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
...
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.65 2001/10/22 02:58:10 drh Exp $
*/
#include "sqlite.h"
#include "hash.h"
#include "vdbe.h"
#include "parse.h"
#include "btree.h"
#include <stdio.h>
................................................................................
*/
typedef unsigned int u32;             /* 4-byte unsigned integer */
typedef unsigned short int u16;       /* 2-byte unsigned integer */
typedef unsigned char u8;             /* 1-byte unsigned integer */

/*
** The maximum number of bytes of data that can be put into a single
** row of a single table.






*/
#define MAX_BYTES_PER_ROW  65535

/*
** If memory allocation problems are found, recompile with
**
**      -DMEMORY_DEBUG=1
**
** to enable some sanity checking on malloc() and free().  To
................................................................................
};

/*
** Each token coming out of the lexer is an instance of
** this structure.
*/
struct Token {
  char *z;      /* Text of the token.  Not NULL-terminated! */
  int n;        /* Number of characters in this token */
};

/*
** Each node of an expression in the parse tree is an instance
** of this structure
*/
struct Expr {
................................................................................
  void *sqliteRealloc(void*,int);
  char *sqliteStrDup(const char*);
  char *sqliteStrNDup(const char*, int);
#endif
void sqliteSetString(char **, const char *, ...);
void sqliteSetNString(char **, ...);
void sqliteDequote(char*);
int sqliteRunParser(Parse*, char*, char **);
void sqliteExec(Parse*);
Expr *sqliteExpr(int, Expr*, Expr*, Token*);
void sqliteExprSpan(Expr*,Token*,Token*);
Expr *sqliteExprFunction(ExprList*, Token*);
void sqliteExprDelete(Expr*);
ExprList *sqliteExprListAppend(ExprList*,Expr*,Token*);
void sqliteExprListDelete(ExprList*);







|







 







|
>
>
>
>
>
>

|







 







|
|







 







|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
...
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
...
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.66 2001/11/04 18:32:47 drh Exp $
*/
#include "sqlite.h"
#include "hash.h"
#include "vdbe.h"
#include "parse.h"
#include "btree.h"
#include <stdio.h>
................................................................................
*/
typedef unsigned int u32;             /* 4-byte unsigned integer */
typedef unsigned short int u16;       /* 2-byte unsigned integer */
typedef unsigned char u8;             /* 1-byte unsigned integer */

/*
** The maximum number of bytes of data that can be put into a single
** row of a single table.  The upper bound on this limit is 16777215
** bytes (or 16MB-1).  We have arbitrarily set the limit to just 1MB
** here because the overflow page chain is inefficient for really big
** records and we want to discourage people from thinking that 
** multi-megabyte records are OK.  If your needs are different, you can
** change this define and recompile to increase or decrease the record
** size.
*/
#define MAX_BYTES_PER_ROW  1048576

/*
** If memory allocation problems are found, recompile with
**
**      -DMEMORY_DEBUG=1
**
** to enable some sanity checking on malloc() and free().  To
................................................................................
};

/*
** Each token coming out of the lexer is an instance of
** this structure.
*/
struct Token {
  const char *z;      /* Text of the token.  Not NULL-terminated! */
  int n;              /* Number of characters in this token */
};

/*
** Each node of an expression in the parse tree is an instance
** of this structure
*/
struct Expr {
................................................................................
  void *sqliteRealloc(void*,int);
  char *sqliteStrDup(const char*);
  char *sqliteStrNDup(const char*, int);
#endif
void sqliteSetString(char **, const char *, ...);
void sqliteSetNString(char **, ...);
void sqliteDequote(char*);
int sqliteRunParser(Parse*, const char*, char **);
void sqliteExec(Parse*);
Expr *sqliteExpr(int, Expr*, Expr*, Token*);
void sqliteExprSpan(Expr*,Token*,Token*);
Expr *sqliteExprFunction(ExprList*, Token*);
void sqliteExprDelete(Expr*);
ExprList *sqliteExprListAppend(ExprList*,Expr*,Token*);
void sqliteExprListDelete(ExprList*);

Changes to src/tokenize.c.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that splits an SQL input string up into
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.30 2001/10/22 02:58:10 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <stdlib.h>

/*
................................................................................
/*
** Run the parser on the given SQL string.  The parser structure is
** passed in.  An SQLITE_ status code is returned.  If an error occurs
** and pzErrMsg!=NULL then an error message might be written into 
** memory obtained from malloc() and *pzErrMsg made to point to that
** error message.  Or maybe not.
*/
int sqliteRunParser(Parse *pParse, char *zSql, char **pzErrMsg){
  int nErr = 0;
  int i;
  void *pEngine;
  int once = 1;
  sqlite *db = pParse->db;
  extern void *sqliteParserAlloc(void*(*)(int));
  extern void sqliteParserFree(void*, void(*)(void*));







|







 







|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that splits an SQL input string up into
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.31 2001/11/04 18:32:48 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include <stdlib.h>

/*
................................................................................
/*
** Run the parser on the given SQL string.  The parser structure is
** passed in.  An SQLITE_ status code is returned.  If an error occurs
** and pzErrMsg!=NULL then an error message might be written into 
** memory obtained from malloc() and *pzErrMsg made to point to that
** error message.  Or maybe not.
*/
int sqliteRunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
  int nErr = 0;
  int i;
  void *pEngine;
  int once = 1;
  sqlite *db = pParse->db;
  extern void *sqliteParserAlloc(void*(*)(int));
  extern void sqliteParserFree(void*, void(*)(void*));

Changes to src/vdbe.c.

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
...
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
...
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
....
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931

1932
1933


















1934
1935
1936
1937
1938
1939
1940
1941
1942
1943







1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954





1955
1956
1957







1958
1959
1960
1961
1962
1963
1964
....
2416
2417
2418
2419
2420
2421
2422


2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
....
2492
2493
2494
2495
2496
2497
2498

2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
....
2527
2528
2529
2530
2531
2532
2533

2534
2535
2536
2537
2538
2539
2540
2541
....
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
....
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666



2667
2668
2669
2670
2671
2672
2673
2674
2675

2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
** type to the other occurs as necessary.
** 
** Most of the code in this file is taken up by the sqliteVdbeExec()
** function which does the work of interpreting a VDBE program.
** But other routines are also provided to help in building up
** a program instruction by instruction.
**
** $Id: vdbe.c,v 1.91 2001/11/01 14:41:34 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** SQL is translated into a sequence of instructions to be
** executed by a virtual machine.  Each instruction is an instance
................................................................................
**
** If n==P3_STATIC  it means that zP3 is a pointer to a constant static
** string we can just copy the pointer.  n==P3_POINTER means zP3 is
** a pointer to some object other than a string.
**
** If addr<0 then change P3 on the most recently inserted instruction.
*/
void sqliteVdbeChangeP3(Vdbe *p, int addr, char *zP3, int n){
  Op *pOp;
  if( p==0 || p->aOp==0 ) return;
  if( addr<0 || addr>=p->nOp ){
    addr = p->nOp - 1;
    if( addr<0 ) return;
  }
  pOp = &p->aOp[addr];
................................................................................
    sqliteFree(pOp->p3);
    pOp->p3 = 0;
  }
  if( zP3==0 ){
    pOp->p3 = 0;
    pOp->p3type = P3_NOTUSED;
  }else if( n<0 ){
    pOp->p3 = zP3;
    pOp->p3type = n;
  }else{
    sqliteSetNString(&pOp->p3, zP3, n, 0);
    pOp->p3type = P3_DYNAMIC;
  }
}

................................................................................
  if( c ) pc = pOp->p2-1;
  break;
}

/* Opcode: MakeRecord P1 * *
**
** Convert the top P1 entries of the stack into a single entry
** suitable for use as a data record in a database table.  To do this
** all entries (except NULLs) are converted to strings and 
** concatenated.  The null-terminators are included on all string
** except for NULL columns which are represented by zero bytes.
** The lowest entry
** on the stack is the first in the concatenation and the top of
** the stack is the last.  After all columns are concatenated, an
** index header is added.  The index header consists of P1 16-bit integers
** which hold the offset of the beginning of each column data from the
** beginning of the completed record including the header.
**
** The Column opcode is used to unpack a record manufactured with
** the opcode.
*/
case OP_MakeRecord: {
  char *zNewRecord;
  int nByte;
  int nField;
  int i, j;

  u16 addr;



















  nField = pOp->p1;
  VERIFY( if( p->tos+1<nField ) goto not_enough_stack; )
  nByte = 0;
  for(i=p->tos-nField+1; i<=p->tos; i++){
    if( (aStack[i].flags & STK_Null)==0 ){
      if( Stringify(p, i) ) goto no_mem;
      nByte += aStack[i].n;
    }
  }
  nByte += sizeof(addr)*nField;







  if( nByte>MAX_BYTES_PER_ROW ){
    rc = SQLITE_TOOBIG;
    goto abort_due_to_error;
  }
  zNewRecord = sqliteMalloc( nByte );
  if( zNewRecord==0 ) goto no_mem;
  j = 0;
  addr = sizeof(addr)*nField;
  for(i=p->tos-nField+1; i<=p->tos; i++){
    memcpy(&zNewRecord[j], (char*)&addr, sizeof(addr));
    j += sizeof(addr);





    if( (aStack[i].flags & STK_Null)==0 ){
      addr += aStack[i].n;
    }







  }
  for(i=p->tos-nField+1; i<=p->tos; i++){
    if( (aStack[i].flags & STK_Null)==0 ){
      memcpy(&zNewRecord[j], zStack[i], aStack[i].n);
      j += aStack[i].n;
    }
  }
................................................................................
** is left pointing at a nearby record.
**
** See also: Found, NotFound, Distinct
*/
case OP_MoveTo: {
  int i = pOp->p1;
  int tos = p->tos;


  VERIFY( if( tos<0 ) goto not_enough_stack; )
  if( i>=0 && i<p->nCursor && p->aCsr[i].pCursor ){
    int res;
    if( aStack[tos].flags & STK_Int ){
      int iKey = bigEndian(aStack[tos].i);
      sqliteBtreeMoveto(p->aCsr[i].pCursor, 
          (char*)&iKey, sizeof(int), &res);
      p->aCsr[i].lastRecno = aStack[tos].i;
      p->aCsr[i].recnoIsValid = 1;
    }else{
      if( Stringify(p, tos) ) goto no_mem;
      sqliteBtreeMoveto(p->aCsr[i].pCursor, zStack[tos], aStack[tos].n, &res);
      p->aCsr[i].recnoIsValid = 0;
    }
    p->nFetch++;
  }
  POPSTACK;
  break;
}

................................................................................
*/
case OP_Distinct:
case OP_NotFound:
case OP_Found: {
  int i = pOp->p1;
  int tos = p->tos;
  int alreadyExists = 0;

  VERIFY( if( tos<0 ) goto not_enough_stack; )
  if( VERIFY( i>=0 && i<p->nCursor && ) p->aCsr[i].pCursor ){
    int res, rx;
    if( aStack[tos].flags & STK_Int ){
      int iKey = bigEndian(aStack[tos].i);
      rx = sqliteBtreeMoveto(p->aCsr[i].pCursor, 
           (char*)&iKey, sizeof(int), &res);
    }else{
      if( Stringify(p, tos) ) goto no_mem;
      rx = sqliteBtreeMoveto(p->aCsr[i].pCursor,
         zStack[tos], aStack[tos].n, &res);
    }
    alreadyExists = rx==SQLITE_OK && res==0;
  }
  if( pOp->opcode==OP_Found ){
    if( alreadyExists ) pc = pOp->p2 - 1;
  }else{
    if( !alreadyExists ) pc = pOp->p2 - 1;
................................................................................
** The record number is not previously used as a key in the database
** table that cursor P1 points to.  The new record number pushed 
** onto the stack.
*/
case OP_NewRecno: {
  int i = pOp->p1;
  int v = 0;

  if( VERIFY( i<0 || i>=p->nCursor || ) p->aCsr[i].pCursor==0 ){
    v = 0;
  }else{
    /* A probablistic algorithm is used to locate an unused rowid.
    ** We select a rowid at random and see if it exists in the table.
    ** If it does not exist, we have succeeded.  If the random rowid
    ** does exist, we select a new one and try again, up to 1000 times.
    **
................................................................................
      if( cnt>5 ){
        v = sqliteRandomInteger();
      }else{
        v += sqliteRandomByte() + 1;
      }
      if( v==0 ) continue;
      x = bigEndian(v);
      rx = sqliteBtreeMoveto(p->aCsr[i].pCursor, &x, sizeof(int), &res);
      cnt++;
    }while( cnt<1000 && rx==SQLITE_OK && res==0 );
    db->nextRowid = v;
    if( rx==SQLITE_OK && res==0 ){
      rc = SQLITE_FULL;
      goto abort_due_to_error;
    }
................................................................................
** in the data.
**
** If the KeyAsData opcode has previously executed on this cursor,
** then the field might be extracted from the key rather than the
** data.
*/
case OP_Column: {
  int amt, offset, nCol, payloadSize;
  u16 aHdr[10];
  static const int mxHdr = sizeof(aHdr)/sizeof(aHdr[0]);
  int i = pOp->p1;
  int p2 = pOp->p2;
  int tos = p->tos+1;
  BtCursor *pCrsr;
  char *z;




  VERIFY( if( NeedStack(p, tos+1) ) goto no_mem; )
  if( VERIFY( i>=0 && i<p->nCursor && ) (pCrsr = p->aCsr[i].pCursor)!=0 ){
    int (*xSize)(BtCursor*, int*);
    int (*xRead)(BtCursor*, int, int, char*);

    /* Use different access functions depending on whether the information
    ** is coming from the key or the data of the record.
    */

    if( p->aCsr[i].keyAsData ){
      xSize = sqliteBtreeKeySize;
      xRead = sqliteBtreeKey;
    }else{
      xSize = sqliteBtreeDataSize;
      xRead = sqliteBtreeData;
    }

    /* 
    ** The code is complicated by efforts to minimize the number
    ** of invocations of xRead() since that call can be expensive.
    ** For the common case where P2 is small, xRead() is invoked
    ** twice.  For larger values of P2, it has to be called
    ** three times.
    */
    (*xSize)(pCrsr, &payloadSize);
    if( payloadSize < sizeof(aHdr[0])*(p2+1) ){
      rc = SQLITE_CORRUPT;
      goto abort_due_to_error;
    }
    if( p2+1<mxHdr ){
      (*xRead)(pCrsr, 0, sizeof(aHdr[0])*(p2+2), (char*)aHdr);
      nCol = aHdr[0];
      nCol /= sizeof(aHdr[0]);
      offset = aHdr[p2];
      if( p2 == nCol-1 ){
        amt = payloadSize - offset;
      }else{
        amt = aHdr[p2+1] - offset;
      }
    }else{
      (*xRead)(pCrsr, 0, sizeof(aHdr[0]), (char*)aHdr);
      nCol = aHdr[0]/sizeof(aHdr[0]);
      if( p2 == nCol-1 ){
        (*xRead)(pCrsr, sizeof(aHdr[0])*p2, sizeof(aHdr[0]), (char*)aHdr);
        offset = aHdr[0];
        amt = payloadSize - offset;
      }else{
        (*xRead)(pCrsr, sizeof(aHdr[0])*p2, sizeof(aHdr[0])*2, (char*)aHdr);
        offset = aHdr[0];
        amt = aHdr[1] - offset;
      }
    }
    if( payloadSize < nCol || amt<0 || offset<0 ){
      rc = SQLITE_CORRUPT;
      goto abort_due_to_error;
    }

    /* amt and offset now hold the offset to the start of data and the
    ** amount of data.  Go get the data and put it on the stack.
    */
    if( amt==0 ){
      aStack[tos].flags = STK_Null;
    }else{
      z = sqliteMalloc( amt );
      if( z==0 ) goto no_mem;
      (*xRead)(pCrsr, offset, amt, z);
      aStack[tos].flags = STK_Str | STK_Dyn;
      zStack[tos] = z;
      aStack[tos].n = amt;
    }
    p->tos = tos;







|







 







|







 







|







 







|
|
|
|
<
<
<
<
<
<
<
<
<






>
|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>









|
>
>
>
>
>
>
>







|

|
|
>
>
>
>
>



>
>
>
>
>
>
>







 







>
>

|



<
|
|
|


|
|







 







>

|



<
|


<
|







 







>
|







 







|







 







|
<
<



|
|
>
>
>


|
<
<




>
|
|


|



|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<










|







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
...
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
...
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
....
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916









1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
....
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458

2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
....
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534

2535
2536
2537

2538
2539
2540
2541
2542
2543
2544
2545
....
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
....
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
....
2682
2683
2684
2685
2686
2687
2688
2689


2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700


2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743






2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
** type to the other occurs as necessary.
** 
** Most of the code in this file is taken up by the sqliteVdbeExec()
** function which does the work of interpreting a VDBE program.
** But other routines are also provided to help in building up
** a program instruction by instruction.
**
** $Id: vdbe.c,v 1.92 2001/11/04 18:32:48 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** SQL is translated into a sequence of instructions to be
** executed by a virtual machine.  Each instruction is an instance
................................................................................
**
** If n==P3_STATIC  it means that zP3 is a pointer to a constant static
** string we can just copy the pointer.  n==P3_POINTER means zP3 is
** a pointer to some object other than a string.
**
** If addr<0 then change P3 on the most recently inserted instruction.
*/
void sqliteVdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){
  Op *pOp;
  if( p==0 || p->aOp==0 ) return;
  if( addr<0 || addr>=p->nOp ){
    addr = p->nOp - 1;
    if( addr<0 ) return;
  }
  pOp = &p->aOp[addr];
................................................................................
    sqliteFree(pOp->p3);
    pOp->p3 = 0;
  }
  if( zP3==0 ){
    pOp->p3 = 0;
    pOp->p3type = P3_NOTUSED;
  }else if( n<0 ){
    pOp->p3 = (char*)zP3;
    pOp->p3type = n;
  }else{
    sqliteSetNString(&pOp->p3, zP3, n, 0);
    pOp->p3type = P3_DYNAMIC;
  }
}

................................................................................
  if( c ) pc = pOp->p2-1;
  break;
}

/* Opcode: MakeRecord P1 * *
**
** Convert the top P1 entries of the stack into a single entry
** suitable for use as a data record in a database table.  The
** details of the format are irrelavant as long as the OP_Column
** opcode can decode the record later.  Refer to source code
** comments for the details of the record format.









*/
case OP_MakeRecord: {
  char *zNewRecord;
  int nByte;
  int nField;
  int i, j;
  int idxWidth;
  u32 addr;

  /* Assuming the record contains N fields, the record format looks
  ** like this:
  **
  **   -------------------------------------------------------------------
  **   | idx0 | idx1 | ... | idx(N-1) | idx(N) | data0 | ... | data(N-1) |
  **   -------------------------------------------------------------------
  **
  ** All data fields are converted to strings before being stored and
  ** are stored with their null terminators.  NULL entries omit the
  ** null terminator.  Thus an empty string uses 1 byte and a NULL uses
  ** zero bytes.  Data(0) is taken from the lowest element of the stack
  ** and data(N-1) is the top of the stack.
  **
  ** Each of the idx() entries is either 1, 2, or 3 bytes depending on
  ** how big the total record is.  Idx(0) contains the offset to the start
  ** of data(0).  Idx(k) contains the offset to the start of data(k).
  ** Idx(N) contains the total number of bytes in the record.
  */
  nField = pOp->p1;
  VERIFY( if( p->tos+1<nField ) goto not_enough_stack; )
  nByte = 0;
  for(i=p->tos-nField+1; i<=p->tos; i++){
    if( (aStack[i].flags & STK_Null)==0 ){
      if( Stringify(p, i) ) goto no_mem;
      nByte += aStack[i].n;
    }
  }
  if( nByte + nField + 1 < 256 ){
    idxWidth = 1;
  }else if( nByte + 2*nField + 2 < 65536 ){
    idxWidth = 2;
  }else{
    idxWidth = 3;
  }
  nByte += idxWidth*(nField + 1);
  if( nByte>MAX_BYTES_PER_ROW ){
    rc = SQLITE_TOOBIG;
    goto abort_due_to_error;
  }
  zNewRecord = sqliteMalloc( nByte );
  if( zNewRecord==0 ) goto no_mem;
  j = 0;
  addr = idxWidth*(nField+1);
  for(i=p->tos-nField+1; i<=p->tos; i++){
    zNewRecord[j++] = addr & 0xff;
    if( idxWidth>1 ){
      zNewRecord[j++] = (addr>>8)&0xff;
      if( idxWidth>2 ){
        zNewRecord[j++] = (addr>>16)&0xff;
      }
    }
    if( (aStack[i].flags & STK_Null)==0 ){
      addr += aStack[i].n;
    }
  }
  zNewRecord[j++] = addr & 0xff;
  if( idxWidth>1 ){
    zNewRecord[j++] = (addr>>8)&0xff;
    if( idxWidth>2 ){
      zNewRecord[j++] = (addr>>16)&0xff;
    }
  }
  for(i=p->tos-nField+1; i<=p->tos; i++){
    if( (aStack[i].flags & STK_Null)==0 ){
      memcpy(&zNewRecord[j], zStack[i], aStack[i].n);
      j += aStack[i].n;
    }
  }
................................................................................
** is left pointing at a nearby record.
**
** See also: Found, NotFound, Distinct
*/
case OP_MoveTo: {
  int i = pOp->p1;
  int tos = p->tos;
  Cursor *pC;

  VERIFY( if( tos<0 ) goto not_enough_stack; )
  if( i>=0 && i<p->nCursor && (pC = &p->aCsr[i])->pCursor!=0 ){
    int res;
    if( aStack[tos].flags & STK_Int ){
      int iKey = bigEndian(aStack[tos].i);

      sqliteBtreeMoveto(pC->pCursor, (char*)&iKey, sizeof(int), &res);
      pC->lastRecno = aStack[tos].i;
      pC->recnoIsValid = 1;
    }else{
      if( Stringify(p, tos) ) goto no_mem;
      sqliteBtreeMoveto(pC->pCursor, zStack[tos], aStack[tos].n, &res);
      pC->recnoIsValid = 0;
    }
    p->nFetch++;
  }
  POPSTACK;
  break;
}

................................................................................
*/
case OP_Distinct:
case OP_NotFound:
case OP_Found: {
  int i = pOp->p1;
  int tos = p->tos;
  int alreadyExists = 0;
  Cursor *pC;
  VERIFY( if( tos<0 ) goto not_enough_stack; )
  if( VERIFY( i>=0 && i<p->nCursor && ) (pC = &p->aCsr[i])->pCursor!=0 ){
    int res, rx;
    if( aStack[tos].flags & STK_Int ){
      int iKey = bigEndian(aStack[tos].i);

      rx = sqliteBtreeMoveto(pC->pCursor, (char*)&iKey, sizeof(int), &res);
    }else{
      if( Stringify(p, tos) ) goto no_mem;

      rx = sqliteBtreeMoveto(pC->pCursor, zStack[tos], aStack[tos].n, &res);
    }
    alreadyExists = rx==SQLITE_OK && res==0;
  }
  if( pOp->opcode==OP_Found ){
    if( alreadyExists ) pc = pOp->p2 - 1;
  }else{
    if( !alreadyExists ) pc = pOp->p2 - 1;
................................................................................
** The record number is not previously used as a key in the database
** table that cursor P1 points to.  The new record number pushed 
** onto the stack.
*/
case OP_NewRecno: {
  int i = pOp->p1;
  int v = 0;
  Cursor *pC;
  if( VERIFY( i<0 || i>=p->nCursor || ) (pC = &p->aCsr[i])->pCursor==0 ){
    v = 0;
  }else{
    /* A probablistic algorithm is used to locate an unused rowid.
    ** We select a rowid at random and see if it exists in the table.
    ** If it does not exist, we have succeeded.  If the random rowid
    ** does exist, we select a new one and try again, up to 1000 times.
    **
................................................................................
      if( cnt>5 ){
        v = sqliteRandomInteger();
      }else{
        v += sqliteRandomByte() + 1;
      }
      if( v==0 ) continue;
      x = bigEndian(v);
      rx = sqliteBtreeMoveto(pC->pCursor, &x, sizeof(int), &res);
      cnt++;
    }while( cnt<1000 && rx==SQLITE_OK && res==0 );
    db->nextRowid = v;
    if( rx==SQLITE_OK && res==0 ){
      rc = SQLITE_FULL;
      goto abort_due_to_error;
    }
................................................................................
** in the data.
**
** If the KeyAsData opcode has previously executed on this cursor,
** then the field might be extracted from the key rather than the
** data.
*/
case OP_Column: {
  int amt, offset, end, nCol, payloadSize;


  int i = pOp->p1;
  int p2 = pOp->p2;
  int tos = p->tos+1;
  Cursor *pC;
  BtCursor *pCrsr;
  int idxWidth;
  unsigned char aHdr[10];
  int (*xRead)(BtCursor*, int, int, char*);

  VERIFY( if( NeedStack(p, tos+1) ) goto no_mem; )
  if( VERIFY( i>=0 && i<p->nCursor && ) (pC = &p->aCsr[i])->pCursor!=0 ){



    /* Use different access functions depending on whether the information
    ** is coming from the key or the data of the record.
    */
    pCrsr = pC->pCursor;
    if( pC->keyAsData ){
      sqliteBtreeKeySize(pCrsr, &payloadSize);
      xRead = sqliteBtreeKey;
    }else{
      sqliteBtreeDataSize(pCrsr, &payloadSize);
      xRead = sqliteBtreeData;
    }

    /* Figure out how many bytes in the column data and where the column
    ** data begins.
    */
    if( payloadSize<256 ){
      idxWidth = 1;
    }else if( payloadSize<65536 ){
      idxWidth = 2;
    }else{
      idxWidth = 3;
    }

    /* Figure out where the requested column is stored and how big it is.
    */
    if( payloadSize < idxWidth*(p2+1) ){
      rc = SQLITE_CORRUPT;
      goto abort_due_to_error;
    }
    (*xRead)(pCrsr, idxWidth*p2, idxWidth*2, (char*)aHdr);
    offset = aHdr[0];
    end = aHdr[idxWidth];
    if( idxWidth>1 ){
      offset |= aHdr[1]<<8;
      end |= aHdr[idxWidth+1]<<8;
      if( idxWidth>2 ){
        offset |= aHdr[2]<<16;
        end |= aHdr[idxWidth+2]<<16;
      }
    }
    amt = end - offset;
    if( amt<0 || offset<0 || end>payloadSize ){






      rc = SQLITE_CORRUPT;
      goto abort_due_to_error;
    }

    /* amt and offset now hold the offset to the start of data and the
    ** amount of data.  Go get the data and put it on the stack.
    */
    if( amt==0 ){
      aStack[tos].flags = STK_Null;
    }else{
      char *z = sqliteMalloc( amt );
      if( z==0 ) goto no_mem;
      (*xRead)(pCrsr, offset, amt, z);
      aStack[tos].flags = STK_Str | STK_Dyn;
      zStack[tos] = z;
      aStack[tos].n = amt;
    }
    p->tos = tos;

Changes to src/vdbe.h.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
*************************************************************************
** Header file for the Virtual DataBase Engine (VDBE)
**
** This header defines the interface to the virtual database engine
** or VDBE.  The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
** $Id: vdbe.h,v 1.31 2001/11/01 14:41:34 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines
................................................................................
** for a description of what each of these routines does.
*/
Vdbe *sqliteVdbeCreate(sqlite*);
void sqliteVdbeCreateCallback(Vdbe*, int*);
int sqliteVdbeAddOp(Vdbe*,int,int,int);
int sqliteVdbeAddOpList(Vdbe*, int nOp, VdbeOp const *aOp);
void sqliteVdbeChangeP1(Vdbe*, int addr, int P1);
void sqliteVdbeChangeP3(Vdbe*, int addr, char *zP1, int N);
void sqliteVdbeDequoteP3(Vdbe*, int addr);
int sqliteVdbeMakeLabel(Vdbe*);
void sqliteVdbeDelete(Vdbe*);
int sqliteVdbeOpcode(const char *zName);
int sqliteVdbeExec(Vdbe*,sqlite_callback,void*,char**,void*,
                   int(*)(void*,const char*,int));
int sqliteVdbeList(Vdbe*,sqlite_callback,void*,char**);
void sqliteVdbeResolveLabel(Vdbe*, int);
int sqliteVdbeCurrentAddr(Vdbe*);
void sqliteVdbeTrace(Vdbe*,FILE*);
void sqliteVdbeCompressSpace(Vdbe*,int);

#endif







|







 







|













11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
*************************************************************************
** Header file for the Virtual DataBase Engine (VDBE)
**
** This header defines the interface to the virtual database engine
** or VDBE.  The VDBE implements an abstract machine that runs a
** simple program to access and modify the underlying database.
**
** $Id: vdbe.h,v 1.32 2001/11/04 18:32:48 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines
................................................................................
** for a description of what each of these routines does.
*/
Vdbe *sqliteVdbeCreate(sqlite*);
void sqliteVdbeCreateCallback(Vdbe*, int*);
int sqliteVdbeAddOp(Vdbe*,int,int,int);
int sqliteVdbeAddOpList(Vdbe*, int nOp, VdbeOp const *aOp);
void sqliteVdbeChangeP1(Vdbe*, int addr, int P1);
void sqliteVdbeChangeP3(Vdbe*, int addr, const char *zP1, int N);
void sqliteVdbeDequoteP3(Vdbe*, int addr);
int sqliteVdbeMakeLabel(Vdbe*);
void sqliteVdbeDelete(Vdbe*);
int sqliteVdbeOpcode(const char *zName);
int sqliteVdbeExec(Vdbe*,sqlite_callback,void*,char**,void*,
                   int(*)(void*,const char*,int));
int sqliteVdbeList(Vdbe*,sqlite_callback,void*,char**);
void sqliteVdbeResolveLabel(Vdbe*, int);
int sqliteVdbeCurrentAddr(Vdbe*);
void sqliteVdbeTrace(Vdbe*,FILE*);
void sqliteVdbeCompressSpace(Vdbe*,int);

#endif

Changes to src/where.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This module contains C code that generates VDBE code used to process
** the WHERE clause of SQL statements.  Also found here are subroutines
** to generate VDBE code to evaluate expressions.
**
** $Id: where.c,v 1.23 2001/10/13 01:06:49 drh Exp $
*/
#include "sqliteInt.h"

/*
** The query generator uses an array of instances of this structure to
** help it analyze the subexpressions of the WHERE clause.  Each WHERE
** clause subexpression is separated from the others by an AND operator.
................................................................................
/*
** The input to this routine is an ExprInfo structure with only the
** "p" field filled in.  The job of this routine is to analyze the
** subexpression and populate all the other fields of the ExprInfo
** structure.
**
** "base" is the cursor number (the value of the iTable field) that
** corresponds to the first entyr in the table list.  This is the
** same as pParse->nTab.
*/
static void exprAnalyze(int base, ExprInfo *pInfo){
  Expr *pExpr = pInfo->p;
  pInfo->prereqLeft = exprTableUsage(base, pExpr->pLeft);
  pInfo->prereqRight = exprTableUsage(base, pExpr->pRight);
  pInfo->indexable = 0;







|







 







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
..
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This module contains C code that generates VDBE code used to process
** the WHERE clause of SQL statements.  Also found here are subroutines
** to generate VDBE code to evaluate expressions.
**
** $Id: where.c,v 1.24 2001/11/04 18:32:48 drh Exp $
*/
#include "sqliteInt.h"

/*
** The query generator uses an array of instances of this structure to
** help it analyze the subexpressions of the WHERE clause.  Each WHERE
** clause subexpression is separated from the others by an AND operator.
................................................................................
/*
** The input to this routine is an ExprInfo structure with only the
** "p" field filled in.  The job of this routine is to analyze the
** subexpression and populate all the other fields of the ExprInfo
** structure.
**
** "base" is the cursor number (the value of the iTable field) that
** corresponds to the first entry in the table list.  This is the
** same as pParse->nTab.
*/
static void exprAnalyze(int base, ExprInfo *pInfo){
  Expr *pExpr = pInfo->p;
  pInfo->prereqLeft = exprTableUsage(base, pExpr->pLeft);
  pInfo->prereqRight = exprTableUsage(base, pExpr->pRight);
  pInfo->indexable = 0;

Changes to test/bigrow.test.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
46
47
48
49
50
51
52

53
54

55
56
57











58
59
60
61
62
63
64
..
97
98
99
100
101
102
103



104
































































































105
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is stressing the library by putting large amounts
# of data in a single row of a table.
#
# $Id: bigrow.test,v 1.1 2001/09/24 03:12:40 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Make a big string that we can use for test data
#
do_test bigrow-1.0 {
................................................................................
  execsql $sql
  execsql {SELECT a, c FROM t1}
} {abc xyz}
do_test bigrow-1.3 {
  execsql {SELECT b FROM t1}
} [list $::big1]
do_test bigrow-1.4 {

  set sql "INSERT INTO t1 VALUES('abc',"
  append sql "'[string range $::bigstr 0 65520]', 'xyz');"

  set r [catch {execsql $sql} msg]
  lappend r $msg
} {1 {too much data for one table row}}












do_test bigrow-1.5 {
  execsql {
    UPDATE t1 SET a=b, b=a;
    SELECT b,c FROM t1
  }
} {abc xyz}
................................................................................
} [list $::big1]
do_test bigrow-2.3 {
  execsql {
    UPDATE t1 SET a=b, b=a
  }
  execsql "SELECT b FROM t1 WHERE a=='$::big1'"
} {abc}




































































































finish_test







|







 







>
|
<
>


<
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
46
47
48
49
50
51
52
53
54

55
56
57

58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
...
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is stressing the library by putting large amounts
# of data in a single row of a table.
#
# $Id: bigrow.test,v 1.2 2001/11/04 18:32:48 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Make a big string that we can use for test data
#
do_test bigrow-1.0 {
................................................................................
  execsql $sql
  execsql {SELECT a, c FROM t1}
} {abc xyz}
do_test bigrow-1.3 {
  execsql {SELECT b FROM t1}
} [list $::big1]
do_test bigrow-1.4 {
  set ::big2 [string range $::bigstr 0 65520]
  set sql "INSERT INTO t1 VALUES('abc2',"

  append sql "'$::big2', 'xyz2');"
  set r [catch {execsql $sql} msg]
  lappend r $msg

} {0 {}}
do_test bigrow-1.4.1 {
  execsql {SELECT b FROM t1 ORDER BY c}
} [list $::big1 $::big2]
do_test bigrow-1.4.2 {
  execsql {SELECT c FROM t1 ORDER BY c}
} {xyz xyz2}
do_test bigrow-1.4.3 {
  execsql {DELETE FROM t1 WHERE a='abc2'}
  execsql {SELECT c FROM t1}
} {xyz}

do_test bigrow-1.5 {
  execsql {
    UPDATE t1 SET a=b, b=a;
    SELECT b,c FROM t1
  }
} {abc xyz}
................................................................................
} [list $::big1]
do_test bigrow-2.3 {
  execsql {
    UPDATE t1 SET a=b, b=a
  }
  execsql "SELECT b FROM t1 WHERE a=='$::big1'"
} {abc}
catch {unset ::bigstr}
catch {unset ::big1}
catch {unset ::big2}

# Mosts of the tests above were created back when rows were limited in
# size to 64K.  Now rows can be much bigger.  Test that logic.  Also
# make sure things work correctly at the transition boundries between
# row sizes of 256 to 257 bytes and from 65536 to 65537 bytes.
#
# We begin by testing the 256..257 transition.
#
do_test bigrow-3.1 {
  execsql {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c) VALUES('one','abcdefghijklmnopqrstuvwxyz0123','hi');
  }
  execsql {SELECT a,length(b),c FROM t1}
} {one 30 hi}
do_test bigrow-3.2 {
  execsql {
    UPDATE t1 SET b=b||b;
    UPDATE t1 SET b=b||b;
    UPDATE t1 SET b=b||b;
  }
  execsql {SELECT a,length(b),c FROM t1}
} {one 240 hi}
for {set i 1} {$i<10} {incr i} {
  do_test bigrow-3.3.$i {
    execsql "UPDATE t1 SET b=b||'$i'"
    execsql {SELECT a,length(b),c FROM t1}
  } "one [expr {240+$i}] hi"
}

# Now test the 65536..65537 row-size transition.
#
do_test bigrow-4.1 {
  execsql {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c) VALUES('one','abcdefghijklmnopqrstuvwxyz0123','hi');
  }
  execsql {SELECT a,length(b),c FROM t1}
} {one 30 hi}
do_test bigrow-4.2 {
  execsql {
    UPDATE t1 SET b=b||b;
    UPDATE t1 SET b=b||b;
    UPDATE t1 SET b=b||b;
    UPDATE t1 SET b=b||b;
    UPDATE t1 SET b=b||b;
    UPDATE t1 SET b=b||b;
    UPDATE t1 SET b=b||b;
    UPDATE t1 SET b=b||b;
    UPDATE t1 SET b=b||b;
    UPDATE t1 SET b=b||b;
    UPDATE t1 SET b=b||b;
    UPDATE t1 SET b=b||b;
  }
  execsql {SELECT a,length(b),c FROM t1}
} {one 122880 hi}
do_test bigrow-4.3 {
  execsql {
    UPDATE t1 SET b=substr(b,0,65515)
  }
  execsql {SELECT a,length(b),c FROM t1}
} {one 65515 hi}
for {set i 1} {$i<10} {incr i} {
  do_test bigrow-4.4.$i {
    execsql "UPDATE t1 SET b=b||'$i'"
    execsql {SELECT a,length(b),c FROM t1}
  } "one [expr {65515+$i}] hi"
}

# Check to make sure the library recovers safely if a row contains
# too much data.
#
do_test bigrow-5.1 {
  execsql {
    DELETE FROM t1;
    INSERT INTO t1(a,b,c) VALUES('one','abcdefghijklmnopqrstuvwxyz0123','hi');
  }
  execsql {SELECT a,length(b),c FROM t1}
} {one 30 hi}
set i 1
for {set sz 60} {$sz<1048560} {incr sz $sz} {
  do_test bigrow-5.2.$i {
    execsql {
      UPDATE t1 SET b=b||b;
      SELECT a,length(b),c FROM t1;
    }
  } "one $sz hi"
  incr i
}
do_test bigrow-5.3 {
  set r [catch {execsql {UPDATE t1 SET b=b||b}} msg]
  lappend r $msg
} {1 {too much data for one table row}}
do_test bigrow-5.4 {
  execsql {DROP TABLE t1}
} {}

finish_test

Changes to www/changes.tcl.

12
13
14
15
16
17
18





19
20
21
22
23
24
25
}


proc chng {date desc} {
  puts "<DT><B>$date</B></DT>"
  puts "<DD><P><UL>$desc</UL></P></DD>"
}






chng {2001 Nov 3 (2.0.8)} {
<li>Made selected parameters in API functions <b>const</b>. This should
    be fully backwards compatible.</li>
<li>Documentation updates</li>
<li>Simplify the design of the VDBE by restricting the number of sorters
    and lists to 1.







>
>
>
>
>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
}


proc chng {date desc} {
  puts "<DT><B>$date</B></DT>"
  puts "<DD><P><UL>$desc</UL></P></DD>"
}

chng {2001 ??? ?? (2.1.0)} {
<li>Change the format of data records so that records up to 16MB in size
    can be stored.</li>
}

chng {2001 Nov 3 (2.0.8)} {
<li>Made selected parameters in API functions <b>const</b>. This should
    be fully backwards compatible.</li>
<li>Documentation updates</li>
<li>Simplify the design of the VDBE by restricting the number of sorters
    and lists to 1.