SQLite

Check-in [86b30cd097]
Login

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

Overview
Comment:better handling of out-of-memory errors (CVS 207)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 86b30cd0975dfea9424b9f9f0d4194aa71ce508b
User & Date: drh 2001-04-11 14:28:42.000
Context
2001-04-11
14:29
:-) (CVS 208) (check-in: 555351dd19 user: drh tags: trunk)
14:28
better handling of out-of-memory errors (CVS 207) (check-in: 86b30cd097 user: drh tags: trunk)
2001-04-07
15:24
Added new tests (CVS 206) (check-in: 2507ec4061 user: drh tags: trunk)
Changes
Side-by-Side Diff Ignore Whitespace Patch
Changes to src/build.c.
29
30
31
32
33
34
35
36

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

52
53
54
55
56
57
58
29
30
31
32
33
34
35

36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59







-
+















+







**     DROP TABLE
**     CREATE INDEX
**     DROP INDEX
**     creating expressions and ID lists
**     COPY
**     VACUUM
**
** $Id: build.c,v 1.26 2001/04/04 11:48:57 drh Exp $
** $Id: build.c,v 1.27 2001/04/11 14:28:42 drh Exp $
*/
#include "sqliteInt.h"

/*
** This routine is called after a single SQL statement has been
** parsed and we want to execute the VDBE code to implement 
** that statement.  Prior action routines should have already
** constructed VDBE code to do the work of the SQL statement.
** This routine just has to execute the VDBE code.
**
** Note that if an error occurred, it might be the case that
** no VDBE code was generated.
*/
void sqliteExec(Parse *pParse){
  int rc = SQLITE_OK;
  if( sqlite_malloc_failed ) return;
  if( pParse->pVdbe ){
    if( pParse->explain ){
      rc = sqliteVdbeList(pParse->pVdbe, pParse->xCallback, pParse->pArg, 
                          &pParse->zErrMsg);
    }else{
      FILE *trace = (pParse->db->flags & SQLITE_VdbeTrace)!=0 ? stderr : 0;
      sqliteVdbeTrace(pParse->pVdbe, trace);
92
93
94
95
96
97
98

99
100



101
102
103
104
105
106
107
93
94
95
96
97
98
99
100


101
102
103
104
105
106
107
108
109
110







+
-
-
+
+
+







}

/*
** Set the Expr.token field of the given expression to span all
** text between the two given tokens.
*/
void sqliteExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){
  if( pExpr ){
  pExpr->span.z = pLeft->z;
  pExpr->span.n = pRight->n + (int)pRight->z - (int)pLeft->z;
    pExpr->span.z = pLeft->z;
    pExpr->span.n = pRight->n + (int)pRight->z - (int)pLeft->z;
  }
}

/*
** Construct a new expression node for a function with multiple
** arguments.
*/
Expr *sqliteExprFunction(ExprList *pList, Token *pToken){
163
164
165
166
167
168
169
170
171
172



173
174
175
176

177
178
179
180
181
182
183
166
167
168
169
170
171
172



173
174
175
176
177
178

179
180
181
182
183
184
185
186







-
-
-
+
+
+



-
+







  return 0;
}

/*
** Remove the given index from the index hash table, and free
** its memory structures.
**
** The index is removed from the database hash table, but it is
** not unlinked from the Table that is being indexed.  Unlinking
** from the Table must be done by the calling function.
** The index is removed from the database hash table if db!=NULL.
** But it is not unlinked from the Table that is being indexed.  
** Unlinking from the Table must be done by the calling function.
*/
static void sqliteDeleteIndex(sqlite *db, Index *pIndex){
  int h;
  if( pIndex->zName ){
  if( pIndex->zName && db ){
    h = sqliteHashNoCase(pIndex->zName, 0) % N_HASH;
    if( db->apIdxHash[h]==pIndex ){
      db->apIdxHash[h] = pIndex->pHash;
    }else{
      Index *p;
      for(p=db->apIdxHash[h]; p && p->pHash!=pIndex; p=p->pHash){}
      if( p && p->pHash==pIndex ){
191
192
193
194
195
196
197





198
199
200
201
202
203
204
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212







+
+
+
+
+







/*
** Remove the memory data structures associated with the given
** Table.  No changes are made to disk by this routine.
**
** This routine just deletes the data structure.  It does not unlink
** the table data structure from the hash table.  But does it destroy
** memory structures of the indices associated with the table.
**
** Indices associated with the table are unlinked from the "db"
** data structure if db!=NULL.  If db==NULL, indices attached to
** the table are deleted, but it is assumed they have already been
** unlinked.
*/
void sqliteDeleteTable(sqlite *db, Table *pTable){
  int i;
  Index *pIndex, *pNext;
  if( pTable==0 ) return;
  for(i=0; i<pTable->nCol; i++){
    sqliteFree(pTable->aCol[i].zName);
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
268
269
270
271
272
273
274
275
276
277
278
279
280
281




282
283
284
285
286
287
288
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
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282




283
284
285
286
287
288
289
290
291
292
293







+
















-
+
-
-
-
-


















-
-
-
-
+
+
+
+







*/
void sqliteStartTable(Parse *pParse, Token *pStart, Token *pName){
  Table *pTable;
  char *zName;

  pParse->sFirstToken = *pStart;
  zName = sqliteTableNameFromToken(pName);
  if( zName==0 ) return;
  pTable = sqliteFindTable(pParse->db, zName);
  if( pTable!=0 ){
    sqliteSetNString(&pParse->zErrMsg, "table ", 0, pName->z, pName->n,
        " already exists", 0, 0);
    sqliteFree(zName);
    pParse->nErr++;
    return;
  }
  if( sqliteFindIndex(pParse->db, zName) ){
    sqliteSetString(&pParse->zErrMsg, "there is already an index named ", 
       zName, 0);
    sqliteFree(zName);
    pParse->nErr++;
    return;
  }
  pTable = sqliteMalloc( sizeof(Table) );
  if( pTable==0 ){
  if( pTable==0 ) return;
    sqliteSetString(&pParse->zErrMsg, "out of memory", 0);
    pParse->nErr++;
    return;
  }
  pTable->zName = zName;
  pTable->pHash = 0;
  pTable->nCol = 0;
  pTable->aCol = 0;
  pTable->pIndex = 0;
  if( pParse->pNewTable ) sqliteDeleteTable(pParse->db, pParse->pNewTable);
  pParse->pNewTable = pTable;
}

/*
** Add a new column to the table currently being constructed.
*/
void sqliteAddColumn(Parse *pParse, Token *pName){
  Table *p;
  char **pz;
  if( (p = pParse->pNewTable)==0 ) return;
  if( (p->nCol & 0x7)==0 ){
    p->aCol = sqliteRealloc( p->aCol, (p->nCol+8)*sizeof(p->aCol[0]));
  }
  if( p->aCol==0 ){
    p->nCol = 0;
    return;
    if( p->aCol==0 ){
      p->nCol = 0;
      return;
    }
  }
  memset(&p->aCol[p->nCol], 0, sizeof(p->aCol[0]));
  pz = &p->aCol[p->nCol++].zName;
  sqliteSetNString(pz, pName->z, pName->n, 0);
  sqliteDequote(*pz);
}

319
320
321
322
323
324
325
326

327

328

329
330
331
332

333
334
335
336
337
338
339
324
325
326
327
328
329
330

331
332
333

334
335
336
337

338
339
340
341
342
343
344
345







-
+

+
-
+



-
+







** We do not want to create it again.
*/
void sqliteEndTable(Parse *pParse, Token *pEnd){
  Table *p;
  int h;
  int addMeta;       /* True to insert a meta records into the file */

  if( pParse->nErr ) return;
  if( pEnd==0 || pParse->nErr || sqlite_malloc_failed ) return;
  p = pParse->pNewTable;
  if( p==0 ) return;
  addMeta =  p!=0 && pParse->db->nTable==1;
  addMeta =  pParse->db->nTable==1;

  /* Add the table to the in-memory representation of the database
  */
  if( p!=0 && pParse->explain==0 ){
  if( pParse->explain==0 ){
    h = sqliteHashNoCase(p->zName, 0) % N_HASH;
    p->pHash = pParse->db->apTblHash[h];
    pParse->db->apTblHash[h] = p;
    pParse->pNewTable = 0;
    pParse->db->nTable++;
  }

377
378
379
380
381
382
383


384
385



386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403

404
405
406
407
408
409
410
383
384
385
386
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
419
420







+
+
-
-
+
+
+


















+







}

/*
** Given a token, look up a table with that name.  If not found, leave
** an error for the parser to find and return NULL.
*/
Table *sqliteTableFromToken(Parse *pParse, Token *pTok){
  char *zName;
  Table *pTab;
  char *zName = sqliteTableNameFromToken(pTok);
  Table *pTab = sqliteFindTable(pParse->db, zName);
  zName = sqliteTableNameFromToken(pTok);
  if( zName==0 ) return 0;
  pTab = sqliteFindTable(pParse->db, zName);
  sqliteFree(zName);
  if( pTab==0 ){
    sqliteSetNString(&pParse->zErrMsg, "no such table: ", 0, 
        pTok->z, pTok->n, 0);
    pParse->nErr++;
  }
  return pTab;
}

/*
** This routine is called to do the work of a DROP TABLE statement.
*/
void sqliteDropTable(Parse *pParse, Token *pName){
  Table *pTable;
  int h;
  Vdbe *v;
  int base;

  if( pParse->nErr || sqlite_malloc_failed ) return;
  pTable = sqliteTableFromToken(pParse, pName);
  if( pTable==0 ) return;
  if( pTable->readOnly ){
    sqliteSetString(&pParse->zErrMsg, "table ", pTable->zName, 
       " may not be dropped", 0);
    pParse->nErr++;
    return;
482
483
484
485
486
487
488


489
490
491
492
493
494
495
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507







+
+







){
  Table *pTab;     /* Table to be indexed */
  Index *pIndex;   /* The index to be created */
  char *zName = 0;
  int i, j, h;
  Token nullId;    /* Fake token for an empty ID list */

  if( pParse->nErr || sqlite_malloc_failed ) goto exit_create_index;

  /*
  ** Find the table that is to be indexed.  Return early if not found.
  */
  if( pTable!=0 ){
    pTab =  sqliteTableFromToken(pParse, pTable);
  }else{
    pTab =  pParse->pNewTable;
508
509
510
511
512
513
514

515
516
517
518
519
520
521
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534







+







  */
  if( pName ){
    zName = sqliteTableNameFromToken(pName);
  }else{
    zName = 0;
    sqliteSetString(&zName, pTab->zName, "__primary_key", 0);
  }
  if( zName==0 ) goto exit_create_index;
  if( sqliteFindIndex(pParse->db, zName) ){
    sqliteSetString(&pParse->zErrMsg, "index ", zName, 
       " already exists", 0);
    pParse->nErr++;
    goto exit_create_index;
  }
  if( sqliteFindTable(pParse->db, zName) ){
537
538
539
540
541
542
543
544

545
546
547
548
549
550
551
552
553
554
555
550
551
552
553
554
555
556

557




558
559
560
561
562
563
564







-
+
-
-
-
-







  }

  /* 
  ** Allocate the index structure. 
  */
  pIndex = sqliteMalloc( sizeof(Index) + strlen(zName) + 1 +
                        sizeof(int)*pList->nId );
  if( pIndex==0 ){
  if( pIndex==0 ) goto exit_create_index;
    sqliteSetString(&pParse->zErrMsg, "out of memory", 0);
    pParse->nErr++;
    goto exit_create_index;
  }
  pIndex->aiColumn = (int*)&pIndex[1];
  pIndex->zName = (char*)&pIndex->aiColumn[pList->nId];
  strcpy(pIndex->zName, zName);
  pIndex->pTable = pTab;
  pIndex->nColumn = pList->nId;

  /* Scan the names of the columns of the table to be indexed and
652
653
654
655
656
657
658

659

660
661
662
663
664
665
666
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677







+

+







** This routine will drop an existing named index.
*/
void sqliteDropIndex(Parse *pParse, Token *pName){
  Index *pIndex;
  char *zName;
  Vdbe *v;

  if( pParse->nErr || sqlite_malloc_failed ) return;
  zName = sqliteTableNameFromToken(pName);
  if( zName==0 ) return;
  pIndex = sqliteFindIndex(pParse->db, zName);
  sqliteFree(zName);
  if( pIndex==0 ){
    sqliteSetNString(&pParse->zErrMsg, "no such index: ", 0, 
        pName->z, pName->n, 0);
    pParse->nErr++;
    return;
710
711
712
713
714
715
716
717
718


719
720
721
722
723
724
725
721
722
723
724
725
726
727


728
729
730
731
732
733
734
735
736







-
-
+
+







** Add a new element to the end of an expression list.  If pList is
** initially NULL, then create a new expression list.
*/
ExprList *sqliteExprListAppend(ExprList *pList, Expr *pExpr, Token *pName){
  int i;
  if( pList==0 ){
    pList = sqliteMalloc( sizeof(ExprList) );
  }
  if( pList==0 ) return 0;
    if( pList==0 ) return 0;
  }
  if( (pList->nExpr & 7)==0 ){
    int n = pList->nExpr + 8;
    pList->a = sqliteRealloc(pList->a, n*sizeof(pList->a[0]));
    if( pList->a==0 ){
      pList->nExpr = 0;
      return pList;
    }
747
748
749
750
751
752
753


754
755
756
757
758
759
760
761
762
763

764

765
766
767
768
769
770








771
772
773
774
775
776
777
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777

778
779
780
781
782


783
784
785
786
787
788
789
790
791
792
793
794
795
796
797







+
+










+
-
+




-
-
+
+
+
+
+
+
+
+







  sqliteFree(pList->a);
  sqliteFree(pList);
}

/*
** Append a new element to the given IdList.  Create a new IdList if
** need be.
**
** A new IdList is returned, or NULL if malloc() fails.
*/
IdList *sqliteIdListAppend(IdList *pList, Token *pToken){
  if( pList==0 ){
    pList = sqliteMalloc( sizeof(IdList) );
    if( pList==0 ) return 0;
  }
  if( (pList->nId & 7)==0 ){
    pList->a = sqliteRealloc(pList->a, (pList->nId+8)*sizeof(pList->a[0]) );
    if( pList->a==0 ){
      pList->nId = 0;
      sqliteIdListDelete(pList);
      return pList;
      return 0;
    }
  }
  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);
    char **pz = &pList->a[pList->nId].zName;
    sqliteSetNString(pz, pToken->z, pToken->n, 0);
    if( *pz==0 ){
      sqliteIdListDelete(pList);
      return 0;
    }else{
      sqliteDequote(*pz);
    }
  }
  pList->nId++;
  return pList;
}

/*
** Add an alias to the last identifier on the given identifier list.
789
790
791
792
793
794
795





796
797
798
799
800
801
802
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827







+
+
+
+
+







*/
void sqliteIdListDelete(IdList *pList){
  int i;
  if( pList==0 ) return;
  for(i=0; i<pList->nId; i++){
    sqliteFree(pList->a[i].zName);
    sqliteFree(pList->a[i].zAlias);
    if( pList->a[i].pSelect ){
      sqliteFree(pList->a[i].zName);
      sqliteSelectDelete(pList->a[i].pSelect);
      sqliteDeleteTable(0, pList->a[i].pTab);
    }
  }
  sqliteFree(pList->a);
  sqliteFree(pList);
}


/*
820
821
822
823
824
825
826

827
828
829
830
831
832
833
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859







+







  char *zTab;
  int i, j;
  Vdbe *v;
  int addr, end;
  Index *pIdx;

  zTab = sqliteTableNameFromToken(pTableName);
  if( sqlite_malloc_failed || zTab==0 ) goto copy_cleanup;
  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;
887
888
889
890
891
892
893

894
895
896
897
898
899
900
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927







+







** collapse free space, etc.  It is modelled after the VACUUM command
** in PostgreSQL.
*/
void sqliteVacuum(Parse *pParse, Token *pTableName){
  char *zName;
  Vdbe *v;

  if( pParse->nErr || sqlite_malloc_failed ) return;
  if( pTableName ){
    zName = sqliteTableNameFromToken(pTableName);
  }else{
    zName = 0;
  }
  if( zName && sqliteFindIndex(pParse->db, zName)==0
    && sqliteFindTable(pParse->db, zName)==0 ){
929
930
931
932
933
934
935

936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955

956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975

976
977
978
979
980
981
982
983
984
985
986
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016







+




















+




















+











** Begin a transaction
*/
void sqliteBeginTransaction(Parse *pParse){
  int rc;
  DbbeMethods *pM;
  sqlite *db;
  if( pParse==0 || (db=pParse->db)==0 || db->pBe==0 ) return;
  if( pParse->nErr || sqlite_malloc_failed ) return;
  if( db->flags & SQLITE_InTrans ) return;
  pM = pParse->db->pBe->x;
  if( pM && pM->BeginTransaction ){
    rc = (*pM->BeginTransaction)(pParse->db->pBe);
  }else{
    rc = SQLITE_OK;
  }
  if( rc==SQLITE_OK ){
    db->flags |= SQLITE_InTrans;
  }
}

/*
** Commit a transaction
*/
void sqliteCommitTransaction(Parse *pParse){
  int rc;
  DbbeMethods *pM;
  sqlite *db;
  if( pParse==0 || (db=pParse->db)==0 || db->pBe==0 ) return;
  if( pParse->nErr || sqlite_malloc_failed ) return;
  if( (db->flags & SQLITE_InTrans)==0 ) return;
  pM = pParse->db->pBe->x;
  if( pM && pM->Commit ){
    rc = (*pM->Commit)(pParse->db->pBe);
  }else{
    rc = SQLITE_OK;
  }
  if( rc==SQLITE_OK ){
    db->flags &= ~SQLITE_InTrans;
  }
}

/*
** Rollback a transaction
*/
void sqliteRollbackTransaction(Parse *pParse){
  int rc;
  DbbeMethods *pM;
  sqlite *db;
  if( pParse==0 || (db=pParse->db)==0 || db->pBe==0 ) return;
  if( pParse->nErr || sqlite_malloc_failed ) return;
  if( (db->flags & SQLITE_InTrans)==0 ) return;
  pM = pParse->db->pBe->x;
  if( pM && pM->Rollback ){
    rc = (*pM->Rollback)(pParse->db->pBe);
  }else{
    rc = SQLITE_OK;
  }
  if( rc==SQLITE_OK ){
    db->flags &= ~SQLITE_InTrans;
  }
}
Changes to src/dbbe.c.
26
27
28
29
30
31
32
33

34
35
36
37
38
39
40
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40







-
+







** 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.26 2001/04/04 21:22:14 drh Exp $
** $Id: dbbe.c,v 1.27 2001/04/11 14:28:42 drh Exp $
*/
#include "sqliteInt.h"
#include <unistd.h>
#include <ctype.h>

/*
** This routine opens a new database.  It looks at the first
61
62
63
64
65
66
67

68
69
70
71
72
73
74
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75







+







  if( strncmp(zName, "memory:", 7)==0 ){
    extern Dbbe *sqliteMemOpen(const char*,int,int,char**);
    return sqliteMemOpen(&zName[7], writeFlag, createFlag, pzErrMsg);
  }
  return sqliteGdbmOpen(zName, writeFlag, createFlag, pzErrMsg);
}

#if 0  /* NOT USED */
/*
** Translate the name of an SQL table (or index) into the name 
** of a file that holds the key/data pairs for that table or
** index.  Space to hold the filename is obtained from
** sqliteMalloc() and must be freed by the calling function.
**
** zDir is the name of the directory in which the file should
111
112
113
114
115
116
117

112
113
114
115
116
117
118
119







+
  }
  for(k=0; (c = zSuffix[k])!=0; k++){
    zFile[i++] = c;
  }
  zFile[i] = 0;
  return zFile;
}
#endif /* NOT USED */
Changes to src/dbbegdbm.c.
26
27
28
29
30
31
32
33

34
35
36
37
38
39
40
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40







-
+







** 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: dbbegdbm.c,v 1.6 2001/04/04 11:48:57 drh Exp $
** $Id: dbbegdbm.c,v 1.7 2001/04/11 14:28:42 drh Exp $
*/
#include "sqliteInt.h"
#include <gdbm.h>
#include <sys/stat.h>
#include <unistd.h>
#include <ctype.h>
#include <time.h>
181
182
183
184
185
186
187

188
189
190
191
192
193
194
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195







+








  if( pBe->inTrans ) writeable = 1;
  *ppCursr = 0;
  pCursr = sqliteMalloc( sizeof(*pCursr) );
  if( pCursr==0 ) return SQLITE_NOMEM;
  if( zTable ){
    zFile = sqliteFileOfTable(pBe, zTable);
    if( zFile==0 ) return SQLITE_NOMEM;
    for(pFile=pBe->pOpen; pFile; pFile=pFile->pNext){
      if( strcmp(pFile->zName,zFile)==0 ) break;
    }
  }else{
    pFile = 0;
    zFile = 0;
  }
Changes to src/dbbemem.c.
26
27
28
29
30
31
32
33

34
35
36
37
38
39
40
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40







-
+







** sqlite and the code that does the actually reading and writing
** of information to the disk.
**
** This file uses an in-memory hash table as the database backend. 
** Nothing is ever written to disk using this backend.  All information
** is forgotten when the program exits.
**
** $Id: dbbemem.c,v 1.13 2001/04/04 11:48:58 drh Exp $
** $Id: dbbemem.c,v 1.14 2001/04/11 14:28:42 drh Exp $
*/
#include "sqliteInt.h"
#include <sys/stat.h>
#include <unistd.h>
#include <ctype.h>
#include <time.h>

152
153
154
155
156
157
158

159
160
161
162
163
164
165
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166







+







static void ArrayRehash(Array *array, int new_size){
  struct _Array_ht *new_ht;       /* The new hash table */
  ArrayElem *elem, *next_elem;    /* For looping over existing elements */
  int i;                          /* Loop counter */
  ArrayElem *x;                   /* Element being copied to new hash table */

  new_ht = sqliteMalloc( new_size*sizeof(struct _Array_ht) );
  if( new_ht==0 ){ ArrayClear(array); return; }
  if( array->ht ) sqliteFree(array->ht);
  array->ht = new_ht;
  array->htsize = new_size;
  for(i=new_size-1; i>=0; i--){ 
    new_ht[i].count = 0;
    new_ht[i].chain = 0;
  }
301
302
303
304
305
306
307

308
309




310
311
312
313
314
315
316
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322







+


+
+
+
+







  new_elem = (ArrayElem*)sqliteMalloc( sizeof(ArrayElem) + key.n );
  if( new_elem==0 ) return nil;
  new_elem->key.n = key.n;
  new_elem->key.p = (void*)&new_elem[1];
  memcpy(new_elem->key.p, key.p, key.n);
  array->count++;
  if( array->htsize==0 ) ArrayRehash(array,4);
  if( array->htsize==0 ) return nil;
  if( array->count > array->htsize ){
    ArrayRehash(array,array->htsize*2);
    if( array->htsize==0 ){
      sqliteFree(new_elem);
      return nil;
    }
  }
  h = hraw & (array->htsize-1);
  elem = array->ht[h].chain;
  if( elem ){
    new_elem->next = elem;
    new_elem->prev = elem->prev;
    if( elem->prev ){ elem->prev->next = new_elem; }
464
465
466
467
468
469
470

471
472
473
474
475
476
477
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484







+








  *ppCursr = 0;
  pCursr = sqliteMalloc( sizeof(*pCursr) );
  if( pCursr==0 ) return SQLITE_NOMEM;
  if( zTable ){
    Datum key;
    zName = sqliteNameOfTable(zTable);
    if( zName==0 ) return SQLITE_NOMEM;
    key.p = zName;
    key.n = strlen(zName);
    pTble = ArrayFind(&pBe->tables, key).p;
  }else{
    zName = 0;
    pTble = 0;
  }
686
687
688
689
690
691
692

693
694
695
696
697
698
699
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707







+







  DbbeCursor *pCursr,       /* Write new entry into this database table */
  int nKey, char *pKey,     /* The key of the new entry */
  int nData, char *pData    /* The data of the new entry */
){
  Datum data, key;
  data.n = nData;
  data.p = sqliteMalloc( data.n );
  if( data.p==0 ) return SQLITE_NOMEM;
  memcpy(data.p, pData, data.n);
  key.n = nKey;
  key.p = pKey;
  assert( nKey==4 || pCursr->pTble->intKeyOnly==0 );
  data = ArrayInsert(&pCursr->pTble->data, key, data);
  if( data.p ){
    sqliteFree(data.p);
Changes to src/delete.c.
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





47
48
49
50
51
52
53

54
55
56
57
58
59
60
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66







-
+



















+
+
+
+
+







+







**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle DELETE FROM statements.
**
** $Id: delete.c,v 1.8 2001/03/20 22:05:00 drh Exp $
** $Id: delete.c,v 1.9 2001/04/11 14:28:42 drh Exp $
*/
#include "sqliteInt.h"

/*
** Process a DELETE FROM statement.
*/
void sqliteDeleteFrom(
  Parse *pParse,         /* The parser context */
  Token *pTableName,     /* The table from which we should delete things */
  Expr *pWhere           /* The WHERE clause.  May be null */
){
  Vdbe *v;               /* The virtual database engine */
  Table *pTab;           /* The table from which records will be deleted */
  IdList *pTabList;      /* An ID list holding pTab and nothing else */
  int end, addr;         /* A couple addresses of generated code */
  int i;                 /* Loop counter */
  WhereInfo *pWInfo;     /* Information about the WHERE clause */
  Index *pIdx;           /* For looping over indices of the table */
  int base;              /* Index of the first available table cursor */

  if( pParse->nErr || sqlite_malloc_failed ){
    pTabList = 0;
    goto delete_from_cleanup;
  }

  /* Locate the table which we want to delete.  This table has to be
  ** put in an IdList structure because some of the subroutines we
  ** will be calling are designed to work with multiple tables and expect
  ** an IdList* parameter instead of just a Table* parameger.
  */
  pTabList = sqliteIdListAppend(0, pTableName);
  if( pTabList==0 ) goto delete_from_cleanup;
  for(i=0; i<pTabList->nId; i++){
    pTabList->a[i].pTab = sqliteFindTable(pParse->db, pTabList->a[i].zName);
    if( pTabList->a[i].pTab==0 ){
      sqliteSetString(&pParse->zErrMsg, "no such table: ", 
         pTabList->a[i].zName, 0);
      pParse->nErr++;
      goto delete_from_cleanup;
Changes to src/expr.c.
20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
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 routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions.
**
** $Id: expr.c,v 1.23 2001/04/04 21:22:14 drh Exp $
** $Id: expr.c,v 1.24 2001/04/11 14:28:42 drh Exp $
*/
#include "sqliteInt.h"

/*
** Walk an expression tree.  Return 1 if the expression is constant
** and 0 if it involves variables.
*/
119
120
121
122
123
124
125
126

127
128
129
130
131
132

133
134
135
136
137
138
139
119
120
121
122
123
124
125

126
127
128
129
130
131
132
133
134
135
136
137
138
139
140







-
+






+







** If it finds any, it generates code to write the value of that select
** into a memory cell.
**
** Unknown columns or tables provoke an error.  The function returns
** the number of errors seen and leaves an error message on pParse->zErrMsg.
*/
int sqliteExprResolveIds(Parse *pParse, IdList *pTabList, Expr *pExpr){
  if( pExpr==0 ) return 0;
  if( pExpr==0 || pTabList==0 ) return 0;
  switch( pExpr->op ){
    /* A lone identifier */
    case TK_ID: {
      int cnt = 0;      /* Number of matches */
      int i;            /* Loop counter */
      char *z = sqliteStrNDup(pExpr->token.z, pExpr->token.n);
      if( z==0 ) return 1;
      for(i=0; i<pTabList->nId; i++){
        int j;
        Table *pTab = pTabList->a[i].pTab;
        if( pTab==0 ) continue;
        for(j=0; j<pTab->nCol; j++){
          if( sqliteStrICmp(pTab->aCol[j].zName, z)==0 ){
            cnt++;
173
174
175
176
177
178
179





180
181
182
183
184
185
186
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192







+
+
+
+
+








      pLeft = pExpr->pLeft;
      pRight = pExpr->pRight;
      assert( pLeft && pLeft->op==TK_ID );
      assert( pRight && pRight->op==TK_ID );
      zLeft = sqliteStrNDup(pLeft->token.z, pLeft->token.n);
      zRight = sqliteStrNDup(pRight->token.z, pRight->token.n);
      if( zLeft==0 || zRight==0 ){
        sqliteFree(zLeft);
        sqliteFree(zRight);
        return 1;
      }
      pExpr->iTable = -1;
      for(i=0; i<pTabList->nId; i++){
        int j;
        char *zTab;
        Table *pTab = pTabList->a[i].pTab;
        if( pTab==0 ) continue;
        if( pTabList->a[i].zAlias ){
476
477
478
479
480
481
482

483
484
485
486
487
488
489
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496







+







/*
** Generate code into the current Vdbe to evaluate the given
** expression and leave the result on the top of stack.
*/
void sqliteExprCode(Parse *pParse, Expr *pExpr){
  Vdbe *v = pParse->pVdbe;
  int op;
  if( v==0 || pExpr==0 ) return;
  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;
679
680
681
682
683
684
685

686
687
688
689
690
691
692
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700







+







** Generate code for a boolean expression such that a jump is made
** to the label "dest" if the expression is true but execution
** continues straight thru if the expression is false.
*/
void sqliteExprIfTrue(Parse *pParse, Expr *pExpr, int dest){
  Vdbe *v = pParse->pVdbe;
  int op = 0;
  if( v==0 || pExpr==0 ) return;
  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;
765
766
767
768
769
770
771

772
773
774
775
776
777
778
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787







+







** Generate code for a boolean expression such that a jump is made
** to the label "dest" if the expression is false but execution
** continues straight thru if the expression is true.
*/
void sqliteExprIfFalse(Parse *pParse, Expr *pExpr, int dest){
  Vdbe *v = pParse->pVdbe;
  int op = 0;
  if( v==0 || pExpr==0 ) return;
  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;
892
893
894
895
896
897
898
899
900

901
902
903
904
905
906
907
901
902
903
904
905
906
907


908
909
910
911
912
913
914
915







-
-
+







** Add a new element to the pParse->aAgg[] array and return its index.
*/
static int appendAggInfo(Parse *pParse){
  if( (pParse->nAgg & 0x7)==0 ){
    int amt = pParse->nAgg + 8;
    pParse->aAgg = sqliteRealloc(pParse->aAgg, amt*sizeof(pParse->aAgg[0]));
    if( pParse->aAgg==0 ){
      sqliteSetString(&pParse->zErrMsg, "out of memory", 0);
      pParse->nErr++;
      pParse->nAgg = 0;
      return -1;
    }
  }
  memset(&pParse->aAgg[pParse->nAgg], 0, sizeof(pParse->aAgg[0]));
  return pParse->nAgg++;
}

Changes to src/insert.c.
20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
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
** to handle INSERT statements.
**
** $Id: insert.c,v 1.12 2001/01/15 22:51:11 drh Exp $
** $Id: insert.c,v 1.13 2001/04/11 14:28:42 drh Exp $
*/
#include "sqliteInt.h"

/*
** This routine is call to handle SQL of the following forms:
**
**    insert into TABLE (IDLIST) values(EXPRLIST)
55
56
57
58
59
60
61


62
63
64
65

66
67
68
69
70
71
72
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75







+
+




+







  int i, j, idx;        /* Loop counters */
  Vdbe *v;              /* Generate code into this virtual machine */
  Index *pIdx;          /* For looping over indices of the table */
  int srcTab;           /* Date comes from this temporary cursor if >=0 */
  int nColumn;          /* Number of columns in the data */
  int base;             /* First available cursor */
  int iCont, iBreak;    /* Beginning and end of the loop over srcTab */

  if( pParse->nErr || sqlite_malloc_failed ) goto insert_cleanup;

  /* Locate the table into which we will be inserting new information.
  */
  zTab = sqliteTableNameFromToken(pTableName);
  if( zTab==0 ) goto insert_cleanup;
  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 insert_cleanup;
90
91
92
93
94
95
96
97

98
99
100

101
102
103
104
105
106
107
93
94
95
96
97
98
99

100
101
102
103
104
105
106
107
108
109
110
111







-
+



+







  ** then we just have to count the number of expressions.
  */
  if( pSelect ){
    int rc;
    srcTab = pParse->nTab++;
    sqliteVdbeAddOp(v, OP_OpenTbl, srcTab, 1, 0, 0);
    rc = sqliteSelect(pParse, pSelect, SRT_Table, srcTab);
    if( rc ) goto insert_cleanup;
    if( rc || pParse->nErr || sqlite_malloc_failed ) goto insert_cleanup;
    assert( pSelect->pEList );
    nColumn = pSelect->pEList->nExpr;
  }else{
    assert( pList!=0 );
    srcTab = -1;
    assert( pList );
    nColumn = pList->nExpr;
  }

  /* Make sure the number of columns in the source data matches the number
  ** of columns to be inserted into the table.
Changes to src/main.c.
22
23
24
25
26
27
28
29

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

29
30
31
32
33
34
35
36







-
+







**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.27 2001/04/06 16:13:43 drh Exp $
** $Id: main.c,v 1.28 2001/04/11 14:28:42 drh Exp $
*/
#include "sqliteInt.h"
#include <unistd.h>

/*
** This is the callback routine for the code that initializes the
** database.  Each callback contains text of a CREATE TABLE or
153
154
155
156
157
158
159
160
161


162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
153
154
155
156
157
158
159


160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181


182
183
184
185
186
187
188







-
-
+
+




















-
-







  };

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

/*
** The version of the library
*/
212
213
214
215
216
217
218
219

220
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
210
211
212
213
214
215
216

217




218
219
220
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







-
+
-
-
-
-




-

+








+
+
-
+



-
+



+
+
+
+
+







sqlite *sqlite_open(const char *zFilename, int mode, char **pzErrMsg){
  sqlite *db;
  int rc;

  /* Allocate the sqlite data structure */
  db = sqliteMalloc( sizeof(sqlite) );
  if( pzErrMsg ) *pzErrMsg = 0;
  if( db==0 ){
  if( db==0 ) goto no_mem_on_open;
    sqliteSetString(pzErrMsg, "out of memory", 0);
    sqliteStrRealloc(pzErrMsg);
    return 0;
  }
  
  /* Open the backend database driver */
  db->pBe = sqliteDbbeOpen(zFilename, (mode&0222)!=0, mode!=0, pzErrMsg);
  if( db->pBe==0 ){
    sqliteStrRealloc(pzErrMsg);
    sqliteFree(db);
    sqliteStrRealloc(pzErrMsg);
    return 0;
  }

  /* Assume file format 1 unless the database says otherwise */
  db->file_format = 1;

  /* Attempt to read the schema */
  rc = sqliteInit(db, pzErrMsg);
  if( sqlite_malloc_failed ){
    goto no_mem_on_open;
  if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
  }else if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
    sqlite_close(db);
    return 0;
  }else /* if( pzErrMsg ) */{
    free(*pzErrMsg);
    sqliteFree(*pzErrMsg);
    *pzErrMsg = 0;
  }
  return db;

no_mem_on_open:
  sqliteSetString(pzErrMsg, "out of memory", 0);
  sqliteStrRealloc(pzErrMsg);
  return 0;
}

/*
** Close an existing SQLite database
*/
void sqlite_close(sqlite *db){
  int i;
332
333
334
335
336
337
338
339




340
341
342
343
344
345





346
347
348
349
350
351
352
353
354
355

356
357
358
359
360
361
362
333
334
335
336
337
338
339

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
368
369
370
371







-
+
+
+
+






+
+
+
+
+









-
+







  char **pzErrMsg             /* Write error messages here */
){
  Parse sParse;

  if( pzErrMsg ) *pzErrMsg = 0;
  if( (db->flags & SQLITE_Initialized)==0 ){
    int rc = sqliteInit(db, pzErrMsg);
    if( rc!=SQLITE_OK ) return rc;
    if( rc!=SQLITE_OK ){
      sqliteStrRealloc(pzErrMsg);
      return rc;
    }
  }
  memset(&sParse, 0, sizeof(sParse));
  sParse.db = db;
  sParse.xCallback = xCallback;
  sParse.pArg = pArg;
  sqliteRunParser(&sParse, zSql, pzErrMsg);
  if( sqlite_malloc_failed ){
    sqliteSetString(pzErrMsg, "out of memory", 0);
    sParse.rc = SQLITE_NOMEM;
  }
  sqliteStrRealloc(pzErrMsg);
  return sParse.rc;
}

/*
** This routine implements a busy callback that sleeps and tries
** again until a timeout value is reached.  The timeout value is
** an integer number of milliseconds passed in as the first
** argument.
*/
static int sqlite_default_busy_callback(
static int sqliteDefaultBusyCallback(
 void *Timeout,           /* Maximum amount of time to wait */
 const char *NotUsed,     /* The name of the table that is busy */
 int count                /* Number of times table has been busy */
){
#if defined(HAVE_USLEEP) && HAVE_USLEEP
  int delay = 10000;
  int prior_delay = 0;
403
404
405
406
407
408
409
410

411
412
413
414
415
416
417
418
419
420
421
412
413
414
415
416
417
418

419
420
421
422
423
424
425
426
427
428
429
430







-
+












/*
** This routine installs a default busy handler that waits for the
** specified number of milliseconds before returning 0.
*/
void sqlite_busy_timeout(sqlite *db, int ms){
  if( ms>0 ){
    sqlite_busy_handler(db, sqlite_default_busy_callback, (void*)ms);
    sqlite_busy_handler(db, sqliteDefaultBusyCallback, (void*)ms);
  }else{
    sqlite_busy_handler(db, 0, 0);
  }
}

/*
** Cause any pending operation to stop at its earliest opportunity.
*/
void sqlite_interrupt(sqlite *db){
  db->flags |= SQLITE_Interrupt;
}
Changes to src/parse.y.
22
23
24
25
26
27
28
29

30
31
32
33
34
35
36
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.27 2001/04/04 11:48:58 drh Exp $
** @(#) $Id: parse.y,v 1.28 2001/04/11 14:28:42 drh Exp $
*/
%token_prefix TK_
%token_type {Token}
%extra_argument {Parse *pParse}
%syntax_error {
  sqliteSetString(&pParse->zErrMsg,"syntax error",0);
  pParse->sErrToken = TOKEN;
166
167
168
169
170
171
172

173
174

175

176
177
178
179
180
181
182
166
167
168
169
170
171
172
173
174
175
176

177
178
179
180
181
182
183
184







+


+
-
+







%type select {Select*}
%destructor select {sqliteSelectDelete($$);}
%type oneselect {Select*}
%destructor oneselect {sqliteSelectDelete($$);}

select(A) ::= oneselect(X).                      {A = X;}
select(A) ::= select(X) joinop(Y) oneselect(Z).  {
  if( Z ){
    Z->op = Y;
    Z->pPrior = X;
  }
    A = Z;
  A = Z;
}
%type joinop {int}
joinop(A) ::= UNION.      {A = TK_UNION;}
joinop(A) ::= UNION ALL.  {A = TK_ALL;}
joinop(A) ::= INTERSECT.  {A = TK_INTERSECT;}
joinop(A) ::= EXCEPT.     {A = TK_EXCEPT;}
oneselect(A) ::= SELECT distinct(D) selcollist(W) from(X) where_opt(Y)
232
233
234
235
236
237
238
239

240
241
242
243

244
245
246
247
248
249
250
234
235
236
237
238
239
240

241
242
243
244

245
246
247
248
249
250
251
252







-
+



-
+







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

orderby_opt(A) ::= .                          {A = 0;}
orderby_opt(A) ::= ORDER BY sortlist(X).      {A = X;}
sortlist(A) ::= sortlist(X) COMMA sortitem(Y) sortorder(Z). {
  A = sqliteExprListAppend(X,Y,0);
  A->a[A->nExpr-1].sortOrder = Z;   /* 0 for ascending order, 1 for decending */
  if( A ) A->a[A->nExpr-1].sortOrder = Z;  /* 0=ascending, 1=decending */
}
sortlist(A) ::= sortitem(Y) sortorder(Z). {
  A = sqliteExprListAppend(0,Y,0);
  A->a[0].sortOrder = Z;
  if( A ) A->a[0].sortOrder = Z;
}
sortitem(A) ::= expr(X).   {A = X;}

%type sortorder {int}

sortorder(A) ::= ASC.      {A = 0;}
sortorder(A) ::= DESC.     {A = 1;}
293
294
295
296
297
298
299
300

301
302
303
304
305
306

307
308
309
310
311
312
313
295
296
297
298
299
300
301

302
303
304
305
306
307

308
309
310
311
312
313
314
315







-
+





-
+








itemlist(A) ::= itemlist(X) COMMA item(Y).  {A = sqliteExprListAppend(X,Y,0);}
itemlist(A) ::= item(X).     {A = sqliteExprListAppend(0,X,0);}
item(A) ::= INTEGER(X).      {A = sqliteExpr(TK_INTEGER, 0, 0, &X);}
item(A) ::= PLUS INTEGER(X). {A = sqliteExpr(TK_INTEGER, 0, 0, &X);}
item(A) ::= MINUS INTEGER(X). {
  A = sqliteExpr(TK_UMINUS, 0, 0, 0);
  A->pLeft = sqliteExpr(TK_INTEGER, 0, 0, &X);
  if( A ) A->pLeft = sqliteExpr(TK_INTEGER, 0, 0, &X);
}
item(A) ::= FLOAT(X).        {A = sqliteExpr(TK_FLOAT, 0, 0, &X);}
item(A) ::= PLUS FLOAT(X).   {A = sqliteExpr(TK_FLOAT, 0, 0, &X);}
item(A) ::= MINUS FLOAT(X).  {
  A = sqliteExpr(TK_UMINUS, 0, 0, 0);
  A->pLeft = sqliteExpr(TK_FLOAT, 0, 0, &X);
  if( A ) A->pLeft = sqliteExpr(TK_FLOAT, 0, 0, &X);
}
item(A) ::= STRING(X).       {A = sqliteExpr(TK_STRING, 0, 0, &X);}
item(A) ::= NULL.            {A = sqliteExpr(TK_NULL, 0, 0, 0);}

%type inscollist_opt {IdList*}
%destructor inscollist_opt {sqliteIdListDelete($$);}
%type inscollist {IdList*}
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
420

421
422
423
424
425

426
427
428
429
430

431
432
433
434
435
436

437
438
439
440
441
442
443
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
420
421

422
423
424
425
426

427
428
429
430
431

432
433
434
435
436
437

438
439
440
441
442
443
444
445







-
+






-
+






-
+





-
+




-
+




-
+





-
+







}
expr(A) ::= PLUS(B) expr(X). [UMINUS] {
  A = X;
  sqliteExprSpan(A,&B,&X->span);
}
expr(A) ::= LP(B) select(X) RP(E). {
  A = sqliteExpr(TK_SELECT, 0, 0, 0);
  A->pSelect = X;
  if( A ) A->pSelect = X;
  sqliteExprSpan(A,&B,&E);
}
expr(A) ::= expr(W) BETWEEN expr(X) AND expr(Y). {
  ExprList *pList = sqliteExprListAppend(0, X, 0);
  pList = sqliteExprListAppend(pList, Y, 0);
  A = sqliteExpr(TK_BETWEEN, W, 0, 0);
  A->pList = pList;
  if( A ) A->pList = pList;
  sqliteExprSpan(A,&W->span,&Y->span);
}
expr(A) ::= expr(W) NOT BETWEEN expr(X) AND expr(Y). {
  ExprList *pList = sqliteExprListAppend(0, X, 0);
  pList = sqliteExprListAppend(pList, Y, 0);
  A = sqliteExpr(TK_BETWEEN, W, 0, 0);
  A->pList = pList;
  if( A ) A->pList = pList;
  A = sqliteExpr(TK_NOT, A, 0, 0);
  sqliteExprSpan(A,&W->span,&Y->span);
}
expr(A) ::= expr(X) IN LP exprlist(Y) RP(E).  {
  A = sqliteExpr(TK_IN, X, 0, 0);
  A->pList = Y;
  if( A ) A->pList = Y;
  sqliteExprSpan(A,&X->span,&E);
}
expr(A) ::= expr(X) IN LP select(Y) RP(E).  {
  A = sqliteExpr(TK_IN, X, 0, 0);
  A->pSelect = Y;
  if( A ) A->pSelect = Y;
  sqliteExprSpan(A,&X->span,&E);
}
expr(A) ::= expr(X) NOT IN LP exprlist(Y) RP(E).  {
  A = sqliteExpr(TK_IN, X, 0, 0);
  A->pList = Y;
  if( A ) A->pList = Y;
  A = sqliteExpr(TK_NOT, A, 0, 0);
  sqliteExprSpan(A,&X->span,&E);
}
expr(A) ::= expr(X) NOT IN LP select(Y) RP(E).  {
  A = sqliteExpr(TK_IN, X, 0, 0);
  A->pSelect = Y;
  if( A ) A->pSelect = Y;
  A = sqliteExpr(TK_NOT, A, 0, 0);
  sqliteExprSpan(A,&X->span,&E);
}



%type exprlist {ExprList*}
Changes to src/printf.c.
559
560
561
562
563
564
565

566
567
568
569
570
571
572
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573







+







          if( arg==0 ) arg = "(NULL)";
          for(i=n=0; (c=arg[i])!=0; i++){
            if( c=='\'' )  n++;
          }
          n += i + 1;
          if( n>etBUFSIZE ){
            bufpt = zExtra = sqliteMalloc( n );
            if( bufpt==0 ) return -1;
          }else{
            bufpt = buf;
          }
          for(i=j=0; (c=arg[i])!=0; i++){
            bufpt[j++] = c;
            if( c=='\'' ) bufpt[j++] = c;
          }
Changes to src/select.c.
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
47
48
49
50
51
52
53
54

















55
56
57
58
59
60
61
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69







-
+








-
-
-
-
-
-
-
+
+
+
+
+
+
+



-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







**   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.30 2001/04/04 11:48:58 drh Exp $
** $Id: select.c,v 1.31 2001/04/11 14:28:42 drh Exp $
*/
#include "sqliteInt.h"

/*
** Allocate a new Select structure and return a pointer to that
** structure.
*/
Select *sqliteSelectNew(
  ExprList *pEList,
  IdList *pSrc,
  Expr *pWhere,
  ExprList *pGroupBy,
  Expr *pHaving,
  ExprList *pOrderBy,
  int isDistinct
  ExprList *pEList,     /* which columns to include in the result */
  IdList *pSrc,         /* the FROM clause -- which tables to scan */
  Expr *pWhere,         /* the WHERE clause */
  ExprList *pGroupBy,   /* the GROUP BY clause */
  Expr *pHaving,        /* the HAVING clause */
  ExprList *pOrderBy,   /* the ORDER BY clause */
  int isDistinct        /* true if the DISTINCT keyword is present */
){
  Select *pNew;
  pNew = sqliteMalloc( sizeof(*pNew) );
  if( pNew==0 ) return 0;
  pNew->pEList = pEList;
  pNew->pSrc = pSrc;
  pNew->pWhere = pWhere;
  pNew->pGroupBy = pGroupBy;
  pNew->pHaving = pHaving;
  pNew->pOrderBy = pOrderBy;
  pNew->isDistinct = isDistinct;
  pNew->op = TK_SELECT;
  if( pNew==0 ){
    sqliteExprListDelete(pEList);
    sqliteIdListDelete(pSrc);
    sqliteExprDelete(pWhere);
    sqliteExprListDelete(pGroupBy);
    sqliteExprDelete(pHaving);
    sqliteExprListDelete(pOrderBy);
  }else{
    pNew->pEList = pEList;
    pNew->pSrc = pSrc;
    pNew->pWhere = pWhere;
    pNew->pGroupBy = pGroupBy;
    pNew->pHaving = pHaving;
    pNew->pOrderBy = pOrderBy;
    pNew->isDistinct = isDistinct;
    pNew->op = TK_SELECT;
  }
  return pNew;
}

/*
** Delete the given Select structure and all of its substructures.
*/
void sqliteSelectDelete(Select *p){
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
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







+














-
-
+
+
+







  int eDest,              /* How to dispose of the results */
  int iParm,              /* An argument to the disposal method */
  int iContinue,          /* Jump here to continue with next row */
  int iBreak              /* Jump here to break out of the inner loop */
){
  Vdbe *v = pParse->pVdbe;
  int i;
  if( v==0 ) return 0;

  /* Pull the requested columns.
  */
  if( pEList ){
    for(i=0; i<pEList->nExpr; i++){
      sqliteExprCode(pParse, pEList->a[i].pExpr);
    }
    nColumn = pEList->nExpr;
  }else{
    for(i=0; i<nColumn; i++){
      sqliteVdbeAddOp(v, OP_Field, srcTab, i, 0, 0);
    }
  }

  /* If the current result is not distinct, skip the rest
  ** of the processing for the current row.
  /* If the DISTINCT keyword was present on the SELECT statement
  ** and this row has been seen before, then do not make this row
  ** part of the result.
  */
  if( distinct>=0 ){
    int lbl = sqliteVdbeMakeLabel(v);
    sqliteVdbeAddOp(v, OP_MakeKey, pEList->nExpr, 1, 0, 0);
    sqliteVdbeAddOp(v, OP_Distinct, distinct, lbl, 0, 0);
    sqliteVdbeAddOp(v, OP_Pop, pEList->nExpr+1, 0, 0, 0);
    sqliteVdbeAddOp(v, OP_Goto, 0, iContinue, 0, 0);
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
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







-
+











+







** are in the result and the name for each column.  This information
** is used to provide "argc" and "azCol[]" values in the callback.
*/
static 
void generateColumnNames(Parse *pParse, IdList *pTabList, ExprList *pEList){
  Vdbe *v = pParse->pVdbe;
  int i;
  if( pParse->colNamesSet ) return;
  if( pParse->colNamesSet || v==0 || sqlite_malloc_failed ) return;
  pParse->colNamesSet = 1;
  sqliteVdbeAddOp(v, OP_ColumnCount, pEList->nExpr, 0, 0, 0);
  for(i=0; i<pEList->nExpr; i++){
    Expr *p;
    int addr;
    if( pEList->a[i].zName ){
      char *zName = pEList->a[i].zName;
      sqliteVdbeAddOp(v, OP_ColumnName, i, 0, zName, 0);
      continue;
    }
    p = pEList->a[i].pExpr;
    if( p==0 ) continue;
    if( p->span.z && p->span.z[0] ){
      addr = sqliteVdbeAddOp(v,OP_ColumnName, i, 0, 0, 0);
      sqliteVdbeChangeP3(v, addr, p->span.z, p->span.n);
      sqliteVdbeCompressSpace(v, addr);
    }else if( p->op!=TK_COLUMN || pTabList==0 ){
      char zName[30];
      sprintf(zName, "column%d", i+1);
295
296
297
298
299
300
301
302
303






304
305
306
307
308
309
310











311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328

329

330
331
332

333
334
335
336
337
338
339
306
307
308
309
310
311
312


313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
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
368







-
-
+
+
+
+
+
+







+
+
+
+
+
+
+
+
+
+
+


















+

+



+







**         of all tables.
**
** Return 0 on success.  If there are problems, leave an error message
** in pParse and return non-zero.
*/
static int fillInColumnList(Parse *pParse, Select *p){
  int i, j;
  IdList *pTabList = p->pSrc;
  ExprList *pEList = p->pEList;
  IdList *pTabList;
  ExprList *pEList;

  if( p==0 || p->pSrc==0 ) return 1;
  pTabList = p->pSrc;
  pEList = p->pEList;

  /* Look up every table in the table list.
  */
  for(i=0; i<pTabList->nId; i++){
    if( pTabList->a[i].pTab ){
      /* This routine has run before!  No need to continue */
      return 0;
    }
    if( pTabList->a[i].zName==0 ){
      /* No table name is given.  Instead, there is a (SELECT ...) statement
      ** the results of which should be used in place of the table.  The
      ** was this is implemented is that the (SELECT ...) writes its results
      ** into a temporary table which is then scanned like any other table.
      */
      sqliteSetString(&pParse->zErrMsg, 
          "(SELECT...) in a FROM clause is not yet implemented.", 0);
      pParse->nErr++;
      return 1;
    }
    pTabList->a[i].pTab = sqliteFindTable(pParse->db, pTabList->a[i].zName);
    if( pTabList->a[i].pTab==0 ){
      sqliteSetString(&pParse->zErrMsg, "no such table: ", 
         pTabList->a[i].zName, 0);
      pParse->nErr++;
      return 1;
    }
  }

  /* If the list of columns to retrieve is "*" then replace it with
  ** a list of all columns from all tables.
  */
  if( pEList==0 ){
    for(i=0; i<pTabList->nId; i++){
      Table *pTab = pTabList->a[i].pTab;
      for(j=0; j<pTab->nCol; j++){
        Expr *pExpr = sqliteExpr(TK_DOT, 0, 0, 0);
        if( pExpr==0 ) break;
        pExpr->pLeft = sqliteExpr(TK_ID, 0, 0, 0);
        if( pExpr->pLeft==0 ) break;
        pExpr->pLeft->token.z = pTab->zName;
        pExpr->pLeft->token.n = strlen(pTab->zName);
        pExpr->pRight = sqliteExpr(TK_ID, 0, 0, 0);
        if( pExpr->pRight==0 ) break;
        pExpr->pRight->token.z = pTab->aCol[j].zName;
        pExpr->pRight->token.n = strlen(pTab->aCol[j].zName);
        pExpr->span.z = "";
        pExpr->span.n = 0;
        pEList = sqliteExprListAppend(pEList, pExpr, 0);
      }
    }
362
363
364
365
366
367
368
369

370
371
372
373
374
375
376
391
392
393
394
395
396
397

398
399
400
401
402
403
404
405







-
+







  int iTable,             /* Insert this this value in iTable */
  int mustComplete        /* If TRUE all ORDER BYs must match */
){
  int nErr = 0;
  int i, j;
  ExprList *pEList;

  assert( pSelect && pOrderBy );
  if( pSelect==0 || pOrderBy==0 ) return 1;
  if( mustComplete ){
    for(i=0; i<pOrderBy->nExpr; i++){ pOrderBy->a[i].done = 0; }
  }
  if( fillInColumnList(pParse, pSelect) ){
    return 1;
  }
  if( pSelect->pPrior ){
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450

451
452
453
454
455
456
457
451
452
453
454
455
456
457




458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474

475
476
477
478
479
480
481
482







-
-
-
-

















-
+







** If an error occurs, return NULL and leave a message in pParse.
*/
Vdbe *sqliteGetVdbe(Parse *pParse){
  Vdbe *v = pParse->pVdbe;
  if( v==0 ){
    v = pParse->pVdbe = sqliteVdbeCreate(pParse->db);
  }
  if( v==0 ){
    sqliteSetString(&pParse->zErrMsg, "out of memory", 0);
    pParse->nErr++;
  }
  return v;
}
    

/*
** This routine is called to process a query that is really the union
** or intersection of two or more separate queries.
*/
static int multiSelect(Parse *pParse, Select *p, int eDest, int iParm){
  int rc;             /* Success code from a subroutine */
  Select *pPrior;     /* Another SELECT immediately to our left */
  Vdbe *v;            /* Generate code to this VDBE */
  int base;           /* Baseline value for pParse->nTab */

  /* Make sure there is no ORDER BY clause on prior SELECTs.  Only the 
  ** last SELECT in the series may have an ORDER BY.
  */
  assert( p->pPrior!=0 );
  if( p==0 || p->pPrior==0 ) return 1;
  pPrior = p->pPrior;
  if( pPrior->pOrderBy ){
    sqliteSetString(&pParse->zErrMsg,"ORDER BY clause should come after ",
      selectOpName(p->op), " not before", 0);
    pParse->nErr++;
    return 1;
  }
646
647
648
649
650
651
652


653
654
655
656
657
658
659
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686







+
+







  Expr *pWhere;          /* The WHERE clause.  May be NULL */
  ExprList *pOrderBy;    /* The ORDER BY clause.  May be NULL */
  ExprList *pGroupBy;    /* The GROUP BY clause.  May be NULL */
  Expr *pHaving;         /* The HAVING clause.  May be NULL */
  int isDistinct;        /* True if the DISTINCT keyword is present */
  int distinct;          /* Table to use for the distinct set */
  int base;              /* First cursor available for use */

  if( sqlite_malloc_failed || pParse->nErr || p==0 ) return 1;

  /* If there is are a sequence of queries, do the earlier ones first.
  */
  if( p->pPrior ){
    return multiSelect(pParse, p, eDest, iParm);
  }

682
683
684
685
686
687
688

689
690
691
692
693
694
695
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723







+







  ** columnlist in pEList if there isn't one already.  (The parser leaves
  ** a NULL in the p->pEList if the SQL said "SELECT * FROM ...")
  */
  if( fillInColumnList(pParse, p) ){
    return 1;
  }
  pEList = p->pEList;
  if( pEList==0 ) return 1;

  /* Allocate a temporary table to use for the DISTINCT set, if
  ** necessary.  This must be done early to allocate the cursor before
  ** any calls to sqliteExprResolveIds().
  */
  if( isDistinct ){
    distinct = pParse->nTab++;
816
817
818
819
820
821
822
823
824


825
826
827
828
829
830
831
832
833
834
835
836
837
838
844
845
846
847
848
849
850


851
852







853
854
855
856
857
858
859







-
-
+
+
-
-
-
-
-
-
-







        }
      }
    }
  }

  /* Begin generating code.
  */
  v = pParse->pVdbe;
  if( v==0 ){
  v = sqliteGetVdbe(pParse);
  if( v==0 ) return 1;
    v = pParse->pVdbe = sqliteVdbeCreate(pParse->db);
  }
  if( v==0 ){
    sqliteSetString(&pParse->zErrMsg, "out of memory", 0);
    pParse->nErr++;
    return 1;
  }
  if( pOrderBy ){
    sqliteVdbeAddOp(v, OP_SortOpen, 0, 0, 0, 0);
  }

  /* Identify column names if we will be using in the callback.  This
  ** step is skipped if the output is going to a table or a memory cell.
  */
Changes to src/shell.c.
20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
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 code to implement the "sqlite" command line
** utility for accessing SQLite databases.
**
** $Id: shell.c,v 1.30 2001/04/04 21:22:14 drh Exp $
** $Id: shell.c,v 1.31 2001/04/11 14:28:42 drh Exp $
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "sqlite.h"
#include <unistd.h>
#include <ctype.h>
56
57
58
59
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
56
57
58
59
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







-
+




















-
+







** the text in memory obtained from malloc() and returns a pointer
** to the text.  NULL is returned at end of file, or if malloc()
** fails.
**
** The interface is like "readline" but no command-line editing
** is done.
*/
static char *getline(char *zPrompt){
static char *getline(char *zPrompt, FILE *in){
  char *zLine;
  int nLine;
  int n;
  int eol;

  if( zPrompt && *zPrompt ){
    printf("%s",zPrompt);
    fflush(stdout);
  }
  nLine = 100;
  zLine = malloc( nLine );
  if( zLine==0 ) return 0;
  n = 0;
  eol = 0;
  while( !eol ){
    if( n+100>nLine ){
      nLine = nLine*2 + 100;
      zLine = realloc(zLine, nLine);
      if( zLine==0 ) return 0;
    }
    if( fgets(&zLine[n], nLine - n, stdin)==0 ){
    if( fgets(&zLine[n], nLine - n, in)==0 ){
      if( n==0 ){
        free(zLine);
        return 0;
      }
      zLine[n] = 0;
      eol = 1;
      break;
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
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







-
+


-
-
+
+


















+







** is coming from a terminal.  In that case, we issue a prompt and
** attempt to use "readline" for command-line editing.  If "isatty"
** is false, use "getline" instead of "readline" and issue to prompt.
**
** zPrior is a string of prior text retrieved.  If not the empty
** string, then issue a continuation prompt.
*/
static char *one_input_line(const char *zPrior, int isatty){
static char *one_input_line(const char *zPrior, FILE *in){
  char *zPrompt;
  char *zResult;
  if( !isatty ){
    return getline(0);
  if( in!=0 ){
    return getline(0, in);
  }
  if( zPrior && zPrior[0] ){
    zPrompt = "   ...> ";
  }else{
    zPrompt = "sqlite> ";
  }
  zResult = readline(zPrompt);
  if( zResult ) add_history(zResult);
  return zResult;
}

/*
** An pointer to an instance of this structure is passed from
** the main program to the callback.  This is used to communicate
** state and mode information.
*/
struct callback_data {
  sqlite *db;            /* The database */
  int echoOn;            /* True to echo input commands */
  int cnt;               /* Number of records displayed so far */
  FILE *out;             /* Write results here */
  int mode;              /* An output mode setting */
  int showHeader;        /* True to show column names in List or Column mode */
  int escape;            /* Escape this character when in MODE_List */
  char zDestTable[250];  /* Name of destination table when MODE_Insert */
  char separator[20];    /* Separator character for MODE_List */
385
386
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
419
420
421
422
423
424
425
426



427
428
429
430
431
432
433



434
435
436
437
438
439
440
386
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
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448







-
+

-
+


-
+



-
-
+
+



-
+

-
+








+










+
+
+







+
+
+







/*
** This is a different callback routine used for dumping the database.
** Each row received by this callback consists of a table name,
** the table type ("index" or "table") and SQL to create the table.
** This routine should print text sufficient to recreate the table.
*/
static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
  struct callback_data *pData = (struct callback_data *)pArg;
  struct callback_data *p = (struct callback_data *)pArg;
  if( nArg!=3 ) return 1;
  fprintf(pData->out, "%s;\n", azArg[2]);
  fprintf(p->out, "%s;\n", azArg[2]);
  if( strcmp(azArg[1],"table")==0 ){
    struct callback_data d2;
    d2 = *pData;
    d2 = *p;
    d2.mode = MODE_List;
    d2.escape = '\t';
    strcpy(d2.separator,"\t");
    fprintf(pData->out, "COPY '%s' FROM STDIN;\n", azArg[0]);
    sqlite_exec_printf(pData->db, 
    fprintf(p->out, "COPY '%s' FROM STDIN;\n", azArg[0]);
    sqlite_exec_printf(p->db, 
       "SELECT * FROM '%q'",
       callback, &d2, 0, azArg[0]
    );
    fprintf(pData->out, "\\.\n");
    fprintf(p->out, "\\.\n");
  }
  fprintf(pData->out, "VACUUM '%s';\n", azArg[0]);
  fprintf(p->out, "VACUUM '%s';\n", azArg[0]);
  return 0;
}

/*
** Text of a help message
*/
static char zHelp[] = 
  ".dump ?TABLE? ...      Dump the database in an text format\n"
  ".echo ON|OFF           Turn command echo on or off\n"
  ".exit                  Exit this program\n"
  ".explain               Set output mode suitable for EXPLAIN\n"
  ".header ON|OFF         Turn display of headers on or off\n"
  ".help                  Show this message\n"
  ".indices TABLE         Show names of all indices on TABLE\n"
  ".mode MODE             Set mode to one of \"line\", \"column\", \n"
  "                       \"insert\", \"list\", or \"html\"\n"
  ".mode insert TABLE     Generate SQL insert statements for TABLE\n"
  ".output FILENAME       Send output to FILENAME\n"
  ".output stdout         Send output to the screen\n"
  ".read FILENAME         Execute SQL in FILENAME\n"
  ".reindex ?TABLE?       Rebuild indices\n"
/*  ".rename OLD NEW        Change the name of a table or index\n" */
  ".schema ?TABLE?        Show the CREATE statements\n"
  ".separator STRING      Change separator string for \"list\" mode\n"
  ".tables ?PATTERN?      List names of tables matching a pattern\n"
  ".timeout MS            Try opening locked tables for MS milliseconds\n"
  ".width NUM NUM ...     Set column widths for \"column\" mode\n"
;

/* Forward reference */
static void process_input(struct callback_data *p, FILE *in);

/*
** If an input line begins with "." then invoke this routine to
** process that line.
*/
static void do_meta_command(char *zLine, sqlite *db, struct callback_data *p){
  int i = 1;
  int nArg = 0;
486
487
488
489
490
491
492















493
494
495
496
497
498
499
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







      }
    }
    if( zErrMsg ){
      fprintf(stderr,"Error: %s\n", zErrMsg);
      free(zErrMsg);
    }
  }else

  if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 ){
    int j;
    char *z = azArg[1];
    int val = atoi(azArg[1]);
    for(j=0; z[j]; j++){
      if( isupper(z[j]) ) z[j] = tolower(z[j]);
    }
    if( strcmp(z,"on")==0 ){
      val = 1;
    }else if( strcmp(z,"yes")==0 ){
      val = 1;
    } 
    p->echoOn = val;
  }else

  if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
    exit(0);
  }else

  if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
    p->mode = MODE_Column;
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
585
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







+
+

















+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







    }else if( strncmp(azArg[1],"insert",n2)==0 ){
      p->mode = MODE_Insert;
      if( nArg>=3 ){
        sprintf(p->zDestTable,"%.*s", (int)(sizeof(p->zDestTable)-1), azArg[2]);
      }else{
        sprintf(p->zDestTable,"table");
      }
    }else {
      fprintf(stderr,"mode should be on of: column html insert line list\n");
    }
  }else

  if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
    if( p->out!=stdout ){
      fclose(p->out);
    }
    if( strcmp(azArg[1],"stdout")==0 ){
      p->out = stdout;
    }else{
      p->out = fopen(azArg[1], "w");
      if( p->out==0 ){
        fprintf(stderr,"can't write to \"%s\"\n", azArg[1]);
        p->out = stdout;
      }
    }
  }else

  if( c=='r' && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
    FILE *alt = fopen(azArg[1], "r");
    if( alt==0 ){
      fprintf(stderr,"can't open \"%s\"\n", azArg[1]);
    }else{
      process_input(p, alt);
      fclose(alt);
    }
  }else

  if( c=='r' && strncmp(azArg[0], "reindex", n)==0 ){
    char **azResult;
    int nRow, rc;
    char *zErrMsg;
    int i;
    char *zSql;
    if( nArg==1 ){
      rc = sqlite_get_table(db,
        "SELECT name, sql FROM sqlite_master "
        "WHERE type='index'",
        &azResult, &nRow, 0, &zErrMsg
      );
    }else{
      rc = sqlite_get_table_printf(db,
        "SELECT name, sql FROM sqlite_master "
        "WHERE type='index' AND tbl_name LIKE '%q'",
        &azResult, &nRow, 0, &zErrMsg, azArg[1]
      );
    }
    for(i=1; rc==SQLITE_OK && i<=nRow; i++){
      extern char *sqlite_mprintf(const char *, ...);
      zSql = sqlite_mprintf(
         "DROP INDEX '%q';\n%s;\nVACUUM '%q';",
         azResult[i*2], azResult[i*2+1], azResult[i*2]);
      if( p->echoOn ) printf("%s\n", zSql);
      rc = sqlite_exec(db, zSql, 0, 0, &zErrMsg);
    }
    sqlite_free_table(azResult);
    if( zErrMsg ){
      fprintf(stderr,"Error: %s\n", zErrMsg);
      free(zErrMsg);
    }
  }else

  if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
    struct callback_data data;
    char *zErrMsg = 0;
    memcpy(&data, p, sizeof(data));
    data.showHeader = 0;
    data.mode = MODE_Semi;
680
681
682
683
684
685
686
687





















































688
689
690
691
692
693

694
695
696
697
698
699
700
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811

812

813
814
815
816
817
818
819
820
821








+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


-

-

+







  }else

  {
    fprintf(stderr, "unknown command: \"%s\". Enter \".help\" for help\n",
      azArg[0]);
  }
}

static char *Argv0;
static void process_input(struct callback_data *p, FILE *in){
  char *zLine;
  char *zSql = 0;
  int nSql = 0;
  char *zErrMsg;
  while( (zLine = one_input_line(zSql, in))!=0 ){
    if( p->echoOn ) printf("%s\n", zLine);
    if( zLine && zLine[0]=='.' ){
      do_meta_command(zLine, db, p);
      free(zLine);
      continue;
    }
    if( zSql==0 ){
      int i;
      for(i=0; zLine[i] && isspace(zLine[i]); i++){}
      if( zLine[i]!=0 ){
        nSql = strlen(zLine);
        zSql = malloc( nSql+1 );
        strcpy(zSql, zLine);
      }
    }else{
      int len = strlen(zLine);
      zSql = realloc( zSql, nSql + len + 2 );
      if( zSql==0 ){
        fprintf(stderr,"%s: out of memory!\n", Argv0);
        exit(1);
      }
      strcpy(&zSql[nSql++], "\n");
      strcpy(&zSql[nSql], zLine);
      nSql += len;
    }
    free(zLine);
    if( zSql && sqlite_complete(zSql) ){
      p->cnt = 0;
      if( sqlite_exec(db, zSql, callback, p, &zErrMsg)!=0 
           && zErrMsg!=0 ){
        if( in!=0 && !p->echoOn ) printf("%s\n",zSql);
        printf("SQL error: %s\n", zErrMsg);
        free(zErrMsg);
        zErrMsg = 0;
      }
      free(zSql);
      zSql = 0;
      nSql = 0;
    }
  }
  if( zSql ){
    printf("Incomplete SQL: %s\n", zSql);
    free(zSql);
  }
}

int main(int argc, char **argv){
  char *zErrMsg = 0;
  char *argv0 = argv[0];
  struct callback_data data;
  int echo = 0;

  Argv0 = argv[0];
  memset(&data, 0, sizeof(data));
  data.mode = MODE_List;
  strcpy(data.separator,"|");
  data.showHeader = 0;
#ifdef SIGINT
  signal(SIGINT, interrupt_handler);
#endif
720
721
722
723
724
725
726
727

728
729
730
731

732
733
734
735
736

737
738
739
740
741
742
743
841
842
843
844
845
846
847

848
849
850
851

852
853
854
855
856

857
858
859
860
861
862
863
864







-
+



-
+




-
+







      argc--;
      argv++;
    }else if( strcmp(argv[1],"-noheader")==0 ){
      data.showHeader = 0;
      argc--;
      argv++;
    }else if( strcmp(argv[1],"-echo")==0 ){
      echo = 1;
      data.echoOn = 1;
      argc--;
      argv++;
    }else{
      fprintf(stderr,"%s: unknown option: %s\n", argv0, argv[1]);
      fprintf(stderr,"%s: unknown option: %s\n", Argv0, argv[1]);
      return 1;
    }
  }
  if( argc!=2 && argc!=3 ){
    fprintf(stderr,"Usage: %s ?OPTIONS? FILENAME ?SQL?\n", argv0);
    fprintf(stderr,"Usage: %s ?OPTIONS? FILENAME ?SQL?\n", Argv0);
    exit(1);
  }
  data.db = db = sqlite_open(argv[1], 0666, &zErrMsg);
  if( db==0 ){
    data.db = db = sqlite_open(argv[1], 0444, &zErrMsg);
    if( db==0 ){
      if( zErrMsg ){
753
754
755
756
757
758
759
760
761
762
763

764
765
766
767
768
769
770
771
772
773
774

775
776
777
778
779
780
781
782
783
784
785
786

787
788
789
790
791
792
793
794
795
796
797
798
799

800
801
802
803
804
805
806

807
808
809
810

811
812
813
814
815
874
875
876
877
878
879
880




881

882
883
884
885
886





887












888













889







890




891


892
893
894







-
-
-
-
+
-





-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
+
-
-
-
-
+
-
-



  data.out = stdout;
  if( argc==3 ){
    if( sqlite_exec(db, argv[2], callback, &data, &zErrMsg)!=0 && zErrMsg!=0 ){
      fprintf(stderr,"SQL error: %s\n", zErrMsg);
      exit(1);
    }
  }else{
    char *zLine;
    char *zSql = 0;
    int nSql = 0;
    int istty = isatty(0);
    if( isatty(0) ){
    if( istty ){
      printf(
        "SQLite version %s\n"
        "Enter \".help\" for instructions\n",
        sqlite_version
      );
    }
    while( (zLine = one_input_line(zSql, istty))!=0 ){
      if( echo ) printf("%s\n", zLine);
      if( zLine && zLine[0]=='.' ){
        do_meta_command(zLine, db, &data);
      process_input(&data, 0);
        free(zLine);
        continue;
      }
      if( zSql==0 ){
        int i;
        for(i=0; zLine[i] && isspace(zLine[i]); i++){}
        if( zLine[i]!=0 ){
          nSql = strlen(zLine);
          zSql = malloc( nSql+1 );
          strcpy(zSql, zLine);
        }
      }else{
    }else{
        int len = strlen(zLine);
        zSql = realloc( zSql, nSql + len + 2 );
        if( zSql==0 ){
          fprintf(stderr,"%s: out of memory!\n", argv0);
          exit(1);
        }
        strcpy(&zSql[nSql++], "\n");
        strcpy(&zSql[nSql], zLine);
        nSql += len;
      }
      free(zLine);
      if( zSql && sqlite_complete(zSql) ){
        data.cnt = 0;
      process_input(&data, stdin);
        if( sqlite_exec(db, zSql, callback, &data, &zErrMsg)!=0 
             && zErrMsg!=0 ){
          if( !istty && !echo ) printf("%s\n",zSql);
          printf("SQL error: %s\n", zErrMsg);
          free(zErrMsg);
          zErrMsg = 0;
        }
    }
        free(zSql);
        zSql = 0;
        nSql = 0;
      }
  }
    }
  }
  sqlite_close(db);
  return 0;
}
Changes to src/sqliteInt.h.
19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
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.40 2001/04/07 15:24:33 drh Exp $
** @(#) $Id: sqliteInt.h,v 1.41 2001/04/11 14:28:43 drh Exp $
*/
#include "sqlite.h"
#include "dbbe.h"
#include "vdbe.h"
#include "parse.h"
#include <gdbm.h>
#include <stdio.h>
61
62
63
64
65
66
67






68
69
70
71
72
73
74
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80







+
+
+
+
+
+







# define sqliteStrDup(X)    sqliteStrDup_(X,__FILE__,__LINE__)
# define sqliteStrNDup(X,Y) sqliteStrNDup_(X,Y,__FILE__,__LINE__)
  void sqliteStrRealloc(char**);
#else
# define sqliteStrRealloc(X)
#endif

/*
** This variable gets set if malloc() ever fails.  After it gets set,
** the SQLite library shuts down permanently.
*/
extern int sqlite_malloc_failed;

/*
** The following global variables are used for testing and debugging
** only.  They only work if MEMORY_DEBUG is defined.
*/
#ifdef MEMORY_DEBUG
extern int sqlite_nMalloc;       /* Number of sqliteMalloc() calls */
extern int sqlite_nFree;         /* Number of sqliteFree() calls */
253
254
255
256
257
258
259
260
261


262
263
264
265
266
267
268
259
260
261
262
263
264
265

266
267
268
269
270
271
272
273
274
275







-

+
+







** A list of identifiers.
*/
struct IdList {
  int nId;         /* Number of identifiers on the list */
  struct {
    char *zName;      /* Text of the identifier. */
    char *zAlias;     /* The "B" part of a "A AS B" phrase.  zName is the "A" */
    Table *pTab;      /* An SQL table corresponding to zName */
    int idx;          /* Index in some Table.aCol[] of a column named zName */
    Table *pTab;      /* An SQL table corresponding to zName */
    Select *pSelect;  /* A SELECT statement used in place of a table name */
  } *a;            /* One entry for each identifier on the list */
};

/*
** The WHERE clause processing routine has two halves.  The
** first part does the start of the WHERE loop and the second
** half does the tail of the WHERE loop.  An instance of
Changes to src/table.c.
136
137
138
139
140
141
142
143

144
145
146
147
148
149
150
136
137
138
139
140
141
142

143
144
145
146
147
148
149
150







-
+







  *pazResult = 0;
  if( pnColumn ) *pnColumn = 0;
  if( pnRow ) *pnRow = 0;
  res.nResult = 0;
  res.nRow = 0;
  res.nColumn = 0;
  res.nData = 1;
  res.nAlloc = 200;
  res.nAlloc = 20;
  res.rc = SQLITE_OK;
  res.azResult = malloc( sizeof(char*)*res.nAlloc );
  if( res.azResult==0 ){
    return SQLITE_NOMEM;
  }
  res.azResult[0] = 0;
  rc = sqlite_exec(db, zSql, sqlite_get_table_cb, &res, pzErrMsg);
Changes to src/test1.c.
21
22
23
24
25
26
27
28

29
30
31
32
33
34
35
21
22
23
24
25
26
27

28
29
30
31
32
33
34
35







-
+







**   http://www.hwaci.com/drh/
**
*************************************************************************
** Code for testing the printf() interface to SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.1 2001/04/07 15:24:33 drh Exp $
** $Id: test1.c,v 1.2 2001/04/11 14:28:43 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>

/*
263
264
265
266
267
268
269












































270
271
272
273
274
275
276
277
278
279
280
281




282
283
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+












+
+
+
+


  if( Tcl_GetDouble(interp, argv[4], &r) ) return TCL_ERROR;
  z = sqlite_mprintf(argv[1], a[0], a[1], r);
  Tcl_AppendResult(interp, z, 0);
  sqliteFree(z);
  return TCL_OK;
}

/*
** Usage: sqlite_malloc_fail N
**
** Rig sqliteMalloc() to fail on the N-th call.  Turn of this mechanism
** and reset the sqlite_malloc_failed variable is N==0.
*/
#ifdef MEMORY_DEBUG
static int sqlite_malloc_fail(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  char **argv            /* Text of each argument */
){
  int n;
  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " N\"", 0);
    return TCL_ERROR;
  }
  if( Tcl_GetInt(interp, argv[1], &n) ) return TCL_ERROR;
  sqlite_iMallocFail = n;
  sqlite_malloc_failed = 0;
  return TCL_OK;
}
#endif

/*
** Usage: sqlite_malloc_stat
**
** Return the number of prior calls to sqliteMalloc() and sqliteFree().
*/
#ifdef MEMORY_DEBUG
static int sqlite_malloc_stat(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  char **argv            /* Text of each argument */
){
  char zBuf[200];
  sprintf(zBuf, "%d %d %d", sqlite_nMalloc, sqlite_nFree, sqlite_iMallocFail);
  Tcl_AppendResult(interp, zBuf, 0);
  return TCL_OK;
}
#endif

/*
** Register commands with the TCL interpreter.
*/
int Sqlitetest1_Init(Tcl_Interp *interp){
  Tcl_CreateCommand(interp, "sqlite_mprintf_int", sqlite_mprintf_int, 0, 0);
  Tcl_CreateCommand(interp, "sqlite_mprintf_str", sqlite_mprintf_str, 0, 0);
  Tcl_CreateCommand(interp, "sqlite_mprintf_double", sqlite_mprintf_double,0,0);
  Tcl_CreateCommand(interp, "sqlite_open", sqlite_test_open, 0, 0);
  Tcl_CreateCommand(interp, "sqlite_exec_printf", test_exec_printf, 0, 0);
  Tcl_CreateCommand(interp, "sqlite_get_table_printf", test_get_table_printf,
      0, 0);
  Tcl_CreateCommand(interp, "sqlite_close", sqlite_test_close, 0, 0);
#ifdef MEMORY_DEBUG
  Tcl_CreateCommand(interp, "sqlite_malloc_fail", sqlite_malloc_fail, 0, 0);
  Tcl_CreateCommand(interp, "sqlite_malloc_stat", sqlite_malloc_stat, 0, 0);
#endif
  return TCL_OK;
}
Changes to src/tokenize.c.
23
24
25
26
27
28
29
30

31
32
33
34
35
36
37
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.18 2001/04/04 11:48:58 drh Exp $
** $Id: tokenize.c,v 1.19 2001/04/11 14:28:43 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include <stdlib.h>

/*
** All the keywords of the SQL language are stored as in a hash
103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
103
104
105
106
107
108
109

110
111
112
113
114
115
116
117







-
+







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

/*
** This is the hash table
*/
#define KEY_HASH_SIZE 69
#define KEY_HASH_SIZE 71
static Keyword *apHashTable[KEY_HASH_SIZE];


/*
** This function looks up an identifier to determine if it is a
** keyword.  If it is a keyword, the token code of that keyword is 
** returned.  If the input is not a keyword, TK_ID is returned.
324
325
326
327
328
329
330
331

332
333
334
335
336
337
338
324
325
326
327
328
329
330

331
332
333
334
335
336
337
338







-
+







  if( pEngine==0 ){
    sqliteSetString(pzErrMsg, "out of memory", 0);
    return 1;
  }
#ifndef NDEBUG
  sqliteParserTrace(trace, "parser: ");
#endif
  while( nErr==0 && i>=0 && zSql[i]!=0 ){
  while( sqlite_malloc_failed==0 && nErr==0 && i>=0 && zSql[i]!=0 ){
    int tokenType;
    
    if( (pParse->db->flags & SQLITE_Interrupt)!=0 ){
      pParse->rc = SQLITE_INTERRUPT;
      sqliteSetString(pzErrMsg, "interrupt", 0);
      break;
    }
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
359
360
361
362
363
364
365


















366
367
368
369
370
371
372







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







        }else if( sqliteStrNICmp(z,"--parser-trace-off--", 20)==0 ){
          trace = 0;
          sqliteParserTrace(trace, "parser: ");
        }else if( sqliteStrNICmp(z,"--vdbe-trace-on--",17)==0 ){
          pParse->db->flags |= SQLITE_VdbeTrace;
        }else if( sqliteStrNICmp(z,"--vdbe-trace-off--", 18)==0 ){
          pParse->db->flags &= ~SQLITE_VdbeTrace;
#ifdef MEMORY_DEBUG
        }else if( sqliteStrNICmp(z,"--malloc-fail=",14)==0 ){
          sqlite_iMallocFail = atoi(&z[14]);
        }else if( sqliteStrNICmp(z,"--malloc-stats--", 16)==0 ){
          if( pParse->xCallback ){
            static char *azName[4] = {"malloc", "free", "to_fail", 0 };
            char *azArg[4];
            char zVal[3][30];
            sprintf(zVal[0],"%d", sqlite_nMalloc);
            sprintf(zVal[1],"%d", sqlite_nFree);
            sprintf(zVal[2],"%d", sqlite_iMallocFail);
            azArg[0] = zVal[0];
            azArg[1] = zVal[1];
            azArg[2] = zVal[2];
            azArg[3] = 0;
            pParse->xCallback(pParse->pArg, 3, azArg, azName);
          }
#endif
        }
#endif
        break;
      }
      case TK_ILLEGAL:
        sqliteSetNString(pzErrMsg, "unrecognized token: \"", -1, 
           pParse->sLastToken.z, pParse->sLastToken.n, "\"", 1, 0);
433
434
435
436
437
438
439
440
441
442
443
444
445
415
416
417
418
419
420
421

422
423
424
425
426







-





    pParse->pVdbe = 0;
  }
  if( pParse->pNewTable ){
    sqliteDeleteTable(pParse->db, pParse->pNewTable);
    pParse->pNewTable = 0;
  }
  sqliteParseInfoReset(pParse);
  sqliteStrRealloc(pzErrMsg);
  if( nErr>0 && pParse->rc==SQLITE_OK ){
    pParse->rc = SQLITE_ERROR;
  }
  return nErr;
}
Changes to src/update.c.
20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
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
** to handle UPDATE statements.
**
** $Id: update.c,v 1.10 2001/03/14 12:35:57 drh Exp $
** $Id: update.c,v 1.11 2001/04/11 14:28:43 drh Exp $
*/
#include "sqliteInt.h"

/*
** Process an UPDATE statement.
*/
void sqliteUpdate(
46
47
48
49
50
51
52


53
54
55
56
57
58
59

60
61
62
63
64
65
66
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69







+
+







+







  Index *pIdx;           /* For looping over indices */
  int nIdx;              /* Number of indices that need updating */
  int base;              /* Index of first available table cursor */
  Index **apIdx = 0;     /* An array of indices that need updating too */
  int *aXRef = 0;        /* aXRef[i] is the index in pChanges->a[] of the
                         ** an expression for the i-th column of the table.
                         ** aXRef[i]==-1 if the i-th column is not changed. */

  if( pParse->nErr || sqlite_malloc_failed ) goto update_cleanup;

  /* Locate the table which we want to update.  This table has to be
  ** put in an IdList structure because some of the subroutines we
  ** will be calling are designed to work with multiple tables and expect
  ** an IdList* parameter instead of just a Table* parameger.
  */
  pTabList = sqliteIdListAppend(0, pTableName);
  if( pTabList==0 ) goto update_cleanup;
  for(i=0; i<pTabList->nId; i++){
    pTabList->a[i].pTab = sqliteFindTable(pParse->db, pTabList->a[i].zName);
    if( pTabList->a[i].pTab==0 ){
      sqliteSetString(&pParse->zErrMsg, "no such table: ", 
         pTabList->a[i].zName, 0);
      pParse->nErr++;
      goto update_cleanup;
Changes to src/util.c.
22
23
24
25
26
27
28
29

30
31
32
33
34






35
36
37
38
39
40
41
22
23
24
25
26
27
28

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47







-
+





+
+
+
+
+
+







**
*************************************************************************
** Utility functions used throughout sqlite.
**
** This file contains functions for allocating memory, comparing
** strings, and stuff like that.
**
** $Id: util.c,v 1.20 2001/04/05 15:57:13 drh Exp $
** $Id: util.c,v 1.21 2001/04/11 14:28:43 drh Exp $
*/
#include "sqliteInt.h"
#include <stdarg.h>
#include <ctype.h>

/*
** If malloc() ever fails, this global variable gets set to 1.
** This causes the library to abort and never again function.
*/
int sqlite_malloc_failed = 0;

/*
** If MEMORY_DEBUG is defined, then use versions of malloc() and
** free() that track memory usage and check for buffer overruns.
*/
#ifdef MEMORY_DEBUG

/*
54
55
56
57
58
59
60
61




62
63
64
65
66




67
68
69
70
71
72
73
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







-
+
+
+
+




-
+
+
+
+







void *sqliteMalloc_(int n, char *zFile, int line){
  void *p;
  int *pi;
  int k;
  sqlite_nMalloc++;
  if( sqlite_iMallocFail>=0 ){
    sqlite_iMallocFail--;
    if( sqlite_iMallocFail==0 ) return 0;
    if( sqlite_iMallocFail==0 ){
      sqlite_malloc_failed++;
      return 0;
    }
  }
  if( n==0 ) return 0;
  k = (n+sizeof(int)-1)/sizeof(int);
  pi = malloc( (3+k)*sizeof(int));
  if( pi==0 ) return 0;
  if( pi==0 ){
    sqlite_malloc_failed++;
    return 0;
  }
  pi[0] = 0xdead1122;
  pi[1] = n;
  pi[k+2] = 0xdead3344;
  p = &pi[2];
  memset(p, 0, n);
#if MEMORY_DEBUG>1
  fprintf(stderr,"malloc %d bytes at 0x%x from %s:%d\n", n, (int)p, zFile,line);
127
128
129
130
131
132
133




134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153




154
155
156
157
158





159

160
161
162
163
164
165
166
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183

184
185
186
187
188
189
190
191







+
+
+
+




















+
+
+
+





+
+
+
+
+
-
+







  oldK = (oldN+sizeof(int)-1)/sizeof(int);
  if( oldPi[oldK+2]!=0xdead3344 ){
    fprintf(stderr,"High-end memory corruption in realloc at 0x%x\n", (int)p);
    return 0;
  }
  k = (n + sizeof(int) - 1)/sizeof(int);
  pi = malloc( (k+3)*sizeof(int) );
  if( pi==0 ){
    sqlite_malloc_failed++;
    return 0;
  }
  pi[0] = 0xdead1122;
  pi[1] = n;
  pi[k+2] = 0xdead3344;
  p = &pi[2];
  memcpy(p, oldP, n>oldN ? oldN : n);
  if( n>oldN ){
    memset(&((char*)p)[oldN], 0, n-oldN);
  }
  memset(oldPi, 0, (oldK+3)*sizeof(int));
  free(oldPi);
#if MEMORY_DEBUG>1
  fprintf(stderr,"realloc %d to %d bytes at 0x%x to 0x%x at %s:%d\n", oldN, n,
    (int)oldP, (int)p, zFile, line);
#endif
  return p;
}

/*
** Make a duplicate of a string into memory obtained from malloc()
** Free the original string using sqliteFree().
**
** This routine is called on all strings that are passed outside of
** the SQLite library.  That way clients can free the string using free()
** rather than having to call sqliteFree().
*/
void sqliteStrRealloc(char **pz){
  char *zNew;
  if( pz==0 || *pz==0 ) return;
  zNew = malloc( strlen(*pz) + 1 );
  if( zNew==0 ){
    sqlite_malloc_failed++;
    sqliteFree(*pz);
    *pz = 0;
  }
  if( zNew ) strcpy(zNew, *pz);
  strcpy(zNew, *pz);
  sqliteFree(*pz);
  *pz = zNew;
}

/*
** Make a copy of a string in memory obtained from sqliteMalloc()
*/
187
188
189
190
191
192
193
194




195
196
197
198
199
200
201
212
213
214
215
216
217
218

219
220
221
222
223
224
225
226
227
228
229







-
+
+
+
+








/*
** Allocate new memory and set it to zero.  Return NULL if
** no memory is available.
*/
void *sqliteMalloc(int n){
  void *p = malloc(n);
  if( p==0 ) return 0;
  if( p==0 ){
    sqlite_malloc_failed++;
    return 0;
  }
  memset(p, 0, n);
  return p;
}

/*
** Free memory previously obtained from sqliteMalloc()
*/
214
215
216
217
218
219
220
221





222
223
224
225
226
227
228
242
243
244
245
246
247
248

249
250
251
252
253
254
255
256
257
258
259
260







-
+
+
+
+
+







  if( p==0 ){
    return sqliteMalloc(n);
  }
  if( n==0 ){
    sqliteFree(p);
    return 0;
  }
  return realloc(p, n);
  p = realloc(p, n);
  if( p==0 ){
    sqlite_malloc_failed++;
  }
  return p;
}

/*
** Make a copy of a string in memory obtained from sqliteMalloc()
*/
char *sqliteStrDup(const char *z){
  char *zNew = sqliteMalloc(strlen(z)+1);
321
322
323
324
325
326
327

328
329
330
331
332
333
334
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367







+







** 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;
  if( z==0 ) return;
  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++;
Changes to src/vdbe.c.
37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
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.56 2001/04/05 15:57:13 drh Exp $
** $Id: vdbe.c,v 1.57 2001/04/11 14:28:43 drh Exp $
*/
#include "sqliteInt.h"
#include <unistd.h>
#include <ctype.h>

/*
** SQL is translated into a sequence of instructions to be
219
220
221
222
223
224
225
226
227

228
229
230
231
232
233
234
219
220
221
222
223
224
225

226
227
228
229
230
231
232
233
234







-

+







};

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

  p = sqliteMalloc( sizeof(Vdbe) );
  if( p==0 ) return 0;
  p->pBe = db->pBe;
  p->db = db;
  return p;
}

/*
** Turn tracing on or off
364
365
366
367
368
369
370
371

372
373
374
375
376
377
378
379
380
381
382
383

384
385
386
387
388
389
390
364
365
366
367
368
369
370

371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391







-
+












+







** 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);
  if( z ) sqliteDequote(z);
}

/*
** On the P3 argument of the given instruction, change all
** strings of whitespace characters into a single space and
** delete leading and trailing whitespace.
*/
void sqliteVdbeCompressSpace(Vdbe *p, int addr){
  char *z;
  int i, j;
  if( addr<0 || addr>=p->nOp ) return;
  z = p->aOp[addr].p3;
  if( z==0 ) return;
  i = j = 0;
  while( isspace(z[i]) ){ i++; }
  while( z[i] ){
    if( isspace(z[i]) ){
      z[j++] = ' ';
      while( isspace(z[++i]) ){}
    }else{
458
459
460
461
462
463
464




465
466
467
468
469
470
471
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476







+
+
+
+







*/
static void AggRehash(Agg *p, int nHash){
  int size;
  AggElem *pElem;
  if( p->nHash==nHash ) return;
  size = nHash * sizeof(AggElem*);
  p->apHash = sqliteRealloc(p->apHash, size );
  if( p->apHash==0 ){
    AggReset(p);
    return;
  }
  memset(p->apHash, 0, size);
  p->nHash = nHash;
  for(pElem=p->pFirst; pElem; pElem=pElem->pNext){
    AggEnhash(p, pElem);
  }
}

530
531
532
533
534
535
536
537




538
539
540
541
542
543
544
535
536
537
538
539
540
541

542
543
544
545
546
547
548
549
550
551
552







-
+
+
+
+







static void SetInsert(Set *p, char *zKey){
  SetElem *pElem;
  int h = sqliteHashNoCase(zKey, 0) % ArraySize(p->apHash);
  for(pElem=p->apHash[h]; pElem; pElem=pElem->pHash){
    if( strcmp(pElem->zKey, zKey)==0 ) return;
  }
  pElem = sqliteMalloc( sizeof(*pElem) + strlen(zKey) );
  if( pElem==0 ) return;
  if( pElem==0 ){
    SetClear(p);
    return;
  }
  strcpy(pElem->zKey, zKey);
  pElem->pNext = p->pAll;
  p->pAll = pElem;
  pElem->pHash = p->apHash[h];
  p->apHash[h] = pElem;
}

1000
1001
1002
1003
1004
1005
1006

1007
1008
1009
1010
1011
1012
1013
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022







+







  rc = SQLITE_OK;
#ifdef MEMORY_DEBUG
  if( access("vdbe_trace",0)==0 ){
    p->trace = stderr;
  }
#endif
  /* if( pzErrMsg ){ *pzErrMsg = 0; } */
  if( sqlite_malloc_failed ) rc = SQLITE_NOMEM;
  for(pc=0; rc==SQLITE_OK && pc<p->nOp VERIFY(&& pc>=0); pc++){
    pOp = &p->aOp[pc];

    /* Interrupt processing if requested.
    */
    if( db->flags & SQLITE_Interrupt ){
      db->flags &= ~SQLITE_Interrupt;
1360
1361
1362
1363
1364
1365
1366
1367

1368
1369
1370
1371
1372
1373
1374
1375
1369
1370
1371
1372
1373
1374
1375

1376

1377
1378
1379
1380
1381
1382
1383







-
+
-







        }else if( (ft & fn & STK_Int)==STK_Int ){
          copy = aStack[nos].i<aStack[tos].i;
        }else if( ( (ft|fn) & (STK_Int|STK_Real) ) !=0 ){
          Realify(p, tos);
          Realify(p, nos);
          copy = aStack[tos].r>aStack[nos].r;
        }else{
          Stringify(p, tos);
          if( Stringify(p, tos) || Stringify(p, nos) ) goto no_mem;
          Stringify(p, nos);
          copy = sqliteCompare(zStack[tos],zStack[nos])>0;
        }
        if( copy ){
          Release(p, nos);
          aStack[nos] = aStack[tos];
          zStack[nos] = zStack[tos];
          zStack[tos] = 0;
1401
1402
1403
1404
1405
1406
1407
1408

1409
1410
1411
1412
1413
1414
1415
1416
1409
1410
1411
1412
1413
1414
1415

1416

1417
1418
1419
1420
1421
1422
1423







-
+
-







        }else if( (ft & fn & STK_Int)==STK_Int ){
          copy = aStack[nos].i>aStack[tos].i;
        }else if( ( (ft|fn) & (STK_Int|STK_Real) ) !=0 ){
          Realify(p, tos);
          Realify(p, nos);
          copy = aStack[tos].r<aStack[nos].r;
        }else{
          Stringify(p, tos);
          if( Stringify(p, tos) || Stringify(p, nos) ) goto no_mem;
          Stringify(p, nos);
          copy = sqliteCompare(zStack[tos],zStack[nos])<0;
        }
        if( copy ){
          Release(p, nos);
          aStack[nos] = aStack[tos];
          zStack[nos] = zStack[tos];
          zStack[tos] = 0;
1481
1482
1483
1484
1485
1486
1487
1488

1489
1490
1491
1492
1493
1494
1495
1496
1488
1489
1490
1491
1492
1493
1494

1495

1496
1497
1498
1499
1500
1501
1502







-
+
-







        int ft, fn;
        VERIFY( if( nos<0 ) goto not_enough_stack; )
        ft = aStack[tos].flags;
        fn = aStack[nos].flags;
        if( (ft & fn)==STK_Int ){
          c = aStack[nos].i - aStack[tos].i;
        }else{
          Stringify(p, tos);
          if( Stringify(p, tos) || Stringify(p, nos) ) goto no_mem;
          Stringify(p, nos);
          c = sqliteCompare(zStack[nos], zStack[tos]);
        }
        switch( pOp->opcode ){
          case OP_Eq:    c = c==0;     break;
          case OP_Ne:    c = c!=0;     break;
          case OP_Lt:    c = c<0;      break;
          case OP_Le:    c = c<=0;     break;
1519
1520
1521
1522
1523
1524
1525
1526

1527
1528
1529
1530
1531
1532
1533
1534
1525
1526
1527
1528
1529
1530
1531

1532

1533
1534
1535
1536
1537
1538
1539







-
+
-







      ** are different.
      */
      case OP_Like: {
        int tos = p->tos;
        int nos = tos - 1;
        int c;
        VERIFY( if( nos<0 ) goto not_enough_stack; )
        Stringify(p, tos);
        if( Stringify(p, tos) || Stringify(p, nos) ) goto no_mem;
        Stringify(p, nos);
        c = sqliteLikeCompare(zStack[tos], zStack[nos]);
        POPSTACK;
        POPSTACK;
        if( pOp->p1 ) c = !c;
        if( c ) pc = pOp->p2-1;
        break;
      }
1552
1553
1554
1555
1556
1557
1558
1559

1560
1561
1562
1563
1564
1565
1566
1567
1557
1558
1559
1560
1561
1562
1563

1564

1565
1566
1567
1568
1569
1570
1571







-
+
-







      ** are different.
      */
      case OP_Glob: {
        int tos = p->tos;
        int nos = tos - 1;
        int c;
        VERIFY( if( nos<0 ) goto not_enough_stack; )
        Stringify(p, tos);
        if( Stringify(p, tos) || Stringify(p, nos) ) goto no_mem;
        Stringify(p, nos);
        c = sqliteGlobCompare(zStack[tos], zStack[nos]);
        POPSTACK;
        POPSTACK;
        if( pOp->p1 ) c = !c;
        if( c ) pc = pOp->p2-1;
        break;
      }
3066
3067
3068
3069
3070
3071
3072
3073

3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088

3089
3090
3091
3092
3093
3094
3095
3070
3071
3072
3073
3074
3075
3076

3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100







-
+















+







      case OP_AggFocus: {
        int tos = p->tos;
        AggElem *pElem;
        char *zKey;
        int nKey;

        VERIFY( if( tos<0 ) goto not_enough_stack; )
        Stringify(p, tos);
        if( Stringify(p, tos) ) goto no_mem;
        zKey = zStack[tos]; 
        nKey = aStack[tos].n;
        if( p->agg.nHash<=0 ){
          pElem = 0;
        }else{
          int h = sqliteHashNoCase(zKey, nKey-1) % p->agg.nHash;
          for(pElem=p->agg.apHash[h]; pElem; pElem=pElem->pHash){
            if( strcmp(pElem->zKey, zKey)==0 ) break;
          }
        }
        if( pElem ){
          p->agg.pCurrent = pElem;
          pc = pOp->p2 - 1;
        }else{
          AggInsert(&p->agg, zKey);
          if( sqlite_malloc_failed ) goto no_mem;
        }
        POPSTACK;
        break; 
      }

      /* Opcode: AggIncr P1 P2 *
      **
3237
3238
3239
3240
3241
3242
3243
3244

3245
3246
3247

3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261

3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279

3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296

3297
3298
3299
3300
3301
3302
3303
3242
3243
3244
3245
3246
3247
3248

3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266

3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284

3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301

3302
3303
3304
3305
3306
3307
3308
3309







-
+



+













-
+

















-
+
















-
+







          p->nSet = i+1;
        }
        if( pOp->p3 ){
          SetInsert(&p->aSet[i], pOp->p3);
        }else{
          int tos = p->tos;
          if( tos<0 ) goto not_enough_stack;
          Stringify(p, tos);
          if( Stringify(p, tos) ) goto no_mem;
          SetInsert(&p->aSet[i], zStack[tos]);
          POPSTACK;
        }
        if( sqlite_malloc_failed ) goto no_mem;
        break;
      }

      /* Opcode: SetFound P1 P2 *
      **
      ** Pop the stack once and compare the value popped off with the
      ** contents of set P1.  If the element popped exists in set P1,
      ** then jump to P2.  Otherwise fall through.
      */
      case OP_SetFound: {
        int i = pOp->p1;
        int tos = p->tos;
        VERIFY( if( tos<0 ) goto not_enough_stack; )
        Stringify(p, tos);
        if( Stringify(p, tos) ) goto no_mem;
        if( VERIFY( i>=0 && i<p->nSet &&) SetTest(&p->aSet[i], zStack[tos])){
          pc = pOp->p2 - 1;
        }
        POPSTACK;
        break;
      }

      /* Opcode: SetNotFound P1 P2 *
      **
      ** Pop the stack once and compare the value popped off with the
      ** contents of set P1.  If the element popped does not exists in 
      ** set P1, then jump to P2.  Otherwise fall through.
      */
      case OP_SetNotFound: {
        int i = pOp->p1;
        int tos = p->tos;
        VERIFY( if( tos<0 ) goto not_enough_stack; )
        Stringify(p, tos);
        if( Stringify(p, tos) ) goto no_mem;
        if(VERIFY( i>=0 && i<p->nSet &&) !SetTest(&p->aSet[i], zStack[tos])){
          pc = pOp->p2 - 1;
        }
        POPSTACK;
        break;
      }

      /* Opcode: Strlen * * *
      **
      ** Interpret the top of the stack as a string.  Replace the top of
      ** stack with an integer which is the length of the string.
      */
      case OP_Strlen: {
        int tos = p->tos;
        int len;
        VERIFY( if( tos<0 ) goto not_enough_stack; )
        Stringify(p, tos);
        if( Stringify(p, tos) ) goto no_mem;
#ifdef SQLITE_UTF8
        {
          char *z = zStack[tos];
          for(len=0; *z; z++){ if( (0xc0&*z)!=0x80 ) len++; }
        }
#else
        len = aStack[tos].n-1;
3347
3348
3349
3350
3351
3352
3353
3354

3355
3356
3357
3358
3359
3360
3361
3353
3354
3355
3356
3357
3358
3359

3360
3361
3362
3363
3364
3365
3366
3367







-
+







          Integerify(p, p->tos);
          start = aStack[p->tos].i - 1;
          POPSTACK;
        }else{
          start = pOp->p1 - 1;
        }
        VERIFY( if( p->tos<0 ) goto not_enough_stack; )
        Stringify(p, p->tos);
        if( Stringify(p, p->tos) ) goto no_mem;

        /* "n" will be the number of characters in the input string.
        ** For iso8859, the number of characters is the number of bytes.
        ** Buf for UTF-8, some characters can use multiple bytes and the
        ** situation is more complex. 
        */
#ifdef SQLITE_UTF8
Changes to src/where.c.
21
22
23
24
25
26
27
28

29
30
31
32
33
34
35
21
22
23
24
25
26
27

28
29
30
31
32
33
34
35







-
+







**   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.13 2001/04/04 11:48:58 drh Exp $
** $Id: where.c,v 1.14 2001/04/11 14:28:43 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.
166
167
168
169
170
171
172
173

174

175
176
177
178
179
180
181
166
167
168
169
170
171
172

173
174
175
176
177
178
179
180
181
182







-
+

+







  /* Allocate space for aOrder[]. */
  aOrder = sqliteMalloc( sizeof(int) * pTabList->nId );

  /* Allocate and initialize the WhereInfo structure that will become the
  ** return value.
  */
  pWInfo = sqliteMalloc( sizeof(WhereInfo) );
  if( pWInfo==0 ){
  if( sqlite_malloc_failed ){
    sqliteFree(aOrder);
    sqliteFree(pWInfo);
    return 0;
  }
  pWInfo->pParse = pParse;
  pWInfo->pTabList = pTabList;
  base = pWInfo->base = pParse->nTab;

  /* Split the WHERE clause into as many as 32 separate subexpressions
Changes to test/all.test.
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
18
19
20
21
22
23
24

25
26
27
28
29
30
31
32







-
+







# Author contact information:
#   drh@hwaci.com
#   http://www.hwaci.com/drh/
#
#***********************************************************************
# This file runs all tests.
#
# $Id: all.test,v 1.5 2000/12/10 18:23:51 drh Exp $
# $Id: all.test,v 1.6 2001/04/11 14:28:43 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
rename finish_test really_finish_test
proc finish_test {} {memleak_check}

if {[file exists ./sqlite_test_count]} {
49
50
51
52
53
54
55

56
57
58
59
60
61
62
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63







+









for {set Counter 0} {$Counter<$COUNT} {incr Counter} {
  foreach p $PREFIXES {
    set dbprefix $p
    foreach testfile [lsort -dictionary [glob $testdir/*.test]] {
      if {[file tail $testfile]=="all.test"} continue
      if {[file tail $testfile]=="malloc.test"} continue
      source $testfile
    }
  }
  if {[info exists Leak]} {
    lappend LeakList $Leak
  }
}
74
75
76
77
78
79
80
81









82
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92








+
+
+
+
+
+
+
+
+

       puts "     Got: $LeakList"
       incr ::nErr
       break
    }
  }
  puts " Ok"
}

if {[file readable $testdir/malloc.test]} {
  for {set Counter 0} {$Counter<$COUNT} {incr Counter} {
    foreach p $PREFIXES {
      set dbprefix $p
      source $testdir/malloc.test
    }
  }
}

really_finish_test
Changes to test/printf.test.
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
47
48
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
47
48
49
50
51
52
53
54
55
56
57







-
+















+
+
+
+
+
+
+
+
+







#   drh@hwaci.com
#   http://www.hwaci.com/drh/
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the sqlite_*_printf() interface.
#
# $Id: printf.test,v 1.1 2001/04/07 15:24:33 drh Exp $
# $Id: printf.test,v 1.2 2001/04/11 14:28:43 drh Exp $

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

set n 1
foreach v {1 2 5 10 99 100 1000000 999999999 0 -1 -2 -5 -10 -99 -100 -9999999} {
  do_test printf-1.$n.1 [subst {
    sqlite_mprintf_int {Three integers: %d %x %o} $v $v $v
  }] [format {Three integers: %d %x %o} $v $v $v]
  do_test printf-1.$n.2 [subst {
    sqlite_mprintf_int {Three integers: (%6d) (%6x) (%6o)} $v $v $v
  }] [format {Three integers: (%6d) (%6x) (%6o)} $v $v $v]
  do_test printf-1.$n.3 [subst {
    sqlite_mprintf_int {Three integers: (%-6d) (%-6x) (%-6o)} $v $v $v
  }] [format {Three integers: (%-6d) (%-6x) (%-6o)} $v $v $v]
  do_test printf-1.$n.4 [subst {
    sqlite_mprintf_int {Three integers: (%+6d) (%+6x) (%+6o)} $v $v $v
  }] [format {Three integers: (%+6d) (%+6x) (%+6o)} $v $v $v]
  do_test printf-1.$n.5 [subst {
    sqlite_mprintf_int {Three integers: (%06d) (%06x) (%06o)} $v $v $v
  }] [format {Three integers: (%06d) (%06x) (%06o)} $v $v $v]
  do_test printf-1.$n.6 [subst {
    sqlite_mprintf_int {Three integers: (% 6d) (% 6x) (% 6o)} $v $v $v
  }] [format {Three integers: (% 6d) (% 6x) (% 6o)} $v $v $v]
  incr n
}

set m 1
foreach {a b} {1 1 5 5 10 10 10 5} {
  set n 1
  foreach x {0.001 1.0e-20 1.0 0.0 100.0 9.99999 -0.00543 -1.0 -99.99999} {
85
86
87
88
89
90
91











92
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112







+
+
+
+
+
+
+
+
+
+
+

  sqlite_mprintf_str {%d %d A String: (%-30s)} 1 2 {This is the string}
} [format {%d %d A String: (%-30s)} 1 2 {This is the string}]

do_test printf-4.1 {
  sqlite_mprintf_str {%d %d A quoted string: '%q'} 1 2 {Hi Y'all}
} {1 2 A quoted string: 'Hi Y''all'}

do_test printf-5.1 {
  set x [sqlite_mprintf_str {%d %d %100000s} 0 0 {Hello}]
  string length $x
} {994}
do_test printf-5.2 {
  sqlite_mprintf_str {%d %d (%-10.10s) %} -9 -10 {HelloHelloHello}
} {-9 -10 (HelloHello) %}
do_test printf-5.3 {
  sqlite_mprintf_str {%% %d %d (%=10s)} 5 6 Hello
} {% 5 6 (  Hello   )}

finish_test
Changes to test/tableapi.test.
20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34







-
+







#   http://www.hwaci.com/drh/
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the sqlite_exec_printf() and
# sqlite_get_table_printf() APIs.
#
# $Id: tableapi.test,v 1.1 2001/04/07 15:24:34 drh Exp $
# $Id: tableapi.test,v 1.2 2001/04/11 14:28:43 drh Exp $

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

do_test tableapi-1.0 {
  set ::dbx [sqlite_open testdb]
  catch {sqlite_exec_printf $::dbx {DROP TABLE xyz} {}}
44
45
46
47
48
49
50











































51
52
53
54
55
56
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+






} {0 {a b 1 {Hi Y'all}}}

do_test tableapi-2.1 {
  sqlite_get_table_printf $::dbx {
    SELECT * FROM xyz WHERE b='%q'
  } {Hi Y'all}
} {0 1 2 a b 1 {Hi Y'all}}
do_test tableapi-2.2 {
  sqlite_get_table_printf $::dbx {
    SELECT * FROM xyz
  } {}
} {0 1 2 a b 1 {Hi Y'all}}
do_test tableapi-2.3 {
  for {set i 2} {$i<=50} {incr i} {
    sqlite_get_table_printf $::dbx \
       "INSERT INTO xyz VALUES($i,'(%s)')" $i
  }
  sqlite_get_table_printf $::dbx {
    SELECT * FROM xyz ORDER BY a
  } {}
} {0 50 2 a b 1 {Hi Y'all} 2 (2) 3 (3) 4 (4) 5 (5) 6 (6) 7 (7) 8 (8) 9 (9) 10 (10) 11 (11) 12 (12) 13 (13) 14 (14) 15 (15) 16 (16) 17 (17) 18 (18) 19 (19) 20 (20) 21 (21) 22 (22) 23 (23) 24 (24) 25 (25) 26 (26) 27 (27) 28 (28) 29 (29) 30 (30) 31 (31) 32 (32) 33 (33) 34 (34) 35 (35) 36 (36) 37 (37) 38 (38) 39 (39) 40 (40) 41 (41) 42 (42) 43 (43) 44 (44) 45 (45) 46 (46) 47 (47) 48 (48) 49 (49) 50 (50)}
do_test tableapi-2.3.1 {
  sqlite_get_table_printf $::dbx {
    SELECT * FROM xyz  WHERE a>49 ORDER BY a
  } {}
} {0 1 2 a b 50 (50)}
do_test tableapi-2.3.2 {
  sqlite_get_table_printf $::dbx {
    SELECT * FROM xyz WHERE a>47 ORDER BY a
  } {}
} {0 3 2 a b 48 (48) 49 (49) 50 (50)}
do_test tableapi-2.4 {
  set ::big_str [sqlite_mprintf_str {%500'* Hello %500'*} 0 0 {}]
  sqlite_get_table_printf $::dbx {
    INSERT INTO xyz VALUES(51,'%q')
  } $::big_str
} {0 0 0}
do_test tableapi-2.5 {
  sqlite_get_table_printf $::dbx {
    SELECT * FROM xyz WHERE a>49 ORDER BY a;
  } {}
} "0 2 2 a b 50 (50) 51 \173$::big_str\175"
do_test tableapi-2.6 {
  sqlite_get_table_printf $::dbx {
    INSERT INTO xyz VALUES(52,NULL)
  } {}
  sqlite_get_table_printf $::dbx {
    SELECT * FROM xyz WHERE a IN (42,50,52) ORDER BY a DESC
  } {}
} {0 3 2 a b 52 NULL 50 (50) 42 (42)}

do_test tableapi-99.0 {
  sqlite_close $::dbx
} {}

finish_test
Changes to test/tester.tcl.
19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
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 some common TCL routines used for regression
# testing the SQLite library
#
# $Id: tester.tcl,v 1.14 2001/04/06 16:13:43 drh Exp $
# $Id: tester.tcl,v 1.15 2001/04/11 14:28:43 drh Exp $

# Make sure tclsqlite was compiled correctly.  Abort now with an
# error message if not.
#
if {[sqlite -tcl-uses-utf]} {
  if {"\u1234"=="u1234"} {
    puts stderr "***** BUILD PROBLEM *****"
179
180
181
182
183
184
185
186

187
188
189
190
191
192
193

194

195
196

197

198
199
200
201
202
203
204
179
180
181
182
183
184
185

186
187
188
189
190
191
192
193
194

195


196

197
198
199
200
201
202
203
204







-
+







+
-
+
-
-
+
-
+







      set ::skip_test 0
      return
    }
  }
  set ::skip_test 1
}

# The procedure uses the special "--malloc-stats--" macro of SQLite
# The procedure uses the special "sqlite_malloc_stat" command
# (which is only available if SQLite is compiled with -DMEMORY_DEBUG=1)
# to see how many malloc()s have not been free()ed.  The number
# of surplus malloc()s is stored in the global variable $::Leak.
# If the value in $::Leak grows, it may mean there is a memory leak
# in the library.
#
proc memleak_check {} {
  if {[info command sqlite_malloc_stat]!=""} {
  set r [execsql {--malloc-stats--}]
    set r [sqlite_malloc_stat]
  if {$r==""} return
  set ::Leak [expr {[lindex $r 0]-[lindex $r 1]}]
    set ::Leak [expr {[lindex $r 0]-[lindex $r 1]}]
  # puts "*** $::Leak mallocs have not been freed ***"
  }
}

# Run this routine last
#
proc finish_test {} {
  global nTest nErr nProb
  memleak_check
Changes to www/changes.tcl.
13
14
15
16
17
18
19
20


21
22
23
24
25
26
27
13
14
15
16
17
18
19

20
21
22
23
24
25
26
27
28







-
+
+









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

chng {2001 Apr 6 (1.0.31)} {
chng {2001 Apr 11 (1.0.31)} {
<li>More robust handling of out-of-memory errors.</li>
<li>New tests added to the test suite.</li>
}

chng {2001 Apr 6 (1.0.30)} {
<li>Remove the <b>sqlite_encoding</b> TCL variable that was introduced
    in the previous version.</li>
<li>Add options <b>-encoding</b> and <b>-tcl-uses-utf</b> to the