sl@0: # The author disclaims copyright to this source code. In place of sl@0: # a legal notice, here is a blessing: sl@0: # sl@0: # May you do good and not evil. sl@0: # May you find forgiveness for yourself and forgive others. sl@0: # May you share freely, never taking more than you give. sl@0: # sl@0: #*********************************************************************** sl@0: # sl@0: # This file tests creating and dropping triggers, and interaction thereof sl@0: # with the database COMMIT/ROLLBACK logic. sl@0: # sl@0: # 1. CREATE and DROP TRIGGER tests sl@0: # trig-1.1: Error if table does not exist sl@0: # trig-1.2: Error if trigger already exists sl@0: # trig-1.3: Created triggers are deleted if the transaction is rolled back sl@0: # trig-1.4: DROP TRIGGER removes trigger sl@0: # trig-1.5: Dropped triggers are restored if the transaction is rolled back sl@0: # trig-1.6: Error if dropped trigger doesn't exist sl@0: # trig-1.7: Dropping the table automatically drops all triggers sl@0: # trig-1.8: A trigger created on a TEMP table is not inserted into sqlite_master sl@0: # trig-1.9: Ensure that we cannot create a trigger on sqlite_master sl@0: # trig-1.10: sl@0: # trig-1.11: sl@0: # trig-1.12: Ensure that INSTEAD OF triggers cannot be created on tables sl@0: # trig-1.13: Ensure that AFTER triggers cannot be created on views sl@0: # trig-1.14: Ensure that BEFORE triggers cannot be created on views sl@0: # sl@0: sl@0: set testdir [file dirname $argv0] sl@0: source $testdir/tester.tcl sl@0: ifcapable {!trigger} { sl@0: finish_test sl@0: return sl@0: } sl@0: sl@0: do_test trigger1-1.1.1 { sl@0: catchsql { sl@0: CREATE TRIGGER trig UPDATE ON no_such_table BEGIN sl@0: SELECT * from sqlite_master; sl@0: END; sl@0: } sl@0: } {1 {no such table: main.no_such_table}} sl@0: sl@0: ifcapable tempdb { sl@0: do_test trigger1-1.1.2 { sl@0: catchsql { sl@0: CREATE TEMP TRIGGER trig UPDATE ON no_such_table BEGIN sl@0: SELECT * from sqlite_master; sl@0: END; sl@0: } sl@0: } {1 {no such table: no_such_table}} sl@0: } sl@0: sl@0: execsql { sl@0: CREATE TABLE t1(a); sl@0: } sl@0: do_test trigger1-1.1.3 { sl@0: catchsql { sl@0: CREATE TRIGGER trig UPDATE ON t1 FOR EACH STATEMENT BEGIN sl@0: SELECT * FROM sqlite_master; sl@0: END; sl@0: } sl@0: } {1 {near "STATEMENT": syntax error}} sl@0: execsql { sl@0: CREATE TRIGGER tr1 INSERT ON t1 BEGIN sl@0: INSERT INTO t1 values(1); sl@0: END; sl@0: } sl@0: do_test trigger1-1.2.0 { sl@0: catchsql { sl@0: CREATE TRIGGER IF NOT EXISTS tr1 DELETE ON t1 BEGIN sl@0: SELECT * FROM sqlite_master; sl@0: END sl@0: } sl@0: } {0 {}} sl@0: do_test trigger1-1.2.1 { sl@0: catchsql { sl@0: CREATE TRIGGER tr1 DELETE ON t1 BEGIN sl@0: SELECT * FROM sqlite_master; sl@0: END sl@0: } sl@0: } {1 {trigger tr1 already exists}} sl@0: do_test trigger1-1.2.2 { sl@0: catchsql { sl@0: CREATE TRIGGER "tr1" DELETE ON t1 BEGIN sl@0: SELECT * FROM sqlite_master; sl@0: END sl@0: } sl@0: } {1 {trigger "tr1" already exists}} sl@0: do_test trigger1-1.2.3 { sl@0: catchsql { sl@0: CREATE TRIGGER [tr1] DELETE ON t1 BEGIN sl@0: SELECT * FROM sqlite_master; sl@0: END sl@0: } sl@0: } {1 {trigger [tr1] already exists}} sl@0: sl@0: do_test trigger1-1.3 { sl@0: catchsql { sl@0: BEGIN; sl@0: CREATE TRIGGER tr2 INSERT ON t1 BEGIN sl@0: SELECT * from sqlite_master; END; sl@0: ROLLBACK; sl@0: CREATE TRIGGER tr2 INSERT ON t1 BEGIN sl@0: SELECT * from sqlite_master; END; sl@0: } sl@0: } {0 {}} sl@0: sl@0: do_test trigger1-1.4 { sl@0: catchsql { sl@0: DROP TRIGGER IF EXISTS tr1; sl@0: CREATE TRIGGER tr1 DELETE ON t1 BEGIN sl@0: SELECT * FROM sqlite_master; sl@0: END sl@0: } sl@0: } {0 {}} sl@0: sl@0: do_test trigger1-1.5 { sl@0: execsql { sl@0: BEGIN; sl@0: DROP TRIGGER tr2; sl@0: ROLLBACK; sl@0: DROP TRIGGER tr2; sl@0: } sl@0: } {} sl@0: sl@0: do_test trigger1-1.6.1 { sl@0: catchsql { sl@0: DROP TRIGGER IF EXISTS biggles; sl@0: } sl@0: } {0 {}} sl@0: sl@0: do_test trigger1-1.6.2 { sl@0: catchsql { sl@0: DROP TRIGGER biggles; sl@0: } sl@0: } {1 {no such trigger: biggles}} sl@0: sl@0: do_test trigger1-1.7 { sl@0: catchsql { sl@0: DROP TABLE t1; sl@0: DROP TRIGGER tr1; sl@0: } sl@0: } {1 {no such trigger: tr1}} sl@0: sl@0: ifcapable tempdb { sl@0: execsql { sl@0: CREATE TEMP TABLE temp_table(a); sl@0: } sl@0: do_test trigger1-1.8 { sl@0: execsql { sl@0: CREATE TRIGGER temp_trig UPDATE ON temp_table BEGIN sl@0: SELECT * from sqlite_master; sl@0: END; sl@0: SELECT count(*) FROM sqlite_master WHERE name = 'temp_trig'; sl@0: } sl@0: } {0} sl@0: } sl@0: sl@0: do_test trigger1-1.9 { sl@0: catchsql { sl@0: CREATE TRIGGER tr1 AFTER UPDATE ON sqlite_master BEGIN sl@0: SELECT * FROM sqlite_master; sl@0: END; sl@0: } sl@0: } {1 {cannot create trigger on system table}} sl@0: sl@0: # Check to make sure that a DELETE statement within the body of sl@0: # a trigger does not mess up the DELETE that caused the trigger to sl@0: # run in the first place. sl@0: # sl@0: do_test trigger1-1.10 { sl@0: execsql { sl@0: create table t1(a,b); sl@0: insert into t1 values(1,'a'); sl@0: insert into t1 values(2,'b'); sl@0: insert into t1 values(3,'c'); sl@0: insert into t1 values(4,'d'); sl@0: create trigger r1 after delete on t1 for each row begin sl@0: delete from t1 WHERE a=old.a+2; sl@0: end; sl@0: delete from t1 where a=1 OR a=3; sl@0: select * from t1; sl@0: drop table t1; sl@0: } sl@0: } {2 b 4 d} sl@0: sl@0: do_test trigger1-1.11 { sl@0: execsql { sl@0: create table t1(a,b); sl@0: insert into t1 values(1,'a'); sl@0: insert into t1 values(2,'b'); sl@0: insert into t1 values(3,'c'); sl@0: insert into t1 values(4,'d'); sl@0: create trigger r1 after update on t1 for each row begin sl@0: delete from t1 WHERE a=old.a+2; sl@0: end; sl@0: update t1 set b='x-' || b where a=1 OR a=3; sl@0: select * from t1; sl@0: drop table t1; sl@0: } sl@0: } {1 x-a 2 b 4 d} sl@0: sl@0: # Ensure that we cannot create INSTEAD OF triggers on tables sl@0: do_test trigger1-1.12 { sl@0: catchsql { sl@0: create table t1(a,b); sl@0: create trigger t1t instead of update on t1 for each row begin sl@0: delete from t1 WHERE a=old.a+2; sl@0: end; sl@0: } sl@0: } {1 {cannot create INSTEAD OF trigger on table: main.t1}} sl@0: sl@0: ifcapable view { sl@0: # Ensure that we cannot create BEFORE triggers on views sl@0: do_test trigger1-1.13 { sl@0: catchsql { sl@0: create view v1 as select * from t1; sl@0: create trigger v1t before update on v1 for each row begin sl@0: delete from t1 WHERE a=old.a+2; sl@0: end; sl@0: } sl@0: } {1 {cannot create BEFORE trigger on view: main.v1}} sl@0: # Ensure that we cannot create AFTER triggers on views sl@0: do_test trigger1-1.14 { sl@0: catchsql { sl@0: drop view v1; sl@0: create view v1 as select * from t1; sl@0: create trigger v1t AFTER update on v1 for each row begin sl@0: delete from t1 WHERE a=old.a+2; sl@0: end; sl@0: } sl@0: } {1 {cannot create AFTER trigger on view: main.v1}} sl@0: } ;# ifcapable view sl@0: sl@0: # Check for memory leaks in the trigger parser sl@0: # sl@0: do_test trigger1-2.1 { sl@0: catchsql { sl@0: CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN sl@0: SELECT * FROM; -- Syntax error sl@0: END; sl@0: } sl@0: } {1 {near ";": syntax error}} sl@0: do_test trigger1-2.2 { sl@0: catchsql { sl@0: CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN sl@0: SELECT * FROM t1; sl@0: SELECT * FROM; -- Syntax error sl@0: END; sl@0: } sl@0: } {1 {near ";": syntax error}} sl@0: sl@0: # Create a trigger that refers to a table that might not exist. sl@0: # sl@0: ifcapable tempdb { sl@0: do_test trigger1-3.1 { sl@0: execsql { sl@0: CREATE TEMP TABLE t2(x,y); sl@0: } sl@0: catchsql { sl@0: CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN sl@0: INSERT INTO t2 VALUES(NEW.a,NEW.b); sl@0: END; sl@0: } sl@0: } {0 {}} sl@0: do_test trigger-3.2 { sl@0: catchsql { sl@0: INSERT INTO t1 VALUES(1,2); sl@0: SELECT * FROM t2; sl@0: } sl@0: } {1 {no such table: main.t2}} sl@0: do_test trigger-3.3 { sl@0: db close sl@0: set rc [catch {sqlite3 db test.db} err] sl@0: if {$rc} {lappend rc $err} sl@0: set rc sl@0: } {0} sl@0: do_test trigger-3.4 { sl@0: catchsql { sl@0: INSERT INTO t1 VALUES(1,2); sl@0: SELECT * FROM t2; sl@0: } sl@0: } {1 {no such table: main.t2}} sl@0: do_test trigger-3.5 { sl@0: catchsql { sl@0: CREATE TEMP TABLE t2(x,y); sl@0: INSERT INTO t1 VALUES(1,2); sl@0: SELECT * FROM t2; sl@0: } sl@0: } {1 {no such table: main.t2}} sl@0: do_test trigger-3.6 { sl@0: catchsql { sl@0: DROP TRIGGER r1; sl@0: CREATE TEMP TRIGGER r1 AFTER INSERT ON t1 BEGIN sl@0: INSERT INTO t2 VALUES(NEW.a,NEW.b); sl@0: END; sl@0: INSERT INTO t1 VALUES(1,2); sl@0: SELECT * FROM t2; sl@0: } sl@0: } {0 {1 2}} sl@0: do_test trigger-3.7 { sl@0: execsql { sl@0: DROP TABLE t2; sl@0: CREATE TABLE t2(x,y); sl@0: SELECT * FROM t2; sl@0: } sl@0: } {} sl@0: sl@0: # There are two versions of trigger-3.8 and trigger-3.9. One that uses sl@0: # compound SELECT statements, and another that does not. sl@0: ifcapable compound { sl@0: do_test trigger1-3.8 { sl@0: execsql { sl@0: INSERT INTO t1 VALUES(3,4); sl@0: SELECT * FROM t1 UNION ALL SELECT * FROM t2; sl@0: } sl@0: } {1 2 3 4 3 4} sl@0: do_test trigger1-3.9 { sl@0: db close sl@0: sqlite3 db test.db sl@0: execsql { sl@0: INSERT INTO t1 VALUES(5,6); sl@0: SELECT * FROM t1 UNION ALL SELECT * FROM t2; sl@0: } sl@0: } {1 2 3 4 5 6 3 4} sl@0: } ;# ifcapable compound sl@0: ifcapable !compound { sl@0: do_test trigger1-3.8 { sl@0: execsql { sl@0: INSERT INTO t1 VALUES(3,4); sl@0: SELECT * FROM t1; sl@0: SELECT * FROM t2; sl@0: } sl@0: } {1 2 3 4 3 4} sl@0: do_test trigger1-3.9 { sl@0: db close sl@0: sqlite3 db test.db sl@0: execsql { sl@0: INSERT INTO t1 VALUES(5,6); sl@0: SELECT * FROM t1; sl@0: SELECT * FROM t2; sl@0: } sl@0: } {1 2 3 4 5 6 3 4} sl@0: } ;# ifcapable !compound sl@0: sl@0: do_test trigger1-4.1 { sl@0: execsql { sl@0: CREATE TEMP TRIGGER r1 BEFORE INSERT ON t1 BEGIN sl@0: INSERT INTO t2 VALUES(NEW.a,NEW.b); sl@0: END; sl@0: INSERT INTO t1 VALUES(7,8); sl@0: SELECT * FROM t2; sl@0: } sl@0: } {3 4 7 8} sl@0: do_test trigger1-4.2 { sl@0: sqlite3 db2 test.db sl@0: execsql { sl@0: INSERT INTO t1 VALUES(9,10); sl@0: } db2; sl@0: db2 close sl@0: execsql { sl@0: SELECT * FROM t2; sl@0: } sl@0: } {3 4 7 8} sl@0: do_test trigger1-4.3 { sl@0: execsql { sl@0: DROP TABLE t1; sl@0: SELECT * FROM t2; sl@0: }; sl@0: } {3 4 7 8} sl@0: do_test trigger1-4.4 { sl@0: db close sl@0: sqlite3 db test.db sl@0: execsql { sl@0: SELECT * FROM t2; sl@0: }; sl@0: } {3 4 7 8} sl@0: } else { sl@0: execsql { sl@0: CREATE TABLE t2(x,y); sl@0: DROP TABLE t1; sl@0: INSERT INTO t2 VALUES(3, 4); sl@0: INSERT INTO t2 VALUES(7, 8); sl@0: } sl@0: } sl@0: sl@0: sl@0: integrity_check trigger1-5.1 sl@0: sl@0: # Create a trigger with the same name as a table. Make sure the sl@0: # trigger works. Then drop the trigger. Make sure the table is sl@0: # still there. sl@0: # sl@0: set view_v1 {} sl@0: ifcapable view { sl@0: set view_v1 {view v1} sl@0: } sl@0: do_test trigger1-6.1 { sl@0: execsql {SELECT type, name FROM sqlite_master} sl@0: } [concat $view_v1 {table t2}] sl@0: do_test trigger1-6.2 { sl@0: execsql { sl@0: CREATE TRIGGER t2 BEFORE DELETE ON t2 BEGIN sl@0: SELECT RAISE(ABORT,'deletes are not allows'); sl@0: END; sl@0: SELECT type, name FROM sqlite_master; sl@0: } sl@0: } [concat $view_v1 {table t2 trigger t2}] sl@0: do_test trigger1-6.3 { sl@0: catchsql {DELETE FROM t2} sl@0: } {1 {deletes are not allows}} sl@0: do_test trigger1-6.4 { sl@0: execsql {SELECT * FROM t2} sl@0: } {3 4 7 8} sl@0: do_test trigger1-6.5 { sl@0: db close sl@0: sqlite3 db test.db sl@0: execsql {SELECT type, name FROM sqlite_master} sl@0: } [concat $view_v1 {table t2 trigger t2}] sl@0: do_test trigger1-6.6 { sl@0: execsql { sl@0: DROP TRIGGER t2; sl@0: SELECT type, name FROM sqlite_master; sl@0: } sl@0: } [concat $view_v1 {table t2}] sl@0: do_test trigger1-6.7 { sl@0: execsql {SELECT * FROM t2} sl@0: } {3 4 7 8} sl@0: do_test trigger1-6.8 { sl@0: db close sl@0: sqlite3 db test.db sl@0: execsql {SELECT * FROM t2} sl@0: } {3 4 7 8} sl@0: sl@0: integrity_check trigger-7.1 sl@0: sl@0: # Check to make sure the name of a trigger can be quoted so that keywords sl@0: # can be used as trigger names. Ticket #468 sl@0: # sl@0: do_test trigger1-8.1 { sl@0: execsql { sl@0: CREATE TRIGGER 'trigger' AFTER INSERT ON t2 BEGIN SELECT 1; END; sl@0: SELECT name FROM sqlite_master WHERE type='trigger'; sl@0: } sl@0: } {trigger} sl@0: do_test trigger1-8.2 { sl@0: execsql { sl@0: DROP TRIGGER 'trigger'; sl@0: SELECT name FROM sqlite_master WHERE type='trigger'; sl@0: } sl@0: } {} sl@0: do_test trigger1-8.3 { sl@0: execsql { sl@0: CREATE TRIGGER "trigger" AFTER INSERT ON t2 BEGIN SELECT 1; END; sl@0: SELECT name FROM sqlite_master WHERE type='trigger'; sl@0: } sl@0: } {trigger} sl@0: do_test trigger1-8.4 { sl@0: execsql { sl@0: DROP TRIGGER "trigger"; sl@0: SELECT name FROM sqlite_master WHERE type='trigger'; sl@0: } sl@0: } {} sl@0: do_test trigger1-8.5 { sl@0: execsql { sl@0: CREATE TRIGGER [trigger] AFTER INSERT ON t2 BEGIN SELECT 1; END; sl@0: SELECT name FROM sqlite_master WHERE type='trigger'; sl@0: } sl@0: } {trigger} sl@0: do_test trigger1-8.6 { sl@0: execsql { sl@0: DROP TRIGGER [trigger]; sl@0: SELECT name FROM sqlite_master WHERE type='trigger'; sl@0: } sl@0: } {} sl@0: sl@0: ifcapable conflict { sl@0: # Make sure REPLACE works inside of triggers. sl@0: # sl@0: # There are two versions of trigger-9.1 and trigger-9.2. One that uses sl@0: # compound SELECT statements, and another that does not. sl@0: ifcapable compound { sl@0: do_test trigger1-9.1 { sl@0: execsql { sl@0: CREATE TABLE t3(a,b); sl@0: CREATE TABLE t4(x UNIQUE, b); sl@0: CREATE TRIGGER r34 AFTER INSERT ON t3 BEGIN sl@0: REPLACE INTO t4 VALUES(new.a,new.b); sl@0: END; sl@0: INSERT INTO t3 VALUES(1,2); sl@0: SELECT * FROM t3 UNION ALL SELECT 99, 99 UNION ALL SELECT * FROM t4; sl@0: } sl@0: } {1 2 99 99 1 2} sl@0: do_test trigger1-9.2 { sl@0: execsql { sl@0: INSERT INTO t3 VALUES(1,3); sl@0: SELECT * FROM t3 UNION ALL SELECT 99, 99 UNION ALL SELECT * FROM t4; sl@0: } sl@0: } {1 2 1 3 99 99 1 3} sl@0: } else { sl@0: do_test trigger1-9.1 { sl@0: execsql { sl@0: CREATE TABLE t3(a,b); sl@0: CREATE TABLE t4(x UNIQUE, b); sl@0: CREATE TRIGGER r34 AFTER INSERT ON t3 BEGIN sl@0: REPLACE INTO t4 VALUES(new.a,new.b); sl@0: END; sl@0: INSERT INTO t3 VALUES(1,2); sl@0: SELECT * FROM t3; SELECT 99, 99; SELECT * FROM t4; sl@0: } sl@0: } {1 2 99 99 1 2} sl@0: do_test trigger1-9.2 { sl@0: execsql { sl@0: INSERT INTO t3 VALUES(1,3); sl@0: SELECT * FROM t3; SELECT 99, 99; SELECT * FROM t4; sl@0: } sl@0: } {1 2 1 3 99 99 1 3} sl@0: } sl@0: execsql { sl@0: DROP TABLE t3; sl@0: DROP TABLE t4; sl@0: } sl@0: } sl@0: sl@0: sl@0: # Ticket #764. At one stage TEMP triggers would fail to re-install when the sl@0: # schema was reloaded. The following tests ensure that TEMP triggers are sl@0: # correctly re-installed. sl@0: # sl@0: # Also verify that references within trigger programs are resolved at sl@0: # statement compile time, not trigger installation time. This means, for sl@0: # example, that you can drop and re-create tables referenced by triggers. sl@0: ifcapable tempdb&&attach { sl@0: do_test trigger1-10.0 { sl@0: file delete -force test2.db sl@0: file delete -force test2.db-journal sl@0: execsql { sl@0: ATTACH 'test2.db' AS aux; sl@0: } sl@0: } {} sl@0: do_test trigger1-10.1 { sl@0: execsql { sl@0: CREATE TABLE main.t4(a, b, c); sl@0: CREATE TABLE temp.t4(a, b, c); sl@0: CREATE TABLE aux.t4(a, b, c); sl@0: CREATE TABLE insert_log(db, a, b, c); sl@0: } sl@0: } {} sl@0: do_test trigger1-10.2 { sl@0: execsql { sl@0: CREATE TEMP TRIGGER trig1 AFTER INSERT ON main.t4 BEGIN sl@0: INSERT INTO insert_log VALUES('main', new.a, new.b, new.c); sl@0: END; sl@0: CREATE TEMP TRIGGER trig2 AFTER INSERT ON temp.t4 BEGIN sl@0: INSERT INTO insert_log VALUES('temp', new.a, new.b, new.c); sl@0: END; sl@0: CREATE TEMP TRIGGER trig3 AFTER INSERT ON aux.t4 BEGIN sl@0: INSERT INTO insert_log VALUES('aux', new.a, new.b, new.c); sl@0: END; sl@0: } sl@0: } {} sl@0: do_test trigger1-10.3 { sl@0: execsql { sl@0: INSERT INTO main.t4 VALUES(1, 2, 3); sl@0: INSERT INTO temp.t4 VALUES(4, 5, 6); sl@0: INSERT INTO aux.t4 VALUES(7, 8, 9); sl@0: } sl@0: } {} sl@0: do_test trigger1-10.4 { sl@0: execsql { sl@0: SELECT * FROM insert_log; sl@0: } sl@0: } {main 1 2 3 temp 4 5 6 aux 7 8 9} sl@0: do_test trigger1-10.5 { sl@0: execsql { sl@0: BEGIN; sl@0: INSERT INTO main.t4 VALUES(1, 2, 3); sl@0: INSERT INTO temp.t4 VALUES(4, 5, 6); sl@0: INSERT INTO aux.t4 VALUES(7, 8, 9); sl@0: ROLLBACK; sl@0: } sl@0: } {} sl@0: do_test trigger1-10.6 { sl@0: execsql { sl@0: SELECT * FROM insert_log; sl@0: } sl@0: } {main 1 2 3 temp 4 5 6 aux 7 8 9} sl@0: do_test trigger1-10.7 { sl@0: execsql { sl@0: DELETE FROM insert_log; sl@0: INSERT INTO main.t4 VALUES(11, 12, 13); sl@0: INSERT INTO temp.t4 VALUES(14, 15, 16); sl@0: INSERT INTO aux.t4 VALUES(17, 18, 19); sl@0: } sl@0: } {} sl@0: do_test trigger1-10.8 { sl@0: execsql { sl@0: SELECT * FROM insert_log; sl@0: } sl@0: } {main 11 12 13 temp 14 15 16 aux 17 18 19} sl@0: do_test trigger1-10.8 { sl@0: # Drop and re-create the insert_log table in a different database. Note sl@0: # that we can change the column names because the trigger programs don't sl@0: # use them explicitly. sl@0: execsql { sl@0: DROP TABLE insert_log; sl@0: CREATE TABLE aux.insert_log(db, d, e, f); sl@0: } sl@0: } {} sl@0: do_test trigger1-10.10 { sl@0: execsql { sl@0: INSERT INTO main.t4 VALUES(21, 22, 23); sl@0: INSERT INTO temp.t4 VALUES(24, 25, 26); sl@0: INSERT INTO aux.t4 VALUES(27, 28, 29); sl@0: } sl@0: } {} sl@0: do_test trigger1-10.11 { sl@0: execsql { sl@0: SELECT * FROM insert_log; sl@0: } sl@0: } {main 21 22 23 temp 24 25 26 aux 27 28 29} sl@0: } sl@0: sl@0: do_test trigger1-11.1 { sl@0: catchsql {SELECT raise(abort,'message');} sl@0: } {1 {RAISE() may only be used within a trigger-program}} sl@0: sl@0: sl@0: finish_test