/ Check-in [9ac8399c]
Login

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

Overview
Comment:It runs. Simple tables can be created. INSERT and SELECT work. Much more testing is needed, however. (CVS 241)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:9ac8399c99cb996a382f3d49f45b6ca857adc827
User & Date: drh 2001-09-13 16:18:54
Context
2001-09-13
21:53
Many problems fixed. Many problems yet to go. (CVS 242) check-in: 62c7bd11 user: drh tags: trunk
16:18
It runs. Simple tables can be created. INSERT and SELECT work. Much more testing is needed, however. (CVS 241) check-in: 9ac8399c user: drh tags: trunk
15:21
The new Btree code runs, but it does not yet work. (CVS 240) check-in: 991ce811 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/build.c.

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
...
456
457
458
459
460
461
462








463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
...
534
535
536
537
538
539
540

541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
...
689
690
691
692
693
694
695








696
697
698
699
700
701
702
...
736
737
738
739
740
741
742

743
744
745
746
747
748
749
...
791
792
793
794
795
796
797

798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
**     DROP TABLE
**     CREATE INDEX
**     DROP INDEX
**     creating expressions and ID lists
**     COPY
**     VACUUM
**
** $Id: build.c,v 1.30 2001/09/13 14:46:10 drh Exp $
*/
#include "sqliteInt.h"

/*
** This routine is called after a single SQL statement has been
** parsed and we want to execute the VDBE code to implement 
** that statement.  Prior action routines should have already
................................................................................
    h = sqliteHashNoCase(p->zName, 0) % N_HASH;
    p->pHash = db->apTblHash[h];
    db->apTblHash[h] = p;
    pParse->pNewTable = 0;
    db->nTable++;
    db->flags |= SQLITE_InternChanges;
  }









  /* If not initializing, then create the table on disk.
  */
  if( !pParse->initFlag ){
    static VdbeOp addTable[] = {
      { OP_Open,        0, 2, 0},
      { OP_NewRecno,    0, 0, 0},
      { OP_String,      0, 0, "table"     },
      { OP_String,      0, 0, 0},            /* 3 */
      { OP_CreateTable, 0, 0, 0},
      { OP_String,      0, 0, 0},            /* 5 */
      { OP_String,      0, 0, 0},            /* 6 */
      { OP_MakeRecord,  4, 0, 0},
      { OP_Put,         0, 0, 0},
    };
    int n, base;
    Vdbe *v;

    v = sqliteGetVdbe(pParse);
    if( v==0 ) return;
................................................................................
  /* Generate code to remove the table from the master table
  ** on disk.
  */
  v = sqliteGetVdbe(pParse);
  if( v ){
    static VdbeOp dropTable[] = {
      { OP_Open,       0, 2,        0},

      { OP_String,     0, 0,        0}, /* 1 */
      { OP_Next,       0, ADDR(9),  0}, /* 2 */
      { OP_Dup,        0, 0,        0},
      { OP_Column,     0, 3,        0},
      { OP_Ne,         0, ADDR(2),  0},
      { OP_Recno,      0, 0,        0},
      { OP_Delete,     0, 0,        0},
      { OP_Goto,       0, ADDR(2),  0},
      { OP_Destroy,    0, 0,        0}, /* 9 */
      { OP_Close,      0, 0,        0},
    };
    Index *pIdx;
    if( (pParse->db->flags & SQLITE_InTrans)==0 ){
      sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
    }
    base = sqliteVdbeAddOpList(v, ArraySize(dropTable), dropTable);
    sqliteVdbeChangeP1(v, base+9, pTable->tnum);
    for(pIdx=pTable->pIndex; pIdx; pIdx=pIdx->pNext){
      sqliteVdbeAddOp(v, OP_Destroy, pIdx->tnum, 0, 0, 0);
    }
    if( (pParse->db->flags & SQLITE_InTrans)==0 ){
      sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0);
    }
  }
................................................................................
    h = sqliteHashNoCase(pIndex->zName, 0) % N_HASH;
    pIndex->pHash = db->apIdxHash[h];
    db->apIdxHash[h] = pIndex;
    pIndex->pNext = pTab->pIndex;
    pTab->pIndex = pIndex;
    db->flags |= SQLITE_InternChanges;
  }









  /* If the initFlag is 0 then create the index on disk.  This
  ** involves writing the index into the master table and filling in the
  ** index with the current table contents.
  **
  ** The initFlag is 0 when the user first enters a CREATE INDEX 
  ** command.  The initFlag is 1 when a database is opened and 
................................................................................
      sqliteVdbeChangeP3(v, base+3, pIndex->zName, 0);
      sqliteVdbeIndexRootAddr(v, &pIndex->tnum);
      sqliteVdbeChangeP3(v, base+5, pTab->zName, 0);
      sqliteVdbeChangeP3(v, base+6, pStart->z, n);
    }
    lbl1 = sqliteVdbeMakeLabel(v);
    lbl2 = sqliteVdbeMakeLabel(v);

    sqliteVdbeAddOp(v, OP_Next, 0, lbl2, 0, lbl1);
    sqliteVdbeAddOp(v, OP_Recno, 0, 0, 0, 0);
    for(i=0; i<pIndex->nColumn; i++){
      sqliteVdbeAddOp(v, OP_Column, 0, pIndex->aiColumn[i], 0, 0);
    }
    sqliteVdbeAddOp(v, OP_MakeIdxKey, pIndex->nColumn, 0, 0, 0);
    sqliteVdbeAddOp(v, OP_PutIdx, 1, 0, 0, 0);
................................................................................
  }

  /* Generate code to remove the index and from the master table */
  v = sqliteGetVdbe(pParse);
  if( v ){
    static VdbeOp dropIndex[] = {
      { OP_Open,       0, 2,       0},

      { OP_String,     0, 0,       0}, /* 1 */
      { OP_Next,       0, ADDR(8), 0}, /* 2 */
      { OP_Dup,        0, 0,       0},
      { OP_Column,     0, 1,       0},
      { OP_Ne,         0, ADDR(2), 0},
      { OP_Recno,      0, 0,       0},
      { OP_Delete,     0, 0,       0},
      { OP_Destroy,    0, 0,       0}, /* 8 */
      { OP_Close,      0, 0,       0},
    };
    int base;

    if( (db->flags & SQLITE_InTrans)==0 ){
      sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
    }
    base = sqliteVdbeAddOpList(v, ArraySize(dropIndex), dropIndex);
    sqliteVdbeChangeP1(v, base+8, pIndex->tnum);
    if( (db->flags & SQLITE_InTrans)==0 ){
      sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0);
    }
  }

  /* Mark the internal Index structure for deletion by the
  ** sqliteCommitInternalChanges routine.







|







 







>
>
>
>
>
>
>
>












|







 







>
|
|


|


|
|







|







 







>
>
>
>
>
>
>
>







 







>







 







>
|
|


|


|








|







29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
...
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
...
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
...
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
...
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
...
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
**     DROP TABLE
**     CREATE INDEX
**     DROP INDEX
**     creating expressions and ID lists
**     COPY
**     VACUUM
**
** $Id: build.c,v 1.31 2001/09/13 16:18:54 drh Exp $
*/
#include "sqliteInt.h"

/*
** This routine is called after a single SQL statement has been
** parsed and we want to execute the VDBE code to implement 
** that statement.  Prior action routines should have already
................................................................................
    h = sqliteHashNoCase(p->zName, 0) % N_HASH;
    p->pHash = db->apTblHash[h];
    db->apTblHash[h] = p;
    pParse->pNewTable = 0;
    db->nTable++;
    db->flags |= SQLITE_InternChanges;
  }

  /* If the initFlag is 1 it means we are reading the SQL off the
  ** "sqlite_master" table on the disk.  So do not write to the disk
  ** again.  Extract the table number from the pParse->newTnum field.
  */
  if( pParse->initFlag ){
    p->tnum = pParse->newTnum;
  }

  /* If not initializing, then create the table on disk.
  */
  if( !pParse->initFlag ){
    static VdbeOp addTable[] = {
      { OP_Open,        0, 2, 0},
      { OP_NewRecno,    0, 0, 0},
      { OP_String,      0, 0, "table"     },
      { OP_String,      0, 0, 0},            /* 3 */
      { OP_CreateTable, 0, 0, 0},
      { OP_String,      0, 0, 0},            /* 5 */
      { OP_String,      0, 0, 0},            /* 6 */
      { OP_MakeRecord,  5, 0, 0},
      { OP_Put,         0, 0, 0},
    };
    int n, base;
    Vdbe *v;

    v = sqliteGetVdbe(pParse);
    if( v==0 ) return;
................................................................................
  /* Generate code to remove the table from the master table
  ** on disk.
  */
  v = sqliteGetVdbe(pParse);
  if( v ){
    static VdbeOp dropTable[] = {
      { OP_Open,       0, 2,        0},
      { OP_Rewind,     0, 0,        0},
      { OP_String,     0, 0,        0}, /* 2 */
      { OP_Next,       0, ADDR(10), 0}, /* 3 */
      { OP_Dup,        0, 0,        0},
      { OP_Column,     0, 3,        0},
      { OP_Ne,         0, ADDR(3),  0},
      { OP_Recno,      0, 0,        0},
      { OP_Delete,     0, 0,        0},
      { OP_Goto,       0, ADDR(3),  0},
      { OP_Destroy,    0, 0,        0}, /* 10 */
      { OP_Close,      0, 0,        0},
    };
    Index *pIdx;
    if( (pParse->db->flags & SQLITE_InTrans)==0 ){
      sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
    }
    base = sqliteVdbeAddOpList(v, ArraySize(dropTable), dropTable);
    sqliteVdbeChangeP1(v, base+10, pTable->tnum);
    for(pIdx=pTable->pIndex; pIdx; pIdx=pIdx->pNext){
      sqliteVdbeAddOp(v, OP_Destroy, pIdx->tnum, 0, 0, 0);
    }
    if( (pParse->db->flags & SQLITE_InTrans)==0 ){
      sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0);
    }
  }
................................................................................
    h = sqliteHashNoCase(pIndex->zName, 0) % N_HASH;
    pIndex->pHash = db->apIdxHash[h];
    db->apIdxHash[h] = pIndex;
    pIndex->pNext = pTab->pIndex;
    pTab->pIndex = pIndex;
    db->flags |= SQLITE_InternChanges;
  }

  /* If the initFlag is 1 it means we are reading the SQL off the
  ** "sqlite_master" table on the disk.  So do not write to the disk
  ** again.  Extract the table number from the pParse->newTnum field.
  */
  if( pParse->initFlag ){
    pIndex->tnum = pParse->newTnum;
  }

  /* If the initFlag is 0 then create the index on disk.  This
  ** involves writing the index into the master table and filling in the
  ** index with the current table contents.
  **
  ** The initFlag is 0 when the user first enters a CREATE INDEX 
  ** command.  The initFlag is 1 when a database is opened and 
................................................................................
      sqliteVdbeChangeP3(v, base+3, pIndex->zName, 0);
      sqliteVdbeIndexRootAddr(v, &pIndex->tnum);
      sqliteVdbeChangeP3(v, base+5, pTab->zName, 0);
      sqliteVdbeChangeP3(v, base+6, pStart->z, n);
    }
    lbl1 = sqliteVdbeMakeLabel(v);
    lbl2 = sqliteVdbeMakeLabel(v);
    sqliteVdbeAddOp(v, OP_Rewind, 0, 0, 0, 0);
    sqliteVdbeAddOp(v, OP_Next, 0, lbl2, 0, lbl1);
    sqliteVdbeAddOp(v, OP_Recno, 0, 0, 0, 0);
    for(i=0; i<pIndex->nColumn; i++){
      sqliteVdbeAddOp(v, OP_Column, 0, pIndex->aiColumn[i], 0, 0);
    }
    sqliteVdbeAddOp(v, OP_MakeIdxKey, pIndex->nColumn, 0, 0, 0);
    sqliteVdbeAddOp(v, OP_PutIdx, 1, 0, 0, 0);
................................................................................
  }

  /* Generate code to remove the index and from the master table */
  v = sqliteGetVdbe(pParse);
  if( v ){
    static VdbeOp dropIndex[] = {
      { OP_Open,       0, 2,       0},
      { OP_Rewind,     0, 0,       0}, 
      { OP_String,     0, 0,       0}, /* 2 */
      { OP_Next,       0, ADDR(9), 0}, /* 3 */
      { OP_Dup,        0, 0,       0},
      { OP_Column,     0, 1,       0},
      { OP_Ne,         0, ADDR(3), 0},
      { OP_Recno,      0, 0,       0},
      { OP_Delete,     0, 0,       0},
      { OP_Destroy,    0, 0,       0}, /* 9 */
      { OP_Close,      0, 0,       0},
    };
    int base;

    if( (db->flags & SQLITE_InTrans)==0 ){
      sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
    }
    base = sqliteVdbeAddOpList(v, ArraySize(dropIndex), dropIndex);
    sqliteVdbeChangeP1(v, base+9, pIndex->tnum);
    if( (db->flags & SQLITE_InTrans)==0 ){
      sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0);
    }
  }

  /* Mark the internal Index structure for deletion by the
  ** sqliteCommitInternalChanges routine.

Changes to src/main.c.

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41


42
43
44
45
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
...
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
...
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
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.32 2001/09/13 15:21:32 drh Exp $
*/
#include "sqliteInt.h"
#if defined(HAVE_USLEEP) && HAVE_USLEEP
#include <unistd.h>
#endif

/*
** This is the callback routine for the code that initializes the
** database.  Each callback contains text of a CREATE TABLE or
** CREATE INDEX statement that must be parsed to yield the internal
** structures that describe the tables.
**


** This callback is also called with argc==2 when there is meta
** information in the sqlite_master file.  The meta information is
** contained in argv[1].  Typical meta information is the file format
** version.
*/
static int sqliteOpenCb(void *pDb, int argc, char **argv, char **azColName){
  sqlite *db = (sqlite*)pDb;
  Parse sParse;
  int nErr;

  if( argc==2 ){


    if( sscanf(argv[1],"file format %d",&db->file_format)==1 ){
      return 0;
    }
    /* Unknown meta information.  Ignore it. */
    return 0;
  }

  if( argc!=1 ) return 0;
  memset(&sParse, 0, sizeof(sParse));
  sParse.db = db;
  sParse.initFlag = 1;

  nErr = sqliteRunParser(&sParse, argv[0], 0);








  return nErr;
}

/*
** Attempt to read the database schema and initialize internal
** data structures.  Return one of the SQLITE_ error codes to
** indicate success or failure.
................................................................................
  ** table then goes back and invokes the callback on the
  ** SQL for each index.  The callback will invoke the
  ** parser to build the internal representation of the
  ** database scheme.
  */
  static VdbeOp initProg[] = {
    { OP_Open,     0, 2,  0},

    { OP_Next,     0, 9,  0},           /* 1 */
    { OP_Column,   0, 0,  0},
    { OP_String,   0, 0,  "meta"},
    { OP_Ne,       0, 1,  0},
    { OP_Column,   0, 0,  0},


    { OP_Column,   0, 4,  0},
    { OP_Callback, 2, 0,  0},
    { OP_Goto,     0, 1,  0},
    { OP_Rewind,   0, 0,  0},           /* 9 */
    { OP_Next,     0, 17, 0},           /* 10 */
    { OP_Column,   0, 0,  0},
    { OP_String,   0, 0,  "table"},
    { OP_Ne,       0, 10, 0},



    { OP_Column,   0, 4,  0},
    { OP_Callback, 1, 0,  0},
    { OP_Goto,     0, 10, 0},
    { OP_Rewind,   0, 0,  0},           /* 17 */
    { OP_Next,     0, 25, 0},           /* 18 */
    { OP_Column,   0, 0,  0},
    { OP_String,   0, 0,  "index"},
    { OP_Ne,       0, 18, 0},



    { OP_Column,   0, 4,  0},
    { OP_Callback, 1, 0,  0},
    { OP_Goto,     0, 18, 0},
    { OP_Close,    2, 0,  0},           /* 25 */
    { OP_Halt,     0, 0,  0},
  };

  /* Create a virtual machine to run the initialization program.  Run
  ** the program.  The delete the virtual machine.
  */
  vdbe = sqliteVdbeCreate(db);
................................................................................
    sqliteSetString(pzErrMsg, "out of memory");
    return SQLITE_NOMEM;
  }
  sqliteVdbeAddOpList(vdbe, sizeof(initProg)/sizeof(initProg[0]), initProg);
  rc = sqliteVdbeExec(vdbe, sqliteOpenCb, db, pzErrMsg, 
                      db->pBusyArg, db->xBusyCallback);
  sqliteVdbeDelete(vdbe);
  if( rc==SQLITE_OK && db->file_format<2 && db->nTable>0 ){
    sqliteSetString(pzErrMsg, "obsolete file format", 0);
    rc = SQLITE_ERROR;
  }
  if( rc==SQLITE_OK ){
    Table *pTab;
    char *azArg[2];



    azArg[0] = master_schema;
    azArg[1] = 0;
    sqliteOpenCb(db, 1, azArg, 0);
    pTab = sqliteFindTable(db, MASTER_NAME);
    if( pTab ){
      pTab->readOnly = 1;
      pTab->tnum = 2;
    }
    db->flags |= SQLITE_Initialized;
    sqliteCommitInternalChanges(db);
  }
  return rc;
}








|








|
<
<

>
>
|
|
|
<




|

|
>
>
|
<
<
|
<
|
>
|
|
|
|
>
|
>
>
>
>
>
>
>
>







 







>
|


|

>
>

|
|
|
|


|
>
>
>

|
|
|
|


|
>
>
>

|
|
|







 







|
|




|
>
>
>
|
|
|



<







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38


39
40
41
42
43
44

45
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
76
77
78
...
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
...
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
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.33 2001/09/13 16:18:54 drh Exp $
*/
#include "sqliteInt.h"
#if defined(HAVE_USLEEP) && HAVE_USLEEP
#include <unistd.h>
#endif

/*
** This is the callback routine for the code that initializes the
** database.  Each callback contains the following information:


**
**     argv[0] = "meta" or "table" or "index"
**     argv[1] = table or index name
**     argv[2] = root page number for table or index
**     argv[3] = SQL create statement for the table or index
**

*/
static int sqliteOpenCb(void *pDb, int argc, char **argv, char **azColName){
  sqlite *db = (sqlite*)pDb;
  Parse sParse;
  int nErr = 0;

  assert( argc==4 );
  switch( argv[0][0] ){
    case 'm': {  /* Meta information */
      sscanf(argv[1],"file format %d",&db->file_format);


      break;

    }
    case 'i':
    case 't': {  /* CREATE TABLE  and CREATE INDEX statements */
      memset(&sParse, 0, sizeof(sParse));
      sParse.db = db;
      sParse.initFlag = 1;
      sParse.newTnum = atoi(argv[2]);
      nErr = sqliteRunParser(&sParse, argv[3], 0);
      break;
    }
    default: {
      /* This can not happen! */
      nErr = 1;
      assert( nErr==0 );
    }
  }
  return nErr;
}

/*
** Attempt to read the database schema and initialize internal
** data structures.  Return one of the SQLITE_ error codes to
** indicate success or failure.
................................................................................
  ** table then goes back and invokes the callback on the
  ** SQL for each index.  The callback will invoke the
  ** parser to build the internal representation of the
  ** database scheme.
  */
  static VdbeOp initProg[] = {
    { OP_Open,     0, 2,  0},
    { OP_Rewind,   0, 0,  0},
    { OP_Next,     0, 12, 0},           /* 2 */
    { OP_Column,   0, 0,  0},
    { OP_String,   0, 0,  "meta"},
    { OP_Ne,       0, 2,  0},
    { OP_Column,   0, 0,  0},
    { OP_Column,   0, 1,  0},
    { OP_Column,   0, 2,  0},
    { OP_Column,   0, 4,  0},
    { OP_Callback, 4, 0,  0},
    { OP_Goto,     0, 2,  0},
    { OP_Rewind,   0, 0,  0},           /* 12 */
    { OP_Next,     0, 23, 0},           /* 13 */
    { OP_Column,   0, 0,  0},
    { OP_String,   0, 0,  "table"},
    { OP_Ne,       0, 13, 0},
    { OP_Column,   0, 0,  0},
    { OP_Column,   0, 1,  0},
    { OP_Column,   0, 2,  0},
    { OP_Column,   0, 4,  0},
    { OP_Callback, 4, 0,  0},
    { OP_Goto,     0, 13, 0},
    { OP_Rewind,   0, 0,  0},           /* 23 */
    { OP_Next,     0, 34, 0},           /* 24 */
    { OP_Column,   0, 0,  0},
    { OP_String,   0, 0,  "index"},
    { OP_Ne,       0, 24, 0},
    { OP_Column,   0, 0,  0},
    { OP_Column,   0, 1,  0},
    { OP_Column,   0, 2,  0},
    { OP_Column,   0, 4,  0},
    { OP_Callback, 4, 0,  0},
    { OP_Goto,     0, 24, 0},
    { OP_Close,    0, 0,  0},           /* 34 */
    { OP_Halt,     0, 0,  0},
  };

  /* Create a virtual machine to run the initialization program.  Run
  ** the program.  The delete the virtual machine.
  */
  vdbe = sqliteVdbeCreate(db);
................................................................................
    sqliteSetString(pzErrMsg, "out of memory");
    return SQLITE_NOMEM;
  }
  sqliteVdbeAddOpList(vdbe, sizeof(initProg)/sizeof(initProg[0]), initProg);
  rc = sqliteVdbeExec(vdbe, sqliteOpenCb, db, pzErrMsg, 
                      db->pBusyArg, db->xBusyCallback);
  sqliteVdbeDelete(vdbe);
  if( rc==SQLITE_OK && db->file_format>1 && db->nTable>0 ){
    sqliteSetString(pzErrMsg, "unsupported file format", 0);
    rc = SQLITE_ERROR;
  }
  if( rc==SQLITE_OK ){
    Table *pTab;
    char *azArg[5];
    azArg[0] = "table";
    azArg[1] = MASTER_NAME;
    azArg[2] = "2";
    azArg[3] = master_schema;
    azArg[4] = 0;
    sqliteOpenCb(db, 4, azArg, 0);
    pTab = sqliteFindTable(db, MASTER_NAME);
    if( pTab ){
      pTab->readOnly = 1;

    }
    db->flags |= SQLITE_Initialized;
    sqliteCommitInternalChanges(db);
  }
  return rc;
}

Changes to src/select.c.

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
...
545
546
547
548
549
550
551

552
553
554
555
556
557
558
...
597
598
599
600
601
602
603

604
605
606
607
608
609
610
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements.
**
** $Id: select.c,v 1.33 2001/09/13 14:46:10 drh Exp $
*/
#include "sqliteInt.h"

/*
** Allocate a new Select structure and return a pointer to that
** structure.
*/
................................................................................
      if( eDest!=priorOp ){
        int iCont, iBreak;
        assert( p->pEList );
        generateColumnNames(pParse, 0, p->pEList);
        if( p->pOrderBy ){
          sqliteVdbeAddOp(v, OP_SortOpen, 0, 0, 0, 0);
        }

        iBreak = sqliteVdbeMakeLabel(v);
        iCont = sqliteVdbeAddOp(v, OP_Next, unionTab, iBreak, 0, 0);
        rc = selectInnerLoop(pParse, 0, unionTab, p->pEList->nExpr,
                             p->pOrderBy, -1, eDest, iParm, 
                             iCont, iBreak);
        if( rc ) return 1;
        sqliteVdbeAddOp(v, OP_Goto, 0, iCont, 0, 0);
................................................................................
      ** tables.
      */
      assert( p->pEList );
      generateColumnNames(pParse, 0, p->pEList);
      if( p->pOrderBy ){
        sqliteVdbeAddOp(v, OP_SortOpen, 0, 0, 0, 0);
      }

      iBreak = sqliteVdbeMakeLabel(v);
      iCont = sqliteVdbeAddOp(v, OP_Next, tab1, iBreak, 0, 0);
      sqliteVdbeAddOp(v, OP_FullKey, tab1, 0, 0, 0);
      sqliteVdbeAddOp(v, OP_NotFound, tab2, iCont, 0, 0);
      rc = selectInnerLoop(pParse, 0, tab1, p->pEList->nExpr,
                             p->pOrderBy, -1, eDest, iParm, 
                             iCont, iBreak);







|







 







>







 







>







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
...
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
...
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements.
**
** $Id: select.c,v 1.34 2001/09/13 16:18:54 drh Exp $
*/
#include "sqliteInt.h"

/*
** Allocate a new Select structure and return a pointer to that
** structure.
*/
................................................................................
      if( eDest!=priorOp ){
        int iCont, iBreak;
        assert( p->pEList );
        generateColumnNames(pParse, 0, p->pEList);
        if( p->pOrderBy ){
          sqliteVdbeAddOp(v, OP_SortOpen, 0, 0, 0, 0);
        }
        sqliteVdbeAddOp(v, OP_Rewind, unionTab, 0, 0, 0);
        iBreak = sqliteVdbeMakeLabel(v);
        iCont = sqliteVdbeAddOp(v, OP_Next, unionTab, iBreak, 0, 0);
        rc = selectInnerLoop(pParse, 0, unionTab, p->pEList->nExpr,
                             p->pOrderBy, -1, eDest, iParm, 
                             iCont, iBreak);
        if( rc ) return 1;
        sqliteVdbeAddOp(v, OP_Goto, 0, iCont, 0, 0);
................................................................................
      ** tables.
      */
      assert( p->pEList );
      generateColumnNames(pParse, 0, p->pEList);
      if( p->pOrderBy ){
        sqliteVdbeAddOp(v, OP_SortOpen, 0, 0, 0, 0);
      }
      sqliteVdbeAddOp(v, OP_Rewind, tab1, 0, 0, 0);
      iBreak = sqliteVdbeMakeLabel(v);
      iCont = sqliteVdbeAddOp(v, OP_Next, tab1, iBreak, 0, 0);
      sqliteVdbeAddOp(v, OP_FullKey, tab1, 0, 0, 0);
      sqliteVdbeAddOp(v, OP_NotFound, tab2, iCont, 0, 0);
      rc = selectInnerLoop(pParse, 0, tab1, p->pEList->nExpr,
                             p->pOrderBy, -1, eDest, iParm, 
                             iCont, iBreak);

Changes to src/sqliteInt.h.

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
...
355
356
357
358
359
360
361

362
363
364
365
366
367
368
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.44 2001/09/13 14:46:10 drh Exp $
*/
#include "sqlite.h"
#include "vdbe.h"
#include "parse.h"
#include "btree.h"
#include <stdio.h>
#include <stdlib.h>
................................................................................
  Token sFirstToken;   /* The first token parsed */
  Token sLastToken;    /* The last token parsed */
  Table *pNewTable;    /* A table being constructed by CREATE TABLE */
  Vdbe *pVdbe;         /* An engine for executing database bytecode */
  int colNamesSet;     /* TRUE after OP_ColumnCount has been issued to pVdbe */
  int explain;         /* True if the EXPLAIN flag is found on the query */
  int initFlag;        /* True if reparsing CREATE TABLEs */

  int nErr;            /* Number of errors seen */
  int nTab;            /* Number of previously allocated cursors */
  int nMem;            /* Number of memory cells used so far */
  int nSet;            /* Number of sets used so far */
  int nAgg;            /* Number of aggregate expressions */
  AggExpr *aAgg;       /* An array of aggregate expressions */
  int iAggCount;       /* Index of the count(*) aggregate in aAgg[] */







|







 







>







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
...
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.45 2001/09/13 16:18:54 drh Exp $
*/
#include "sqlite.h"
#include "vdbe.h"
#include "parse.h"
#include "btree.h"
#include <stdio.h>
#include <stdlib.h>
................................................................................
  Token sFirstToken;   /* The first token parsed */
  Token sLastToken;    /* The last token parsed */
  Table *pNewTable;    /* A table being constructed by CREATE TABLE */
  Vdbe *pVdbe;         /* An engine for executing database bytecode */
  int colNamesSet;     /* TRUE after OP_ColumnCount has been issued to pVdbe */
  int explain;         /* True if the EXPLAIN flag is found on the query */
  int initFlag;        /* True if reparsing CREATE TABLEs */
  int newTnum;         /* Table number to use when reparsing CREATE TABLEs */
  int nErr;            /* Number of errors seen */
  int nTab;            /* Number of previously allocated cursors */
  int nMem;            /* Number of memory cells used so far */
  int nSet;            /* Number of sets used so far */
  int nAgg;            /* Number of aggregate expressions */
  AggExpr *aAgg;       /* An array of aggregate expressions */
  int iAggCount;       /* Index of the count(*) aggregate in aAgg[] */

Changes to src/vdbe.c.

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
....
1794
1795
1796
1797
1798
1799
1800


1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
....
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
....
2334
2335
2336
2337
2338
2339
2340

2341
2342
2343
2344
2345
2346
2347
** inplicit conversion from one 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.62 2001/09/13 15:21:32 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
................................................................................
  }
  nByte += sizeof(int)*nField;
  zNewRecord = sqliteMalloc( nByte );
  if( zNewRecord==0 ) goto no_mem;
  j = 0;
  addr = sizeof(int)*nField;
  for(i=p->tos-nField+1; i<=p->tos; i++){


    if( (aStack[i].flags & STK_Null)==0 ){
      addr += aStack[i].n;
    }
    memcpy(&zNewRecord[j], (char*)&addr, sizeof(int));
    j += sizeof(int);
  }
  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;
    }
  }
................................................................................
** 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;
  int aHdr[10];
  const int mxHdr = sizeof(aHdr)/sizeof(aHdr[0]);
  int i = pOp->p1;
  int p2 = pOp->p2;
  int tos = ++p->tos;
  BtCursor *pCrsr;
  char *z;

  VERIFY( if( NeedStack(p, tos) ) goto no_mem; )
................................................................................
    if( payloadSize < sizeof(int)*(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];

      offset = aHdr[p2];
      if( p2 == nCol-1 ){
        amt = payloadSize - offset;
      }else{
        amt = aHdr[p2+1] - offset;
      }
    }else{







|







 







>
>



<
<







 







|







 







>







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
....
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805


1806
1807
1808
1809
1810
1811
1812
....
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
....
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
** inplicit conversion from one 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.63 2001/09/13 16:18:54 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
................................................................................
  }
  nByte += sizeof(int)*nField;
  zNewRecord = sqliteMalloc( nByte );
  if( zNewRecord==0 ) goto no_mem;
  j = 0;
  addr = sizeof(int)*nField;
  for(i=p->tos-nField+1; i<=p->tos; i++){
    memcpy(&zNewRecord[j], (char*)&addr, sizeof(int));
    j += sizeof(int);
    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;
    }
  }
................................................................................
** 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;
  int aHdr[10];
  static const int mxHdr = sizeof(aHdr)/sizeof(aHdr[0]);
  int i = pOp->p1;
  int p2 = pOp->p2;
  int tos = ++p->tos;
  BtCursor *pCrsr;
  char *z;

  VERIFY( if( NeedStack(p, tos) ) goto no_mem; )
................................................................................
    if( payloadSize < sizeof(int)*(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(int);
      offset = aHdr[p2];
      if( p2 == nCol-1 ){
        amt = payloadSize - offset;
      }else{
        amt = aHdr[p2+1] - offset;
      }
    }else{

Changes to src/where.c.

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
...
354
355
356
357
358
359
360

361
362
363
364
365
366
367
**   http://www.hwaci.com/drh/
**
*************************************************************************
** 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.17 2001/09/13 14:46:11 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.
................................................................................
        sqliteVdbeAddOp(v, OP_MoveTo, base+idx, 0, 0, 0);
        haveKey = 0;
      }
    }else if( pIdx==0 ){
      /* Case 2:  There was no usable index.  We must do a complete
      ** scan of the table.
      */

      cont = sqliteVdbeMakeLabel(v);
      sqliteVdbeAddOp(v, OP_Next, base+idx, brk, 0, cont);
      haveKey = 0;
    }else{
      /* Case 3:  We do have a usable index in pIdx.
      */
      cont = sqliteVdbeMakeLabel(v);







|







 







>







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
...
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
**   http://www.hwaci.com/drh/
**
*************************************************************************
** 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.18 2001/09/13 16:18:55 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.
................................................................................
        sqliteVdbeAddOp(v, OP_MoveTo, base+idx, 0, 0, 0);
        haveKey = 0;
      }
    }else if( pIdx==0 ){
      /* Case 2:  There was no usable index.  We must do a complete
      ** scan of the table.
      */
      sqliteVdbeAddOp(v, OP_Rewind, base+idx, 0, 0, 0);
      cont = sqliteVdbeMakeLabel(v);
      sqliteVdbeAddOp(v, OP_Next, base+idx, brk, 0, cont);
      haveKey = 0;
    }else{
      /* Case 3:  We do have a usable index in pIdx.
      */
      cont = sqliteVdbeMakeLabel(v);