/ Check-in [e1370276]
Login

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

Overview
Comment:Remove cruft: restrict the number of sorters and lists in the VDBE to one since no more than one was ever used anyway. This eliminates several op-codes and simplifies the implementation of several others. (CVS 297)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:e1370276c2a0d045b29c981ddcb59f737e19a91c
User & Date: drh 2001-11-01 14:41:34
Context
2001-11-03
23:57
Added "const" to lots of "char*" parameters in the API. (CVS 298) check-in: 1c448f1f user: drh tags: trunk
2001-11-01
14:41
Remove cruft: restrict the number of sorters and lists in the VDBE to one since no more than one was ever used anyway. This eliminates several op-codes and simplifies the implementation of several others. (CVS 297) check-in: e1370276 user: drh tags: trunk
13:52
Comment changes only. (CVS 296) check-in: b2cb118f user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to README.

17
18
19
20
21
22
23










    make                     ;#  Run the makefile.

The configure script uses autoconf 2.50 and libtool.  If the configure
script does not work out for you, there is a generic makefile named
"Makefile.template" in the top directory of the source tree that you
can copy and edit to suite your needs.  Comments on the generic makefile
show what changes are needed.

















>
>
>
>
>
>
>
>
>
>
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
    make                     ;#  Run the makefile.

The configure script uses autoconf 2.50 and libtool.  If the configure
script does not work out for you, there is a generic makefile named
"Makefile.template" in the top directory of the source tree that you
can copy and edit to suite your needs.  Comments on the generic makefile
show what changes are needed.

The windows binaries on the website are created using MinGW32 configured
as a cross-compiler running under Linux.  For details, see the ./publish.sh
script at the top-level of the source tree.

Contacts:

   http://www.hwaci.com/sw/sqlite/
   http://groups.yahoo.com/group/sqlite/
   drh@hwaci.com

Changes to publish.sh.

86
87
88
89
90
91
92

93
94
95
96
97
98
99
100
101
102
103
104
zip sqlite.zip sqlite.exe

# Construct a tarball of the source tree
#
ORIGIN=`pwd`
cd $srcdir
cd ..

tar czf $ORIGIN/sqlite.tar.gz sqlite
cd $ORIGIN
vers=`cat $srcdir/VERSION`
rm -f sqlite-$vers.tar.gz
ln sqlite.tar.gz sqlite-$vers.tar.gz

# Build the website
#
cp $srcdir/../historical/* .
rm -rf doc
make doc
ln sqlite.bin.gz sqlite.zip sqlite*.tar.gz tclsqlite.so.gz tclsqlite.zip doc







>
|











86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
zip sqlite.zip sqlite.exe

# Construct a tarball of the source tree
#
ORIGIN=`pwd`
cd $srcdir
cd ..
EXCLUDE=`find sqlite -print | grep CVS | sed 's,sqlite/, --exclude sqlite/,'`
tar czf $ORIGIN/sqlite.tar.gz $EXCLUDE sqlite
cd $ORIGIN
vers=`cat $srcdir/VERSION`
rm -f sqlite-$vers.tar.gz
ln sqlite.tar.gz sqlite-$vers.tar.gz

# Build the website
#
cp $srcdir/../historical/* .
rm -rf doc
make doc
ln sqlite.bin.gz sqlite.zip sqlite*.tar.gz tclsqlite.so.gz tclsqlite.zip doc

Changes to src/delete.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
...
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
**    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.18 2001/10/15 00:44:36 drh Exp $
*/
#include "sqliteInt.h"

/*
** Process a DELETE FROM statement.
*/
void sqliteDeleteFrom(
................................................................................

  /* The usual case: There is a WHERE clause so we have to scan through
  ** the table an pick which records to delete.
  */
  else{
    /* Begin the database scan
    */
    sqliteVdbeAddOp(v, OP_ListOpen, 0, 0);
    pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 1);
    if( pWInfo==0 ) goto delete_from_cleanup;

    /* Remember the key of every item to be deleted.
    */
    sqliteVdbeAddOp(v, OP_ListWrite, 0, 0);
    if( db->flags & SQLITE_CountRows ){
................................................................................
        sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
        sqliteVdbeAddOp(v, OP_DeleteIdx, base+i, 0);
      }
    }
    sqliteVdbeAddOp(v, OP_Delete, base, 0);
    sqliteVdbeAddOp(v, OP_Goto, 0, addr);
    sqliteVdbeResolveLabel(v, end);
    sqliteVdbeAddOp(v, OP_ListClose, 0, 0);
  }
  if( (db->flags & SQLITE_InTrans)==0 ){
    sqliteVdbeAddOp(v, OP_Commit, 0, 0);
  }

  /*
  ** Return the number of rows that were deleted.







|







 







<







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
121
122
123
124
125
126
127

128
129
130
131
132
133
134
...
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
**    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.19 2001/11/01 14:41:34 drh Exp $
*/
#include "sqliteInt.h"

/*
** Process a DELETE FROM statement.
*/
void sqliteDeleteFrom(
................................................................................

  /* The usual case: There is a WHERE clause so we have to scan through
  ** the table an pick which records to delete.
  */
  else{
    /* Begin the database scan
    */

    pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 1);
    if( pWInfo==0 ) goto delete_from_cleanup;

    /* Remember the key of every item to be deleted.
    */
    sqliteVdbeAddOp(v, OP_ListWrite, 0, 0);
    if( db->flags & SQLITE_CountRows ){
................................................................................
        sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
        sqliteVdbeAddOp(v, OP_DeleteIdx, base+i, 0);
      }
    }
    sqliteVdbeAddOp(v, OP_Delete, base, 0);
    sqliteVdbeAddOp(v, OP_Goto, 0, addr);
    sqliteVdbeResolveLabel(v, end);
    sqliteVdbeAddOp(v, OP_ListReset, 0, 0);
  }
  if( (db->flags & SQLITE_InTrans)==0 ){
    sqliteVdbeAddOp(v, OP_Commit, 0, 0);
  }

  /*
  ** Return the number of rows that were deleted.

Changes to src/select.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
...
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
...
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
...
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
**    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.44 2001/10/22 02:58:10 drh Exp $
*/
#include "sqliteInt.h"

/*
** Allocate a new Select structure and return a pointer to that
** structure.
*/
................................................................................
  int end = sqliteVdbeMakeLabel(v);
  int addr;
  sqliteVdbeAddOp(v, OP_Sort, 0, 0);
  addr = sqliteVdbeAddOp(v, OP_SortNext, 0, end);
  sqliteVdbeAddOp(v, OP_SortCallback, nColumn, 0);
  sqliteVdbeAddOp(v, OP_Goto, 0, addr);
  sqliteVdbeResolveLabel(v, end);
  sqliteVdbeAddOp(v, OP_SortClose, 0, 0);
}

/*
** Generate code that will tell the VDBE how many columns there
** are in the result and the name for each column.  This information
** is used to provide "argc" and "azCol[]" values in the callback.
*/
................................................................................
      /* Convert the data in the temporary table into whatever form
      ** it is that we currently need.
      */      
      if( eDest!=priorOp ){
        int iCont, iBreak;
        assert( p->pEList );
        generateColumnNames(pParse, 0, p->pEList);
        if( p->pOrderBy ){
          sqliteVdbeAddOp(v, OP_SortOpen, 0, 0);
        }
        sqliteVdbeAddOp(v, OP_Rewind, unionTab, 0);
        iBreak = sqliteVdbeMakeLabel(v);
        iCont = sqliteVdbeAddOp(v, OP_Next, unionTab, iBreak);
        rc = selectInnerLoop(pParse, 0, unionTab, p->pEList->nExpr,
                             p->pOrderBy, -1, eDest, iParm, 
                             iCont, iBreak);
        if( rc ) return 1;
................................................................................
      if( rc ) return rc;

      /* Generate code to take the intersection of the two temporary
      ** tables.
      */
      assert( p->pEList );
      generateColumnNames(pParse, 0, p->pEList);
      if( p->pOrderBy ){
        sqliteVdbeAddOp(v, OP_SortOpen, 0, 0);
      }
      sqliteVdbeAddOp(v, OP_Rewind, tab1, 0);
      iBreak = sqliteVdbeMakeLabel(v);
      iCont = sqliteVdbeAddOp(v, OP_Next, tab1, iBreak);
      sqliteVdbeAddOp(v, OP_FullKey, tab1, 0);
      sqliteVdbeAddOp(v, OP_NotFound, tab2, iCont);
      rc = selectInnerLoop(pParse, 0, tab1, p->pEList->nExpr,
                             p->pOrderBy, -1, eDest, iParm, 
................................................................................
    }
  }

  /* Begin generating code.
  */
  v = sqliteGetVdbe(pParse);
  if( v==0 ) return 1;
  if( pOrderBy ){
    sqliteVdbeAddOp(v, OP_SortOpen, 0, 0);
  }

  /* Identify column names if we will be using in the callback.  This
  ** step is skipped if the output is going to a table or a memory cell.
  */
  if( eDest==SRT_Callback ){
    generateColumnNames(pParse, pTabList, pEList);
  }







|







 







|







 







<
<
<







 







<
<
<







 







<
<
<







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
...
547
548
549
550
551
552
553



554
555
556
557
558
559
560
...
598
599
600
601
602
603
604



605
606
607
608
609
610
611
...
849
850
851
852
853
854
855



856
857
858
859
860
861
862
**    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.45 2001/11/01 14:41:34 drh Exp $
*/
#include "sqliteInt.h"

/*
** Allocate a new Select structure and return a pointer to that
** structure.
*/
................................................................................
  int end = sqliteVdbeMakeLabel(v);
  int addr;
  sqliteVdbeAddOp(v, OP_Sort, 0, 0);
  addr = sqliteVdbeAddOp(v, OP_SortNext, 0, end);
  sqliteVdbeAddOp(v, OP_SortCallback, nColumn, 0);
  sqliteVdbeAddOp(v, OP_Goto, 0, addr);
  sqliteVdbeResolveLabel(v, end);
  sqliteVdbeAddOp(v, OP_SortReset, 0, 0);
}

/*
** Generate code that will tell the VDBE how many columns there
** are in the result and the name for each column.  This information
** is used to provide "argc" and "azCol[]" values in the callback.
*/
................................................................................
      /* Convert the data in the temporary table into whatever form
      ** it is that we currently need.
      */      
      if( eDest!=priorOp ){
        int iCont, iBreak;
        assert( p->pEList );
        generateColumnNames(pParse, 0, p->pEList);



        sqliteVdbeAddOp(v, OP_Rewind, unionTab, 0);
        iBreak = sqliteVdbeMakeLabel(v);
        iCont = sqliteVdbeAddOp(v, OP_Next, unionTab, iBreak);
        rc = selectInnerLoop(pParse, 0, unionTab, p->pEList->nExpr,
                             p->pOrderBy, -1, eDest, iParm, 
                             iCont, iBreak);
        if( rc ) return 1;
................................................................................
      if( rc ) return rc;

      /* Generate code to take the intersection of the two temporary
      ** tables.
      */
      assert( p->pEList );
      generateColumnNames(pParse, 0, p->pEList);



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

  /* Begin generating code.
  */
  v = sqliteGetVdbe(pParse);
  if( v==0 ) return 1;




  /* Identify column names if we will be using in the callback.  This
  ** step is skipped if the output is going to a table or a memory cell.
  */
  if( eDest==SRT_Callback ){
    generateColumnNames(pParse, pTabList, pEList);
  }

Changes to src/update.c.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
...
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
**    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.19 2001/10/15 00:44:36 drh Exp $
*/
#include "sqliteInt.h"

/*
** Process an UPDATE statement.
*/
void sqliteUpdate(
................................................................................
    sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
    sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
    pParse->schemaVerified = 1;
  }

  /* Begin the database scan
  */
  sqliteVdbeAddOp(v, OP_ListOpen, 0, 0);
  pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 1);
  if( pWInfo==0 ) goto update_cleanup;

  /* Remember the index of every item to be updated.
  */
  sqliteVdbeAddOp(v, OP_ListWrite, 0, 0);

................................................................................
  }

  /* Repeat the above with the next record to be updated, until
  ** all record selected by the WHERE clause have been updated.
  */
  sqliteVdbeAddOp(v, OP_Goto, 0, addr);
  sqliteVdbeResolveLabel(v, end);
  sqliteVdbeAddOp(v, OP_ListClose, 0, 0);
  if( (db->flags & SQLITE_InTrans)==0 ){
    sqliteVdbeAddOp(v, OP_Commit, 0, 0);
  }

  /*
  ** Return the number of rows that were changed.
  */







|







 







<







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
139
140
141
142
143
144
145

146
147
148
149
150
151
152
...
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
**    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.20 2001/11/01 14:41:34 drh Exp $
*/
#include "sqliteInt.h"

/*
** Process an UPDATE statement.
*/
void sqliteUpdate(
................................................................................
    sqliteVdbeAddOp(v, OP_Transaction, 0, 0);
    sqliteVdbeAddOp(v, OP_VerifyCookie, db->schema_cookie, 0);
    pParse->schemaVerified = 1;
  }

  /* Begin the database scan
  */

  pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 1);
  if( pWInfo==0 ) goto update_cleanup;

  /* Remember the index of every item to be updated.
  */
  sqliteVdbeAddOp(v, OP_ListWrite, 0, 0);

................................................................................
  }

  /* Repeat the above with the next record to be updated, until
  ** all record selected by the WHERE clause have been updated.
  */
  sqliteVdbeAddOp(v, OP_Goto, 0, addr);
  sqliteVdbeResolveLabel(v, end);
  sqliteVdbeAddOp(v, OP_ListReset, 0, 0);
  if( (db->flags & SQLITE_InTrans)==0 ){
    sqliteVdbeAddOp(v, OP_Commit, 0, 0);
  }

  /*
  ** Return the number of rows that were changed.
  */

Changes to src/vdbe.c.

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
...
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
...
713
714
715
716
717
718
719













720
721
722
723
724
725
726
...
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759

760
761
762
763
764
765
766
...
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
....
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192

3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
....
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
....
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378


3379
3380
3381
3382
3383
3384

3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
....
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
** 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.90 2001/11/01 13:52: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
................................................................................
  int tos;            /* Index of top of stack */
  int nStackAlloc;    /* Size of the stack */
  Stack *aStack;      /* The operand stack, except string values */
  char **zStack;      /* Text or binary values of the stack */
  char **azColName;   /* Becomes the 4th parameter to callbacks */
  int nCursor;        /* Number of slots in aCsr[] */
  Cursor *aCsr;       /* On element of this array for each open cursor */
  int nList;          /* Number of slots in apList[] */
  Keylist **apList;   /* For each Keylist */
  int nSort;          /* Number of slots in apSort[] */
  Sorter **apSort;    /* An open sorter list */
  FILE *pFile;        /* At most one open file handler */
  int nField;         /* Number of file fields */
  char **azField;     /* Data for each file field */
  char *zLine;        /* A single line from the input file */
  int nLineAlloc;     /* Number of spaces allocated for zLine */
  int nMem;           /* Number of memory locations currently allocated */
  Mem *aMem;          /* The memory locations */
................................................................................
  for(i=0; i<p->nCursor; i++){
    cleanupCursor(&p->aCsr[i]);
  }
  sqliteFree(p->aCsr);
  p->aCsr = 0;
  p->nCursor = 0;
}














/*
** Clean up the VM after execution.
**
** This routine will automatically close any cursors, lists, and/or
** sorters that were left open.
*/
................................................................................
    if( p->aMem[i].s.flags & STK_Dyn ){
      sqliteFree(p->aMem[i].z);
    }
  }
  sqliteFree(p->aMem);
  p->aMem = 0;
  p->nMem = 0;
  for(i=0; i<p->nList; i++){
    KeylistFree(p->apList[i]);
    p->apList[i] = 0;
  }
  sqliteFree(p->apList);
  p->apList = 0;
  p->nList = 0;
  for(i=0; i<p->nSort; i++){
    Sorter *pSorter;
    while( (pSorter = p->apSort[i])!=0 ){
      p->apSort[i] = pSorter->pNext;
      sqliteFree(pSorter->zKey);
      sqliteFree(pSorter->pData);
      sqliteFree(pSorter);
    }
  }
  sqliteFree(p->apSort);
  p->apSort = 0;
  p->nSort = 0;

  if( p->pFile ){
    if( p->pFile!=stdin ) fclose(p->pFile);
    p->pFile = 0;
  }
  if( p->azField ){
    sqliteFree(p->azField);
    p->azField = 0;
................................................................................
  "OpenWrite",         "OpenAux",           "OpenWrAux",         "Close",
  "MoveTo",            "Fcnt",              "NewRecno",          "Put",
  "Distinct",          "Found",             "NotFound",          "Delete",
  "Column",            "KeyAsData",         "Recno",             "FullKey",
  "Rewind",            "Next",              "Destroy",           "Clear",
  "CreateIndex",       "CreateTable",       "Reorganize",        "BeginIdx",
  "NextIdx",           "PutIdx",            "DeleteIdx",         "MemLoad",
  "MemStore",          "ListOpen",          "ListWrite",         "ListRewind",
  "ListRead",          "ListClose",         "SortOpen",          "SortPut",
  "SortMakeRec",       "SortMakeKey",       "Sort",              "SortNext",
  "SortKey",           "SortCallback",      "SortClose",         "FileOpen",
  "FileRead",          "FileColumn",        "FileClose",         "AggReset",
  "AggFocus",          "AggIncr",           "AggNext",           "AggSet",
  "AggGet",            "SetInsert",         "SetFound",          "SetNotFound",
  "SetClear",          "MakeRecord",        "MakeKey",           "MakeIdxKey",
  "Goto",              "If",                "Halt",              "ColumnCount",
  "ColumnName",        "Callback",          "NullCallback",      "Integer",
  "String",            "Null",              "Pop",               "Dup",
  "Pull",              "Add",               "AddImm",            "Subtract",
  "Multiply",          "Divide",            "Remainder",         "BitAnd",
  "BitOr",             "BitNot",            "ShiftLeft",         "ShiftRight",
  "AbsValue",          "Precision",         "Min",               "Max",
  "Like",              "Glob",              "Eq",                "Ne",
  "Lt",                "Le",                "Gt",                "Ge",
  "IsNull",            "NotNull",           "Negative",          "And",
  "Or",                "Not",               "Concat",            "Noop",
  "Strlen",            "Substr",          
};

/*
** Given the name of an opcode, return its number.  Return 0 if
** there is no match.
**
** This routine is used for testing and debugging.
................................................................................
** In the current implementation, this is a no-op.
*/
case OP_Reorganize: {
  /* This is currently a no-op */
  break;
}

/* Opcode: ListOpen P1 * *
**
** Open a "List" structure used for temporary storage of integer 
** record numbers.  P1 will server as a handle to this list for future
** interactions.  If another list with the P1 handle is
** already opened, the prior list is closed and a new one opened
** in its place.
*/
case OP_ListOpen: {
  int i = pOp->p1;
  VERIFY( if( i<0 ) goto bad_instruction; )
  if( i>=p->nList ){
    int j;
    Keylist **apList = sqliteRealloc( p->apList, (i+1)*sizeof(Keylist*) );
    if( apList==0 ){ goto no_mem; }
    p->apList = apList;
    for(j=p->nList; j<=i; j++) p->apList[j] = 0;
    p->nList = i+1;
  }else if( p->apList[i] ){
    KeylistFree(p->apList[i]);
    p->apList[i] = 0;
  }
  break;
}

/* Opcode: ListWrite P1 * *
**
** Write the integer on the top of the stack
** into the temporary storage list P1.
*/
case OP_ListWrite: {
  int i = pOp->p1;
  Keylist *pKeylist;
  VERIFY( if( i<0 || i>=p->nList ) goto bad_instruction; )
  VERIFY( if( p->tos<0 ) goto not_enough_stack; )
  pKeylist = p->apList[i];
  if( pKeylist==0 || pKeylist->nUsed>=pKeylist->nKey ){
    pKeylist = sqliteMalloc( sizeof(Keylist)+999*sizeof(pKeylist->aKey[0]) );
    if( pKeylist==0 ) goto no_mem;
    pKeylist->nKey = 1000;
    pKeylist->nRead = 0;
    pKeylist->nUsed = 0;
    pKeylist->pNext = p->apList[i];
    p->apList[i] = pKeylist;
  }
  Integerify(p, p->tos);
  pKeylist->aKey[pKeylist->nUsed++] = aStack[p->tos].i;
  POPSTACK;
  break;
}

/* Opcode: ListRewind P1 * *
**
** Rewind the temporary buffer P1 back to the beginning.
*/
case OP_ListRewind: {
  int i = pOp->p1;
  VERIFY( if( i<0 ) goto bad_instruction; )
  /* This is now a no-op */
  break;
}

/* Opcode: ListRead P1 P2 *
**
** Attempt to read an integer from temporary storage buffer P1
** and push it onto the stack.  If the storage buffer is empty, 
** push nothing but instead jump to P2.
*/
case OP_ListRead: {
  int i = pOp->p1;
  Keylist *pKeylist;
  VERIFY(if( i<0 || i>=p->nList ) goto bad_instruction;)
  pKeylist = p->apList[i];
  if( pKeylist!=0 ){
    VERIFY(
      if( pKeylist->nRead<0 
        || pKeylist->nRead>=pKeylist->nUsed
        || pKeylist->nRead>=pKeylist->nKey ) goto bad_instruction;
    )
    p->tos++;
    if( NeedStack(p, p->tos) ) goto no_mem;
    aStack[p->tos].i = pKeylist->aKey[pKeylist->nRead++];
    aStack[p->tos].flags = STK_Int;
    zStack[p->tos] = 0;
    if( pKeylist->nRead>=pKeylist->nUsed ){
      p->apList[i] = pKeylist->pNext;
      sqliteFree(pKeylist);
    }
  }else{
    pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: ListClose P1 * *
**
** Close the temporary storage buffer and discard its contents.
*/
case OP_ListClose: {
  int i = pOp->p1;
  VERIFY( if( i<0 ) goto bad_instruction; )
  VERIFY( if( i>=p->nList ) goto bad_instruction; )
  KeylistFree(p->apList[i]);
  p->apList[i] = 0;
  break;

}

/* Opcode: SortOpen P1 * *
**
** Create a new sorter with index P1
*/
case OP_SortOpen: {
  int i = pOp->p1;
  VERIFY( if( i<0 ) goto bad_instruction; )
  if( i>=p->nSort ){
    int j;
    Sorter **apSort = sqliteRealloc( p->apSort, (i+1)*sizeof(Sorter*) );
    if( apSort==0 ){ goto no_mem; }
    p->apSort = apSort;
    for(j=p->nSort; j<=i; j++) p->apSort[j] = 0;
    p->nSort = i+1;
  }
  break;
}

/* Opcode: SortPut P1 * *
**
** The TOS is the key and the NOS is the data.  Pop both from the stack
** and put them on the sorter.
*/
case OP_SortPut: {
  int i = pOp->p1;
  int tos = p->tos;
  int nos = tos - 1;
  Sorter *pSorter;
  VERIFY( if( i<0 || i>=p->nSort ) goto bad_instruction; )
  VERIFY( if( tos<1 ) goto not_enough_stack; )
  if( Stringify(p, tos) || Stringify(p, nos) ) goto no_mem;
  pSorter = sqliteMalloc( sizeof(Sorter) );
  if( pSorter==0 ) goto no_mem;
  pSorter->pNext = p->apSort[i];
  p->apSort[i] = pSorter;
  pSorter->nKey = aStack[tos].n;
  pSorter->zKey = zStack[tos];
  pSorter->nData = aStack[nos].n;
  pSorter->pData = zStack[nos];
  aStack[tos].flags = 0;
  aStack[nos].flags = 0;
  zStack[tos] = 0;
................................................................................
  p->tos++;
  aStack[p->tos].n = nByte;
  zStack[p->tos] = (char*)azArg;
  aStack[p->tos].flags = STK_Str|STK_Dyn;
  break;
}

/* Opcode: SortMakeKey P1 * P3
**
** Convert the top few entries of the stack into a sort key.  The
** number of stack entries consumed is the number of characters in 
** the string P3.  One character from P3 is prepended to each entry.
** The first character of P3 is prepended to the element lowest in
** the stack and the last character of P3 is appended to the top of
** the stack.  All stack entries are separated by a \000 character
................................................................................
  p->tos++;
  aStack[p->tos].n = nByte;
  aStack[p->tos].flags = STK_Str|STK_Dyn;
  zStack[p->tos] = zNewKey;
  break;
}

/* Opcode: Sort P1 * *
**
** Sort all elements on the given sorter.  The algorithm is a
** mergesort.
*/
case OP_Sort: {
  int j;
  j = pOp->p1;
  VERIFY( if( j<0 ) goto bad_instruction; )
  if( j<p->nSort ){
    int i;
    Sorter *pElem;
    Sorter *apSorter[NSORT];
    for(i=0; i<NSORT; i++){
      apSorter[i] = 0;
    }
    while( p->apSort[j] ){
      pElem = p->apSort[j];
      p->apSort[j] = pElem->pNext;
      pElem->pNext = 0;
      for(i=0; i<NSORT-1; i++){
        if( apSorter[i]==0 ){
          apSorter[i] = pElem;
          break;
        }else{
          pElem = Merge(apSorter[i], pElem);
          apSorter[i] = 0;
        }
      }
      if( i>=NSORT-1 ){
        apSorter[NSORT-1] = Merge(apSorter[NSORT-1],pElem);
      }
    }
    pElem = 0;
    for(i=0; i<NSORT; i++){
      pElem = Merge(apSorter[i], pElem);
    }
    p->apSort[j] = pElem;
  }
  break;
}

/* Opcode: SortNext P1 P2 *
**
** Push the data for the topmost element in the given sorter onto the
** stack, then remove the element from the sorter.


*/
case OP_SortNext: {
  int i = pOp->p1;
  VERIFY( if( i<0 ) goto bad_instruction; )
  if( VERIFY( i<p->nSort && ) p->apSort[i]!=0 ){
    Sorter *pSorter = p->apSort[i];

    p->apSort[i] = pSorter->pNext;
    p->tos++;
    VERIFY( NeedStack(p, p->tos); )
    zStack[p->tos] = pSorter->pData;
    aStack[p->tos].n = pSorter->nData;
    aStack[p->tos].flags = STK_Str|STK_Dyn;
    sqliteFree(pSorter->zKey);
    sqliteFree(pSorter);
  }else{
    pc = pOp->p2 - 1;
  }
  break;
}

#if 0 /* NOT USED */
/* Opcode: SortKey P1 * *
**
** Push the key for the topmost element of the sorter onto the stack.
** But don't change the sorter an any other way.
*/
case OP_SortKey: {
  int i = pOp->p1;
  VERIFY( if( i<0 ) goto bad_instruction; )
  if( i<p->nSort && p->apSort[i]!=0 ){
    Sorter *pSorter = p->apSort[i];
    p->tos++;
    VERIFY( NeedStack(p, p->tos); )
    sqliteSetString(&zStack[p->tos], pSorter->zKey, 0);
    aStack[p->tos].n = pSorter->nKey;
    aStack[p->tos].flags = STK_Str|STK_Dyn;
  }
  break;
}
#endif /* NOT USED */

/* Opcode: SortCallback P1 P2 *
**
** The top of the stack contains a callback record built using
** the SortMakeRec operation with the same P1 value as this
** instruction.  Pop this record from the stack and invoke the
** callback on it.
*/
case OP_SortCallback: {
................................................................................
    p->nCallback++;
  }
  POPSTACK;
  if( sqlite_malloc_failed ) goto no_mem;
  break;
}

/* Opcode: SortClose P1 * *
**
** Close the given sorter and remove all its elements.
*/
case OP_SortClose: {
  Sorter *pSorter;
  int i = pOp->p1;
  VERIFY( if( i<0 ) goto bad_instruction; )
  if( i<p->nSort ){
     while( (pSorter = p->apSort[i])!=0 ){
       p->apSort[i] = pSorter->pNext;
       sqliteFree(pSorter->zKey);
       sqliteFree(pSorter->pData);
       sqliteFree(pSorter);
     }
  }
  break;
}

/* Opcode: FileOpen * * P3
**
** Open the file named by P3 for reading using the FileRead opcode.
** If P3 is "stdin" then open standard input for reading.







|







 







|
|
<
<







 







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







 







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







 







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







 







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


|


<

<

|






|
|







|

|


<
<




|

|




<

<
|












|








|

|

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



|





<



<




|
|







 







|







 







|

|



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



|

|
|
>
>


<
<
<
|
>
|













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







 







|

|

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







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
...
183
184
185
186
187
188
189
190
191


192
193
194
195
196
197
198
...
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
...
745
746
747
748
749
750
751
752
753



754








755




756
757
758
759
760
761
762
763
...
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
841
842
843
844
845
846
847
....
3077
3078
3079
3080
3081
3082
3083

























3084
3085
3086
3087
3088
3089

3090

3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112


3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123

3124

3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152


3153


3154
3155
















3156
3157
3158
3159
3160
3161
3162
3163
3164

3165
3166
3167

3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
....
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
....
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282




3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310

3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321



3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337





















3338
3339
3340
3341
3342
3343
3344
3345
....
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364










3365
3366
3367
3368
3369
3370
3371
** 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
................................................................................
  int tos;            /* Index of top of stack */
  int nStackAlloc;    /* Size of the stack */
  Stack *aStack;      /* The operand stack, except string values */
  char **zStack;      /* Text or binary values of the stack */
  char **azColName;   /* Becomes the 4th parameter to callbacks */
  int nCursor;        /* Number of slots in aCsr[] */
  Cursor *aCsr;       /* On element of this array for each open cursor */
  Keylist *pList;     /* A list of ROWIDs */
  Sorter *pSort;      /* A linked list of objects to be sorted */


  FILE *pFile;        /* At most one open file handler */
  int nField;         /* Number of file fields */
  char **azField;     /* Data for each file field */
  char *zLine;        /* A single line from the input file */
  int nLineAlloc;     /* Number of spaces allocated for zLine */
  int nMem;           /* Number of memory locations currently allocated */
  Mem *aMem;          /* The memory locations */
................................................................................
  for(i=0; i<p->nCursor; i++){
    cleanupCursor(&p->aCsr[i]);
  }
  sqliteFree(p->aCsr);
  p->aCsr = 0;
  p->nCursor = 0;
}

/*
** Remove any elements that remain on the sorter for the VDBE given.
*/
static void SorterReset(Vdbe *p){
  while( p->pSort ){
    Sorter *pSorter = p->pSort;
    p->pSort = pSorter->pNext;
    sqliteFree(pSorter->zKey);
    sqliteFree(pSorter->pData);
    sqliteFree(pSorter);
  }
}

/*
** Clean up the VM after execution.
**
** This routine will automatically close any cursors, lists, and/or
** sorters that were left open.
*/
................................................................................
    if( p->aMem[i].s.flags & STK_Dyn ){
      sqliteFree(p->aMem[i].z);
    }
  }
  sqliteFree(p->aMem);
  p->aMem = 0;
  p->nMem = 0;
  if( p->pList ){
    KeylistFree(p->pList);



    p->pList = 0;








  }




  SorterReset(p);
  if( p->pFile ){
    if( p->pFile!=stdin ) fclose(p->pFile);
    p->pFile = 0;
  }
  if( p->azField ){
    sqliteFree(p->azField);
    p->azField = 0;
................................................................................
  "OpenWrite",         "OpenAux",           "OpenWrAux",         "Close",
  "MoveTo",            "Fcnt",              "NewRecno",          "Put",
  "Distinct",          "Found",             "NotFound",          "Delete",
  "Column",            "KeyAsData",         "Recno",             "FullKey",
  "Rewind",            "Next",              "Destroy",           "Clear",
  "CreateIndex",       "CreateTable",       "Reorganize",        "BeginIdx",
  "NextIdx",           "PutIdx",            "DeleteIdx",         "MemLoad",
  "MemStore",          "ListWrite",         "ListRewind",        "ListRead",
  "ListReset",         "SortPut",           "SortMakeRec",       "SortMakeKey",
  "Sort",              "SortNext",          "SortCallback",      "SortReset",

  "FileOpen",          "FileRead",          "FileColumn",        "FileClose",
  "AggReset",          "AggFocus",          "AggIncr",           "AggNext",
  "AggSet",            "AggGet",            "SetInsert",         "SetFound",
  "SetNotFound",       "SetClear",          "MakeRecord",        "MakeKey",
  "MakeIdxKey",        "Goto",              "If",                "Halt",
  "ColumnCount",       "ColumnName",        "Callback",          "NullCallback",
  "Integer",           "String",            "Null",              "Pop",
  "Dup",               "Pull",              "Add",               "AddImm",
  "Subtract",          "Multiply",          "Divide",            "Remainder",
  "BitAnd",            "BitOr",             "BitNot",            "ShiftLeft",
  "ShiftRight",        "AbsValue",          "Precision",         "Min",
  "Max",               "Like",              "Glob",              "Eq",
  "Ne",                "Lt",                "Le",                "Gt",
  "Ge",                "IsNull",            "NotNull",           "Negative",
  "And",               "Or",                "Not",               "Concat",
  "Noop",              "Strlen",            "Substr",          
};

/*
** Given the name of an opcode, return its number.  Return 0 if
** there is no match.
**
** This routine is used for testing and debugging.
................................................................................
** In the current implementation, this is a no-op.
*/
case OP_Reorganize: {
  /* This is currently a no-op */
  break;
}


























/* Opcode: ListWrite * * *
**
** Write the integer on the top of the stack
** into the temporary storage list.
*/
case OP_ListWrite: {

  Keylist *pKeylist;

  VERIFY( if( p->tos<0 ) goto not_enough_stack; )
  pKeylist = p->pList;
  if( pKeylist==0 || pKeylist->nUsed>=pKeylist->nKey ){
    pKeylist = sqliteMalloc( sizeof(Keylist)+999*sizeof(pKeylist->aKey[0]) );
    if( pKeylist==0 ) goto no_mem;
    pKeylist->nKey = 1000;
    pKeylist->nRead = 0;
    pKeylist->nUsed = 0;
    pKeylist->pNext = p->pList;
    p->pList = pKeylist;
  }
  Integerify(p, p->tos);
  pKeylist->aKey[pKeylist->nUsed++] = aStack[p->tos].i;
  POPSTACK;
  break;
}

/* Opcode: ListRewind * * *
**
** Rewind the temporary buffer back to the beginning.
*/
case OP_ListRewind: {


  /* This is now a no-op */
  break;
}

/* Opcode: ListRead * P2 *
**
** Attempt to read an integer from the temporary storage buffer
** and push it onto the stack.  If the storage buffer is empty, 
** push nothing but instead jump to P2.
*/
case OP_ListRead: {

  Keylist *pKeylist;

  pKeylist = p->pList;
  if( pKeylist!=0 ){
    VERIFY(
      if( pKeylist->nRead<0 
        || pKeylist->nRead>=pKeylist->nUsed
        || pKeylist->nRead>=pKeylist->nKey ) goto bad_instruction;
    )
    p->tos++;
    if( NeedStack(p, p->tos) ) goto no_mem;
    aStack[p->tos].i = pKeylist->aKey[pKeylist->nRead++];
    aStack[p->tos].flags = STK_Int;
    zStack[p->tos] = 0;
    if( pKeylist->nRead>=pKeylist->nUsed ){
      p->pList = pKeylist->pNext;
      sqliteFree(pKeylist);
    }
  }else{
    pc = pOp->p2 - 1;
  }
  break;
}

/* Opcode: ListReset * * *
**
** Reset the temporary storage buffer so that it holds nothing.
*/
case OP_ListReset: {
  if( p->pList ){


    KeylistFree(p->pList);


    p->pList = 0;
  }
















  break;
}

/* Opcode: SortPut * * *
**
** The TOS is the key and the NOS is the data.  Pop both from the stack
** and put them on the sorter.
*/
case OP_SortPut: {

  int tos = p->tos;
  int nos = tos - 1;
  Sorter *pSorter;

  VERIFY( if( tos<1 ) goto not_enough_stack; )
  if( Stringify(p, tos) || Stringify(p, nos) ) goto no_mem;
  pSorter = sqliteMalloc( sizeof(Sorter) );
  if( pSorter==0 ) goto no_mem;
  pSorter->pNext = p->pSort;
  p->pSort = pSorter;
  pSorter->nKey = aStack[tos].n;
  pSorter->zKey = zStack[tos];
  pSorter->nData = aStack[nos].n;
  pSorter->pData = zStack[nos];
  aStack[tos].flags = 0;
  aStack[nos].flags = 0;
  zStack[tos] = 0;
................................................................................
  p->tos++;
  aStack[p->tos].n = nByte;
  zStack[p->tos] = (char*)azArg;
  aStack[p->tos].flags = STK_Str|STK_Dyn;
  break;
}

/* Opcode: SortMakeKey * * P3
**
** Convert the top few entries of the stack into a sort key.  The
** number of stack entries consumed is the number of characters in 
** the string P3.  One character from P3 is prepended to each entry.
** The first character of P3 is prepended to the element lowest in
** the stack and the last character of P3 is appended to the top of
** the stack.  All stack entries are separated by a \000 character
................................................................................
  p->tos++;
  aStack[p->tos].n = nByte;
  aStack[p->tos].flags = STK_Str|STK_Dyn;
  zStack[p->tos] = zNewKey;
  break;
}

/* Opcode: Sort * * *
**
** Sort all elements on the sorter.  The algorithm is a
** mergesort.
*/
case OP_Sort: {




  int i;
  Sorter *pElem;
  Sorter *apSorter[NSORT];
  for(i=0; i<NSORT; i++){
    apSorter[i] = 0;
  }
  while( p->pSort ){
    pElem = p->pSort;
    p->pSort = pElem->pNext;
    pElem->pNext = 0;
    for(i=0; i<NSORT-1; i++){
    if( apSorter[i]==0 ){
        apSorter[i] = pElem;
        break;
      }else{
        pElem = Merge(apSorter[i], pElem);
        apSorter[i] = 0;
      }
    }
    if( i>=NSORT-1 ){
      apSorter[NSORT-1] = Merge(apSorter[NSORT-1],pElem);
    }
  }
  pElem = 0;
  for(i=0; i<NSORT; i++){
    pElem = Merge(apSorter[i], pElem);
  }
  p->pSort = pElem;

  break;
}

/* Opcode: SortNext * P2 *
**
** Push the data for the topmost element in the sorter onto the
** stack, then remove the element from the sorter.  If the sorter
** is empty, push nothing on the stack and instead jump immediately 
** to instruction P2.
*/
case OP_SortNext: {



  Sorter *pSorter = p->pSort;
  if( pSorter!=0 ){
    p->pSort = pSorter->pNext;
    p->tos++;
    VERIFY( NeedStack(p, p->tos); )
    zStack[p->tos] = pSorter->pData;
    aStack[p->tos].n = pSorter->nData;
    aStack[p->tos].flags = STK_Str|STK_Dyn;
    sqliteFree(pSorter->zKey);
    sqliteFree(pSorter);
  }else{
    pc = pOp->p2 - 1;
  }
  break;
}






















/* Opcode: SortCallback * P2 *
**
** The top of the stack contains a callback record built using
** the SortMakeRec operation with the same P1 value as this
** instruction.  Pop this record from the stack and invoke the
** callback on it.
*/
case OP_SortCallback: {
................................................................................
    p->nCallback++;
  }
  POPSTACK;
  if( sqlite_malloc_failed ) goto no_mem;
  break;
}

/* Opcode: SortReset * * *
**
** Remove any elements that remain on the sorter.
*/
case OP_SortReset: {
  SorterReset(p);










  break;
}

/* Opcode: FileOpen * * P3
**
** Open the file named by P3 for reading using the FileRead opcode.
** If P3 is "stdin" then open standard input for reading.

Changes to src/vdbe.h.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
107
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
*************************************************************************
** 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.30 2001/10/19 16:44:57 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines
................................................................................
#define OP_NextIdx            33
#define OP_PutIdx             34
#define OP_DeleteIdx          35

#define OP_MemLoad            36
#define OP_MemStore           37

#define OP_ListOpen           38
#define OP_ListWrite          39
#define OP_ListRewind         40
#define OP_ListRead           41
#define OP_ListClose          42

#define OP_SortOpen           43
#define OP_SortPut            44
#define OP_SortMakeRec        45
#define OP_SortMakeKey        46
#define OP_Sort               47
#define OP_SortNext           48
#define OP_SortKey            49
#define OP_SortCallback       50
#define OP_SortClose          51

#define OP_FileOpen           52
#define OP_FileRead           53
#define OP_FileColumn         54
#define OP_FileClose          55

#define OP_AggReset           56
#define OP_AggFocus           57
#define OP_AggIncr            58
#define OP_AggNext            59
#define OP_AggSet             60
#define OP_AggGet             61

#define OP_SetInsert          62
#define OP_SetFound           63
#define OP_SetNotFound        64
#define OP_SetClear           65

#define OP_MakeRecord         66
#define OP_MakeKey            67
#define OP_MakeIdxKey         68

#define OP_Goto               69
#define OP_If                 70
#define OP_Halt               71

#define OP_ColumnCount        72
#define OP_ColumnName         73
#define OP_Callback           74
#define OP_NullCallback       75

#define OP_Integer            76
#define OP_String             77
#define OP_Null               78
#define OP_Pop                79
#define OP_Dup                80
#define OP_Pull               81

#define OP_Add                82
#define OP_AddImm             83
#define OP_Subtract           84
#define OP_Multiply           85
#define OP_Divide             86
#define OP_Remainder          87
#define OP_BitAnd             88
#define OP_BitOr              89
#define OP_BitNot             90
#define OP_ShiftLeft          91
#define OP_ShiftRight         92
#define OP_AbsValue           93
#define OP_Precision          94
#define OP_Min                95
#define OP_Max                96
#define OP_Like               97
#define OP_Glob               98
#define OP_Eq                 99
#define OP_Ne                100
#define OP_Lt                101
#define OP_Le                102
#define OP_Gt                103
#define OP_Ge                104
#define OP_IsNull            105
#define OP_NotNull           106
#define OP_Negative          107
#define OP_And               108
#define OP_Or                109
#define OP_Not               110
#define OP_Concat            111
#define OP_Noop              112

#define OP_Strlen            113
#define OP_Substr            114

#define OP_MAX               114

/*
** Prototypes for the VDBE interface.  See comments on the implementation
** for a description of what each of these routines does.
*/
Vdbe *sqliteVdbeCreate(sqlite*);
void sqliteVdbeCreateCallback(Vdbe*, int*);







|







 







<
|
|
|
|

<
|
|
|
|
|
<
|
|

|
|
|
|

|
|
|
|
|
|

|
|
|
|

|
|
|

|
|
|

|
|
|
|

|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|

|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
...
107
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
*************************************************************************
** 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
................................................................................
#define OP_NextIdx            33
#define OP_PutIdx             34
#define OP_DeleteIdx          35

#define OP_MemLoad            36
#define OP_MemStore           37


#define OP_ListWrite          38
#define OP_ListRewind         39
#define OP_ListRead           40
#define OP_ListReset          41


#define OP_SortPut            42
#define OP_SortMakeRec        43
#define OP_SortMakeKey        44
#define OP_Sort               45
#define OP_SortNext           46

#define OP_SortCallback       47
#define OP_SortReset          48

#define OP_FileOpen           49
#define OP_FileRead           50
#define OP_FileColumn         51
#define OP_FileClose          52

#define OP_AggReset           53
#define OP_AggFocus           54
#define OP_AggIncr            55
#define OP_AggNext            56
#define OP_AggSet             57
#define OP_AggGet             58

#define OP_SetInsert          59
#define OP_SetFound           60
#define OP_SetNotFound        61
#define OP_SetClear           62

#define OP_MakeRecord         63
#define OP_MakeKey            64
#define OP_MakeIdxKey         65

#define OP_Goto               66
#define OP_If                 67
#define OP_Halt               68

#define OP_ColumnCount        69
#define OP_ColumnName         70
#define OP_Callback           71
#define OP_NullCallback       72

#define OP_Integer            73
#define OP_String             74
#define OP_Null               75
#define OP_Pop                76
#define OP_Dup                77
#define OP_Pull               78

#define OP_Add                79
#define OP_AddImm             80
#define OP_Subtract           81
#define OP_Multiply           82
#define OP_Divide             83
#define OP_Remainder          84
#define OP_BitAnd             85
#define OP_BitOr              86
#define OP_BitNot             87
#define OP_ShiftLeft          88
#define OP_ShiftRight         89
#define OP_AbsValue           90
#define OP_Precision          91
#define OP_Min                92
#define OP_Max                93
#define OP_Like               94
#define OP_Glob               95
#define OP_Eq                 96
#define OP_Ne                 97
#define OP_Lt                 98
#define OP_Le                 99
#define OP_Gt                100
#define OP_Ge                101
#define OP_IsNull            102
#define OP_NotNull           103
#define OP_Negative          104
#define OP_And               105
#define OP_Or                106
#define OP_Not               107
#define OP_Concat            108
#define OP_Noop              109

#define OP_Strlen            110
#define OP_Substr            111

#define OP_MAX               111

/*
** Prototypes for the VDBE interface.  See comments on the implementation
** for a description of what each of these routines does.
*/
Vdbe *sqliteVdbeCreate(sqlite*);
void sqliteVdbeCreateCallback(Vdbe*, int*);

Changes to www/changes.tcl.

15
16
17
18
19
20
21




22
23
24
25
26
27
28
proc chng {date desc} {
  puts "<DT><B>$date</B></DT>"
  puts "<DD><P><UL>$desc</UL></P></DD>"
}

chng {2001 Oct ?? (2.0.8)} {
<li>Documentation updates</li>




}

chng {2001 Oct 21 (2.0.7)} {
<li>Any UTF-8 character or ISO8859 character can be used as part of
    an identifier.</li>
<li>Patches from Christian Werner to improve ODBC compatibility and to
    fix a bug in the round() function.</li>







>
>
>
>







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
proc chng {date desc} {
  puts "<DT><B>$date</B></DT>"
  puts "<DD><P><UL>$desc</UL></P></DD>"
}

chng {2001 Oct ?? (2.0.8)} {
<li>Documentation updates</li>
<li>Simplify the design of the VDBE by restricting the number of sorters
    and lists to 1.
    In practice, no more than one sorter and one list was every used anyhow.
    </li>
}

chng {2001 Oct 21 (2.0.7)} {
<li>Any UTF-8 character or ISO8859 character can be used as part of
    an identifier.</li>
<li>Patches from Christian Werner to improve ODBC compatibility and to
    fix a bug in the round() function.</li>

Changes to www/index.tcl.

1
2
3
4
5
6
7
8
9
10
11
..
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
..
60
61
62
63
64
65
66
67
68


69
70
71
72
73
74
75
...
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
#
# Run this TCL script to generate HTML for the index.html file.
#
set rcsid {$Id: index.tcl,v 1.45 2001/10/31 15:44:47 drh Exp $}

puts {<html>
<head><title>SQLite: An SQL Database Engine In A C Library</title></head>
<body bgcolor=white>
<h1 align=center>SQLite: An SQL Database Engine In A C Library</h1>
<p align=center>}
puts "This page was last modified on [lrange $rcsid 3 4] GMT<br>"
................................................................................
set vers [lindex $argv 0]
puts "The latest SQLite version is <b>$vers</b>"
puts " created on [exec cat last_change] GMT"
puts {</p>}

puts {<h2>Introduction</h2>

<p>SQLite is a C library that implements an SQL database engine.
Programs that link with the SQLite library can have SQL database
access without running a separate RDBMS process.
The distribution comes with a standalone command-line
access program (<a href="sqlite.html">sqlite</a>) that can
be used to administer an SQLite database and which serves as
an example of how to use the SQLite library.</p>

................................................................................
}

puts {<h2>Current Status</h2>

<p>A <a href="changes.html">change history</a> is available online.
The latest source code is
<a href="download.html">available for download</a>.
There are currently no <em>known</em> memory leaks or debilitating bugs
in the library.


</p>

<p>
The file format used changed beginning with version 2.0.0.  Version 1.0.X
of SQLite used GDBM as its database backend.  Version 2.0.0 and later
use a built-in implementation of B-trees.  If you have older 1.0 databases
you will need to convert them before they can be read using a 2.0
................................................................................
$ cd bld
$ ../sqlite/configure
$ make                       <i> Builds "sqlite" and "libsqlite.a" </i>
$ make test                  <i> Optional: run regression tests </i>
</pre></blockquote>
}

puts {<h2>Command-line Usage Example</h2>

<p>Download the source archive and compile the <b>sqlite</b>
program as described above.  Then type:</p>

<blockquote><pre>
bash$ sqlite ~/newdb              <i>Directory ~/newdb created automatically</i>
sqlite> create table t1(
   ...>    a int,
   ...>    b varchar(20)
   ...>    c text
   ...> );                        <i>End each SQL statement with a ';'</i>
sqlite> insert into t1
   ...> values(1,'hi','y''all');
sqlite> select * from t1;
1|hello|world
sqlite> .mode columns             <i>Special commands begin with '.'</i>
sqlite> .header on                <i>Type ".help" for a list of commands</i>
sqlite> select * from t1;
a      b       c
------ ------- -------
1      hi      y'all
sqlite> .exit
base$
</pre></blockquote>
}
puts {<h2>Related Sites</h2>

<ul>

<li><p>An ODBC driver for SQLite can be found at
       <a href="http://www.ch-werner.de/sqliteodbc/">
       http://www.ch-werner.de/sqliteodbc/</a>.</p></li>



|







 







|







 







|

>
>







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
..
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
..
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
...
156
157
158
159
160
161
162


























163
164
165
166
167
168
169
#
# Run this TCL script to generate HTML for the index.html file.
#
set rcsid {$Id: index.tcl,v 1.46 2001/11/01 14:41:34 drh Exp $}

puts {<html>
<head><title>SQLite: An SQL Database Engine In A C Library</title></head>
<body bgcolor=white>
<h1 align=center>SQLite: An SQL Database Engine In A C Library</h1>
<p align=center>}
puts "This page was last modified on [lrange $rcsid 3 4] GMT<br>"
................................................................................
set vers [lindex $argv 0]
puts "The latest SQLite version is <b>$vers</b>"
puts " created on [exec cat last_change] GMT"
puts {</p>}

puts {<h2>Introduction</h2>

<p>SQLite is a C library that implements an embeddable SQL database engine.
Programs that link with the SQLite library can have SQL database
access without running a separate RDBMS process.
The distribution comes with a standalone command-line
access program (<a href="sqlite.html">sqlite</a>) that can
be used to administer an SQLite database and which serves as
an example of how to use the SQLite library.</p>

................................................................................
}

puts {<h2>Current Status</h2>

<p>A <a href="changes.html">change history</a> is available online.
The latest source code is
<a href="download.html">available for download</a>.
There are currently no known memory leaks or bugs
in the library.
SQLite is currently being used in several mission-critical
applications.
</p>

<p>
The file format used changed beginning with version 2.0.0.  Version 1.0.X
of SQLite used GDBM as its database backend.  Version 2.0.0 and later
use a built-in implementation of B-trees.  If you have older 1.0 databases
you will need to convert them before they can be read using a 2.0
................................................................................
$ cd bld
$ ../sqlite/configure
$ make                       <i> Builds "sqlite" and "libsqlite.a" </i>
$ make test                  <i> Optional: run regression tests </i>
</pre></blockquote>
}



























puts {<h2>Related Sites</h2>

<ul>

<li><p>An ODBC driver for SQLite can be found at
       <a href="http://www.ch-werner.de/sqliteodbc/">
       http://www.ch-werner.de/sqliteodbc/</a>.</p></li>

Changes to www/opcode.tcl.

1
2
3
4
5
6
7
8
9
10
11
...
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
#
# Run this Tcl script to generate the sqlite.html file.
#
set rcsid {$Id: opcode.tcl,v 1.6 2001/09/28 23:11:24 drh Exp $}

puts {<html>
<head>
  <title>SQLite Virtual Machine Opcodes</title>
</head>
<body bgcolor=white>
<h1 align=center>
................................................................................

<p>The virtual machine contains an arbitrary number of fixed memory
locations with addresses beginning at zero and growing upward.
Each memory location can hold an arbitrary string.  The memory
cells are typically used to hold the result of a scalar SELECT
that is part of a larger expression.</p>

<p>The virtual machine contains an arbitrary number of sorters.
Each sorter is able to accumulate records, sort those records,
then play the records back in sorted order.  Sorters are used
to implement the ORDER BY clause of a SELECT statement.  The
fact that the virtual machine allows multiple sorters is an
historical accident.  In practice no more than one sorter
(sorter number 0) ever gets used.</p>

<p>The virtual machine may contain an arbitrary number of "Lists".
Each list stores a list of integers.  Lists are used to hold the
rowids for records of a database table that needs to be modified.
The WHERE clause of an UPDATE or DELETE statement scans through
the table and writes the rowid of every record to be modified
into a list.  Then the list is played back and the table is modified
in a separate step.  It is necessary to do this in two steps since
making a change to a database table can alter the scan order.</p>

<p>The virtual machine can contain an arbitrary number of "Sets".
Each set holds an arbitrary number of strings.  Sets are used to
implement the IN operator with a constant right-hand side.</p>

<p>The virtual machine can open a single external file for reading.
This external read file is used to implement the COPY command.</p>



|







 







|
|
|
|
<
<
<

|
|



|
|
<







1
2
3
4
5
6
7
8
9
10
11
...
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
#
# Run this Tcl script to generate the sqlite.html file.
#
set rcsid {$Id: opcode.tcl,v 1.7 2001/11/01 14:41:34 drh Exp $}

puts {<html>
<head>
  <title>SQLite Virtual Machine Opcodes</title>
</head>
<body bgcolor=white>
<h1 align=center>
................................................................................

<p>The virtual machine contains an arbitrary number of fixed memory
locations with addresses beginning at zero and growing upward.
Each memory location can hold an arbitrary string.  The memory
cells are typically used to hold the result of a scalar SELECT
that is part of a larger expression.</p>

<p>The virtual machine contains a single sorter.
The sorter is able to accumulate records, sort those records,
then play the records back in sorted order.  The sorter is used
to implement the ORDER BY clause of a SELECT statement.</p>




<p>The virtual machine contains a single "Lists".
The list stores a list of integers.  Lists are used to hold the
rowids for records of a database table that needs to be modified.
The WHERE clause of an UPDATE or DELETE statement scans through
the table and writes the rowid of every record to be modified
into the list.  Then the list is played back and the table is modified
in a separate step.</p>


<p>The virtual machine can contain an arbitrary number of "Sets".
Each set holds an arbitrary number of strings.  Sets are used to
implement the IN operator with a constant right-hand side.</p>

<p>The virtual machine can open a single external file for reading.
This external read file is used to implement the COPY command.</p>