SQLite

Check-in [8d66c7355d]
Login

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

Overview
Comment::-) (CVS 15)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 8d66c7355de1d87b25c4fb92d0ef3603da72899a
User & Date: drh 2000-05-30 16:27:04.000
Context
2000-05-30
17:30
:-) (CVS 16) (check-in: b56d1b9c0f user: drh tags: trunk)
16:27
:-) (CVS 15) (check-in: 8d66c7355d user: drh tags: trunk)
13:44
:-) (CVS 14) (check-in: 1bb8ee8d9f user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/build.c.
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
**   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.6 2000/05/30 13:44:19 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







|







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
**   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.7 2000/05/30 16:27:04 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
187
188
189
190
191
192
193

194
195
196
197
198
199
200
**
** Space to hold the name is obtained from sqliteMalloc() and must
** be freed by the calling function.
*/
static char *sqliteTableNameFromToken(Token *pName){
  char *zName = 0;
  sqliteSetNString(&zName, pName->z, pName->n, 0);

  return zName;
}

/*
** Begin constructing a new table representation in memory.  This is
** the first of several action routines that get called in response
** to a CREATE TABLE statement.







>







187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
**
** Space to hold the name is obtained from sqliteMalloc() and must
** be freed by the calling function.
*/
static char *sqliteTableNameFromToken(Token *pName){
  char *zName = 0;
  sqliteSetNString(&zName, pName->z, pName->n, 0);
  sqliteDequote(zName);
  return zName;
}

/*
** Begin constructing a new table representation in memory.  This is
** the first of several action routines that get called in response
** to a CREATE TABLE statement.
248
249
250
251
252
253
254

255
256
257
258
259
260
261
  if( p->azCol==0 ){
    p->nCol = 0;
    return;
  }
  pz = &p->azCol[p->nCol++];
  *pz = 0;
  sqliteSetNString(pz, pName->z, pName->n, 0);

}

/*
** This routine is called to report the final ")" that terminates
** a CREATE TABLE statement.
**
** The table structure is added to the internal hash tables.  







>







249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
  if( p->azCol==0 ){
    p->nCol = 0;
    return;
  }
  pz = &p->azCol[p->nCol++];
  *pz = 0;
  sqliteSetNString(pz, pName->z, pName->n, 0);
  sqliteDequote(*pz);
}

/*
** This routine is called to report the final ")" that terminates
** a CREATE TABLE statement.
**
** The table structure is added to the internal hash tables.  
661
662
663
664
665
666
667

668
669
670
671
672
673
674
    }
  }
  i = pList->nExpr++;
  pList->a[i].pExpr = pExpr;
  pList->a[i].zName = 0;
  if( pName ){
    sqliteSetNString(&pList->a[i].zName, pName->z, pName->n, 0);

  }
  return pList;
}

/*
** Delete an entire expression list.
*/







>







663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
    }
  }
  i = pList->nExpr++;
  pList->a[i].pExpr = pExpr;
  pList->a[i].zName = 0;
  if( pName ){
    sqliteSetNString(&pList->a[i].zName, pName->z, pName->n, 0);
    sqliteDequote(pList->a[i].zName);
  }
  return pList;
}

/*
** Delete an entire expression list.
*/
698
699
700
701
702
703
704

705
706
707
708
709
710
711
712
713
714
715
716

717
718
719
720
721
722
723
      pList->nId = 0;
      return pList;
    }
  }
  memset(&pList->a[pList->nId], 0, sizeof(pList->a[0]));
  if( pToken ){
    sqliteSetNString(&pList->a[pList->nId].zName, pToken->z, pToken->n, 0);

  }
  pList->nId++;
  return pList;
}

/*
** Add an alias to the last identifier on the given identifier list.
*/
void sqliteIdListAddAlias(IdList *pList, Token *pToken){
  if( pList && pList->nId>0 ){
    int i = pList->nId - 1;
    sqliteSetNString(&pList->a[i].zAlias, pToken->z, pToken->n, 0);

  }
}

/*
** Delete an entire IdList
*/
void sqliteIdListDelete(IdList *pList){







>












>







701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
      pList->nId = 0;
      return pList;
    }
  }
  memset(&pList->a[pList->nId], 0, sizeof(pList->a[0]));
  if( pToken ){
    sqliteSetNString(&pList->a[pList->nId].zName, pToken->z, pToken->n, 0);
    sqliteDequote(pList->a[pList->nId].zName);
  }
  pList->nId++;
  return pList;
}

/*
** Add an alias to the last identifier on the given identifier list.
*/
void sqliteIdListAddAlias(IdList *pList, Token *pToken){
  if( pList && pList->nId>0 ){
    int i = pList->nId - 1;
    sqliteSetNString(&pList->a[i].zAlias, pToken->z, pToken->n, 0);
    sqliteDequote(pList->a[i].zAlias);
  }
}

/*
** Delete an entire IdList
*/
void sqliteIdListDelete(IdList *pList){
1429
1430
1431
1432
1433
1434
1435


















































































  sqliteFree(apIdx);
  sqliteFree(aXRef);
  sqliteIdListDelete(pTabList);
  sqliteExprListDelete(pChanges);
  sqliteExprDelete(pWhere);
  return;
}

























































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
  sqliteFree(apIdx);
  sqliteFree(aXRef);
  sqliteIdListDelete(pTabList);
  sqliteExprListDelete(pChanges);
  sqliteExprDelete(pWhere);
  return;
}

/*
** The COPY command is for compatibility with PostgreSQL and specificially
** for the ability to read the output of pg_dump.  The format is as
** follows:
**
**    COPY table FROM file [USING DELIMITERS string]
**
** "table" is an existing table name.  We will read lines of code from
** file to fill this table with data.  File might be "stdin".  The optional
** delimiter string identifies the field separators.  The default is a tab.
*/
void sqliteCopy(
  Parse *pParse,       /* The parser context */
  Token *pTableName,   /* The name of the table into which we will insert */
  Token *pFilename,    /* The file from which to obtain information */
  Token *pDelimiter    /* Use this as the field delimiter */
){
  Table *pTab;
  char *zTab;
  int i, j;
  Vdbe *v;
  int addr, end;
  Index *pIdx;

  zTab = sqliteTableNameFromToken(pTableName);
  pTab = sqliteFindTable(pParse->db, zTab);
  sqliteFree(zTab);
  if( pTab==0 ){
    sqliteSetNString(&pParse->zErrMsg, "no such table: ", 0, 
        pTableName->z, pTableName->n, 0);
    pParse->nErr++;
    goto copy_cleanup;
  }
  if( pTab->readOnly ){
    sqliteSetString(&pParse->zErrMsg, "table ", pTab->zName,
        " may not be modified", 0);
    pParse->nErr++;
    goto copy_cleanup;
  }
  v = pParse->pVdbe = sqliteVdbeCreate(pParse->db->pBe);
  if( v ){
    addr = sqliteVdbeAddOp(v, OP_FileOpen, 0, 0, 0, 0);
    sqliteVdbeChangeP3(v, addr, pFilename->z, pFilename->n);
    sqliteVdbeAddOp(v, OP_Open, 0, 0, pTab->zName, 0);
    for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
      sqliteVdbeAddOp(v, OP_Open, i, 0, pIdx->zName, 0);
    }
    end = sqliteVdbeMakeLabel(v);
    addr = sqliteVdbeAddOp(v, OP_FileRead, pTab->nCol, end, 0, 0);
    if( pDelimiter ){
      sqliteVdbeChangeP3(v, addr, pDelimiter->z, pDelimiter->n);
      sqliteVdbeDequoteP3(v, addr);
    }else{
      sqliteVdbeChangeP3(v, addr, "\t", 1);
    }
    sqliteVdbeAddOp(v, OP_New, 0, 0, 0, 0);
    if( pTab->pIndex ){
      sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
    }
    for(i=0; i<pTab->nCol; i++){
      sqliteVdbeAddOp(v, OP_FileField, i, 0, 0, 0);
    }
    sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0, 0, 0);
    sqliteVdbeAddOp(v, OP_Put, 0, 0, 0, 0);
    for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
      if( pIdx->pNext ){
        sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
      }
      for(j=0; j<pIdx->nField; j++){
        sqliteVdbeAddOp(v, OP_FileField, pIdx->aiField[j], 0, 0, 0);
      }
      sqliteVdbeAddOp(v, OP_MakeKey, pIdx->nField, 0, 0, 0);
      sqliteVdbeAddOp(v, OP_PutIdx, i, 0, 0, 0);
    }
    sqliteVdbeAddOp(v, OP_Goto, 0, addr, 0, 0);
    sqliteVdbeAddOp(v, OP_Noop, 0, 0, 0, end);
  }
  
copy_cleanup:
  return;
}
Changes to src/parse.y.
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
**
*************************************************************************
** 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.1 2000/05/29 20:42:06 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);







|







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
**
*************************************************************************
** 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);
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
ecmd ::= cmd.          {sqliteExec(pParse);}
ecmd ::= .
explain ::= EXPLAIN.    {pParse->explain = 1;}

// The first form of a command is a CREATE TABLE statement.
//
cmd ::= create_table create_table_args.
create_table ::= CREATE(X) TABLE ID(Y).    {sqliteStartTable(pParse,&X,&Y);}
create_table_args ::= LP columnlist conslist_opt RP(X).
                                           {sqliteEndTable(pParse,&X);}
columnlist ::= columnlist COMMA column.
columnlist ::= column.

// About the only information used for a column is the name of the
// column.  The type is always just "text".  But the code will accept
// an elaborate typename.  Perhaps someday we'll do something with it.
//
column ::= columnid type carglist. 
columnid ::= ID(X).                {sqliteAddColumn(pParse,&X);}



type ::= typename.
type ::= typename LP signed RP.
type ::= typename LP signed COMMA signed RP.
typename ::= ID.
typename ::= typename ID.
signed ::= INTEGER.
signed ::= PLUS INTEGER.







|










|
>
>
>







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
ecmd ::= cmd.          {sqliteExec(pParse);}
ecmd ::= .
explain ::= EXPLAIN.    {pParse->explain = 1;}

// The first form of a command is a CREATE TABLE statement.
//
cmd ::= create_table create_table_args.
create_table ::= CREATE(X) TABLE id(Y).    {sqliteStartTable(pParse,&X,&Y);}
create_table_args ::= LP columnlist conslist_opt RP(X).
                                           {sqliteEndTable(pParse,&X);}
columnlist ::= columnlist COMMA column.
columnlist ::= column.

// About the only information used for a column is the name of the
// column.  The type is always just "text".  But the code will accept
// an elaborate typename.  Perhaps someday we'll do something with it.
//
column ::= columnid type carglist. 
columnid ::= id(X).                {sqliteAddColumn(pParse,&X);}
%type id {Token}
id(A) ::= ID(X).     {A = X;}
id(A) ::= STRING(X). {A = X;}
type ::= typename.
type ::= typename LP signed RP.
type ::= typename LP signed COMMA signed RP.
typename ::= ID.
typename ::= typename ID.
signed ::= INTEGER.
signed ::= PLUS INTEGER.
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
conslist ::= tcons.
tcons ::= CONSTRAINT ID tcons2.
tcons ::= tcons2.
tcons2 ::= PRIMARY KEY LP idxlist(X) RP.  
      {sqliteCreateIndex(pParse,0,0,X,0,0);}
tcons2 ::= UNIQUE LP idlist RP.
tcons2 ::= CHECK expr.
idlist ::= idlist COMMA ID.
idlist ::= ID.

// The next command format is dropping tables.
//
cmd ::= DROP TABLE ID(X).          {sqliteDropTable(pParse,&X);}

// The select statement
//
cmd ::= select.
select ::= SELECT selcollist(W) from(X) where_opt(Y) orderby_opt(Z).
     {sqliteSelect(pParse, W, X, Y, Z);}
select ::= SELECT STAR from(X) where_opt(Y) orderby_opt(Z).







|
|



|







111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
conslist ::= tcons.
tcons ::= CONSTRAINT ID tcons2.
tcons ::= tcons2.
tcons2 ::= PRIMARY KEY LP idxlist(X) RP.  
      {sqliteCreateIndex(pParse,0,0,X,0,0);}
tcons2 ::= UNIQUE LP idlist RP.
tcons2 ::= CHECK expr.
idlist ::= idlist COMMA id.
idlist ::= id.

// The next command format is dropping tables.
//
cmd ::= DROP TABLE id(X).          {sqliteDropTable(pParse,&X);}

// The select statement
//
cmd ::= select.
select ::= SELECT selcollist(W) from(X) where_opt(Y) orderby_opt(Z).
     {sqliteSelect(pParse, W, X, Y, Z);}
select ::= SELECT STAR from(X) where_opt(Y) orderby_opt(Z).
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
%destructor stl_prefix {sqliteIdListDelete($$);}
%type from {IdList*}
%destructor from {sqliteIdListDelete($$);}

from(A) ::= FROM seltablist(X).               {A = X;}
stl_prefix(A) ::= seltablist(X) COMMA.        {A = X;}
stl_prefix(A) ::= .                           {A = 0;}
seltablist(A) ::= stl_prefix(X) ID(Y).        {A = sqliteIdListAppend(X,&Y);}
seltablist(A) ::= stl_prefix(X) ID(Y) AS ID(Z).
   {A = sqliteIdListAppend(X,&Y);
    sqliteIdListAddAlias(A,&Z);}

%type orderby_opt {ExprList*}
%destructor orderby_opt {sqliteExprListDelete($$);}
%type sortlist {ExprList*}
%destructor sortlist {sqliteExprListDelete($$);}







|
|







148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
%destructor stl_prefix {sqliteIdListDelete($$);}
%type from {IdList*}
%destructor from {sqliteIdListDelete($$);}

from(A) ::= FROM seltablist(X).               {A = X;}
stl_prefix(A) ::= seltablist(X) COMMA.        {A = X;}
stl_prefix(A) ::= .                           {A = 0;}
seltablist(A) ::= stl_prefix(X) id(Y).        {A = sqliteIdListAppend(X,&Y);}
seltablist(A) ::= stl_prefix(X) id(Y) AS id(Z).
   {A = sqliteIdListAppend(X,&Y);
    sqliteIdListAddAlias(A,&Z);}

%type orderby_opt {ExprList*}
%destructor orderby_opt {sqliteExprListDelete($$);}
%type sortlist {ExprList*}
%destructor sortlist {sqliteExprListDelete($$);}
296
297
298
299
300
301
302
303






idxlist(A) ::= idxlist(X) COMMA idxitem(Y).  
     {A = sqliteIdListAppend(X,&Y);}
idxlist(A) ::= idxitem(Y).
     {A = sqliteIdListAppend(0,&Y);}
idxitem(A) ::= ID(X).           {A = X;}

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












|
>
>
>
>
>
299
300
301
302
303
304
305
306
307
308
309
310
311

idxlist(A) ::= idxlist(X) COMMA idxitem(Y).  
     {A = sqliteIdListAppend(X,&Y);}
idxlist(A) ::= idxitem(Y).
     {A = sqliteIdListAppend(0,&Y);}
idxitem(A) ::= ID(X).           {A = X;}

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);}
Changes to src/sqliteInt.h.
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.2 2000/05/30 13:44:20 drh Exp $
*/
#include "sqlite.h"
#include "dbbe.h"
#include "vdbe.h"
#include "parse.h"
#include <gdbm.h>
#include <stdio.h>







|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
** 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>
215
216
217
218
219
220
221

222
223
224
225
226
227
228
  void *sqliteMalloc(int);
  void sqliteFree(void*);
  void *sqliteRealloc(void*,int);
#endif
int sqliteGetToken(const char*, int *);
void sqliteSetString(char **, const char *, ...);
void sqliteSetNString(char **, ...);

int sqliteRunParser(Parse*, char*, char **);
void sqliteExec(Parse*);
Expr *sqliteExpr(int, Expr*, Expr*, Token*);
Expr *sqliteExprFunction(ExprList*, Token*);
void sqliteExprDelete(Expr*);
ExprList *sqliteExprListAppend(ExprList*,Expr*,Token*);
void sqliteExprListDelete(ExprList*);







>







215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
  void *sqliteMalloc(int);
  void sqliteFree(void*);
  void *sqliteRealloc(void*,int);
#endif
int sqliteGetToken(const char*, int *);
void sqliteSetString(char **, const char *, ...);
void sqliteSetNString(char **, ...);
void sqliteDequote(char*);
int sqliteRunParser(Parse*, char*, char **);
void sqliteExec(Parse*);
Expr *sqliteExpr(int, Expr*, Expr*, Token*);
Expr *sqliteExprFunction(ExprList*, Token*);
void sqliteExprDelete(Expr*);
ExprList *sqliteExprListAppend(ExprList*,Expr*,Token*);
void sqliteExprListDelete(ExprList*);
242
243
244
245
246
247
248

void sqliteUpdate(Parse*, Token*, ExprList*, Expr*);
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*);








>
243
244
245
246
247
248
249
250
void sqliteUpdate(Parse*, Token*, ExprList*, Expr*);
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*);
Changes to src/tokenize.c.
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
*************************************************************************
** 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.2 2000/05/30 13:44:20 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include <stdlib.h>

/*
** All the keywords of the SQL language are stored as in a hash







|







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
*************************************************************************
** 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
51
52
53
54
55
56
57

58
59
60

61
62
63
64
65
66
67
static Keyword aKeywordTable[] = {
  { "AND",               0, TK_AND,              0 },
  { "AS",                0, TK_AS,               0 },
  { "ASC",               0, TK_ASC,              0 },
  { "BY",                0, TK_BY,               0 },
  { "CHECK",             0, TK_CHECK,            0 },
  { "CONSTRAINT",        0, TK_CONSTRAINT,       0 },

  { "CREATE",            0, TK_CREATE,           0 },
  { "DEFAULT",           0, TK_DEFAULT,          0 },
  { "DELETE",            0, TK_DELETE,           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 },







>



>







51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
static Keyword aKeywordTable[] = {
  { "AND",               0, TK_AND,              0 },
  { "AS",                0, TK_AS,               0 },
  { "ASC",               0, TK_ASC,              0 },
  { "BY",                0, TK_BY,               0 },
  { "CHECK",             0, TK_CHECK,            0 },
  { "CONSTRAINT",        0, TK_CONSTRAINT,       0 },
  { "COPY",              0, TK_COPY,             0 },
  { "CREATE",            0, TK_CREATE,           0 },
  { "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 },
76
77
78
79
80
81
82

83
84
85
86
87
88
89
  { "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 },

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

/*
** This is the hash table
*/







>







78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
  { "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
*/
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
  static FILE *trace = 0;
  extern void *sqliteParserAlloc(void*(*)(int));
  extern void sqliteParserFree(void*, void(*)(void*));
  extern int sqliteParser(void*, int, ...);
  extern void sqliteParserTrace(FILE*, char *);

  i = 0;
  pEngine = sqliteParserAlloc((void(*)())malloc);
  if( pEngine==0 ){
    sqliteSetString(pzErrMsg, "out of memory", 0);
    return 1;
  }
  sqliteParserTrace(trace, "parser: ");
  while( nErr==0 && i>=0 && zSql[i]!=0 ){
    int tokenType;







|







287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
  static FILE *trace = 0;
  extern void *sqliteParserAlloc(void*(*)(int));
  extern void sqliteParserFree(void*, void(*)(void*));
  extern int sqliteParser(void*, int, ...);
  extern void sqliteParserTrace(FILE*, char *);

  i = 0;
  pEngine = sqliteParserAlloc((void*(*)(int))malloc);
  if( pEngine==0 ){
    sqliteSetString(pzErrMsg, "out of memory", 0);
    return 1;
  }
  sqliteParserTrace(trace, "parser: ");
  while( nErr==0 && i>=0 && zSql[i]!=0 ){
    int tokenType;
Changes to src/util.c.
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.5 2000/05/30 13:44:20 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>

#ifdef MEMORY_DEBUG








|







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
**
*************************************************************************
** 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

221
222
223
224
225
226
227


























228
229
230
231
232
233
234
    if( n<=0 ) n = strlen(z);
    strncpy(zResult, z, n);
    zResult += n;
  }
  *zResult = 0;
  va_end(ap);
}



























/* An array to map all upper-case characters into their corresponding
** lower-case character. 
*/
static unsigned char UpperToLower[] = {
      0,  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,







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







221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
    if( n<=0 ) n = strlen(z);
    strncpy(zResult, z, n);
    zResult += n;
  }
  *zResult = 0;
  va_end(ap);
}

/*
** Convert an SQL-style quoted string into a normal string by removing
** the quote characters.  The conversion is done in-place.  If the
** input does not begin with a quote character, then this routine
** is a no-op.
*/
void sqliteDequote(char *z){
  int quote;
  int i, j;
  quote = z[0];
  if( quote!='\'' && quote!='"' ) return;
  for(i=1, j=0; z[i]; i++){
    if( z[i]==quote ){
      if( z[i+1]==quote ){
        z[j++] = quote;
        i++;
      }else{
        z[j++] = 0;
        break;
      }
    }else{
      z[j++] = z[i];
    }
  }
}

/* An array to map all upper-case characters into their corresponding
** lower-case character. 
*/
static unsigned char UpperToLower[] = {
      0,  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,
Changes to src/vdbe.c.
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
** 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.1 2000/05/29 14:26:02 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.







|







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
** 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.
99
100
101
102
103
104
105





106
107
108
109
110
111
112
  char **azColName;   /* Becomes the 4th parameter to callbacks */
  int nTable;         /* Number of slots in aTab[] */
  VdbeTable *aTab;    /* On element of this array for each open table */
  int nList;          /* Number of slots in apList[] */
  FILE **apList;      /* An open file for each list */
  int nSort;          /* Number of slots in apSort[] */
  Sorter **apSort;    /* An open sorter list */





};

/*
** Create a new virtual database engine.
*/
Vdbe *sqliteVdbeCreate(Dbbe *pBe){
  Vdbe *p;







>
>
>
>
>







99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
  char **azColName;   /* Becomes the 4th parameter to callbacks */
  int nTable;         /* Number of slots in aTab[] */
  VdbeTable *aTab;    /* On element of this array for each open table */
  int nList;          /* Number of slots in apList[] */
  FILE **apList;      /* An open file for each list */
  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 */
};

/*
** Create a new virtual database engine.
*/
Vdbe *sqliteVdbeCreate(Dbbe *pBe){
  Vdbe *p;
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
** the quotes.
**
** The quoting operator can be either a grave ascent (ASCII 0x27)
** or a double quote character (ASCII 0x22).  Two quotes in a row
** resolve to be a single actual quote character within the string.
*/
void sqliteVdbeDequoteP3(Vdbe *p, int addr){
  int quote;
  int i, j;
  char *z;
  if( addr<0 || addr>=p->nOp ) return;
  z = p->aOp[addr].p3;
  quote = z[0];
  if( quote!='\'' && quote!='"' ) return;
  for(i=1, j=0; z[i]; i++){
    if( z[i]==quote ){
      if( z[i+1]==quote ){
        z[j++] = quote;
        i++;
      }else{
        z[j++] = 0;
        break;
      }
    }else{
      z[j++] = z[i];
    }
  }
}

/*
** Create a new symbolic label for an instruction that has yet to be
** coded.  The symbolic label is really just a negative number.  The
** label can be used as the P2 value of an operation.  Later, when
** the label is resolved to a specific address, the VDBE will scan







<
<



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







252
253
254
255
256
257
258


259
260
261
262














263
264
265
266
267
268
269
** the quotes.
**
** The quoting operator can be either a grave ascent (ASCII 0x27)
** or a double quote character (ASCII 0x22).  Two quotes in a row
** resolve to be a single actual quote character within the string.
*/
void sqliteVdbeDequoteP3(Vdbe *p, int addr){


  char *z;
  if( addr<0 || addr>=p->nOp ) return;
  z = p->aOp[addr].p3;
  sqliteDequote(z);














}

/*
** Create a new symbolic label for an instruction that has yet to be
** coded.  The symbolic label is really just a negative number.  The
** label can be used as the P2 value of an operation.  Later, when
** the label is resolved to a specific address, the VDBE will scan
351
352
353
354
355
356
357














358
359
360
361
362
363
364
      sqliteFree(pSorter->pData);
      sqliteFree(pSorter);
    }
  }
  sqliteFree(p->apSort);
  p->apSort = 0;
  p->nSort = 0;














}

/*
** Delete an entire VDBE.
*/
void sqliteVdbeDelete(Vdbe *p){
  int i;







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







340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
      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;
  }
  p->nField = 0;
  if( p->zLine ){
    sqliteFree(p->zLine);
    p->zLine = 0;
  }
  p->nLineAlloc = 0;
}

/*
** Delete an entire VDBE.
*/
void sqliteVdbeDelete(Vdbe *p){
  int i;
391
392
393
394
395
396
397

398
399
400
401
402
403
404
405
  "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",      "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",







>
|







394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
  "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",
1913
1914
1915
1916
1917
1918
1919




















































































































































1920
1921
1922
1923
1924
1925
1926
             sqliteFree(pSorter->zKey);
             sqliteFree(pSorter->pData);
             sqliteFree(pSorter);
           }
        }
        break;
      }





















































































































































      /* An other opcode is illegal...
      */
      default: {
        sprintf(zBuf,"%d",pOp->opcode);
        sqliteSetString(pzErrMsg, "unknown opcode ", zBuf, 0);
        rc = 1;







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







1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
             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 output standard input for reading.
      */
      case OP_FileOpen: {
        if( pOp->p3==0 ) goto bad_instruction;
        if( p->pFile ){
          if( p->pFile!=stdin ) fclose(p->pFile);
          p->pFile = 0;
        }
        if( sqliteStrICmp(pOp->p3,"stdin")==0 ){
          p->pFile = stdin;
        }else{
          p->pFile = fopen(pOp->p3, "r");
        }
        if( p->pFile==0 ){
          sqliteSetString(pzErrMsg,"unable to open file: ", pOp->p3, 0);
          rc = 1;
          goto cleanup;
        }
        break;
      }

      /* Opcode: FileClose * * *
      **
      ** Close a file previously opened using FileOpen.  This is a no-op
      ** if there is no prior FileOpen call.
      */
      case OP_FileClose: {
        if( p->pFile ){
          if( p->pFile!=stdin ) fclose(p->pFile);
          p->pFile = 0;
        }
        if( p->azField ){
          sqliteFree(p->azField);
          p->azField = 0;
        }
        p->nField = 0;
        if( p->zLine ){
          sqliteFree(p->zLine);
          p->zLine = 0;
        }
        p->nLineAlloc = 0;
        break;
      }

      /* Opcode: FileRead P1 P2 P3
      **
      ** Read a single line of input the open file (the file opened using
      ** FileOpen).  If we reach end-of-file, jump immediately to P2.  If
      ** we are able to get another line, split the line apart using P3 as
      ** a delimiter.  There should be exactly P1 fields.  Throw an exception
      ** if the number of fields is different from P1.
      */
      case OP_FileRead: {
        int n, eol, nField, i, c, nDelim;
        char *zDelim, *z;
        if( p->pFile==0 ) goto fileread_jump;
        nField = pOp->p1;
        if( nField<=0 ) goto fileread_jump;
        if( nField!=p->nField || p->azField==0 ){
          p->azField = sqliteRealloc(p->azField, sizeof(char*)*nField+1);
          if( p->azField==0 ){
            p->nField = 0;
            goto fileread_jump;
          }
          p->nField = nField;
        }
        n = 0;
        eol = 0;
        while( eol==0 ){
          if( p->zLine==0 || n+200>p->nLineAlloc ){
            p->nLineAlloc = p->nLineAlloc*2 + 300;
            p->zLine = sqliteRealloc(p->zLine, p->nLineAlloc);
            if( p->zLine==0 ){
              p->nLineAlloc = 0;
              goto fileread_jump;
            }
          }
          if( fgets(&p->zLine[n], p->nLineAlloc-n, p->pFile)==0 ){
            eol = 1;
            p->zLine[n] = 0;
          }else{
            while( p->zLine[n] ){ n++; }
            if( n>0 && p->zLine[n-1]=='\n' ){
              n--;
              p->zLine[n] = 0;
              eol = 1;
            }
          }
        }
        if( n==0 ) goto fileread_jump;
        z = p->zLine;
        if( z[0]=='\\' && z[1]=='.' && z[2]==0 ){
          goto fileread_jump;
        }
        zDelim = pOp->p3;
        if( zDelim==0 ) zDelim = "\t";
        c = zDelim[0];
        nDelim = strlen(zDelim);
        p->azField[0] = z;
        for(i=1; *z!=0 && i<nField; i++){
          while( *z && (*z!=c || strncmp(z,zDelim,nDelim)) ){ z++; }
          if( *z ){
            *z = 0;
            z += nDelim;
            p->azField[i] = z;
          }
        }
        while( i<nField ){
          p->azField[i++] = "";
        }
        break;

        /* If we reach end-of-file, or if anything goes wrong, jump here.
        ** This code will cause a jump to P2 */
      fileread_jump:
        pc = pOp->p2;
        if( pc<0 || pc>p->nOp ){
          sqliteSetString(pzErrMsg, "jump destination out of range", 0);
          rc = 1;
        }
        pc--;
        break;
      }

      /* Opcode: FileField P1 * *
      **
      ** Push onto the stack the P1-th field of the most recently read line
      ** from the file.
      */
      case OP_FileField: {
        int i = pOp->p1;
        char *z;
        if( NeedStack(p, p->tos+1) ) goto no_mem;
        if( i>=0 && i<p->nField && p->azField ){
          z = p->azField[i];
        }else{
          z = 0;
        }
        if( z==0 ) z = "";
        p->tos++;
        p->iStack[p->tos] = strlen(z) + 1;
        sqliteSetString(&p->zStack[p->tos], z, 0);
        break;
      }

      /* An other opcode is illegal...
      */
      default: {
        sprintf(zBuf,"%d",pOp->opcode);
        sqliteSetString(pzErrMsg, "unknown opcode ", zBuf, 0);
        rc = 1;
Changes to src/vdbe.h.
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
*************************************************************************
** 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.1 2000/05/29 14:26:02 drh Exp $
*/
#ifndef _SQLITE_VDBE_H_
#define _SQLITE_VDBE_H_
#include <stdio.h>

/*
** A single VDBE is an opaque structure named "Vdbe".  Only routines







|







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
*************************************************************************
** 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
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
#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_MakeRecord         30
#define OP_MakeKey            31

#define OP_Goto               32
#define OP_If                 33
#define OP_Halt               34

#define OP_ColumnCount        35
#define OP_ColumnName         36
#define OP_Callback           37

#define OP_Integer            38
#define OP_String             39
#define OP_Pop                40
#define OP_Dup                41
#define OP_Pull               42

#define OP_Add                43
#define OP_AddImm             44
#define OP_Subtract           45
#define OP_Multiply           46
#define OP_Divide             47
#define OP_Min                48
#define OP_Max                49
#define OP_Eq                 50
#define OP_Ne                 51
#define OP_Lt                 52
#define OP_Le                 53
#define OP_Gt                 54
#define OP_Ge                 55
#define OP_IsNull             56
#define OP_NotNull            57
#define OP_Negative           58
#define OP_And                59
#define OP_Or                 60
#define OP_Not                61
#define OP_Concat             62
#define OP_Noop               63

#define OP_MAX                63

/*
** 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);







>
>
>
>
>
|
|

|
|
|

|
|
|

|
|
|
|
|

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

|







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
#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);
Changes to test/table.test.
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#   drh@hwaci.com
#   http://www.hwaci.com/drh/
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the CREATE TABLE statement.
#
# $Id: table.test,v 1.3 2000/05/30 13:44:20 drh Exp $

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

# Create a basic table and verify it is added to sqlite_master
#
do_test table-1.1 {







|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#   drh@hwaci.com
#   http://www.hwaci.com/drh/
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the CREATE TABLE statement.
#
# $Id: table.test,v 1.4 2000/05/30 16:27:05 drh Exp $

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

# Create a basic table and verify it is added to sqlite_master
#
do_test table-1.1 {
84
85
86
87
88
89
90




















91
92
93
94
95
96
97
# still gone.
#
do_test table-1.6 {
  db close
  sqlite db testdb
  execsql {SELECT name FROM sqlite_master}
} {}






















# Verify that we cannot make two tables with the same name
#
do_test table-2.1 {
  execsql {CREATE TABLE test2(one text)}
  set v [catch {execsql {CREATE TABLE test2(two text)}} msg]







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







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
# still gone.
#
do_test table-1.6 {
  db close
  sqlite db testdb
  execsql {SELECT name FROM sqlite_master}
} {}

# Repeat the above steps, but this time quote the table name.
#
do_test table-1.10 {
  execsql {CREATE TABLE "create" (f1 int)}
  execsql {SELECT name FROM sqlite_master}
} {create}
do_test table-1.11 {
  execsql {DROP TABLE "create"}
  execsql {SELECT name FROM "sqlite_master"}
} {}
do_test table-1.12 {
  execsql {CREATE TABLE test1("f1 ho" int)}
  execsql {SELECT name as "X" FROM sqlite_master}
} {test1}
do_test table-1.13 {
  execsql {DROP TABLE "TEST1"}
  execsql {SELECT name FROM "sqlite_master"}
} {}



# Verify that we cannot make two tables with the same name
#
do_test table-2.1 {
  execsql {CREATE TABLE test2(one text)}
  set v [catch {execsql {CREATE TABLE test2(two text)}} msg]