SQLite

Check-in [e7b65e37fd]
Login

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

Overview
Comment:All tests now pass. But there are still issues. For example, inserts are way too slow. And additional tests are needed for new features. (CVS 243)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: e7b65e37fd88c4d69c89cfe73ab345b8b645ada6
User & Date: drh 2001-09-14 03:24:24.000
Context
2001-09-14
16:42
Bug fixes and speed improvements. Delete is still slow. (CVS 244) (check-in: 7da856cd94 user: drh tags: trunk)
03:24
All tests now pass. But there are still issues. For example, inserts are way too slow. And additional tests are needed for new features. (CVS 243) (check-in: e7b65e37fd user: drh tags: trunk)
2001-09-13
21:53
Many problems fixed. Many problems yet to go. (CVS 1722) (check-in: 3dfe1711e6 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/btree.c.
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
** Boston, MA  02111-1307, USA.
**
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** $Id: btree.c,v 1.24 2001/09/13 21:53:09 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
**     "Sorting And Searching", pages 473-480. Addison-Wesley
**     Publishing Company, Reading, Massachusetts.







|







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
** Boston, MA  02111-1307, USA.
**
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** $Id: btree.c,v 1.25 2001/09/14 03:24:24 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
**     "Sorting And Searching", pages 473-480. Addison-Wesley
**     Publishing Company, Reading, Massachusetts.
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
  MemPage aOld[3];             /* Temporary copies of pPage and its siblings */

  /* 
  ** Return without doing any work if pPage is neither overfull nor
  ** underfull.
  */
  assert( sqlitepager_iswriteable(pPage) );
  if( !pPage->isOverfull && pPage->nFree<SQLITE_PAGE_SIZE/3 ){
    relinkCellList(pPage);
    return SQLITE_OK;
  }

  /*
  ** Find the parent of the page to be balanceed.
  ** If there is no parent, it means this page is the root page and







|







1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
  MemPage aOld[3];             /* Temporary copies of pPage and its siblings */

  /* 
  ** Return without doing any work if pPage is neither overfull nor
  ** underfull.
  */
  assert( sqlitepager_iswriteable(pPage) );
  if( !pPage->isOverfull && pPage->nFree<SQLITE_PAGE_SIZE/2 && pPage->nCell>=2){
    relinkCellList(pPage);
    return SQLITE_OK;
  }

  /*
  ** Find the parent of the page to be balanceed.
  ** If there is no parent, it means this page is the root page and
1977
1978
1979
1980
1981
1982
1983




1984
1985
1986

1987
1988
1989
1990
1991
1992
1993
  apNew[nNew-1]->u.hdr.rightChild = apOld[nOld-1]->u.hdr.rightChild;
  if( nxDiv==pParent->nCell ){
    pParent->u.hdr.rightChild = pgnoNew[nNew-1];
  }else{
    pParent->apCell[nxDiv]->h.leftChild = pgnoNew[nNew-1];
  }
  if( pCur ){




    assert( pOldCurPage!=0 );
    sqlitepager_ref(pCur->pPage);
    sqlitepager_unref(pOldCurPage);

  }

  /*
  ** Reparent children of all cells.
  */
  for(i=0; i<nNew; i++){
    reparentChildPages(pBt->pPager, apNew[i]);







>
>
>
>
|
|
|
>







1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
  apNew[nNew-1]->u.hdr.rightChild = apOld[nOld-1]->u.hdr.rightChild;
  if( nxDiv==pParent->nCell ){
    pParent->u.hdr.rightChild = pgnoNew[nNew-1];
  }else{
    pParent->apCell[nxDiv]->h.leftChild = pgnoNew[nNew-1];
  }
  if( pCur ){
    if( j<=iCur && pCur->pPage==pParent && pCur->idx>idxDiv[nOld-1] ){
      assert( pCur->pPage==pOldCurPage );
      pCur->idx += nNew - nOld;
    }else{
      assert( pOldCurPage!=0 );
      sqlitepager_ref(pCur->pPage);
      sqlitepager_unref(pOldCurPage);
    }
  }

  /*
  ** Reparent children of all cells.
  */
  for(i=0; i<nNew; i++){
    reparentChildPages(pBt->pPager, apNew[i]);
2059
2060
2061
2062
2063
2064
2065


2066
2067
2068
2069
2070
2071
2072
    assert( pPage->u.hdr.rightChild==0 );  /* Must be a leaf page */
    pCur->idx++;
  }else{
    assert( pPage->u.hdr.rightChild==0 );  /* Must be a leaf page */
  }
  insertCell(pPage, pCur->idx, &newCell, szNew);
  rc = balance(pCur->pBt, pPage, pCur);


  return rc;
}

/*
** Delete the entry that the cursor is pointing to.
**
** The cursor is left pointing at either the next or the previous







>
>







2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
    assert( pPage->u.hdr.rightChild==0 );  /* Must be a leaf page */
    pCur->idx++;
  }else{
    assert( pPage->u.hdr.rightChild==0 );  /* Must be a leaf page */
  }
  insertCell(pPage, pCur->idx, &newCell, szNew);
  rc = balance(pCur->pBt, pPage, pCur);
  /* sqliteBtreePageDump(pCur->pBt, pCur->pgnoRoot, 1); */
  /* fflush(stdout); */
  return rc;
}

/*
** Delete the entry that the cursor is pointing to.
**
** The cursor is left pointing at either the next or the previous
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
59
60
61
62
63
64
65
66
**     DROP TABLE
**     CREATE INDEX
**     DROP INDEX
**     creating expressions and ID lists
**     COPY
**     VACUUM
**
** $Id: build.c,v 1.32 2001/09/13 21:53:10 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;
  sqlite *db = pParse->db;
  if( sqlite_malloc_failed ) return;
  if( pParse->pVdbe ){
    if( pParse->explain ){
      rc = sqliteVdbeList(pParse->pVdbe, pParse->xCallback, pParse->pArg, 
                          &pParse->zErrMsg);
    }else{
      FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stderr : 0;
      sqliteVdbeTrace(pParse->pVdbe, trace);
      rc = sqliteVdbeExec(pParse->pVdbe, pParse->xCallback, pParse->pArg, 
                          &pParse->zErrMsg, db->pBusyArg,
                          db->xBusyCallback);
    }
    sqliteVdbeDelete(pParse->pVdbe);
    pParse->pVdbe = 0;







|

















|




|







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
**     DROP TABLE
**     CREATE INDEX
**     DROP INDEX
**     creating expressions and ID lists
**     COPY
**     VACUUM
**
** $Id: build.c,v 1.33 2001/09/14 03:24:24 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;
  sqlite *db = pParse->db;
  if( sqlite_malloc_failed ) return;
  if( pParse->pVdbe && pParse->nErr==0 ){
    if( pParse->explain ){
      rc = sqliteVdbeList(pParse->pVdbe, pParse->xCallback, pParse->pArg, 
                          &pParse->zErrMsg);
    }else{
      FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0;
      sqliteVdbeTrace(pParse->pVdbe, trace);
      rc = sqliteVdbeExec(pParse->pVdbe, pParse->xCallback, pParse->pArg, 
                          &pParse->zErrMsg, db->pBusyArg,
                          db->xBusyCallback);
    }
    sqliteVdbeDelete(pParse->pVdbe);
    pParse->pVdbe = 0;
864
865
866
867
868
869
870

871
872
873
874
875
876
877
    };
    int base;

    if( (db->flags & SQLITE_InTrans)==0 ){
      sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
    }
    base = sqliteVdbeAddOpList(v, ArraySize(dropIndex), dropIndex);

    sqliteVdbeChangeP1(v, base+8, pIndex->tnum);
    if( (db->flags & SQLITE_InTrans)==0 ){
      sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0);
    }
  }

  /* Mark the internal Index structure for deletion by the







>







864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
    };
    int base;

    if( (db->flags & SQLITE_InTrans)==0 ){
      sqliteVdbeAddOp(v, OP_Transaction, 0, 0, 0, 0);
    }
    base = sqliteVdbeAddOpList(v, ArraySize(dropIndex), dropIndex);
    sqliteVdbeChangeP3(v, base+2, pIndex->zName, 0);
    sqliteVdbeChangeP1(v, base+8, pIndex->tnum);
    if( (db->flags & SQLITE_InTrans)==0 ){
      sqliteVdbeAddOp(v, OP_Commit, 0, 0, 0, 0);
    }
  }

  /* Mark the internal Index structure for deletion by the
Changes to src/expr.c.
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** This file contains routines used for analyzing expressions and
** for generating VDBE code that evaluates expressions.
**
** $Id: expr.c,v 1.26 2001/09/13 14:46:10 drh Exp $
*/
#include "sqliteInt.h"

/*
** Walk an expression tree.  Return 1 if the expression is constant
** and 0 if it involves variables.
*/







|







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.27 2001/09/14 03:24:25 drh Exp $
*/
#include "sqliteInt.h"

/*
** Walk an expression tree.  Return 1 if the expression is constant
** and 0 if it involves variables.
*/
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
  switch( pExpr->op ){
    case TK_COLUMN: {
      if( pParse->useAgg ){
        sqliteVdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg, 0, 0);
      }else if( pExpr->iColumn>=0 ){
        sqliteVdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn, 0, 0);
      }else{
        sqliteVdbeAddOp(v, OP_FullKey, pExpr->iTable, 0, 0, 0);
      }
      break;
    }
    case TK_INTEGER: {
      int i = atoi(pExpr->token.z);
      sqliteVdbeAddOp(v, OP_Integer, i, 0, 0, 0);
      break;







|







513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
  switch( pExpr->op ){
    case TK_COLUMN: {
      if( pParse->useAgg ){
        sqliteVdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg, 0, 0);
      }else if( pExpr->iColumn>=0 ){
        sqliteVdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn, 0, 0);
      }else{
        sqliteVdbeAddOp(v, OP_Recno, pExpr->iTable, 0, 0, 0);
      }
      break;
    }
    case TK_INTEGER: {
      int i = atoi(pExpr->token.z);
      sqliteVdbeAddOp(v, OP_Integer, i, 0, 0, 0);
      break;
Changes to src/insert.c.
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle INSERT statements.
**
** $Id: insert.c,v 1.15 2001/09/13 14:46:10 drh Exp $
*/
#include "sqliteInt.h"

/*
** This routine is call to handle SQL of the following forms:
**
**    insert into TABLE (IDLIST) values(EXPRLIST)







|







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.16 2001/09/14 03:24:25 drh Exp $
*/
#include "sqliteInt.h"

/*
** This routine is call to handle SQL of the following forms:
**
**    insert into TABLE (IDLIST) values(EXPRLIST)
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
    sqliteVdbeAddOp(v, OP_Rewind, srcTab, 0, 0, 0);
    iBreak = sqliteVdbeMakeLabel(v);
    iCont = sqliteVdbeAddOp(v, OP_Next, srcTab, iBreak, 0, 0);
  }

  /* Create a new entry in the table and fill it with data.
  */
  sqliteVdbeAddOp(v, OP_NewRecno, 0, 0, 0, 0);
  if( pTab->pIndex ){
    sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
  }
  for(i=0; i<pTab->nCol; i++){
    if( pColumn==0 ){
      j = i;
    }else{







|







177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
    sqliteVdbeAddOp(v, OP_Rewind, srcTab, 0, 0, 0);
    iBreak = sqliteVdbeMakeLabel(v);
    iCont = sqliteVdbeAddOp(v, OP_Next, srcTab, iBreak, 0, 0);
  }

  /* Create a new entry in the table and fill it with data.
  */
  sqliteVdbeAddOp(v, OP_NewRecno, base, 0, 0, 0);
  if( pTab->pIndex ){
    sqliteVdbeAddOp(v, OP_Dup, 0, 0, 0, 0);
  }
  for(i=0; i<pTab->nCol; i++){
    if( pColumn==0 ){
      j = i;
    }else{
Changes to src/pager.c.
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
*************************************************************************
** This is the implementation of the page cache subsystem.
** 
** The page cache is used to access a database file.  The pager journals
** all writes in order to support rollback.  Locking is used to limit
** access to one or more reader or to one writer.
**
** @(#) $Id: pager.c,v 1.15 2001/09/13 14:46:10 drh Exp $
*/
#include "sqliteInt.h"
#include "pager.h"
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <assert.h>







|







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
*************************************************************************
** This is the implementation of the page cache subsystem.
** 
** The page cache is used to access a database file.  The pager journals
** all writes in order to support rollback.  Locking is used to limit
** access to one or more reader or to one writer.
**
** @(#) $Id: pager.c,v 1.16 2001/09/14 03:24:25 drh Exp $
*/
#include "sqliteInt.h"
#include "pager.h"
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <assert.h>
471
472
473
474
475
476
477
478

479
480
481
482
483
484
485
486
487
488
     "/tmp",
     "/temp",
     "./temp",
  };
  int i;
  struct stat buf;
  for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){
    if( stat(azDirs[i], &buf)==0 && S_ISDIR(buf.st_mode)

         && access(azDirs[i], W_OK) ){
       return azDirs[i];
    }
  }
  return 0;
}

/*
** Create a new page cache and put a pointer to the page cache in *ppPager.
** The file to be cached need not exist.  The file is not locked until







|
>
|
|
<







471
472
473
474
475
476
477
478
479
480
481

482
483
484
485
486
487
488
     "/tmp",
     "/temp",
     "./temp",
  };
  int i;
  struct stat buf;
  for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){
    if( stat(azDirs[i], &buf) ) continue;
    if( !S_ISDIR(buf.st_mode) ) continue;
    if( access(azDirs[i], 07) ) continue;
    return azDirs[i];

  }
  return 0;
}

/*
** Create a new page cache and put a pointer to the page cache in *ppPager.
** The file to be cached need not exist.  The file is not locked until
Changes to src/random.c.
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
*************************************************************************
** This file contains code to implement a pseudo-random number
** generator (PRNG) for SQLite.
**
** Random numbers are used by some of the database backends in order
** to generate random integer keys for tables or random filenames.
**
** $Id: random.c,v 1.3 2001/09/13 21:53:10 drh Exp $
*/
#include "sqliteInt.h"
#include <time.h>

/*
** Get a single 8-bit random value from the RC4 PRNG.
*/







|







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
*************************************************************************
** This file contains code to implement a pseudo-random number
** generator (PRNG) for SQLite.
**
** Random numbers are used by some of the database backends in order
** to generate random integer keys for tables or random filenames.
**
** $Id: random.c,v 1.4 2001/09/14 03:24:25 drh Exp $
*/
#include "sqliteInt.h"
#include <time.h>

/*
** Get a single 8-bit random value from the RC4 PRNG.
*/
100
101
102
103
104
105
106










107
108
109
110
111
112
113
  r = sqliteRandomByte();
  for(i=1; i<4; i++){
    r = (r<<8) + sqliteRandomByte();
  }
  return r;
}












/*
** Generate a random filename with the given prefix.  The new filename
** is written into zBuf[].  The calling function must insure that
** zBuf[] is big enough to hold the prefix plus 20 or so extra
** characters.
**







>
>
>
>
>
>
>
>
>
>







100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
  r = sqliteRandomByte();
  for(i=1; i<4; i++){
    r = (r<<8) + sqliteRandomByte();
  }
  return r;
}

/*
** Return a random 16-bit unsigned integer.  The integer is generated by
** making 2 calls to sqliteRandomByte().
*/
int sqliteRandomShort(void){
  int r;
  r = sqliteRandomByte();
  r = (r<<8) + sqliteRandomByte();
  return r;
}

/*
** Generate a random filename with the given prefix.  The new filename
** is written into zBuf[].  The calling function must insure that
** zBuf[] is big enough to hold the prefix plus 20 or so extra
** characters.
**
Changes to src/select.c.
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*************************************************************************
** This file contains C code routines that are called by the parser
** to handle SELECT statements.
**
** $Id: select.c,v 1.35 2001/09/13 21:53:10 drh Exp $
*/
#include "sqliteInt.h"

/*
** Allocate a new Select structure and return a pointer to that
** structure.
*/







|







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 SELECT statements.
**
** $Id: select.c,v 1.36 2001/09/14 03:24:25 drh Exp $
*/
#include "sqliteInt.h"

/*
** Allocate a new Select structure and return a pointer to that
** structure.
*/
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
  }else 

  /* Construct a record from the query result, but instead of
  ** saving that record, use it as a key to delete elements from
  ** the temporary table iParm.
  */
  if( eDest==SRT_Except ){
    sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0, 0, 0);
    sqliteVdbeAddOp(v, OP_MoveTo, iParm, 0, 0, 0);
    sqliteVdbeAddOp(v, OP_Delete, iParm, 0, 0, 0);
  }else 

  /* If we are creating a set for an "expr IN (SELECT ...)" construct,
  ** then there should be a single item on the stack.  Write this
  ** item into the set table with bogus data.
  */







|
|







177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
  }else 

  /* Construct a record from the query result, but instead of
  ** saving that record, use it as a key to delete elements from
  ** the temporary table iParm.
  */
  if( eDest==SRT_Except ){
    int addr = sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0, 0, 0);
    sqliteVdbeAddOp(v, OP_NotFound, iParm, addr+3, 0, 0);
    sqliteVdbeAddOp(v, OP_Delete, iParm, 0, 0, 0);
  }else 

  /* If we are creating a set for an "expr IN (SELECT ...)" construct,
  ** then there should be a single item on the stack.  Write this
  ** item into the set table with bogus data.
  */
Changes to src/tokenize.c.
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
*************************************************************************
** An tokenizer for SQL
**
** This file contains C code that splits an SQL input string up into
** individual tokens and sends those tokens one-by-one over to the
** parser for analysis.
**
** $Id: tokenize.c,v 1.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







|







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.20 2001/09/14 03:24:25 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include <stdlib.h>

/*
** All the keywords of the SQL language are stored as in a hash
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
        /* Various debugging modes can be turned on and off using
        ** special SQL comments.  Check for the special comments
        ** here and take approriate action if found.
        */
#ifndef NDEBUG
        char *z = pParse->sLastToken.z;
        if( sqliteStrNICmp(z,"--parser-trace-on--",19)==0 ){
          trace = stderr;
          sqliteParserTrace(trace, "parser: ");
        }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 ){







|







350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
        /* Various debugging modes can be turned on and off using
        ** special SQL comments.  Check for the special comments
        ** here and take approriate action if found.
        */
#ifndef NDEBUG
        char *z = pParse->sLastToken.z;
        if( sqliteStrNICmp(z,"--parser-trace-on--",19)==0 ){
          trace = stdout;
          sqliteParserTrace(trace, "parser: ");
        }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 ){
Changes to src/vdbe.c.
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
** inplicit conversion from one type to the other occurs as necessary.
** 
** Most of the code in this file is taken up by the sqliteVdbeExec()
** function which does the work of interpreting a VDBE program.
** But other routines are also provided to help in building up
** a program instruction by instruction.
**
** $Id: vdbe.c,v 1.64 2001/09/13 21:53:10 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include <unistd.h>

/*
** SQL is translated into a sequence of instructions to be







|







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.65 2001/09/14 03:24:25 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include <unistd.h>

/*
** SQL is translated into a sequence of instructions to be
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
  zStack = p->zStack;
  aStack = p->aStack;
  p->tos = -1;

  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];








|







1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
  zStack = p->zStack;
  aStack = p->aStack;
  p->tos = -1;

  rc = SQLITE_OK;
#ifdef MEMORY_DEBUG
  if( access("vdbe_trace",0)==0 ){
    p->trace = stdout;
  }
#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];

1081
1082
1083
1084
1085
1086
1087

1088
1089
1090
1091
1092
1093
1094
    /* Only allow tracing if NDEBUG is not defined.
    */
#ifndef NDEBUG
    if( p->trace ){
      fprintf(p->trace,"%4d %-12s %4d %4d %s\n",
        pc, zOpName[pOp->opcode], pOp->p1, pOp->p2,
           pOp->p3 ? pOp->p3 : "");

    }
#endif

    switch( pOp->opcode ){

/*****************************************************************************
** What follows is a massive switch statement where each case implements a







>







1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
    /* Only allow tracing if NDEBUG is not defined.
    */
#ifndef NDEBUG
    if( p->trace ){
      fprintf(p->trace,"%4d %-12s %4d %4d %s\n",
        pc, zOpName[pOp->opcode], pOp->p1, pOp->p2,
           pOp->p3 ? pOp->p3 : "");
      fflush(p->trace);
    }
#endif

    switch( pOp->opcode ){

/*****************************************************************************
** What follows is a massive switch statement where each case implements a
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
  break;
}

/* Opcode: Distinct P1 P2 *
**
** Use the top of the stack as a key.  If a record with that key
** does not exist in file P1, then jump to P2.  If the record
** does already exist, then fall thru.  The record is not retrieved.
** The key is not popped from the stack.
**
** This operation is similar to NotFound except that this operation
** does not pop the key from the stack.
*/
/* Opcode: Found P1 P2 *
**
** Use the top of the stack as a key.  If a record with that key
** does exist in file P1, then jump to P2.  If the record
** does not exist, then fall thru.  The record is not retrieved.
** The key is popped from the stack.
*/
/* Opcode: NotFound P1 P2 *
**
** Use the top of the stack as a key.  If a record with that key
** does not exist in file P1, then jump to P2.  If the record
** does exist, then fall thru.  The record is not retrieved.
** The key is popped from the stack.
**
** The difference between this operation and Distinct is that
** Distinct does not pop the key from the stack.
*/
case OP_Distinct:
case OP_NotFound:
case OP_Found: {







|
|








|
|





|
|







2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
  break;
}

/* Opcode: Distinct P1 P2 *
**
** Use the top of the stack as a key.  If a record with that key
** does not exist in file P1, then jump to P2.  If the record
** does already exist, then fall thru.  The cursor is left pointing
** at the record if it exists. The key is not popped from the stack.
**
** This operation is similar to NotFound except that this operation
** does not pop the key from the stack.
*/
/* Opcode: Found P1 P2 *
**
** Use the top of the stack as a key.  If a record with that key
** does exist in file P1, then jump to P2.  If the record
** does not exist, then fall thru.  The cursor is left pointing
** to the record if it exists.  The key is popped from the stack.
*/
/* Opcode: NotFound P1 P2 *
**
** Use the top of the stack as a key.  If a record with that key
** does not exist in file P1, then jump to P2.  If the record
** does exist, then fall thru.  The cursor is left pointing to the
** record if it exists.  The key is popped from the stack.
**
** The difference between this operation and Distinct is that
** Distinct does not pop the key from the stack.
*/
case OP_Distinct:
case OP_NotFound:
case OP_Found: {
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212

2213



2214
2215
2216
2217
2218
2219
2220
** Get a new integer record number used as the key to a table.
** The record number is not previous used by the database file
** associated with cursor P1.  The new record number pushed 
** onto the stack.
*/
case OP_NewRecno: {
  int i = pOp->p1;
  int v;
  if( VERIFY( i<0 || i>=p->nCursor || ) p->aCsr[i].pCursor==0 ){
    v = 0;
  }else{
    int res, rx, cnt;
    cnt = 0;
    do{

      v = sqliteRandomInteger();



      rx = sqliteBtreeMoveto(p->aCsr[i].pCursor, &v, sizeof(v), &res);
      cnt++;
    }while( cnt<10 && rx==SQLITE_OK && res==0 );
  }
  VERIFY( NeedStack(p, p->tos+1); )
  p->tos++;
  aStack[p->tos].i = v;







|






>
|
>
>
>







2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
** Get a new integer record number used as the key to a table.
** The record number is not previous used by the database file
** associated with cursor P1.  The new record number pushed 
** onto the stack.
*/
case OP_NewRecno: {
  int i = pOp->p1;
  static int v = 0;
  if( VERIFY( i<0 || i>=p->nCursor || ) p->aCsr[i].pCursor==0 ){
    v = 0;
  }else{
    int res, rx, cnt;
    cnt = 0;
    do{
      if( v==0 || cnt>5 ){
        v = sqliteRandomInteger();
      }else{
        v += sqliteRandomByte() + 1;
      }
      rx = sqliteBtreeMoveto(p->aCsr[i].pCursor, &v, sizeof(v), &res);
      cnt++;
    }while( cnt<10 && rx==SQLITE_OK && res==0 );
  }
  VERIFY( NeedStack(p, p->tos+1); )
  p->tos++;
  aStack[p->tos].i = v;
Changes to test/insert2.test.
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
#   http://www.hwaci.com/drh/
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the INSERT statement that takes is
# result from a SELECT.
#
# $Id: insert2.test,v 1.2 2000/06/07 15:11:27 drh Exp $

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

# Create some tables with data that we can select against
#
do_test insert2-1.0 {
  execsql {CREATE TABLE d1(n int, log int);}
  for {set i 1} {$i<=20} {incr i} {
    for {set j 0} {pow(2,$j)<$i} {incr j} {}
    execsql "INSERT INTO d1 VALUES($i,$j)"
  }
  execsql {SELECT * FROM d1 ORDER BY n}
} {1 0 2 1 3 2 4 2 5 3 6 3 7 3 8 3 9 4 10 4 11 4 12 4 13 4 14 4 15 4 16 4 17 5 18 5 19 5 20 5}

# Insert into a new table from the old one.
#
do_test insert2-1.1 {
  execsql {
    CREATE TABLE t1(log int, cnt int);

    INSERT INTO t1 SELECT log, count(*) FROM d1 GROUP BY log;
  }
  execsql {SELECT * FROM t1 ORDER BY log}
} {0 1 1 1 2 2 3 4 4 8 5 4}

do_test insert2-1.2 {
  catch {execsql {DROP TABLE t1}}
  execsql {
    CREATE TABLE t1(log int, cnt int);
    INSERT INTO t1 
       SELECT log, count(*) FROM d1 GROUP BY log
       EXCEPT SELECT n-1,log FROM d1;







|




















>




>







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
#   http://www.hwaci.com/drh/
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the INSERT statement that takes is
# result from a SELECT.
#
# $Id: insert2.test,v 1.3 2001/09/14 03:24:25 drh Exp $

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

# Create some tables with data that we can select against
#
do_test insert2-1.0 {
  execsql {CREATE TABLE d1(n int, log int);}
  for {set i 1} {$i<=20} {incr i} {
    for {set j 0} {pow(2,$j)<$i} {incr j} {}
    execsql "INSERT INTO d1 VALUES($i,$j)"
  }
  execsql {SELECT * FROM d1 ORDER BY n}
} {1 0 2 1 3 2 4 2 5 3 6 3 7 3 8 3 9 4 10 4 11 4 12 4 13 4 14 4 15 4 16 4 17 5 18 5 19 5 20 5}

# Insert into a new table from the old one.
#
do_test insert2-1.1 {
  execsql {
    CREATE TABLE t1(log int, cnt int);
---vdbe-trace-on--
    INSERT INTO t1 SELECT log, count(*) FROM d1 GROUP BY log;
  }
  execsql {SELECT * FROM t1 ORDER BY log}
} {0 1 1 1 2 2 3 4 4 8 5 4}

do_test insert2-1.2 {
  catch {execsql {DROP TABLE t1}}
  execsql {
    CREATE TABLE t1(log int, cnt int);
    INSERT INTO t1 
       SELECT log, count(*) FROM d1 GROUP BY log
       EXCEPT SELECT n-1,log FROM d1;
Changes to test/lock.test.
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#   drh@hwaci.com
#   http://www.hwaci.com/drh/
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is database locks.
#
# $Id: lock.test,v 1.8 2001/04/03 16:53:22 drh Exp $

if {$dbprefix=="gdbm:" && $::tcl_platform(platform)!="windows"} {

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

# Create a largish table
#
do_test lock-1.0 {







|

|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#   drh@hwaci.com
#   http://www.hwaci.com/drh/
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is database locks.
#
# $Id: lock.test,v 1.9 2001/09/14 03:24:25 drh Exp $

if {0} {

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

# Create a largish table
#
do_test lock-1.0 {
Changes to test/main.test.
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#   drh@hwaci.com
#   http://www.hwaci.com/drh/
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is exercising the code in main.c.
#
# $Id: main.test,v 1.6 2001/04/04 11:48:58 drh Exp $

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

# Tests of the sqlite_complete() function.
#
do_test main-1.1 {







|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#   drh@hwaci.com
#   http://www.hwaci.com/drh/
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is exercising the code in main.c.
#
# $Id: main.test,v 1.7 2001/09/14 03:24:25 drh Exp $

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

# Tests of the sqlite_complete() function.
#
do_test main-1.1 {
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
do_test main-1.14 {
  db complete {SELECT a-b FROM t1; }
} {1}
do_test main-1.15 {
  db complete {SELECT a-b FROM t1 }
} {0}

# Try to open a database with a corrupt master file.
#
do_test main-2.0 {
  catch {db close}
  foreach f [glob -nocomplain testdb/*] {file delete -force $f}
  file delete -force testdb
  file mkdir testdb
  set fd [open testdb/sqlite_master.tbl w]
  puts $fd hi!
  close $fd
  set v [catch {sqlite db testdb} msg]
  lappend v $msg
} {0 {}}

# Here are some tests for tokenize.c.  
#
do_test main-3.1 {
  catch {db close}







|



<
|
<
|


|







79
80
81
82
83
84
85
86
87
88
89

90

91
92
93
94
95
96
97
98
99
100
101
do_test main-1.14 {
  db complete {SELECT a-b FROM t1; }
} {1}
do_test main-1.15 {
  db complete {SELECT a-b FROM t1 }
} {0}

# Try to open a database with a corrupt database file.
#
do_test main-2.0 {
  catch {db close}

  file delete -force test.db

  set fd [open test.db w]
  puts $fd hi!
  close $fd
  set v [catch {sqlite db test.db} msg]
  lappend v $msg
} {0 {}}

# Here are some tests for tokenize.c.  
#
do_test main-3.1 {
  catch {db close}
Changes to test/pager.test.
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#   drh@hwaci.com
#   http://www.hwaci.com/drh/
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is page cache subsystem.
#
# $Id: pager.test,v 1.8 2001/08/20 00:33:58 drh Exp $


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

if {$dbprefix!="memory:" && [info commands pager_open]!=""} {

# Basic sanity check.  Open and close a pager.
#
do_test pager-1.0 {
  catch {file delete -force ptf1.db}
  catch {file delete -force ptf1.db-journal}
  set v [catch {







|





|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#   drh@hwaci.com
#   http://www.hwaci.com/drh/
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is page cache subsystem.
#
# $Id: pager.test,v 1.9 2001/09/14 03:24:25 drh Exp $


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

if {[info commands pager_open]!=""} {

# Basic sanity check.  Open and close a pager.
#
do_test pager-1.0 {
  catch {file delete -force ptf1.db}
  catch {file delete -force ptf1.db-journal}
  set v [catch {
Changes to test/select2.test.
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#   drh@hwaci.com
#   http://www.hwaci.com/drh/
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the SELECT statement.
#
# $Id: select2.test,v 1.12 2001/09/13 21:53:10 drh Exp $

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

# Create a table with some data
#
execsql {CREATE TABLE tbl1(f1 int, f2 int)}







|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#   drh@hwaci.com
#   http://www.hwaci.com/drh/
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the SELECT statement.
#
# $Id: select2.test,v 1.13 2001/09/14 03:24:25 drh Exp $

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

# Create a table with some data
#
execsql {CREATE TABLE tbl1(f1 int, f2 int)}
74
75
76
77
78
79
80

81
82
83
84
85
86
87
do_test select2-2.0 {
  execsql {CREATE TABLE tbl2(f1 int, f2 int, f3 int)}
  set f [open ./testdata1.txt w]
  for {set i 1} {$i<=30000} {incr i} {
    puts $f "$i\t[expr {$i*2}]\t[expr {$i*3}]"
  }
  close $f

  execsql {COPY tbl2 FROM './testdata1.txt'}
  file delete -force ./testdata1.txt
} {}

do_test select2-2.1 {
  execsql {SELECT count(*) FROM tbl2}
} {30000}







>







74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
do_test select2-2.0 {
  execsql {CREATE TABLE tbl2(f1 int, f2 int, f3 int)}
  set f [open ./testdata1.txt w]
  for {set i 1} {$i<=30000} {incr i} {
    puts $f "$i\t[expr {$i*2}]\t[expr {$i*3}]"
  }
  close $f
  # execsql {--vdbe-trace-on--}
  execsql {COPY tbl2 FROM './testdata1.txt'}
  file delete -force ./testdata1.txt
} {}

do_test select2-2.1 {
  execsql {SELECT count(*) FROM tbl2}
} {30000}
Changes to test/table.test.
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#   drh@hwaci.com
#   http://www.hwaci.com/drh/
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the CREATE TABLE statement.
#
# $Id: table.test,v 1.10 2001/09/13 21:53:10 drh Exp $

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

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







|







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

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

# Create a basic table and verify it is added to sqlite_master
#
do_test table-1.1 {
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
} {test1 test1 table}

# Close and reopen the database.  Verify that everything is
# still the same.
#
do_test table-1.4 {
  db close
  sqlite db testdb
  execsql {SELECT name, tbl_name, type from sqlite_master WHERE type!='meta'}
} {test1 test1 table}

# Drop the database and make sure it disappears.
#
do_test table-1.5 {
  execsql {DROP TABLE test1}
  execsql {SELECT * FROM sqlite_master WHERE type!='meta'}
} {}

# Verify that the file associated with the database is gone.
#
do_test table-1.5 {
  lsort [glob -nocomplain testdb/*.tbl]
} {testdb/sqlite_master.tbl}

# Close and reopen the database.  Verify that the table is
# still gone.
#
do_test table-1.6 {
  db close
  sqlite db testdb
  execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
} {}

# Repeat the above steps, but this time quote the table name.
#
do_test table-1.10 {
  execsql {CREATE TABLE "create" (f1 int)}







|










<
<
<
<
<
<





|







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
} {test1 test1 table}

# Close and reopen the database.  Verify that everything is
# still the same.
#
do_test table-1.4 {
  db close
  sqlite db test.db
  execsql {SELECT name, tbl_name, type from sqlite_master WHERE type!='meta'}
} {test1 test1 table}

# Drop the database and make sure it disappears.
#
do_test table-1.5 {
  execsql {DROP TABLE test1}
  execsql {SELECT * FROM sqlite_master WHERE type!='meta'}
} {}







# Close and reopen the database.  Verify that the table is
# still gone.
#
do_test table-1.6 {
  db close
  sqlite db test.db
  execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
} {}

# Repeat the above steps, but this time quote the table name.
#
do_test table-1.10 {
  execsql {CREATE TABLE "create" (f1 int)}
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
} {1 {table test2 already exists}}
do_test table-2.1b {
  set v [catch {execsql {CREATE TABLE sqlite_master(two text)}} msg]
  lappend v $msg
} {1 {table sqlite_master already exists}}
do_test table-2.1c {
  db close
  sqlite db testdb
  set v [catch {execsql {CREATE TABLE sqlite_master(two text)}} msg]
  lappend v $msg
} {1 {table sqlite_master already exists}}
do_test table-2.1d {
  execsql {DROP TABLE test2; SELECT name FROM sqlite_master WHERE type!='meta'}
} {}

# Verify that we cannot make a table with the same name as an index
#
do_test table-2.2a {
  execsql {CREATE TABLE test2(one text); CREATE INDEX test3 ON test2(one)}
  set v [catch {execsql {CREATE TABLE test3(two text)}} msg]
  lappend v $msg
} {1 {there is already an index named test3}}
do_test table-2.2b {
  db close
  sqlite db testdb
  set v [catch {execsql {CREATE TABLE test3(two text)}} msg]
  lappend v $msg
} {1 {there is already an index named test3}}
do_test table-2.2c {



  execsql {DROP INDEX test3}
  set v [catch {execsql {CREATE TABLE test3(two text)}} msg]
  lappend v $msg
} {0 {}}
do_test table-2.2d {
  execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
} {test2 test3}
do_test table-2.2e {
  execsql {DROP TABLE test2; DROP TABLE test3}
  execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
} {}

# Create a table with many field names
#
set big_table \







|
















|




>
>
>




|


|







107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
} {1 {table test2 already exists}}
do_test table-2.1b {
  set v [catch {execsql {CREATE TABLE sqlite_master(two text)}} msg]
  lappend v $msg
} {1 {table sqlite_master already exists}}
do_test table-2.1c {
  db close
  sqlite db test.db
  set v [catch {execsql {CREATE TABLE sqlite_master(two text)}} msg]
  lappend v $msg
} {1 {table sqlite_master already exists}}
do_test table-2.1d {
  execsql {DROP TABLE test2; SELECT name FROM sqlite_master WHERE type!='meta'}
} {}

# Verify that we cannot make a table with the same name as an index
#
do_test table-2.2a {
  execsql {CREATE TABLE test2(one text); CREATE INDEX test3 ON test2(one)}
  set v [catch {execsql {CREATE TABLE test3(two text)}} msg]
  lappend v $msg
} {1 {there is already an index named test3}}
do_test table-2.2b {
  db close
  sqlite db test.db
  set v [catch {execsql {CREATE TABLE test3(two text)}} msg]
  lappend v $msg
} {1 {there is already an index named test3}}
do_test table-2.2c {
  execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
} {test2 test3}
do_test table-2.2d {
  execsql {DROP INDEX test3}
  set v [catch {execsql {CREATE TABLE test3(two text)}} msg]
  lappend v $msg
} {0 {}}
do_test table-2.2e {
  execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
} {test2 test3}
do_test table-2.2f {
  execsql {DROP TABLE test2; DROP TABLE test3}
  execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
} {}

# Create a table with many field names
#
set big_table \
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
} {1 {table biG already exists}}
do_test table-3.4 {
  set v [catch {execsql {CREATE TABLE bIg(xyz foo)}} msg]
  lappend v $msg
} {1 {table bIg already exists}}
do_test table-3.5 {
  db close
  sqlite db testdb
  set v [catch {execsql {CREATE TABLE Big(xyz foo)}} msg]
  lappend v $msg
} {1 {table Big already exists}}
do_test table-3.6 {
  execsql {DROP TABLE big}
  execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
} {}







|







187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
} {1 {table biG already exists}}
do_test table-3.4 {
  set v [catch {execsql {CREATE TABLE bIg(xyz foo)}} msg]
  lappend v $msg
} {1 {table bIg already exists}}
do_test table-3.5 {
  db close
  sqlite db test.db
  set v [catch {execsql {CREATE TABLE Big(xyz foo)}} msg]
  lappend v $msg
} {1 {table Big already exists}}
do_test table-3.6 {
  execsql {DROP TABLE big}
  execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
} {}
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
    append sql "last_field text)"
    execsql $sql
  }
  execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
} $r
do_test table-4.1b {
  db close
  sqlite db testdb
  execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
} $r

# Drop the even numbered tables
#
set r {}
for {set i 1} {$i<=100} {incr i 2} {
  lappend r test$i
}

do_test table-4.2 {
  for {set i 2} {$i<=100} {incr i 2} {
    set sql "DROP TABLE TEST$i"
    execsql $sql
  }
  execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
} $r


# Drop the odd number tables
#
do_test table-4.3 {
  for {set i 1} {$i<=100} {incr i 2} {
    set sql "DROP TABLE test$i"
    execsql $sql







|









>







>







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
    append sql "last_field text)"
    execsql $sql
  }
  execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
} $r
do_test table-4.1b {
  db close
  sqlite db test.db
  execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
} $r

# Drop the even numbered tables
#
set r {}
for {set i 1} {$i<=100} {incr i 2} {
  lappend r test$i
}
#execsql {--vdbe-trace-on--}
do_test table-4.2 {
  for {set i 2} {$i<=100} {incr i 2} {
    set sql "DROP TABLE TEST$i"
    execsql $sql
  }
  execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
} $r
#exit

# Drop the odd number tables
#
do_test table-4.3 {
  for {set i 1} {$i<=100} {incr i 2} {
    set sql "DROP TABLE test$i"
    execsql $sql
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
  execsql {CREATE TABLE test1(f1 int)}
  execsql {EXPLAIN DROP TABLE test1}
  execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
} {test1}

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

# Try using keywords as table names or column names.
# 
do_test table-7.1 {
  set v [catch {execsql {
    CREATE TABLE weird(
      desc text,







|
|
|
|
|







276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
  execsql {CREATE TABLE test1(f1 int)}
  execsql {EXPLAIN DROP TABLE test1}
  execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
} {test1}

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

# Try using keywords as table names or column names.
# 
do_test table-7.1 {
  set v [catch {execsql {
    CREATE TABLE weird(
      desc text,
Changes to test/trans.test.
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#   drh@hwaci.com
#   http://www.hwaci.com/drh/
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is database locks.
#
# $Id: trans.test,v 1.2 2001/04/12 23:21:59 drh Exp $


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

if {$dbprefix=="gdbm:" && $::tcl_platform(platform)!="windows"} {

# Create several tables to work with.
#
do_test trans-1.0 {
  execsql {
    CREATE TABLE one(a int PRIMARY KEY, b text);
    INSERT INTO one VALUES(1,'one');







|





|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#   drh@hwaci.com
#   http://www.hwaci.com/drh/
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is database locks.
#
# $Id: trans.test,v 1.3 2001/09/14 03:24:25 drh Exp $


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

if {0} {

# Create several tables to work with.
#
do_test trans-1.0 {
  execsql {
    CREATE TABLE one(a int PRIMARY KEY, b text);
    INSERT INTO one VALUES(1,'one');
Changes to test/vacuum.test.
19
20
21
22
23
24
25
26
27
28
29


30
31
32
33
34
35
36
#   drh@hwaci.com
#   http://www.hwaci.com/drh/
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the VACUUM statement.
#
# $Id: vacuum.test,v 1.4 2001/09/13 21:53:10 drh Exp $

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



# Try to vacuum a non-existant table.
#
do_test vacuum-1.1 {
  set v [catch {execsql {VACUUM dummy1}} msg]
  lappend v $msg
} {1 {no such table or index: dummy1}}







|



>
>







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#   drh@hwaci.com
#   http://www.hwaci.com/drh/
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the VACUUM statement.
#
# $Id: vacuum.test,v 1.5 2001/09/14 03:24:25 drh Exp $

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

if {0} {

# Try to vacuum a non-existant table.
#
do_test vacuum-1.1 {
  set v [catch {execsql {VACUUM dummy1}} msg]
  lappend v $msg
} {1 {no such table or index: dummy1}}
75
76
77
78
79
80
81


  set a2 [file mtime testdb/test2.tbl]
  set a3 [file mtime testdb/index1.tbl]
  expr {$a1>$b1 && $a2>$b2 && $a3>$b3}
} {1}
} ;# End if( platform!=windows )

finish_test









>
>
77
78
79
80
81
82
83
84
85
  set a2 [file mtime testdb/test2.tbl]
  set a3 [file mtime testdb/index1.tbl]
  expr {$a1>$b1 && $a2>$b2 && $a3>$b3}
} {1}
} ;# End if( platform!=windows )

finish_test

}