-C Enforce\sthe\sMAX_EXPR_DEPTH\slimit\swhile\sbuilding\sexpression\strees\sduring\sSQL\sparsing.
-D 2010-10-28T11:31:23
+C Add\snew\s"dynamic_triggers"\stest\scase\sto\sthreadtest3.c.
+D 2010-10-28T15:52:05
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 2c8cefd962eca0147132c7cf9eaa4bb24c656f3f
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F test/thread_common.tcl 2aa6f2fdcd4d6e461169c3e5ca098eebf643b863
F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b
F test/threadtest2.c ace893054fa134af3fc8d6e7cfecddb8e3acefb9
-F test/threadtest3.c 58df1e3c060f534fd7fb0702331b0acc41c381d8
+F test/threadtest3.c d6d209190c7110f9a7e6a8154bdc3260efdbf8b7
F test/tkt-02a8e81d44.test 58494de77be2cf249228ada3f313fa399821c6ab
F test/tkt-26ff0c2d1e.test 888324e751512972c6e0d1a09df740d8f5aaf660
F test/tkt-2ea2425d34.test 1cf13e6f75d149b3209a0cb32927a82d3d79fb28
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 739b5d9aa4eaa4191ca512d0dbf94a6bdbb12d97
-R 7d13c78e61246d2ffda39eef845308b8
+P 2625eee0cb7f22dba61459b689e33a03ecebb6da
+R 72ae68a6bead35074543f0fbb3f99813
U dan
-Z 089b9ce90fd6493612af9b7c95a2cded
+Z d97641c607fcd38b195631c16e5de58c
print_and_free_err(&err);
}
+/*------------------------------------------------------------------------
+** Test case "dynamic_triggers"
+**
+** Two threads executing statements that cause deeply nested triggers
+** to fire. And one thread busily creating and deleting triggers. This
+** is an attempt to find a bug reported to us.
+*/
+
+static char *dynamic_triggers_1(int iTid, int iArg){
+ Error err = {0}; /* Error code and message */
+ Sqlite db = {0}; /* SQLite database connection */
+ int nDrop = 0;
+ int nCreate = 0;
+
+ opendb(&err, &db, "test.db", 0);
+ while( !timetostop(&err) ){
+ int i;
+
+ for(i=1; i<9; i++){
+ char *zSql = sqlite3_mprintf(
+ "CREATE TRIGGER itr%d BEFORE INSERT ON t%d BEGIN "
+ "INSERT INTO t%d VALUES(new.x, new.y);"
+ "END;", i, i, i+1
+ );
+ execsql(&err, &db, zSql);
+ sqlite3_free(zSql);
+ nCreate++;
+ }
+
+ for(i=1; i<9; i++){
+ char *zSql = sqlite3_mprintf(
+ "CREATE TRIGGER dtr%d BEFORE DELETE ON t%d BEGIN "
+ "DELETE FROM t%d WHERE x = old.x; "
+ "END;", i, i, i+1
+ );
+ execsql(&err, &db, zSql);
+ sqlite3_free(zSql);
+ nCreate++;
+ }
+
+ for(i=1; i<9; i++){
+ char *zSql = sqlite3_mprintf("DROP TRIGGER itr%d", i);
+ execsql(&err, &db, zSql);
+ sqlite3_free(zSql);
+ nDrop++;
+ }
+
+ for(i=1; i<9; i++){
+ char *zSql = sqlite3_mprintf("DROP TRIGGER dtr%d", i);
+ execsql(&err, &db, zSql);
+ sqlite3_free(zSql);
+ nDrop++;
+ }
+ }
+
+ print_and_free_err(&err);
+ return sqlite3_mprintf("%d created, %d dropped", nCreate, nDrop);
+}
+
+static char *dynamic_triggers_2(int iTid, int iArg){
+ Error err = {0}; /* Error code and message */
+ Sqlite db = {0}; /* SQLite database connection */
+ i64 iVal = 0;
+ int nInsert = 0;
+ int nDelete = 0;
+
+ opendb(&err, &db, "test.db", 0);
+ while( !timetostop(&err) ){
+ do {
+ iVal = (iVal+1)%100;
+ execsql(&err, &db, "INSERT INTO t1 VALUES(:iX, :iY+1)", &iVal, &iVal);
+ nInsert++;
+ } while( iVal );
+
+ do {
+ iVal = (iVal+1)%100;
+ execsql(&err, &db, "DELETE FROM t1 WHERE x = :iX", &iVal);
+ nDelete++;
+ } while( iVal );
+ }
+
+ print_and_free_err(&err);
+ return sqlite3_mprintf("%d inserts, %d deletes", nInsert, nDelete);
+}
+
+static void dynamic_triggers(int nMs){
+ Error err = {0};
+ Sqlite db = {0};
+ Threadset threads = {0};
+
+ opendb(&err, &db, "test.db", 1);
+ sql_script(&err, &db,
+ "PRAGMA page_size = 1024;"
+ "PRAGMA journal_mode = WAL;"
+ "CREATE TABLE t1(x, y);"
+ "CREATE TABLE t2(x, y);"
+ "CREATE TABLE t3(x, y);"
+ "CREATE TABLE t4(x, y);"
+ "CREATE TABLE t5(x, y);"
+ "CREATE TABLE t6(x, y);"
+ "CREATE TABLE t7(x, y);"
+ "CREATE TABLE t8(x, y);"
+ "CREATE TABLE t9(x, y);"
+ );
+
+ setstoptime(&err, nMs);
+
+ sqlite3_enable_shared_cache(1);
+ launch_thread(&err, &threads, dynamic_triggers_2, 0);
+ launch_thread(&err, &threads, dynamic_triggers_2, 0);
+ sqlite3_enable_shared_cache(0);
+
+ sleep(2);
+
+ launch_thread(&err, &threads, dynamic_triggers_2, 0);
+ launch_thread(&err, &threads, dynamic_triggers_1, 0);
+
+ join_all_threads(&err, &threads);
+
+ print_and_free_err(&err);
+}
+
+
int main(int argc, char **argv){
struct ThreadTest {
void (*xTest)(int);
{ walthread5, "walthread5", 1000 },
{ cgt_pager_1, "cgt_pager_1", 0 },
+ { dynamic_triggers, "dynamic_triggers", 20000 },
};
int i;