-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
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
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
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
-fdd44bbb501c7252097e79685e916e760846e183bc9f022f9cf32f1d32f0089d
\ No newline at end of file
+62557fab0d21d47893e69d504ae2b4405c1837ccd6300a5a6743cb756eb28ad3
\ No newline at end of file
#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 */
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 ){
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)",
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");
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);"
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);
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);
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;
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);"
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);
}
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(
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);"
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);
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;"
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;"
int nDrop = 0;
int nCreate = 0;
- opendb(&err, &db, "test.db", 0);
+ opendb(&err, &db, "test.db", 0, 0);
while( !timetostop(&err) ){
int i;
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;
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;"
#include "tt3_lookaside1.c"
#include "tt3_vacuum.c"
#include "tt3_stress.c"
+#include "tt3_reuseschema.c"
int main(int argc, char **argv){
struct ThreadTest {
{ vacuum1, "vacuum1", 10000 },
{ stress1, "stress1", 10000 },
{ stress2, "stress2", 60000 },
+ { reuse_schema_1, "reuse_schema_1", 20000 },
};
static char *substArgv[] = { 0, "*", 0 };
int i, iArg;
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");
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;"
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;"
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) "
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;
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,
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 ("
--- /dev/null
+/*
+** 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);
+}
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);
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);
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++;
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) "
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++;
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);
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 && cnt<STRESS2_TABCNT; cnt++){
pCtx->xProc(&err, &db, i1);
i2 += (err.rc==SQLITE_OK);
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);"
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) ){
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");
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);"