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