Annotation of embedaddon/sqlite3/test/triggerC.test, revision 1.1

1.1     ! misho       1: # 2009 August 24
        !             2: #
        !             3: # The author disclaims copyright to this source code.  In place of
        !             4: # a legal notice', here is a blessing:
        !             5: #
        !             6: #    May you do good and not evil.
        !             7: #    May you find forgiveness for yourself and forgive others.
        !             8: #    May you share freely, never taking more than you give.
        !             9: #
        !            10: #***********************************************************************
        !            11: #
        !            12: 
        !            13: set testdir [file dirname $argv0]
        !            14: source $testdir/tester.tcl
        !            15: ifcapable {!trigger} {
        !            16:   finish_test
        !            17:   return
        !            18: }
        !            19: 
        !            20: #-------------------------------------------------------------------------
        !            21: # Test organization:
        !            22: #
        !            23: # triggerC-1.*: Haphazardly designed trigger related tests that were useful
        !            24: #               during an upgrade of the triggers sub-system.
        !            25: # 
        !            26: # triggerC-2.*:
        !            27: #
        !            28: # triggerC-3.*:
        !            29: #
        !            30: # triggerC-4.*:
        !            31: #
        !            32: # triggerC-5.*: Test that when recursive triggers are enabled DELETE 
        !            33: #               triggers are fired when rows are deleted as part of OR
        !            34: #               REPLACE conflict resolution. And that they are not fired
        !            35: #               if recursive triggers are not enabled.
        !            36: #
        !            37: # triggerC-6.*: Test that the recursive_triggers pragma returns correct
        !            38: #               results when invoked without an argument.
        !            39: #
        !            40: 
        !            41: # Enable recursive triggers for this file.
        !            42: #
        !            43: execsql { PRAGMA recursive_triggers = on }
        !            44: 
        !            45: #sqlite3_db_config_lookaside db 0 0 0
        !            46: 
        !            47: #-------------------------------------------------------------------------
        !            48: # This block of tests, triggerC-1.*, are not aimed at any specific
        !            49: # property of the triggers sub-system. They were created to debug
        !            50: # specific problems while modifying SQLite to support recursive
        !            51: # triggers. They are left here in case they can help debug the
        !            52: # same problems again.
        !            53: #
        !            54: do_test triggerC-1.1 {
        !            55:   execsql {
        !            56:     CREATE TABLE t1(a, b, c);
        !            57:     CREATE TABLE log(t, a1, b1, c1, a2, b2, c2);
        !            58:     CREATE TRIGGER trig1 BEFORE INSERT ON t1 BEGIN
        !            59:       INSERT INTO log VALUES('before', NULL, NULL, NULL, new.a, new.b, new.c);
        !            60:     END;
        !            61:     CREATE TRIGGER trig2 AFTER INSERT ON t1 BEGIN
        !            62:       INSERT INTO log VALUES('after', NULL, NULL, NULL, new.a, new.b, new.c);
        !            63:     END;
        !            64:     CREATE TRIGGER trig3 BEFORE UPDATE ON t1 BEGIN
        !            65:       INSERT INTO log VALUES('before', old.a,old.b,old.c, new.a,new.b,new.c);
        !            66:     END;
        !            67:     CREATE TRIGGER trig4 AFTER UPDATE ON t1 BEGIN
        !            68:       INSERT INTO log VALUES('after', old.a,old.b,old.c, new.a,new.b,new.c);
        !            69:     END;
        !            70: 
        !            71:     CREATE TRIGGER trig5 BEFORE DELETE ON t1 BEGIN
        !            72:       INSERT INTO log VALUES('before', old.a,old.b,old.c, NULL,NULL,NULL);
        !            73:     END;
        !            74:     CREATE TRIGGER trig6 AFTER DELETE ON t1 BEGIN
        !            75:       INSERT INTO log VALUES('after', old.a,old.b,old.c, NULL,NULL,NULL);
        !            76:     END;
        !            77:   }
        !            78: } {}
        !            79: do_test triggerC-1.2 {
        !            80:   execsql {
        !            81:     INSERT INTO t1 VALUES('A', 'B', 'C');
        !            82:     SELECT * FROM log;
        !            83:   }
        !            84: } {before {} {} {} A B C after {} {} {} A B C}
        !            85: do_test triggerC-1.3 {
        !            86:   execsql { SELECT * FROM t1 }
        !            87: } {A B C}
        !            88: do_test triggerC-1.4 {
        !            89:   execsql {
        !            90:     DELETE FROM log;
        !            91:     UPDATE t1 SET a = 'a';
        !            92:     SELECT * FROM log;
        !            93:   }
        !            94: } {before A B C a B C after A B C a B C}
        !            95: do_test triggerC-1.5 {
        !            96:   execsql { SELECT * FROM t1 }
        !            97: } {a B C}
        !            98: do_test triggerC-1.6 {
        !            99:   execsql {
        !           100:     DELETE FROM log;
        !           101:     DELETE FROM t1;
        !           102:     SELECT * FROM log;
        !           103:   }
        !           104: } {before a B C {} {} {} after a B C {} {} {}}
        !           105: do_test triggerC-1.7 {
        !           106:   execsql { SELECT * FROM t1 }
        !           107: } {}
        !           108: do_test triggerC-1.8 {
        !           109:   execsql {
        !           110:     CREATE TABLE t4(a, b);
        !           111:     CREATE TRIGGER t4t AFTER DELETE ON t4 BEGIN
        !           112:       SELECT RAISE(ABORT, 'delete is not supported');
        !           113:     END;
        !           114:   }
        !           115: } {}
        !           116: do_test triggerC-1.9 {
        !           117:   execsql { INSERT INTO t4 VALUES(1, 2) }
        !           118:   catchsql { DELETE FROM t4 }
        !           119: } {1 {delete is not supported}}
        !           120: do_test triggerC-1.10 {
        !           121:   execsql { SELECT * FROM t4 }
        !           122: } {1 2}
        !           123: do_test triggerC-1.11 {
        !           124:   execsql {
        !           125:     CREATE TABLE t5 (a primary key, b, c);
        !           126:     INSERT INTO t5 values (1, 2, 3);
        !           127:     CREATE TRIGGER au_tbl AFTER UPDATE ON t5 BEGIN
        !           128:       UPDATE OR IGNORE t5 SET a = new.a, c = 10;
        !           129:     END;
        !           130:   }
        !           131: } {}
        !           132: do_test triggerC-1.12 {
        !           133:   catchsql { UPDATE OR REPLACE t5 SET a = 4 WHERE a = 1 }
        !           134: } {1 {too many levels of trigger recursion}}
        !           135: do_test triggerC-1.13 {
        !           136:   execsql {
        !           137:     CREATE TABLE t6(a INTEGER PRIMARY KEY, b);
        !           138:     INSERT INTO t6 VALUES(1, 2);
        !           139:     create trigger r1 after update on t6 for each row begin
        !           140:       SELECT 1;
        !           141:     end;
        !           142:     UPDATE t6 SET a=a; 
        !           143:   }
        !           144: } {}
        !           145: do_test triggerC-1.14 {
        !           146:   execsql {
        !           147:     DROP TABLE t1;
        !           148:     CREATE TABLE cnt(n);
        !           149:     INSERT INTO cnt VALUES(0);
        !           150:     CREATE TABLE t1(a INTEGER PRIMARY KEY, b UNIQUE, c, d, e);
        !           151:     CREATE INDEX t1cd ON t1(c,d);
        !           152:     CREATE TRIGGER t1r1 AFTER UPDATE ON t1 BEGIN UPDATE cnt SET n=n+1; END;
        !           153:     INSERT INTO t1 VALUES(1,2,3,4,5);
        !           154:     INSERT INTO t1 VALUES(6,7,8,9,10);
        !           155:     INSERT INTO t1 VALUES(11,12,13,14,15);
        !           156:   }
        !           157: } {}
        !           158: do_test triggerC-1.15 {
        !           159:   catchsql { UPDATE OR ROLLBACK t1 SET a=100 }
        !           160: } {1 {PRIMARY KEY must be unique}}
        !           161: 
        !           162: 
        !           163: #-------------------------------------------------------------------------
        !           164: # This block of tests, triggerC-2.*, tests that recursive trigger
        !           165: # programs (triggers that fire themselves) work. More specifically,
        !           166: # this block focuses on recursive INSERT triggers.
        !           167: #
        !           168: do_test triggerC-2.1.0 {
        !           169:   execsql {
        !           170:     CREATE TABLE t2(a PRIMARY KEY);
        !           171:   }
        !           172: } {}
        !           173: 
        !           174: foreach {n tdefn rc} {
        !           175:   1 { 
        !           176:     CREATE TRIGGER t2_trig AFTER INSERT ON t2 WHEN (new.a>0) BEGIN
        !           177:       INSERT INTO t2 VALUES(new.a - 1);
        !           178:     END; 
        !           179:   } {0 {10 9 8 7 6 5 4 3 2 1 0}}
        !           180: 
        !           181:   2 {
        !           182:     CREATE TRIGGER t2_trig AFTER INSERT ON t2 BEGIN
        !           183:       SELECT CASE WHEN new.a==2 THEN RAISE(IGNORE) ELSE NULL END;
        !           184:       INSERT INTO t2 VALUES(new.a - 1);
        !           185:     END;
        !           186:   } {0 {10 9 8 7 6 5 4 3 2}}
        !           187: 
        !           188:   3 { 
        !           189:     CREATE TRIGGER t2_trig BEFORE INSERT ON t2 WHEN (new.a>0) BEGIN
        !           190:       INSERT INTO t2 VALUES(new.a - 1);
        !           191:     END; 
        !           192:   } {0 {0 1 2 3 4 5 6 7 8 9 10}}
        !           193: 
        !           194:   4 { 
        !           195:     CREATE TRIGGER t2_trig BEFORE INSERT ON t2 BEGIN
        !           196:       SELECT CASE WHEN new.a==2 THEN RAISE(IGNORE) ELSE NULL END;
        !           197:       INSERT INTO t2 VALUES(new.a - 1);
        !           198:     END;
        !           199:   } {0 {3 4 5 6 7 8 9 10}}
        !           200: 
        !           201:   5 { 
        !           202:     CREATE TRIGGER t2_trig BEFORE INSERT ON t2 BEGIN
        !           203:       INSERT INTO t2 VALUES(new.a - 1);
        !           204:     END;
        !           205:   } {1 {too many levels of trigger recursion}}
        !           206: 
        !           207:   6 { 
        !           208:     CREATE TRIGGER t2_trig AFTER INSERT ON t2 WHEN (new.a>0) BEGIN
        !           209:       INSERT OR IGNORE INTO t2 VALUES(new.a);
        !           210:     END;
        !           211:   } {0 10}
        !           212: 
        !           213:   7 { 
        !           214:     CREATE TRIGGER t2_trig BEFORE INSERT ON t2 WHEN (new.a>0) BEGIN
        !           215:       INSERT OR IGNORE INTO t2 VALUES(new.a);
        !           216:     END;
        !           217:   } {1 {too many levels of trigger recursion}}
        !           218: } {
        !           219:   do_test triggerC-2.1.$n {
        !           220:     catchsql { DROP TRIGGER t2_trig }
        !           221:     execsql  { DELETE FROM t2 }
        !           222:     execsql  $tdefn
        !           223:     catchsql {
        !           224:       INSERT INTO t2 VALUES(10);
        !           225:       SELECT * FROM t2;
        !           226:     }
        !           227:   } $rc
        !           228: }
        !           229: 
        !           230: do_test triggerC-2.2 {
        !           231:   execsql "
        !           232:     CREATE TABLE t22(x);
        !           233: 
        !           234:     CREATE TRIGGER t22a AFTER INSERT ON t22 BEGIN
        !           235:       INSERT INTO t22 SELECT x + (SELECT max(x) FROM t22) FROM t22;
        !           236:     END;
        !           237:     CREATE TRIGGER t22b BEFORE INSERT ON t22 BEGIN
        !           238:       SELECT CASE WHEN (SELECT count(*) FROM t22) >= [expr $SQLITE_MAX_TRIGGER_DEPTH / 2]
        !           239:                   THEN RAISE(IGNORE)
        !           240:                   ELSE NULL END;
        !           241:     END;
        !           242: 
        !           243:     INSERT INTO t22 VALUES(1);
        !           244:     SELECT count(*) FROM t22;
        !           245:   "
        !           246: } [list [expr $SQLITE_MAX_TRIGGER_DEPTH / 2]]
        !           247: 
        !           248: do_test triggerC-2.3 {
        !           249:   execsql "
        !           250:     CREATE TABLE t23(x PRIMARY KEY);
        !           251: 
        !           252:     CREATE TRIGGER t23a AFTER INSERT ON t23 BEGIN
        !           253:       INSERT INTO t23 VALUES(new.x + 1);
        !           254:     END;
        !           255: 
        !           256:     CREATE TRIGGER t23b BEFORE INSERT ON t23 BEGIN
        !           257:       SELECT CASE WHEN new.x>[expr $SQLITE_MAX_TRIGGER_DEPTH / 2]
        !           258:                   THEN RAISE(IGNORE)
        !           259:                   ELSE NULL END;
        !           260:     END;
        !           261: 
        !           262:     INSERT INTO t23 VALUES(1);
        !           263:     SELECT count(*) FROM t23;
        !           264:   "
        !           265: } [list [expr $SQLITE_MAX_TRIGGER_DEPTH / 2]]
        !           266:  
        !           267: 
        !           268: #-----------------------------------------------------------------------
        !           269: # This block of tests, triggerC-3.*, test that SQLite throws an exception
        !           270: # when it detects excessive recursion.
        !           271: #
        !           272: do_test triggerC-3.1.1 {
        !           273:   execsql {
        !           274:     CREATE TABLE t3(a, b);
        !           275:     CREATE TRIGGER t3i AFTER INSERT ON t3 BEGIN
        !           276:       DELETE FROM t3 WHERE rowid = new.rowid;
        !           277:     END;
        !           278:     CREATE TRIGGER t3d AFTER DELETE ON t3 BEGIN
        !           279:       INSERT INTO t3 VALUES(old.a, old.b);
        !           280:     END;
        !           281:   }
        !           282: } {}
        !           283: do_test triggerC-3.1.2 {
        !           284:   catchsql { INSERT INTO t3 VALUES(0,0) }
        !           285: } {1 {too many levels of trigger recursion}}
        !           286: do_test triggerC-3.1.3 {
        !           287:   execsql { SELECT * FROM t3 }
        !           288: } {}
        !           289: 
        !           290: do_test triggerC-3.2.1 {
        !           291:   execsql "
        !           292:     CREATE TABLE t3b(x);
        !           293:     CREATE TRIGGER t3bi AFTER INSERT ON t3b WHEN new.x<[expr $SQLITE_MAX_TRIGGER_DEPTH * 2] BEGIN
        !           294:       INSERT INTO t3b VALUES(new.x+1);
        !           295:     END;
        !           296:   "
        !           297:   catchsql {
        !           298:     INSERT INTO t3b VALUES(1);
        !           299:   }
        !           300: } {1 {too many levels of trigger recursion}}
        !           301: do_test triggerC-3.2.2 {
        !           302:   db eval {SELECT * FROM t3b}
        !           303: } {}
        !           304: 
        !           305: do_test triggerC-3.3.1 {
        !           306:   catchsql "
        !           307:     INSERT INTO t3b VALUES([expr $SQLITE_MAX_TRIGGER_DEPTH + 1]);
        !           308:   "
        !           309: } {0 {}}
        !           310: do_test triggerC-3.3.2 {
        !           311:   db eval {SELECT count(*), max(x), min(x) FROM t3b}
        !           312: } [list $SQLITE_MAX_TRIGGER_DEPTH [expr $SQLITE_MAX_TRIGGER_DEPTH * 2] [expr $SQLITE_MAX_TRIGGER_DEPTH + 1]]
        !           313: 
        !           314: do_test triggerC-3.4.1 {
        !           315:   catchsql "
        !           316:     DELETE FROM t3b;
        !           317:     INSERT INTO t3b VALUES([expr $SQLITE_MAX_TRIGGER_DEPTH - 1]);
        !           318:   "
        !           319: } {1 {too many levels of trigger recursion}}
        !           320: do_test triggerC-3.4.2 {
        !           321:   db eval {SELECT count(*), max(x), min(x) FROM t3b}
        !           322: } {0 {} {}}
        !           323: 
        !           324: do_test triggerC-3.5.1 {
        !           325:   sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH  [expr $SQLITE_MAX_TRIGGER_DEPTH / 10]
        !           326:   catchsql "
        !           327:     INSERT INTO t3b VALUES([expr ($SQLITE_MAX_TRIGGER_DEPTH * 2) - ($SQLITE_MAX_TRIGGER_DEPTH / 10) + 1]);
        !           328:   "
        !           329: } {0 {}}
        !           330: do_test triggerC-3.5.2 {
        !           331:   db eval {SELECT count(*), max(x), min(x) FROM t3b}
        !           332: } [list [expr $SQLITE_MAX_TRIGGER_DEPTH / 10] [expr $SQLITE_MAX_TRIGGER_DEPTH * 2] [expr ($SQLITE_MAX_TRIGGER_DEPTH * 2) - ($SQLITE_MAX_TRIGGER_DEPTH / 10) + 1]]
        !           333: 
        !           334: do_test triggerC-3.5.3 {
        !           335:   catchsql "
        !           336:     DELETE FROM t3b;
        !           337:     INSERT INTO t3b VALUES([expr ($SQLITE_MAX_TRIGGER_DEPTH * 2) - ($SQLITE_MAX_TRIGGER_DEPTH / 10)]);
        !           338:   "
        !           339: } {1 {too many levels of trigger recursion}}
        !           340: do_test triggerC-3.5.4 {
        !           341:   db eval {SELECT count(*), max(x), min(x) FROM t3b}
        !           342: } {0 {} {}}
        !           343: 
        !           344: do_test triggerC-3.6.1 {
        !           345:   sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 1
        !           346:   catchsql "
        !           347:     INSERT INTO t3b VALUES([expr $SQLITE_MAX_TRIGGER_DEPTH * 2]);
        !           348:   "
        !           349: } {0 {}}
        !           350: do_test triggerC-3.6.2 {
        !           351:   db eval {SELECT count(*), max(x), min(x) FROM t3b}
        !           352: } [list 1 [expr $SQLITE_MAX_TRIGGER_DEPTH * 2] [expr $SQLITE_MAX_TRIGGER_DEPTH * 2]]
        !           353: 
        !           354: do_test triggerC-3.6.3 {
        !           355:   catchsql "
        !           356:     DELETE FROM t3b;
        !           357:     INSERT INTO t3b VALUES([expr ($SQLITE_MAX_TRIGGER_DEPTH * 2) - 1]);
        !           358:   "
        !           359: } {1 {too many levels of trigger recursion}}
        !           360: do_test triggerC-3.6.4 {
        !           361:   db eval {SELECT count(*), max(x), min(x) FROM t3b}
        !           362: } {0 {} {}}
        !           363: sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH $SQLITE_MAX_TRIGGER_DEPTH
        !           364: 
        !           365: 
        !           366: #-----------------------------------------------------------------------
        !           367: # This next block of tests, triggerC-4.*, checks that affinity 
        !           368: # transformations and constraint processing is performed at the correct 
        !           369: # times relative to BEFORE and AFTER triggers.
        !           370: #
        !           371: # For an INSERT statement, for each row to be inserted:
        !           372: #
        !           373: #   1. Apply affinities to non-rowid values to be inserted.
        !           374: #   2. Fire BEFORE triggers.
        !           375: #   3. Process constraints.
        !           376: #   4. Insert new record.
        !           377: #   5. Fire AFTER triggers.
        !           378: #
        !           379: # If the value of the rowid field is to be automatically assigned, it is
        !           380: # set to -1 in the new.* record. Even if it is explicitly set to NULL
        !           381: # by the INSERT statement.
        !           382: #
        !           383: # For an UPDATE statement, for each row to be deleted:
        !           384: #
        !           385: #   1. Apply affinities to non-rowid values to be inserted.
        !           386: #   2. Fire BEFORE triggers.
        !           387: #   3. Process constraints.
        !           388: #   4. Insert new record.
        !           389: #   5. Fire AFTER triggers.
        !           390: #
        !           391: # For a DELETE statement, for each row to be deleted:
        !           392: #
        !           393: #   1. Fire BEFORE triggers.
        !           394: #   2. Remove database record.
        !           395: #   3. Fire AFTER triggers.
        !           396: #
        !           397: # When a numeric value that as an exact integer representation is stored
        !           398: # in a column with REAL affinity, it is actually stored as an integer.
        !           399: # These tests check that the typeof() such values is always 'real',
        !           400: # not 'integer'.
        !           401: #
        !           402: # triggerC-4.1.*: Check that affinity transformations are made before
        !           403: #                 triggers are invoked.
        !           404: #
        !           405: do_test triggerC-4.1.1 {
        !           406:   catchsql { DROP TABLE log }
        !           407:   catchsql { DROP TABLE t4 }
        !           408:   execsql {
        !           409:     CREATE TABLE log(t);
        !           410:     CREATE TABLE t4(a TEXT,b INTEGER,c REAL);
        !           411:     CREATE TRIGGER t4bi BEFORE INSERT ON t4 BEGIN
        !           412:       INSERT INTO log VALUES(new.rowid || ' ' || typeof(new.rowid) || ' ' ||
        !           413:                              new.a     || ' ' || typeof(new.a)     || ' ' ||
        !           414:                              new.b     || ' ' || typeof(new.b)     || ' ' ||
        !           415:                              new.c     || ' ' || typeof(new.c)
        !           416:       );
        !           417:     END;
        !           418:     CREATE TRIGGER t4ai AFTER INSERT ON t4 BEGIN
        !           419:       INSERT INTO log VALUES(new.rowid || ' ' || typeof(new.rowid) || ' ' ||
        !           420:                              new.a     || ' ' || typeof(new.a)     || ' ' ||
        !           421:                              new.b     || ' ' || typeof(new.b)     || ' ' ||
        !           422:                              new.c     || ' ' || typeof(new.c)
        !           423:       );
        !           424:     END;
        !           425:     CREATE TRIGGER t4bd BEFORE DELETE ON t4 BEGIN
        !           426:       INSERT INTO log VALUES(old.rowid || ' ' || typeof(old.rowid) || ' ' ||
        !           427:                              old.a     || ' ' || typeof(old.a)     || ' ' ||
        !           428:                              old.b     || ' ' || typeof(old.b)     || ' ' ||
        !           429:                              old.c     || ' ' || typeof(old.c)
        !           430:       );
        !           431:     END;
        !           432:     CREATE TRIGGER t4ad AFTER DELETE ON t4 BEGIN
        !           433:       INSERT INTO log VALUES(old.rowid || ' ' || typeof(old.rowid) || ' ' ||
        !           434:                              old.a     || ' ' || typeof(old.a)     || ' ' ||
        !           435:                              old.b     || ' ' || typeof(old.b)     || ' ' ||
        !           436:                              old.c     || ' ' || typeof(old.c)
        !           437:       );
        !           438:     END;
        !           439:     CREATE TRIGGER t4bu BEFORE UPDATE ON t4 BEGIN
        !           440:       INSERT INTO log VALUES(old.rowid || ' ' || typeof(old.rowid) || ' ' ||
        !           441:                              old.a     || ' ' || typeof(old.a)     || ' ' ||
        !           442:                              old.b     || ' ' || typeof(old.b)     || ' ' ||
        !           443:                              old.c     || ' ' || typeof(old.c)
        !           444:       );
        !           445:       INSERT INTO log VALUES(new.rowid || ' ' || typeof(new.rowid) || ' ' ||
        !           446:                              new.a     || ' ' || typeof(new.a)     || ' ' ||
        !           447:                              new.b     || ' ' || typeof(new.b)     || ' ' ||
        !           448:                              new.c     || ' ' || typeof(new.c)
        !           449:       );
        !           450:     END;
        !           451:     CREATE TRIGGER t4au AFTER UPDATE ON t4 BEGIN
        !           452:       INSERT INTO log VALUES(old.rowid || ' ' || typeof(old.rowid) || ' ' ||
        !           453:                              old.a     || ' ' || typeof(old.a)     || ' ' ||
        !           454:                              old.b     || ' ' || typeof(old.b)     || ' ' ||
        !           455:                              old.c     || ' ' || typeof(old.c)
        !           456:       );
        !           457:       INSERT INTO log VALUES(new.rowid || ' ' || typeof(new.rowid) || ' ' ||
        !           458:                              new.a     || ' ' || typeof(new.a)     || ' ' ||
        !           459:                              new.b     || ' ' || typeof(new.b)     || ' ' ||
        !           460:                              new.c     || ' ' || typeof(new.c)
        !           461:       );
        !           462:     END;
        !           463:   }
        !           464: } {}
        !           465: foreach {n insert log} {
        !           466: 
        !           467:   2 { 
        !           468:    INSERT INTO t4 VALUES('1', '1', '1');
        !           469:    DELETE FROM t4;
        !           470:   } {
        !           471:     -1 integer 1 text 1 integer 1.0 real 
        !           472:      1 integer 1 text 1 integer 1.0 real
        !           473:      1 integer 1 text 1 integer 1.0 real 
        !           474:      1 integer 1 text 1 integer 1.0 real
        !           475:   }
        !           476: 
        !           477:   3 { 
        !           478:    INSERT INTO t4(rowid,a,b,c) VALUES(45, 45, 45, 45);
        !           479:    DELETE FROM t4;
        !           480:   } {
        !           481:     45 integer 45 text 45 integer 45.0 real
        !           482:     45 integer 45 text 45 integer 45.0 real
        !           483:     45 integer 45 text 45 integer 45.0 real
        !           484:     45 integer 45 text 45 integer 45.0 real
        !           485:   }
        !           486: 
        !           487:   4 { 
        !           488:    INSERT INTO t4(rowid,a,b,c) VALUES(-42.0, -42.0, -42.0, -42.0);
        !           489:    DELETE FROM t4;
        !           490:   } {
        !           491:     -42 integer -42.0 text -42 integer -42.0 real 
        !           492:     -42 integer -42.0 text -42 integer -42.0 real
        !           493:     -42 integer -42.0 text -42 integer -42.0 real 
        !           494:     -42 integer -42.0 text -42 integer -42.0 real
        !           495:   }
        !           496: 
        !           497:   5 { 
        !           498:    INSERT INTO t4(rowid,a,b,c) VALUES(NULL, -42.4, -42.4, -42.4);
        !           499:    DELETE FROM t4;
        !           500:   } {
        !           501:     -1 integer -42.4 text -42.4 real -42.4 real
        !           502:      1 integer -42.4 text -42.4 real -42.4 real
        !           503:      1 integer -42.4 text -42.4 real -42.4 real
        !           504:      1 integer -42.4 text -42.4 real -42.4 real
        !           505:   }
        !           506: 
        !           507:   6 { 
        !           508:    INSERT INTO t4 VALUES(7, 7, 7);
        !           509:    UPDATE t4 SET a=8, b=8, c=8;
        !           510:   } {
        !           511:     -1 integer 7 text 7 integer 7.0 real
        !           512:      1 integer 7 text 7 integer 7.0 real
        !           513:      1 integer 7 text 7 integer 7.0 real
        !           514:      1 integer 8 text 8 integer 8.0 real
        !           515:      1 integer 7 text 7 integer 7.0 real
        !           516:      1 integer 8 text 8 integer 8.0 real
        !           517:   }
        !           518: 
        !           519:   7 { 
        !           520:    UPDATE t4 SET rowid=2;
        !           521:   } {
        !           522:      1 integer 8 text 8 integer 8.0 real
        !           523:      2 integer 8 text 8 integer 8.0 real
        !           524:      1 integer 8 text 8 integer 8.0 real
        !           525:      2 integer 8 text 8 integer 8.0 real
        !           526:   }
        !           527: 
        !           528:   8 { 
        !           529:    UPDATE t4 SET a='9', b='9', c='9';
        !           530:   } {
        !           531:      2 integer 8 text 8 integer 8.0 real
        !           532:      2 integer 9 text 9 integer 9.0 real
        !           533:      2 integer 8 text 8 integer 8.0 real
        !           534:      2 integer 9 text 9 integer 9.0 real
        !           535:   }
        !           536: 
        !           537:   9 { 
        !           538:    UPDATE t4 SET a='9.1', b='9.1', c='9.1';
        !           539:   } {
        !           540:      2 integer 9   text 9   integer 9.0 real
        !           541:      2 integer 9.1 text 9.1 real    9.1 real
        !           542:      2 integer 9   text 9   integer 9.0 real
        !           543:      2 integer 9.1 text 9.1 real    9.1 real
        !           544:   }
        !           545: } {
        !           546:   do_test triggerC-4.1.$n {
        !           547:     eval concat [execsql " 
        !           548:       DELETE FROM log;
        !           549:       $insert ; 
        !           550:       SELECT * FROM log;
        !           551:     "]
        !           552:   } [join $log " "]
        !           553: } 
        !           554: 
        !           555: #-------------------------------------------------------------------------
        !           556: # This block of tests, triggerC-5.*, test that DELETE triggers are fired
        !           557: # if a row is deleted as a result of OR REPLACE conflict resolution.
        !           558: #
        !           559: do_test triggerC-5.1.0 {
        !           560:   execsql {
        !           561:     DROP TABLE IF EXISTS t5;
        !           562:     CREATE TABLE t5(a INTEGER PRIMARY KEY, b);
        !           563:     CREATE UNIQUE INDEX t5i ON t5(b);
        !           564:     INSERT INTO t5 VALUES(1, 'a');
        !           565:     INSERT INTO t5 VALUES(2, 'b');
        !           566:     INSERT INTO t5 VALUES(3, 'c');
        !           567: 
        !           568:     CREATE TABLE t5g(a, b, c);
        !           569:     CREATE TRIGGER t5t BEFORE DELETE ON t5 BEGIN
        !           570:       INSERT INTO t5g VALUES(old.a, old.b, (SELECT count(*) FROM t5));
        !           571:     END;
        !           572:   }
        !           573: } {}
        !           574: foreach {n dml t5g t5} {
        !           575:   1 "DELETE FROM t5 WHERE a=2"                        {2 b 3} {1 a 3 c}
        !           576:   2 "INSERT OR REPLACE INTO t5 VALUES(2, 'd')"        {2 b 3} {1 a 2 d 3 c}
        !           577:   3 "UPDATE OR REPLACE t5 SET a = 2 WHERE a = 3"      {2 b 3} {1 a 2 c}
        !           578:   4 "INSERT OR REPLACE INTO t5 VALUES(4, 'b')"        {2 b 3} {1 a 3 c 4 b}
        !           579:   5 "UPDATE OR REPLACE t5 SET b = 'b' WHERE b = 'c'"  {2 b 3} {1 a 3 b}
        !           580:   6 "INSERT OR REPLACE INTO t5 VALUES(2, 'c')"        {2 b 3 3 c 2} {1 a 2 c}
        !           581:   7 "UPDATE OR REPLACE t5 SET a=1, b='b' WHERE a = 3" {1 a 3 2 b 2} {1 b}
        !           582: } {
        !           583:   do_test triggerC-5.1.$n {
        !           584:     execsql "
        !           585:       BEGIN;
        !           586:         $dml ;
        !           587:         SELECT * FROM t5g;
        !           588:         SELECT * FROM t5;
        !           589:       ROLLBACK;
        !           590:     "
        !           591:   } [concat $t5g $t5]
        !           592: }
        !           593: do_test triggerC-5.2.0 {
        !           594:   execsql {
        !           595:     DROP TRIGGER t5t;
        !           596:     CREATE TRIGGER t5t AFTER DELETE ON t5 BEGIN
        !           597:       INSERT INTO t5g VALUES(old.a, old.b, (SELECT count(*) FROM t5));
        !           598:     END;
        !           599:   }
        !           600: } {}
        !           601: foreach {n dml t5g t5} {
        !           602:   1 "DELETE FROM t5 WHERE a=2"                        {2 b 2} {1 a 3 c}
        !           603:   2 "INSERT OR REPLACE INTO t5 VALUES(2, 'd')"        {2 b 2} {1 a 2 d 3 c}
        !           604:   3 "UPDATE OR REPLACE t5 SET a = 2 WHERE a = 3"      {2 b 2} {1 a 2 c}
        !           605:   4 "INSERT OR REPLACE INTO t5 VALUES(4, 'b')"        {2 b 2} {1 a 3 c 4 b}
        !           606:   5 "UPDATE OR REPLACE t5 SET b = 'b' WHERE b = 'c'"  {2 b 2} {1 a 3 b}
        !           607:   6 "INSERT OR REPLACE INTO t5 VALUES(2, 'c')"        {2 b 2 3 c 1} {1 a 2 c}
        !           608:   7 "UPDATE OR REPLACE t5 SET a=1, b='b' WHERE a = 3" {1 a 2 2 b 1} {1 b}
        !           609: } {
        !           610:   do_test triggerC-5.2.$n {
        !           611:     execsql "
        !           612:       BEGIN;
        !           613:         $dml ;
        !           614:         SELECT * FROM t5g;
        !           615:         SELECT * FROM t5;
        !           616:       ROLLBACK;
        !           617:     "
        !           618:   } [concat $t5g $t5]
        !           619: }
        !           620: do_test triggerC-5.3.0 {
        !           621:   execsql { PRAGMA recursive_triggers = off }
        !           622: } {}
        !           623: foreach {n dml t5g t5} {
        !           624:   1 "DELETE FROM t5 WHERE a=2"                        {2 b 2} {1 a 3 c}
        !           625:   2 "INSERT OR REPLACE INTO t5 VALUES(2, 'd')"        {} {1 a 2 d 3 c}
        !           626:   3 "UPDATE OR REPLACE t5 SET a = 2 WHERE a = 3"      {} {1 a 2 c}
        !           627:   4 "INSERT OR REPLACE INTO t5 VALUES(4, 'b')"        {} {1 a 3 c 4 b}
        !           628:   5 "UPDATE OR REPLACE t5 SET b = 'b' WHERE b = 'c'"  {} {1 a 3 b}
        !           629:   6 "INSERT OR REPLACE INTO t5 VALUES(2, 'c')"        {} {1 a 2 c}
        !           630:   7 "UPDATE OR REPLACE t5 SET a=1, b='b' WHERE a = 3" {} {1 b}
        !           631: } {
        !           632:   do_test triggerC-5.3.$n {
        !           633:     execsql "
        !           634:       BEGIN;
        !           635:         $dml ;
        !           636:         SELECT * FROM t5g;
        !           637:         SELECT * FROM t5;
        !           638:       ROLLBACK;
        !           639:     "
        !           640:   } [concat $t5g $t5]
        !           641: }
        !           642: do_test triggerC-5.3.8 {
        !           643:   execsql { PRAGMA recursive_triggers = on }
        !           644: } {}
        !           645: 
        !           646: #-------------------------------------------------------------------------
        !           647: # This block of tests, triggerC-6.*, tests that "PRAGMA recursive_triggers"
        !           648: # statements return the current value of the recursive triggers flag.
        !           649: #
        !           650: do_test triggerC-6.1 {
        !           651:   execsql { PRAGMA recursive_triggers }
        !           652: } {1}
        !           653: do_test triggerC-6.2 {
        !           654:   execsql { 
        !           655:     PRAGMA recursive_triggers = off;
        !           656:     PRAGMA recursive_triggers;
        !           657:   }
        !           658: } {0}
        !           659: do_test triggerC-6.3 {
        !           660:   execsql { 
        !           661:     PRAGMA recursive_triggers = on;
        !           662:     PRAGMA recursive_triggers;
        !           663:   }
        !           664: } {1}
        !           665: 
        !           666: #-------------------------------------------------------------------------
        !           667: # Test some of the "undefined behaviour" associated with triggers. The
        !           668: # undefined behaviour occurs when a row being updated or deleted is 
        !           669: # manipulated by a BEFORE trigger.
        !           670: # 
        !           671: do_test triggerC-7.1 {
        !           672:   execsql {
        !           673:     CREATE TABLE t8(x);
        !           674:     CREATE TABLE t7(a, b);
        !           675:     INSERT INTO t7 VALUES(1, 2);
        !           676:     INSERT INTO t7 VALUES(3, 4);
        !           677:     INSERT INTO t7 VALUES(5, 6);
        !           678:     CREATE TRIGGER t7t BEFORE UPDATE ON t7 BEGIN
        !           679:       DELETE FROM t7 WHERE a = 1;
        !           680:     END;
        !           681:     CREATE TRIGGER t7ta AFTER UPDATE ON t7 BEGIN
        !           682:       INSERT INTO t8 VALUES('after fired ' || old.rowid || '->' || new.rowid);
        !           683:     END;
        !           684:   }
        !           685: } {}
        !           686: do_test triggerC-7.2 {
        !           687:   execsql {
        !           688:     BEGIN;
        !           689:       UPDATE t7 SET b=7 WHERE a = 5;
        !           690:       SELECT * FROM t7;
        !           691:       SELECT * FROM t8;
        !           692:     ROLLBACK;
        !           693:   }
        !           694: } {3 4 5 7 {after fired 3->3}}
        !           695: do_test triggerC-7.3 {
        !           696:   execsql {
        !           697:     BEGIN;
        !           698:       UPDATE t7 SET b=7 WHERE a = 1;
        !           699:       SELECT * FROM t7;
        !           700:       SELECT * FROM t8;
        !           701:     ROLLBACK;
        !           702:   }
        !           703: } {3 4 5 6}
        !           704: 
        !           705: do_test triggerC-7.4 {
        !           706:   execsql {
        !           707:     DROP TRIGGER t7t;
        !           708:     CREATE TRIGGER t7t BEFORE UPDATE ON t7 WHEN (old.rowid!=1 OR new.rowid!=8)
        !           709:     BEGIN
        !           710:       UPDATE t7 set rowid = 8 WHERE rowid=1;
        !           711:     END;
        !           712:   }
        !           713: } {}
        !           714: do_test triggerC-7.5 {
        !           715:   execsql {
        !           716:     BEGIN;
        !           717:       UPDATE t7 SET b=7 WHERE a = 5;
        !           718:       SELECT rowid, * FROM t7;
        !           719:       SELECT * FROM t8;
        !           720:     ROLLBACK;
        !           721:   }
        !           722: } {2 3 4 3 5 7 8 1 2 {after fired 1->8} {after fired 3->3}}
        !           723: do_test triggerC-7.6 {
        !           724:   execsql {
        !           725:     BEGIN;
        !           726:       UPDATE t7 SET b=7 WHERE a = 1;
        !           727:       SELECT rowid, * FROM t7;
        !           728:       SELECT * FROM t8;
        !           729:     ROLLBACK;
        !           730:   }
        !           731: } {2 3 4 3 5 6 8 1 2 {after fired 1->8}}
        !           732: 
        !           733: do_test triggerC-7.7 {
        !           734:   execsql {
        !           735:     DROP TRIGGER t7t;
        !           736:     DROP TRIGGER t7ta;
        !           737:     CREATE TRIGGER t7t BEFORE DELETE ON t7 BEGIN
        !           738:       UPDATE t7 set rowid = 8 WHERE rowid=1;
        !           739:     END;
        !           740:     CREATE TRIGGER t7ta AFTER DELETE ON t7 BEGIN
        !           741:       INSERT INTO t8 VALUES('after fired ' || old.rowid);
        !           742:     END;
        !           743:   }
        !           744: } {}
        !           745: do_test triggerC-7.8 {
        !           746:   execsql {
        !           747:     BEGIN;
        !           748:       DELETE FROM t7 WHERE a = 3;
        !           749:       SELECT rowid, * FROM t7;
        !           750:       SELECT * FROM t8;
        !           751:     ROLLBACK;
        !           752:   }
        !           753: } {3 5 6 8 1 2 {after fired 2}}
        !           754: do_test triggerC-7.9 {
        !           755:   execsql {
        !           756:     BEGIN;
        !           757:       DELETE FROM t7 WHERE a = 1;
        !           758:       SELECT rowid, * FROM t7;
        !           759:       SELECT * FROM t8;
        !           760:     ROLLBACK;
        !           761:   }
        !           762: } {2 3 4 3 5 6 8 1 2}
        !           763: 
        !           764: # Ticket [e25d9ea771febc9c311928c1c01c3163dcb26643]
        !           765: # 
        !           766: do_test triggerC-9.1 {
        !           767:   execsql {
        !           768:     CREATE TABLE t9(a,b);
        !           769:     CREATE INDEX t9b ON t9(b);
        !           770:     INSERT INTO t9 VALUES(1,0);
        !           771:     INSERT INTO t9 VALUES(2,1);
        !           772:     INSERT INTO t9 VALUES(3,2);
        !           773:     INSERT INTO t9 SELECT a+3, a+2 FROM t9;
        !           774:     INSERT INTO t9 SELECT a+6, a+5 FROM t9;
        !           775:     SELECT a FROM t9 ORDER BY a;
        !           776:   }
        !           777: } {1 2 3 4 5 6 7 8 9 10 11 12}
        !           778: do_test triggerC-9.2 {
        !           779:   execsql {
        !           780:     CREATE TRIGGER t9r1 AFTER DELETE ON t9 BEGIN
        !           781:       DELETE FROM t9 WHERE b=old.a;
        !           782:     END;
        !           783:     DELETE FROM t9 WHERE b=4;
        !           784:     SELECT a FROM t9 ORDER BY a;
        !           785:   }
        !           786: } {1 2 3 4}
        !           787: 
        !           788: # At one point (between versions 3.6.18 and 3.6.20 inclusive), an UPDATE 
        !           789: # that fired a BEFORE trigger that itself updated the same row as the 
        !           790: # statement causing it to fire was causing a strange side-effect: The 
        !           791: # values updated by the statement within the trigger were being overwritten 
        !           792: # by the values in the new.* array, even if those values were not 
        !           793: # themselves written by the parent UPDATE statement.
        !           794: #
        !           795: # Technically speaking this was not a bug. The SQLite documentation says
        !           796: # that if a BEFORE UPDATE or BEFORE DELETE trigger modifies or deletes the
        !           797: # row that the parent statement is operating on the results are undefined. 
        !           798: # But as of 3.6.21 behaviour is restored to the way it was in versions
        !           799: # 3.6.17 and earlier to avoid causing unnecessary difficulties.
        !           800: #
        !           801: do_test triggerC-10.1 {
        !           802:   execsql {
        !           803:     CREATE TABLE t10(a, updatecnt DEFAULT 0);
        !           804:     CREATE TRIGGER t10_bu BEFORE UPDATE OF a ON t10 BEGIN
        !           805:       UPDATE t10 SET updatecnt = updatecnt+1 WHERE rowid = old.rowid;
        !           806:     END;
        !           807:     INSERT INTO t10(a) VALUES('hello');
        !           808:   }
        !           809: 
        !           810:   # Before the problem was fixed, table t10 would contain the tuple 
        !           811:   # (world, 0) after running the following script (because the value
        !           812:   # 1 written to column "updatecnt" was clobbered by the old value 0).
        !           813:   #
        !           814:   execsql {
        !           815:     UPDATE t10 SET a = 'world';
        !           816:     SELECT * FROM t10;
        !           817:   }
        !           818: } {world 1}
        !           819: 
        !           820: do_test triggerC-10.2 {
        !           821:   execsql {
        !           822:     UPDATE t10 SET a = 'tcl', updatecnt = 5;
        !           823:     SELECT * FROM t10;
        !           824:   }
        !           825: } {tcl 5}
        !           826: 
        !           827: do_test triggerC-10.3 {
        !           828:   execsql {
        !           829:     CREATE TABLE t11(
        !           830:       c1,   c2,  c3,  c4,  c5,  c6,  c7,  c8,  c9, c10,
        !           831:       c11, c12, c13, c14, c15, c16, c17, c18, c19, c20,
        !           832:       c21, c22, c23, c24, c25, c26, c27, c28, c29, c30,
        !           833:       c31, c32, c33, c34, c35, c36, c37, c38, c39, c40
        !           834:     );
        !           835: 
        !           836:     CREATE TRIGGER t11_bu BEFORE UPDATE OF c1 ON t11 BEGIN
        !           837:       UPDATE t11 SET c31 = c31+1, c32=c32+1 WHERE rowid = old.rowid;
        !           838:     END;
        !           839: 
        !           840:     INSERT INTO t11 VALUES(
        !           841:       1,   2,  3,  4,  5,  6,  7,  8,  9, 10,
        !           842:       11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
        !           843:       21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
        !           844:       31, 32, 33, 34, 35, 36, 37, 38, 39, 40
        !           845:     );
        !           846:   }
        !           847: 
        !           848:   # Before the problem was fixed, table t10 would contain the tuple 
        !           849:   # (world, 0) after running the following script (because the value
        !           850:   # 1 written to column "updatecnt" was clobbered by the old value 0).
        !           851:   #
        !           852:   execsql {
        !           853:     UPDATE t11 SET c4=35, c33=22, c1=5;
        !           854:     SELECT * FROM t11;
        !           855:   } 
        !           856: } {5 2 3 35 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 32 33 22 34 35 36 37 38 39 40}
        !           857: 
        !           858: #-------------------------------------------------------------------------
        !           859: # Test that bug [371bab5d65] has been fixed. BEFORE INSERT and INSTEAD OF
        !           860: # INSERT triggers with the DEFAULT VALUES INSERT syntax.
        !           861: #
        !           862: do_test triggerC-11.0 {
        !           863:   catchsql { DROP TABLE log }
        !           864:   execsql  { CREATE TABLE log(a, b) }
        !           865: } {}
        !           866: 
        !           867: foreach {testno tbl defaults} {
        !           868:   1 "CREATE TABLE t1(a, b)"                          {{} {}}
        !           869:   2 "CREATE TABLE t1(a DEFAULT 1, b DEFAULT 'abc')"  {1 abc}
        !           870:   3 "CREATE TABLE t1(a, b DEFAULT 4.5)"              {{} 4.5}
        !           871: } {
        !           872:   do_test triggerC-11.$testno.1 {
        !           873:     catchsql { DROP TABLE t1 }
        !           874:     execsql { DELETE FROM log }
        !           875:     execsql $tbl
        !           876:     execsql {
        !           877:       CREATE TRIGGER tt1 BEFORE INSERT ON t1 BEGIN 
        !           878:         INSERT INTO log VALUES(new.a, new.b);
        !           879:       END;
        !           880:       INSERT INTO t1 DEFAULT VALUES;
        !           881:       SELECT * FROM log;
        !           882:     }
        !           883:   } $defaults
        !           884: 
        !           885:   do_test triggerC-11.$testno.2 {
        !           886:     execsql { DELETE FROM log }
        !           887:     execsql {
        !           888:       CREATE TRIGGER tt2 AFTER INSERT ON t1 BEGIN 
        !           889:         INSERT INTO log VALUES(new.a, new.b);
        !           890:       END;
        !           891:       INSERT INTO t1 DEFAULT VALUES;
        !           892:       SELECT * FROM log;
        !           893:     }
        !           894:   } [concat $defaults $defaults]
        !           895: 
        !           896:   do_test triggerC-11.$testno.3 {
        !           897:     execsql { DROP TRIGGER tt1 }
        !           898:     execsql { DELETE FROM log }
        !           899:     execsql {
        !           900:       INSERT INTO t1 DEFAULT VALUES;
        !           901:       SELECT * FROM log;
        !           902:     }
        !           903:   } $defaults
        !           904: } 
        !           905: do_test triggerC-11.4 {
        !           906:   catchsql { DROP TABLE t2 }
        !           907:   execsql {
        !           908:     DELETE FROM log;
        !           909:     CREATE TABLE t2(a, b);
        !           910:     CREATE VIEW v2 AS SELECT * FROM t2;
        !           911:     CREATE TRIGGER tv2 INSTEAD OF INSERT ON v2 BEGIN
        !           912:       INSERT INTO log VALUES(new.a, new.b);
        !           913:     END;
        !           914:     INSERT INTO v2 DEFAULT VALUES;
        !           915:     SELECT a, b, a IS NULL, b IS NULL FROM log;
        !           916:   }
        !           917: } {{} {} 1 1}
        !           918: 
        !           919: do_test triggerC-12.1 {
        !           920:   db close
        !           921:   forcedelete test.db
        !           922:   sqlite3 db test.db
        !           923: 
        !           924:   execsql {
        !           925:     CREATE TABLE t1(a, b);
        !           926:     INSERT INTO t1 VALUES(1, 2);
        !           927:     INSERT INTO t1 VALUES(3, 4);
        !           928:     INSERT INTO t1 VALUES(5, 6);
        !           929:     CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN SELECT 1 ; END ;
        !           930:     SELECT count(*) FROM sqlite_master;
        !           931:   }
        !           932: } {2}
        !           933: do_test triggerC-12.2 {
        !           934:   db eval { SELECT * FROM t1 } {
        !           935:     if {$a == 3} { execsql { DROP TRIGGER tr1 } }
        !           936:   }
        !           937:   execsql { SELECT count(*) FROM sqlite_master }
        !           938: } {1}
        !           939: 
        !           940: do_execsql_test triggerC-13.1 {
        !           941:   PRAGMA recursive_triggers = ON;
        !           942:   CREATE TABLE t12(a, b);
        !           943:   INSERT INTO t12 VALUES(1, 2);
        !           944:   CREATE TRIGGER tr12 AFTER UPDATE ON t12 BEGIN
        !           945:     UPDATE t12 SET a=new.a+1, b=new.b+1;
        !           946:   END;
        !           947: } {}
        !           948: do_catchsql_test triggerC-13.2 {
        !           949:   UPDATE t12 SET a=a+1, b=b+1;
        !           950: } {1 {too many levels of trigger recursion}}
        !           951: 
        !           952: 
        !           953: 
        !           954: finish_test

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>