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