blob: 66bd60a8ff1afb1b016d164c32a569e322f6d765 [file] [log] [blame]
danielk1977c3f9bad2002-05-15 08:30:12 +00001# 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#
drh41a3bd02002-09-14 12:04:56 +000016# trigger2-1.1.*: ON UPDATE trigger execution model.
17# trigger2-1.2.*: DELETE trigger execution model.
18# trigger2-1.3.*: INSERT trigger execution model.
danielk1977c3f9bad2002-05-15 08:30:12 +000019#
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#
drh41a3bd02002-09-14 12:04:56 +000029# trigger2-3.1: UPDATE OF triggers
30# trigger2-3.2: WHEN clause
danielk1977c3f9bad2002-05-15 08:30:12 +000031#
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#
drh41a3bd02002-09-14 12:04:56 +000036# trigger2-4.1: Trivial cascading trigger
37# trigger2-4.2: Trivial recursive trigger handling
danielk1977c3f9bad2002-05-15 08:30:12 +000038#
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
drh41a3bd02002-09-14 12:04:56 +000044# trigger2-6.1[a-f]: INSERT statements
45# trigger2-6.2[a-f]: UPDATE statements
danielk1977c3f9bad2002-05-15 08:30:12 +000046#
danielk19770fa8ddb2004-11-22 08:43:32 +000047# 7. & 8. Triggers on views fire correctly.
danielk1977c3f9bad2002-05-15 08:30:12 +000048#
49
50set testdir [file dirname $argv0]
51source $testdir/tester.tcl
drhb7f91642004-10-31 02:22:47 +000052ifcapable {!trigger} {
53 finish_test
54 return
55}
danielk1977c3f9bad2002-05-15 08:30:12 +000056
57# 1.
58set ii 0
drh8bf8dc92003-05-17 17:35:10 +000059foreach tbl_defn {
60 {CREATE TEMP TABLE tbl (a, b);}
61 {CREATE TABLE tbl (a, b);}
62 {CREATE TABLE tbl (a INTEGER PRIMARY KEY, b);}
63 {CREATE TEMPORARY TABLE tbl (a INTEGER PRIMARY KEY, b);}
64 {CREATE TABLE tbl (a, b PRIMARY KEY);}
65 {CREATE TABLE tbl (a, b); CREATE INDEX tbl_idx ON tbl(b);}
66 {CREATE TEMP TABLE tbl (a, b); CREATE INDEX tbl_idx ON tbl(b);}
drh8bf8dc92003-05-17 17:35:10 +000067} {
danielk1977c3f9bad2002-05-15 08:30:12 +000068 incr ii
69 catchsql { DROP INDEX tbl_idx; }
70 catchsql {
71 DROP TABLE rlog;
72 DROP TABLE clog;
73 DROP TABLE tbl;
74 DROP TABLE other_tbl;
75 }
76
77 execsql $tbl_defn
78
79 execsql {
80 INSERT INTO tbl VALUES(1, 2);
81 INSERT INTO tbl VALUES(3, 4);
82
83 CREATE TABLE rlog (idx, old_a, old_b, db_sum_a, db_sum_b, new_a, new_b);
84 CREATE TABLE clog (idx, old_a, old_b, db_sum_a, db_sum_b, new_a, new_b);
85
86 CREATE TRIGGER before_update_row BEFORE UPDATE ON tbl FOR EACH ROW
87 BEGIN
drhf5905aa2002-05-26 20:54:33 +000088 INSERT INTO rlog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM rlog),
danielk1977c3f9bad2002-05-15 08:30:12 +000089 old.a, old.b,
90 (SELECT sum(a) FROM tbl), (SELECT sum(b) FROM tbl),
91 new.a, new.b);
92 END;
93
94 CREATE TRIGGER after_update_row AFTER UPDATE ON tbl FOR EACH ROW
95 BEGIN
drhf5905aa2002-05-26 20:54:33 +000096 INSERT INTO rlog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM rlog),
danielk1977c3f9bad2002-05-15 08:30:12 +000097 old.a, old.b,
98 (SELECT sum(a) FROM tbl), (SELECT sum(b) FROM tbl),
99 new.a, new.b);
100 END;
101
102 CREATE TRIGGER conditional_update_row AFTER UPDATE ON tbl FOR EACH ROW
103 WHEN old.a = 1
104 BEGIN
drhf5905aa2002-05-26 20:54:33 +0000105 INSERT INTO clog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM clog),
danielk1977c3f9bad2002-05-15 08:30:12 +0000106 old.a, old.b,
107 (SELECT sum(a) FROM tbl), (SELECT sum(b) FROM tbl),
108 new.a, new.b);
109 END;
110 }
111
drh8bf8dc92003-05-17 17:35:10 +0000112 do_test trigger2-1.$ii.1 {
drh92febd92004-08-20 18:34:20 +0000113 set r {}
114 foreach v [execsql {
danielk1977c3f9bad2002-05-15 08:30:12 +0000115 UPDATE tbl SET a = a * 10, b = b * 10;
116 SELECT * FROM rlog ORDER BY idx;
117 SELECT * FROM clog ORDER BY idx;
drh92febd92004-08-20 18:34:20 +0000118 }] {
119 lappend r [expr {int($v)}]
danielk1977c3f9bad2002-05-15 08:30:12 +0000120 }
drh92febd92004-08-20 18:34:20 +0000121 set r
danielk1977c3f9bad2002-05-15 08:30:12 +0000122 } [list 1 1 2 4 6 10 20 \
123 2 1 2 13 24 10 20 \
124 3 3 4 13 24 30 40 \
125 4 3 4 40 60 30 40 \
126 1 1 2 13 24 10 20 ]
drh8bf8dc92003-05-17 17:35:10 +0000127
danielk1977c3f9bad2002-05-15 08:30:12 +0000128 execsql {
129 DELETE FROM rlog;
130 DELETE FROM tbl;
131 INSERT INTO tbl VALUES (100, 100);
132 INSERT INTO tbl VALUES (300, 200);
133 CREATE TRIGGER delete_before_row BEFORE DELETE ON tbl FOR EACH ROW
134 BEGIN
drhf5905aa2002-05-26 20:54:33 +0000135 INSERT INTO rlog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM rlog),
danielk1977c3f9bad2002-05-15 08:30:12 +0000136 old.a, old.b,
137 (SELECT sum(a) FROM tbl), (SELECT sum(b) FROM tbl),
138 0, 0);
139 END;
140
141 CREATE TRIGGER delete_after_row AFTER DELETE ON tbl FOR EACH ROW
142 BEGIN
drhf5905aa2002-05-26 20:54:33 +0000143 INSERT INTO rlog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM rlog),
danielk1977c3f9bad2002-05-15 08:30:12 +0000144 old.a, old.b,
145 (SELECT sum(a) FROM tbl), (SELECT sum(b) FROM tbl),
146 0, 0);
147 END;
148 }
drh8bf8dc92003-05-17 17:35:10 +0000149 do_test trigger2-1.$ii.2 {
drh92febd92004-08-20 18:34:20 +0000150 set r {}
151 foreach v [execsql {
danielk1977c3f9bad2002-05-15 08:30:12 +0000152 DELETE FROM tbl;
153 SELECT * FROM rlog;
drh92febd92004-08-20 18:34:20 +0000154 }] {
155 lappend r [expr {int($v)}]
danielk1977c3f9bad2002-05-15 08:30:12 +0000156 }
drh92febd92004-08-20 18:34:20 +0000157 set r
danielk1977c3f9bad2002-05-15 08:30:12 +0000158 } [list 1 100 100 400 300 0 0 \
159 2 100 100 300 200 0 0 \
160 3 300 200 300 200 0 0 \
161 4 300 200 0 0 0 0 ]
162
163 execsql {
164 DELETE FROM rlog;
165 CREATE TRIGGER insert_before_row BEFORE INSERT ON tbl FOR EACH ROW
166 BEGIN
drhf5905aa2002-05-26 20:54:33 +0000167 INSERT INTO rlog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM rlog),
danielk1977c3f9bad2002-05-15 08:30:12 +0000168 0, 0,
169 (SELECT sum(a) FROM tbl), (SELECT sum(b) FROM tbl),
170 new.a, new.b);
171 END;
172
173 CREATE TRIGGER insert_after_row AFTER INSERT ON tbl FOR EACH ROW
174 BEGIN
drhf5905aa2002-05-26 20:54:33 +0000175 INSERT INTO rlog VALUES ( (SELECT coalesce(max(idx),0) + 1 FROM rlog),
danielk1977c3f9bad2002-05-15 08:30:12 +0000176 0, 0,
177 (SELECT sum(a) FROM tbl), (SELECT sum(b) FROM tbl),
178 new.a, new.b);
179 END;
180 }
drh8bf8dc92003-05-17 17:35:10 +0000181 do_test trigger2-1.$ii.3 {
danielk1977c3f9bad2002-05-15 08:30:12 +0000182 execsql {
183
184 CREATE TABLE other_tbl(a, b);
185 INSERT INTO other_tbl VALUES(1, 2);
186 INSERT INTO other_tbl VALUES(3, 4);
187 -- INSERT INTO tbl SELECT * FROM other_tbl;
188 INSERT INTO tbl VALUES(5, 6);
189 DROP TABLE other_tbl;
190
191 SELECT * FROM rlog;
192 }
drh92febd92004-08-20 18:34:20 +0000193 } [list 1 0 0 0.0 0.0 5 6 \
194 2 0 0 5.0 6.0 5 6 ]
drh8bf8dc92003-05-17 17:35:10 +0000195
drh40e016e2004-11-04 14:47:11 +0000196 integrity_check trigger2-1.$ii.4
danielk1977c3f9bad2002-05-15 08:30:12 +0000197}
198catchsql {
199 DROP TABLE rlog;
200 DROP TABLE clog;
201 DROP TABLE tbl;
202 DROP TABLE other_tbl;
203}
204
205# 2.
206set ii 0
drh8bf8dc92003-05-17 17:35:10 +0000207foreach tr_program {
208 {UPDATE tbl SET b = old.b;}
209 {INSERT INTO log VALUES(new.c, 2, 3);}
210 {DELETE FROM log WHERE a = 1;}
danielk1977c3f9bad2002-05-15 08:30:12 +0000211 {INSERT INTO tbl VALUES(500, new.b * 10, 700);
212 UPDATE tbl SET c = old.c;
drh8bf8dc92003-05-17 17:35:10 +0000213 DELETE FROM log;}
danielk1977c3f9bad2002-05-15 08:30:12 +0000214 {INSERT INTO log select * from tbl;}
drh8bf8dc92003-05-17 17:35:10 +0000215} {
danielk1977c3f9bad2002-05-15 08:30:12 +0000216 foreach test_varset [ list \
217 {
218 set statement {UPDATE tbl SET c = 10 WHERE a = 1;}
219 set prep {INSERT INTO tbl VALUES(1, 2, 3);}
220 set newC 10
221 set newB 2
222 set newA 1
223 set oldA 1
224 set oldB 2
225 set oldC 3
226 } \
227 {
228 set statement {DELETE FROM tbl WHERE a = 1;}
229 set prep {INSERT INTO tbl VALUES(1, 2, 3);}
230 set oldA 1
231 set oldB 2
232 set oldC 3
233 } \
234 {
235 set statement {INSERT INTO tbl VALUES(1, 2, 3);}
236 set newA 1
237 set newB 2
238 set newC 3
239 }
240 ] \
241 {
242 set statement {}
243 set prep {}
244 set newA {''}
245 set newB {''}
246 set newC {''}
247 set oldA {''}
248 set oldB {''}
249 set oldC {''}
250
251 incr ii
252
253 eval $test_varset
254
255 set statement_type [string range $statement 0 5]
256 set tr_program_fixed $tr_program
257 if {$statement_type == "DELETE"} {
258 regsub -all new\.a $tr_program_fixed {''} tr_program_fixed
259 regsub -all new\.b $tr_program_fixed {''} tr_program_fixed
260 regsub -all new\.c $tr_program_fixed {''} tr_program_fixed
261 }
262 if {$statement_type == "INSERT"} {
263 regsub -all old\.a $tr_program_fixed {''} tr_program_fixed
264 regsub -all old\.b $tr_program_fixed {''} tr_program_fixed
265 regsub -all old\.c $tr_program_fixed {''} tr_program_fixed
266 }
267
268
269 set tr_program_cooked $tr_program
270 regsub -all new\.a $tr_program_cooked $newA tr_program_cooked
271 regsub -all new\.b $tr_program_cooked $newB tr_program_cooked
272 regsub -all new\.c $tr_program_cooked $newC tr_program_cooked
273 regsub -all old\.a $tr_program_cooked $oldA tr_program_cooked
274 regsub -all old\.b $tr_program_cooked $oldB tr_program_cooked
275 regsub -all old\.c $tr_program_cooked $oldC tr_program_cooked
276
277 catchsql {
278 DROP TABLE tbl;
279 DROP TABLE log;
280 }
drh8bf8dc92003-05-17 17:35:10 +0000281
danielk1977c3f9bad2002-05-15 08:30:12 +0000282 execsql {
283 CREATE TABLE tbl(a PRIMARY KEY, b, c);
284 CREATE TABLE log(a, b, c);
285 }
286
287 set query {SELECT * FROM tbl; SELECT * FROM log;}
drh8bf8dc92003-05-17 17:35:10 +0000288 set prep "$prep; INSERT INTO log VALUES(1, 2, 3);\
289 INSERT INTO log VALUES(10, 20, 30);"
danielk1977c3f9bad2002-05-15 08:30:12 +0000290
291# Check execution of BEFORE programs:
292
293 set before_data [ execsql "$prep $tr_program_cooked $statement $query" ]
294
295 execsql "DELETE FROM tbl; DELETE FROM log; $prep";
drh8bf8dc92003-05-17 17:35:10 +0000296 execsql "CREATE TRIGGER the_trigger BEFORE [string range $statement 0 6]\
297 ON tbl BEGIN $tr_program_fixed END;"
danielk1977c3f9bad2002-05-15 08:30:12 +0000298
drh8bf8dc92003-05-17 17:35:10 +0000299 do_test trigger2-2.$ii-before "execsql {$statement $query}" $before_data
danielk1977c3f9bad2002-05-15 08:30:12 +0000300
301 execsql "DROP TRIGGER the_trigger;"
302 execsql "DELETE FROM tbl; DELETE FROM log;"
303
304# Check execution of AFTER programs
305 set after_data [ execsql "$prep $statement $tr_program_cooked $query" ]
306
307 execsql "DELETE FROM tbl; DELETE FROM log; $prep";
drh8bf8dc92003-05-17 17:35:10 +0000308 execsql "CREATE TRIGGER the_trigger AFTER [string range $statement 0 6]\
309 ON tbl BEGIN $tr_program_fixed END;"
danielk1977c3f9bad2002-05-15 08:30:12 +0000310
drh8bf8dc92003-05-17 17:35:10 +0000311 do_test trigger2-2.$ii-after "execsql {$statement $query}" $after_data
danielk1977c3f9bad2002-05-15 08:30:12 +0000312 execsql "DROP TRIGGER the_trigger;"
drh8bf8dc92003-05-17 17:35:10 +0000313
drh40e016e2004-11-04 14:47:11 +0000314 integrity_check trigger2-2.$ii-integrity
danielk1977c3f9bad2002-05-15 08:30:12 +0000315 }
316}
317catchsql {
318 DROP TABLE tbl;
319 DROP TABLE log;
320}
321
322# 3.
323
drh41a3bd02002-09-14 12:04:56 +0000324# trigger2-3.1: UPDATE OF triggers
danielk1977c3f9bad2002-05-15 08:30:12 +0000325execsql {
326 CREATE TABLE tbl (a, b, c, d);
327 CREATE TABLE log (a);
328 INSERT INTO log VALUES (0);
329 INSERT INTO tbl VALUES (0, 0, 0, 0);
330 INSERT INTO tbl VALUES (1, 0, 0, 0);
331 CREATE TRIGGER tbl_after_update_cd BEFORE UPDATE OF c, d ON tbl
332 BEGIN
333 UPDATE log SET a = a + 1;
334 END;
335}
drh41a3bd02002-09-14 12:04:56 +0000336do_test trigger2-3.1 {
danielk1977c3f9bad2002-05-15 08:30:12 +0000337 execsql {
338 UPDATE tbl SET b = 1, c = 10; -- 2
339 UPDATE tbl SET b = 10; -- 0
340 UPDATE tbl SET d = 4 WHERE a = 0; --1
341 UPDATE tbl SET a = 4, b = 10; --0
342 SELECT * FROM log;
343 }
344} {3}
345execsql {
346 DROP TABLE tbl;
347 DROP TABLE log;
348}
349
drh41a3bd02002-09-14 12:04:56 +0000350# trigger2-3.2: WHEN clause
danielk1977c3f9bad2002-05-15 08:30:12 +0000351set when_triggers [ list \
352 {t1 BEFORE INSERT ON tbl WHEN new.a > 20} \
353 {t2 BEFORE INSERT ON tbl WHEN (SELECT count(*) FROM tbl) = 0} ]
354
355execsql {
356 CREATE TABLE tbl (a, b, c, d);
357 CREATE TABLE log (a);
358 INSERT INTO log VALUES (0);
359}
360
361foreach trig $when_triggers {
362 execsql "CREATE TRIGGER $trig BEGIN UPDATE log set a = a + 1; END;"
363}
364
drh41a3bd02002-09-14 12:04:56 +0000365do_test trigger2-3.2 {
danielk1977c3f9bad2002-05-15 08:30:12 +0000366 execsql {
367
368 INSERT INTO tbl VALUES(0, 0, 0, 0); -- 1
369 SELECT * FROM log;
370 UPDATE log SET a = 0;
371
372 INSERT INTO tbl VALUES(0, 0, 0, 0); -- 0
373 SELECT * FROM log;
374 UPDATE log SET a = 0;
375
376 INSERT INTO tbl VALUES(200, 0, 0, 0); -- 1
377 SELECT * FROM log;
378 UPDATE log SET a = 0;
379 }
380} {1 0 1}
381execsql {
382 DROP TABLE tbl;
383 DROP TABLE log;
384}
drh40e016e2004-11-04 14:47:11 +0000385integrity_check trigger2-3.3
danielk1977c3f9bad2002-05-15 08:30:12 +0000386
387# Simple cascaded trigger
388execsql {
389 CREATE TABLE tblA(a, b);
390 CREATE TABLE tblB(a, b);
391 CREATE TABLE tblC(a, b);
392
393 CREATE TRIGGER tr1 BEFORE INSERT ON tblA BEGIN
394 INSERT INTO tblB values(new.a, new.b);
395 END;
396
397 CREATE TRIGGER tr2 BEFORE INSERT ON tblB BEGIN
398 INSERT INTO tblC values(new.a, new.b);
399 END;
400}
drh41a3bd02002-09-14 12:04:56 +0000401do_test trigger2-4.1 {
danielk1977c3f9bad2002-05-15 08:30:12 +0000402 execsql {
403 INSERT INTO tblA values(1, 2);
404 SELECT * FROM tblA;
405 SELECT * FROM tblB;
406 SELECT * FROM tblC;
407 }
408} {1 2 1 2 1 2}
409execsql {
410 DROP TABLE tblA;
411 DROP TABLE tblB;
412 DROP TABLE tblC;
413}
414
415# Simple recursive trigger
416execsql {
417 CREATE TABLE tbl(a, b, c);
418 CREATE TRIGGER tbl_trig BEFORE INSERT ON tbl
419 BEGIN
420 INSERT INTO tbl VALUES (new.a, new.b, new.c);
421 END;
422}
drh41a3bd02002-09-14 12:04:56 +0000423do_test trigger2-4.2 {
danielk1977c3f9bad2002-05-15 08:30:12 +0000424 execsql {
425 INSERT INTO tbl VALUES (1, 2, 3);
426 select * from tbl;
427 }
428} {1 2 3 1 2 3}
429execsql {
430 DROP TABLE tbl;
431}
432
433# 5.
434execsql {
435 CREATE TABLE tbl(a, b, c);
436 CREATE TRIGGER tbl_trig BEFORE INSERT ON tbl
437 BEGIN
438 INSERT INTO tbl VALUES (1, 2, 3);
439 INSERT INTO tbl VALUES (2, 2, 3);
440 UPDATE tbl set b = 10 WHERE a = 1;
441 DELETE FROM tbl WHERE a = 1;
442 DELETE FROM tbl;
443 END;
444}
drh41a3bd02002-09-14 12:04:56 +0000445do_test trigger2-5 {
danielk1977c3f9bad2002-05-15 08:30:12 +0000446 execsql {
447 INSERT INTO tbl VALUES(100, 200, 300);
448 }
449 db changes
450} {1}
451execsql {
452 DROP TABLE tbl;
453}
454
danielk1977c3f9bad2002-05-15 08:30:12 +0000455# Handling of ON CONFLICT by INSERT statements inside triggers
456execsql {
457 CREATE TABLE tbl (a primary key, b, c);
458 CREATE TRIGGER ai_tbl AFTER INSERT ON tbl BEGIN
459 INSERT OR IGNORE INTO tbl values (new.a, 0, 0);
460 END;
461}
drh41a3bd02002-09-14 12:04:56 +0000462do_test trigger2-6.1a {
danielk1977c3f9bad2002-05-15 08:30:12 +0000463 execsql {
464 BEGIN;
465 INSERT INTO tbl values (1, 2, 3);
466 SELECT * from tbl;
467 }
468} {1 2 3}
drh41a3bd02002-09-14 12:04:56 +0000469do_test trigger2-6.1b {
danielk1977c3f9bad2002-05-15 08:30:12 +0000470 catchsql {
471 INSERT OR ABORT INTO tbl values (2, 2, 3);
472 }
drh37ed48e2003-08-05 13:13:38 +0000473} {1 {column a is not unique}}
drh41a3bd02002-09-14 12:04:56 +0000474do_test trigger2-6.1c {
danielk1977c3f9bad2002-05-15 08:30:12 +0000475 execsql {
476 SELECT * from tbl;
477 }
478} {1 2 3}
drh41a3bd02002-09-14 12:04:56 +0000479do_test trigger2-6.1d {
danielk1977c3f9bad2002-05-15 08:30:12 +0000480 catchsql {
481 INSERT OR FAIL INTO tbl values (2, 2, 3);
482 }
drh37ed48e2003-08-05 13:13:38 +0000483} {1 {column a is not unique}}
drh41a3bd02002-09-14 12:04:56 +0000484do_test trigger2-6.1e {
danielk1977c3f9bad2002-05-15 08:30:12 +0000485 execsql {
486 SELECT * from tbl;
487 }
488} {1 2 3 2 2 3}
drh41a3bd02002-09-14 12:04:56 +0000489do_test trigger2-6.1f {
danielk1977c3f9bad2002-05-15 08:30:12 +0000490 execsql {
491 INSERT OR REPLACE INTO tbl values (2, 2, 3);
492 SELECT * from tbl;
493 }
494} {1 2 3 2 0 0}
drh41a3bd02002-09-14 12:04:56 +0000495do_test trigger2-6.1g {
danielk1977c3f9bad2002-05-15 08:30:12 +0000496 catchsql {
497 INSERT OR ROLLBACK INTO tbl values (3, 2, 3);
498 }
drh37ed48e2003-08-05 13:13:38 +0000499} {1 {column a is not unique}}
drh41a3bd02002-09-14 12:04:56 +0000500do_test trigger2-6.1h {
danielk1977c3f9bad2002-05-15 08:30:12 +0000501 execsql {
502 SELECT * from tbl;
503 }
504} {}
drh4303fee2003-02-15 23:09:17 +0000505execsql {DELETE FROM tbl}
danielk1977c3f9bad2002-05-15 08:30:12 +0000506
507
508# Handling of ON CONFLICT by UPDATE statements inside triggers
509execsql {
510 INSERT INTO tbl values (4, 2, 3);
511 INSERT INTO tbl values (6, 3, 4);
512 CREATE TRIGGER au_tbl AFTER UPDATE ON tbl BEGIN
513 UPDATE OR IGNORE tbl SET a = new.a, c = 10;
514 END;
515}
drh41a3bd02002-09-14 12:04:56 +0000516do_test trigger2-6.2a {
danielk1977c3f9bad2002-05-15 08:30:12 +0000517 execsql {
518 BEGIN;
519 UPDATE tbl SET a = 1 WHERE a = 4;
520 SELECT * from tbl;
521 }
522} {1 2 10 6 3 4}
drh41a3bd02002-09-14 12:04:56 +0000523do_test trigger2-6.2b {
danielk1977c3f9bad2002-05-15 08:30:12 +0000524 catchsql {
525 UPDATE OR ABORT tbl SET a = 4 WHERE a = 1;
526 }
drh37ed48e2003-08-05 13:13:38 +0000527} {1 {column a is not unique}}
drh41a3bd02002-09-14 12:04:56 +0000528do_test trigger2-6.2c {
danielk1977c3f9bad2002-05-15 08:30:12 +0000529 execsql {
530 SELECT * from tbl;
531 }
532} {1 2 10 6 3 4}
drh41a3bd02002-09-14 12:04:56 +0000533do_test trigger2-6.2d {
danielk1977c3f9bad2002-05-15 08:30:12 +0000534 catchsql {
535 UPDATE OR FAIL tbl SET a = 4 WHERE a = 1;
536 }
drh37ed48e2003-08-05 13:13:38 +0000537} {1 {column a is not unique}}
drh41a3bd02002-09-14 12:04:56 +0000538do_test trigger2-6.2e {
danielk1977c3f9bad2002-05-15 08:30:12 +0000539 execsql {
540 SELECT * from tbl;
541 }
542} {4 2 10 6 3 4}
drh4303fee2003-02-15 23:09:17 +0000543do_test trigger2-6.2f.1 {
danielk1977c3f9bad2002-05-15 08:30:12 +0000544 execsql {
545 UPDATE OR REPLACE tbl SET a = 1 WHERE a = 4;
546 SELECT * from tbl;
547 }
548} {1 3 10}
drh4303fee2003-02-15 23:09:17 +0000549do_test trigger2-6.2f.2 {
550 execsql {
551 INSERT INTO tbl VALUES (2, 3, 4);
552 SELECT * FROM tbl;
553 }
554} {1 3 10 2 3 4}
drh41a3bd02002-09-14 12:04:56 +0000555do_test trigger2-6.2g {
danielk1977c3f9bad2002-05-15 08:30:12 +0000556 catchsql {
557 UPDATE OR ROLLBACK tbl SET a = 4 WHERE a = 1;
558 }
drh37ed48e2003-08-05 13:13:38 +0000559} {1 {column a is not unique}}
drh41a3bd02002-09-14 12:04:56 +0000560do_test trigger2-6.2h {
danielk1977c3f9bad2002-05-15 08:30:12 +0000561 execsql {
562 SELECT * from tbl;
563 }
564} {4 2 3 6 3 4}
565execsql {
566 DROP TABLE tbl;
567}
568
569# 7. Triggers on views
danielk19770fa8ddb2004-11-22 08:43:32 +0000570ifcapable view {
571
drh41a3bd02002-09-14 12:04:56 +0000572do_test trigger2-7.1 {
drh1873cd52002-05-23 00:30:31 +0000573 execsql {
danielk1977c3f9bad2002-05-15 08:30:12 +0000574 CREATE TABLE ab(a, b);
575 CREATE TABLE cd(c, d);
576 INSERT INTO ab VALUES (1, 2);
577 INSERT INTO ab VALUES (0, 0);
578 INSERT INTO cd VALUES (3, 4);
579
580 CREATE TABLE tlog(ii INTEGER PRIMARY KEY,
581 olda, oldb, oldc, oldd, newa, newb, newc, newd);
582
583 CREATE VIEW abcd AS SELECT a, b, c, d FROM ab, cd;
584
danielk1977993b1732002-05-28 06:55:27 +0000585 CREATE TRIGGER before_update INSTEAD OF UPDATE ON abcd BEGIN
danielk1977c3f9bad2002-05-15 08:30:12 +0000586 INSERT INTO tlog VALUES(NULL,
587 old.a, old.b, old.c, old.d, new.a, new.b, new.c, new.d);
588 END;
danielk1977993b1732002-05-28 06:55:27 +0000589 CREATE TRIGGER after_update INSTEAD OF UPDATE ON abcd BEGIN
danielk1977c3f9bad2002-05-15 08:30:12 +0000590 INSERT INTO tlog VALUES(NULL,
591 old.a, old.b, old.c, old.d, new.a, new.b, new.c, new.d);
592 END;
593
danielk1977993b1732002-05-28 06:55:27 +0000594 CREATE TRIGGER before_delete INSTEAD OF DELETE ON abcd BEGIN
danielk1977c3f9bad2002-05-15 08:30:12 +0000595 INSERT INTO tlog VALUES(NULL,
596 old.a, old.b, old.c, old.d, 0, 0, 0, 0);
597 END;
danielk1977993b1732002-05-28 06:55:27 +0000598 CREATE TRIGGER after_delete INSTEAD OF DELETE ON abcd BEGIN
danielk1977c3f9bad2002-05-15 08:30:12 +0000599 INSERT INTO tlog VALUES(NULL,
600 old.a, old.b, old.c, old.d, 0, 0, 0, 0);
601 END;
602
danielk1977993b1732002-05-28 06:55:27 +0000603 CREATE TRIGGER before_insert INSTEAD OF INSERT ON abcd BEGIN
danielk1977c3f9bad2002-05-15 08:30:12 +0000604 INSERT INTO tlog VALUES(NULL,
605 0, 0, 0, 0, new.a, new.b, new.c, new.d);
606 END;
danielk1977993b1732002-05-28 06:55:27 +0000607 CREATE TRIGGER after_insert INSTEAD OF INSERT ON abcd BEGIN
danielk1977c3f9bad2002-05-15 08:30:12 +0000608 INSERT INTO tlog VALUES(NULL,
609 0, 0, 0, 0, new.a, new.b, new.c, new.d);
610 END;
drh1873cd52002-05-23 00:30:31 +0000611 }
drh8bf8dc92003-05-17 17:35:10 +0000612} {};
danielk1977c3f9bad2002-05-15 08:30:12 +0000613
drh41a3bd02002-09-14 12:04:56 +0000614do_test trigger2-7.2 {
danielk1977c3f9bad2002-05-15 08:30:12 +0000615 execsql {
616 UPDATE abcd SET a = 100, b = 5*5 WHERE a = 1;
617 DELETE FROM abcd WHERE a = 1;
618 INSERT INTO abcd VALUES(10, 20, 30, 40);
619 SELECT * FROM tlog;
620 }
621} [ list 1 1 2 3 4 100 25 3 4 \
622 2 1 2 3 4 100 25 3 4 \
danielk1977993b1732002-05-28 06:55:27 +0000623 3 1 2 3 4 0 0 0 0 \
624 4 1 2 3 4 0 0 0 0 \
625 5 0 0 0 0 10 20 30 40 \
626 6 0 0 0 0 10 20 30 40 ]
danielk1977c3f9bad2002-05-15 08:30:12 +0000627
drh5cf590c2003-04-24 01:45:04 +0000628do_test trigger2-7.3 {
629 execsql {
630 DELETE FROM tlog;
631 INSERT INTO abcd VALUES(10, 20, 30, 40);
632 UPDATE abcd SET a = 100, b = 5*5 WHERE a = 1;
633 DELETE FROM abcd WHERE a = 1;
634 SELECT * FROM tlog;
635 }
636} [ list \
637 1 0 0 0 0 10 20 30 40 \
638 2 0 0 0 0 10 20 30 40 \
639 3 1 2 3 4 100 25 3 4 \
640 4 1 2 3 4 100 25 3 4 \
641 5 1 2 3 4 0 0 0 0 \
642 6 1 2 3 4 0 0 0 0 \
643]
644do_test trigger2-7.4 {
645 execsql {
646 DELETE FROM tlog;
647 DELETE FROM abcd WHERE a = 1;
648 INSERT INTO abcd VALUES(10, 20, 30, 40);
649 UPDATE abcd SET a = 100, b = 5*5 WHERE a = 1;
650 SELECT * FROM tlog;
651 }
652} [ list \
653 1 1 2 3 4 0 0 0 0 \
654 2 1 2 3 4 0 0 0 0 \
655 3 0 0 0 0 10 20 30 40 \
656 4 0 0 0 0 10 20 30 40 \
657 5 1 2 3 4 100 25 3 4 \
658 6 1 2 3 4 100 25 3 4 \
659]
660
661do_test trigger2-8.1 {
662 execsql {
663 CREATE TABLE t1(a,b,c);
664 INSERT INTO t1 VALUES(1,2,3);
665 CREATE VIEW v1 AS
666 SELECT a+b AS x, b+c AS y, a+c AS z FROM t1;
667 SELECT * FROM v1;
668 }
669} {3 5 4}
670do_test trigger2-8.2 {
671 execsql {
672 CREATE TABLE v1log(a,b,c,d,e,f);
673 CREATE TRIGGER r1 INSTEAD OF DELETE ON v1 BEGIN
674 INSERT INTO v1log VALUES(OLD.x,NULL,OLD.y,NULL,OLD.z,NULL);
675 END;
676 DELETE FROM v1 WHERE x=1;
677 SELECT * FROM v1log;
678 }
679} {}
680do_test trigger2-8.3 {
681 execsql {
682 DELETE FROM v1 WHERE x=3;
683 SELECT * FROM v1log;
684 }
685} {3 {} 5 {} 4 {}}
686do_test trigger2-8.4 {
687 execsql {
688 INSERT INTO t1 VALUES(4,5,6);
689 DELETE FROM v1log;
690 DELETE FROM v1 WHERE y=11;
691 SELECT * FROM v1log;
692 }
693} {9 {} 11 {} 10 {}}
694do_test trigger2-8.5 {
695 execsql {
696 CREATE TRIGGER r2 INSTEAD OF INSERT ON v1 BEGIN
697 INSERT INTO v1log VALUES(NULL,NEW.x,NULL,NEW.y,NULL,NEW.z);
698 END;
699 DELETE FROM v1log;
700 INSERT INTO v1 VALUES(1,2,3);
701 SELECT * FROM v1log;
702 }
703} {{} 1 {} 2 {} 3}
704do_test trigger2-8.6 {
705 execsql {
706 CREATE TRIGGER r3 INSTEAD OF UPDATE ON v1 BEGIN
707 INSERT INTO v1log VALUES(OLD.x,NEW.x,OLD.y,NEW.y,OLD.z,NEW.z);
708 END;
709 DELETE FROM v1log;
710 UPDATE v1 SET x=x+100, y=y+200, z=z+300;
711 SELECT * FROM v1log;
712 }
713} {3 103 5 205 4 304 9 109 11 211 10 310}
714
danielk19770fa8ddb2004-11-22 08:43:32 +0000715} ;# ifcapable view
716
drh40e016e2004-11-04 14:47:11 +0000717integrity_check trigger2-9.9
drh5cf590c2003-04-24 01:45:04 +0000718
danielk1977c3f9bad2002-05-15 08:30:12 +0000719finish_test