/ Check-in [d9e588ef]
Login

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

Overview
Comment:This was suppose to go on "trunk" but got committed to the wrong branch. Add new "dynamic_triggers" test case to threadtest3.c.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | mistake
Files: files | file ages | folders
SHA1: d9e588ef17ea4393a4219f03f5edf587a0fd829c
User & Date: dan 2010-10-28 15:49:54
Original Comment: Add new "dynamic_triggers" test case to threadtest3.c.
Context
2010-10-28
15:49
This was suppose to go on "trunk" but got committed to the wrong branch. Add new "dynamic_triggers" test case to threadtest3.c. Closed-Leaf check-in: d9e588ef user: dan tags: mistake
2010-10-27
19:23
Add tail recursion to the sqlite3ExprDelete() routine in order to keep down stack space usage for really, really large expressions. Later: The tail recursion is dangerous since the recursion might happen after the expression has been freed. check-in: 7324c7f2 user: drh tags: mistake
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to test/threadtest3.c.

  1267   1267     xSub = cgt_pager_1_populate; xSub(&err, &db);
  1268   1268     xSub = cgt_pager_1_update;   xSub(&err, &db);
  1269   1269     xSub = cgt_pager_1_read;     xSub(&err, &db);
  1270   1270   
  1271   1271     closedb(&err, &db);
  1272   1272     print_and_free_err(&err);
  1273   1273   }
         1274  +
         1275  +/*------------------------------------------------------------------------
         1276  +** Test case "dynamic_triggers"
         1277  +**
         1278  +**   Two threads executing statements that cause deeply nested triggers
         1279  +**   to fire. And one thread busily creating and deleting triggers. This
         1280  +**   is an attempt to find a bug reported to us.
         1281  +*/
         1282  +
         1283  +static char *dynamic_triggers_1(int iTid, int iArg){
         1284  +  Error err = {0};                /* Error code and message */
         1285  +  Sqlite db = {0};                /* SQLite database connection */
         1286  +  int nDrop = 0;
         1287  +  int nCreate = 0;
         1288  +
         1289  +  opendb(&err, &db, "test.db", 0);
         1290  +  while( !timetostop(&err) ){
         1291  +    int i;
         1292  +
         1293  +    for(i=1; i<9; i++){
         1294  +      char *zSql = sqlite3_mprintf(
         1295  +        "CREATE TRIGGER itr%d BEFORE INSERT ON t%d BEGIN "
         1296  +          "INSERT INTO t%d VALUES(new.x, new.y);"
         1297  +        "END;", i, i, i+1
         1298  +      );
         1299  +      execsql(&err, &db, zSql);
         1300  +      sqlite3_free(zSql);
         1301  +      nCreate++;
         1302  +    }
         1303  +
         1304  +    for(i=1; i<9; i++){
         1305  +      char *zSql = sqlite3_mprintf(
         1306  +        "CREATE TRIGGER dtr%d BEFORE DELETE ON t%d BEGIN "
         1307  +          "DELETE FROM t%d WHERE x = old.x; "
         1308  +        "END;", i, i, i+1
         1309  +      );
         1310  +      execsql(&err, &db, zSql);
         1311  +      sqlite3_free(zSql);
         1312  +      nCreate++;
         1313  +    }
         1314  +
         1315  +    for(i=1; i<9; i++){
         1316  +      char *zSql = sqlite3_mprintf("DROP TRIGGER itr%d", i);
         1317  +      execsql(&err, &db, zSql);
         1318  +      sqlite3_free(zSql);
         1319  +      nDrop++;
         1320  +    }
         1321  +
         1322  +    for(i=1; i<9; i++){
         1323  +      char *zSql = sqlite3_mprintf("DROP TRIGGER dtr%d", i);
         1324  +      execsql(&err, &db, zSql);
         1325  +      sqlite3_free(zSql);
         1326  +      nDrop++;
         1327  +    }
         1328  +  }
         1329  +
         1330  +  print_and_free_err(&err);
         1331  +  return sqlite3_mprintf("%d created, %d dropped", nCreate, nDrop);
         1332  +}
         1333  +
         1334  +static char *dynamic_triggers_2(int iTid, int iArg){
         1335  +  Error err = {0};                /* Error code and message */
         1336  +  Sqlite db = {0};                /* SQLite database connection */
         1337  +  i64 iVal = 0;
         1338  +  int nInsert = 0;
         1339  +  int nDelete = 0;
         1340  +
         1341  +  opendb(&err, &db, "test.db", 0);
         1342  +  while( !timetostop(&err) ){
         1343  +    do {
         1344  +      iVal = (iVal+1)%100;
         1345  +      execsql(&err, &db, "INSERT INTO t1 VALUES(:iX, :iY+1)", &iVal, &iVal);
         1346  +      nInsert++;
         1347  +    } while( iVal );
         1348  +
         1349  +    do {
         1350  +      iVal = (iVal+1)%100;
         1351  +      execsql(&err, &db, "DELETE FROM t1 WHERE x = :iX", &iVal);
         1352  +      nDelete++;
         1353  +    } while( iVal );
         1354  +  }
         1355  +
         1356  +  print_and_free_err(&err);
         1357  +  return sqlite3_mprintf("%d inserts, %d deletes", nInsert, nDelete);
         1358  +}
         1359  +
         1360  +static void dynamic_triggers(int nMs){
         1361  +  Error err = {0};
         1362  +  Sqlite db = {0};
         1363  +  Threadset threads = {0};
         1364  +
         1365  +  opendb(&err, &db, "test.db", 1);
         1366  +  sql_script(&err, &db, 
         1367  +      "PRAGMA page_size = 1024;"
         1368  +      "PRAGMA journal_mode = WAL;"
         1369  +      "CREATE TABLE t1(x, y);"
         1370  +      "CREATE TABLE t2(x, y);"
         1371  +      "CREATE TABLE t3(x, y);"
         1372  +      "CREATE TABLE t4(x, y);"
         1373  +      "CREATE TABLE t5(x, y);"
         1374  +      "CREATE TABLE t6(x, y);"
         1375  +      "CREATE TABLE t7(x, y);"
         1376  +      "CREATE TABLE t8(x, y);"
         1377  +      "CREATE TABLE t9(x, y);"
         1378  +  );
         1379  +
         1380  +  setstoptime(&err, nMs);
         1381  +
         1382  +  sqlite3_enable_shared_cache(1);
         1383  +  launch_thread(&err, &threads, dynamic_triggers_2, 0);
         1384  +  launch_thread(&err, &threads, dynamic_triggers_2, 0);
         1385  +  sqlite3_enable_shared_cache(0);
         1386  +
         1387  +  sleep(2);
         1388  +
         1389  +  launch_thread(&err, &threads, dynamic_triggers_2, 0);
         1390  +  launch_thread(&err, &threads, dynamic_triggers_1, 0);
         1391  +
         1392  +  join_all_threads(&err, &threads);
         1393  +
         1394  +  print_and_free_err(&err);
         1395  +}
         1396  +
  1274   1397   
  1275   1398   int main(int argc, char **argv){
  1276   1399     struct ThreadTest {
  1277   1400       void (*xTest)(int);
  1278   1401       const char *zTest;
  1279   1402       int nMs;
  1280   1403     } aTest[] = {
................................................................................
  1282   1405       { walthread2, "walthread2", 20000 },
  1283   1406       { walthread3, "walthread3", 20000 },
  1284   1407       { walthread4, "walthread4", 20000 },
  1285   1408       { walthread5, "walthread5",  1000 },
  1286   1409       { walthread5, "walthread5",  1000 },
  1287   1410       
  1288   1411       { cgt_pager_1, "cgt_pager_1", 0 },
         1412  +    { dynamic_triggers, "dynamic_triggers", 20000 },
  1289   1413     };
  1290   1414   
  1291   1415     int i;
  1292   1416     char *zTest = 0;
  1293   1417     int nTest = 0;
  1294   1418     int bTestfound = 0;
  1295   1419     int bPrefix = 0;