xref: /illumos-gate/usr/src/lib/libsqlite/test/trigger2.test (revision 1da57d551424de5a9d469760be7c4b4d4f10a755)
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