]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add a case to permutations.test to run the veryquick test suite using sqlite3_prepare...
authordan <dan@noemail.net>
Mon, 27 Jun 2011 16:55:50 +0000 (16:55 +0000)
committerdan <dan@noemail.net>
Mon, 27 Jun 2011 16:55:50 +0000 (16:55 +0000)
FossilOrigin-Name: d9f7993bfa2ecb30c44455de538eb6f8a4a59087

manifest
manifest.uuid
src/tclsqlite.c
test/all.test
test/alter2.test
test/exists.test
test/permutations.test
test/temptable.test

index 1a8f207d3b334470544dffdf7d9398d9574e63e9..c7349038304efd3ea7fa09aed1a81cbd88c9508d 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Make\ssure\sall\snew\sstatements\sbegin\slife\sunexpired,\seven\sif\sthey\sregistered\nfunctions\sor\sdid\sother\sactions\sduring\spreparation\sthat\swould\shave\sexpired\nall\sstatements.\s\sFix\sfor\sticket\s[25ee81271091]
-D 2011-06-27T00:01:22.248
+C Add\sa\scase\sto\spermutations.test\sto\srun\sthe\sveryquick\stest\ssuite\susing\ssqlite3_prepare()\sinstead\sof\ssqlite3_prepare_v2().\sThis\shelps\sto\stest\sthe\sfix\sfor\sbug\s[25ee812710].
+D 2011-06-27T16:55:50.495
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in c1d7a7f4fd8da6b1815032efca950e3d5125407e
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -187,7 +187,7 @@ F src/sqliteInt.h 7b72f7c6929757c0678d94524dbc7e7e3d6dc398
 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
 F src/status.c 7ac64842c86cec2fc1a1d0e5c16d3beb8ad332bf
 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
-F src/tclsqlite.c 5db825be61708b1a2b3f8f6e185e9b753829acef
+F src/tclsqlite.c c355b33803fb756dc09297ec84d19604301fa622
 F src/test1.c 8eef932f1024f1076a8adb8a6f5d9c5267c9e969
 F src/test2.c 80d323d11e909cf0eb1b6fbb4ac22276483bcf31
 F src/test3.c 124ff9735fb6bb7d41de180d6bac90e7b1509432
@@ -254,9 +254,9 @@ F src/where.c 55403ce19c506be6a321c7f129aff693d6103db5
 F test/8_3_names.test b93687beebd17f6ebf812405a6833bae5d1f4199
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87
-F test/all.test 51756962d522e474338e9b2ebb26e7364d4aa125
+F test/all.test 52fc8dee494092031a556911d404ca30a749a30b
 F test/alter.test a3f570072b53d7c0fe463bab3f5affa8e113c487
-F test/alter2.test 75f731508f1bf27ba09a6075c66cd02216ba464b
+F test/alter2.test e0c09d630d650ea32333781a4ed3c45eb02c4289
 F test/alter3.test 8677e48d95536f7a6ed86a1a774744dadcc22b07
 F test/alter4.test 1e5dd6b951e9f65ca66422edff02e56df82dd403
 F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc
@@ -393,7 +393,7 @@ F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3
 F test/exclusive.test 53e1841b422e554cecf0160f937c473d6d0e3062
 F test/exclusive2.test 343d55130c12c67b8bf10407acec043a6c26c86b
 F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
-F test/exists.test 5e2d64b4eb5a9d08876599bdae2e1213d2d12e2a
+F test/exists.test 8f7b27b61c2fbe5822f0a1f899c715d14e416e30
 F test/expr.test 67c9fd6f8f829e239dc8b0f4a08a73c08b09196d
 F test/fallocate.test 43dc34b8c24be6baffadc3b4401ee15710ce83c6
 F test/filectrl.test 97003734290887566e01dded09dc9e99cb937e9e
@@ -615,7 +615,7 @@ F test/pageropt.test 8146bf448cf09e87bb1867c2217b921fb5857806
 F test/pagesize.test 76aa9f23ecb0741a4ed9d2e16c5fa82671f28efb
 F test/pcache.test 065aa286e722ab24f2e51792c1f093bf60656b16
 F test/pcache2.test 0d85f2ab6963aee28c671d4c71bec038c00a1d16
-F test/permutations.test 1e8892ebf1bd6e9e8036f4841c72a91bf72da74a
+F test/permutations.test aae89941ca0968b53633c97b5dd0d6f9f9899d27
 F test/pragma.test fdfc09067ea104a0c247a1a79d8093b56656f850
 F test/pragma2.test 5364893491b9231dd170e3459bfc2e2342658b47
 F test/printf.test 05970cde31b1a9f54bd75af60597be75a5c54fea
@@ -693,7 +693,7 @@ F test/table.test 04ba066432430657712d167ebf28080fe878d305
 F test/tableapi.test 2674633fa95d80da917571ebdd759a14d9819126
 F test/tclsqlite.test 8c154101e704170c2be10f137a5499ac2c6da8d3
 F test/tempdb.test 19d0f66e2e3eeffd68661a11c83ba5e6ace9128c
-F test/temptable.test f42121a0d29a62f00f93274464164177ab1cc24a
+F test/temptable.test 1a21a597055dcf6002b6f1ee867632dccd6e925c
 F test/temptrigger.test b0273db072ce5f37cf19140ceb1f0d524bbe9f05
 F test/tester.tcl 7d3d17914ca5397a82f801db733b81d4a82f50c3
 F test/thread001.test a3e6a7254d1cb057836cb3145b60c10bf5b7e60f
@@ -949,7 +949,7 @@ F tool/symbols.sh bc2a3709940d47c8ac8e0a1fdf17ec801f015a00
 F tool/tostr.awk 11760e1b94a5d3dcd42378f3cc18544c06cfa576
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
 F tool/warnings.sh 2ebae31e1eb352696f3c2f7706a34c084b28c262
-P c4db5b640638a211b096454ba90b58faf595392b
-R 1d2c6c9972e41fe17af0cc7482f056ad
-U drh
-Z 50eb339a1b9fd382164ccbf3dfada87e
+P faa38c8724d3eebad97197bfa44d11e75cfe6c69
+R ea65f158609dffa4f41c8ce1eb564414
+U dan
+Z 2df66e3ffb41532c6826925a7e3446a4
index 6f48ead0438bc929d8a9832727cbf0695c1e5664..4cd588aa865d08b584615505fc0a6858b9f833a3 100644 (file)
@@ -1 +1 @@
-faa38c8724d3eebad97197bfa44d11e75cfe6c69
\ No newline at end of file
+d9f7993bfa2ecb30c44455de538eb6f8a4a59087
\ No newline at end of file
index ad4d27a1263cf69b0ff5d6e050cd2bd0400e070d..339b8967df1c82ba32a8e70f06947688787c2174 100644 (file)
@@ -107,6 +107,11 @@ typedef struct IncrblobChannel IncrblobChannel;
 /*
 ** There is one instance of this structure for each SQLite database
 ** that has been opened by the SQLite TCL interface.
+**
+** If this module is built with SQLITE_TEST defined (to create the SQLite
+** testfixture executable), then it may be configured to use either
+** sqlite3_prepare_v2() or sqlite3_prepare() to prepare SQL statements.
+** If SqliteDb.bLegacyPrepare is true, sqlite3_prepare() is used.
 */
 typedef struct SqliteDb SqliteDb;
 struct SqliteDb {
@@ -135,6 +140,9 @@ struct SqliteDb {
   IncrblobChannel *pIncrblob;/* Linked list of open incrblob channels */
   int nStep, nSort, nIndex;  /* Statistics for most recent operation */
   int nTransaction;          /* Number of nested [transaction] methods */
+#ifdef SQLITE_TEST
+  int bLegacyPrepare;        /* True to use sqlite3_prepare() */
+#endif
 };
 
 struct IncrblobChannel {
@@ -429,20 +437,33 @@ static SqlFunc *findSqlFunc(SqliteDb *pDb, const char *zName){
   return pNew;
 }
 
+/*
+** Free a single SqlPreparedStmt object.
+*/
+static void dbFreeStmt(SqlPreparedStmt *pStmt){
+#ifdef SQLITE_TEST
+  if( sqlite3_sql(pStmt->pStmt)==0 ){
+    Tcl_Free((char *)pStmt->zSql);
+  }
+#endif
+  sqlite3_finalize(pStmt->pStmt);
+  Tcl_Free((char *)pStmt);
+}
+
 /*
 ** Finalize and free a list of prepared statements
 */
-static void flushStmtCache( SqliteDb *pDb ){
+static void flushStmtCache(SqliteDb *pDb){
   SqlPreparedStmt *pPreStmt;
+  SqlPreparedStmt *pNext;
 
-  while(  pDb->stmtList ){
-    sqlite3_finalize( pDb->stmtList->pStmt );
-    pPreStmt = pDb->stmtList;
-    pDb->stmtList = pDb->stmtList->pNext;
-    Tcl_Free( (char*)pPreStmt );
+  for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pNext){
+    pNext = pPreStmt->pNext;
+    dbFreeStmt(pPreStmt);
   }
   pDb->nStmt = 0;
   pDb->stmtLast = 0;
+  pDb->stmtList = 0;
 }
 
 /*
@@ -1030,6 +1051,27 @@ static int DbTransPostCmd(
   return rc;
 }
 
+/*
+** Unless SQLITE_TEST is defined, this function is a simple wrapper around
+** sqlite3_prepare_v2(). If SQLITE_TEST is defined, then it uses either
+** sqlite3_prepare_v2() or legacy interface sqlite3_prepare(), depending
+** on whether or not the [db_use_legacy_prepare] command has been used to 
+** configure the connection.
+*/
+static int dbPrepare(
+  SqliteDb *pDb,                  /* Database object */
+  const char *zSql,               /* SQL to compile */
+  sqlite3_stmt **ppStmt,          /* OUT: Prepared statement */
+  const char **pzOut              /* OUT: Pointer to next SQL statement */
+){
+#ifdef SQLITE_TEST
+  if( pDb->bLegacyPrepare ){
+    return sqlite3_prepare(pDb->db, zSql, -1, ppStmt, pzOut);
+  }
+#endif
+  return sqlite3_prepare_v2(pDb->db, zSql, -1, ppStmt, pzOut);
+}
+
 /*
 ** Search the cache for a prepared-statement object that implements the
 ** first SQL statement in the buffer pointed to by parameter zIn. If
@@ -1100,7 +1142,7 @@ static int dbPrepareAndBind(
   if( pPreStmt==0 ){
     int nByte;
 
-    if( SQLITE_OK!=sqlite3_prepare_v2(pDb->db, zSql, -1, &pStmt, pzOut) ){
+    if( SQLITE_OK!=dbPrepare(pDb, zSql, &pStmt, pzOut) ){
       Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
       return TCL_ERROR;
     }
@@ -1127,6 +1169,14 @@ static int dbPrepareAndBind(
     pPreStmt->nSql = (*pzOut - zSql);
     pPreStmt->zSql = sqlite3_sql(pStmt);
     pPreStmt->apParm = (Tcl_Obj **)&pPreStmt[1];
+#ifdef SQLITE_TEST
+    if( pPreStmt->zSql==0 ){
+      char *zCopy = Tcl_Alloc(pPreStmt->nSql + 1);
+      memcpy(zCopy, zSql, pPreStmt->nSql);
+      zCopy[pPreStmt->nSql] = '\0';
+      pPreStmt->zSql = zCopy;
+    }
+#endif
   }
   assert( pPreStmt );
   assert( strlen30(pPreStmt->zSql)==pPreStmt->nSql );
@@ -1180,7 +1230,6 @@ static int dbPrepareAndBind(
   return TCL_OK;
 }
 
-
 /*
 ** Release a statement reference obtained by calling dbPrepareAndBind().
 ** There should be exactly one call to this function for each call to
@@ -1205,8 +1254,7 @@ static void dbReleaseStmt(
 
   if( pDb->maxStmt<=0 || discard ){
     /* If the cache is turned off, deallocated the statement */
-    sqlite3_finalize(pPreStmt->pStmt);
-    Tcl_Free((char *)pPreStmt);
+    dbFreeStmt(pPreStmt);
   }else{
     /* Add the prepared statement to the beginning of the cache list. */
     pPreStmt->pNext = pDb->stmtList;
@@ -1226,11 +1274,11 @@ static void dbReleaseStmt(
     /* If we have too many statement in cache, remove the surplus from 
     ** the end of the cache list.  */
     while( pDb->nStmt>pDb->maxStmt ){
-      sqlite3_finalize(pDb->stmtLast->pStmt);
-      pDb->stmtLast = pDb->stmtLast->pPrev;
-      Tcl_Free((char*)pDb->stmtLast->pNext);
+      SqlPreparedStmt *pLast = pDb->stmtLast;
+      pDb->stmtLast = pLast->pPrev;
       pDb->stmtLast->pNext = 0;
       pDb->nStmt--;
+      dbFreeStmt(pLast);
     }
   }
 }
@@ -1363,9 +1411,12 @@ static void dbEvalRowInfo(
 ** no further rows available. This is similar to SQLITE_DONE.
 */
 static int dbEvalStep(DbEvalContext *p){
+  const char *zPrevSql = 0;       /* Previous value of p->zSql */
+
   while( p->zSql[0] || p->pPreStmt ){
     int rc;
     if( p->pPreStmt==0 ){
+      zPrevSql = (p->zSql==zPrevSql ? 0 : p->zSql);
       rc = dbPrepareAndBind(p->pDb, p->zSql, &p->zSql, &p->pPreStmt);
       if( rc!=TCL_OK ) return rc;
     }else{
@@ -1392,8 +1443,19 @@ static int dbEvalStep(DbEvalContext *p){
       if( rcs!=SQLITE_OK ){
         /* If a run-time error occurs, report the error and stop reading
         ** the SQL.  */
-        Tcl_SetObjResult(pDb->interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
         dbReleaseStmt(pDb, pPreStmt, 1);
+#if SQLITE_TEST
+        if( p->pDb->bLegacyPrepare && rcs==SQLITE_SCHEMA && zPrevSql ){
+          /* If the runtime error was an SQLITE_SCHEMA, and the database
+          ** handle is configured to use the legacy sqlite3_prepare() 
+          ** interface, retry prepare()/step() on the same SQL statement.
+          ** This only happens once. If there is a second SQLITE_SCHEMA
+          ** error, the error will be returned to the caller. */
+          p->zSql = zPrevSql;
+          continue;
+        }
+#endif
+        Tcl_SetObjResult(pDb->interp, dbTextToObj(sqlite3_errmsg(pDb->db)));
         return TCL_ERROR;
       }else{
         dbReleaseStmt(pDb, pPreStmt, 0);
@@ -2926,7 +2988,7 @@ static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
       }else{
         flags &= ~SQLITE_OPEN_NOMUTEX;
       }
-   }else if( strcmp(zArg, "-fullmutex")==0 ){
+    }else if( strcmp(zArg, "-fullmutex")==0 ){
       int b;
       if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
       if( b ){
@@ -3527,6 +3589,44 @@ static int init_all_cmd(
   init_all(slave);
   return TCL_OK;
 }
+
+/*
+** Tclcmd: db_use_legacy_prepare DB BOOLEAN
+**
+**   The first argument to this command must be a database command created by
+**   [sqlite3]. If the second argument is true, then the handle is configured
+**   to use the sqlite3_prepare_v2() function to prepare statements. If it
+**   is false, sqlite3_prepare().
+*/
+static int db_use_legacy_prepare_cmd(
+  ClientData cd,
+  Tcl_Interp *interp,
+  int objc,
+  Tcl_Obj *CONST objv[]
+){
+  Tcl_CmdInfo cmdInfo;
+  SqliteDb *pDb;
+  int bPrepare;
+
+  if( objc!=3 ){
+    Tcl_WrongNumArgs(interp, 1, objv, "DB BOOLEAN");
+    return TCL_ERROR;
+  }
+
+  if( !Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &cmdInfo) ){
+    Tcl_AppendResult(interp, "no such db: ", Tcl_GetString(objv[1]), (char*)0);
+    return TCL_ERROR;
+  }
+  pDb = (SqliteDb*)cmdInfo.objClientData;
+  if( Tcl_GetBooleanFromObj(interp, objv[2], &bPrepare) ){
+    return TCL_ERROR;
+  }
+
+  pDb->bLegacyPrepare = bPrepare;
+
+  Tcl_ResetResult(interp);
+  return TCL_OK;
+}
 #endif
 
 /*
@@ -3633,7 +3733,12 @@ static void init_all(Tcl_Interp *interp){
     Sqlitetestfts3_Init(interp);
 #endif
 
-    Tcl_CreateObjCommand(interp,"load_testfixture_extensions",init_all_cmd,0,0);
+    Tcl_CreateObjCommand(
+        interp, "load_testfixture_extensions", init_all_cmd, 0, 0
+    );
+    Tcl_CreateObjCommand(
+        interp, "db_use_legacy_prepare", db_use_legacy_prepare_cmd, 0, 0
+    );
 
 #ifdef SQLITE_SSE
     Sqlitetestsse_Init(interp);
index 967124668152beeeee5e657bb17fc13f3fba0aa9..54302d02e91788d5e04f71734b549bc6a5f74f06 100644 (file)
@@ -38,6 +38,7 @@ run_test_suite pcache10
 run_test_suite pcache50 
 run_test_suite pcache90 
 run_test_suite pcache100
+run_test_suite prepare
 
 if {$::tcl_platform(platform)=="unix"} {
   ifcapable !default_autovacuum {
index 712960c0eaf9e3cffacc97995329fb1bb92e993d..66b19509451c7d35f0e8bd302c5aabe799a3fe04 100644 (file)
@@ -137,6 +137,7 @@ do_test alter2-1.8 {
 do_test alter2-1.9 {
   # ALTER TABLE abc ADD COLUMN d;
   alter_table abc {CREATE TABLE abc(a, b, c, d);}
+  if {[permutation] == "prepare"} { db cache flush }
   execsql { SELECT * FROM abc; }
   execsql {
     UPDATE abc SET d = 11 WHERE c IS NULL AND a<4;
index c7c14a2402e60bffd51747e6c503359c037997cc..fb73797d2997a90ec859aa1c20962d6b782b6447 100644 (file)
@@ -159,7 +159,7 @@ foreach jm {rollback wal} {
       sql1 { DROP INDEX IF EXISTS i2 }
       sql2 { CREATE INDEX aux.i2 ON t2(x) }
       sql1 { DROP INDEX IF EXISTS i2 }
-      sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'index' }
+      sql2 { SELECT * FROM aux.sqlite_master WHERE type = 'index' }
     } {}
 
     # VIEW objects.
index 22e2189d9896c580d7b6ad4dc21a2600d0facc6a..57f69462a58c88b691b185cb9734f63452d43e4b 100644 (file)
@@ -776,6 +776,15 @@ test_suite "no_optimization" -description {
   optimization_control $::dbhandle all 0
 }
 
+test_suite "prepare" -description {
+  Run tests with the db connection using sqlite3_prepare() instead of _v2().
+} -dbconfig {
+  db_use_legacy_prepare $::dbhandle 1
+  #$::dbhandle cache size 0
+} -files [
+  test_set $allquicktests -exclude *malloc* *ioerr* *fault*
+]
+
 # End of tests
 #############################################################################
 
index ad85f7e9f6627176435ca9897723d7c4dfd5395a..d82ea3644456842986e37874d7e44ec166c7b85e 100644 (file)
@@ -292,6 +292,7 @@ do_test temptable-5.1 {
   execsql {
     CREATE TEMP TABLE mask(a,b,c)
   } db2
+  if {[permutation]=="prepare"} { db2 cache flush }
   execsql {
     CREATE INDEX mask ON t2(x);
     SELECT * FROM t2;