blob: d24e80105670b4af060f39035991f9d189eeade2 [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#
47# 7. Triggers on views fire correctly.
48#
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
196 do_test trigger2-1.$ii.4 {
197 execsql {
198 PRAGMA integrity_check;
199 }
drhed717fe2003-06-15 23:42:24 +0000200 } {ok}
danielk1977c3f9bad2002-05-15 08:30:12 +0000201}
202catchsql {
203 DROP TABLE rlog;
204 DROP TABLE clog;
205 DROP TABLE tbl;
206 DROP TABLE other_tbl;
207}
208
209# 2.
210set ii 0
drh8bf8dc92003-05-17 17:35:10 +0000211foreach tr_program {
212 {UPDATE tbl SET b = old.b;}
213 {INSERT INTO log VALUES(new.c, 2, 3);}
214 {DELETE FROM log WHERE a = 1;}
danielk1977c3f9bad2002-05-15 08:30:12 +0000215 {INSERT INTO tbl VALUES(500, new.b * 10, 700);
216 UPDATE tbl SET c = old.c;
drh8bf8dc92003-05-17 17:35:10 +0000217 DELETE FROM log;}
danielk1977c3f9bad2002-05-15 08:30:12 +0000218 {INSERT INTO log select * from tbl;}
drh8bf8dc92003-05-17 17:35:10 +0000219} {
danielk1977c3f9bad2002-05-15 08:30:12 +0000220 foreach test_varset [ list \
221 {
222 set statement {UPDATE tbl SET c = 10 WHERE a = 1;}
223 set prep {INSERT INTO tbl VALUES(1, 2, 3);}
224 set newC 10
225 set newB 2
226 set newA 1
227 set oldA 1
228 set oldB 2
229 set oldC 3
230 } \
231 {
232 set statement {DELETE FROM tbl WHERE a = 1;}
233 set prep {INSERT INTO tbl VALUES(1, 2, 3);}
234 set oldA 1
235 set oldB 2
236 set oldC 3
237 } \
238 {
239 set statement {INSERT INTO tbl VALUES(1, 2, 3);}
240 set newA 1
241 set newB 2
242 set newC 3
243 }
244 ] \
245 {
246 set statement {}
247 set prep {}
248 set newA {''}
249 set newB {''}
250 set newC {''}
251 set oldA {''}
252 set oldB {''}
253 set oldC {''}
254
255 incr ii
256
257 eval $test_varset
258
259 set statement_type [string range $statement 0 5]
260 set tr_program_fixed $tr_program
261 if {$statement_type == "DELETE"} {
262 regsub -all new\.a $tr_program_fixed {''} tr_program_fixed
263 regsub -all new\.b $tr_program_fixed {''} tr_program_fixed
264 regsub -all new\.c $tr_program_fixed {''} tr_program_fixed
265 }
266 if {$statement_type == "INSERT"} {
267 regsub -all old\.a $tr_program_fixed {''} tr_program_fixed
268 regsub -all old\.b $tr_program_fixed {''} tr_program_fixed
269 regsub -all old\.c $tr_program_fixed {''} tr_program_fixed
270 }
271
272
273 set tr_program_cooked $tr_program
274 regsub -all new\.a $tr_program_cooked $newA tr_program_cooked
275 regsub -all new\.b $tr_program_cooked $newB tr_program_cooked
276 regsub -all new\.c $tr_program_cooked $newC tr_program_cooked
277 regsub -all old\.a $tr_program_cooked $oldA tr_program_cooked
278 regsub -all old\.b $tr_program_cooked $oldB tr_program_cooked
279 regsub -all old\.c $tr_program_cooked $oldC tr_program_cooked
280
281 catchsql {
282 DROP TABLE tbl;
283 DROP TABLE log;
284 }
drh8bf8dc92003-05-17 17:35:10 +0000285
danielk1977c3f9bad2002-05-15 08:30:12 +0000286 execsql {
287 CREATE TABLE tbl(a PRIMARY KEY, b, c);
288 CREATE TABLE log(a, b, c);
289 }
290
291 set query {SELECT * FROM tbl; SELECT * FROM log;}
drh8bf8dc92003-05-17 17:35:10 +0000292 set prep "$prep; INSERT INTO log VALUES(1, 2, 3);\
293 INSERT INTO log VALUES(10, 20, 30);"
danielk1977c3f9bad2002-05-15 08:30:12 +0000294
295# Check execution of BEFORE programs:
296
297 set before_data [ execsql "$prep $tr_program_cooked $statement $query" ]
298
299 execsql "DELETE FROM tbl; DELETE FROM log; $prep";
drh8bf8dc92003-05-17 17:35:10 +0000300 execsql "CREATE TRIGGER the_trigger BEFORE [string range $statement 0 6]\
301 ON tbl BEGIN $tr_program_fixed END;"
danielk1977c3f9bad2002-05-15 08:30:12 +0000302
drh8bf8dc92003-05-17 17:35:10 +0000303 do_test trigger2-2.$ii-before "execsql {$statement $query}" $before_data
danielk1977c3f9bad2002-05-15 08:30:12 +0000304
305 execsql "DROP TRIGGER the_trigger;"
306 execsql "DELETE FROM tbl; DELETE FROM log;"
307
308# Check execution of AFTER programs
309 set after_data [ execsql "$prep $statement $tr_program_cooked $query" ]
310
311 execsql "DELETE FROM tbl; DELETE FROM log; $prep";
drh8bf8dc92003-05-17 17:35:10 +0000312 execsql "CREATE TRIGGER the_trigger AFTER [string range $statement 0 6]\
313 ON tbl BEGIN $tr_program_fixed END;"
danielk1977c3f9bad2002-05-15 08:30:12 +0000314
drh8bf8dc92003-05-17 17:35:10 +0000315 do_test trigger2-2.$ii-after "execsql {$statement $query}" $after_data
danielk1977c3f9bad2002-05-15 08:30:12 +0000316 execsql "DROP TRIGGER the_trigger;"
drh8bf8dc92003-05-17 17:35:10 +0000317
318 do_test trigger2-2.$ii-integrity {
319 execsql {
320 PRAGMA integrity_check;
321 }
drhed717fe2003-06-15 23:42:24 +0000322 } {ok}
drh8bf8dc92003-05-17 17:35:10 +0000323
danielk1977c3f9bad2002-05-15 08:30:12 +0000324 }
325}
326catchsql {
327 DROP TABLE tbl;
328 DROP TABLE log;
329}
330
331# 3.
332
drh41a3bd02002-09-14 12:04:56 +0000333# trigger2-3.1: UPDATE OF triggers
danielk1977c3f9bad2002-05-15 08:30:12 +0000334execsql {
335 CREATE TABLE tbl (a, b, c, d);
336 CREATE TABLE log (a);
337 INSERT INTO log VALUES (0);
338 INSERT INTO tbl VALUES (0, 0, 0, 0);
339 INSERT INTO tbl VALUES (1, 0, 0, 0);
340 CREATE TRIGGER tbl_after_update_cd BEFORE UPDATE OF c, d ON tbl
341 BEGIN
342 UPDATE log SET a = a + 1;
343 END;
344}
drh41a3bd02002-09-14 12:04:56 +0000345do_test trigger2-3.1 {
danielk1977c3f9bad2002-05-15 08:30:12 +0000346 execsql {
347 UPDATE tbl SET b = 1, c = 10; -- 2
348 UPDATE tbl SET b = 10; -- 0
349 UPDATE tbl SET d = 4 WHERE a = 0; --1
350 UPDATE tbl SET a = 4, b = 10; --0
351 SELECT * FROM log;
352 }
353} {3}
354execsql {
355 DROP TABLE tbl;
356 DROP TABLE log;
357}
358
drh41a3bd02002-09-14 12:04:56 +0000359# trigger2-3.2: WHEN clause
danielk1977c3f9bad2002-05-15 08:30:12 +0000360set when_triggers [ list \
361 {t1 BEFORE INSERT ON tbl WHEN new.a > 20} \
362 {t2 BEFORE INSERT ON tbl WHEN (SELECT count(*) FROM tbl) = 0} ]
363
364execsql {
365 CREATE TABLE tbl (a, b, c, d);
366 CREATE TABLE log (a);
367 INSERT INTO log VALUES (0);
368}
369
370foreach trig $when_triggers {
371 execsql "CREATE TRIGGER $trig BEGIN UPDATE log set a = a + 1; END;"
372}
373
drh41a3bd02002-09-14 12:04:56 +0000374do_test trigger2-3.2 {
danielk1977c3f9bad2002-05-15 08:30:12 +0000375 execsql {
376
377 INSERT INTO tbl VALUES(0, 0, 0, 0); -- 1
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} {1 0 1}
390execsql {
391 DROP TABLE tbl;
392 DROP TABLE log;
393}
drh8bf8dc92003-05-17 17:35:10 +0000394do_test trigger2-3.3 {
395 execsql {
396 PRAGMA integrity_check;
397 }
drhed717fe2003-06-15 23:42:24 +0000398} {ok}
danielk1977c3f9bad2002-05-15 08:30:12 +0000399
400# Simple cascaded trigger
401execsql {
402 CREATE TABLE tblA(a, b);
403 CREATE TABLE tblB(a, b);
404 CREATE TABLE tblC(a, b);
405
406 CREATE TRIGGER tr1 BEFORE INSERT ON tblA BEGIN
407 INSERT INTO tblB values(new.a, new.b);
408 END;
409
410 CREATE TRIGGER tr2 BEFORE INSERT ON tblB BEGIN
411 INSERT INTO tblC values(new.a, new.b);
412 END;
413}
drh41a3bd02002-09-14 12:04:56 +0000414do_test trigger2-4.1 {
danielk1977c3f9bad2002-05-15 08:30:12 +0000415 execsql {
416 INSERT INTO tblA values(1, 2);
417 SELECT * FROM tblA;
418 SELECT * FROM tblB;
419 SELECT * FROM tblC;
420 }
421} {1 2 1 2 1 2}
422execsql {
423 DROP TABLE tblA;
424 DROP TABLE tblB;
425 DROP TABLE tblC;
426}
427
428# Simple recursive trigger
429execsql {
430 CREATE TABLE tbl(a, b, c);
431 CREATE TRIGGER tbl_trig BEFORE INSERT ON tbl
432 BEGIN
433 INSERT INTO tbl VALUES (new.a, new.b, new.c);
434 END;
435}
drh41a3bd02002-09-14 12:04:56 +0000436do_test trigger2-4.2 {
danielk1977c3f9bad2002-05-15 08:30:12 +0000437 execsql {
438 INSERT INTO tbl VALUES (1, 2, 3);
439 select * from tbl;
440 }
441} {1 2 3 1 2 3}
442execsql {
443 DROP TABLE tbl;
444}
445
446# 5.
447execsql {
448 CREATE TABLE tbl(a, b, c);
449 CREATE TRIGGER tbl_trig BEFORE INSERT ON tbl
450 BEGIN
451 INSERT INTO tbl VALUES (1, 2, 3);
452 INSERT INTO tbl VALUES (2, 2, 3);
453 UPDATE tbl set b = 10 WHERE a = 1;
454 DELETE FROM tbl WHERE a = 1;
455 DELETE FROM tbl;
456 END;
457}
drh41a3bd02002-09-14 12:04:56 +0000458do_test trigger2-5 {
danielk1977c3f9bad2002-05-15 08:30:12 +0000459 execsql {
460 INSERT INTO tbl VALUES(100, 200, 300);
461 }
462 db changes
463} {1}
464execsql {
465 DROP TABLE tbl;
466}
467
danielk1977c3f9bad2002-05-15 08:30:12 +0000468# Handling of ON CONFLICT by INSERT statements inside triggers
469execsql {
470 CREATE TABLE tbl (a primary key, b, c);
471 CREATE TRIGGER ai_tbl AFTER INSERT ON tbl BEGIN
472 INSERT OR IGNORE INTO tbl values (new.a, 0, 0);
473 END;
474}
drh41a3bd02002-09-14 12:04:56 +0000475do_test trigger2-6.1a {
danielk1977c3f9bad2002-05-15 08:30:12 +0000476 execsql {
477 BEGIN;
478 INSERT INTO tbl values (1, 2, 3);
479 SELECT * from tbl;
480 }
481} {1 2 3}
drh41a3bd02002-09-14 12:04:56 +0000482do_test trigger2-6.1b {
danielk1977c3f9bad2002-05-15 08:30:12 +0000483 catchsql {
484 INSERT OR ABORT INTO tbl values (2, 2, 3);
485 }
drh37ed48e2003-08-05 13:13:38 +0000486} {1 {column a is not unique}}
drh41a3bd02002-09-14 12:04:56 +0000487do_test trigger2-6.1c {
danielk1977c3f9bad2002-05-15 08:30:12 +0000488 execsql {
489 SELECT * from tbl;
490 }
491} {1 2 3}
drh41a3bd02002-09-14 12:04:56 +0000492do_test trigger2-6.1d {
danielk1977c3f9bad2002-05-15 08:30:12 +0000493 catchsql {
494 INSERT OR FAIL INTO tbl values (2, 2, 3);
495 }
drh37ed48e2003-08-05 13:13:38 +0000496} {1 {column a is not unique}}
drh41a3bd02002-09-14 12:04:56 +0000497do_test trigger2-6.1e {
danielk1977c3f9bad2002-05-15 08:30:12 +0000498 execsql {
499 SELECT * from tbl;
500 }
501} {1 2 3 2 2 3}
drh41a3bd02002-09-14 12:04:56 +0000502do_test trigger2-6.1f {
danielk1977c3f9bad2002-05-15 08:30:12 +0000503 execsql {
504 INSERT OR REPLACE INTO tbl values (2, 2, 3);
505 SELECT * from tbl;
506 }
507} {1 2 3 2 0 0}
drh41a3bd02002-09-14 12:04:56 +0000508do_test trigger2-6.1g {
danielk1977c3f9bad2002-05-15 08:30:12 +0000509 catchsql {
510 INSERT OR ROLLBACK INTO tbl values (3, 2, 3);
511 }
drh37ed48e2003-08-05 13:13:38 +0000512} {1 {column a is not unique}}
drh41a3bd02002-09-14 12:04:56 +0000513do_test trigger2-6.1h {
danielk1977c3f9bad2002-05-15 08:30:12 +0000514 execsql {
515 SELECT * from tbl;
516 }
517} {}
drh4303fee2003-02-15 23:09:17 +0000518execsql {DELETE FROM tbl}
danielk1977c3f9bad2002-05-15 08:30:12 +0000519
520
521# Handling of ON CONFLICT by UPDATE statements inside triggers
522execsql {
523 INSERT INTO tbl values (4, 2, 3);
524 INSERT INTO tbl values (6, 3, 4);
525 CREATE TRIGGER au_tbl AFTER UPDATE ON tbl BEGIN
526 UPDATE OR IGNORE tbl SET a = new.a, c = 10;
527 END;
528}
drh41a3bd02002-09-14 12:04:56 +0000529do_test trigger2-6.2a {
danielk1977c3f9bad2002-05-15 08:30:12 +0000530 execsql {
531 BEGIN;
532 UPDATE tbl SET a = 1 WHERE a = 4;
533 SELECT * from tbl;
534 }
535} {1 2 10 6 3 4}
drh41a3bd02002-09-14 12:04:56 +0000536do_test trigger2-6.2b {
danielk1977c3f9bad2002-05-15 08:30:12 +0000537 catchsql {
538 UPDATE OR ABORT tbl SET a = 4 WHERE a = 1;
539 }
drh37ed48e2003-08-05 13:13:38 +0000540} {1 {column a is not unique}}
drh41a3bd02002-09-14 12:04:56 +0000541do_test trigger2-6.2c {
danielk1977c3f9bad2002-05-15 08:30:12 +0000542 execsql {
543 SELECT * from tbl;
544 }
545} {1 2 10 6 3 4}
drh41a3bd02002-09-14 12:04:56 +0000546do_test trigger2-6.2d {
danielk1977c3f9bad2002-05-15 08:30:12 +0000547 catchsql {
548 UPDATE OR FAIL tbl SET a = 4 WHERE a = 1;
549 }
drh37ed48e2003-08-05 13:13:38 +0000550} {1 {column a is not unique}}
drh41a3bd02002-09-14 12:04:56 +0000551do_test trigger2-6.2e {
danielk1977c3f9bad2002-05-15 08:30:12 +0000552 execsql {
553 SELECT * from tbl;
554 }
555} {4 2 10 6 3 4}
drh4303fee2003-02-15 23:09:17 +0000556do_test trigger2-6.2f.1 {
danielk1977c3f9bad2002-05-15 08:30:12 +0000557 execsql {
558 UPDATE OR REPLACE tbl SET a = 1 WHERE a = 4;
559 SELECT * from tbl;
560 }
561} {1 3 10}
drh4303fee2003-02-15 23:09:17 +0000562do_test trigger2-6.2f.2 {
563 execsql {
564 INSERT INTO tbl VALUES (2, 3, 4);
565 SELECT * FROM tbl;
566 }
567} {1 3 10 2 3 4}
drh41a3bd02002-09-14 12:04:56 +0000568do_test trigger2-6.2g {
danielk1977c3f9bad2002-05-15 08:30:12 +0000569 catchsql {
570 UPDATE OR ROLLBACK tbl SET a = 4 WHERE a = 1;
571 }
drh37ed48e2003-08-05 13:13:38 +0000572} {1 {column a is not unique}}
drh41a3bd02002-09-14 12:04:56 +0000573do_test trigger2-6.2h {
danielk1977c3f9bad2002-05-15 08:30:12 +0000574 execsql {
575 SELECT * from tbl;
576 }
577} {4 2 3 6 3 4}
578execsql {
579 DROP TABLE tbl;
580}
581
582# 7. Triggers on views
drh41a3bd02002-09-14 12:04:56 +0000583do_test trigger2-7.1 {
drh1873cd52002-05-23 00:30:31 +0000584 execsql {
danielk1977c3f9bad2002-05-15 08:30:12 +0000585 CREATE TABLE ab(a, b);
586 CREATE TABLE cd(c, d);
587 INSERT INTO ab VALUES (1, 2);
588 INSERT INTO ab VALUES (0, 0);
589 INSERT INTO cd VALUES (3, 4);
590
591 CREATE TABLE tlog(ii INTEGER PRIMARY KEY,
592 olda, oldb, oldc, oldd, newa, newb, newc, newd);
593
594 CREATE VIEW abcd AS SELECT a, b, c, d FROM ab, cd;
595
danielk1977993b1732002-05-28 06:55:27 +0000596 CREATE TRIGGER before_update INSTEAD OF UPDATE ON abcd BEGIN
danielk1977c3f9bad2002-05-15 08:30:12 +0000597 INSERT INTO tlog VALUES(NULL,
598 old.a, old.b, old.c, old.d, new.a, new.b, new.c, new.d);
599 END;
danielk1977993b1732002-05-28 06:55:27 +0000600 CREATE TRIGGER after_update INSTEAD OF UPDATE ON abcd BEGIN
danielk1977c3f9bad2002-05-15 08:30:12 +0000601 INSERT INTO tlog VALUES(NULL,
602 old.a, old.b, old.c, old.d, new.a, new.b, new.c, new.d);
603 END;
604
danielk1977993b1732002-05-28 06:55:27 +0000605 CREATE TRIGGER before_delete INSTEAD OF DELETE ON abcd BEGIN
danielk1977c3f9bad2002-05-15 08:30:12 +0000606 INSERT INTO tlog VALUES(NULL,
607 old.a, old.b, old.c, old.d, 0, 0, 0, 0);
608 END;
danielk1977993b1732002-05-28 06:55:27 +0000609 CREATE TRIGGER after_delete INSTEAD OF DELETE ON abcd BEGIN
danielk1977c3f9bad2002-05-15 08:30:12 +0000610 INSERT INTO tlog VALUES(NULL,
611 old.a, old.b, old.c, old.d, 0, 0, 0, 0);
612 END;
613
danielk1977993b1732002-05-28 06:55:27 +0000614 CREATE TRIGGER before_insert INSTEAD OF INSERT ON abcd BEGIN
danielk1977c3f9bad2002-05-15 08:30:12 +0000615 INSERT INTO tlog VALUES(NULL,
616 0, 0, 0, 0, new.a, new.b, new.c, new.d);
617 END;
danielk1977993b1732002-05-28 06:55:27 +0000618 CREATE TRIGGER after_insert INSTEAD OF INSERT ON abcd BEGIN
danielk1977c3f9bad2002-05-15 08:30:12 +0000619 INSERT INTO tlog VALUES(NULL,
620 0, 0, 0, 0, new.a, new.b, new.c, new.d);
621 END;
drh1873cd52002-05-23 00:30:31 +0000622 }
drh8bf8dc92003-05-17 17:35:10 +0000623} {};
danielk1977c3f9bad2002-05-15 08:30:12 +0000624
drh41a3bd02002-09-14 12:04:56 +0000625do_test trigger2-7.2 {
danielk1977c3f9bad2002-05-15 08:30:12 +0000626 execsql {
627 UPDATE abcd SET a = 100, b = 5*5 WHERE a = 1;
628 DELETE FROM abcd WHERE a = 1;
629 INSERT INTO abcd VALUES(10, 20, 30, 40);
630 SELECT * FROM tlog;
631 }
632} [ list 1 1 2 3 4 100 25 3 4 \
633 2 1 2 3 4 100 25 3 4 \
danielk1977993b1732002-05-28 06:55:27 +0000634 3 1 2 3 4 0 0 0 0 \
635 4 1 2 3 4 0 0 0 0 \
636 5 0 0 0 0 10 20 30 40 \
637 6 0 0 0 0 10 20 30 40 ]
danielk1977c3f9bad2002-05-15 08:30:12 +0000638
drh5cf590c2003-04-24 01:45:04 +0000639do_test trigger2-7.3 {
640 execsql {
641 DELETE FROM tlog;
642 INSERT INTO abcd VALUES(10, 20, 30, 40);
643 UPDATE abcd SET a = 100, b = 5*5 WHERE a = 1;
644 DELETE FROM abcd WHERE a = 1;
645 SELECT * FROM tlog;
646 }
647} [ list \
648 1 0 0 0 0 10 20 30 40 \
649 2 0 0 0 0 10 20 30 40 \
650 3 1 2 3 4 100 25 3 4 \
651 4 1 2 3 4 100 25 3 4 \
652 5 1 2 3 4 0 0 0 0 \
653 6 1 2 3 4 0 0 0 0 \
654]
655do_test trigger2-7.4 {
656 execsql {
657 DELETE FROM tlog;
658 DELETE FROM abcd WHERE a = 1;
659 INSERT INTO abcd VALUES(10, 20, 30, 40);
660 UPDATE abcd SET a = 100, b = 5*5 WHERE a = 1;
661 SELECT * FROM tlog;
662 }
663} [ list \
664 1 1 2 3 4 0 0 0 0 \
665 2 1 2 3 4 0 0 0 0 \
666 3 0 0 0 0 10 20 30 40 \
667 4 0 0 0 0 10 20 30 40 \
668 5 1 2 3 4 100 25 3 4 \
669 6 1 2 3 4 100 25 3 4 \
670]
671
672do_test trigger2-8.1 {
673 execsql {
674 CREATE TABLE t1(a,b,c);
675 INSERT INTO t1 VALUES(1,2,3);
676 CREATE VIEW v1 AS
677 SELECT a+b AS x, b+c AS y, a+c AS z FROM t1;
678 SELECT * FROM v1;
679 }
680} {3 5 4}
681do_test trigger2-8.2 {
682 execsql {
683 CREATE TABLE v1log(a,b,c,d,e,f);
684 CREATE TRIGGER r1 INSTEAD OF DELETE ON v1 BEGIN
685 INSERT INTO v1log VALUES(OLD.x,NULL,OLD.y,NULL,OLD.z,NULL);
686 END;
687 DELETE FROM v1 WHERE x=1;
688 SELECT * FROM v1log;
689 }
690} {}
691do_test trigger2-8.3 {
692 execsql {
693 DELETE FROM v1 WHERE x=3;
694 SELECT * FROM v1log;
695 }
696} {3 {} 5 {} 4 {}}
697do_test trigger2-8.4 {
698 execsql {
699 INSERT INTO t1 VALUES(4,5,6);
700 DELETE FROM v1log;
701 DELETE FROM v1 WHERE y=11;
702 SELECT * FROM v1log;
703 }
704} {9 {} 11 {} 10 {}}
705do_test trigger2-8.5 {
706 execsql {
707 CREATE TRIGGER r2 INSTEAD OF INSERT ON v1 BEGIN
708 INSERT INTO v1log VALUES(NULL,NEW.x,NULL,NEW.y,NULL,NEW.z);
709 END;
710 DELETE FROM v1log;
711 INSERT INTO v1 VALUES(1,2,3);
712 SELECT * FROM v1log;
713 }
714} {{} 1 {} 2 {} 3}
715do_test trigger2-8.6 {
716 execsql {
717 CREATE TRIGGER r3 INSTEAD OF UPDATE ON v1 BEGIN
718 INSERT INTO v1log VALUES(OLD.x,NEW.x,OLD.y,NEW.y,OLD.z,NEW.z);
719 END;
720 DELETE FROM v1log;
721 UPDATE v1 SET x=x+100, y=y+200, z=z+300;
722 SELECT * FROM v1log;
723 }
724} {3 103 5 205 4 304 9 109 11 211 10 310}
725
drh8bf8dc92003-05-17 17:35:10 +0000726do_test trigger2-9.9 {
727 execsql {PRAGMA integrity_check}
drhed717fe2003-06-15 23:42:24 +0000728} {ok}
drh5cf590c2003-04-24 01:45:04 +0000729
danielk1977c3f9bad2002-05-15 08:30:12 +0000730finish_test