OLD | NEW |
| (Empty) |
1 # 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 # This file tests creating and dropping triggers, and interaction thereof | |
11 # with the database COMMIT/ROLLBACK logic. | |
12 # | |
13 # 1. CREATE and DROP TRIGGER tests | |
14 # trigger1-1.1: Error if table does not exist | |
15 # trigger1-1.2: Error if trigger already exists | |
16 # trigger1-1.3: Created triggers are deleted if the transaction is rolled back | |
17 # trigger1-1.4: DROP TRIGGER removes trigger | |
18 # trigger1-1.5: Dropped triggers are restored if the transaction is rolled back | |
19 # trigger1-1.6: Error if dropped trigger doesn't exist | |
20 # trigger1-1.7: Dropping the table automatically drops all triggers | |
21 # trigger1-1.8: A trigger created on a TEMP table is not inserted into sqlite_ma
ster | |
22 # trigger1-1.9: Ensure that we cannot create a trigger on sqlite_master | |
23 # trigger1-1.10: | |
24 # trigger1-1.11: | |
25 # trigger1-1.12: Ensure that INSTEAD OF triggers cannot be created on tables | |
26 # trigger1-1.13: Ensure that AFTER triggers cannot be created on views | |
27 # trigger1-1.14: Ensure that BEFORE triggers cannot be created on views | |
28 # | |
29 | |
30 set testdir [file dirname $argv0] | |
31 source $testdir/tester.tcl | |
32 ifcapable !trigger||!compound { | |
33 finish_test | |
34 return | |
35 } | |
36 | |
37 do_test trigger1-1.1.1 { | |
38 catchsql { | |
39 CREATE TRIGGER trig UPDATE ON no_such_table BEGIN | |
40 SELECT * from sqlite_master; | |
41 END; | |
42 } | |
43 } {1 {no such table: main.no_such_table}} | |
44 | |
45 ifcapable tempdb { | |
46 do_test trigger1-1.1.2 { | |
47 catchsql { | |
48 CREATE TEMP TRIGGER trig UPDATE ON no_such_table BEGIN | |
49 SELECT * from sqlite_master; | |
50 END; | |
51 } | |
52 } {1 {no such table: no_such_table}} | |
53 } | |
54 | |
55 execsql { | |
56 CREATE TABLE t1(a); | |
57 } | |
58 do_test trigger1-1.1.3 { | |
59 catchsql { | |
60 CREATE TRIGGER trig UPDATE ON t1 FOR EACH STATEMENT BEGIN | |
61 SELECT * FROM sqlite_master; | |
62 END; | |
63 } | |
64 } {1 {near "STATEMENT": syntax error}} | |
65 execsql { | |
66 CREATE TRIGGER tr1 INSERT ON t1 BEGIN | |
67 INSERT INTO t1 values(1); | |
68 END; | |
69 } | |
70 do_test trigger1-1.2.0 { | |
71 catchsql { | |
72 CREATE TRIGGER IF NOT EXISTS tr1 DELETE ON t1 BEGIN | |
73 SELECT * FROM sqlite_master; | |
74 END | |
75 } | |
76 } {0 {}} | |
77 do_test trigger1-1.2.1 { | |
78 catchsql { | |
79 CREATE TRIGGER tr1 DELETE ON t1 BEGIN | |
80 SELECT * FROM sqlite_master; | |
81 END | |
82 } | |
83 } {1 {trigger tr1 already exists}} | |
84 do_test trigger1-1.2.2 { | |
85 catchsql { | |
86 CREATE TRIGGER "tr1" DELETE ON t1 BEGIN | |
87 SELECT * FROM sqlite_master; | |
88 END | |
89 } | |
90 } {1 {trigger "tr1" already exists}} | |
91 do_test trigger1-1.2.3 { | |
92 catchsql { | |
93 CREATE TRIGGER [tr1] DELETE ON t1 BEGIN | |
94 SELECT * FROM sqlite_master; | |
95 END | |
96 } | |
97 } {1 {trigger [tr1] already exists}} | |
98 | |
99 do_test trigger1-1.3 { | |
100 catchsql { | |
101 BEGIN; | |
102 CREATE TRIGGER tr2 INSERT ON t1 BEGIN | |
103 SELECT * from sqlite_master; END; | |
104 ROLLBACK; | |
105 CREATE TRIGGER tr2 INSERT ON t1 BEGIN | |
106 SELECT * from sqlite_master; END; | |
107 } | |
108 } {0 {}} | |
109 | |
110 do_test trigger1-1.4 { | |
111 catchsql { | |
112 DROP TRIGGER IF EXISTS tr1; | |
113 CREATE TRIGGER tr1 DELETE ON t1 BEGIN | |
114 SELECT * FROM sqlite_master; | |
115 END | |
116 } | |
117 } {0 {}} | |
118 | |
119 do_test trigger1-1.5 { | |
120 execsql { | |
121 BEGIN; | |
122 DROP TRIGGER tr2; | |
123 ROLLBACK; | |
124 DROP TRIGGER tr2; | |
125 } | |
126 } {} | |
127 | |
128 do_test trigger1-1.6.1 { | |
129 catchsql { | |
130 DROP TRIGGER IF EXISTS biggles; | |
131 } | |
132 } {0 {}} | |
133 | |
134 do_test trigger1-1.6.2 { | |
135 catchsql { | |
136 DROP TRIGGER biggles; | |
137 } | |
138 } {1 {no such trigger: biggles}} | |
139 | |
140 do_test trigger1-1.7 { | |
141 catchsql { | |
142 DROP TABLE t1; | |
143 DROP TRIGGER tr1; | |
144 } | |
145 } {1 {no such trigger: tr1}} | |
146 | |
147 ifcapable tempdb { | |
148 execsql { | |
149 CREATE TEMP TABLE temp_table(a); | |
150 } | |
151 do_test trigger1-1.8 { | |
152 execsql { | |
153 CREATE TRIGGER temp_trig UPDATE ON temp_table BEGIN | |
154 SELECT * from sqlite_master; | |
155 END; | |
156 SELECT count(*) FROM sqlite_master WHERE name = 'temp_trig'; | |
157 } | |
158 } {0} | |
159 } | |
160 | |
161 do_test trigger1-1.9 { | |
162 catchsql { | |
163 CREATE TRIGGER tr1 AFTER UPDATE ON sqlite_master BEGIN | |
164 SELECT * FROM sqlite_master; | |
165 END; | |
166 } | |
167 } {1 {cannot create trigger on system table}} | |
168 | |
169 # Check to make sure that a DELETE statement within the body of | |
170 # a trigger does not mess up the DELETE that caused the trigger to | |
171 # run in the first place. | |
172 # | |
173 do_test trigger1-1.10 { | |
174 execsql { | |
175 create table t1(a,b); | |
176 insert into t1 values(1,'a'); | |
177 insert into t1 values(2,'b'); | |
178 insert into t1 values(3,'c'); | |
179 insert into t1 values(4,'d'); | |
180 create trigger r1 after delete on t1 for each row begin | |
181 delete from t1 WHERE a=old.a+2; | |
182 end; | |
183 delete from t1 where a=1 OR a=3; | |
184 select * from t1; | |
185 drop table t1; | |
186 } | |
187 } {2 b 4 d} | |
188 | |
189 do_test trigger1-1.11 { | |
190 execsql { | |
191 create table t1(a,b); | |
192 insert into t1 values(1,'a'); | |
193 insert into t1 values(2,'b'); | |
194 insert into t1 values(3,'c'); | |
195 insert into t1 values(4,'d'); | |
196 create trigger r1 after update on t1 for each row begin | |
197 delete from t1 WHERE a=old.a+2; | |
198 end; | |
199 update t1 set b='x-' || b where a=1 OR a=3; | |
200 select * from t1; | |
201 drop table t1; | |
202 } | |
203 } {1 x-a 2 b 4 d} | |
204 | |
205 # Ensure that we cannot create INSTEAD OF triggers on tables | |
206 do_test trigger1-1.12 { | |
207 catchsql { | |
208 create table t1(a,b); | |
209 create trigger t1t instead of update on t1 for each row begin | |
210 delete from t1 WHERE a=old.a+2; | |
211 end; | |
212 } | |
213 } {1 {cannot create INSTEAD OF trigger on table: t1}} | |
214 | |
215 ifcapable view { | |
216 # Ensure that we cannot create BEFORE triggers on views | |
217 do_test trigger1-1.13 { | |
218 catchsql { | |
219 create view v1 as select * from t1; | |
220 create trigger v1t before update on v1 for each row begin | |
221 delete from t1 WHERE a=old.a+2; | |
222 end; | |
223 } | |
224 } {1 {cannot create BEFORE trigger on view: v1}} | |
225 # Ensure that we cannot create AFTER triggers on views | |
226 do_test trigger1-1.14 { | |
227 catchsql { | |
228 drop view v1; | |
229 create view v1 as select * from t1; | |
230 create trigger v1t AFTER update on v1 for each row begin | |
231 delete from t1 WHERE a=old.a+2; | |
232 end; | |
233 } | |
234 } {1 {cannot create AFTER trigger on view: v1}} | |
235 } ;# ifcapable view | |
236 | |
237 # Check for memory leaks in the trigger parser | |
238 # | |
239 do_test trigger1-2.1 { | |
240 catchsql { | |
241 CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN | |
242 SELECT * FROM; -- Syntax error | |
243 END; | |
244 } | |
245 } {1 {near ";": syntax error}} | |
246 do_test trigger1-2.2 { | |
247 catchsql { | |
248 CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN | |
249 SELECT * FROM t1; | |
250 SELECT * FROM; -- Syntax error | |
251 END; | |
252 } | |
253 } {1 {near ";": syntax error}} | |
254 | |
255 # Create a trigger that refers to a table that might not exist. | |
256 # | |
257 ifcapable tempdb { | |
258 do_test trigger1-3.1 { | |
259 execsql { | |
260 CREATE TEMP TABLE t2(x,y); | |
261 } | |
262 catchsql { | |
263 CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN | |
264 INSERT INTO t2 VALUES(NEW.a,NEW.b); | |
265 END; | |
266 } | |
267 } {0 {}} | |
268 do_test trigger1-3.2 { | |
269 catchsql { | |
270 INSERT INTO t1 VALUES(1,2); | |
271 SELECT * FROM t2; | |
272 } | |
273 } {1 {no such table: main.t2}} | |
274 do_test trigger1-3.3 { | |
275 db close | |
276 set rc [catch {sqlite3 db test.db} err] | |
277 if {$rc} {lappend rc $err} | |
278 set rc | |
279 } {0} | |
280 do_test trigger1-3.4 { | |
281 catchsql { | |
282 INSERT INTO t1 VALUES(1,2); | |
283 SELECT * FROM t2; | |
284 } | |
285 } {1 {no such table: main.t2}} | |
286 do_test trigger1-3.5 { | |
287 catchsql { | |
288 CREATE TEMP TABLE t2(x,y); | |
289 INSERT INTO t1 VALUES(1,2); | |
290 SELECT * FROM t2; | |
291 } | |
292 } {1 {no such table: main.t2}} | |
293 do_test trigger1-3.6.1 { | |
294 catchsql { | |
295 DROP TRIGGER r1; | |
296 CREATE TEMP TRIGGER r1 AFTER INSERT ON t1 BEGIN | |
297 INSERT INTO t2 VALUES(NEW.a,NEW.b), (NEW.b*100, NEW.a*100); | |
298 END; | |
299 INSERT INTO t1 VALUES(1,2); | |
300 SELECT * FROM t2; | |
301 } | |
302 } {0 {1 2 200 100}} | |
303 do_test trigger1-3.6.2 { | |
304 catchsql { | |
305 DROP TRIGGER r1; | |
306 DELETE FROM t1; | |
307 DELETE FROM t2; | |
308 CREATE TEMP TRIGGER r1 AFTER INSERT ON t1 BEGIN | |
309 INSERT INTO t2 VALUES(NEW.a,NEW.b); | |
310 END; | |
311 INSERT INTO t1 VALUES(1,2); | |
312 SELECT * FROM t2; | |
313 } | |
314 } {0 {1 2}} | |
315 do_test trigger1-3.7 { | |
316 execsql { | |
317 DROP TABLE t2; | |
318 CREATE TABLE t2(x,y); | |
319 SELECT * FROM t2; | |
320 } | |
321 } {} | |
322 | |
323 # There are two versions of trigger1-3.8 and trigger1-3.9. One that uses | |
324 # compound SELECT statements, and another that does not. | |
325 ifcapable compound { | |
326 do_test trigger1-3.8 { | |
327 execsql { | |
328 INSERT INTO t1 VALUES(3,4); | |
329 SELECT * FROM t1 UNION ALL SELECT * FROM t2; | |
330 } | |
331 } {1 2 3 4 3 4} | |
332 do_test trigger1-3.9 { | |
333 db close | |
334 sqlite3 db test.db | |
335 execsql { | |
336 INSERT INTO t1 VALUES(5,6); | |
337 SELECT * FROM t1 UNION ALL SELECT * FROM t2; | |
338 } | |
339 } {1 2 3 4 5 6 3 4} | |
340 } ;# ifcapable compound | |
341 ifcapable !compound { | |
342 do_test trigger1-3.8 { | |
343 execsql { | |
344 INSERT INTO t1 VALUES(3,4); | |
345 SELECT * FROM t1; | |
346 SELECT * FROM t2; | |
347 } | |
348 } {1 2 3 4 3 4} | |
349 do_test trigger1-3.9 { | |
350 db close | |
351 sqlite3 db test.db | |
352 execsql { | |
353 INSERT INTO t1 VALUES(5,6); | |
354 SELECT * FROM t1; | |
355 SELECT * FROM t2; | |
356 } | |
357 } {1 2 3 4 5 6 3 4} | |
358 } ;# ifcapable !compound | |
359 | |
360 do_test trigger1-4.1 { | |
361 execsql { | |
362 CREATE TEMP TRIGGER r1 BEFORE INSERT ON t1 BEGIN | |
363 INSERT INTO t2 VALUES(NEW.a,NEW.b); | |
364 END; | |
365 INSERT INTO t1 VALUES(7,8); | |
366 SELECT * FROM t2; | |
367 } | |
368 } {3 4 7 8} | |
369 do_test trigger1-4.2 { | |
370 sqlite3 db2 test.db | |
371 execsql { | |
372 INSERT INTO t1 VALUES(9,10); | |
373 } db2; | |
374 db2 close | |
375 execsql { | |
376 SELECT * FROM t2; | |
377 } | |
378 } {3 4 7 8} | |
379 do_test trigger1-4.3 { | |
380 execsql { | |
381 DROP TABLE t1; | |
382 SELECT * FROM t2; | |
383 }; | |
384 } {3 4 7 8} | |
385 do_test trigger1-4.4 { | |
386 db close | |
387 sqlite3 db test.db | |
388 execsql { | |
389 SELECT * FROM t2; | |
390 }; | |
391 } {3 4 7 8} | |
392 } else { | |
393 execsql { | |
394 CREATE TABLE t2(x,y); | |
395 DROP TABLE t1; | |
396 INSERT INTO t2 VALUES(3, 4); | |
397 INSERT INTO t2 VALUES(7, 8); | |
398 } | |
399 } | |
400 | |
401 | |
402 integrity_check trigger1-5.1 | |
403 | |
404 # Create a trigger with the same name as a table. Make sure the | |
405 # trigger works. Then drop the trigger. Make sure the table is | |
406 # still there. | |
407 # | |
408 set view_v1 {} | |
409 ifcapable view { | |
410 set view_v1 {view v1} | |
411 } | |
412 do_test trigger1-6.1 { | |
413 execsql {SELECT type, name FROM sqlite_master} | |
414 } [concat $view_v1 {table t2}] | |
415 do_test trigger1-6.2 { | |
416 execsql { | |
417 CREATE TRIGGER t2 BEFORE DELETE ON t2 BEGIN | |
418 SELECT RAISE(ABORT,'deletes are not permitted'); | |
419 END; | |
420 SELECT type, name FROM sqlite_master; | |
421 } | |
422 } [concat $view_v1 {table t2 trigger t2}] | |
423 do_test trigger1-6.3 { | |
424 catchsql {DELETE FROM t2} | |
425 } {1 {deletes are not permitted}} | |
426 verify_ex_errcode trigger1-6.3b SQLITE_CONSTRAINT_TRIGGER | |
427 do_test trigger1-6.4 { | |
428 execsql {SELECT * FROM t2} | |
429 } {3 4 7 8} | |
430 do_test trigger1-6.5 { | |
431 db close | |
432 sqlite3 db test.db | |
433 execsql {SELECT type, name FROM sqlite_master} | |
434 } [concat $view_v1 {table t2 trigger t2}] | |
435 do_test trigger1-6.6 { | |
436 execsql { | |
437 DROP TRIGGER t2; | |
438 SELECT type, name FROM sqlite_master; | |
439 } | |
440 } [concat $view_v1 {table t2}] | |
441 do_test trigger1-6.7 { | |
442 execsql {SELECT * FROM t2} | |
443 } {3 4 7 8} | |
444 do_test trigger1-6.8 { | |
445 db close | |
446 sqlite3 db test.db | |
447 execsql {SELECT * FROM t2} | |
448 } {3 4 7 8} | |
449 | |
450 integrity_check trigger1-7.1 | |
451 | |
452 # Check to make sure the name of a trigger can be quoted so that keywords | |
453 # can be used as trigger names. Ticket #468 | |
454 # | |
455 do_test trigger1-8.1 { | |
456 execsql { | |
457 CREATE TRIGGER 'trigger' AFTER INSERT ON t2 BEGIN SELECT 1; END; | |
458 SELECT name FROM sqlite_master WHERE type='trigger'; | |
459 } | |
460 } {trigger} | |
461 do_test trigger1-8.2 { | |
462 execsql { | |
463 DROP TRIGGER 'trigger'; | |
464 SELECT name FROM sqlite_master WHERE type='trigger'; | |
465 } | |
466 } {} | |
467 do_test trigger1-8.3 { | |
468 execsql { | |
469 CREATE TRIGGER "trigger" AFTER INSERT ON t2 BEGIN SELECT 1; END; | |
470 SELECT name FROM sqlite_master WHERE type='trigger'; | |
471 } | |
472 } {trigger} | |
473 do_test trigger1-8.4 { | |
474 execsql { | |
475 DROP TRIGGER "trigger"; | |
476 SELECT name FROM sqlite_master WHERE type='trigger'; | |
477 } | |
478 } {} | |
479 do_test trigger1-8.5 { | |
480 execsql { | |
481 CREATE TRIGGER [trigger] AFTER INSERT ON t2 BEGIN SELECT 1; END; | |
482 SELECT name FROM sqlite_master WHERE type='trigger'; | |
483 } | |
484 } {trigger} | |
485 do_test trigger1-8.6 { | |
486 execsql { | |
487 DROP TRIGGER [trigger]; | |
488 SELECT name FROM sqlite_master WHERE type='trigger'; | |
489 } | |
490 } {} | |
491 | |
492 ifcapable conflict { | |
493 # Make sure REPLACE works inside of triggers. | |
494 # | |
495 # There are two versions of trigger1-9.1 and trigger1-9.2. One that uses | |
496 # compound SELECT statements, and another that does not. | |
497 ifcapable compound { | |
498 do_test trigger1-9.1 { | |
499 execsql { | |
500 CREATE TABLE t3(a,b); | |
501 CREATE TABLE t4(x UNIQUE, b); | |
502 CREATE TRIGGER r34 AFTER INSERT ON t3 BEGIN | |
503 REPLACE INTO t4 VALUES(new.a,new.b); | |
504 END; | |
505 INSERT INTO t3 VALUES(1,2); | |
506 SELECT * FROM t3 UNION ALL SELECT 99, 99 UNION ALL SELECT * FROM t4; | |
507 } | |
508 } {1 2 99 99 1 2} | |
509 do_test trigger1-9.2 { | |
510 execsql { | |
511 INSERT INTO t3 VALUES(1,3); | |
512 SELECT * FROM t3 UNION ALL SELECT 99, 99 UNION ALL SELECT * FROM t4; | |
513 } | |
514 } {1 2 1 3 99 99 1 3} | |
515 } else { | |
516 do_test trigger1-9.1 { | |
517 execsql { | |
518 CREATE TABLE t3(a,b); | |
519 CREATE TABLE t4(x UNIQUE, b); | |
520 CREATE TRIGGER r34 AFTER INSERT ON t3 BEGIN | |
521 REPLACE INTO t4 VALUES(new.a,new.b); | |
522 END; | |
523 INSERT INTO t3 VALUES(1,2); | |
524 SELECT * FROM t3; SELECT 99, 99; SELECT * FROM t4; | |
525 } | |
526 } {1 2 99 99 1 2} | |
527 do_test trigger1-9.2 { | |
528 execsql { | |
529 INSERT INTO t3 VALUES(1,3); | |
530 SELECT * FROM t3; SELECT 99, 99; SELECT * FROM t4; | |
531 } | |
532 } {1 2 1 3 99 99 1 3} | |
533 } | |
534 execsql { | |
535 DROP TABLE t3; | |
536 DROP TABLE t4; | |
537 } | |
538 } | |
539 | |
540 | |
541 # Ticket #764. At one stage TEMP triggers would fail to re-install when the | |
542 # schema was reloaded. The following tests ensure that TEMP triggers are | |
543 # correctly re-installed. | |
544 # | |
545 # Also verify that references within trigger programs are resolved at | |
546 # statement compile time, not trigger installation time. This means, for | |
547 # example, that you can drop and re-create tables referenced by triggers. | |
548 ifcapable tempdb&&attach { | |
549 do_test trigger1-10.0 { | |
550 forcedelete test2.db | |
551 forcedelete test2.db-journal | |
552 execsql { | |
553 ATTACH 'test2.db' AS aux; | |
554 } | |
555 } {} | |
556 do_test trigger1-10.1 { | |
557 execsql { | |
558 CREATE TABLE main.t4(a, b, c); | |
559 CREATE TABLE temp.t4(a, b, c); | |
560 CREATE TABLE aux.t4(a, b, c); | |
561 CREATE TABLE insert_log(db, a, b, c); | |
562 } | |
563 } {} | |
564 do_test trigger1-10.2 { | |
565 execsql { | |
566 CREATE TEMP TRIGGER trig1 AFTER INSERT ON main.t4 BEGIN | |
567 INSERT INTO insert_log VALUES('main', new.a, new.b, new.c); | |
568 END; | |
569 CREATE TEMP TRIGGER trig2 AFTER INSERT ON temp.t4 BEGIN | |
570 INSERT INTO insert_log VALUES('temp', new.a, new.b, new.c); | |
571 END; | |
572 CREATE TEMP TRIGGER trig3 AFTER INSERT ON aux.t4 BEGIN | |
573 INSERT INTO insert_log VALUES('aux', new.a, new.b, new.c); | |
574 END; | |
575 } | |
576 } {} | |
577 do_test trigger1-10.3 { | |
578 execsql { | |
579 INSERT INTO main.t4 VALUES(1, 2, 3); | |
580 INSERT INTO temp.t4 VALUES(4, 5, 6); | |
581 INSERT INTO aux.t4 VALUES(7, 8, 9); | |
582 } | |
583 } {} | |
584 do_test trigger1-10.4 { | |
585 execsql { | |
586 SELECT * FROM insert_log; | |
587 } | |
588 } {main 1 2 3 temp 4 5 6 aux 7 8 9} | |
589 do_test trigger1-10.5 { | |
590 execsql { | |
591 BEGIN; | |
592 INSERT INTO main.t4 VALUES(1, 2, 3); | |
593 INSERT INTO temp.t4 VALUES(4, 5, 6); | |
594 INSERT INTO aux.t4 VALUES(7, 8, 9); | |
595 ROLLBACK; | |
596 } | |
597 } {} | |
598 do_test trigger1-10.6 { | |
599 execsql { | |
600 SELECT * FROM insert_log; | |
601 } | |
602 } {main 1 2 3 temp 4 5 6 aux 7 8 9} | |
603 do_test trigger1-10.7 { | |
604 execsql { | |
605 DELETE FROM insert_log; | |
606 INSERT INTO main.t4 VALUES(11, 12, 13); | |
607 INSERT INTO temp.t4 VALUES(14, 15, 16); | |
608 INSERT INTO aux.t4 VALUES(17, 18, 19); | |
609 } | |
610 } {} | |
611 do_test trigger1-10.8 { | |
612 execsql { | |
613 SELECT * FROM insert_log; | |
614 } | |
615 } {main 11 12 13 temp 14 15 16 aux 17 18 19} | |
616 do_test trigger1-10.9 { | |
617 # Drop and re-create the insert_log table in a different database. Note | |
618 # that we can change the column names because the trigger programs don't | |
619 # use them explicitly. | |
620 execsql { | |
621 DROP TABLE insert_log; | |
622 CREATE TABLE aux.insert_log(db, d, e, f); | |
623 } | |
624 } {} | |
625 do_test trigger1-10.10 { | |
626 execsql { | |
627 INSERT INTO main.t4 VALUES(21, 22, 23); | |
628 INSERT INTO temp.t4 VALUES(24, 25, 26); | |
629 INSERT INTO aux.t4 VALUES(27, 28, 29); | |
630 } | |
631 } {} | |
632 do_test trigger1-10.11 { | |
633 execsql { | |
634 SELECT * FROM insert_log; | |
635 } | |
636 } {main 21 22 23 temp 24 25 26 aux 27 28 29} | |
637 } | |
638 | |
639 do_test trigger1-11.1 { | |
640 catchsql {SELECT raise(abort,'message');} | |
641 } {1 {RAISE() may only be used within a trigger-program}} | |
642 | |
643 do_test trigger1-15.1 { | |
644 execsql { | |
645 CREATE TABLE tA(a INTEGER PRIMARY KEY, b, c); | |
646 CREATE TRIGGER tA_trigger BEFORE UPDATE ON "tA" BEGIN SELECT 1; END; | |
647 INSERT INTO tA VALUES(1, 2, 3); | |
648 } | |
649 catchsql { UPDATE tA SET a = 'abc' } | |
650 } {1 {datatype mismatch}} | |
651 do_test trigger1-15.2 { | |
652 catchsql { INSERT INTO tA VALUES('abc', 2, 3) } | |
653 } {1 {datatype mismatch}} | |
654 | |
655 # Ticket #3947: Do not allow qualified table names on INSERT, UPDATE, and | |
656 # DELETE statements within triggers. Actually, this has never been allowed | |
657 # by the grammar. But the error message is confusing: one simply gets a | |
658 # "syntax error". That has now been changed to give a full error message. | |
659 # | |
660 do_test trigger1-16.1 { | |
661 db eval { | |
662 CREATE TABLE t16(a,b,c); | |
663 CREATE INDEX t16a ON t16(a); | |
664 CREATE INDEX t16b ON t16(b); | |
665 } | |
666 catchsql { | |
667 CREATE TRIGGER main.t16err1 AFTER INSERT ON tA BEGIN | |
668 INSERT INTO main.t16 VALUES(1,2,3); | |
669 END; | |
670 } | |
671 } {1 {qualified table names are not allowed on INSERT, UPDATE, and DELETE statem
ents within triggers}} | |
672 do_test trigger1-16.2 { | |
673 catchsql { | |
674 CREATE TRIGGER main.t16err2 AFTER INSERT ON tA BEGIN | |
675 UPDATE main.t16 SET rowid=rowid+1; | |
676 END; | |
677 } | |
678 } {1 {qualified table names are not allowed on INSERT, UPDATE, and DELETE statem
ents within triggers}} | |
679 do_test trigger1-16.3 { | |
680 catchsql { | |
681 CREATE TRIGGER main.t16err3 AFTER INSERT ON tA BEGIN | |
682 DELETE FROM main.t16; | |
683 END; | |
684 } | |
685 } {1 {qualified table names are not allowed on INSERT, UPDATE, and DELETE statem
ents within triggers}} | |
686 do_test trigger1-16.4 { | |
687 catchsql { | |
688 CREATE TRIGGER main.t16err4 AFTER INSERT ON tA BEGIN | |
689 UPDATE t16 NOT INDEXED SET rowid=rowid+1; | |
690 END; | |
691 } | |
692 } {1 {the NOT INDEXED clause is not allowed on UPDATE or DELETE statements withi
n triggers}} | |
693 do_test trigger1-16.5 { | |
694 catchsql { | |
695 CREATE TRIGGER main.t16err5 AFTER INSERT ON tA BEGIN | |
696 UPDATE t16 INDEXED BY t16a SET rowid=rowid+1 WHERE a=1; | |
697 END; | |
698 } | |
699 } {1 {the INDEXED BY clause is not allowed on UPDATE or DELETE statements within
triggers}} | |
700 do_test trigger1-16.6 { | |
701 catchsql { | |
702 CREATE TRIGGER main.t16err6 AFTER INSERT ON tA BEGIN | |
703 DELETE FROM t16 NOT INDEXED WHERE a=123; | |
704 END; | |
705 } | |
706 } {1 {the NOT INDEXED clause is not allowed on UPDATE or DELETE statements withi
n triggers}} | |
707 do_test trigger1-16.7 { | |
708 catchsql { | |
709 CREATE TRIGGER main.t16err7 AFTER INSERT ON tA BEGIN | |
710 DELETE FROM t16 INDEXED BY t16a WHERE a=123; | |
711 END; | |
712 } | |
713 } {1 {the INDEXED BY clause is not allowed on UPDATE or DELETE statements within
triggers}} | |
714 | |
715 finish_test | |
OLD | NEW |