/ Check-in [61c381e7]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment::-) (CVS 81)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 61c381e7e6c85619b7b494417956fc209c5b7b84
User & Date: drh 2000-06-08 15:10:47
Context
2000-06-08
16:26
:-) (CVS 82) check-in: 33355b2d user: drh tags: trunk
15:10
:-) (CVS 81) check-in: 61c381e7 user: drh tags: trunk
13:36
remove all memory leaks (CVS 80) check-in: bf98cf82 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/dbbe.c.

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
...
308
309
310
311
312
313
314

315



316
317
318
319
320
321
322
...
335
336
337
338
339
340
341


342
343
344
345
346
347
348
349
** 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.12 2000/06/07 14:42:26 drh Exp $
*/
#include "sqliteInt.h"
#include <gdbm.h>
#include <sys/stat.h>
#include <unistd.h>
#include <ctype.h>
#include <time.h>
................................................................................
    }
    pFile = sqliteMalloc( sizeof(*pFile) );
    if( pFile==0 ){
      sqliteFree(zFile);
      return SQLITE_NOMEM;
    }
    if( zFile ){

      pFile->dbf = gdbm_open(zFile, 0, rw_mask, mode, 0);



    }else{
      int limit;
      struct rc4 *pRc4;
      char zRandom[50];
      pRc4 = &pBe->rc4;
      zFile = 0;
      limit = 5;
................................................................................
    if( pBe->pOpen ){
      pBe->pOpen->pPrev = pFile;
    }
    pFile->pNext = pBe->pOpen;
    pBe->pOpen = pFile;
    if( pFile->dbf==0 ){
      if( !writeable && access(zFile,0) ){


        rc = SQLITE_OK;
      }else if( access(zFile,W_OK|R_OK) ){
        rc = SQLITE_PERM;
      }else{
        rc = SQLITE_BUSY;
      }
    }
  }else{







|







 







>
|
>
>
>







 







>
>
|







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
...
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
...
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
** 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.13 2000/06/08 15:10:47 drh Exp $
*/
#include "sqliteInt.h"
#include <gdbm.h>
#include <sys/stat.h>
#include <unistd.h>
#include <ctype.h>
#include <time.h>
................................................................................
    }
    pFile = sqliteMalloc( sizeof(*pFile) );
    if( pFile==0 ){
      sqliteFree(zFile);
      return SQLITE_NOMEM;
    }
    if( zFile ){
      if( !writeable || pBe->write ){
        pFile->dbf = gdbm_open(zFile, 0, rw_mask, mode, 0);
      }else{
        pFile->dbf = 0;
      }
    }else{
      int limit;
      struct rc4 *pRc4;
      char zRandom[50];
      pRc4 = &pBe->rc4;
      zFile = 0;
      limit = 5;
................................................................................
    if( pBe->pOpen ){
      pBe->pOpen->pPrev = pFile;
    }
    pFile->pNext = pBe->pOpen;
    pBe->pOpen = pFile;
    if( pFile->dbf==0 ){
      if( !writeable && access(zFile,0) ){
        /* Trying to read a non-existant file.  This is OK.  All the
        ** reads will return empty, which is what we want. */
        rc = SQLITE_OK;   
      }else if( access(zFile,W_OK|R_OK) ){
        rc = SQLITE_PERM;
      }else{
        rc = SQLITE_BUSY;
      }
    }
  }else{

Changes to src/expr.c.

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
...
396
397
398
399
400
401
402
403

404
405
406
407
408
409
410
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** This file contains C code routines used for processing expressions
**
** $Id: expr.c,v 1.13 2000/06/08 13:36:40 drh Exp $
*/
#include "sqliteInt.h"

/*
** Walk an expression tree.  Return 1 if the expression is constant
** and 0 if it involves variables.
*/
................................................................................
           pExpr->token.z, pExpr->token.n, "()", 2, 0);
        pParse->nErr++;
        nErr++;
      }
      if( is_agg ) pExpr->op = TK_AGG_FUNCTION;
      if( is_agg && pIsAgg ) *pIsAgg = 1;
      for(i=0; nErr==0 && i<n; i++){
        nErr = sqliteExprCheck(pParse, pExpr->pList->a[i].pExpr, 0, 0);

      }
    }
    default: {
      if( pExpr->pLeft ){
        nErr = sqliteExprCheck(pParse, pExpr->pLeft, allowAgg, pIsAgg);
      }
      if( nErr==0 && pExpr->pRight ){







|







 







|
>







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
...
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** This file contains C code routines used for processing expressions
**
** $Id: expr.c,v 1.14 2000/06/08 15:10:47 drh Exp $
*/
#include "sqliteInt.h"

/*
** Walk an expression tree.  Return 1 if the expression is constant
** and 0 if it involves variables.
*/
................................................................................
           pExpr->token.z, pExpr->token.n, "()", 2, 0);
        pParse->nErr++;
        nErr++;
      }
      if( is_agg ) pExpr->op = TK_AGG_FUNCTION;
      if( is_agg && pIsAgg ) *pIsAgg = 1;
      for(i=0; nErr==0 && i<n; i++){
        nErr = sqliteExprCheck(pParse, pExpr->pList->a[i].pExpr,
                               allowAgg && !is_agg, pIsAgg);
      }
    }
    default: {
      if( pExpr->pLeft ){
        nErr = sqliteExprCheck(pParse, pExpr->pLeft, allowAgg, pIsAgg);
      }
      if( nErr==0 && pExpr->pRight ){

Changes to src/parse.y.

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
..
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
...
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
...
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
...
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
261
262
263
264
265
266
267
...
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
...
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
...
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
419
**
*************************************************************************
** 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.17 2000/06/08 13:36:40 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);
................................................................................
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.
signed ::= MINUS INTEGER.
carglist ::= carglist carg.
carglist ::= .
carg ::= CONSTRAINT ID ccons.
carg ::= ccons.
carg ::= DEFAULT STRING(X).          {sqliteAddDefaultValue(pParse,&X,0);}
carg ::= DEFAULT ID(X).              {sqliteAddDefaultValue(pParse,&X,0);}
carg ::= DEFAULT INTEGER(X).         {sqliteAddDefaultValue(pParse,&X,0);}
carg ::= DEFAULT PLUS INTEGER(X).    {sqliteAddDefaultValue(pParse,&X,0);}
carg ::= DEFAULT MINUS INTEGER(X).   {sqliteAddDefaultValue(pParse,&X,1);}
carg ::= DEFAULT FLOAT(X).           {sqliteAddDefaultValue(pParse,&X,0);}
................................................................................
// For the time being, the only constraint we care about is the primary
// key.
//
conslist_opt ::= .
conslist_opt ::= COMMA conslist.
conslist ::= conslist COMMA tcons.
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.
................................................................................
%destructor selcollist {sqliteExprListDelete($$);}
%type sclp {ExprList*}
%destructor sclp {sqliteExprListDelete($$);}
sclp(A) ::= selcollist(X) COMMA.             {A = X;}
sclp(A) ::= .                                {A = 0;}
selcollist(A) ::= STAR.                      {A = 0;}
selcollist(A) ::= sclp(P) expr(X).           {A = sqliteExprListAppend(P,X,0);}
selcollist(A) ::= sclp(P) expr(X) as ID(Y).  {A = sqliteExprListAppend(P,X,&Y);}
selcollist(A) ::= sclp(P) expr(X) as STRING(Y).
  {A = sqliteExprListAppend(P,X,&Y);}
as ::= .
as ::= AS.


%type seltablist {IdList*}
%destructor seltablist {sqliteIdListDelete($$);}
%type stl_prefix {IdList*}
................................................................................

%type having_opt {Expr*}
%destructor having_opt {sqliteExprDelete($$);}
having_opt(A) ::= .      {A = 0;}
having_opt(A) ::= HAVING expr(X).  {A = X;}


cmd ::= DELETE FROM ID(X) where_opt(Y).
    {sqliteDeleteFrom(pParse, &X, Y);}

%type where_opt {Expr*}
%destructor where_opt {sqliteExprDelete($$);}

where_opt(A) ::= .                    {A = 0;}
where_opt(A) ::= WHERE expr(X).       {A = X;}

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

cmd ::= UPDATE ID(X) SET setlist(Y) where_opt(Z).
    {sqliteUpdate(pParse,&X,Y,Z);}

setlist(A) ::= ID(X) EQ expr(Y) COMMA setlist(Z).
    {A = sqliteExprListAppend(Z,Y,&X);}
setlist(A) ::= ID(X) EQ expr(Y).   {A = sqliteExprListAppend(0,Y,&X);}

cmd ::= INSERT INTO ID(X) fieldlist_opt(F) VALUES LP itemlist(Y) RP.
               {sqliteInsert(pParse, &X, Y, 0, F);}
cmd ::= INSERT INTO ID(X) fieldlist_opt(F) select(S).
               {sqliteInsert(pParse, &X, 0, S, F);}


%type itemlist {ExprList*}
%destructor itemlist {sqliteExprListDelete($$);}
%type item {Expr*}
%destructor item {sqliteExprDelete($$);}
................................................................................
%type fieldlist_opt {IdList*}
%destructor fieldlist_opt {sqliteIdListDelete($$);}
%type fieldlist {IdList*}
%destructor fieldlist {sqliteIdListDelete($$);}

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.
%right NOT.
%left EQ NE ISNULL NOTNULL IS LIKE GLOB BETWEEN IN.
%left GT GE LT LE.
%left PLUS MINUS.
................................................................................

%type expr {Expr*}
%destructor expr {sqliteExprDelete($$);}

expr(A) ::= LP expr(X) RP.   {A = X;}
expr(A) ::= ID(X).           {A = sqliteExpr(TK_ID, 0, 0, &X);}
expr(A) ::= NULL.            {A = sqliteExpr(TK_NULL, 0, 0, 0);}
expr(A) ::= ID(X) DOT ID(Y). {Expr *temp1 = sqliteExpr(TK_ID, 0, 0, &X);
                              Expr *temp2 = sqliteExpr(TK_ID, 0, 0, &Y);
                              A = sqliteExpr(TK_DOT, temp1, temp2, 0);}
expr(A) ::= INTEGER(X).      {A = sqliteExpr(TK_INTEGER, 0, 0, &X);}
expr(A) ::= FLOAT(X).        {A = sqliteExpr(TK_FLOAT, 0, 0, &X);}
expr(A) ::= STRING(X).       {A = sqliteExpr(TK_STRING, 0, 0, &X);}
expr(A) ::= ID(X) LP exprlist(Y) RP.  {A = sqliteExprFunction(Y, &X);}
expr(A) ::= ID(X) LP STAR RP.         {A = sqliteExprFunction(0, &X);}
................................................................................
exprlist(A) ::= exprlist(X) COMMA expritem(Y). 
   {A = sqliteExprListAppend(X,Y,0);}
exprlist(A) ::= expritem(X).            {A = sqliteExprListAppend(0,X,0);}
expritem(A) ::= expr(X).                {A = X;}
expritem(A) ::= .                       {A = 0;}


cmd ::= CREATE(S) uniqueflag INDEX ID(X) ON ID(Y) LP idxlist(Z) RP(E).
    {sqliteCreateIndex(pParse, &X, &Y, Z, &S, &E);}
uniqueflag ::= UNIQUE.
uniqueflag ::= .

%type idxlist {IdList*}
%destructor idxlist {sqliteIdListDelete($$);}
%type idxitem {Token}

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);}

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







|







 







|
|





|







 







|







 







<
<
|







 







|











|


|

|

|

|







 







|
|







 







|







 







|












|










22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
..
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
...
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
...
174
175
176
177
178
179
180


181
182
183
184
185
186
187
188
...
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
261
262
263
264
265
...
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
...
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
...
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
**
*************************************************************************
** 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.18 2000/06/08 15:10:47 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);
................................................................................
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.
signed ::= MINUS INTEGER.
carglist ::= carglist carg.
carglist ::= .
carg ::= CONSTRAINT id ccons.
carg ::= ccons.
carg ::= DEFAULT STRING(X).          {sqliteAddDefaultValue(pParse,&X,0);}
carg ::= DEFAULT ID(X).              {sqliteAddDefaultValue(pParse,&X,0);}
carg ::= DEFAULT INTEGER(X).         {sqliteAddDefaultValue(pParse,&X,0);}
carg ::= DEFAULT PLUS INTEGER(X).    {sqliteAddDefaultValue(pParse,&X,0);}
carg ::= DEFAULT MINUS INTEGER(X).   {sqliteAddDefaultValue(pParse,&X,1);}
carg ::= DEFAULT FLOAT(X).           {sqliteAddDefaultValue(pParse,&X,0);}
................................................................................
// For the time being, the only constraint we care about is the primary
// key.
//
conslist_opt ::= .
conslist_opt ::= COMMA conslist.
conslist ::= conslist COMMA tcons.
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.
................................................................................
%destructor selcollist {sqliteExprListDelete($$);}
%type sclp {ExprList*}
%destructor sclp {sqliteExprListDelete($$);}
sclp(A) ::= selcollist(X) COMMA.             {A = X;}
sclp(A) ::= .                                {A = 0;}
selcollist(A) ::= STAR.                      {A = 0;}
selcollist(A) ::= sclp(P) expr(X).           {A = sqliteExprListAppend(P,X,0);}


selcollist(A) ::= sclp(P) expr(X) as id(Y).  {A = sqliteExprListAppend(P,X,&Y);}
as ::= .
as ::= AS.


%type seltablist {IdList*}
%destructor seltablist {sqliteIdListDelete($$);}
%type stl_prefix {IdList*}
................................................................................

%type having_opt {Expr*}
%destructor having_opt {sqliteExprDelete($$);}
having_opt(A) ::= .      {A = 0;}
having_opt(A) ::= HAVING expr(X).  {A = X;}


cmd ::= DELETE FROM id(X) where_opt(Y).
    {sqliteDeleteFrom(pParse, &X, Y);}

%type where_opt {Expr*}
%destructor where_opt {sqliteExprDelete($$);}

where_opt(A) ::= .                    {A = 0;}
where_opt(A) ::= WHERE expr(X).       {A = X;}

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

cmd ::= UPDATE id(X) SET setlist(Y) where_opt(Z).
    {sqliteUpdate(pParse,&X,Y,Z);}

setlist(A) ::= id(X) EQ expr(Y) COMMA setlist(Z).
    {A = sqliteExprListAppend(Z,Y,&X);}
setlist(A) ::= id(X) EQ expr(Y).   {A = sqliteExprListAppend(0,Y,&X);}

cmd ::= INSERT INTO id(X) fieldlist_opt(F) VALUES LP itemlist(Y) RP.
               {sqliteInsert(pParse, &X, Y, 0, F);}
cmd ::= INSERT INTO id(X) fieldlist_opt(F) select(S).
               {sqliteInsert(pParse, &X, 0, S, F);}


%type itemlist {ExprList*}
%destructor itemlist {sqliteExprListDelete($$);}
%type item {Expr*}
%destructor item {sqliteExprDelete($$);}
................................................................................
%type fieldlist_opt {IdList*}
%destructor fieldlist_opt {sqliteIdListDelete($$);}
%type fieldlist {IdList*}
%destructor fieldlist {sqliteIdListDelete($$);}

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.
%right NOT.
%left EQ NE ISNULL NOTNULL IS LIKE GLOB BETWEEN IN.
%left GT GE LT LE.
%left PLUS MINUS.
................................................................................

%type expr {Expr*}
%destructor expr {sqliteExprDelete($$);}

expr(A) ::= LP expr(X) RP.   {A = X;}
expr(A) ::= ID(X).           {A = sqliteExpr(TK_ID, 0, 0, &X);}
expr(A) ::= NULL.            {A = sqliteExpr(TK_NULL, 0, 0, 0);}
expr(A) ::= id(X) DOT id(Y). {Expr *temp1 = sqliteExpr(TK_ID, 0, 0, &X);
                              Expr *temp2 = sqliteExpr(TK_ID, 0, 0, &Y);
                              A = sqliteExpr(TK_DOT, temp1, temp2, 0);}
expr(A) ::= INTEGER(X).      {A = sqliteExpr(TK_INTEGER, 0, 0, &X);}
expr(A) ::= FLOAT(X).        {A = sqliteExpr(TK_FLOAT, 0, 0, &X);}
expr(A) ::= STRING(X).       {A = sqliteExpr(TK_STRING, 0, 0, &X);}
expr(A) ::= ID(X) LP exprlist(Y) RP.  {A = sqliteExprFunction(Y, &X);}
expr(A) ::= ID(X) LP STAR RP.         {A = sqliteExprFunction(0, &X);}
................................................................................
exprlist(A) ::= exprlist(X) COMMA expritem(Y). 
   {A = sqliteExprListAppend(X,Y,0);}
exprlist(A) ::= expritem(X).            {A = sqliteExprListAppend(0,X,0);}
expritem(A) ::= expr(X).                {A = X;}
expritem(A) ::= .                       {A = 0;}


cmd ::= CREATE(S) uniqueflag INDEX id(X) ON id(Y) LP idxlist(Z) RP(E).
    {sqliteCreateIndex(pParse, &X, &Y, Z, &S, &E);}
uniqueflag ::= UNIQUE.
uniqueflag ::= .

%type idxlist {IdList*}
%destructor idxlist {sqliteIdListDelete($$);}
%type idxitem {Token}

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);}

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

Changes to src/select.c.

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
...
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements.
**
** $Id: select.c,v 1.22 2000/06/08 13:36:40 drh Exp $
*/
#include "sqliteInt.h"

/*
** Allocate a new Select structure and return a pointer to that
** structure.
*/
................................................................................
  }
  pEList = pSelect->pEList;
  for(i=0; i<pOrderBy->nExpr; i++){
    Expr *pE = pOrderBy->a[i].pExpr;
    int match = 0;
    if( pOrderBy->a[i].done ) continue;
    for(j=0; j<pEList->nExpr; j++){
      if( pEList->a[i].zName && (pE->op==TK_ID || pE->op==TK_STRING) ){
        char *zName = pEList->a[i].zName;
        char *zLabel = sqliteStrNDup(pE->token.z, pE->token.n);
        sqliteDequote(zLabel);
        if( sqliteStrICmp(zName, zLabel)==0 ){ 
          match = 1; 
        }
        sqliteFree(zLabel);
      }
      if( match==0 && sqliteExprCompare(pE, pEList->a[i].pExpr) ){
        match = 1;
      }
      if( match ){
        pE->op = TK_FIELD;
        pE->iField = j;
        pE->iTable = iTable;
        pOrderBy->a[i].done = 1;







|







 







|
|







|







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
...
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements.
**
** $Id: select.c,v 1.23 2000/06/08 15:10:48 drh Exp $
*/
#include "sqliteInt.h"

/*
** Allocate a new Select structure and return a pointer to that
** structure.
*/
................................................................................
  }
  pEList = pSelect->pEList;
  for(i=0; i<pOrderBy->nExpr; i++){
    Expr *pE = pOrderBy->a[i].pExpr;
    int match = 0;
    if( pOrderBy->a[i].done ) continue;
    for(j=0; j<pEList->nExpr; j++){
      if( pEList->a[j].zName && (pE->op==TK_ID || pE->op==TK_STRING) ){
        char *zName = pEList->a[j].zName;
        char *zLabel = sqliteStrNDup(pE->token.z, pE->token.n);
        sqliteDequote(zLabel);
        if( sqliteStrICmp(zName, zLabel)==0 ){ 
          match = 1; 
        }
        sqliteFree(zLabel);
      }
      if( match==0 && sqliteExprCompare(pE, pEList->a[j].pExpr) ){
        match = 1;
      }
      if( match ){
        pE->op = TK_FIELD;
        pE->iField = j;
        pE->iTable = iTable;
        pOrderBy->a[i].done = 1;

Changes to src/vdbe.c.

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
....
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
** 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.28 2000/06/08 13:36:41 drh Exp $
*/
#include "sqliteInt.h"
#include <unistd.h>

/*
** SQL is translated into a sequence of instructions to be
** executed by a virtual machine.  Each instruction is an instance
................................................................................
          case SQLITE_PERM: {
            sqliteSetString(pzErrMsg, pOp->p2 ? "write" : "read",
              " permission denied for table ", pOp->p3, 0);
            break;
          }
          case SQLITE_READONLY: {
            sqliteSetString(pzErrMsg,"table ", pOp->p3, 
               " is already opened for reading", 0);
            break;
          }
          case SQLITE_NOMEM: {
            goto no_mem;
          }
        }
        p->aTab[i].index = 0;







|







 







|







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
....
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
** 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.29 2000/06/08 15:10:48 drh Exp $
*/
#include "sqliteInt.h"
#include <unistd.h>

/*
** SQL is translated into a sequence of instructions to be
** executed by a virtual machine.  Each instruction is an instance
................................................................................
          case SQLITE_PERM: {
            sqliteSetString(pzErrMsg, pOp->p2 ? "write" : "read",
              " permission denied for table ", pOp->p3, 0);
            break;
          }
          case SQLITE_READONLY: {
            sqliteSetString(pzErrMsg,"table ", pOp->p3, 
               " is readonly", 0);
            break;
          }
          case SQLITE_NOMEM: {
            goto no_mem;
          }
        }
        p->aTab[i].index = 0;

Changes to test/dbbe.test.

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
...
114
115
116
117
118
119
120
121














122
#   drh@hwaci.com
#   http://www.hwaci.com/drh/
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is exercising the code in dbbe.c.
#
# $Id: dbbe.test,v 1.1 2000/06/07 14:42:27 drh Exp $

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

# Try to open a database that does not exist.
#
do_test dbbe-1.1 {
................................................................................
  db close
  sqlite db testdb 0444
  set r [execsql {SELECT * FROM T1}]
  db close
  sqlite db testdb 0666
  lappend r [execsql {SELECT * FROM t1}]
} {1 1}















finish_test







|







 








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

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
...
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#   drh@hwaci.com
#   http://www.hwaci.com/drh/
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is exercising the code in dbbe.c.
#
# $Id: dbbe.test,v 1.2 2000/06/08 15:10:48 drh Exp $

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

# Try to open a database that does not exist.
#
do_test dbbe-1.1 {
................................................................................
  db close
  sqlite db testdb 0444
  set r [execsql {SELECT * FROM T1}]
  db close
  sqlite db testdb 0666
  lappend r [execsql {SELECT * FROM t1}]
} {1 1}

# Try to change a table after opening the database readonly
#
do_test dbbe-3.1 {
  catch {db close}
  file delete -force testdb
  sqlite db testdb 0666
  execsql {CREATE TABLE t1(x int)}
  db close
  sqlite db testdb 0444
  set v [catch {execsql {INSERT INTO t1 VALUES(1)}} msg]
  lappend v $msg
} {1 {write permission denied for table t1}}


finish_test

Changes to test/delete.test.

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
..
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#   drh@hwaci.com
#   http://www.hwaci.com/drh/
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the DELETE FROM statement.
#
# $Id: delete.test,v 1.4 2000/06/03 19:19:42 drh Exp $

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

# Try to delete from a non-existant table.
#
do_test delete-1.1 {
................................................................................
} {1 2 2 4 3 8 4 16}
do_test delete-3.1b {
  execsql {DELETE FROM table1 WHERE f1=3}
  execsql {SELECT * FROM table1 ORDER BY f1}
} {1 2 2 4 4 16}
do_test delete-3.1c {
  execsql {CREATE INDEX index1 ON table1(f1)}
  execsql {DELETE FROM table1 WHERE f1=3}
  execsql {SELECT * FROM table1 ORDER BY f1}
} {1 2 2 4 4 16}
do_test delete-3.1d {
  execsql {DELETE FROM table1 WHERE f1=2}
  execsql {SELECT * FROM table1 ORDER BY f1}
} {1 2 4 16}








|







 







|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
..
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#   drh@hwaci.com
#   http://www.hwaci.com/drh/
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the DELETE FROM statement.
#
# $Id: delete.test,v 1.5 2000/06/08 15:10:48 drh Exp $

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

# Try to delete from a non-existant table.
#
do_test delete-1.1 {
................................................................................
} {1 2 2 4 3 8 4 16}
do_test delete-3.1b {
  execsql {DELETE FROM table1 WHERE f1=3}
  execsql {SELECT * FROM table1 ORDER BY f1}
} {1 2 2 4 4 16}
do_test delete-3.1c {
  execsql {CREATE INDEX index1 ON table1(f1)}
  execsql {DELETE FROM 'table1' WHERE f1=3}
  execsql {SELECT * FROM table1 ORDER BY f1}
} {1 2 2 4 4 16}
do_test delete-3.1d {
  execsql {DELETE FROM table1 WHERE f1=2}
  execsql {SELECT * FROM table1 ORDER BY f1}
} {1 2 4 16}

Changes to test/select3.test.

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
...
107
108
109
110
111
112
113















114
#   http://www.hwaci.com/drh/
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing aggregate functions and the
# GROUP BY and HAVING clauses of SELECT statements.
#
# $Id: select3.test,v 1.1 2000/06/06 18:00:16 drh Exp $

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

# Build some test data
#
do_test select3-1.0 {
................................................................................
    SELECT log, count(*) FROM t1 
    GROUP BY log 
    HAVING count(*)>=4 
    ORDER BY max(n)
  }
} {3 4 4 8 5 15}
















finish_test







|







 







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

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
...
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#   http://www.hwaci.com/drh/
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing aggregate functions and the
# GROUP BY and HAVING clauses of SELECT statements.
#
# $Id: select3.test,v 1.2 2000/06/08 15:10:48 drh Exp $

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

# Build some test data
#
do_test select3-1.0 {
................................................................................
    SELECT log, count(*) FROM t1 
    GROUP BY log 
    HAVING count(*)>=4 
    ORDER BY max(n)
  }
} {3 4 4 8 5 15}

do_test select3-5.1 {
  execsql {
    SELECT log, count(*), avg(n), max(n+log*2) FROM t1 
    GROUP BY log 
    ORDER BY max(n+log*2), avg(n)
  }
} {0 1 1 1 1 1 2 4 2 2 3.5 8 3 4 6.5 14 4 8 12.5 24 5 15 24 41}
do_test select3-5.2 {
  execsql {
    SELECT log, count(*), avg(n), max(n+log*2) FROM t1 
    GROUP BY log 
    ORDER BY max(n+log*2), min(log,avg(n))
  }
} {0 1 1 1 1 1 2 4 2 2 3.5 8 3 4 6.5 14 4 8 12.5 24 5 15 24 41}

finish_test

Changes to test/select4.test.

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
...
240
241
242
243
244
245
246

















247
#   http://www.hwaci.com/drh/
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing UNION, INTERSECT and EXCEPT operators
# in SELECT statements.
#
# $Id: select4.test,v 1.2 2000/06/08 01:55:31 drh Exp $

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

# Build some test data
#
set fd [open data1.txt w]
................................................................................
    UNION ALL
    SELECT log FROM t1 WHERE n=5
    ORDER BY log;
  }} msg]
  lappend v $msg
} {0 {1 2 2 3}}


















finish_test







|







 







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

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
...
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
#   http://www.hwaci.com/drh/
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing UNION, INTERSECT and EXCEPT operators
# in SELECT statements.
#
# $Id: select4.test,v 1.3 2000/06/08 15:10:48 drh Exp $

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

# Build some test data
#
set fd [open data1.txt w]
................................................................................
    UNION ALL
    SELECT log FROM t1 WHERE n=5
    ORDER BY log;
  }} msg]
  lappend v $msg
} {0 {1 2 2 3}}

do_test select4-6.1 {
  execsql {
    SELECT log, count(*) as cnt FROM t1 GROUP BY log
    UNION
    SELECT log, n FROM t1 WHERE n=7
    ORDER BY cnt, log;
  }
} {0 1 1 1 2 2 3 4 3 7 4 8 5 15}
do_test select4-6.2 {
  execsql {
    SELECT log, count(*) FROM t1 GROUP BY log
    UNION
    SELECT log, n FROM t1 WHERE n=7
    ORDER BY count(*), log;
  }
} {0 1 1 1 2 2 3 4 3 7 4 8 5 15}

finish_test

Changes to test/table.test.

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
...
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
...
281
282
283
284
285
286
287








288
#   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 {
................................................................................
} {}



# 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]
  lappend v $msg
} {1 {table test2 already exists}}
do_test table-2.1b {
  set v [catch {execsql {CREATE TABLE sqlite_master(two text)}} msg]
  lappend v $msg
} {1 {table sqlite_master already exists}}
................................................................................
#
do_test table-5.4 {
  execsql {CREATE TABLE test1(f1 int)}
  execsql {EXPLAIN DROP TABLE test1}
  execsql {SELECT name FROM sqlite_master}
} {test1}









finish_test







|







 







|







 







>
>
>
>
>
>
>
>

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
...
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
...
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
#   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.5 2000/06/08 15:10:48 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 {
................................................................................
} {}



# 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]
  lappend v $msg
} {1 {table test2 already exists}}
do_test table-2.1b {
  set v [catch {execsql {CREATE TABLE sqlite_master(two text)}} msg]
  lappend v $msg
} {1 {table sqlite_master already exists}}
................................................................................
#
do_test table-5.4 {
  execsql {CREATE TABLE test1(f1 int)}
  execsql {EXPLAIN DROP TABLE test1}
  execsql {SELECT name FROM sqlite_master}
} {test1}

# Create a table with a goofy name
#
do_test table-6.1 {
  execsql {CREATE TABLE 'Spaces In This Name!'(x int)}
  execsql {INSERT INTO 'spaces in this name!' VALUES(1)}
  set list [glob -nocomplain testdb/spaces*.tbl]
} {testdb/spaces+in+this+name+.tbl}

finish_test