Snapshot of upstream SQLite 3.43.2
[sqlcipher.git] / test / trigger9.test
blob6e31d1af972f456150f986135427953ec12a8da7
1 # 2008 January 1
3 # The author disclaims copyright to this source code.  In place of
4 # a legal notice, here is a blessing:
6 #    May you do good and not evil.
7 #    May you find forgiveness for yourself and forgive others.
8 #    May you share freely, never taking more than you give.
10 #***********************************************************************
11 # This file implements regression tests for SQLite library. Specifically,
12 # it tests some compiler optimizations for SQL statements featuring
13 # triggers:
18 # trigger9-1.* -   Test that if there are no references to OLD.* cols, or a
19 #                  reference to only OLD.rowid, the data is not loaded.
21 # trigger9-2.* -   Test that for NEW.* records populated by UPDATE 
22 #                  statements, unused fields are populated with NULL values. 
24 # trigger9-3.* -   Test that the temporary tables used for OLD.* references
25 #                  in "INSTEAD OF" triggers have NULL values in unused 
26 #                  fields.
29 set testdir [file dirname $argv0]
30 source $testdir/tester.tcl
31 ifcapable {!trigger} {
32   finish_test
33   return
35 set ::testprefix trigger9
37 proc has_rowdata {sql} {
38   expr {[lsearch [execsql "explain $sql"] RowData]>=0}
41 do_test trigger9-1.1 {
42   execsql {
43     PRAGMA page_size = 1024;
44     CREATE TABLE t1(x, y, z);
45     INSERT INTO t1 VALUES('1', randstr(10000,10000), '2');
46     INSERT INTO t1 VALUES('2', randstr(10000,10000), '4');
47     INSERT INTO t1 VALUES('3', randstr(10000,10000), '6');
48     CREATE TABLE t2(x);
49   }
50 } {}
52 do_test trigger9-1.2.1 {
53   execsql {
54     BEGIN;
55       CREATE TRIGGER trig1 BEFORE DELETE ON t1 BEGIN
56         INSERT INTO t2 VALUES(old.rowid);
57       END;
58       DELETE FROM t1;
59       SELECT * FROM t2;
60   }
61 } {1 2 3}
62 do_test trigger9-1.2.3 {
63   has_rowdata {DELETE FROM t1}
64 } 0
65 do_test trigger9-1.2.4 { execsql { ROLLBACK } } {}
67 do_test trigger9-1.3.1 {
68   execsql {
69     BEGIN;
70       CREATE TRIGGER trig1 BEFORE DELETE ON t1 BEGIN
71         INSERT INTO t2 VALUES(old.x);
72       END;
73       DELETE FROM t1;
74       SELECT * FROM t2;
75   }
76 } {1 2 3}
77 do_test trigger9-1.3.2 {
78   has_rowdata {DELETE FROM t1}
79 } 0
80 do_test trigger9-1.3.3 { execsql { ROLLBACK } } {}
82 do_test trigger9-1.4.1 {
83   execsql {
84     BEGIN;
85       CREATE TRIGGER trig1 BEFORE DELETE ON t1 WHEN old.x='1' BEGIN
86         INSERT INTO t2 VALUES(old.rowid);
87       END;
88       DELETE FROM t1;
89       SELECT * FROM t2;
90   }
91 } {1}
92 do_test trigger9-1.4.2 {
93   has_rowdata {DELETE FROM t1}
94 } 0
95 do_test trigger9-1.4.3 { execsql { ROLLBACK } } {}
97 do_test trigger9-1.5.1 {
98   execsql {
99     BEGIN;
100       CREATE TRIGGER trig1 BEFORE UPDATE ON t1 BEGIN
101         INSERT INTO t2 VALUES(old.rowid);
102       END;
103       UPDATE t1 SET y = '';
104       SELECT * FROM t2;
105   }
106 } {1 2 3}
107 do_test trigger9-1.5.2 {
108   has_rowdata {UPDATE t1 SET y = ''}
109 } 0
110 do_test trigger9-1.5.3 { execsql { ROLLBACK } } {}
112 do_test trigger9-1.6.1 {
113   execsql {
114     BEGIN;
115       CREATE TRIGGER trig1 BEFORE UPDATE ON t1 BEGIN
116         INSERT INTO t2 VALUES(old.x);
117       END;
118       UPDATE t1 SET y = '';
119       SELECT * FROM t2;
120   }
121 } {1 2 3}
122 do_test trigger9-1.6.2 {
123   has_rowdata {UPDATE t1 SET y = ''}
124 } 0
125 do_test trigger9-1.6.3 { execsql { ROLLBACK } } {}
127 do_test trigger9-1.7.1 {
128   execsql {
129     BEGIN;
130       CREATE TRIGGER trig1 BEFORE UPDATE ON t1 WHEN old.x>='2' BEGIN
131         INSERT INTO t2 VALUES(old.x);
132       END;
133       UPDATE t1 SET y = '';
134       SELECT * FROM t2;
135   }
136 } {2 3}
137 do_test trigger9-1.7.2 {
138   has_rowdata {UPDATE t1 SET y = ''}
139 } 0
140 do_test trigger9-1.7.3 { execsql { ROLLBACK } } {}
142 do_test trigger9-3.1 {
143   execsql {
144     CREATE TABLE t3(a, b);
145     INSERT INTO t3 VALUES(1, 'one');
146     INSERT INTO t3 VALUES(2, 'two');
147     INSERT INTO t3 VALUES(3, 'three');
148   }
149 } {}
150 do_test trigger9-3.2 {
151   execsql {
152     BEGIN;
153       CREATE VIEW v1 AS SELECT * FROM t3;
154       CREATE TRIGGER trig1 INSTEAD OF UPDATE ON v1 BEGIN
155         INSERT INTO t2 VALUES(old.a);
156       END;
157       UPDATE v1 SET b = 'hello';
158       SELECT * FROM t2;
159     ROLLBACK;
160   }
161 } {1 2 3}
162 do_test trigger9-3.3 {
163   # In this test the 'c' column of the view is not required by
164   # the INSTEAD OF trigger, but the expression is reused internally as
165   # part of the view's WHERE clause. Check that this does not cause
166   # a problem.
167   #
168   execsql {
169     BEGIN;
170       CREATE VIEW v1 AS SELECT a, b AS c FROM t3 WHERE c > 'one';
171       CREATE TRIGGER trig1 INSTEAD OF UPDATE ON v1 BEGIN
172         INSERT INTO t2 VALUES(old.a);
173       END;
174       UPDATE v1 SET c = 'hello';
175       SELECT * FROM t2;
176     ROLLBACK;
177   }
178 } {2 3}
179 do_test trigger9-3.4 {
180   execsql {
181     BEGIN;
182       INSERT INTO t3 VALUES(3, 'three');
183       INSERT INTO t3 VALUES(3, 'four');
184       CREATE VIEW v1 AS SELECT DISTINCT a, b FROM t3;
185       CREATE TRIGGER trig1 INSTEAD OF UPDATE ON v1 BEGIN
186         INSERT INTO t2 VALUES(old.a);
187       END;
188       UPDATE v1 SET b = 'hello';
189       SELECT * FROM t2;
190     ROLLBACK;
191   }
192 } {1 2 3 3}
194 ifcapable compound {
195   do_test trigger9-3.5 {
196     execsql {
197       BEGIN;
198         INSERT INTO t3 VALUES(1, 'uno');
199         CREATE VIEW v1 AS SELECT a, b FROM t3 EXCEPT SELECT 1, 'one';
200         CREATE TRIGGER trig1 INSTEAD OF UPDATE ON v1 BEGIN
201           INSERT INTO t2 VALUES(old.a);
202         END;
203         UPDATE v1 SET b = 'hello';
204         SELECT * FROM t2;
205       ROLLBACK;
206     }
207   } {1 2 3}
208   do_test trigger9-3.6 {
209     execsql {
210       BEGIN;
211         INSERT INTO t3 VALUES(1, 'zero');
212         CREATE VIEW v1 AS 
213           SELECT sum(a) AS a, max(b) AS b FROM t3 GROUP BY t3.a HAVING b>'two';
214         CREATE TRIGGER trig1 INSTEAD OF UPDATE ON v1 BEGIN
215           INSERT INTO t2 VALUES(old.a);
216         END;
217         UPDATE v1 SET b = 'hello';
218         SELECT * FROM t2;
219       ROLLBACK;
220     }
221   } {2}
224 reset_db
225 do_execsql_test 4.1 {
226   CREATE TABLE t1(a, b);
227   CREATE TABLE log(x);
228   INSERT INTO t1 VALUES(1, 2);
229   INSERT INTO t1 VALUES(3, 4);
230   CREATE VIEW v1 AS SELECT a, b FROM t1;
232   CREATE TRIGGER tr1 INSTEAD OF DELETE ON v1 BEGIN
233     INSERT INTO log VALUES('delete');
234   END;
236   CREATE TRIGGER tr2 INSTEAD OF UPDATE ON v1 BEGIN
237     INSERT INTO log VALUES('update');
238   END;
240   CREATE TRIGGER tr3 INSTEAD OF INSERT ON v1 BEGIN
241     INSERT INTO log VALUES('insert');
242   END;
245 do_catchsql_test 4.2 {
246   DELETE FROM v1 WHERE rowid=1;
247 } {1 {no such column: rowid}}
249 do_catchsql_test 4.3 {
250   UPDATE v1 SET a=b WHERE rowid=2;
251 } {1 {no such column: rowid}}
253 finish_test