Home | History | Annotate | Download | only in test
      1 # The author disclaims copyright to this source code.  In place of
      2 # a legal notice, here is a blessing:
      3 #
      4 #    May you do good and not evil.
      5 #    May you find forgiveness for yourself and forgive others.
      6 #    May you share freely, never taking more than you give.
      7 #
      8 #***********************************************************************
      9 #
     10 # Regression testing of FOR EACH ROW table triggers
     11 #
     12 # 1. Trigger execution order tests. 
     13 # These tests ensure that BEFORE and AFTER triggers are fired at the correct
     14 # times relative to each other and the triggering statement. 
     15 #
     16 # trigger2-1.1.*: ON UPDATE trigger execution model.
     17 # trigger2-1.2.*: DELETE trigger execution model.
     18 # trigger2-1.3.*: INSERT trigger execution model.
     19 #
     20 # 2. Trigger program execution tests.
     21 # These tests ensure that trigger programs execute correctly (ie. that a
     22 # trigger program can correctly execute INSERT, UPDATE, DELETE * SELECT
     23 # statements, and combinations thereof).
     24 #
     25 # 3. Selective trigger execution 
     26 # This tests that conditional triggers (ie. UPDATE OF triggers and triggers
     27 # with WHEN clauses) are fired only fired when they are supposed to be.
     28 #
     29 # trigger2-3.1: UPDATE OF triggers
     30 # trigger2-3.2: WHEN clause
     31 #
     32 # 4. Cascaded trigger execution 
     33 # Tests that trigger-programs may cause other triggers to fire. Also that a 
     34 # trigger-program is never executed recursively.
     35 # 
     36 # trigger2-4.1: Trivial cascading trigger
     37 # trigger2-4.2: Trivial recursive trigger handling 
     38 #
     39 # 5. Count changes behaviour.
     40 # Verify that rows altered by triggers are not included in the return value
     41 # of the "count changes" interface.
     42 #
     43 # 6. ON CONFLICT clause handling
     44 # trigger2-6.1[a-f]: INSERT statements
     45 # trigger2-6.2[a-f]: UPDATE statements
     46 #
     47 # 7. & 8. Triggers on views fire correctly.
     48 #
     49 
     50 set testdir [file dirname $argv0]
     51 source $testdir/tester.tcl
     52 ifcapable {!trigger} {
     53   finish_test
     54   return
     55 }
     56 
     57 # The tests in this file were written before SQLite supported recursive
     58 # trigger invocation, and some tests depend on that to pass. So disable
     59 # recursive triggers for this file.
     60 catchsql { pragma recursive_triggers = off } 
     61 
     62 # 1.
     63 ifcapable subquery {
     64   set ii 0
     65   set tbl_definitions [list \
     66   	{CREATE TABLE tbl (a, b);}                                      \
     67   	{CREATE TABLE tbl (a INTEGER PRIMARY KEY, b);}                  \
     68         {CREATE TABLE tbl (a, b PRIMARY KEY);}                          \
     69   	{CREATE TABLE tbl (a, b); CREATE INDEX tbl_idx ON tbl(b);}      \
     70   ]
     71   ifcapable tempdb {
     72     lappend tbl_definitions \
     73         {CREATE TEMP TABLE tbl (a, b); CREATE INDEX tbl_idx ON tbl(b);} 
     74     lappend tbl_definitions {CREATE TEMP TABLE tbl (a, b);}
     75     lappend tbl_definitions \
     76         {CREATE TEMPORARY TABLE tbl (a INTEGER PRIMARY KEY, b);}
     77   }
     78   foreach tbl_defn $tbl_definitions {
     79     incr ii
     80     catchsql { DROP INDEX tbl_idx; }
     81     catchsql {
     82       DROP TABLE rlog;
     83       DROP TABLE clog;
     84       DROP TABLE tbl;
     85       DROP TABLE other_tbl;
     86     }
     87   
     88     execsql $tbl_defn
     89   
     90     execsql {
     91       INSERT INTO tbl VALUES(1, 2);
     92       INSERT INTO tbl VALUES(3, 4);
     93   
     94       CREATE TABLE rlog (idx, old_a, old_b, db_sum_a, db_sum_b, new_a, new_b);
     95       CREATE TABLE clog (idx, old_a, old_b, db_sum_a, db_sum_b, new_a, new_b);
     96   
     97       CREATE TRIGGER before_update_row BEFORE UPDATE ON tbl FOR EACH ROW 
     98         BEGIN
     99         INSERT INTO rlog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM rlog), 
    100   	  old.a, old.b, 
    101   	  (SELECT coalesce(sum(a),0) FROM tbl),
    102           (SELECT coalesce(sum(b),0) FROM tbl), 
    103   	  new.a, new.b);
    104       END;
    105   
    106       CREATE TRIGGER after_update_row AFTER UPDATE ON tbl FOR EACH ROW 
    107         BEGIN
    108         INSERT INTO rlog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM rlog), 
    109   	  old.a, old.b, 
    110   	  (SELECT coalesce(sum(a),0) FROM tbl),
    111           (SELECT coalesce(sum(b),0) FROM tbl), 
    112   	  new.a, new.b);
    113       END;
    114   
    115       CREATE TRIGGER conditional_update_row AFTER UPDATE ON tbl FOR EACH ROW
    116         WHEN old.a = 1
    117         BEGIN
    118         INSERT INTO clog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM clog), 
    119   	  old.a, old.b, 
    120   	  (SELECT coalesce(sum(a),0) FROM tbl),
    121           (SELECT coalesce(sum(b),0) FROM tbl), 
    122   	  new.a, new.b);
    123       END;
    124     }
    125   
    126     do_test trigger2-1.$ii.1 {
    127       set r {}
    128       foreach v [execsql { 
    129         UPDATE tbl SET a = a * 10, b = b * 10;
    130         SELECT * FROM rlog ORDER BY idx;
    131         SELECT * FROM clog ORDER BY idx;
    132       }] {
    133         lappend r [expr {int($v)}]
    134       }
    135       set r
    136     } [list 1 1 2  4  6 10 20 \
    137             2 1 2 13 24 10 20 \
    138   	    3 3 4 13 24 30 40 \
    139   	    4 3 4 40 60 30 40 \
    140             1 1 2 13 24 10 20 ]
    141   
    142     execsql {
    143       DELETE FROM rlog;
    144       DELETE FROM tbl;
    145       INSERT INTO tbl VALUES (100, 100);
    146       INSERT INTO tbl VALUES (300, 200);
    147       CREATE TRIGGER delete_before_row BEFORE DELETE ON tbl FOR EACH ROW
    148         BEGIN
    149         INSERT INTO rlog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM rlog), 
    150   	  old.a, old.b, 
    151   	  (SELECT coalesce(sum(a),0) FROM tbl),
    152           (SELECT coalesce(sum(b),0) FROM tbl), 
    153   	  0, 0);
    154       END;
    155   
    156       CREATE TRIGGER delete_after_row AFTER DELETE ON tbl FOR EACH ROW
    157         BEGIN
    158         INSERT INTO rlog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM rlog), 
    159   	  old.a, old.b, 
    160   	  (SELECT coalesce(sum(a),0) FROM tbl),
    161           (SELECT coalesce(sum(b),0) FROM tbl), 
    162   	  0, 0);
    163       END;
    164     }
    165     do_test trigger2-1.$ii.2 {
    166       set r {}
    167       foreach v [execsql {
    168         DELETE FROM tbl;
    169         SELECT * FROM rlog;
    170       }] {
    171         lappend r [expr {int($v)}]
    172       }
    173       set r
    174     } [list 1 100 100 400 300 0 0 \
    175             2 100 100 300 200 0 0 \
    176             3 300 200 300 200 0 0 \
    177             4 300 200 0 0 0 0 ]
    178   
    179     execsql {
    180       DELETE FROM rlog;
    181       CREATE TRIGGER insert_before_row BEFORE INSERT ON tbl FOR EACH ROW
    182         BEGIN
    183         INSERT INTO rlog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM rlog), 
    184   	  0, 0,
    185   	  (SELECT coalesce(sum(a),0) FROM tbl),
    186           (SELECT coalesce(sum(b),0) FROM tbl), 
    187   	  new.a, new.b);
    188       END;
    189   
    190       CREATE TRIGGER insert_after_row AFTER INSERT ON tbl FOR EACH ROW
    191         BEGIN
    192         INSERT INTO rlog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM rlog), 
    193   	  0, 0,
    194   	  (SELECT coalesce(sum(a),0) FROM tbl),
    195           (SELECT coalesce(sum(b),0) FROM tbl), 
    196   	  new.a, new.b);
    197       END;
    198     }
    199     do_test trigger2-1.$ii.3 {
    200       execsql {
    201   
    202         CREATE TABLE other_tbl(a, b);
    203         INSERT INTO other_tbl VALUES(1, 2);
    204         INSERT INTO other_tbl VALUES(3, 4);
    205         -- INSERT INTO tbl SELECT * FROM other_tbl;
    206         INSERT INTO tbl VALUES(5, 6);
    207         DROP TABLE other_tbl;
    208   
    209         SELECT * FROM rlog;
    210       }
    211     } [list 1 0 0 0 0 5 6 \
    212             2 0 0 5 6 5 6 ]
    213   
    214     integrity_check trigger2-1.$ii.4
    215   }
    216   catchsql {
    217     DROP TABLE rlog;
    218     DROP TABLE clog;
    219     DROP TABLE tbl;
    220     DROP TABLE other_tbl;
    221   }
    222 }
    223 
    224 # 2.
    225 set ii 0
    226 foreach tr_program {
    227   {UPDATE tbl SET b = old.b;}
    228   {INSERT INTO log VALUES(new.c, 2, 3);}
    229   {DELETE FROM log WHERE a = 1;}
    230   {INSERT INTO tbl VALUES(500, new.b * 10, 700); 
    231     UPDATE tbl SET c = old.c; 
    232     DELETE FROM log;}
    233   {INSERT INTO log select * from tbl;} 
    234 } {
    235   foreach test_varset [ list \
    236     {
    237       set statement {UPDATE tbl SET c = 10 WHERE a = 1;} 
    238       set prep      {INSERT INTO tbl VALUES(1, 2, 3);}
    239       set newC 10
    240       set newB 2
    241       set newA 1
    242       set oldA 1
    243       set oldB 2
    244       set oldC 3
    245     } \
    246     {
    247       set statement {DELETE FROM tbl WHERE a = 1;}
    248       set prep      {INSERT INTO tbl VALUES(1, 2, 3);}
    249       set oldA 1
    250       set oldB 2
    251       set oldC 3
    252     } \
    253     {
    254       set statement {INSERT INTO tbl VALUES(1, 2, 3);}
    255       set newA 1
    256       set newB 2
    257       set newC 3
    258     }
    259   ] \
    260   {
    261     set statement {}
    262     set prep {}
    263     set newA {''}
    264     set newB {''}
    265     set newC {''}
    266     set oldA {''}
    267     set oldB {''}
    268     set oldC {''}
    269 
    270     incr ii
    271 
    272     eval $test_varset
    273 
    274     set statement_type [string range $statement 0 5]
    275     set tr_program_fixed $tr_program
    276     if {$statement_type == "DELETE"} {
    277       regsub -all new\.a $tr_program_fixed {''} tr_program_fixed 
    278       regsub -all new\.b $tr_program_fixed {''} tr_program_fixed 
    279       regsub -all new\.c $tr_program_fixed {''} tr_program_fixed 
    280     }
    281     if {$statement_type == "INSERT"} {
    282       regsub -all old\.a $tr_program_fixed {''} tr_program_fixed 
    283       regsub -all old\.b $tr_program_fixed {''} tr_program_fixed 
    284       regsub -all old\.c $tr_program_fixed {''} tr_program_fixed 
    285     }
    286 
    287 
    288     set tr_program_cooked $tr_program
    289     regsub -all new\.a $tr_program_cooked $newA tr_program_cooked 
    290     regsub -all new\.b $tr_program_cooked $newB tr_program_cooked 
    291     regsub -all new\.c $tr_program_cooked $newC tr_program_cooked 
    292     regsub -all old\.a $tr_program_cooked $oldA tr_program_cooked 
    293     regsub -all old\.b $tr_program_cooked $oldB tr_program_cooked 
    294     regsub -all old\.c $tr_program_cooked $oldC tr_program_cooked 
    295 
    296     catchsql {
    297       DROP TABLE tbl;
    298       DROP TABLE log;
    299     }
    300 
    301     execsql {
    302       CREATE TABLE tbl(a PRIMARY KEY, b, c);
    303       CREATE TABLE log(a, b, c);
    304     }
    305 
    306     set query {SELECT * FROM tbl; SELECT * FROM log;}
    307     set prep "$prep; INSERT INTO log VALUES(1, 2, 3);\
    308              INSERT INTO log VALUES(10, 20, 30);"
    309 
    310 # Check execution of BEFORE programs:
    311 
    312     set before_data [ execsql "$prep $tr_program_cooked $statement $query" ]
    313 
    314     execsql "DELETE FROM tbl; DELETE FROM log; $prep";
    315     execsql "CREATE TRIGGER the_trigger BEFORE [string range $statement 0 6]\
    316              ON tbl BEGIN $tr_program_fixed END;"
    317 
    318     do_test trigger2-2.$ii-before "execsql {$statement $query}" $before_data
    319 
    320     execsql "DROP TRIGGER the_trigger;"
    321     execsql "DELETE FROM tbl; DELETE FROM log;"
    322 
    323 # Check execution of AFTER programs
    324     set after_data [ execsql "$prep $statement $tr_program_cooked $query" ]
    325 
    326     execsql "DELETE FROM tbl; DELETE FROM log; $prep";
    327     execsql "CREATE TRIGGER the_trigger AFTER [string range $statement 0 6]\
    328              ON tbl BEGIN $tr_program_fixed END;"
    329 
    330     do_test trigger2-2.$ii-after "execsql {$statement $query}" $after_data
    331     execsql "DROP TRIGGER the_trigger;"
    332 
    333     integrity_check trigger2-2.$ii-integrity
    334   }
    335 }
    336 catchsql {
    337   DROP TABLE tbl;
    338   DROP TABLE log;
    339 }
    340 
    341 # 3.
    342 
    343 # trigger2-3.1: UPDATE OF triggers
    344 execsql {
    345   CREATE TABLE tbl (a, b, c, d);
    346   CREATE TABLE log (a);
    347   INSERT INTO log VALUES (0);
    348   INSERT INTO tbl VALUES (0, 0, 0, 0);
    349   INSERT INTO tbl VALUES (1, 0, 0, 0);
    350   CREATE TRIGGER tbl_after_update_cd BEFORE UPDATE OF c, d ON tbl
    351     BEGIN
    352       UPDATE log SET a = a + 1;
    353     END;
    354 }
    355 do_test trigger2-3.1 {
    356   execsql {
    357     UPDATE tbl SET b = 1, c = 10; -- 2
    358     UPDATE tbl SET b = 10; -- 0
    359     UPDATE tbl SET d = 4 WHERE a = 0; --1
    360     UPDATE tbl SET a = 4, b = 10; --0
    361     SELECT * FROM log;
    362   }
    363 } {3}
    364 execsql {
    365   DROP TABLE tbl;
    366   DROP TABLE log;
    367 }
    368 
    369 # trigger2-3.2: WHEN clause
    370 set when_triggers [list {t1 BEFORE INSERT ON tbl WHEN new.a > 20}]
    371 ifcapable subquery {
    372   lappend when_triggers \
    373       {t2 BEFORE INSERT ON tbl WHEN (SELECT count(*) FROM tbl) = 0}
    374 }
    375 
    376 execsql {
    377   CREATE TABLE tbl (a, b, c, d);
    378   CREATE TABLE log (a);
    379   INSERT INTO log VALUES (0);
    380 }
    381 
    382 foreach trig $when_triggers {
    383   execsql "CREATE TRIGGER $trig BEGIN UPDATE log set a = a + 1; END;"
    384 }
    385 
    386 ifcapable subquery {
    387   set t232 {1 0 1}
    388 } else {
    389   set t232 {0 0 1}
    390 }
    391 do_test trigger2-3.2 {
    392   execsql { 
    393 
    394     INSERT INTO tbl VALUES(0, 0, 0, 0);     -- 1 (ifcapable subquery)
    395     SELECT * FROM log;
    396     UPDATE log SET a = 0;
    397 
    398     INSERT INTO tbl VALUES(0, 0, 0, 0);     -- 0
    399     SELECT * FROM log;
    400     UPDATE log SET a = 0;
    401 
    402     INSERT INTO tbl VALUES(200, 0, 0, 0);     -- 1
    403     SELECT * FROM log;
    404     UPDATE log SET a = 0;
    405   }
    406 } $t232
    407 execsql {
    408   DROP TABLE tbl;
    409   DROP TABLE log;
    410 }
    411 integrity_check trigger2-3.3
    412 
    413 # Simple cascaded trigger
    414 execsql {
    415   CREATE TABLE tblA(a, b);
    416   CREATE TABLE tblB(a, b);
    417   CREATE TABLE tblC(a, b);
    418 
    419   CREATE TRIGGER tr1 BEFORE INSERT ON tblA BEGIN
    420     INSERT INTO tblB values(new.a, new.b);
    421   END;
    422 
    423   CREATE TRIGGER tr2 BEFORE INSERT ON tblB BEGIN
    424     INSERT INTO tblC values(new.a, new.b);
    425   END;
    426 }
    427 do_test trigger2-4.1 {
    428   execsql {
    429     INSERT INTO tblA values(1, 2);
    430     SELECT * FROM tblA;
    431     SELECT * FROM tblB;
    432     SELECT * FROM tblC;
    433   }
    434 } {1 2 1 2 1 2}
    435 execsql {
    436   DROP TABLE tblA;
    437   DROP TABLE tblB;
    438   DROP TABLE tblC;
    439 }
    440 
    441 # Simple recursive trigger
    442 execsql {
    443   CREATE TABLE tbl(a, b, c);
    444   CREATE TRIGGER tbl_trig BEFORE INSERT ON tbl 
    445     BEGIN
    446       INSERT INTO tbl VALUES (new.a, new.b, new.c);
    447     END;
    448 }
    449 do_test trigger2-4.2 {
    450   execsql {
    451     INSERT INTO tbl VALUES (1, 2, 3);
    452     select * from tbl;
    453   }
    454 } {1 2 3 1 2 3}
    455 execsql {
    456   DROP TABLE tbl;
    457 }
    458 
    459 # 5.
    460 execsql {
    461   CREATE TABLE tbl(a, b, c);
    462   CREATE TRIGGER tbl_trig BEFORE INSERT ON tbl 
    463     BEGIN
    464       INSERT INTO tbl VALUES (1, 2, 3);
    465       INSERT INTO tbl VALUES (2, 2, 3);
    466       UPDATE tbl set b = 10 WHERE a = 1;
    467       DELETE FROM tbl WHERE a = 1;
    468       DELETE FROM tbl;
    469     END;
    470 }
    471 do_test trigger2-5 {
    472   execsql {
    473     INSERT INTO tbl VALUES(100, 200, 300);
    474   }
    475   db changes
    476 } {1}
    477 execsql {
    478   DROP TABLE tbl;
    479 }
    480 
    481 ifcapable conflict {
    482   # Handling of ON CONFLICT by INSERT statements inside triggers
    483   execsql {
    484     CREATE TABLE tbl (a primary key, b, c);
    485     CREATE TRIGGER ai_tbl AFTER INSERT ON tbl BEGIN
    486       INSERT OR IGNORE INTO tbl values (new.a, 0, 0);
    487     END;
    488   }
    489   do_test trigger2-6.1a {
    490     execsql {
    491       BEGIN;
    492       INSERT INTO tbl values (1, 2, 3);
    493       SELECT * from tbl;
    494     }
    495   } {1 2 3}
    496   do_test trigger2-6.1b {
    497     catchsql {
    498       INSERT OR ABORT INTO tbl values (2, 2, 3);
    499     }
    500   } {1 {column a is not unique}}
    501   do_test trigger2-6.1c {
    502     execsql {
    503       SELECT * from tbl;
    504     }
    505   } {1 2 3}
    506   do_test trigger2-6.1d {
    507     catchsql {
    508       INSERT OR FAIL INTO tbl values (2, 2, 3);
    509     }
    510   } {1 {column a is not unique}}
    511   do_test trigger2-6.1e {
    512     execsql {
    513       SELECT * from tbl;
    514     }
    515   } {1 2 3 2 2 3}
    516   do_test trigger2-6.1f {
    517     execsql {
    518       INSERT OR REPLACE INTO tbl values (2, 2, 3);
    519       SELECT * from tbl;
    520     }
    521   } {1 2 3 2 0 0}
    522   do_test trigger2-6.1g {
    523     catchsql {
    524       INSERT OR ROLLBACK INTO tbl values (3, 2, 3);
    525     }
    526   } {1 {column a is not unique}}
    527   do_test trigger2-6.1h {
    528     execsql {
    529       SELECT * from tbl;
    530     }
    531   } {}
    532   execsql {DELETE FROM tbl}
    533   
    534   
    535   # Handling of ON CONFLICT by UPDATE statements inside triggers
    536   execsql {
    537     INSERT INTO tbl values (4, 2, 3);
    538     INSERT INTO tbl values (6, 3, 4);
    539     CREATE TRIGGER au_tbl AFTER UPDATE ON tbl BEGIN
    540       UPDATE OR IGNORE tbl SET a = new.a, c = 10;
    541     END;
    542   }
    543   do_test trigger2-6.2a {
    544     execsql {
    545       BEGIN;
    546       UPDATE tbl SET a = 1 WHERE a = 4;
    547       SELECT * from tbl;
    548     }
    549   } {1 2 10 6 3 4}
    550   do_test trigger2-6.2b {
    551     catchsql {
    552       UPDATE OR ABORT tbl SET a = 4 WHERE a = 1;
    553     }
    554   } {1 {column a is not unique}}
    555   do_test trigger2-6.2c {
    556     execsql {
    557       SELECT * from tbl;
    558     }
    559   } {1 2 10 6 3 4}
    560   do_test trigger2-6.2d {
    561     catchsql {
    562       UPDATE OR FAIL tbl SET a = 4 WHERE a = 1;
    563     }
    564   } {1 {column a is not unique}}
    565   do_test trigger2-6.2e {
    566     execsql {
    567       SELECT * from tbl;
    568     }
    569   } {4 2 10 6 3 4}
    570   do_test trigger2-6.2f.1 {
    571     execsql {
    572       UPDATE OR REPLACE tbl SET a = 1 WHERE a = 4;
    573       SELECT * from tbl;
    574     }
    575   } {1 3 10}
    576   do_test trigger2-6.2f.2 {
    577     execsql {
    578       INSERT INTO tbl VALUES (2, 3, 4);
    579       SELECT * FROM tbl;
    580     }
    581   } {1 3 10 2 3 4}
    582   do_test trigger2-6.2g {
    583     catchsql {
    584       UPDATE OR ROLLBACK tbl SET a = 4 WHERE a = 1;
    585     }
    586   } {1 {column a is not unique}}
    587   do_test trigger2-6.2h {
    588     execsql {
    589       SELECT * from tbl;
    590     }
    591   } {4 2 3 6 3 4}
    592   execsql {
    593     DROP TABLE tbl;
    594   }
    595 } ; # ifcapable conflict
    596 
    597 # 7. Triggers on views
    598 ifcapable view {
    599 
    600 do_test trigger2-7.1 {
    601   execsql {
    602   CREATE TABLE ab(a, b);
    603   CREATE TABLE cd(c, d);
    604   INSERT INTO ab VALUES (1, 2);
    605   INSERT INTO ab VALUES (0, 0);
    606   INSERT INTO cd VALUES (3, 4);
    607 
    608   CREATE TABLE tlog(ii INTEGER PRIMARY KEY, 
    609       olda, oldb, oldc, oldd, newa, newb, newc, newd);
    610 
    611   CREATE VIEW abcd AS SELECT a, b, c, d FROM ab, cd;
    612 
    613   CREATE TRIGGER before_update INSTEAD OF UPDATE ON abcd BEGIN
    614     INSERT INTO tlog VALUES(NULL, 
    615 	old.a, old.b, old.c, old.d, new.a, new.b, new.c, new.d);
    616   END;
    617   CREATE TRIGGER after_update INSTEAD OF UPDATE ON abcd BEGIN
    618     INSERT INTO tlog VALUES(NULL, 
    619 	old.a, old.b, old.c, old.d, new.a, new.b, new.c, new.d);
    620   END;
    621 
    622   CREATE TRIGGER before_delete INSTEAD OF DELETE ON abcd BEGIN
    623     INSERT INTO tlog VALUES(NULL, 
    624 	old.a, old.b, old.c, old.d, 0, 0, 0, 0);
    625   END;
    626   CREATE TRIGGER after_delete INSTEAD OF DELETE ON abcd BEGIN
    627     INSERT INTO tlog VALUES(NULL, 
    628 	old.a, old.b, old.c, old.d, 0, 0, 0, 0);
    629   END;
    630 
    631   CREATE TRIGGER before_insert INSTEAD OF INSERT ON abcd BEGIN
    632     INSERT INTO tlog VALUES(NULL, 
    633 	0, 0, 0, 0, new.a, new.b, new.c, new.d);
    634   END;
    635    CREATE TRIGGER after_insert INSTEAD OF INSERT ON abcd BEGIN
    636     INSERT INTO tlog VALUES(NULL, 
    637 	0, 0, 0, 0, new.a, new.b, new.c, new.d);
    638    END;
    639   }
    640 } {};
    641 
    642 do_test trigger2-7.2 {
    643   execsql {
    644     UPDATE abcd SET a = 100, b = 5*5 WHERE a = 1;
    645     DELETE FROM abcd WHERE a = 1;
    646     INSERT INTO abcd VALUES(10, 20, 30, 40);
    647     SELECT * FROM tlog;
    648   }
    649 } [ list 1 1 2 3 4 100 25 3 4 \
    650          2 1 2 3 4 100 25 3 4 \
    651 	 3 1 2 3 4 0 0 0 0 \
    652 	 4 1 2 3 4 0 0 0 0 \
    653 	 5 0 0 0 0 10 20 30 40 \
    654 	 6 0 0 0 0 10 20 30 40 ]
    655 
    656 do_test trigger2-7.3 {
    657   execsql {
    658     DELETE FROM tlog;
    659     INSERT INTO abcd VALUES(10, 20, 30, 40);
    660     UPDATE abcd SET a = 100, b = 5*5 WHERE a = 1;
    661     DELETE FROM abcd WHERE a = 1;
    662     SELECT * FROM tlog;
    663   }
    664 } [ list \
    665    1 0 0 0 0 10 20 30 40 \
    666    2 0 0 0 0 10 20 30 40 \
    667    3 1 2 3 4 100 25 3 4 \
    668    4 1 2 3 4 100 25 3 4 \
    669    5 1 2 3 4 0 0 0 0 \
    670    6 1 2 3 4 0 0 0 0 \
    671 ]
    672 do_test trigger2-7.4 {
    673   execsql {
    674     DELETE FROM tlog;
    675     DELETE FROM abcd WHERE a = 1;
    676     INSERT INTO abcd VALUES(10, 20, 30, 40);
    677     UPDATE abcd SET a = 100, b = 5*5 WHERE a = 1;
    678     SELECT * FROM tlog;
    679   }
    680 } [ list \
    681    1 1 2 3 4 0 0 0 0 \
    682    2 1 2 3 4 0 0 0 0 \
    683    3 0 0 0 0 10 20 30 40 \
    684    4 0 0 0 0 10 20 30 40 \
    685    5 1 2 3 4 100 25 3 4 \
    686    6 1 2 3 4 100 25 3 4 \
    687 ]
    688 
    689 do_test trigger2-8.1 {
    690   execsql {
    691     CREATE TABLE t1(a,b,c);
    692     INSERT INTO t1 VALUES(1,2,3);
    693     CREATE VIEW v1 AS
    694       SELECT a+b AS x, b+c AS y, a+c AS z FROM t1;
    695     SELECT * FROM v1;
    696   }
    697 } {3 5 4}
    698 do_test trigger2-8.2 {
    699   execsql {
    700     CREATE TABLE v1log(a,b,c,d,e,f);
    701     CREATE TRIGGER r1 INSTEAD OF DELETE ON v1 BEGIN
    702       INSERT INTO v1log VALUES(OLD.x,NULL,OLD.y,NULL,OLD.z,NULL);
    703     END;
    704     DELETE FROM v1 WHERE x=1;
    705     SELECT * FROM v1log;
    706   }
    707 } {}
    708 do_test trigger2-8.3 {
    709   execsql {
    710     DELETE FROM v1 WHERE x=3;
    711     SELECT * FROM v1log;
    712   }
    713 } {3 {} 5 {} 4 {}}
    714 do_test trigger2-8.4 {
    715   execsql {
    716     INSERT INTO t1 VALUES(4,5,6);
    717     DELETE FROM v1log;
    718     DELETE FROM v1 WHERE y=11;
    719     SELECT * FROM v1log;
    720   }
    721 } {9 {} 11 {} 10 {}}
    722 do_test trigger2-8.5 {
    723   execsql {
    724     CREATE TRIGGER r2 INSTEAD OF INSERT ON v1 BEGIN
    725       INSERT INTO v1log VALUES(NULL,NEW.x,NULL,NEW.y,NULL,NEW.z);
    726     END;
    727     DELETE FROM v1log;
    728     INSERT INTO v1 VALUES(1,2,3);
    729     SELECT * FROM v1log;
    730   }
    731 } {{} 1 {} 2 {} 3}
    732 do_test trigger2-8.6 {
    733   execsql {
    734     CREATE TRIGGER r3 INSTEAD OF UPDATE ON v1 BEGIN
    735       INSERT INTO v1log VALUES(OLD.x,NEW.x,OLD.y,NEW.y,OLD.z,NEW.z);
    736     END;
    737     DELETE FROM v1log;
    738     UPDATE v1 SET x=x+100, y=y+200, z=z+300;
    739     SELECT * FROM v1log;
    740   }
    741 } {3 103 5 205 4 304 9 109 11 211 10 310}
    742 
    743 # At one point the following was causing a segfault.
    744 do_test trigger2-9.1 {
    745   execsql {
    746     CREATE TABLE t3(a TEXT, b TEXT);
    747     CREATE VIEW v3 AS SELECT t3.a FROM t3;
    748     CREATE TRIGGER trig1 INSTEAD OF DELETE ON v3 BEGIN
    749       SELECT 1;
    750     END;
    751     DELETE FROM v3 WHERE a = 1;
    752   }
    753 } {}
    754 
    755 } ;# ifcapable view
    756 
    757 integrity_check trigger2-9.9
    758 
    759 finish_test
    760