/ Check-in [202a470f]
Login

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

Overview
Comment:Omit the '\0' at the end of UTF-8 strings on disk (it is implied). Also don't store the number of rows at the beginning of each table record. (CVS 1390)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:202a470f2c1804a96e69f16709d1a92e405971f0
User & Date: danielk1977 2004-05-18 01:23:38
Context
2004-05-18
01:31
Bugfix for row format. (CVS 1391) check-in: c1745f47 user: danielk1977 tags: trunk
01:23
Omit the '\0' at the end of UTF-8 strings on disk (it is implied). Also don't store the number of rows at the beginning of each table record. (CVS 1390) check-in: 202a470f user: danielk1977 tags: trunk
2004-05-17
10:48
More changes to support the new types model. Compound SELECTs are currently broken. (CVS 1389) check-in: 0f6c9b05 user: danielk1977 tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/build.c.

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
...
403
404
405
406
407
408
409

410
411
412
413
414
415
416
....
1720
1721
1722
1723
1724
1725
1726

1727
1728
1729
1730
1731
1732
1733
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**     PRAGMA
**
** $Id: build.c,v 1.185 2004/05/16 11:57:28 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Check to see if the schema for the database needs
................................................................................
** opened will be SQLITE_MASTER for persistent tables and 
** SQLITE_TEMP_MASTER for temporary tables.  The table is opened
** on cursor 0.
*/
void sqlite3OpenMasterTable(Vdbe *v, int isTemp){
  sqlite3VdbeAddOp(v, OP_Integer, isTemp, 0);
  sqlite3VdbeAddOp(v, OP_OpenWrite, 0, MASTER_ROOT);

}

/*
** Begin constructing a new table representation in memory.  This is
** the first of several action routines that get called in response
** to a CREATE TABLE statement.  In particular, this routine is called
** after seeing tokens "CREATE" and "TABLE" and the table name.  The
................................................................................
      sqlite3VdbeChangeP3(v, addr, pStart->z, n);
    }
    sqlite3VdbeAddOp(v, OP_MakeRecord, 5, 0);
    sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0);
    if( pTable ){
      sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
      sqlite3VdbeOp3(v, OP_OpenRead, 2, pTab->tnum, pTab->zName, 0);

      lbl2 = sqlite3VdbeMakeLabel(v);
      sqlite3VdbeAddOp(v, OP_Rewind, 2, lbl2);
      lbl1 = sqlite3VdbeAddOp(v, OP_Recno, 2, 0);
      for(i=0; i<pIndex->nColumn; i++){
        int iCol = pIndex->aiColumn[i];
        if( pTab->iPKey==iCol ){
          sqlite3VdbeAddOp(v, OP_Dup, i, 0);







|







 







>







 







>







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
...
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
....
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**     PRAGMA
**
** $Id: build.c,v 1.186 2004/05/18 01:23:38 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Check to see if the schema for the database needs
................................................................................
** opened will be SQLITE_MASTER for persistent tables and 
** SQLITE_TEMP_MASTER for temporary tables.  The table is opened
** on cursor 0.
*/
void sqlite3OpenMasterTable(Vdbe *v, int isTemp){
  sqlite3VdbeAddOp(v, OP_Integer, isTemp, 0);
  sqlite3VdbeAddOp(v, OP_OpenWrite, 0, MASTER_ROOT);
  sqlite3VdbeAddOp(v, OP_SetNumColumns, 0, 5); /* sqlite_master has 5 columns */
}

/*
** Begin constructing a new table representation in memory.  This is
** the first of several action routines that get called in response
** to a CREATE TABLE statement.  In particular, this routine is called
** after seeing tokens "CREATE" and "TABLE" and the table name.  The
................................................................................
      sqlite3VdbeChangeP3(v, addr, pStart->z, n);
    }
    sqlite3VdbeAddOp(v, OP_MakeRecord, 5, 0);
    sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0);
    if( pTable ){
      sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
      sqlite3VdbeOp3(v, OP_OpenRead, 2, pTab->tnum, pTab->zName, 0);
      sqlite3VdbeAddOp(v, OP_SetNumColumns, 2, pTab->nCol);
      lbl2 = sqlite3VdbeMakeLabel(v);
      sqlite3VdbeAddOp(v, OP_Rewind, 2, lbl2);
      lbl1 = sqlite3VdbeAddOp(v, OP_Recno, 2, 0);
      for(i=0; i<pIndex->nColumn; i++){
        int iCol = pIndex->aiColumn[i];
        if( pTab->iPKey==iCol ){
          sqlite3VdbeAddOp(v, OP_Dup, i, 0);

Changes to src/delete.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
169
170
171
172
173
174
175

176
177
178
179
180
181
182
...
226
227
228
229
230
231
232

233
234
235
236
237
238
239
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle DELETE FROM statements.
**
** $Id: delete.c,v 1.65 2004/05/16 11:15:37 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** Look up every table that is named in pSrc.  If any table is not found,
** add an error message to pParse->zErrMsg and return NULL.  If all tables
** are found, return a pointer to the last table.
................................................................................
      /* If counting rows deleted, just count the total number of
      ** entries in the table. */
      int endOfLoop = sqlite3VdbeMakeLabel(v);
      int addr;
      if( !isView ){
        sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
        sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum);

      }
      sqlite3VdbeAddOp(v, OP_Rewind, iCur, sqlite3VdbeCurrentAddr(v)+2);
      addr = sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
      sqlite3VdbeAddOp(v, OP_Next, iCur, addr);
      sqlite3VdbeResolveLabel(v, endOfLoop);
      sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
    }
................................................................................
    */
    if( row_triggers_exist ){
      addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, end);
      sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
      if( !isView ){
        sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
        sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum);

      }
      sqlite3VdbeAddOp(v, OP_MoveTo, iCur, 0);

      sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
      sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);
      sqlite3VdbeAddOp(v, OP_PutIntKey, oldIdx, 0);
      if( !isView ){







|







 







>







 







>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
...
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle DELETE FROM statements.
**
** $Id: delete.c,v 1.66 2004/05/18 01:23:38 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** Look up every table that is named in pSrc.  If any table is not found,
** add an error message to pParse->zErrMsg and return NULL.  If all tables
** are found, return a pointer to the last table.
................................................................................
      /* If counting rows deleted, just count the total number of
      ** entries in the table. */
      int endOfLoop = sqlite3VdbeMakeLabel(v);
      int addr;
      if( !isView ){
        sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
        sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum);
        sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, pTab->nCol);
      }
      sqlite3VdbeAddOp(v, OP_Rewind, iCur, sqlite3VdbeCurrentAddr(v)+2);
      addr = sqlite3VdbeAddOp(v, OP_AddImm, 1, 0);
      sqlite3VdbeAddOp(v, OP_Next, iCur, addr);
      sqlite3VdbeResolveLabel(v, endOfLoop);
      sqlite3VdbeAddOp(v, OP_Close, iCur, 0);
    }
................................................................................
    */
    if( row_triggers_exist ){
      addr = sqlite3VdbeAddOp(v, OP_ListRead, 0, end);
      sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
      if( !isView ){
        sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
        sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum);
        sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, pTab->nCol);
      }
      sqlite3VdbeAddOp(v, OP_MoveTo, iCur, 0);

      sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
      sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);
      sqlite3VdbeAddOp(v, OP_PutIntKey, oldIdx, 0);
      if( !isView ){

Changes to src/insert.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
303
304
305
306
307
308
309

310
311
312
313
314
315
316
...
997
998
999
1000
1001
1002
1003

1004
1005
1006
1007
1008
1009
1010
1011
1012
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
** $Id: insert.c,v 1.100 2004/05/17 10:48:58 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** Set P3 of the most recently inserted opcode to a column affinity
** string for index pIdx. A column affinity string has one character
** for each column in the table, according to the affinity of the column:
................................................................................

      /* The following code runs first because the GOTO at the very top
      ** of the program jumps to it.  Create the temporary table, then jump
      ** back up and execute the SELECT code above.
      */
      sqlite3VdbeChangeP2(v, iInitCode, sqlite3VdbeCurrentAddr(v));
      sqlite3VdbeAddOp(v, OP_OpenTemp, srcTab, 0);

      sqlite3VdbeAddOp(v, OP_Goto, 0, iSelectLoop);
      sqlite3VdbeResolveLabel(v, iCleanup);
    }else{
      sqlite3VdbeChangeP2(v, iInitCode, sqlite3VdbeCurrentAddr(v));
    }
  }else{
    /* This is the case if the data for the INSERT is coming from a VALUES
................................................................................
int sqlite3OpenTableAndIndices(Parse *pParse, Table *pTab, int base){
  int i;
  Index *pIdx;
  Vdbe *v = sqlite3GetVdbe(pParse);
  assert( v!=0 );
  sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
  sqlite3VdbeOp3(v, OP_OpenWrite, base, pTab->tnum, pTab->zName, P3_STATIC);

  for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
    sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
    sqlite3VdbeOp3(v, OP_OpenWrite, i+base, pIdx->tnum, pIdx->zName, P3_STATIC);
  }
  return i;
}










|







 







>







 







>









8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
...
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle INSERT statements in SQLite.
**
** $Id: insert.c,v 1.101 2004/05/18 01:23:38 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** Set P3 of the most recently inserted opcode to a column affinity
** string for index pIdx. A column affinity string has one character
** for each column in the table, according to the affinity of the column:
................................................................................

      /* The following code runs first because the GOTO at the very top
      ** of the program jumps to it.  Create the temporary table, then jump
      ** back up and execute the SELECT code above.
      */
      sqlite3VdbeChangeP2(v, iInitCode, sqlite3VdbeCurrentAddr(v));
      sqlite3VdbeAddOp(v, OP_OpenTemp, srcTab, 0);
      sqlite3VdbeAddOp(v, OP_SetNumColumns, srcTab, pTab->nCol);
      sqlite3VdbeAddOp(v, OP_Goto, 0, iSelectLoop);
      sqlite3VdbeResolveLabel(v, iCleanup);
    }else{
      sqlite3VdbeChangeP2(v, iInitCode, sqlite3VdbeCurrentAddr(v));
    }
  }else{
    /* This is the case if the data for the INSERT is coming from a VALUES
................................................................................
int sqlite3OpenTableAndIndices(Parse *pParse, Table *pTab, int base){
  int i;
  Index *pIdx;
  Vdbe *v = sqlite3GetVdbe(pParse);
  assert( v!=0 );
  sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
  sqlite3VdbeOp3(v, OP_OpenWrite, base, pTab->tnum, pTab->zName, P3_STATIC);
  sqlite3VdbeAddOp(v, OP_SetNumColumns, base, pTab->nCol);
  for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
    sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
    sqlite3VdbeOp3(v, OP_OpenWrite, i+base, pIdx->tnum, pIdx->zName, P3_STATIC);
  }
  return i;
}



Changes to src/pragma.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
576
577
578
579
580
581
582


583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
...
633
634
635
636
637
638
639

640
641
642
643
644
645
646
**    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.
**
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.23 2004/05/16 11:15:38 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Interpret the given string as a boolean value.
*/
................................................................................

    /* Code to do an BTree integrity check on a single database file.
    */
    static VdbeOpList checkDb[] = {
      { OP_SetInsert,   0, 0,        "1"},
      { OP_Integer,     0, 0,        0},    /* 1 */
      { OP_OpenRead,    0, MASTER_ROOT, 0},


      { OP_Rewind,      0, 7,        0},    /* 3 */
      { OP_Column,      0, 3,        0},    /* 4 */
      { OP_SetInsert,   0, 0,        0},
      { OP_Next,        0, 4,        0},    /* 6 */
      { OP_IntegrityCk, 0, 0,        0},    /* 7 */
      { OP_Dup,         0, 1,        0},
      { OP_String,      0, 0,        "ok"},
      { OP_StrEq,       0, 12,       0},    /* 10 */
      { OP_MemIncr,     0, 0,        0},
      { OP_String,      0, 0,        "*** in database "},
      { OP_String,      0, 0,        0},    /* 13 */
      { OP_String,      0, 0,        " ***\n"},
      { OP_Pull,        3, 0,        0},
      { OP_Concat,      4, 1,        0},
      { OP_Callback,    1, 0,        0},
    };

    /* Code that appears at the end of the integrity check.  If no error
................................................................................
        Table *pTab = sqliteHashData(x);
        Index *pIdx;
        int loopTop;

        if( pTab->pIndex==0 ) continue;
        sqlite3VdbeAddOp(v, OP_Integer, i, 0);
        sqlite3VdbeOp3(v, OP_OpenRead, 1, pTab->tnum, pTab->zName, 0);

        for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
          if( pIdx->tnum==0 ) continue;
          sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
          sqlite3VdbeOp3(v, OP_OpenRead, j+2, pIdx->tnum, pIdx->zName, 0);
        }
        sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
        sqlite3VdbeAddOp(v, OP_MemStore, 1, 1);







|







 







>
>
|
|

|
|


|


|







 







>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
...
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
**    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.
**
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.24 2004/05/18 01:23:38 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** Interpret the given string as a boolean value.
*/
................................................................................

    /* Code to do an BTree integrity check on a single database file.
    */
    static VdbeOpList checkDb[] = {
      { OP_SetInsert,   0, 0,        "1"},
      { OP_Integer,     0, 0,        0},    /* 1 */
      { OP_OpenRead,    0, MASTER_ROOT, 0},
      { OP_SetNumColumns,0,5,        0},    /* sqlite_master has 5 cols */

      { OP_Rewind,      0, 8,        0},    /* 4 */
      { OP_Column,      0, 3,        0},    /* 5 */
      { OP_SetInsert,   0, 0,        0},
      { OP_Next,        0, 5,        0},    /* 7 */
      { OP_IntegrityCk, 0, 0,        0},    /* 8 */
      { OP_Dup,         0, 1,        0},
      { OP_String,      0, 0,        "ok"},
      { OP_StrEq,       0, 13,       0},    /* 11 */
      { OP_MemIncr,     0, 0,        0},
      { OP_String,      0, 0,        "*** in database "},
      { OP_String,      0, 0,        0},    /* 14 */
      { OP_String,      0, 0,        " ***\n"},
      { OP_Pull,        3, 0,        0},
      { OP_Concat,      4, 1,        0},
      { OP_Callback,    1, 0,        0},
    };

    /* Code that appears at the end of the integrity check.  If no error
................................................................................
        Table *pTab = sqliteHashData(x);
        Index *pIdx;
        int loopTop;

        if( pTab->pIndex==0 ) continue;
        sqlite3VdbeAddOp(v, OP_Integer, i, 0);
        sqlite3VdbeOp3(v, OP_OpenRead, 1, pTab->tnum, pTab->zName, 0);
        sqlite3VdbeAddOp(v, OP_SetNumColumns, 1, pTab->nCol);
        for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
          if( pIdx->tnum==0 ) continue;
          sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
          sqlite3VdbeOp3(v, OP_OpenRead, j+2, pIdx->tnum, pIdx->zName, 0);
        }
        sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
        sqlite3VdbeAddOp(v, OP_MemStore, 1, 1);

Changes to src/select.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
1309
1310
1311
1312
1313
1314
1315

1316

1317
1318
1319
1320
1321
1322
1323
....
1900
1901
1902
1903
1904
1905
1906

1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919

1920
1921
1922
1923
1924
1925
1926
....
2240
2241
2242
2243
2244
2245
2246

2247
2248
2249
2250
2251
2252
2253
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.165 2004/05/17 10:48:58 danielk1977 Exp $
*/
#include "sqliteInt.h"


/*
** Allocate a new Select structure and return a pointer to that
** structure.
................................................................................
  */
  v = sqlite3GetVdbe(pParse);
  if( v==0 ) return 1;

  /* Create the destination temporary table if necessary
  */
  if( eDest==SRT_TempTable ){

    sqlite3VdbeAddOp(v, OP_OpenTemp, iParm, 0);

    eDest = SRT_Table;
  }

  /* Generate code for the left and right SELECT statements.
  */
  switch( p->op ){
    case TK_ALL: {
................................................................................
    generateColumnTypes(pParse, p->pSrc, p->pEList);
  }

  /* If the output is destined for a temporary table, open that table.
  */
  if( eDest==SRT_TempTable ){
    sqlite3VdbeAddOp(v, OP_OpenTemp, iParm, 0);

  }

  /* Generating code to find the min or the max.  Basically all we have
  ** to do is find the first or the last entry in the chosen index.  If
  ** the min() or max() is on the INTEGER PRIMARY KEY, then find the first
  ** or last entry in the main table.
  */
  sqlite3CodeVerifySchema(pParse, pTab->iDb);
  base = pSrc->a[0].iCursor;
  computeLimitRegisters(pParse, p);
  if( pSrc->a[0].pSelect==0 ){
    sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
    sqlite3VdbeOp3(v, OP_OpenRead, base, pTab->tnum, pTab->zName, 0);

  }
  cont = sqlite3VdbeMakeLabel(v);
  if( pIdx==0 ){
    sqlite3VdbeAddOp(v, seekOp, base, 0);
  }else{
    sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
    sqlite3VdbeOp3(v, OP_OpenRead, base+1, pIdx->tnum, pIdx->zName, P3_STATIC);
................................................................................
    generateColumnTypes(pParse, pTabList, pEList);
  }

  /* If the output is destined for a temporary table, open that table.
  */
  if( eDest==SRT_TempTable ){
    sqlite3VdbeAddOp(v, OP_OpenTemp, iParm, 0);

  }

  /* Do an analysis of aggregate expressions.
  */
  sqliteAggregateInfoReset(pParse);
  if( isAgg || pGroupBy ){
    assert( pParse->nAgg==0 );







|







 







>

>







 







>













>







 







>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
....
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
....
1902
1903
1904
1905
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
....
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements in SQLite.
**
** $Id: select.c,v 1.166 2004/05/18 01:23:38 danielk1977 Exp $
*/
#include "sqliteInt.h"


/*
** Allocate a new Select structure and return a pointer to that
** structure.
................................................................................
  */
  v = sqlite3GetVdbe(pParse);
  if( v==0 ) return 1;

  /* Create the destination temporary table if necessary
  */
  if( eDest==SRT_TempTable ){
    assert( p->pEList );
    sqlite3VdbeAddOp(v, OP_OpenTemp, iParm, 0);
    sqlite3VdbeAddOp(v, OP_SetNumColumns, iParm, p->pEList->nExpr);
    eDest = SRT_Table;
  }

  /* Generate code for the left and right SELECT statements.
  */
  switch( p->op ){
    case TK_ALL: {
................................................................................
    generateColumnTypes(pParse, p->pSrc, p->pEList);
  }

  /* If the output is destined for a temporary table, open that table.
  */
  if( eDest==SRT_TempTable ){
    sqlite3VdbeAddOp(v, OP_OpenTemp, iParm, 0);
    sqlite3VdbeAddOp(v, OP_SetNumColumns, iParm, 1);
  }

  /* Generating code to find the min or the max.  Basically all we have
  ** to do is find the first or the last entry in the chosen index.  If
  ** the min() or max() is on the INTEGER PRIMARY KEY, then find the first
  ** or last entry in the main table.
  */
  sqlite3CodeVerifySchema(pParse, pTab->iDb);
  base = pSrc->a[0].iCursor;
  computeLimitRegisters(pParse, p);
  if( pSrc->a[0].pSelect==0 ){
    sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
    sqlite3VdbeOp3(v, OP_OpenRead, base, pTab->tnum, pTab->zName, 0);
    sqlite3VdbeAddOp(v, OP_SetNumColumns, base, pTab->nCol);
  }
  cont = sqlite3VdbeMakeLabel(v);
  if( pIdx==0 ){
    sqlite3VdbeAddOp(v, seekOp, base, 0);
  }else{
    sqlite3VdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
    sqlite3VdbeOp3(v, OP_OpenRead, base+1, pIdx->tnum, pIdx->zName, P3_STATIC);
................................................................................
    generateColumnTypes(pParse, pTabList, pEList);
  }

  /* If the output is destined for a temporary table, open that table.
  */
  if( eDest==SRT_TempTable ){
    sqlite3VdbeAddOp(v, OP_OpenTemp, iParm, 0);
    sqlite3VdbeAddOp(v, OP_SetNumColumns, iParm, pEList->nExpr);
  }

  /* Do an analysis of aggregate expressions.
  */
  sqliteAggregateInfoReset(pParse);
  if( isAgg || pGroupBy ){
    assert( pParse->nAgg==0 );

Changes to src/update.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
254
255
256
257
258
259
260

261
262
263
264
265
266
267
...
309
310
311
312
313
314
315

316
317
318
319
320
321
322
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
**
** $Id: update.c,v 1.74 2004/05/16 11:15:39 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** Process an UPDATE statement.
**
**   UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
................................................................................
    /* Open a cursor and make it point to the record that is
    ** being updated.
    */
    sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
    if( !isView ){
      sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
      sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum);

    }
    sqlite3VdbeAddOp(v, OP_MoveTo, iCur, 0);

    /* Generate the OLD table
    */
    sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
    sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);
................................................................................
    ** Open every index that needs updating.  Note that if any
    ** index could potentially invoke a REPLACE conflict resolution 
    ** action, then we need to open all indices because we might need
    ** to be deleting some records.
    */
    sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
    sqlite3VdbeAddOp(v, OP_OpenWrite, iCur, pTab->tnum);

    if( onError==OE_Replace ){
      openAll = 1;
    }else{
      openAll = 0;
      for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
        if( pIdx->onError==OE_Replace ){
          openAll = 1;







|







 







>







 







>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
...
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle UPDATE statements.
**
** $Id: update.c,v 1.75 2004/05/18 01:23:38 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** Process an UPDATE statement.
**
**   UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
................................................................................
    /* Open a cursor and make it point to the record that is
    ** being updated.
    */
    sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
    if( !isView ){
      sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
      sqlite3VdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum);
      sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, pTab->nCol);
    }
    sqlite3VdbeAddOp(v, OP_MoveTo, iCur, 0);

    /* Generate the OLD table
    */
    sqlite3VdbeAddOp(v, OP_Recno, iCur, 0);
    sqlite3VdbeAddOp(v, OP_RowData, iCur, 0);
................................................................................
    ** Open every index that needs updating.  Note that if any
    ** index could potentially invoke a REPLACE conflict resolution 
    ** action, then we need to open all indices because we might need
    ** to be deleting some records.
    */
    sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
    sqlite3VdbeAddOp(v, OP_OpenWrite, iCur, pTab->tnum);
    sqlite3VdbeAddOp(v, OP_SetNumColumns, iCur, pTab->nCol);
    if( onError==OE_Replace ){
      openAll = 1;
    }else{
      openAll = 0;
      for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
        if( pIdx->onError==OE_Replace ){
          openAll = 1;

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
1987
1988
1989
1990
1991
1992
1993













1994
1995
1996
1997
1998
1999
2000
....
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
....
2034
2035
2036
2037
2038
2039
2040

2041
2042
2043
2044
2045
2046
2047
....
2063
2064
2065
2066
2067
2068
2069








2070
2071
2072
2073
2074
2075

2076
2077
2078
2079
2080
2081
2082
....
2084
2085
2086
2087
2088
2089
2090


2091
2092



2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
....
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
....
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
....
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
....
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.296 2004/05/17 10:48:58 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
      pTos->z = classes[i].zClass;
      break;
    }
  }
  assert( i<5 );
  break;
}














/* Opcode: Column P1 P2 *
**
** Interpret the data that cursor P1 points to as a structure built using
** the MakeRecord instruction.  (See the MakeRecord opcode for additional
** information about the format of the data.) Push onto the stack the value
** of the P2-th column contained in the data.
................................................................................
** just a pointer into the record which is stored further down on the
** stack.  The column value is not copied.
*/
case OP_Column: {
  int payloadSize;   /* Number of bytes in the record */
  int i = pOp->p1;
  int p2 = pOp->p2;  /* column number to retrieve */
  Cursor *pC;
  char *zRec;        /* Pointer to record-data from stack or pseudo-table. */
  BtCursor *pCrsr;

  char *zData;       
  int freeZdata = 0; /* zData requires sqliteFree() */

  u64 nField;        /* number of fields in the record */

  int len;           /* The length of the serialized data for the column */
  int offset;
  int nn;

  assert( i<p->nCursor );
  pTos++;

  /* This block sets the variable payloadSize, and if the data is coming
  ** from the stack or from a pseudo-table zRec. If the data is coming
................................................................................
  */
  if( i<0 ){
    assert( &pTos[i]>=p->aStack );
    assert( pTos[i].flags & MEM_Str );
    zRec = pTos[i].z;
    payloadSize = pTos[i].n;
    pC->cacheValid = 0;

  }else if( (pC = p->apCsr[i])->pCursor!=0 ){
    sqlite3VdbeCursorMoveto(pC);
    zRec = 0;
    pCrsr = pC->pCursor;
    if( pC->nullRow ){
      payloadSize = 0;
    }else if( pC->cacheValid ){
................................................................................
  }

  /* If payloadSize is 0, then just push a NULL onto the stack. */
  if( payloadSize==0 ){
    pTos->flags = MEM_Null;
    break;
  }









  /* Read and parse the table header.  Store the results of the parse
  ** into the record header cache fields of the cursor.
  */
  if( !pC->cacheValid ){
    pC->payloadSize = payloadSize;

    if( zRec ){
      zData = zRec;
    }else{
      /* We can assume that 10 bytes (maximum length of a varint) fits
      ** on the main page in all cases.
      */
      int n = 10;
................................................................................
      if( pC->keyAsData ){
        zData = (char *)sqlite3BtreeKeyFetch(pCrsr, n);
      }else{
        zData = (char *)sqlite3BtreeDataFetch(pCrsr, n);
      }
      assert( zData );
    }


    offset = sqlite3GetVarint(zData, &nField);
    if( nField>pC->nField ){



      sqliteFree(pC->aType);
      pC->aType = sqliteMallocRaw( nField*sizeof(pC->aType[0]) );
      if( pC->aType==0 ){
        goto no_mem;
      }
    }
    pC->nField = nField;

    if( !zRec ){
      /* If the record is stored in a table, see if enough of it is on
      ** the main page to use sqlite3BtreeDataFetch() to get the data
      ** containing the nField serial types (varints). This will almost
      ** always work, but if it doesn't sqliteMalloc() space and use
      ** sqlite3BtreeData().
................................................................................
  **   allocates it dynamically.
  */
  int nField = pOp->p1;
  unsigned char *zNewRecord;
  unsigned char *zCsr;
  char *zAffinity;
  Mem *pRec;
  int nBytes;    /* Space required for this record */

  Mem *pData0 = &pTos[1-nField];
  assert( pData0>=p->aStack );
  zAffinity = pOp->p3;

  /* Loop through the elements that will make up the record to figure
  ** out how much space is required for the new record.
  */
  nBytes = sqlite3VarintLen(nField);
  for(pRec=pData0; pRec<=pTos; pRec++){
    u64 serial_type;
    if( zAffinity ){
      applyAffinity(pRec, zAffinity[pRec-pData0]);
    }
    serial_type = sqlite3VdbeSerialType(pRec);
    nBytes += sqlite3VdbeSerialTypeLen(serial_type);
................................................................................
    rc = SQLITE_TOOBIG;
    goto abort_due_to_error;
  }

  /* Allocate space for the new record. */
  zNewRecord = sqliteMallocRaw(nBytes);
  if( !zNewRecord ){
    rc = SQLITE_NOMEM;
    goto abort_due_to_error;
  }

  /* Write the record */
  zCsr = zNewRecord;
  zCsr += sqlite3PutVarint(zCsr, nField);             /* number of fields */
  for(pRec=pData0; pRec<=pTos; pRec++){
    u64 serial_type = sqlite3VdbeSerialType(pRec);
    zCsr += sqlite3PutVarint(zCsr, serial_type);      /* serial type */
  }
  for(pRec=pData0; pRec<=pTos; pRec++){
    zCsr += sqlite3VdbeSerialPut(zCsr, pRec);  /* serial data */
  }
................................................................................
    rc = SQLITE_TOOBIG;
    goto abort_due_to_error;
  }

  /* Allocate space for the new key */
  zKey = (char *)sqliteMallocRaw(nByte);
  if( !zKey ){
    rc = SQLITE_NOMEM;
    goto abort_due_to_error;
  }
  
  /* Build the key in the buffer pointed to by zKey. */
  for(pRec=pData0; pRec<=pTos; pRec++){
    offset += sqlite3PutVarint(&zKey[offset], sqlite3VdbeSerialType(pRec));
    offset += sqlite3VdbeSerialPut(&zKey[offset], pRec);
  }
................................................................................
  len = sqlite3GetVarint(zData, &serial_type);
  n = sqlite3VdbeSerialTypeLen(serial_type);

  zData = (char *)sqlite3BtreeKeyFetch(pCsr, len+n);
  if( !zData ){
    zData = (char *)sqliteMalloc(n);
    if( !zData ){
      rc = SQLITE_NOMEM;
      goto abort_due_to_error;
    }
    rc = sqlite3BtreeKey(pCsr, len, n, zData);
    if( rc!=SQLITE_OK ){
      sqliteFree(zData);
      goto abort_due_to_error;
    }
    freeZData = 1;







|







 







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







 







|









|







 







>







 







>
>
>
>
>
>
>
>






>







 







>
>
|
|
>
>
>
|





<







 







|








|







 







|
<




|







 







|
<







 







|
<







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
....
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
....
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
....
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
....
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126

2127
2128
2129
2130
2131
2132
2133
....
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
....
2308
2309
2310
2311
2312
2313
2314
2315

2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
....
2443
2444
2445
2446
2447
2448
2449
2450

2451
2452
2453
2454
2455
2456
2457
....
3585
3586
3587
3588
3589
3590
3591
3592

3593
3594
3595
3596
3597
3598
3599
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.297 2004/05/18 01:23:38 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
      pTos->z = classes[i].zClass;
      break;
    }
  }
  assert( i<5 );
  break;
}

/* Opcode: SetNumColumns P1 P2 *
**
** Before the OP_Column opcode can be executed on a cursor, this
** opcode must be called to set the number of fields in the table.
**
** This opcode sets the number of columns for cursor P1 to P2.
*/
case OP_SetNumColumns: {
  assert( (pOp->p1)<p->nCursor );
  p->apCsr[pOp->p1]->nField = pOp->p2;
  break;
}

/* Opcode: Column P1 P2 *
**
** Interpret the data that cursor P1 points to as a structure built using
** the MakeRecord instruction.  (See the MakeRecord opcode for additional
** information about the format of the data.) Push onto the stack the value
** of the P2-th column contained in the data.
................................................................................
** just a pointer into the record which is stored further down on the
** stack.  The column value is not copied.
*/
case OP_Column: {
  int payloadSize;   /* Number of bytes in the record */
  int i = pOp->p1;
  int p2 = pOp->p2;  /* column number to retrieve */
  Cursor *pC = 0;
  char *zRec;        /* Pointer to record-data from stack or pseudo-table. */
  BtCursor *pCrsr;

  char *zData;       
  int freeZdata = 0; /* zData requires sqliteFree() */

  u64 nField;        /* number of fields in the record */

  int len;           /* The length of the serialized data for the column */
  int offset = 0;
  int nn;

  assert( i<p->nCursor );
  pTos++;

  /* This block sets the variable payloadSize, and if the data is coming
  ** from the stack or from a pseudo-table zRec. If the data is coming
................................................................................
  */
  if( i<0 ){
    assert( &pTos[i]>=p->aStack );
    assert( pTos[i].flags & MEM_Str );
    zRec = pTos[i].z;
    payloadSize = pTos[i].n;
    pC->cacheValid = 0;
    assert(!"broken for now");
  }else if( (pC = p->apCsr[i])->pCursor!=0 ){
    sqlite3VdbeCursorMoveto(pC);
    zRec = 0;
    pCrsr = pC->pCursor;
    if( pC->nullRow ){
      payloadSize = 0;
    }else if( pC->cacheValid ){
................................................................................
  }

  /* If payloadSize is 0, then just push a NULL onto the stack. */
  if( payloadSize==0 ){
    pTos->flags = MEM_Null;
    break;
  }

  /* If the row data is coming from a cursor, then OP_SetNumColumns must of
  ** been executed on that cursor. Also, p2 (the column to read) must be
  ** less than nField.
  */
  assert( !pC || pC->nField>0 );
  assert( p2<pC->nField );
  nField = pC->nField;

  /* Read and parse the table header.  Store the results of the parse
  ** into the record header cache fields of the cursor.
  */
  if( !pC->cacheValid ){
    pC->payloadSize = payloadSize;
#if 0
    if( zRec ){
      zData = zRec;
    }else{
      /* We can assume that 10 bytes (maximum length of a varint) fits
      ** on the main page in all cases.
      */
      int n = 10;
................................................................................
      if( pC->keyAsData ){
        zData = (char *)sqlite3BtreeKeyFetch(pCrsr, n);
      }else{
        zData = (char *)sqlite3BtreeDataFetch(pCrsr, n);
      }
      assert( zData );
    }
    {
      u64 x;
      offset = sqlite3GetVarint(zData, &x);
      assert( x==nField );
    }
#endif

    if( !pC->aType ){
      pC->aType = sqliteMallocRaw( nField*sizeof(pC->aType[0]) );
      if( pC->aType==0 ){
        goto no_mem;
      }
    }


    if( !zRec ){
      /* If the record is stored in a table, see if enough of it is on
      ** the main page to use sqlite3BtreeDataFetch() to get the data
      ** containing the nField serial types (varints). This will almost
      ** always work, but if it doesn't sqliteMalloc() space and use
      ** sqlite3BtreeData().
................................................................................
  **   allocates it dynamically.
  */
  int nField = pOp->p1;
  unsigned char *zNewRecord;
  unsigned char *zCsr;
  char *zAffinity;
  Mem *pRec;
  int nBytes = 0;    /* Space required for this record */

  Mem *pData0 = &pTos[1-nField];
  assert( pData0>=p->aStack );
  zAffinity = pOp->p3;

  /* Loop through the elements that will make up the record to figure
  ** out how much space is required for the new record.
  */
  // nBytes = sqlite3VarintLen(nField);
  for(pRec=pData0; pRec<=pTos; pRec++){
    u64 serial_type;
    if( zAffinity ){
      applyAffinity(pRec, zAffinity[pRec-pData0]);
    }
    serial_type = sqlite3VdbeSerialType(pRec);
    nBytes += sqlite3VdbeSerialTypeLen(serial_type);
................................................................................
    rc = SQLITE_TOOBIG;
    goto abort_due_to_error;
  }

  /* Allocate space for the new record. */
  zNewRecord = sqliteMallocRaw(nBytes);
  if( !zNewRecord ){
    goto no_mem;

  }

  /* Write the record */
  zCsr = zNewRecord;
  // zCsr += sqlite3PutVarint(zCsr, nField);             /* number of fields */
  for(pRec=pData0; pRec<=pTos; pRec++){
    u64 serial_type = sqlite3VdbeSerialType(pRec);
    zCsr += sqlite3PutVarint(zCsr, serial_type);      /* serial type */
  }
  for(pRec=pData0; pRec<=pTos; pRec++){
    zCsr += sqlite3VdbeSerialPut(zCsr, pRec);  /* serial data */
  }
................................................................................
    rc = SQLITE_TOOBIG;
    goto abort_due_to_error;
  }

  /* Allocate space for the new key */
  zKey = (char *)sqliteMallocRaw(nByte);
  if( !zKey ){
    goto no_mem;

  }
  
  /* Build the key in the buffer pointed to by zKey. */
  for(pRec=pData0; pRec<=pTos; pRec++){
    offset += sqlite3PutVarint(&zKey[offset], sqlite3VdbeSerialType(pRec));
    offset += sqlite3VdbeSerialPut(&zKey[offset], pRec);
  }
................................................................................
  len = sqlite3GetVarint(zData, &serial_type);
  n = sqlite3VdbeSerialTypeLen(serial_type);

  zData = (char *)sqlite3BtreeKeyFetch(pCsr, len+n);
  if( !zData ){
    zData = (char *)sqliteMalloc(n);
    if( !zData ){
      goto no_mem;

    }
    rc = sqlite3BtreeKey(pCsr, len, n, zData);
    if( rc!=SQLITE_OK ){
      sqliteFree(zData);
      goto abort_due_to_error;
    }
    freeZData = 1;

Changes to src/where.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
676
677
678
679
680
681
682

683
684
685
686
687
688
689
**    May you find forgiveness for yourself and forgive others.
**    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.
**
** $Id: where.c,v 1.95 2004/05/17 10:48:58 danielk1977 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.
................................................................................
    Index *pIx;

    pTab = pTabList->a[i].pTab;
    if( pTab->isTransient || pTab->pSelect ) continue;
    sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
    sqlite3VdbeOp3(v, OP_OpenRead, pTabList->a[i].iCursor, pTab->tnum,
                     pTab->zName, P3_STATIC);

    sqlite3CodeVerifySchema(pParse, pTab->iDb);
    if( (pIx = pWInfo->a[i].pIdx)!=0 ){
      sqlite3VdbeAddOp(v, OP_Integer, pIx->iDb, 0);
      sqlite3VdbeOp3(v, OP_OpenRead, pWInfo->a[i].iCur, pIx->tnum, pIx->zName,0);
    }
  }








|







 







>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
**    May you find forgiveness for yourself and forgive others.
**    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.
**
** $Id: where.c,v 1.96 2004/05/18 01:23:39 danielk1977 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.
................................................................................
    Index *pIx;

    pTab = pTabList->a[i].pTab;
    if( pTab->isTransient || pTab->pSelect ) continue;
    sqlite3VdbeAddOp(v, OP_Integer, pTab->iDb, 0);
    sqlite3VdbeOp3(v, OP_OpenRead, pTabList->a[i].iCursor, pTab->tnum,
                     pTab->zName, P3_STATIC);
    sqlite3VdbeAddOp(v, OP_SetNumColumns, pTabList->a[i].iCursor, pTab->nCol);
    sqlite3CodeVerifySchema(pParse, pTab->iDb);
    if( (pIx = pWInfo->a[i].pIdx)!=0 ){
      sqlite3VdbeAddOp(v, OP_Integer, pIx->iDb, 0);
      sqlite3VdbeOp3(v, OP_OpenRead, pWInfo->a[i].iCur, pIx->tnum, pIx->zName,0);
    }
  }