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