From: dan Date: Tue, 6 Aug 2019 15:02:49 +0000 (+0000) Subject: Add a multi-threaded test to threadtest3.c for the feature on this branch. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=49c7657ac9151eb634649b694e168e5afcf1778e;p=thirdparty%2Fsqlite.git Add a multi-threaded test to threadtest3.c for the feature on this branch. FossilOrigin-Name: 62557fab0d21d47893e69d504ae2b4405c1837ccd6300a5a6743cb756eb28ad3 --- diff --git a/manifest b/manifest index 431ecdde5e..a4ca8b55e8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\san\sassert()\sto\sthe\scode\son\sthis\sbranch. -D 2019-08-06T11:45:33.654 +C Add\sa\smulti-threaded\stest\sto\sthreadtest3.c\sfor\sthe\sfeature\son\sthis\sbranch. +D 2019-08-06T15:02:49.156 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1416,7 +1416,7 @@ F test/thread2.test f35d2106452b77523b3a2b7d1dcde2e5ee8f9e46 F test/thread_common.tcl 334639cadcb9f912bf82aa73f49efd5282e6cadd F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b F test/threadtest2.c a70a8e94bef23339d34226eb9521015ef99f4df8 -F test/threadtest3.c 38a612ea62854349ed66372f330a40d73c5cf956 +F test/threadtest3.c 4de1edf7cddac6195acfaea56cccb8572df803854531251784f6b8ca46f256e3 F test/threadtest4.c c1e67136ceb6c7ec8184e56ac61db28f96bd2925 F test/time-wordcount.sh 8e0b0f8109367827ad5d58f5cc849705731e4b90 F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c @@ -1585,11 +1585,12 @@ F test/triggerD.test 8e7f3921a92a5797d472732108109e44575fa650 F test/triggerE.test ede2e4bce4ba802337bd69d39447fa04a938e06d84a8bfc53c76850fc36ed86d F test/triggerF.test 5d76f0a8c428ff87a4d5ed52da06f6096a2c787a1e21b846111dfac4123de3ad F test/triggerG.test d5caeef6144ede2426dd13211fd72248241ff2ebc68e12a4c0bf30f5faa21499 -F test/tt3_checkpoint.c 9e75cf7c1c364f52e1c47fd0f14c4340a9db0fe1 -F test/tt3_index.c 39eec10a35f57672225be4d182862152896dee4a -F test/tt3_lookaside1.c 0377e202c3c2a50d688cb65ba203afeda6fafeb9 -F test/tt3_stress.c c57d804716165811d979d4a719e05baccd79277f -F test/tt3_vacuum.c 1753f45917699c9c1f66b64c717a717c9379f776 +F test/tt3_checkpoint.c 9a7fe00e07700af027769d83ef67ab727927ae6c865ecdc71fe8011194200c53 +F test/tt3_index.c 95592839426dc85ce5a7a57b41be2cbf3c2ec3457b9cd841a06ed5877f712c7c +F test/tt3_lookaside1.c 2ddd99bfffeef288f0786827ef68f912f6f47ce3d3184e62f05808d8e13b920e +F test/tt3_reuseschema.c 4d52e141f89f009028d8ab0bd1f0697d0edffa94bafc1fff0f7ad4d9d9baa549 +F test/tt3_stress.c bbd430f23fa64f466ea8f212756f5f7135a2f8ff5accad85550c0ba73be76b16 +F test/tt3_vacuum.c ca42adcf8a671abbe34338b828464269e21758a6b4857b889dabfd39a3206d98 F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff F test/types2.test 1aeb81976841a91eef292723649b5c4fe3bc3cac F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a @@ -1846,7 +1847,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 7f1e4e4b99644f986aa68bd40afddc4886145972eae1106347185eeff52150d6 -R 74be422d8178d1a704e716c0180e63a4 +P fdd44bbb501c7252097e79685e916e760846e183bc9f022f9cf32f1d32f0089d +R a9b8527bf0773b824fbecc1d333eb46b U dan -Z 9c1ce67a75ce4b7fcc7df0d80c599066 +Z defc4aad4b110f20b71fb180d41dde27 diff --git a/manifest.uuid b/manifest.uuid index 7a8882ecd9..2089444a38 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -fdd44bbb501c7252097e79685e916e760846e183bc9f022f9cf32f1d32f0089d \ No newline at end of file +62557fab0d21d47893e69d504ae2b4405c1837ccd6300a5a6743cb756eb28ad3 \ No newline at end of file diff --git a/test/threadtest3.c b/test/threadtest3.c index 6062b64285..2910edfa28 100644 --- a/test/threadtest3.c +++ b/test/threadtest3.c @@ -38,7 +38,7 @@ #define SEL(e) ((e)->iLine = ((e)->rc ? (e)->iLine : __LINE__)) /* Database functions */ -#define opendb(w,x,y,z) (SEL(w), opendb_x(w,x,y,z)) +#define opendb(w,x,y,z,f) (SEL(w), opendb_x(w,x,y,z,f)) #define closedb(y,z) (SEL(y), closedb_x(y,z)) /* Functions to execute SQL */ @@ -520,11 +520,14 @@ static void opendb_x( Error *pErr, /* IN/OUT: Error code */ Sqlite *pDb, /* OUT: Database handle */ const char *zFile, /* Database file name */ - int bDelete /* True to delete db file before opening */ + int bDelete, /* True to delete db file before opening */ + int flags ){ if( pErr->rc==SQLITE_OK ){ int rc; - int flags = SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE | SQLITE_OPEN_URI; + if( flags==0 ){ + flags = SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE | SQLITE_OPEN_URI; + } if( bDelete ) unlink(zFile); rc = sqlite3_open_v2(zFile, &pDb->db, flags, 0); if( rc ){ @@ -926,7 +929,7 @@ static char *walthread1_thread(int iTid, void *pArg){ Sqlite db = {0}; /* SQLite database connection */ int nIter = 0; /* Iterations so far */ - opendb(&err, &db, "test.db", 0); + opendb(&err, &db, "test.db", 0, 0); while( !timetostop(&err) ){ const char *azSql[] = { "SELECT md5sum(x) FROM t1 WHERE rowid != (SELECT max(rowid) FROM t1)", @@ -965,7 +968,7 @@ static char *walthread1_ckpt_thread(int iTid, void *pArg){ Sqlite db = {0}; /* SQLite database connection */ int nCkpt = 0; /* Checkpoints so far */ - opendb(&err, &db, "test.db", 0); + opendb(&err, &db, "test.db", 0, 0); while( !timetostop(&err) ){ usleep(500*1000); execsql(&err, &db, "PRAGMA wal_checkpoint"); @@ -984,7 +987,7 @@ static void walthread1(int nMs){ Threadset threads = {0}; /* Test threads */ int i; /* Iterator variable */ - opendb(&err, &db, "test.db", 1); + opendb(&err, &db, "test.db", 1, 0); sql_script(&err, &db, "PRAGMA journal_mode = WAL;" "CREATE TABLE t1(x PRIMARY KEY);" @@ -1017,7 +1020,7 @@ static char *walthread2_thread(int iTid, void *pArg){ int journal_exists = 0; int wal_exists = 0; - opendb(&err, &db, "test.db", 0); + opendb(&err, &db, "test.db", 0, 0); sql_script(&err, &db, zJournal); clear_error(&err, SQLITE_BUSY); @@ -1047,7 +1050,7 @@ static void walthread2(int nMs){ Sqlite db = {0}; Threadset threads = {0}; - opendb(&err, &db, "test.db", 1); + opendb(&err, &db, "test.db", 1, 0); sql_script(&err, &db, "CREATE TABLE t1(x INTEGER PRIMARY KEY, y UNIQUE)"); closedb(&err, &db); @@ -1067,7 +1070,7 @@ static char *walthread3_thread(int iTid, void *pArg){ i64 iNextWrite; /* Next value this thread will write */ int iArg = PTR2INT(pArg); - opendb(&err, &db, "test.db", 0); + opendb(&err, &db, "test.db", 0, 0); sql_script(&err, &db, "PRAGMA wal_autocheckpoint = 10"); iNextWrite = iArg+1; @@ -1104,7 +1107,7 @@ static void walthread3(int nMs){ Threadset threads = {0}; int i; - opendb(&err, &db, "test.db", 1); + opendb(&err, &db, "test.db", 1, 0); sql_script(&err, &db, "PRAGMA journal_mode = WAL;" "CREATE TABLE t1(cnt PRIMARY KEY, sum1, sum2);" @@ -1127,7 +1130,7 @@ static char *walthread4_reader_thread(int iTid, void *pArg){ Error err = {0}; /* Error code and message */ Sqlite db = {0}; /* SQLite database connection */ - opendb(&err, &db, "test.db", 0); + opendb(&err, &db, "test.db", 0, 0); while( !timetostop(&err) ){ integrity_check(&err, &db); } @@ -1142,7 +1145,7 @@ static char *walthread4_writer_thread(int iTid, void *pArg){ Sqlite db = {0}; /* SQLite database connection */ i64 iRow = 1; - opendb(&err, &db, "test.db", 0); + opendb(&err, &db, "test.db", 0, 0); sql_script(&err, &db, "PRAGMA wal_autocheckpoint = 15;"); while( !timetostop(&err) ){ execsql_i64( @@ -1162,7 +1165,7 @@ static void walthread4(int nMs){ Sqlite db = {0}; Threadset threads = {0}; - opendb(&err, &db, "test.db", 1); + opendb(&err, &db, "test.db", 1, 0); sql_script(&err, &db, "PRAGMA journal_mode = WAL;" "CREATE TABLE t1(a INTEGER PRIMARY KEY, b UNIQUE);" @@ -1182,7 +1185,7 @@ static char *walthread5_thread(int iTid, void *pArg){ Sqlite db = {0}; /* SQLite database connection */ i64 nRow; - opendb(&err, &db, "test.db", 0); + opendb(&err, &db, "test.db", 0, 0); nRow = execsql_i64(&err, &db, "SELECT count(*) FROM t1"); closedb(&err, &db); @@ -1195,7 +1198,7 @@ static void walthread5(int nMs){ Sqlite db = {0}; Threadset threads = {0}; - opendb(&err, &db, "test.db", 1); + opendb(&err, &db, "test.db", 1, 0); sql_script(&err, &db, "PRAGMA wal_autocheckpoint = 0;" "PRAGMA page_size = 1024;" @@ -1286,7 +1289,7 @@ static void cgt_pager_1(int nMs){ Error err = {0}; Sqlite db = {0}; - opendb(&err, &db, "test.db", 1); + opendb(&err, &db, "test.db", 1, 0); sql_script(&err, &db, "PRAGMA cache_size = 2000;" "PRAGMA page_size = 1024;" @@ -1315,7 +1318,7 @@ static char *dynamic_triggers_1(int iTid, void *pArg){ int nDrop = 0; int nCreate = 0; - opendb(&err, &db, "test.db", 0); + opendb(&err, &db, "test.db", 0, 0); while( !timetostop(&err) ){ int i; @@ -1368,7 +1371,7 @@ static char *dynamic_triggers_2(int iTid, void *pArg){ int nInsert = 0; int nDelete = 0; - opendb(&err, &db, "test.db", 0); + opendb(&err, &db, "test.db", 0, 0); while( !timetostop(&err) ){ do { iVal = (iVal+1)%100; @@ -1393,7 +1396,7 @@ static void dynamic_triggers(int nMs){ Sqlite db = {0}; Threadset threads = {0}; - opendb(&err, &db, "test.db", 1); + opendb(&err, &db, "test.db", 1, 0); sql_script(&err, &db, "PRAGMA page_size = 1024;" "PRAGMA journal_mode = WAL;" @@ -1433,6 +1436,7 @@ static void dynamic_triggers(int nMs){ #include "tt3_lookaside1.c" #include "tt3_vacuum.c" #include "tt3_stress.c" +#include "tt3_reuseschema.c" int main(int argc, char **argv){ struct ThreadTest { @@ -1457,6 +1461,7 @@ int main(int argc, char **argv){ { vacuum1, "vacuum1", 10000 }, { stress1, "stress1", 10000 }, { stress2, "stress2", 60000 }, + { reuse_schema_1, "reuse_schema_1", 20000 }, }; static char *substArgv[] = { 0, "*", 0 }; int i, iArg; diff --git a/test/tt3_checkpoint.c b/test/tt3_checkpoint.c index 060a698211..c06b3e06c1 100644 --- a/test/tt3_checkpoint.c +++ b/test/tt3_checkpoint.c @@ -70,7 +70,7 @@ static char *checkpoint_starvation_reader(int iTid, void *pArg){ Error err = {0}; Sqlite db = {0}; - opendb(&err, &db, "test.db", 0); + opendb(&err, &db, "test.db", 0, 0); while( !timetostop(&err) ){ i64 iCount1, iCount2; sql_script(&err, &db, "BEGIN"); @@ -96,7 +96,7 @@ static void checkpoint_starvation_main(int nMs, CheckpointStarvationCtx *p){ int nInsert = 0; int i; - opendb(&err, &db, "test.db", 1); + opendb(&err, &db, "test.db", 1, 0); sql_script(&err, &db, "PRAGMA page_size = 1024;" "PRAGMA journal_mode = WAL;" diff --git a/test/tt3_index.c b/test/tt3_index.c index 62f06ade4a..a752200b2d 100644 --- a/test/tt3_index.c +++ b/test/tt3_index.c @@ -19,7 +19,7 @@ static char *create_drop_index_thread(int iTid, void *pArg){ Sqlite db = {0}; /* SQLite database connection */ while( !timetostop(&err) ){ - opendb(&err, &db, "test.db", 0); + opendb(&err, &db, "test.db", 0, 0); sql_script(&err, &db, "DROP INDEX IF EXISTS i1;" @@ -51,7 +51,7 @@ static void create_drop_index_1(int nMs){ Sqlite db = {0}; Threadset threads = {0}; - opendb(&err, &db, "test.db", 1); + opendb(&err, &db, "test.db", 1, 0); sql_script(&err, &db, "CREATE TABLE t11(a, b, c, d);" "WITH data(x) AS (SELECT 1 UNION ALL SELECT x+1 FROM data WHERE x<100) " diff --git a/test/tt3_lookaside1.c b/test/tt3_lookaside1.c index e785e7998b..05dda5de73 100644 --- a/test/tt3_lookaside1.c +++ b/test/tt3_lookaside1.c @@ -22,7 +22,7 @@ static char *lookaside1_thread_reader(int iTid, void *pArg){ Error err = {0}; /* Error code and message */ Sqlite db = {0}; /* SQLite database connection */ - opendb(&err, &db, "test.db", 0); + opendb(&err, &db, "test.db", 0, 0); while( !timetostop(&err) ){ sqlite3_stmt *pStmt = 0; @@ -47,7 +47,7 @@ static char *lookaside1_thread_writer(int iTid, void *pArg){ Error err = {0}; /* Error code and message */ Sqlite db = {0}; /* SQLite database connection */ - opendb(&err, &db, "test.db", 0); + opendb(&err, &db, "test.db", 0, 0); do{ sql_script(&err, &db, @@ -68,7 +68,7 @@ static void lookaside1(int nMs){ Sqlite db = {0}; Threadset threads = {0}; - opendb(&err, &db, "test.db", 1); + opendb(&err, &db, "test.db", 1, 0); sql_script(&err, &db, "CREATE TABLE t1(x PRIMARY KEY) WITHOUT ROWID;" "WITH data(x,y) AS (" diff --git a/test/tt3_reuseschema.c b/test/tt3_reuseschema.c new file mode 100644 index 0000000000..5e269fe47e --- /dev/null +++ b/test/tt3_reuseschema.c @@ -0,0 +1,73 @@ +/* +** 2014 December 9 +** +** 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. +** +************************************************************************* +** +** reuse_schema_1 +*/ + + +static char *reuse_schema_thread(int iTid, void *pArg){ + Error err = {0}; /* Error code and message */ + Sqlite db = {0}; /* SQLite database connection */ + int iRep = 0; + + while( !timetostop(&err) ){ + int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_SHARED_SCHEMA; + opendb(&err, &db, "test.db", 0, f); + + execsql_i64(&err, &db, "SELECT count(*) FROM t1"); + sql_script(&err, &db, "ATTACH 'test.db2' AS aux"); + execsql_i64(&err, &db, "SELECT count(*) FROM t1"); + + closedb(&err, &db); + iRep++; + } + + print_and_free_err(&err); + return sqlite3_mprintf("%d", iRep); +} + +static void reuse_schema_1(int nMs){ + Error err = {0}; + Sqlite db = {0}; + Threadset threads = {0}; + + opendb(&err, &db, "test.db", 1, 0); + sql_script(&err, &db, + "CREATE TABLE t1(a, b, c, d);" + "WITH data(x) AS (SELECT 1 UNION ALL SELECT x+1 FROM data WHERE x<100) " + "INSERT INTO t1 SELECT x,x,x,x FROM data;" + ); + closedb(&err, &db); + opendb(&err, &db, "test.db2", 1, 0); + sql_script(&err, &db, +#ifdef SQLITE_ENABLE_FTS5 + "CREATE VIRTUAL TABLE t2 USING fts5(a, b, c, d);" +#else + "CREATE TABLE t2(a, b, c, d);" +#endif + "WITH data(x) AS (SELECT 1 UNION ALL SELECT x+1 FROM data WHERE x<100) " + "INSERT INTO t2 SELECT x*2,x*2,x*2,x*2 FROM data;" + ); + closedb(&err, &db); + + setstoptime(&err, nMs); + + launch_thread(&err, &threads, reuse_schema_thread, 0); + launch_thread(&err, &threads, reuse_schema_thread, 0); + launch_thread(&err, &threads, reuse_schema_thread, 0); + launch_thread(&err, &threads, reuse_schema_thread, 0); + launch_thread(&err, &threads, reuse_schema_thread, 0); + + join_all_threads(&err, &threads); + sqlite3_enable_shared_cache(0); + print_and_free_err(&err); +} diff --git a/test/tt3_stress.c b/test/tt3_stress.c index cdfab9c09c..8c9519770c 100644 --- a/test/tt3_stress.c +++ b/test/tt3_stress.c @@ -21,7 +21,7 @@ static char *stress_thread_1(int iTid, void *pArg){ Error err = {0}; /* Error code and message */ Sqlite db = {0}; /* SQLite database connection */ - opendb(&err, &db, "test.db", 0); + opendb(&err, &db, "test.db", 0, 0); while( !timetostop(&err) ){ sql_script(&err, &db, "CREATE TABLE IF NOT EXISTS t1(a PRIMARY KEY, b)"); clear_error(&err, SQLITE_LOCKED); @@ -40,7 +40,7 @@ static char *stress_thread_2(int iTid, void *pArg){ Error err = {0}; /* Error code and message */ Sqlite db = {0}; /* SQLite database connection */ while( !timetostop(&err) ){ - opendb(&err, &db, "test.db", 0); + opendb(&err, &db, "test.db", 0, 0); sql_script(&err, &db, "SELECT * FROM sqlite_master;"); clear_error(&err, SQLITE_LOCKED); closedb(&err, &db); @@ -59,7 +59,7 @@ static char *stress_thread_3(int iTid, void *pArg){ int i1 = 0; int i2 = 0; - opendb(&err, &db, "test.db", 0); + opendb(&err, &db, "test.db", 0, 0); while( !timetostop(&err) ){ sql_script(&err, &db, "SELECT * FROM t1 ORDER BY a;"); i1++; @@ -82,11 +82,11 @@ static char *stress_thread_4(int iTid, void *pArg){ int i2 = 0; int iArg = PTR2INT(pArg); - opendb(&err, &db, "test.db", 0); + opendb(&err, &db, "test.db", 0, 0); while( !timetostop(&err) ){ if( iArg ){ closedb(&err, &db); - opendb(&err, &db, "test.db", 0); + opendb(&err, &db, "test.db", 0, 0); } sql_script(&err, &db, "WITH loop(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM loop LIMIT 200) " @@ -113,12 +113,12 @@ static char *stress_thread_5(int iTid, void *pArg){ int i1 = 0; int i2 = 0; - opendb(&err, &db, "test.db", 0); + opendb(&err, &db, "test.db", 0, 0); while( !timetostop(&err) ){ i64 i = (i1 % 4); if( iArg ){ closedb(&err, &db); - opendb(&err, &db, "test.db", 0); + opendb(&err, &db, "test.db", 0, 0); } execsql(&err, &db, "DELETE FROM t1 WHERE (rowid % 4)==:i", &i); i1++; @@ -265,7 +265,7 @@ static char *stress2_workload19(int iTid, void *pArg){ Sqlite db = {0}; /* SQLite database connection */ const char *zDb = (const char*)pArg; while( !timetostop(&err) ){ - opendb(&err, &db, zDb, 0); + opendb(&err, &db, zDb, 0, 0); sql_script(&err, &db, "SELECT * FROM sqlite_master;"); clear_error(&err, SQLITE_LOCKED); closedb(&err, &db); @@ -290,7 +290,7 @@ static char *stress2_thread_wrapper(int iTid, void *pArg){ while( !timetostop(&err) ){ int cnt; - opendb(&err, &db, pCtx->zDb, 0); + opendb(&err, &db, pCtx->zDb, 0, 0); for(cnt=0; err.rc==SQLITE_OK && cntxProc(&err, &db, i1); i2 += (err.rc==SQLITE_OK); @@ -342,7 +342,7 @@ static void stress2(int nMs){ Threadset threads = {0}; /* To make sure the db file is empty before commencing */ - opendb(&err, &db, zDb, 1); + opendb(&err, &db, zDb, 1, 0); sql_script(&err, &db, "CREATE TABLE IF NOT EXISTS t0(x PRIMARY KEY, y, z);" "CREATE INDEX IF NOT EXISTS i0 ON t0(y);" diff --git a/test/tt3_vacuum.c b/test/tt3_vacuum.c index 023fdfd74d..6598a9eec4 100644 --- a/test/tt3_vacuum.c +++ b/test/tt3_vacuum.c @@ -23,7 +23,7 @@ static char *vacuum1_thread_writer(int iTid, void *pArg){ Error err = {0}; /* Error code and message */ Sqlite db = {0}; /* SQLite database connection */ - opendb(&err, &db, "test.db", 0); + opendb(&err, &db, "test.db", 0, 0); i64 i = 0; while( !timetostop(&err) ){ @@ -52,7 +52,7 @@ static char *vacuum1_thread_writer(int iTid, void *pArg){ static char *vacuum1_thread_vacuumer(int iTid, void *pArg){ Error err = {0}; /* Error code and message */ Sqlite db = {0}; /* SQLite database connection */ - opendb(&err, &db, "test.db", 0); + opendb(&err, &db, "test.db", 0, 0); do{ sql_script(&err, &db, "VACUUM"); @@ -69,7 +69,7 @@ static void vacuum1(int nMs){ Sqlite db = {0}; Threadset threads = {0}; - opendb(&err, &db, "test.db", 1); + opendb(&err, &db, "test.db", 1, 0); sql_script(&err, &db, "CREATE TABLE t1(x PRIMARY KEY, y BLOB);" "CREATE INDEX i1 ON t1(y);"