/ Check-in [01d85b35]
Login

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

Overview
Comment::-) (CVS 20)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 01d85b35e9c4ca5619ad21a4232a8f8bf9ec3538
User & Date: drh 2000-05-31 02:27:49
Context
2000-05-31
15:34
added aggregate functions like count(*) (CVS 21) check-in: dee7a8be user: drh tags: trunk
02:27
:-) (CVS 20) check-in: 01d85b35 user: drh tags: trunk
2000-05-30
20:17
:-) (CVS 19) check-in: 03725ce5 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to Makefile.in.

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

sqlite.html:	$(TOP)/www/sqlite.tcl
	tclsh $(TOP)/www/sqlite.tcl >sqlite.html

c_interface.html:	$(TOP)/www/c_interface.tcl
	tclsh $(TOP)/www/c_interface.tcl >c_interface.html




# Files to be published on the website.
#
PUBLISH = \
  sqlite.tar.gz \
  all.tar.gz \
  index.html \
  sqlite.html \

  c_interface.html

website:	$(PUBLISH)

publish:	$(PUBLISH)
	scp $(PUBLISH) hwaci@oak.he.net:public_html/sw/sqlite

clean:	
	rm -f *.o sqlite libsqlite.a sqlite.h
	rm -f lemon lempar.c parse.* sqlite.tar.gz
	rm -f $(PUBLISH)







>
>
>







>











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

sqlite.html:	$(TOP)/www/sqlite.tcl
	tclsh $(TOP)/www/sqlite.tcl >sqlite.html

c_interface.html:	$(TOP)/www/c_interface.tcl
	tclsh $(TOP)/www/c_interface.tcl >c_interface.html

changes.html:	$(TOP)/www/changes.tcl
	tclsh $(TOP)/www/changes.tcl >changes.html

# Files to be published on the website.
#
PUBLISH = \
  sqlite.tar.gz \
  all.tar.gz \
  index.html \
  sqlite.html \
  changes.html \
  c_interface.html

website:	$(PUBLISH)

publish:	$(PUBLISH)
	scp $(PUBLISH) hwaci@oak.he.net:public_html/sw/sqlite

clean:	
	rm -f *.o sqlite libsqlite.a sqlite.h
	rm -f lemon lempar.c parse.* sqlite.tar.gz
	rm -f $(PUBLISH)

Changes to src/build.c.

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
....
1524
1525
1526
1527
1528
1529
1530











































**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** This file contains C code routines that are called by the parser
** when syntax rules are reduced.
**
** $Id: build.c,v 1.9 2000/05/30 19:22:26 drh Exp $
*/
#include "sqliteInt.h"

/*
** This routine is called after a single SQL statement has been
** parsed and we want to execute the code to implement 
** the statement.  Prior action routines should have already
................................................................................
    sqliteVdbeAddOp(v, OP_Goto, 0, addr, 0, 0);
    sqliteVdbeAddOp(v, OP_Noop, 0, 0, 0, end);
  }
  
copy_cleanup:
  return;
}


















































|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
....
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** This file contains C code routines that are called by the parser
** when syntax rules are reduced.
**
** $Id: build.c,v 1.10 2000/05/31 02:27:49 drh Exp $
*/
#include "sqliteInt.h"

/*
** This routine is called after a single SQL statement has been
** parsed and we want to execute the code to implement 
** the statement.  Prior action routines should have already
................................................................................
    sqliteVdbeAddOp(v, OP_Goto, 0, addr, 0, 0);
    sqliteVdbeAddOp(v, OP_Noop, 0, 0, 0, end);
  }
  
copy_cleanup:
  return;
}

/*
** The non-standard VACUUM command is used to clean up the database,
** collapse free space, etc.  It is modelled after the VACUUM command
** in PostgreSQL.
*/
void sqliteVacuum(Parse *pParse, Token *pTableName){
  char *zName;
  Vdbe *v;

  if( pTableName ){
    zName = sqliteTableNameFromToken(pTableName);
  }else{
    zName = 0;
  }
  if( zName && sqliteFindIndex(pParse->db, zName)==0
    && sqliteFindTable(pParse->db, zName)==0 ){
    sqliteSetString(&pParse->zErrMsg, "no such table or index: ", zName, 0);
    pParse->nErr++;
    goto vacuum_cleanup;
  }
  v = pParse->pVdbe = sqliteVdbeCreate(pParse->db->pBe);
  if( v==0 ) goto vacuum_cleanup;
  if( zName ){
    sqliteVdbeAddOp(v, OP_Reorganize, 0, 0, zName, 0);
  }else{
    int h;
    Table *pTab;
    Index *pIdx;
    for(h=0; h<N_HASH; h++){
      for(pTab=pParse->db->apTblHash[h]; pTab; pTab=pTab->pHash){
        sqliteVdbeAddOp(v, OP_Reorganize, 0, 0, pTab->zName, 0);
        for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
          sqliteVdbeAddOp(v, OP_Reorganize, 0, 0, pIdx->zName, 0);
        }
      }
    }
  }

vacuum_cleanup:
  sqliteFree(zName);
  return;
}

Changes to src/dbbe.c.

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
...
194
195
196
197
198
199
200
















201
202
203
204
205
206
207
** sqlite and the code that does the actually reading and writing
** of information to the disk.
**
** This file uses GDBM as the database backend.  It should be
** relatively simple to convert to a different database such
** as NDBM, SDBM, or BerkeleyDB.
**
** $Id: dbbe.c,v 1.2 2000/05/30 18:45:24 drh Exp $
*/
#include "sqliteInt.h"
#include <gdbm.h>
#include <sys/stat.h>
#include <unistd.h>
#include <ctype.h>
#include <time.h>
................................................................................
void sqliteDbbeDropTable(Dbbe *pBe, const char *zTable){
  char *zFile;            /* Name of the table file */

  zFile = sqliteFileOfTable(pBe, zTable);
  unlink(zFile);
  sqliteFree(zFile);
}

















/*
** Close a table previously opened by sqliteDbbeOpenTable().
*/
void sqliteDbbeCloseTable(DbbeTable *pTable){
  BeFile *pFile;
  Dbbe *pBe;







|







 







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







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
...
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
** sqlite and the code that does the actually reading and writing
** of information to the disk.
**
** This file uses GDBM as the database backend.  It should be
** relatively simple to convert to a different database such
** as NDBM, SDBM, or BerkeleyDB.
**
** $Id: dbbe.c,v 1.3 2000/05/31 02:27:49 drh Exp $
*/
#include "sqliteInt.h"
#include <gdbm.h>
#include <sys/stat.h>
#include <unistd.h>
#include <ctype.h>
#include <time.h>
................................................................................
void sqliteDbbeDropTable(Dbbe *pBe, const char *zTable){
  char *zFile;            /* Name of the table file */

  zFile = sqliteFileOfTable(pBe, zTable);
  unlink(zFile);
  sqliteFree(zFile);
}

/*
** Reorganize a table to reduce search times and disk usage.
*/
void sqliteDbbeReorganizeTable(Dbbe *pBe, const char *zTable){
  char *zFile;            /* Name of the table file */
  DbbeTable *pTab;

  pTab = sqliteDbbeOpenTable(pBe, zTable, 1);
  if( pTab && pTab->pFile && pTab->pFile->dbf ){
    gdbm_reorganize(pTab->pFile->dbf);
  }
  if( pTab ){
    sqliteDbbeCloseTable(pTab);
  }
}

/*
** Close a table previously opened by sqliteDbbeOpenTable().
*/
void sqliteDbbeCloseTable(DbbeTable *pTable){
  BeFile *pFile;
  Dbbe *pBe;

Changes to src/dbbe.h.

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
..
60
61
62
63
64
65
66



67
68
69
70
71
72
73
** This file defines the interface to the database backend (Dbbe).
**
** The database backend is designed to be as general as possible
** so that it can easily be replaced by a different backend.
** This library was originally designed to support the following
** backends: GDBM, NDBM, SDBM, Berkeley DB.
**
** $Id: dbbe.h,v 1.1 2000/05/29 14:26:01 drh Exp $
*/
#ifndef _SQLITE_DBBE_H_
#define _SQLITE_DBBE_H_
#include <stdio.h>

/*
** The database backend supports two opaque structures.  A Dbbe is
................................................................................
/* Open a particular table of a previously opened database.
** Create the table if it doesn't already exist and writeable!=0.
*/
DbbeTable *sqliteDbbeOpenTable(Dbbe*, const char *zTableName, int writeable);

/* Delete a table from the database */
void sqliteDbbeDropTable(Dbbe*, const char *zTableName);




/* Close a table */
void sqliteDbbeCloseTable(DbbeTable*);

/* Fetch an entry from a table with the given key.  Return 1 if
** successful and 0 if no such entry exists.
*/







|







 







>
>
>







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
..
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
** This file defines the interface to the database backend (Dbbe).
**
** The database backend is designed to be as general as possible
** so that it can easily be replaced by a different backend.
** This library was originally designed to support the following
** backends: GDBM, NDBM, SDBM, Berkeley DB.
**
** $Id: dbbe.h,v 1.2 2000/05/31 02:27:49 drh Exp $
*/
#ifndef _SQLITE_DBBE_H_
#define _SQLITE_DBBE_H_
#include <stdio.h>

/*
** The database backend supports two opaque structures.  A Dbbe is
................................................................................
/* Open a particular table of a previously opened database.
** Create the table if it doesn't already exist and writeable!=0.
*/
DbbeTable *sqliteDbbeOpenTable(Dbbe*, const char *zTableName, int writeable);

/* Delete a table from the database */
void sqliteDbbeDropTable(Dbbe*, const char *zTableName);

/* Reorganize a table to speed access or reduce its disk usage */
void sqliteDbbeReorganizeTable(Dbbe*, const char *zTableName);

/* Close a table */
void sqliteDbbeCloseTable(DbbeTable*);

/* Fetch an entry from a table with the given key.  Return 1 if
** successful and 0 if no such entry exists.
*/

Changes to src/parse.y.

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
...
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
...
260
261
262
263
264
265
266


267
268
269
270
271
272
273
274
...
305
306
307
308
309
310
311



**
*************************************************************************
** This file contains SQLite's grammar for SQL.  Process this file
** using the lemon parser generator to generate C code that runs
** the parser.  Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
** @(#) $Id: parse.y,v 1.2 2000/05/30 16:27:04 drh Exp $
*/
%token_prefix TK_
%token_type {Token}
%extra_argument {Parse *pParse}
%syntax_error {
  sqliteSetNString(&pParse->zErrMsg,"syntax error near \"",0,TOKEN.z,TOKEN.n,
                   "\"", 1, 0);
................................................................................
fieldlist_opt(A) ::= .                    {A = 0;}
fieldlist_opt(A) ::= LP fieldlist(X) RP.  {A = X;}
fieldlist(A) ::= fieldlist(X) COMMA ID(Y). {A = sqliteIdListAppend(X,&Y);}
fieldlist(A) ::= ID(Y).                    {A = sqliteIdListAppend(0,&Y);}

%left OR.
%left AND.
%left EQ NE ISNULL NOTNULL IS.
%left GT GE LT LE.
%left PLUS MINUS.
%left STAR SLASH PERCENT.
%right NOT.

%type expr {Expr*}
%destructor expr {sqliteExprDelete($$);}
................................................................................
expr(A) ::= expr(X) OR expr(Y).    {A = sqliteExpr(TK_OR, X, Y, 0);}
expr(A) ::= expr(X) LT expr(Y).    {A = sqliteExpr(TK_LT, X, Y, 0);}
expr(A) ::= expr(X) GT expr(Y).    {A = sqliteExpr(TK_GT, X, Y, 0);}
expr(A) ::= expr(X) LE expr(Y).    {A = sqliteExpr(TK_LE, X, Y, 0);}
expr(A) ::= expr(X) GE expr(Y).    {A = sqliteExpr(TK_GE, X, Y, 0);}
expr(A) ::= expr(X) NE expr(Y).    {A = sqliteExpr(TK_NE, X, Y, 0);}
expr(A) ::= expr(X) EQ expr(Y).    {A = sqliteExpr(TK_EQ, X, Y, 0);}


expr(A) ::= expr(X) IS expr(Y).    {A = sqliteExpr(TK_EQ, X, Y, 0);}
expr(A) ::= expr(X) PLUS expr(Y).  {A = sqliteExpr(TK_PLUS, X, Y, 0);}
expr(A) ::= expr(X) MINUS expr(Y). {A = sqliteExpr(TK_MINUS, X, Y, 0);}
expr(A) ::= expr(X) STAR expr(Y).  {A = sqliteExpr(TK_STAR, X, Y, 0);}
expr(A) ::= expr(X) SLASH expr(Y). {A = sqliteExpr(TK_SLASH, X, Y, 0);}
expr(A) ::= expr(X) ISNULL.        {A = sqliteExpr(TK_ISNULL, X, 0, 0);}
expr(A) ::= expr(X) NOTNULL.       {A = sqliteExpr(TK_NOTNULL, X, 0, 0);}
expr(A) ::= NOT expr(X).           {A = sqliteExpr(TK_NOT, X, 0, 0);}
................................................................................

cmd ::= DROP INDEX id(X).       {sqliteDropIndex(pParse, &X);}

cmd ::= COPY id(X) FROM id(Y) USING DELIMITERS STRING(Z).
    {sqliteCopy(pParse,&X,&Y,&Z);}
cmd ::= COPY id(X) FROM id(Y).
    {sqliteCopy(pParse,&X,&Y,0);}










|







 







|







 







>
>
|







 







>
>
>
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
...
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
...
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
...
307
308
309
310
311
312
313
314
315
316
**
*************************************************************************
** This file contains SQLite's grammar for SQL.  Process this file
** using the lemon parser generator to generate C code that runs
** the parser.  Lemon will also generate a header file containing
** numeric codes for all of the tokens.
**
** @(#) $Id: parse.y,v 1.3 2000/05/31 02:27:49 drh Exp $
*/
%token_prefix TK_
%token_type {Token}
%extra_argument {Parse *pParse}
%syntax_error {
  sqliteSetNString(&pParse->zErrMsg,"syntax error near \"",0,TOKEN.z,TOKEN.n,
                   "\"", 1, 0);
................................................................................
fieldlist_opt(A) ::= .                    {A = 0;}
fieldlist_opt(A) ::= LP fieldlist(X) RP.  {A = X;}
fieldlist(A) ::= fieldlist(X) COMMA ID(Y). {A = sqliteIdListAppend(X,&Y);}
fieldlist(A) ::= ID(Y).                    {A = sqliteIdListAppend(0,&Y);}

%left OR.
%left AND.
%left EQ NE ISNULL NOTNULL IS LIKE GLOB.
%left GT GE LT LE.
%left PLUS MINUS.
%left STAR SLASH PERCENT.
%right NOT.

%type expr {Expr*}
%destructor expr {sqliteExprDelete($$);}
................................................................................
expr(A) ::= expr(X) OR expr(Y).    {A = sqliteExpr(TK_OR, X, Y, 0);}
expr(A) ::= expr(X) LT expr(Y).    {A = sqliteExpr(TK_LT, X, Y, 0);}
expr(A) ::= expr(X) GT expr(Y).    {A = sqliteExpr(TK_GT, X, Y, 0);}
expr(A) ::= expr(X) LE expr(Y).    {A = sqliteExpr(TK_LE, X, Y, 0);}
expr(A) ::= expr(X) GE expr(Y).    {A = sqliteExpr(TK_GE, X, Y, 0);}
expr(A) ::= expr(X) NE expr(Y).    {A = sqliteExpr(TK_NE, X, Y, 0);}
expr(A) ::= expr(X) EQ expr(Y).    {A = sqliteExpr(TK_EQ, X, Y, 0);}
expr(A) ::= expr(X) LIKE expr(Y).  {A = sqliteExpr(TK_LIKE, X, Y, 0);}
expr(A) ::= expr(X) GLOB expr(Y).   {A = sqliteExpr(TK_GLOB,X,Y,0);}
// expr(A) ::= expr(X) IS expr(Y).    {A = sqliteExpr(TK_EQ, X, Y, 0);}
expr(A) ::= expr(X) PLUS expr(Y).  {A = sqliteExpr(TK_PLUS, X, Y, 0);}
expr(A) ::= expr(X) MINUS expr(Y). {A = sqliteExpr(TK_MINUS, X, Y, 0);}
expr(A) ::= expr(X) STAR expr(Y).  {A = sqliteExpr(TK_STAR, X, Y, 0);}
expr(A) ::= expr(X) SLASH expr(Y). {A = sqliteExpr(TK_SLASH, X, Y, 0);}
expr(A) ::= expr(X) ISNULL.        {A = sqliteExpr(TK_ISNULL, X, 0, 0);}
expr(A) ::= expr(X) NOTNULL.       {A = sqliteExpr(TK_NOTNULL, X, 0, 0);}
expr(A) ::= NOT expr(X).           {A = sqliteExpr(TK_NOT, X, 0, 0);}
................................................................................

cmd ::= DROP INDEX id(X).       {sqliteDropIndex(pParse, &X);}

cmd ::= COPY id(X) FROM id(Y) USING DELIMITERS STRING(Z).
    {sqliteCopy(pParse,&X,&Y,&Z);}
cmd ::= COPY id(X) FROM id(Y).
    {sqliteCopy(pParse,&X,&Y,0);}

cmd ::= VACUUM.                {sqliteVacuum(pParse,0);}
cmd ::= VACUUM id(X).          {sqliteVacuum(pParse,&X);}

Changes to src/shell.c.

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
...
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
...
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** This file contains code to implement the "sqlite" command line
** utility for accessing SQLite databases.
**
** $Id: shell.c,v 1.3 2000/05/30 18:45:24 drh Exp $
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "sqlite.h"
#include <unistd.h>
#include <ctype.h>
................................................................................
    struct callback_data data;
    char *zErrMsg = 0;
    char zSql[1000];
    memcpy(&data, p, sizeof(data));
    data.showHeader = 0;
    data.mode = MODE_List;
    sprintf(zSql, "SELECT name FROM sqlite_master "
                  "WHERE type='index' AND tbl_name='%.00s' "
                  "ORDER BY name", azArg[1]);
    sqlite_exec(db, zSql, callback, &data, &zErrMsg);
    if( zErrMsg ){
      fprintf(stderr,"Error: %s\n", zErrMsg);
      free(zErrMsg);
    }
  }else
................................................................................
    struct callback_data data;
    char *zErrMsg = 0;
    char zSql[1000];
    memcpy(&data, p, sizeof(data));
    data.showHeader = 0;
    data.mode = MODE_List;
    if( nArg>1 ){
      sprintf(zSql, "SELECT sql FROM sqlite_master WHERE name='%.900s'",
         azArg[1]);
    }else{
      sprintf(zSql, "SELECT sql FROM sqlite_master "
         "ORDER BY tbl_name, type DESC, name");
    }
    sqlite_exec(db, zSql, callback, &data, &zErrMsg);
    if( zErrMsg ){







|







 







|







 







|







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
...
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
...
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** This file contains code to implement the "sqlite" command line
** utility for accessing SQLite databases.
**
** $Id: shell.c,v 1.4 2000/05/31 02:27:49 drh Exp $
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "sqlite.h"
#include <unistd.h>
#include <ctype.h>
................................................................................
    struct callback_data data;
    char *zErrMsg = 0;
    char zSql[1000];
    memcpy(&data, p, sizeof(data));
    data.showHeader = 0;
    data.mode = MODE_List;
    sprintf(zSql, "SELECT name FROM sqlite_master "
                  "WHERE type='index' AND tbl_name LIKE '%.00s' "
                  "ORDER BY name", azArg[1]);
    sqlite_exec(db, zSql, callback, &data, &zErrMsg);
    if( zErrMsg ){
      fprintf(stderr,"Error: %s\n", zErrMsg);
      free(zErrMsg);
    }
  }else
................................................................................
    struct callback_data data;
    char *zErrMsg = 0;
    char zSql[1000];
    memcpy(&data, p, sizeof(data));
    data.showHeader = 0;
    data.mode = MODE_List;
    if( nArg>1 ){
      sprintf(zSql, "SELECT sql FROM sqlite_master WHERE name LIKE '%.900s'",
         azArg[1]);
    }else{
      sprintf(zSql, "SELECT sql FROM sqlite_master "
         "ORDER BY tbl_name, type DESC, name");
    }
    sqlite_exec(db, zSql, callback, &data, &zErrMsg);
    if( zErrMsg ){

Changes to src/sqliteInt.h.

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
...
244
245
246
247
248
249
250



** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.3 2000/05/30 16:27:04 drh Exp $
*/
#include "sqlite.h"
#include "dbbe.h"
#include "vdbe.h"
#include "parse.h"
#include <gdbm.h>
#include <stdio.h>
................................................................................
WhereInfo *sqliteWhereBegin(Parse*, IdList*, Expr*, int);
void sqliteWhereEnd(WhereInfo*);
void sqliteExprCode(Parse*, Expr*);
void sqliteExprIfTrue(Parse*, Expr*, int);
void sqliteExprIfFalse(Parse*, Expr*, int);
Table *sqliteFindTable(sqlite*,char*);
void sqliteCopy(Parse*, Token*, Token*, Token*);










|







 







>
>
>
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
...
244
245
246
247
248
249
250
251
252
253
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.4 2000/05/31 02:27:49 drh Exp $
*/
#include "sqlite.h"
#include "dbbe.h"
#include "vdbe.h"
#include "parse.h"
#include <gdbm.h>
#include <stdio.h>
................................................................................
WhereInfo *sqliteWhereBegin(Parse*, IdList*, Expr*, int);
void sqliteWhereEnd(WhereInfo*);
void sqliteExprCode(Parse*, Expr*);
void sqliteExprIfTrue(Parse*, Expr*, int);
void sqliteExprIfFalse(Parse*, Expr*, int);
Table *sqliteFindTable(sqlite*,char*);
void sqliteCopy(Parse*, Token*, Token*, Token*);
void sqliteVacuum(Parse*, Token*);
int sqliteGlobCompare(const char*,const char*);
int sqliteLikeCompare(const unsigned char*,const unsigned char*);

Changes to src/tokenize.c.

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
..
60
61
62
63
64
65
66

67
68
69
70
71
72

73
74
75
76
77
78
79
80
81
82
83
84
85

86
87
88
89
90
91
92
*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that splits an SQL input string up into
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.3 2000/05/30 16:27:04 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include <stdlib.h>

/*
** All the keywords of the SQL language are stored as in a hash
................................................................................
  { "DEFAULT",           0, TK_DEFAULT,          0 },
  { "DELETE",            0, TK_DELETE,           0 },
  { "DELIMITERS",        0, TK_DELIMITERS,       0 },
  { "DESC",              0, TK_DESC,             0 },
  { "DROP",              0, TK_DROP,             0 },
  { "EXPLAIN",           0, TK_EXPLAIN,          0 },
  { "FROM",              0, TK_FROM,             0 },

  { "INDEX",             0, TK_INDEX,            0 },
  { "INSERT",            0, TK_INSERT,           0 },
  { "INTO",              0, TK_INTO,             0 },
  { "IS",                0, TK_IS,               0 },
  { "ISNULL",            0, TK_ISNULL,           0 },
  { "KEY",               0, TK_KEY,              0 },

  { "NOT",               0, TK_NOT,              0 },
  { "NOTNULL",           0, TK_NOTNULL,          0 },
  { "NULL",              0, TK_NULL,             0 },
  { "ON",                0, TK_ON,               0 },
  { "OR",                0, TK_OR,               0 },
  { "ORDER",             0, TK_ORDER,            0 },
  { "PRIMARY",           0, TK_PRIMARY,          0 },
  { "SELECT",            0, TK_SELECT,           0 },
  { "SET",               0, TK_SET,              0 },
  { "TABLE",             0, TK_TABLE,            0 },
  { "UNIQUE",            0, TK_UNIQUE,           0 },
  { "UPDATE",            0, TK_UPDATE,           0 },
  { "USING",             0, TK_USING,            0 },

  { "VALUES",            0, TK_VALUES,           0 },
  { "WHERE",             0, TK_WHERE,            0 },
};

/*
** This is the hash table
*/







|







 







>






>













>







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
..
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that splits an SQL input string up into
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.4 2000/05/31 02:27:49 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include <stdlib.h>

/*
** All the keywords of the SQL language are stored as in a hash
................................................................................
  { "DEFAULT",           0, TK_DEFAULT,          0 },
  { "DELETE",            0, TK_DELETE,           0 },
  { "DELIMITERS",        0, TK_DELIMITERS,       0 },
  { "DESC",              0, TK_DESC,             0 },
  { "DROP",              0, TK_DROP,             0 },
  { "EXPLAIN",           0, TK_EXPLAIN,          0 },
  { "FROM",              0, TK_FROM,             0 },
  { "GLOB",              0, TK_GLOB,             0 },
  { "INDEX",             0, TK_INDEX,            0 },
  { "INSERT",            0, TK_INSERT,           0 },
  { "INTO",              0, TK_INTO,             0 },
  { "IS",                0, TK_IS,               0 },
  { "ISNULL",            0, TK_ISNULL,           0 },
  { "KEY",               0, TK_KEY,              0 },
  { "LIKE",              0, TK_LIKE,             0 },
  { "NOT",               0, TK_NOT,              0 },
  { "NOTNULL",           0, TK_NOTNULL,          0 },
  { "NULL",              0, TK_NULL,             0 },
  { "ON",                0, TK_ON,               0 },
  { "OR",                0, TK_OR,               0 },
  { "ORDER",             0, TK_ORDER,            0 },
  { "PRIMARY",           0, TK_PRIMARY,          0 },
  { "SELECT",            0, TK_SELECT,           0 },
  { "SET",               0, TK_SET,              0 },
  { "TABLE",             0, TK_TABLE,            0 },
  { "UNIQUE",            0, TK_UNIQUE,           0 },
  { "UPDATE",            0, TK_UPDATE,           0 },
  { "USING",             0, TK_USING,            0 },
  { "VACUUM",            0, TK_VACUUM,           0 },
  { "VALUES",            0, TK_VALUES,           0 },
  { "WHERE",             0, TK_WHERE,            0 },
};

/*
** This is the hash table
*/

Changes to src/util.c.

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
...
559
560
561
562
563
564
565







































































































































**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.6 2000/05/30 16:27:04 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>

#ifdef MEMORY_DEBUG

................................................................................
      a += len;
      b += len;
    }
  }
  if( *a=='-' ) res = -res;
  return res;
}














































































































































|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
...
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.7 2000/05/31 02:27:49 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>

#ifdef MEMORY_DEBUG

................................................................................
      a += len;
      b += len;
    }
  }
  if( *a=='-' ) res = -res;
  return res;
}

/*
** Compare two strings for equality where the first string can
** potentially be a "glob" expression.  Return true (1) if they
** are the same and false (0) if they are different.
**
** Globbing rules:
**
**      '*'       Matches any sequence of zero or more characters.
**
**      '?'       Matches exactly one character.
**
**     [...]      Matches one character from the enclosed list of
**                characters.
**
**     [^...]     Matches one character not in the enclosed list.
**
** With the [...] and [^...] matching, a ']' character can be included
** in the list by making it the first character after '[' or '^'.  A
** range of characters can be specified using '-'.  Example:
** "[a-z]" matches any single lower-case letter.  To match a '-', make
** it the last character in the list.
**
** This routine is usually quick, but can be N**2 in the worst case.
**
** Hints: to match '*' or '?', put them in "[]".  Like this:
**
**         abc[*]xyz        Matches "abc*xyz" only
*/
int sqliteGlobCompare(const char *zPattern, const char *zString){
  register char c;
  int invert;
  int seen;
  char c2;

  while( (c = *zPattern)!=0 ){
    switch( c ){
      case '*':
        while( zPattern[1]=='*' ) zPattern++;
        if( zPattern[1]==0 ) return 1;
        c = zPattern[1];
        if( c=='[' || c=='?' ){
          while( *zString && sqliteGlobCompare(&zPattern[1],zString)==0 ){
            zString++;
          }
          return *zString!=0;
        }else{
          while( (c2 = *zString)!=0 ){
            while( c2 != 0 && c2 != c ){ c2 = *++zString; }
            if( sqliteGlobCompare(&zPattern[1],zString) ) return 1;
            zString++;
          }
          return 0;
        }
      case '?':
        if( *zString==0 ) return 0;
        break;
      case '[':
        seen = 0;
        invert = 0;
        c = *zString;
        if( c==0 ) return 0;
        c2 = *++zPattern;
        if( c2=='^' ){ invert = 1; c2 = *++zPattern; }
        if( c2==']' ){
          if( c==']' ) seen = 1;
          c2 = *++zPattern;
        }
        while( (c2 = *zPattern)!=0 && c2!=']' ){
          if( c2=='-' && zPattern[1]!=']' && zPattern[1]!=0 ){
            if( c>zPattern[-1] && c<zPattern[1] ) seen = 1;
          }else if( c==c2 ){
            seen = 1;
          }
          zPattern++;
        }
        if( c2==0 || (seen ^ invert)==0 ) return 0;
        break;
      default:
        if( c != *zString ) return 0;
        break;
    }
    zPattern++;
    zString++;
  }
  return *zString==0;
}

/*
** Compare two strings for equality using the "LIKE" operator of
** SQL.  The '%' character matches any sequence of 0 or more
** characters and '_' matches any single character.  Case is
** not significant.
**
** This routine is just an adaptation of the sqliteGlobCompare()
** routine above.
*/
int 
sqliteLikeCompare(const unsigned char *zPattern, const unsigned char *zString){
  register char c;
  int invert;
  int seen;
  char c2;

  while( (c = UpperToLower[*zPattern])!=0 ){
    switch( c ){
      case '%':
        while( zPattern[1]=='%' ) zPattern++;
        if( zPattern[1]==0 ) return 1;
        c = UpperToLower[0xff & zPattern[1]];
        if( c=='_' ){
          while( *zString && sqliteLikeCompare(&zPattern[1],zString)==0 ){
            zString++;
          }
          return *zString!=0;
        }else{
          while( (c2 = UpperToLower[*zString])!=0 ){
            while( c2 != 0 && c2 != c ){ c2 = UpperToLower[*++zString]; }
            if( sqliteLikeCompare(&zPattern[1],zString) ) return 1;
            zString++;
          }
          return 0;
        }
      case '_':
        if( *zString==0 ) return 0;
        break;
      default:
        if( c != UpperToLower[*zString] ) return 0;
        break;
    }
    zPattern++;
    zString++;
  }
  return *zString==0;
}

Changes to src/vdbe.c.

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
...
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406

407
408
409
410
411
412
413
414
415
416
417
...
992
993
994
995
996
997
998





























































999
1000
1001
1002
1003
1004
1005
....
1576
1577
1578
1579
1580
1581
1582









1583
1584
1585
1586
1587
1588
1589
** 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.2 2000/05/30 16:27:04 drh Exp $
*/
#include "sqliteInt.h"

/*
** SQL is translated into a sequence of instructions to be
** executed by a virtual machine.  Each instruction is an instance
** of the following structure.
................................................................................
**
** If any of the numeric OP_ values for opcodes defined in sqliteVdbe.h
** change, be sure to change this array to match.  You can use the
** "opNames.awk" awk script which is part of the source tree to regenerate
** this array, then copy and paste it into this file, if you want.
*/
static char *zOpName[] = { 0,
  "Open",           "Close",          "Destroy",        "Fetch",
  "New",            "Put",            "Delete",         "Field",
  "Key",            "Rewind",         "Next",           "ResetIdx",
  "NextIdx",        "PutIdx",         "DeleteIdx",      "ListOpen",
  "ListWrite",      "ListRewind",     "ListRead",       "ListClose",
  "SortOpen",       "SortPut",        "SortMakeRec",    "SortMakeKey",
  "Sort",           "SortNext",       "SortKey",        "SortCallback",
  "SortClose",      "FileOpen",       "FileRead",       "FileField",
  "FileClose",      "MakeRecord",     "MakeKey",        "Goto",
  "If",             "Halt",           "ColumnCount",    "ColumnName",
  "Callback",       "Integer",        "String",         "Pop",
  "Dup",            "Pull",           "Add",            "AddImm",
  "Subtract",       "Multiply",       "Divide",         "Min",

  "Max",            "Eq",             "Ne",             "Lt",
  "Le",             "Gt",             "Ge",             "IsNull",
  "NotNull",        "Negative",       "And",            "Or",
  "Not",            "Concat",         "Noop",         
};

/*
** Given the name of an opcode, return its number.  Return 0 if
** there is no match.
**
** This routine is used for testing and debugging.
................................................................................
            default:       c = c>=0;     break;
          }
        }
        PopStack(p, 2);
        if( c ) pc = pOp->p2-1;
        break;
      }






























































      /* Opcode: And * * *
      **
      ** Pop two values off the stack.  Take the logical AND of the
      ** two values and push the resulting boolean value back onto the
      ** stack.  Integers are considered false if zero and true otherwise.
      ** Strings are considered false if their length is zero and true
................................................................................
      ** Drop the table whose name is P3.  The file that holds this table
      ** is removed from the disk drive.
      */
      case OP_Destroy: {
        sqliteDbbeDropTable(p->pBe, pOp->p3);
        break;
      }










      /* Opcode: ListOpen P1 * *
      **
      ** Open a file used for temporary storage of index numbers.  P1
      ** will server as a handle to this temporary file for future
      ** interactions.  If another temporary file with the P1 handle is
      ** already opened, the prior file is closed and a new one opened







|







 







|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|







 







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







 







>
>
>
>
>
>
>
>
>







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
...
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
...
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
....
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
** 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.3 2000/05/31 02:27:50 drh Exp $
*/
#include "sqliteInt.h"

/*
** SQL is translated into a sequence of instructions to be
** executed by a virtual machine.  Each instruction is an instance
** of the following structure.
................................................................................
**
** If any of the numeric OP_ values for opcodes defined in sqliteVdbe.h
** change, be sure to change this array to match.  You can use the
** "opNames.awk" awk script which is part of the source tree to regenerate
** this array, then copy and paste it into this file, if you want.
*/
static char *zOpName[] = { 0,
  "Open",           "Close",          "Fetch",          "New",
  "Put",            "Delete",         "Field",          "Key",
  "Rewind",         "Next",           "Destroy",        "Reorganize",
  "ResetIdx",       "NextIdx",        "PutIdx",         "DeleteIdx",
  "ListOpen",       "ListWrite",      "ListRewind",     "ListRead",
  "ListClose",      "SortOpen",       "SortPut",        "SortMakeRec",
  "SortMakeKey",    "Sort",           "SortNext",       "SortKey",
  "SortCallback",   "SortClose",      "FileOpen",       "FileRead",
  "FileField",      "FileClose",      "MakeRecord",     "MakeKey",
  "Goto",           "If",             "Halt",           "ColumnCount",
  "ColumnName",     "Callback",       "Integer",        "String",
  "Pop",            "Dup",            "Pull",           "Add",
  "AddImm",         "Subtract",       "Multiply",       "Divide",
  "Min",            "Max",            "Like",           "Glob",
  "Eq",             "Ne",             "Lt",             "Le",
  "Gt",             "Ge",             "IsNull",         "NotNull",
  "Negative",       "And",            "Or",             "Not",
  "Concat",         "Noop",         
};

/*
** Given the name of an opcode, return its number.  Return 0 if
** there is no match.
**
** This routine is used for testing and debugging.
................................................................................
            default:       c = c>=0;     break;
          }
        }
        PopStack(p, 2);
        if( c ) pc = pOp->p2-1;
        break;
      }

      /* Opcode: Like P1 P2 *
      **
      ** Pop the top two elements from the stack.  The top-most is a
      ** "like" pattern -- the right operand of the SQL "LIKE" operator.
      ** The lower element is the string to compare against the like
      ** pattern.  Jump to P2 if the two compare, and fall through without
      ** jumping if they do not.  The '%' in the top-most element matches
      ** any sequence of zero or more characters in the lower element.  The
      ** '_' character in the topmost matches any single character of the
      ** lower element.  Case is ignored for this comparison.
      **
      ** If P1 is not zero, the sense of the test is inverted and we
      ** have a "NOT LIKE" operator.  The jump is made if the two values
      ** are different.
      */
      case OP_Like: {
        int tos = p->tos;
        int nos = tos - 1;
        int c;
        if( nos<0 ) goto not_enough_stack;
        Stringify(p, tos);
        Stringify(p, nos);
        c = sqliteLikeCompare(p->zStack[tos], p->zStack[nos]);
        PopStack(p, 2);
        if( pOp->p1 ) c = !c;
        if( c ) pc = pOp->p2-1;
        break;
      }

      /* Opcode: Glob P1 P2 *
      **
      ** Pop the top two elements from the stack.  The top-most is a
      ** "glob" pattern.  The lower element is the string to compare 
      ** against the glob pattern.
      **
      ** Jump to P2 if the two compare, and fall through without
      ** jumping if they do not.  The '*' in the top-most element matches
      ** any sequence of zero or more characters in the lower element.  The
      ** '?' character in the topmost matches any single character of the
      ** lower element.  [...] matches a range of characters.  [^...]
      ** matches any character not in the range.  Case is significant
      ** for globs.
      **
      ** If P1 is not zero, the sense of the test is inverted and we
      ** have a "NOT GLOB" operator.  The jump is made if the two values
      ** are different.
      */
      case OP_Glob: {
        int tos = p->tos;
        int nos = tos - 1;
        int c;
        if( nos<0 ) goto not_enough_stack;
        Stringify(p, tos);
        Stringify(p, nos);
        c = sqliteGlobCompare(p->zStack[tos], p->zStack[nos]);
        PopStack(p, 2);
        if( pOp->p1 ) c = !c;
        if( c ) pc = pOp->p2-1;
        break;
      }

      /* Opcode: And * * *
      **
      ** Pop two values off the stack.  Take the logical AND of the
      ** two values and push the resulting boolean value back onto the
      ** stack.  Integers are considered false if zero and true otherwise.
      ** Strings are considered false if their length is zero and true
................................................................................
      ** Drop the table whose name is P3.  The file that holds this table
      ** is removed from the disk drive.
      */
      case OP_Destroy: {
        sqliteDbbeDropTable(p->pBe, pOp->p3);
        break;
      }

      /* Opcode: Reorganize * * P3
      **
      ** Compress, optimize, and tidy up the GDBM file named by P3.
      */
      case OP_Reorganize: {
        sqliteDbbeReorganizeTable(p->pBe, pOp->p3);
        break;
      }

      /* Opcode: ListOpen P1 * *
      **
      ** Open a file used for temporary storage of index numbers.  P1
      ** will server as a handle to this temporary file for future
      ** interactions.  If another temporary file with the P1 handle is
      ** already opened, the prior file is closed and a new one opened

Changes to src/vdbe.h.

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
..
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84




85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
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
*************************************************************************
** 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.2 2000/05/30 16:27:05 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines
................................................................................
** mirror the change.
**
** The source tree contains an AWK script named renumberOps.awk that
** can be used to renumber these opcodes when new opcodes are inserted.
*/
#define OP_Open                1
#define OP_Close               2
#define OP_Destroy             3
#define OP_Fetch               4
#define OP_New                 5
#define OP_Put                 6
#define OP_Delete              7
#define OP_Field               8
#define OP_Key                 9
#define OP_Rewind             10
#define OP_Next               11




#define OP_ResetIdx           12
#define OP_NextIdx            13
#define OP_PutIdx             14
#define OP_DeleteIdx          15

#define OP_ListOpen           16
#define OP_ListWrite          17
#define OP_ListRewind         18
#define OP_ListRead           19
#define OP_ListClose          20

#define OP_SortOpen           21
#define OP_SortPut            22
#define OP_SortMakeRec        23
#define OP_SortMakeKey        24
#define OP_Sort               25
#define OP_SortNext           26
#define OP_SortKey            27
#define OP_SortCallback       28
#define OP_SortClose          29

#define OP_FileOpen           30
#define OP_FileRead           31
#define OP_FileField          32
#define OP_FileClose          33

#define OP_MakeRecord         34
#define OP_MakeKey            35

#define OP_Goto               36
#define OP_If                 37
#define OP_Halt               38

#define OP_ColumnCount        39
#define OP_ColumnName         40
#define OP_Callback           41

#define OP_Integer            42
#define OP_String             43
#define OP_Pop                44
#define OP_Dup                45
#define OP_Pull               46

#define OP_Add                47
#define OP_AddImm             48
#define OP_Subtract           49
#define OP_Multiply           50
#define OP_Divide             51
#define OP_Min                52
#define OP_Max                53


#define OP_Eq                 54
#define OP_Ne                 55
#define OP_Lt                 56
#define OP_Le                 57
#define OP_Gt                 58
#define OP_Ge                 59
#define OP_IsNull             60
#define OP_NotNull            61
#define OP_Negative           62
#define OP_And                63
#define OP_Or                 64
#define OP_Not                65
#define OP_Concat             66
#define OP_Noop               67

#define OP_MAX                67

/*
** Prototypes for the VDBE interface.  See comments on the implementation
** for a description of what each of these routines does.
*/
Vdbe *sqliteVdbeCreate(Dbbe*);
int sqliteVdbeAddOp(Vdbe*,int,int,int,const char*,int);







|







 







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

|
|
|
|
|

|
|
|
|
|
|
|
|
|

|
|
|
|

|
|

|
|
|

|
|
|

|
|
|
|
|

|
|
|
|
|
|
|
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
..
69
70
71
72
73
74
75

76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
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
*************************************************************************
** 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.3 2000/05/31 02:27:50 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines
................................................................................
** mirror the change.
**
** The source tree contains an AWK script named renumberOps.awk that
** can be used to renumber these opcodes when new opcodes are inserted.
*/
#define OP_Open                1
#define OP_Close               2

#define OP_Fetch               3
#define OP_New                 4
#define OP_Put                 5
#define OP_Delete              6
#define OP_Field               7
#define OP_Key                 8
#define OP_Rewind              9
#define OP_Next               10

#define OP_Destroy            11
#define OP_Reorganize         12

#define OP_ResetIdx           13
#define OP_NextIdx            14
#define OP_PutIdx             15
#define OP_DeleteIdx          16

#define OP_ListOpen           17
#define OP_ListWrite          18
#define OP_ListRewind         19
#define OP_ListRead           20
#define OP_ListClose          21

#define OP_SortOpen           22
#define OP_SortPut            23
#define OP_SortMakeRec        24
#define OP_SortMakeKey        25
#define OP_Sort               26
#define OP_SortNext           27
#define OP_SortKey            28
#define OP_SortCallback       29
#define OP_SortClose          30

#define OP_FileOpen           31
#define OP_FileRead           32
#define OP_FileField          33
#define OP_FileClose          34

#define OP_MakeRecord         35
#define OP_MakeKey            36

#define OP_Goto               37
#define OP_If                 38
#define OP_Halt               39

#define OP_ColumnCount        40
#define OP_ColumnName         41
#define OP_Callback           42

#define OP_Integer            43
#define OP_String             44
#define OP_Pop                45
#define OP_Dup                46
#define OP_Pull               47

#define OP_Add                48
#define OP_AddImm             49
#define OP_Subtract           50
#define OP_Multiply           51
#define OP_Divide             52
#define OP_Min                53
#define OP_Max                54
#define OP_Like               55
#define OP_Glob               56
#define OP_Eq                 57
#define OP_Ne                 58
#define OP_Lt                 59
#define OP_Le                 60
#define OP_Gt                 61
#define OP_Ge                 62
#define OP_IsNull             63
#define OP_NotNull            64
#define OP_Negative           65
#define OP_And                66
#define OP_Or                 67
#define OP_Not                68
#define OP_Concat             69
#define OP_Noop               70

#define OP_MAX                70

/*
** Prototypes for the VDBE interface.  See comments on the implementation
** for a description of what each of these routines does.
*/
Vdbe *sqliteVdbeCreate(Dbbe*);
int sqliteVdbeAddOp(Vdbe*,int,int,int,const char*,int);

Changes to src/where.c.

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
...
364
365
366
367
368
369
370
371
372
373
374
375
376


377
378
379
380
381
382
383
...
417
418
419
420
421
422
423
424


425
426
427
428
429
430
431
432
433
434
435
436
437
438
...
462
463
464
465
466
467
468


469
470
471
472
473
474
475
...
478
479
480
481
482
483
484




485
486
487
488
489
490
491


492
493
494
495
496
497
498
...
519
520
521
522
523
524
525


526
527
528
529
530
531
532
...
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
**   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.3 2000/05/30 20:17:49 drh Exp $
*/
#include "sqliteInt.h"

/*
** The query generator uses an array of instances of this structure to
** help it analyze the subexpressions of the WHERE clause.  Each WHERE
** clause subexpression is separated from the others by an AND operator.
................................................................................
  switch( pExpr->op ){
    case TK_PLUS:     op = OP_Add;      break;
    case TK_MINUS:    op = OP_Subtract; break;
    case TK_STAR:     op = OP_Multiply; break;
    case TK_SLASH:    op = OP_Divide;   break;
    case TK_AND:      op = OP_And;      break;
    case TK_OR:       op = OP_Or;       break;
    case TK_LT:       op = OP_Ge;       break;
    case TK_LE:       op = OP_Gt;       break;
    case TK_GT:       op = OP_Le;       break;
    case TK_GE:       op = OP_Lt;       break;
    case TK_NE:       op = OP_Eq;       break;
    case TK_EQ:       op = OP_Ne;       break;


    case TK_ISNULL:   op = OP_IsNull;   break;
    case TK_NOTNULL:  op = OP_NotNull;  break;
    case TK_NOT:      op = OP_Not;      break;
    case TK_UMINUS:   op = OP_Negative; break;
    default: break;
  }
  switch( pExpr->op ){
................................................................................
      break;
    }
    case TK_LT:
    case TK_LE:
    case TK_GT:
    case TK_GE:
    case TK_NE:
    case TK_EQ: {


      int dest;
      sqliteVdbeAddOp(v, OP_Integer, 0, 0, 0, 0);
      sqliteExprCode(pParse, pExpr->pLeft);
      sqliteExprCode(pParse, pExpr->pRight);
      dest = sqliteVdbeCurrentAddr(v) + 2;
      sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
      sqliteVdbeAddOp(v, OP_AddImm, 1, 0, 0, 0);
      break;
    }
    case TK_NOT:
    case TK_UMINUS: {
      sqliteExprCode(pParse, pExpr->pLeft);
      sqliteVdbeAddOp(v, op, 0, 0, 0, 0);
      break;
................................................................................
  switch( pExpr->op ){
    case TK_LT:       op = OP_Lt;       break;
    case TK_LE:       op = OP_Le;       break;
    case TK_GT:       op = OP_Gt;       break;
    case TK_GE:       op = OP_Ge;       break;
    case TK_NE:       op = OP_Ne;       break;
    case TK_EQ:       op = OP_Eq;       break;


    case TK_ISNULL:   op = OP_IsNull;   break;
    case TK_NOTNULL:  op = OP_NotNull;  break;
    default:  break;
  }
  switch( pExpr->op ){
    case TK_AND: {
      int d2 = sqliteVdbeMakeLabel(v);
................................................................................
      sqliteVdbeResolveLabel(v, d2);
      break;
    }
    case TK_OR: {
      sqliteExprIfTrue(pParse, pExpr->pLeft, dest);
      sqliteExprIfTrue(pParse, pExpr->pRight, dest);
      break;




    }
    case TK_LT:
    case TK_LE:
    case TK_GT:
    case TK_GE:
    case TK_NE:
    case TK_EQ: {


      sqliteExprCode(pParse, pExpr->pLeft);
      sqliteExprCode(pParse, pExpr->pRight);
      sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
      break;
    }
    case TK_ISNULL:
    case TK_NOTNULL: {
................................................................................
  switch( pExpr->op ){
    case TK_LT:       op = OP_Ge;       break;
    case TK_LE:       op = OP_Gt;       break;
    case TK_GT:       op = OP_Le;       break;
    case TK_GE:       op = OP_Lt;       break;
    case TK_NE:       op = OP_Eq;       break;
    case TK_EQ:       op = OP_Ne;       break;


    case TK_ISNULL:   op = OP_NotNull;  break;
    case TK_NOTNULL:  op = OP_IsNull;   break;
    default:  break;
  }
  switch( pExpr->op ){
    case TK_AND: {
      sqliteExprIfFalse(pParse, pExpr->pLeft, dest);
................................................................................
    }
    case TK_OR: {
      int d2 = sqliteVdbeMakeLabel(v);
      sqliteExprIfTrue(pParse, pExpr->pLeft, d2);
      sqliteExprIfFalse(pParse, pExpr->pRight, dest);
      sqliteVdbeResolveLabel(v, d2);
      break;




    }
    case TK_LT:
    case TK_LE:
    case TK_GT:
    case TK_GE:
    case TK_NE:
    case TK_EQ: {
      sqliteExprCode(pParse, pExpr->pLeft);
      sqliteExprCode(pParse, pExpr->pRight);
      sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
      break;







    }
    case TK_ISNULL:
    case TK_NOTNULL: {
      sqliteExprCode(pParse, pExpr->pLeft);
      sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
      break;
    }







|







 







|
|
|
|
|
|
>
>







 







|
>
>

|




|







 







>
>







 







>
>
>
>






|
>
>







 







>
>







 







>
>
>
>











>
>
>
>
>
>
>







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
...
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
...
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
...
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
...
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
...
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
...
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
574
575
576
577
578
579
580
581
582
583
584
**   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.4 2000/05/31 02:27:50 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.
................................................................................
  switch( pExpr->op ){
    case TK_PLUS:     op = OP_Add;      break;
    case TK_MINUS:    op = OP_Subtract; break;
    case TK_STAR:     op = OP_Multiply; break;
    case TK_SLASH:    op = OP_Divide;   break;
    case TK_AND:      op = OP_And;      break;
    case TK_OR:       op = OP_Or;       break;
    case TK_LT:       op = OP_Lt;       break;
    case TK_LE:       op = OP_Le;       break;
    case TK_GT:       op = OP_Gt;       break;
    case TK_GE:       op = OP_Ge;       break;
    case TK_NE:       op = OP_Ne;       break;
    case TK_EQ:       op = OP_Eq;       break;
    case TK_LIKE:     op = OP_Like;     break;
    case TK_GLOB:     op = OP_Glob;     break;
    case TK_ISNULL:   op = OP_IsNull;   break;
    case TK_NOTNULL:  op = OP_NotNull;  break;
    case TK_NOT:      op = OP_Not;      break;
    case TK_UMINUS:   op = OP_Negative; break;
    default: break;
  }
  switch( pExpr->op ){
................................................................................
      break;
    }
    case TK_LT:
    case TK_LE:
    case TK_GT:
    case TK_GE:
    case TK_NE:
    case TK_EQ: 
    case TK_LIKE: 
    case TK_GLOB: {
      int dest;
      sqliteVdbeAddOp(v, OP_Integer, 1, 0, 0, 0);
      sqliteExprCode(pParse, pExpr->pLeft);
      sqliteExprCode(pParse, pExpr->pRight);
      dest = sqliteVdbeCurrentAddr(v) + 2;
      sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
      sqliteVdbeAddOp(v, OP_AddImm, -1, 0, 0, 0);
      break;
    }
    case TK_NOT:
    case TK_UMINUS: {
      sqliteExprCode(pParse, pExpr->pLeft);
      sqliteVdbeAddOp(v, op, 0, 0, 0, 0);
      break;
................................................................................
  switch( pExpr->op ){
    case TK_LT:       op = OP_Lt;       break;
    case TK_LE:       op = OP_Le;       break;
    case TK_GT:       op = OP_Gt;       break;
    case TK_GE:       op = OP_Ge;       break;
    case TK_NE:       op = OP_Ne;       break;
    case TK_EQ:       op = OP_Eq;       break;
    case TK_LIKE:     op = OP_Like;     break;
    case TK_GLOB:     op = OP_Glob;     break;
    case TK_ISNULL:   op = OP_IsNull;   break;
    case TK_NOTNULL:  op = OP_NotNull;  break;
    default:  break;
  }
  switch( pExpr->op ){
    case TK_AND: {
      int d2 = sqliteVdbeMakeLabel(v);
................................................................................
      sqliteVdbeResolveLabel(v, d2);
      break;
    }
    case TK_OR: {
      sqliteExprIfTrue(pParse, pExpr->pLeft, dest);
      sqliteExprIfTrue(pParse, pExpr->pRight, dest);
      break;
    }
    case TK_NOT: {
      sqliteExprIfFalse(pParse, pExpr->pLeft, dest);
      break;
    }
    case TK_LT:
    case TK_LE:
    case TK_GT:
    case TK_GE:
    case TK_NE:
    case TK_EQ:
    case TK_LIKE:
    case TK_GLOB: {
      sqliteExprCode(pParse, pExpr->pLeft);
      sqliteExprCode(pParse, pExpr->pRight);
      sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
      break;
    }
    case TK_ISNULL:
    case TK_NOTNULL: {
................................................................................
  switch( pExpr->op ){
    case TK_LT:       op = OP_Ge;       break;
    case TK_LE:       op = OP_Gt;       break;
    case TK_GT:       op = OP_Le;       break;
    case TK_GE:       op = OP_Lt;       break;
    case TK_NE:       op = OP_Eq;       break;
    case TK_EQ:       op = OP_Ne;       break;
    case TK_LIKE:     op = OP_Like;     break;
    case TK_GLOB:     op = OP_Glob;     break;
    case TK_ISNULL:   op = OP_NotNull;  break;
    case TK_NOTNULL:  op = OP_IsNull;   break;
    default:  break;
  }
  switch( pExpr->op ){
    case TK_AND: {
      sqliteExprIfFalse(pParse, pExpr->pLeft, dest);
................................................................................
    }
    case TK_OR: {
      int d2 = sqliteVdbeMakeLabel(v);
      sqliteExprIfTrue(pParse, pExpr->pLeft, d2);
      sqliteExprIfFalse(pParse, pExpr->pRight, dest);
      sqliteVdbeResolveLabel(v, d2);
      break;
    }
    case TK_NOT: {
      sqliteExprIfTrue(pParse, pExpr->pLeft, dest);
      break;
    }
    case TK_LT:
    case TK_LE:
    case TK_GT:
    case TK_GE:
    case TK_NE:
    case TK_EQ: {
      sqliteExprCode(pParse, pExpr->pLeft);
      sqliteExprCode(pParse, pExpr->pRight);
      sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
      break;
    }
    case TK_LIKE:
    case TK_GLOB: {
      sqliteExprCode(pParse, pExpr->pLeft);
      sqliteExprCode(pParse, pExpr->pRight);
      sqliteVdbeAddOp(v, op, 1, dest, 0, 0);
      break;
    }
    case TK_ISNULL:
    case TK_NOTNULL: {
      sqliteExprCode(pParse, pExpr->pLeft);
      sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
      break;
    }

Added www/changes.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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#
# Run this script to generated a changes.html output file
#
puts {<html>
<head>
  <title>SQLite Change Log</title>
</head>
<body bgcolor="white">
<h1 align="center">Recent Changes To SQLite</h1>

<DL>
}


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

chng {2000 May 30} {
<li>Added the <b>LIKE</b> operator.</li>
<li>Added a <b>GLOB</b> operator: similar to <B>LIKE</B> 
but it uses Unix shell globbing wildcards instead of the '%' 
and '_' wildcards of SQL.</li>
<li>Added the <B>COPY</b> command patterned after 
<a href="http://www.postgresql.org/">PostgreSQL</a> so that SQLite
can now read the output of the <b>pg_dump</b> database dump utility
of PostgreSQL.</li>
<li>Added a <B>VACUUM</B> command that that calls the 
<b>gdbm_reorganize()</b> function on the underlying database
files.</li>
<li>And many, many bug fixes...</li>
}

chng {2000 May 29} {
<li>Initial Public Release of Alpha code</li>
}

puts {
</DL>
<p><hr /></p>
<p><a href="index.html"><img src="/goback.jpg" border=0 />
Back to the SQLite Home Page</a>
</p>

</body></html>}

Changes to www/index.tcl.

1
2
3
4
5
6
7
8
9
10
11
..
42
43
44
45
46
47
48



49
50
51
52
53
54
55
..
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#
# Run this TCL script to generate HTML for the index.html file.
#
set rcsid {$Id: index.tcl,v 1.4 2000/05/30 00:05:13 drh Exp $}

puts {<html>
<head><title>SQLite: An SQL Frontend For GDBM</title></head>
<body bgcolor=white>
<h1 align=center>SQLite: An SQL Frontend For GDBM</h1>
<p align=center>}
puts "Last modified [lrange $rcsid 3 4] GMT"
................................................................................

<p>There is a standalone C program named "sqlite" that can be used
to interactively create, update and/or query an SQLite database.
The sources to the sqlite program are part of the source tree and
can be used as an example of how to interact with the SQLite C
library.  For more information on the sqlite program,
see <a href="sqlite.html">sqlite.html</a>.</p>




<p>SQLite does not try to implement every feature of SQL.  But it
does strive to implement to most commonly used features.  SQLite
currently understands the following SQL commands:</p>

<p>
<ul>
................................................................................
<p>A few of the many SQL features that SQLite does not (currently) 
implement are as follows:</p>

<p>
<ul>
<li>ALTER TABLE</li>
<li>The GROUP BY or HAVING clauses of a SELECT</li>
<li>The LIKE or IN operators</li>
<li>The COUNT(), MAX(), MIN(), and AVG() functions</li>
<li>Constraints</li>
<li>Nested queries</li>
<li>Transactions or rollback</li>
</ul>
</p>




|







 







>
>
>







 







<







1
2
3
4
5
6
7
8
9
10
11
..
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
..
70
71
72
73
74
75
76

77
78
79
80
81
82
83
#
# Run this TCL script to generate HTML for the index.html file.
#
set rcsid {$Id: index.tcl,v 1.5 2000/05/31 02:27:50 drh Exp $}

puts {<html>
<head><title>SQLite: An SQL Frontend For GDBM</title></head>
<body bgcolor=white>
<h1 align=center>SQLite: An SQL Frontend For GDBM</h1>
<p align=center>}
puts "Last modified [lrange $rcsid 3 4] GMT"
................................................................................

<p>There is a standalone C program named "sqlite" that can be used
to interactively create, update and/or query an SQLite database.
The sources to the sqlite program are part of the source tree and
can be used as an example of how to interact with the SQLite C
library.  For more information on the sqlite program,
see <a href="sqlite.html">sqlite.html</a>.</p>

<p>A history of changes to SQLite is found
<a href="changes.html">here</a>.</p>

<p>SQLite does not try to implement every feature of SQL.  But it
does strive to implement to most commonly used features.  SQLite
currently understands the following SQL commands:</p>

<p>
<ul>
................................................................................
<p>A few of the many SQL features that SQLite does not (currently) 
implement are as follows:</p>

<p>
<ul>
<li>ALTER TABLE</li>
<li>The GROUP BY or HAVING clauses of a SELECT</li>

<li>The COUNT(), MAX(), MIN(), and AVG() functions</li>
<li>Constraints</li>
<li>Nested queries</li>
<li>Transactions or rollback</li>
</ul>
</p>

Changes to www/sqlite.tcl.

1
2
3
4
5
6
7
8
9
10
11
...
349
350
351
352
353
354
355












356
357
358
359
360
361
362
#
# Run this Tcl script to generate the sqlite.html file.
#
set rcsid {$Id: sqlite.tcl,v 1.3 2000/05/29 18:50:16 drh Exp $}

puts {<html>
<head>
  <title>sqlite: A program of interacting with SQLite databases</title>
</head>
<body bgcolor=white>
<h1 align=center>
................................................................................
<p>The ".schema" command accomplishes the same thing as setting
list mode, then entering the following query:</p>

<blockquote><pre>
SELECT sql FROM sqlite_master
ORDER BY tbl_name, type DESC, name
</pre></blockquote>













<h2>Other Dot Commands</h2>

<p>The ".explain" dot command can be used to set the output mode
to "column" and to set the column widths to values that are reasonable
for looking at the output of an EXPLAIN command.  The EXPLAIN command
is an SQLite-specific command that is useful for debugging.  If any



|







 







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







1
2
3
4
5
6
7
8
9
10
11
...
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
#
# Run this Tcl script to generate the sqlite.html file.
#
set rcsid {$Id: sqlite.tcl,v 1.4 2000/05/31 02:27:50 drh Exp $}

puts {<html>
<head>
  <title>sqlite: A program of interacting with SQLite databases</title>
</head>
<body bgcolor=white>
<h1 align=center>
................................................................................
<p>The ".schema" command accomplishes the same thing as setting
list mode, then entering the following query:</p>

<blockquote><pre>
SELECT sql FROM sqlite_master
ORDER BY tbl_name, type DESC, name
</pre></blockquote>

<p>Of, if you give an argument to ".schema" because you only
one the schema for a single table, the query looks like this:</p>

<blockquote><pre>
SELECT sql FROM sqlite_master
WHERE tbl_name LIKE '%s'
ORDER BY type DESC, name
</pre></blockquote>

<p>The <b>%s</b> in the query above is replaced by the argument
to ".schema", of course.</p>

<h2>Other Dot Commands</h2>

<p>The ".explain" dot command can be used to set the output mode
to "column" and to set the column widths to values that are reasonable
for looking at the output of an EXPLAIN command.  The EXPLAIN command
is an SQLite-specific command that is useful for debugging.  If any