/ Check-in [d5233e07]
Login

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

Overview
Comment:Modifications and bugfixes so that the test suite passes with the TCL statement cache turned on. (CVS 2271)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: d5233e0747789dea04d35a8350b408321d23a64d
User & Date: danielk1977 2005-01-24 10:25:59
Context
2005-01-24
12:46
Use the cache with loading a large table in select2-2.0. (CVS 2272) check-in: bd65b180 user: drh tags: trunk
10:25
Modifications and bugfixes so that the test suite passes with the TCL statement cache turned on. (CVS 2271) check-in: d5233e07 user: danielk1977 tags: trunk
01:38
Flush the TCL statement cache before each lock_status pragma. (CVS 2270) check-in: 8beae3ff user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/attach.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
34
35
36
37
38
39
40

41
42
43
44
45
46
47
...
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
...
157
158
159
160
161
162
163

164
165
166
167
168
169
170
...
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to implement the ATTACH and DETACH commands.
**
** $Id: attach.c,v 1.30 2005/01/23 13:14:55 drh Exp $
*/
#include "sqliteInt.h"

/*
** This routine is called by the parser to process an ATTACH statement:
**
**     ATTACH DATABASE filename AS dbname
................................................................................
  int rc, i;
  char *zFile, *zName;
  sqlite3 *db;
  Vdbe *v;

  v = sqlite3GetVdbe(pParse);
  if( !v ) return;

  sqlite3VdbeAddOp(v, OP_Halt, 0, 0);
  if( pParse->explain ) return;
  db = pParse->db;
  if( db->nDb>=MAX_ATTACHED+2 ){
    sqlite3ErrorMsg(pParse, "too many attached databases - max %d", 
       MAX_ATTACHED);
    pParse->rc = SQLITE_ERROR;
................................................................................
    sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
    if( keyType ){
      sqliteFree(zKey);
    }
  }
#endif
  sqliteFree(zFile);
  sqlite3ExpirePreparedStatements(db);
  db->flags &= ~SQLITE_Initialized;
  if( pParse->nErr==0 && rc==SQLITE_OK ){
    rc = sqlite3ReadSchema(pParse);
  }
  if( rc ){
    int i = db->nDb - 1;
    assert( i>=2 );
................................................................................
  int i;
  sqlite3 *db;
  Vdbe *v;
  Db *pDb = 0;

  v = sqlite3GetVdbe(pParse);
  if( !v ) return;

  sqlite3VdbeAddOp(v, OP_Halt, 0, 0);
  if( pParse->explain ) return;
  db = pParse->db;
  for(i=0; i<db->nDb; i++){
    pDb = &db->aDb[i];
    if( pDb->pBt==0 || pDb->zName==0 ) continue;
    if( strlen(pDb->zName)!=pDbname->n ) continue;
................................................................................
  if( sqlite3AuthCheck(pParse,SQLITE_DETACH,db->aDb[i].zName,0,0)!=SQLITE_OK ){
    return;
  }
#endif /* SQLITE_OMIT_AUTHORIZATION */
  sqlite3BtreeClose(pDb->pBt);
  pDb->pBt = 0;
  sqlite3ResetInternalSchema(db, 0);
  sqlite3ExpirePreparedStatements(db);
}

/*
** Initialize a DbFixer structure.  This routine must be called prior
** to passing the structure to one of the sqliteFixAAAA() routines below.
**
** The return value indicates whether or not fixation is required.  TRUE







|







 







>







 







<







 







>







 







<







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
...
123
124
125
126
127
128
129

130
131
132
133
134
135
136
...
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
...
188
189
190
191
192
193
194

195
196
197
198
199
200
201
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to implement the ATTACH and DETACH commands.
**
** $Id: attach.c,v 1.31 2005/01/24 10:25:59 danielk1977 Exp $
*/
#include "sqliteInt.h"

/*
** This routine is called by the parser to process an ATTACH statement:
**
**     ATTACH DATABASE filename AS dbname
................................................................................
  int rc, i;
  char *zFile, *zName;
  sqlite3 *db;
  Vdbe *v;

  v = sqlite3GetVdbe(pParse);
  if( !v ) return;
  sqlite3VdbeAddOp(v, OP_Expire, 1, 0);
  sqlite3VdbeAddOp(v, OP_Halt, 0, 0);
  if( pParse->explain ) return;
  db = pParse->db;
  if( db->nDb>=MAX_ATTACHED+2 ){
    sqlite3ErrorMsg(pParse, "too many attached databases - max %d", 
       MAX_ATTACHED);
    pParse->rc = SQLITE_ERROR;
................................................................................
    sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
    if( keyType ){
      sqliteFree(zKey);
    }
  }
#endif
  sqliteFree(zFile);

  db->flags &= ~SQLITE_Initialized;
  if( pParse->nErr==0 && rc==SQLITE_OK ){
    rc = sqlite3ReadSchema(pParse);
  }
  if( rc ){
    int i = db->nDb - 1;
    assert( i>=2 );
................................................................................
  int i;
  sqlite3 *db;
  Vdbe *v;
  Db *pDb = 0;

  v = sqlite3GetVdbe(pParse);
  if( !v ) return;
  sqlite3VdbeAddOp(v, OP_Expire, 0, 0);
  sqlite3VdbeAddOp(v, OP_Halt, 0, 0);
  if( pParse->explain ) return;
  db = pParse->db;
  for(i=0; i<db->nDb; i++){
    pDb = &db->aDb[i];
    if( pDb->pBt==0 || pDb->zName==0 ) continue;
    if( strlen(pDb->zName)!=pDbname->n ) continue;
................................................................................
  if( sqlite3AuthCheck(pParse,SQLITE_DETACH,db->aDb[i].zName,0,0)!=SQLITE_OK ){
    return;
  }
#endif /* SQLITE_OMIT_AUTHORIZATION */
  sqlite3BtreeClose(pDb->pBt);
  pDb->pBt = 0;
  sqlite3ResetInternalSchema(db, 0);

}

/*
** Initialize a DbFixer structure.  This routine must be called prior
** to passing the structure to one of the sqliteFixAAAA() routines below.
**
** The return value indicates whether or not fixation is required.  TRUE

Changes to src/build.c.

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
...
756
757
758
759
760
761
762








763
764
765
766
767
768

769
770
771
772
773
774
775
....
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
....
1880
1881
1882
1883
1884
1885
1886
1887

1888
1889

1890
1891
1892
1893
1894
1895
1896
....
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
....
2399
2400
2401
2402
2403
2404
2405
2406

2407
2408
2409
2410
2411
2412

2413
2414
2415
2416
2417
2418
2419
**     CREATE INDEX
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**
** $Id: build.c,v 1.297 2005/01/21 11:55:27 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Initialize the pParse structure as needed.
................................................................................
    ** The record created does not contain anything yet.  It will be replaced
    ** by the real entry in code generated at sqlite3EndTable().
    **
    ** The rowid for the new entry is left on the top of the stack.
    ** The rowid value is needed by the code that sqlite3EndTable will
    ** generate.
    */








    sqlite3OpenMasterTable(v, iDb);
    sqlite3VdbeAddOp(v, OP_NewRecno, 0, 0);
    sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
    sqlite3VdbeAddOp(v, OP_String8, 0, 0);
    sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0);
    sqlite3VdbeAddOp(v, OP_Close, 0, 0);

  }

  /* Normal (non-error) return. */
  return;

  /* If an error occurs, we jump here */
begin_table_error:
................................................................................

    /* Create the rootpage for the new table and push it onto the stack.
    ** A view has no rootpage, so just push a zero onto the stack for
    ** views.  Initialize zType at the same time.
    */
    if( p->pSelect==0 ){
      /* A regular table */
      sqlite3VdbeAddOp(v, OP_CreateTable, p->iDb, 0);
      zType = "table";
      zType2 = "TABLE";
#ifndef SQLITE_OMIT_VIEW
    }else{
      /* A view */
      sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
      zType = "view";
      zType2 = "VIEW";
#endif
    }

    /* If this is a CREATE TABLE xx AS SELECT ..., execute the SELECT
    ** statement to populate the new table. The root-page number for the
................................................................................
    sqlite3NestedParse(pParse, 
        "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'",
        pDb->zName, SCHEMA_TABLE(iDb), pTab->zName);
    if( !isView ){
      destroyTable(pParse, pTab);
    }

    /* Remove the table entry from SQLite's internal schema

    */
    sqlite3VdbeOp3(v, OP_DropTable, iDb, 0, pTab->zName, 0);

  }
  sqliteViewResetAll(db, iDb);

exit_drop_table:
  sqlite3SrcListDelete(pName);
}

................................................................................
        goto exit_create_index;
      }
      if( (pTSameName = sqlite3FindTable(db, zName, 0))!=0 ){
        sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
        goto exit_create_index;
      }
    }
  }else if( pName==0 ){
    char zBuf[30];
    int n;
    Index *pLoop;
    for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){}
    sprintf(zBuf,"_%d",n);
    zName = 0;
    sqlite3SetString(&zName, "sqlite_autoindex_", pTab->zName, zBuf, (char*)0);
................................................................................
        pIndex->zName,
        pTab->zName,
        zStmt
    );
    sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
    sqliteFree(zStmt);

    /* Fill the index with data and reparse the schema

    */
    if( pTblName ){
      sqlite3RefillIndex(pParse, pIndex, iMem);
      sqlite3ChangeCookie(db, v, iDb);
      sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0,
         sqlite3MPrintf("name='%q'", pIndex->zName), P3_DYNAMIC);

    }
  }

  /* When adding an index to the list of indices for a table, make
  ** sure all indices labeled OE_Replace come after all those labeled
  ** OE_Ignore.  This is necessary for the correct operation of UPDATE
  ** and INSERT.







|







 







>
>
>
>
>
>
>
>






>







 







|





|







 







|
>


>







 







|







 







|
>






>







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
...
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
....
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
....
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
....
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
....
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
**     CREATE INDEX
**     DROP INDEX
**     creating ID lists
**     BEGIN TRANSACTION
**     COMMIT
**     ROLLBACK
**
** $Id: build.c,v 1.298 2005/01/24 10:25:59 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>

/*
** This routine is called when a new SQL statement is beginning to
** be parsed.  Initialize the pParse structure as needed.
................................................................................
    ** The record created does not contain anything yet.  It will be replaced
    ** by the real entry in code generated at sqlite3EndTable().
    **
    ** The rowid for the new entry is left on the top of the stack.
    ** The rowid value is needed by the code that sqlite3EndTable will
    ** generate.
    */
#ifndef SQLITE_OMIT_VIEW
    if( isView ){
      sqlite3VdbeAddOp(v, OP_Integer, 0, 0);
    }else
#endif
    {
      sqlite3VdbeAddOp(v, OP_CreateTable, iDb, 0);
    }
    sqlite3OpenMasterTable(v, iDb);
    sqlite3VdbeAddOp(v, OP_NewRecno, 0, 0);
    sqlite3VdbeAddOp(v, OP_Dup, 0, 0);
    sqlite3VdbeAddOp(v, OP_String8, 0, 0);
    sqlite3VdbeAddOp(v, OP_PutIntKey, 0, 0);
    sqlite3VdbeAddOp(v, OP_Close, 0, 0);
    sqlite3VdbeAddOp(v, OP_Pull, 1, 0);
  }

  /* Normal (non-error) return. */
  return;

  /* If an error occurs, we jump here */
begin_table_error:
................................................................................

    /* Create the rootpage for the new table and push it onto the stack.
    ** A view has no rootpage, so just push a zero onto the stack for
    ** views.  Initialize zType at the same time.
    */
    if( p->pSelect==0 ){
      /* A regular table */
      /* sqlite3VdbeAddOp(v, OP_CreateTable, p->iDb, 0); */
      zType = "table";
      zType2 = "TABLE";
#ifndef SQLITE_OMIT_VIEW
    }else{
      /* A view */
    /*  sqlite3VdbeAddOp(v, OP_Integer, 0, 0); */
      zType = "view";
      zType2 = "VIEW";
#endif
    }

    /* If this is a CREATE TABLE xx AS SELECT ..., execute the SELECT
    ** statement to populate the new table. The root-page number for the
................................................................................
    sqlite3NestedParse(pParse, 
        "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'",
        pDb->zName, SCHEMA_TABLE(iDb), pTab->zName);
    if( !isView ){
      destroyTable(pParse, pTab);
    }

    /* Remove the table entry from SQLite's internal schema and modify
    ** the schema cookie.
    */
    sqlite3VdbeOp3(v, OP_DropTable, iDb, 0, pTab->zName, 0);
    sqlite3ChangeCookie(db, v, iDb);
  }
  sqliteViewResetAll(db, iDb);

exit_drop_table:
  sqlite3SrcListDelete(pName);
}

................................................................................
        goto exit_create_index;
      }
      if( (pTSameName = sqlite3FindTable(db, zName, 0))!=0 ){
        sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
        goto exit_create_index;
      }
    }
  }else{
    char zBuf[30];
    int n;
    Index *pLoop;
    for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){}
    sprintf(zBuf,"_%d",n);
    zName = 0;
    sqlite3SetString(&zName, "sqlite_autoindex_", pTab->zName, zBuf, (char*)0);
................................................................................
        pIndex->zName,
        pTab->zName,
        zStmt
    );
    sqlite3VdbeAddOp(v, OP_Pop, 1, 0);
    sqliteFree(zStmt);

    /* Fill the index with data and reparse the schema. Code an OP_Expire
    ** to invalidate all pre-compiled statements.
    */
    if( pTblName ){
      sqlite3RefillIndex(pParse, pIndex, iMem);
      sqlite3ChangeCookie(db, v, iDb);
      sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0,
         sqlite3MPrintf("name='%q'", pIndex->zName), P3_DYNAMIC);
      sqlite3VdbeAddOp(v, OP_Expire, 0, 0);
    }
  }

  /* When adding an index to the list of indices for a table, make
  ** sure all indices labeled OE_Replace come after all those labeled
  ** OE_Ignore.  This is necessary for the correct operation of UPDATE
  ** and INSERT.

Changes to src/main.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
....
1283
1284
1285
1286
1287
1288
1289








1290
1291
1292
1293
1294
1295
1296
**
*************************************************************************
** 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.273 2005/01/21 08:13:15 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** The following constant value is used by the SQLITE_BIGENDIAN and
................................................................................
  if( enc!=SQLITE_UTF8 && enc!=SQLITE_UTF16LE && enc!=SQLITE_UTF16BE ){
    sqlite3Error(db, SQLITE_ERROR, 
        "Param 3 to sqlite3_create_collation() must be one of "
        "SQLITE_UTF8, SQLITE_UTF16, SQLITE_UTF16LE or SQLITE_UTF16BE"
    );
    return SQLITE_ERROR;
  }








  pColl = sqlite3FindCollSeq(db, (u8)enc, zName, strlen(zName), 1);
  if( 0==pColl ){
   rc = SQLITE_NOMEM;
  }else{
    pColl->xCmp = xCompare;
    pColl->pUser = pCtx;
    pColl->enc = enc;







|







 







>
>
>
>
>
>
>
>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
....
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
**
*************************************************************************
** 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.274 2005/01/24 10:25:59 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** The following constant value is used by the SQLITE_BIGENDIAN and
................................................................................
  if( enc!=SQLITE_UTF8 && enc!=SQLITE_UTF16LE && enc!=SQLITE_UTF16BE ){
    sqlite3Error(db, SQLITE_ERROR, 
        "Param 3 to sqlite3_create_collation() must be one of "
        "SQLITE_UTF8, SQLITE_UTF16, SQLITE_UTF16LE or SQLITE_UTF16BE"
    );
    return SQLITE_ERROR;
  }

  /* If removing a collation sequence, then set the expired flag for
  ** all precompiled statements.
  */
  if( !xCompare ){
    sqlite3ExpirePreparedStatements(db);
  }

  pColl = sqlite3FindCollSeq(db, (u8)enc, zName, strlen(zName), 1);
  if( 0==pColl ){
   rc = SQLITE_NOMEM;
  }else{
    pColl->xCmp = xCompare;
    pColl->pUser = pCtx;
    pColl->enc = enc;

Changes to src/pragma.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
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
...
892
893
894
895
896
897
898








899
900
901
902
903
904
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.85 2005/01/22 03:03:54 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/* Ignore this whole file if pragmas are disabled
*/
................................................................................
  };
  int i;
  const struct sPragmaType *p;
  for(i=0, p=aPragma; i<sizeof(aPragma)/sizeof(aPragma[0]); i++, p++){
    if( sqlite3StrICmp(zLeft, p->zName)==0 ){
      sqlite3 *db = pParse->db;
      Vdbe *v;
      if( zRight==0 ){
        v = sqlite3GetVdbe(pParse);
        if( v ){

          returnSingleInt(pParse, p->zName, (db->flags & p->mask)!=0 );
        }
      }else{
        if( getBoolean(zRight) ){
          db->flags |= p->mask;
        }else{
          db->flags &= ~p->mask;
        }

        sqlite3ExpirePreparedStatements(db);



      }
      return 1;
    }
  }
  return 0;
}

................................................................................
      }
      sqlite3VdbeAddOp(v, OP_Callback, 2, 0);
    }
  }else
#endif

  {}








pragma_out:
  sqliteFree(zLeft);
  sqliteFree(zRight);
}

#endif /* SQLITE_OMIT_PRAGMA */







|







 







<
|
|
>

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







 







>
>
>
>
>
>
>
>






7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
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
...
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code used to implement the PRAGMA command.
**
** $Id: pragma.c,v 1.86 2005/01/24 10:25:59 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/* Ignore this whole file if pragmas are disabled
*/
................................................................................
  };
  int i;
  const struct sPragmaType *p;
  for(i=0, p=aPragma; i<sizeof(aPragma)/sizeof(aPragma[0]); i++, p++){
    if( sqlite3StrICmp(zLeft, p->zName)==0 ){
      sqlite3 *db = pParse->db;
      Vdbe *v;

      v = sqlite3GetVdbe(pParse);
      if( v ){
        if( zRight==0 ){
          returnSingleInt(pParse, p->zName, (db->flags & p->mask)!=0 );

        }else{
          if( getBoolean(zRight) ){
            db->flags |= p->mask;
          }else{
            db->flags &= ~p->mask;
          }
        }
        /* If one of these pragmas is executed, any prepared statements
        ** need to be recompiled.
        */
        sqlite3VdbeAddOp(v, OP_Expire, 0, 0);
      }
      return 1;
    }
  }
  return 0;
}

................................................................................
      }
      sqlite3VdbeAddOp(v, OP_Callback, 2, 0);
    }
  }else
#endif

  {}

  if( v ){
    /* Code an OP_Expire at the end of each PRAGMA program to cause
    ** the VDBE implementing the pragma to expire. Most (all?) pragmas
    ** are only valid for a single execution.
    */
    sqlite3VdbeAddOp(v, OP_Expire, 1, 0);
  }
pragma_out:
  sqliteFree(zLeft);
  sqliteFree(zRight);
}

#endif /* SQLITE_OMIT_PRAGMA */

Changes to src/tclsqlite.c.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** A TCL Interface to SQLite
**
** $Id: tclsqlite.c,v 1.116 2005/01/24 00:28:43 drh Exp $
*/
#ifndef NO_TCL     /* Omit this whole file if TCL is unavailable */

#include "sqliteInt.h"
#include "hash.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#define NUM_PREPARED_STMTS 0
#define MAX_PREPARED_STMTS 100

/*
** If TCL uses UTF-8 and SQLite is configured to use iso8859, then we
** have to do a translation when going between the two.  Set the 
** UTF_TRANSLATION_NEEDED macro to indicate that we need to do
** this translation.  







|










|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** A TCL Interface to SQLite
**
** $Id: tclsqlite.c,v 1.117 2005/01/24 10:25:59 danielk1977 Exp $
*/
#ifndef NO_TCL     /* Omit this whole file if TCL is unavailable */

#include "sqliteInt.h"
#include "hash.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#define NUM_PREPARED_STMTS 10
#define MAX_PREPARED_STMTS 100

/*
** If TCL uses UTF-8 and SQLite is configured to use iso8859, then we
** have to do a translation when going between the two.  Set the 
** UTF_TRANSLATION_NEEDED macro to indicate that we need to do
** this translation.  

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
4490
4491
4492
4493
4494
4495
4496


















4497
4498
4499
4500
4501
4502
4503
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.445 2005/01/21 08:13:15 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
  assert( pCursor!=0 );
  assert( pOp->p2>=0 && pOp->p2<2 );  
  pTos++;
  sqlite3VdbeMemShallowCopy(pTos, &pCursor->aPtr[i], MEM_Ephem);
  break;
}
#endif /* SQLITE_OMIT_CURSOR */





















/* An other opcode is illegal...
*/
default: {
  sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",pOp->opcode);







|







 







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







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.446 2005/01/24 10:25:59 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
................................................................................
  assert( pCursor!=0 );
  assert( pOp->p2>=0 && pOp->p2<2 );  
  pTos++;
  sqlite3VdbeMemShallowCopy(pTos, &pCursor->aPtr[i], MEM_Ephem);
  break;
}
#endif /* SQLITE_OMIT_CURSOR */

/* Opcode: Expire P1 * *
**
** Cause precompiled statements to become expired. An expired statement
** fails with an error code of SQLITE_SCHEMA if it is ever executed 
** (via sqlite3_step()).
** 
** If P1 is 0, then all SQL statements become expired. If P1 is non-zero,
** then only the currently executing statement is affected. 
*/
case OP_Expire: {
  if( !pOp->p1 ){
    sqlite3ExpirePreparedStatements(db);
  }else{
    p->expired = 1;
  }
  break;
}



/* An other opcode is illegal...
*/
default: {
  sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",pOp->opcode);

Changes to src/vdbeapi.c.

158
159
160
161
162
163
164






165
166
167
168
169
170
171
  int rc;

  if( p==0 || p->magic!=VDBE_MAGIC_RUN ){
    return SQLITE_MISUSE;
  }
  if( p->aborted ){
    return SQLITE_ABORT;






  }
  db = p->db;
  if( sqlite3SafetyOn(db) ){
    p->rc = SQLITE_MISUSE;
    return SQLITE_MISUSE;
  }
  if( p->pc<0 ){







>
>
>
>
>
>







158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
  int rc;

  if( p==0 || p->magic!=VDBE_MAGIC_RUN ){
    return SQLITE_MISUSE;
  }
  if( p->aborted ){
    return SQLITE_ABORT;
  }
  if( p->pc<=0 && p->expired ){
    if( p->rc==SQLITE_OK ){
      p->rc = SQLITE_SCHEMA;
    }
    return SQLITE_ERROR;
  }
  db = p->db;
  if( sqlite3SafetyOn(db) ){
    p->rc = SQLITE_MISUSE;
    return SQLITE_MISUSE;
  }
  if( p->pc<0 ){

Changes to src/vdbeaux.c.

1298
1299
1300
1301
1302
1303
1304






1305
1306
1307
1308
1309
1310
1311
      sqliteFree(p->zErrMsg);
      p->zErrMsg = 0;
    }else if( p->rc ){
      sqlite3Error(p->db, p->rc, 0);
    }else{
      sqlite3Error(p->db, SQLITE_OK, 0);
    }






  }

  /* Reclaim all memory used by the VDBE
  */
  Cleanup(p);

  /* Save profiling information from this VDBE run.







>
>
>
>
>
>







1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
      sqliteFree(p->zErrMsg);
      p->zErrMsg = 0;
    }else if( p->rc ){
      sqlite3Error(p->db, p->rc, 0);
    }else{
      sqlite3Error(p->db, SQLITE_OK, 0);
    }
  }else if( p->rc && p->expired ){
    /* The expired flag was set on the VDBE before the first call
    ** to sqlite3_step(). For consistency (since sqlite3_step() was
    ** called), set the database error in this case as well.
    */
    sqlite3Error(p->db, p->rc, 0);
  }

  /* Reclaim all memory used by the VDBE
  */
  Cleanup(p);

  /* Save profiling information from this VDBE run.

Changes to test/attach.test.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is testing the ATTACH and DETACH commands
# and related functionality.
#
# $Id: attach.test,v 1.36 2005/01/23 13:14:55 drh Exp $
#

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

for {set i 2} {$i<=15} {incr i} {
  file delete -force test$i.db
................................................................................
  }
} {}
ifcapable schema_pragmas {
do_test attach-1.20.2 {
  db_list db
} {0 main 2 db2 3 db3 4 db4 5 db6 6 db7 7 db8 8 db9 9 db10 10 db11}
} ;# ifcapable schema_pragmas
integrity_check attach-1.20.2
execsql {select * from sqlite_temp_master}
do_test attach-1.21 {
  catchsql {
    ATTACH 'test.db' as db12;
  }
} {0 {}}
do_test attach-1.22 {







|







 







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is testing the ATTACH and DETACH commands
# and related functionality.
#
# $Id: attach.test,v 1.37 2005/01/24 10:26:00 danielk1977 Exp $
#

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

for {set i 2} {$i<=15} {incr i} {
  file delete -force test$i.db
................................................................................
  }
} {}
ifcapable schema_pragmas {
do_test attach-1.20.2 {
  db_list db
} {0 main 2 db2 3 db3 4 db4 5 db6 6 db7 7 db8 8 db9 9 db10 10 db11}
} ;# ifcapable schema_pragmas
integrity_check attach-1.20.3
execsql {select * from sqlite_temp_master}
do_test attach-1.21 {
  catchsql {
    ATTACH 'test.db' as db12;
  }
} {0 {}}
do_test attach-1.22 {

Changes to test/auth.test.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26








27
28
29
30
31
32
33
....
2104
2105
2106
2107
2108
2109
2110



2111
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is testing the ATTACH and DETACH commands
# and related functionality.
#
# $Id: auth.test,v 1.25 2004/11/23 15:41:17 danielk1977 Exp $
#

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

# disable this test if the SQLITE_OMIT_AUTHORIZATION macro is
# defined during compilation.
if {[catch {db auth {}} msg]} {
  finish_test
  return
}









do_test auth-1.1.1 {
  db close
  set ::DB [sqlite3 db test.db]
  proc auth {code arg1 arg2 arg3 arg4} {
    if {$code=="SQLITE_INSERT" && $arg1=="sqlite_master"} {
      return SQLITE_DENY
................................................................................
  SQLITE_READ   t2     a  main v1 \
  SQLITE_READ   t2     b  main v1 \
  SQLITE_INSERT v1chng {} main r3 \
  SQLITE_READ   v1     x  main r3]

} ;# ifcapable view && trigger




finish_test







|











>
>
>
>
>
>
>
>







 







>
>
>

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
....
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is testing the ATTACH and DETACH commands
# and related functionality.
#
# $Id: auth.test,v 1.26 2005/01/24 10:26:00 danielk1977 Exp $
#

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

# disable this test if the SQLITE_OMIT_AUTHORIZATION macro is
# defined during compilation.
if {[catch {db auth {}} msg]} {
  finish_test
  return
}

rename proc proc_real
proc_real proc {name arguments script} {
  proc_real $name $arguments $script
  if {$name=="auth"} {
    db authorizer ::auth
  }
}

do_test auth-1.1.1 {
  db close
  set ::DB [sqlite3 db test.db]
  proc auth {code arg1 arg2 arg3 arg4} {
    if {$code=="SQLITE_INSERT" && $arg1=="sqlite_master"} {
      return SQLITE_DENY
................................................................................
  SQLITE_READ   t2     a  main v1 \
  SQLITE_READ   t2     b  main v1 \
  SQLITE_INSERT v1chng {} main r3 \
  SQLITE_READ   v1     x  main r3]

} ;# ifcapable view && trigger

rename proc {}
rename proc_real proc

finish_test

Changes to test/autovacuum.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
...
374
375
376
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
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
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the SELECT statement.
#
# $Id: autovacuum.test,v 1.15 2005/01/21 03:12:16 danielk1977 Exp $

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

# If this build of the library does not support auto-vacuum, omit this
# whole file.
ifcapable {!autovacuum} {
................................................................................
  }
} {}

do_test autovacuum-2.5.2 {
  execsql {
    SELECT name, rootpage FROM sqlite_master;
  }
} [list av1 4  sqlite_autoindex_av1_1 3 \
        av2 6  sqlite_autoindex_av2_1 5 av2_i1 7 av2_i2 8 \
        av3 10 sqlite_autoindex_av3_1 9 av3_i1 11 \
        av4 12 av4_i1 13 av4_i2 14 av4_i3 15 av4_i4 16 \
]

# The following 4 tests are SELECT queries that use the indices created.
# If the root-pages in the internal schema are not updated correctly when
# a table or indice is moved, these queries will fail. They are repeated
# after each table is dropped (i.e. as test cases 2.5.*.[1..4]).
................................................................................
# Step 2: Delete av3 (root-page 10). Move root-page of av4_i3 to page 10.
# Step 3: Delete sqlite_autoindex_av1_3 (root-page 9). Move av4_i2 to page 9.
do_test autovacuum-2.5.3 {
  execsql {
    DROP TABLE av3;
    SELECT name, rootpage FROM sqlite_master;
  }
} [list av1 4  sqlite_autoindex_av1_1 3 \
        av2 6  sqlite_autoindex_av2_1 5 av2_i1 7 av2_i2 8 \
        av4 12 av4_i1 13 av4_i2 9 av4_i3 10 av4_i4 11 \
]
do_test autovacuum-2.5.2.1 {
  execsql {
    SELECT * FROM av1 WHERE a = 'av1 a';
  }
} {{av1 a} {av1 b} {av1 c}}
do_test autovacuum-2.5.2.2 {
  execsql {
    SELECT * FROM av2 WHERE a = 'av2 a' AND b = 'av2 b' AND c = 'av2 c'
  }
} {{av2 a} {av2 b} {av2 c}}
do_test autovacuum-2.5.2.4 {
  execsql {
    SELECT * FROM av4 WHERE a = 'av4 a' AND b = 'av4 b' AND c = 'av4 c';
  }
} {{av4 a} {av4 b} {av4 c}}

# Drop table av1:
# Step 1: Delete av1 (root page 4). Root-page of av4_i1 fills the gap.
# Step 2: Delete sqlite_autoindex_av1_1 (root page 3). Move av4 to the gap.
do_test autovacuum-2.5.4 {
  execsql {
    DROP TABLE av1;
    SELECT name, rootpage FROM sqlite_master;
  }
} [list av2 6  sqlite_autoindex_av2_1 5 av2_i1 7 av2_i2 8 \
        av4 3 av4_i1 4 av4_i2 9 av4_i3 10 av4_i4 11 \
]
do_test autovacuum-2.5.2.2 {
  execsql {
    SELECT * FROM av2 WHERE a = 'av2 a' AND b = 'av2 b' AND c = 'av2 c'
  }
} {{av2 a} {av2 b} {av2 c}}
do_test autovacuum-2.5.2.4 {
  execsql {
    SELECT * FROM av4 WHERE a = 'av4 a' AND b = 'av4 b' AND c = 'av4 c';
  }
} {{av4 a} {av4 b} {av4 c}}

# Drop table av4:
# Step 1: Delete av4_i4.
# Step 2: Delete av4_i3.
# Step 3: Delete av4_i2.
# Step 4: Delete av4_i1. av2_i2 replaces it.
# Step 5: Delete av4. av2_i1 replaces it.
do_test autovacuum-2.5.4 {
  execsql {
    DROP TABLE av4;
    SELECT name, rootpage FROM sqlite_master;
  }
} [list av2 6 sqlite_autoindex_av2_1 5 av2_i1 3 av2_i2 4]
do_test autovacuum-2.5.2.2 {
  execsql {
    SELECT * FROM av2 WHERE a = 'av2 a' AND b = 'av2 b' AND c = 'av2 c'
  }
} {{av2 a} {av2 b} {av2 c}}

#--------------------------------------------------------------------------
# Test cases autovacuum-3.* test the operation of the "PRAGMA auto_vacuum"







|







 







|
|
|







 







|
|


|




|




|













|


|




|











|




|
|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
...
374
375
376
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
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
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the SELECT statement.
#
# $Id: autovacuum.test,v 1.16 2005/01/24 10:26:00 danielk1977 Exp $

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

# If this build of the library does not support auto-vacuum, omit this
# whole file.
ifcapable {!autovacuum} {
................................................................................
  }
} {}

do_test autovacuum-2.5.2 {
  execsql {
    SELECT name, rootpage FROM sqlite_master;
  }
} [list av1 3  sqlite_autoindex_av1_1 4 \
        av2 5  sqlite_autoindex_av2_1 6 av2_i1 7 av2_i2 8 \
        av3 9 sqlite_autoindex_av3_1 10 av3_i1 11 \
        av4 12 av4_i1 13 av4_i2 14 av4_i3 15 av4_i4 16 \
]

# The following 4 tests are SELECT queries that use the indices created.
# If the root-pages in the internal schema are not updated correctly when
# a table or indice is moved, these queries will fail. They are repeated
# after each table is dropped (i.e. as test cases 2.5.*.[1..4]).
................................................................................
# Step 2: Delete av3 (root-page 10). Move root-page of av4_i3 to page 10.
# Step 3: Delete sqlite_autoindex_av1_3 (root-page 9). Move av4_i2 to page 9.
do_test autovacuum-2.5.3 {
  execsql {
    DROP TABLE av3;
    SELECT name, rootpage FROM sqlite_master;
  }
} [list av1 3  sqlite_autoindex_av1_1 4 \
        av2 5  sqlite_autoindex_av2_1 6 av2_i1 7 av2_i2 8 \
        av4 12 av4_i1 13 av4_i2 9 av4_i3 10 av4_i4 11 \
]
do_test autovacuum-2.5.3.1 {
  execsql {
    SELECT * FROM av1 WHERE a = 'av1 a';
  }
} {{av1 a} {av1 b} {av1 c}}
do_test autovacuum-2.5.3.2 {
  execsql {
    SELECT * FROM av2 WHERE a = 'av2 a' AND b = 'av2 b' AND c = 'av2 c'
  }
} {{av2 a} {av2 b} {av2 c}}
do_test autovacuum-2.5.3.3 {
  execsql {
    SELECT * FROM av4 WHERE a = 'av4 a' AND b = 'av4 b' AND c = 'av4 c';
  }
} {{av4 a} {av4 b} {av4 c}}

# Drop table av1:
# Step 1: Delete av1 (root page 4). Root-page of av4_i1 fills the gap.
# Step 2: Delete sqlite_autoindex_av1_1 (root page 3). Move av4 to the gap.
do_test autovacuum-2.5.4 {
  execsql {
    DROP TABLE av1;
    SELECT name, rootpage FROM sqlite_master;
  }
} [list av2 5  sqlite_autoindex_av2_1 6 av2_i1 7 av2_i2 8 \
        av4 3 av4_i1 4 av4_i2 9 av4_i3 10 av4_i4 11 \
]
do_test autovacuum-2.5.4.2 {
  execsql {
    SELECT * FROM av2 WHERE a = 'av2 a' AND b = 'av2 b' AND c = 'av2 c'
  }
} {{av2 a} {av2 b} {av2 c}}
do_test autovacuum-2.5.4.4 {
  execsql {
    SELECT * FROM av4 WHERE a = 'av4 a' AND b = 'av4 b' AND c = 'av4 c';
  }
} {{av4 a} {av4 b} {av4 c}}

# Drop table av4:
# Step 1: Delete av4_i4.
# Step 2: Delete av4_i3.
# Step 3: Delete av4_i2.
# Step 4: Delete av4_i1. av2_i2 replaces it.
# Step 5: Delete av4. av2_i1 replaces it.
do_test autovacuum-2.5.5 {
  execsql {
    DROP TABLE av4;
    SELECT name, rootpage FROM sqlite_master;
  }
} [list av2 5 sqlite_autoindex_av2_1 6 av2_i1 3 av2_i2 4]
do_test autovacuum-2.5.5.2 {
  execsql {
    SELECT * FROM av2 WHERE a = 'av2 a' AND b = 'av2 b' AND c = 'av2 c'
  }
} {{av2 a} {av2 b} {av2 c}}

#--------------------------------------------------------------------------
# Test cases autovacuum-3.* test the operation of the "PRAGMA auto_vacuum"

Changes to test/capi3.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script testing the callback-free C/C++ API.
#
# $Id: capi3.test,v 1.28 2005/01/22 03:03:55 drh Exp $
#

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

# Return the UTF-16 representation of the supplied UTF-8 string $str.
# If $nt is true, append two 0x00 bytes as a nul terminator.
................................................................................
  sqlite3_column_count $STMT
} 3

check_header $STMT capi3-5.1 {a b c} {VARINT BLOB VARCHAR(16)}
do_test capi3-5.2 {
  sqlite3_step $STMT
} SQLITE_ROW
do_test capi3-5.2.1 {
  sqlite3_expired $STMT
} {0}
do_test capi3-5.2.2 {
  db auth {}
  sqlite3_expired $STMT
} {1}

check_header $STMT capi3-5.3 {a b c} {VARINT BLOB VARCHAR(16)}
check_data $STMT capi3-5.4 {INTEGER INTEGER TEXT} {1 2 3} {1.0 2.0 3.0} {1 2 3}

do_test capi3-5.5 {
  sqlite3_step $STMT
} SQLITE_ROW







|







 







<
<
<
<
<
<
<







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
426
427
428
429
430
431
432







433
434
435
436
437
438
439
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script testing the callback-free C/C++ API.
#
# $Id: capi3.test,v 1.29 2005/01/24 10:26:00 danielk1977 Exp $
#

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

# Return the UTF-16 representation of the supplied UTF-8 string $str.
# If $nt is true, append two 0x00 bytes as a nul terminator.
................................................................................
  sqlite3_column_count $STMT
} 3

check_header $STMT capi3-5.1 {a b c} {VARINT BLOB VARCHAR(16)}
do_test capi3-5.2 {
  sqlite3_step $STMT
} SQLITE_ROW








check_header $STMT capi3-5.3 {a b c} {VARINT BLOB VARCHAR(16)}
check_data $STMT capi3-5.4 {INTEGER INTEGER TEXT} {1 2 3} {1.0 2.0 3.0} {1 2 3}

do_test capi3-5.5 {
  sqlite3_step $STMT
} SQLITE_ROW

Changes to test/misuse.test.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
168
169
170
171
172
173
174



175
176
177
178
179
180
181
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for the SQLITE_MISUSE detection logic.
# This test file leaks memory and file descriptors.
#
# $Id: misuse.test,v 1.9 2005/01/16 09:06:34 danielk1977 Exp $

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

proc catchsql2 {sql} {
  set r [
    catch {
................................................................................
    db eval {SELECT * FROM t1} {} {
      set r [sqlite3_close $::DB]
    }
  } msg]
  lappend v $msg $r
} {0 {} SQLITE_BUSY}
do_test misuse-4.4 {



  sqlite3_close $::DB
  catchsql2 {SELECT * FROM t1}
} {1 {library routine called out of sequence}}
do_test misuse-4.5 {
  catchsql {
    SELECT * FROM t1
  }







|







 







>
>
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for the SQLITE_MISUSE detection logic.
# This test file leaks memory and file descriptors.
#
# $Id: misuse.test,v 1.10 2005/01/24 10:26:00 danielk1977 Exp $

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

proc catchsql2 {sql} {
  set r [
    catch {
................................................................................
    db eval {SELECT * FROM t1} {} {
      set r [sqlite3_close $::DB]
    }
  } msg]
  lappend v $msg $r
} {0 {} SQLITE_BUSY}
do_test misuse-4.4 {
  # Flush the TCL statement cache here, otherwise the sqlite3_close() will
  # fail because there are still un-finalized() VDBEs.
  db cache flush
  sqlite3_close $::DB
  catchsql2 {SELECT * FROM t1}
} {1 {library routine called out of sequence}}
do_test misuse-4.5 {
  catchsql {
    SELECT * FROM t1
  }

Added test/schema.test.











































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# 2004 Jun 27
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file tests the various conditions under which an SQLITE_SCHEMA
# error should be returned.
#
# $Id: schema.test,v 1.1 2005/01/24 10:26:00 danielk1977 Exp $

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

# schema-1.1: Test that if a table is dropped by one database connection, 
#             other database connections are aware of the schema change.
# schema-1.2: Test that if a view is dropped by one database connection,
#             other database connections are aware of the schema change.
#
do_test schema-1.1 {
  execsql {
    CREATE TABLE abc(a, b, c);
  }
  sqlite3 db2 test.db
  execsql {
    DROP TABLE abc;
  } db2
  catchsql {
    SELECT * FROM abc;
  }
} {1 {no such table: abc}}
do_test schema-1.2 {
  execsql {
    CREATE TABLE abc(a, b, c);
    CREATE VIEW abcview AS SELECT * FROM abc;
  }
  sqlite3 db2 test.db
  execsql {
    DROP VIEW abcview;
  } db2
  db2 close
  catchsql {
    SELECT * FROM abcview;
  }
} {1 {no such table: abcview}}

# Tests 2.1 to 2.4 check that prepared statements are invalidated when
# a collation sequence is deleted (but not when one is added).
#
do_test schema-2.1 {
  set sql {SELECT * FROM abc;}
  set ::STMT [sqlite3_prepare $::DB $sql -1 TAIL]
  add_test_collate $::DB 1 1 1
  sqlite3_step $::STMT
} {SQLITE_DONE}
do_test schema-2.2 {
  sqlite3_reset $::STMT
} {SQLITE_OK}
do_test schema-2.3 {
  add_test_collate $::DB 0 0 0 
  sqlite3_step $::STMT
} {SQLITE_ERROR}
do_test schema-2.4 {
  sqlite3_finalize $::STMT
} {SQLITE_SCHEMA}

# Tests 3.1 to 3.4 check that prepared statements are invalidated when
# a database is DETACHed (but not when one is ATTACHed).
#
do_test schema-3.1 {
  set sql {SELECT * FROM abc;}
  set ::STMT [sqlite3_prepare $::DB $sql -1 TAIL]
  execsql {
    ATTACH 'test2.db' AS aux;
  }
  sqlite3_step $::STMT
} {SQLITE_DONE}
do_test schema-3.2 {
  sqlite3_reset $::STMT
} {SQLITE_OK}
do_test schema-3.3 {
  execsql {
    DETACH aux;
  }
  sqlite3_step $::STMT
} {SQLITE_ERROR}
do_test schema-3.4 {
  sqlite3_finalize $::STMT
} {SQLITE_SCHEMA}


# Test that if a CREATE TABLE statement fails because there are other
# btree cursors open on the same database file it does not corrupt
# the sqlite_master table.
#
do_test schema-4.1 {
  execsql {
    INSERT INTO abc VALUES(1, 2, 3);
  }
  set sql {SELECT * FROM abc}
  set ::STMT [sqlite3_prepare $::DB $sql -1 TAIL]
  sqlite3_step $::STMT
} {SQLITE_ROW}
do_test schema-4.2 {
  catchsql {
    CREATE TABLE t2(a, b, c);
  }
} {1 {database table is locked}}
do_test schema-4.3 {
  sqlite3_finalize $::STMT
} {SQLITE_OK}
do_test schema-4.4 {
  sqlite3 db2 test.db
  execsql {
    SELECT * FROM abc
  } db2
} {1 2 3}
do_test schema-4.5 {
  db2 close
} {}

finish_test





Changes to test/table.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
570
571
572
573
574
575
576



577
578
579
580
581
582
583
...
650
651
652
653
654
655
656

#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the CREATE TABLE statement.
#
# $Id: table.test,v 1.37 2005/01/22 03:39:39 danielk1977 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 {
................................................................................
#
# Test that a table cannot be created or dropped while other virtual
# machines are active. This is required because otherwise when in 
# auto-vacuum mode the btree-layer may need to move the root-pages of 
# a table for which there is an open cursor.
#




# Try to create a table from within a callback:
unset -nocomplain result
do_test table-14.1 {
  set rc [
    catch {
      db eval {SELECT * FROM tablet8 LIMIT 1} {} {
        db eval {CREATE TABLE t9(a, b, c)}
................................................................................
  for {set i 0} {$i<2000} {incr i} {
    execsql "DROP TABLE tbl$i"
  }
  execsql {COMMIT}
} {}

finish_test








|







 







>
>
>







 







>
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
...
653
654
655
656
657
658
659
660
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the CREATE TABLE statement.
#
# $Id: table.test,v 1.38 2005/01/24 10:26:00 danielk1977 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 {
................................................................................
#
# Test that a table cannot be created or dropped while other virtual
# machines are active. This is required because otherwise when in 
# auto-vacuum mode the btree-layer may need to move the root-pages of 
# a table for which there is an open cursor.
#

# db eval {
#   pragma vdbe_trace = 0;
# }
# Try to create a table from within a callback:
unset -nocomplain result
do_test table-14.1 {
  set rc [
    catch {
      db eval {SELECT * FROM tablet8 LIMIT 1} {} {
        db eval {CREATE TABLE t9(a, b, c)}
................................................................................
  for {set i 0} {$i<2000} {incr i} {
    execsql "DROP TABLE tbl$i"
  }
  execsql {COMMIT}
} {}

finish_test

Changes to test/tester.tcl.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements some common TCL routines used for regression
# testing the SQLite library
#
# $Id: tester.tcl,v 1.46 2005/01/22 03:39:39 danielk1977 Exp $

# Make sure tclsqlite3 was compiled correctly.  Abort now with an
# error message if not.
#
if {[sqlite3 -tcl-uses-utf]} {
  if {"\u1234"=="u1234"} {
    puts stderr "***** BUILD PROBLEM *****"
................................................................................


# Create a test database
#
catch {db close}
file delete -force test.db
file delete -force test.db-journal
sqlite3 db ./test.db
if {[info exists ::SETUP_SQL]} {
  db eval $::SETUP_SQL
}

# Abort early if this script has been run before.
#
if {[info exists nTest]} return







|







 







|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements some common TCL routines used for regression
# testing the SQLite library
#
# $Id: tester.tcl,v 1.47 2005/01/24 10:26:00 danielk1977 Exp $

# Make sure tclsqlite3 was compiled correctly.  Abort now with an
# error message if not.
#
if {[sqlite3 -tcl-uses-utf]} {
  if {"\u1234"=="u1234"} {
    puts stderr "***** BUILD PROBLEM *****"
................................................................................


# Create a test database
#
catch {db close}
file delete -force test.db
file delete -force test.db-journal
set ::DB [sqlite3 db ./test.db]
if {[info exists ::SETUP_SQL]} {
  db eval $::SETUP_SQL
}

# Abort early if this script has been run before.
#
if {[info exists nTest]} return