xref: /sqlite-3.40.0/test/trigger1.test (revision 4c460bbf)
1c3f9bad2Sdanielk1977# The author disclaims copyright to this source code.  In place of
2c3f9bad2Sdanielk1977# a legal notice, here is a blessing:
3c3f9bad2Sdanielk1977#
4c3f9bad2Sdanielk1977#    May you do good and not evil.
5c3f9bad2Sdanielk1977#    May you find forgiveness for yourself and forgive others.
6c3f9bad2Sdanielk1977#    May you share freely, never taking more than you give.
7c3f9bad2Sdanielk1977#
8c3f9bad2Sdanielk1977#***********************************************************************
9c3f9bad2Sdanielk1977#
10c3f9bad2Sdanielk1977# This file tests creating and dropping triggers, and interaction thereof
11c3f9bad2Sdanielk1977# with the database COMMIT/ROLLBACK logic.
12c3f9bad2Sdanielk1977#
13c3f9bad2Sdanielk1977# 1. CREATE and DROP TRIGGER tests
143038cfe9Smistachkin# trigger1-1.1: Error if table does not exist
153038cfe9Smistachkin# trigger1-1.2: Error if trigger already exists
163038cfe9Smistachkin# trigger1-1.3: Created triggers are deleted if the transaction is rolled back
173038cfe9Smistachkin# trigger1-1.4: DROP TRIGGER removes trigger
183038cfe9Smistachkin# trigger1-1.5: Dropped triggers are restored if the transaction is rolled back
193038cfe9Smistachkin# trigger1-1.6: Error if dropped trigger doesn't exist
203038cfe9Smistachkin# trigger1-1.7: Dropping the table automatically drops all triggers
213038cfe9Smistachkin# trigger1-1.8: A trigger created on a TEMP table is not inserted into sqlite_master
223038cfe9Smistachkin# trigger1-1.9: Ensure that we cannot create a trigger on sqlite_master
233038cfe9Smistachkin# trigger1-1.10:
243038cfe9Smistachkin# trigger1-1.11:
253038cfe9Smistachkin# trigger1-1.12: Ensure that INSTEAD OF triggers cannot be created on tables
263038cfe9Smistachkin# trigger1-1.13: Ensure that AFTER triggers cannot be created on views
273038cfe9Smistachkin# trigger1-1.14: Ensure that BEFORE triggers cannot be created on views
28c3f9bad2Sdanielk1977#
29c3f9bad2Sdanielk1977
30c3f9bad2Sdanielk1977set testdir [file dirname $argv0]
31c3f9bad2Sdanielk1977source $testdir/tester.tcl
322f56da3fSdanifcapable !trigger||!compound {
33b7f9164eSdrh  finish_test
34b7f9164eSdrh  return
35b7f9164eSdrh}
36c3f9bad2Sdanielk1977
37b7f9164eSdrhdo_test trigger1-1.1.1 {
38c3f9bad2Sdanielk1977   catchsql {
39c3f9bad2Sdanielk1977     CREATE TRIGGER trig UPDATE ON no_such_table BEGIN
40c3f9bad2Sdanielk1977       SELECT * from sqlite_master;
41c3f9bad2Sdanielk1977     END;
42c3f9bad2Sdanielk1977   }
43ef2cb63eSdanielk1977} {1 {no such table: main.no_such_table}}
4453c0f748Sdanielk1977
4553c0f748Sdanielk1977ifcapable tempdb {
4679a519c0Sdrh  do_test trigger1-1.1.2 {
4779a519c0Sdrh     catchsql {
4879a519c0Sdrh       CREATE TEMP TRIGGER trig UPDATE ON no_such_table BEGIN
4979a519c0Sdrh         SELECT * from sqlite_master;
5079a519c0Sdrh       END;
5179a519c0Sdrh     }
5279a519c0Sdrh  } {1 {no such table: no_such_table}}
5353c0f748Sdanielk1977}
54c3f9bad2Sdanielk1977
55c3f9bad2Sdanielk1977execsql {
56c3f9bad2Sdanielk1977    CREATE TABLE t1(a);
57c3f9bad2Sdanielk1977}
5860218d2aSdrhdo_test trigger1-1.1.3 {
5960218d2aSdrh  catchsql {
6060218d2aSdrh     CREATE TRIGGER trig UPDATE ON t1 FOR EACH STATEMENT BEGIN
6160218d2aSdrh        SELECT * FROM sqlite_master;
6260218d2aSdrh     END;
6360218d2aSdrh  }
6460218d2aSdrh} {1 {near "STATEMENT": syntax error}}
65c3f9bad2Sdanielk1977execsql {
66c3f9bad2Sdanielk1977        CREATE TRIGGER tr1 INSERT ON t1 BEGIN
67c3f9bad2Sdanielk1977          INSERT INTO t1 values(1);
68c3f9bad2Sdanielk1977         END;
69c3f9bad2Sdanielk1977}
70fdd48a76Sdrhdo_test trigger1-1.2.0 {
71fdd48a76Sdrh    catchsql {
72fdd48a76Sdrh        CREATE TRIGGER IF NOT EXISTS tr1 DELETE ON t1 BEGIN
73fdd48a76Sdrh            SELECT * FROM sqlite_master;
74fdd48a76Sdrh         END
75fdd48a76Sdrh     }
76fdd48a76Sdrh} {0 {}}
77e4df0e74Sdrhdo_test trigger1-1.2.1 {
78c3f9bad2Sdanielk1977    catchsql {
79c3f9bad2Sdanielk1977        CREATE TRIGGER tr1 DELETE ON t1 BEGIN
80c3f9bad2Sdanielk1977            SELECT * FROM sqlite_master;
81c3f9bad2Sdanielk1977         END
82c3f9bad2Sdanielk1977     }
83c3f9bad2Sdanielk1977} {1 {trigger tr1 already exists}}
84e4df0e74Sdrhdo_test trigger1-1.2.2 {
85e4df0e74Sdrh    catchsql {
86e4df0e74Sdrh        CREATE TRIGGER "tr1" DELETE ON t1 BEGIN
87e4df0e74Sdrh            SELECT * FROM sqlite_master;
88e4df0e74Sdrh         END
89e4df0e74Sdrh     }
90e4df0e74Sdrh} {1 {trigger "tr1" already exists}}
91e4df0e74Sdrhdo_test trigger1-1.2.3 {
92e4df0e74Sdrh    catchsql {
93e4df0e74Sdrh        CREATE TRIGGER [tr1] DELETE ON t1 BEGIN
94e4df0e74Sdrh            SELECT * FROM sqlite_master;
95e4df0e74Sdrh         END
96e4df0e74Sdrh     }
97e4df0e74Sdrh} {1 {trigger [tr1] already exists}}
98c3f9bad2Sdanielk1977
9941a3bd0aSdrhdo_test trigger1-1.3 {
100c3f9bad2Sdanielk1977    catchsql {
101c3f9bad2Sdanielk1977        BEGIN;
102c3f9bad2Sdanielk1977        CREATE TRIGGER tr2 INSERT ON t1 BEGIN
103c3f9bad2Sdanielk1977            SELECT * from sqlite_master; END;
104c3f9bad2Sdanielk1977        ROLLBACK;
105c3f9bad2Sdanielk1977        CREATE TRIGGER tr2 INSERT ON t1 BEGIN
106c3f9bad2Sdanielk1977            SELECT * from sqlite_master; END;
107c3f9bad2Sdanielk1977    }
108c3f9bad2Sdanielk1977} {0 {}}
109c3f9bad2Sdanielk1977
11041a3bd0aSdrhdo_test trigger1-1.4 {
111c3f9bad2Sdanielk1977    catchsql {
112fdd48a76Sdrh        DROP TRIGGER IF EXISTS tr1;
113c3f9bad2Sdanielk1977        CREATE TRIGGER tr1 DELETE ON t1 BEGIN
114c3f9bad2Sdanielk1977            SELECT * FROM sqlite_master;
115c3f9bad2Sdanielk1977        END
116c3f9bad2Sdanielk1977    }
117c3f9bad2Sdanielk1977} {0 {}}
118c3f9bad2Sdanielk1977
11941a3bd0aSdrhdo_test trigger1-1.5 {
120c3f9bad2Sdanielk1977    execsql {
121c3f9bad2Sdanielk1977        BEGIN;
122c3f9bad2Sdanielk1977        DROP TRIGGER tr2;
123c3f9bad2Sdanielk1977        ROLLBACK;
124c3f9bad2Sdanielk1977        DROP TRIGGER tr2;
125c3f9bad2Sdanielk1977    }
126c3f9bad2Sdanielk1977} {}
127c3f9bad2Sdanielk1977
128fdd48a76Sdrhdo_test trigger1-1.6.1 {
129fdd48a76Sdrh    catchsql {
130fdd48a76Sdrh        DROP TRIGGER IF EXISTS biggles;
131fdd48a76Sdrh    }
132fdd48a76Sdrh} {0 {}}
133fdd48a76Sdrh
134fdd48a76Sdrhdo_test trigger1-1.6.2 {
135c3f9bad2Sdanielk1977    catchsql {
136c3f9bad2Sdanielk1977        DROP TRIGGER biggles;
137c3f9bad2Sdanielk1977    }
138c3f9bad2Sdanielk1977} {1 {no such trigger: biggles}}
139c3f9bad2Sdanielk1977
14041a3bd0aSdrhdo_test trigger1-1.7 {
141c3f9bad2Sdanielk1977    catchsql {
142c3f9bad2Sdanielk1977        DROP TABLE t1;
143c3f9bad2Sdanielk1977        DROP TRIGGER tr1;
144c3f9bad2Sdanielk1977    }
145c3f9bad2Sdanielk1977} {1 {no such trigger: tr1}}
146c3f9bad2Sdanielk1977
14753c0f748Sdanielk1977ifcapable tempdb {
148c3f9bad2Sdanielk1977  execsql {
149c3f9bad2Sdanielk1977    CREATE TEMP TABLE temp_table(a);
150c3f9bad2Sdanielk1977  }
15141a3bd0aSdrh  do_test trigger1-1.8 {
152c3f9bad2Sdanielk1977    execsql {
153c3f9bad2Sdanielk1977          CREATE TRIGGER temp_trig UPDATE ON temp_table BEGIN
154c3f9bad2Sdanielk1977              SELECT * from sqlite_master;
155c3f9bad2Sdanielk1977          END;
156c3f9bad2Sdanielk1977          SELECT count(*) FROM sqlite_master WHERE name = 'temp_trig';
157c3f9bad2Sdanielk1977    }
158c3f9bad2Sdanielk1977  } {0}
15953c0f748Sdanielk1977}
160c3f9bad2Sdanielk1977
16141a3bd0aSdrhdo_test trigger1-1.9 {
1621873cd50Sdrh  catchsql {
1631873cd50Sdrh    CREATE TRIGGER tr1 AFTER UPDATE ON sqlite_master BEGIN
1641873cd50Sdrh       SELECT * FROM sqlite_master;
1651873cd50Sdrh    END;
1661873cd50Sdrh  }
1670be9df07Sdrh} {1 {cannot create trigger on system table}}
1681873cd50Sdrh
16907d6e3a7Sdrh# Check to make sure that a DELETE statement within the body of
17007d6e3a7Sdrh# a trigger does not mess up the DELETE that caused the trigger to
17107d6e3a7Sdrh# run in the first place.
17207d6e3a7Sdrh#
17341a3bd0aSdrhdo_test trigger1-1.10 {
17407d6e3a7Sdrh  execsql {
17507d6e3a7Sdrh    create table t1(a,b);
17607d6e3a7Sdrh    insert into t1 values(1,'a');
17707d6e3a7Sdrh    insert into t1 values(2,'b');
17807d6e3a7Sdrh    insert into t1 values(3,'c');
17907d6e3a7Sdrh    insert into t1 values(4,'d');
18007d6e3a7Sdrh    create trigger r1 after delete on t1 for each row begin
18107d6e3a7Sdrh      delete from t1 WHERE a=old.a+2;
18207d6e3a7Sdrh    end;
183e61b9f4fSdanielk1977    delete from t1 where a=1 OR a=3;
18407d6e3a7Sdrh    select * from t1;
18507d6e3a7Sdrh    drop table t1;
186c3f9bad2Sdanielk1977  }
18707d6e3a7Sdrh} {2 b 4 d}
1881398ad36Sdrh
18941a3bd0aSdrhdo_test trigger1-1.11 {
19007d6e3a7Sdrh  execsql {
19107d6e3a7Sdrh    create table t1(a,b);
19207d6e3a7Sdrh    insert into t1 values(1,'a');
19307d6e3a7Sdrh    insert into t1 values(2,'b');
19407d6e3a7Sdrh    insert into t1 values(3,'c');
19507d6e3a7Sdrh    insert into t1 values(4,'d');
19607d6e3a7Sdrh    create trigger r1 after update on t1 for each row begin
19707d6e3a7Sdrh      delete from t1 WHERE a=old.a+2;
19807d6e3a7Sdrh    end;
199e61b9f4fSdanielk1977    update t1 set b='x-' || b where a=1 OR a=3;
20007d6e3a7Sdrh    select * from t1;
20107d6e3a7Sdrh    drop table t1;
202c3f9bad2Sdanielk1977  }
20307d6e3a7Sdrh} {1 x-a 2 b 4 d}
204c3f9bad2Sdanielk1977
205d702fccbSdanielk1977# Ensure that we cannot create INSTEAD OF triggers on tables
20641a3bd0aSdrhdo_test trigger1-1.12 {
207d702fccbSdanielk1977  catchsql {
208d702fccbSdanielk1977    create table t1(a,b);
209d702fccbSdanielk1977    create trigger t1t instead of update on t1 for each row begin
210d702fccbSdanielk1977      delete from t1 WHERE a=old.a+2;
211d702fccbSdanielk1977    end;
212d702fccbSdanielk1977  }
21341fb5cd1Sdan} {1 {cannot create INSTEAD OF trigger on table: t1}}
2140fa8ddbdSdanielk1977
2150fa8ddbdSdanielk1977ifcapable view {
216d702fccbSdanielk1977# Ensure that we cannot create BEFORE triggers on views
21741a3bd0aSdrhdo_test trigger1-1.13 {
218d702fccbSdanielk1977  catchsql {
219d702fccbSdanielk1977    create view v1 as select * from t1;
220d702fccbSdanielk1977    create trigger v1t before update on v1 for each row begin
221d702fccbSdanielk1977      delete from t1 WHERE a=old.a+2;
222d702fccbSdanielk1977    end;
223d702fccbSdanielk1977  }
22441fb5cd1Sdan} {1 {cannot create BEFORE trigger on view: v1}}
225d702fccbSdanielk1977# Ensure that we cannot create AFTER triggers on views
22641a3bd0aSdrhdo_test trigger1-1.14 {
227d702fccbSdanielk1977  catchsql {
228a1f9b5eeSdrh    drop view v1;
229d702fccbSdanielk1977    create view v1 as select * from t1;
230d702fccbSdanielk1977    create trigger v1t AFTER update on v1 for each row begin
231d702fccbSdanielk1977      delete from t1 WHERE a=old.a+2;
232d702fccbSdanielk1977    end;
233d702fccbSdanielk1977  }
23441fb5cd1Sdan} {1 {cannot create AFTER trigger on view: v1}}
2350fa8ddbdSdanielk1977} ;# ifcapable view
236d702fccbSdanielk1977
237f0f258b1Sdrh# Check for memory leaks in the trigger parser
238f0f258b1Sdrh#
239f0f258b1Sdrhdo_test trigger1-2.1 {
240f0f258b1Sdrh  catchsql {
241f0f258b1Sdrh    CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN
242f0f258b1Sdrh      SELECT * FROM;  -- Syntax error
243f0f258b1Sdrh    END;
244f0f258b1Sdrh  }
245f0f258b1Sdrh} {1 {near ";": syntax error}}
246f0f258b1Sdrhdo_test trigger1-2.2 {
247f0f258b1Sdrh  catchsql {
248f0f258b1Sdrh    CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN
249f0f258b1Sdrh      SELECT * FROM t1;
250f0f258b1Sdrh      SELECT * FROM;  -- Syntax error
251f0f258b1Sdrh    END;
252f0f258b1Sdrh  }
253f0f258b1Sdrh} {1 {near ";": syntax error}}
254f0f258b1Sdrh
255f0f258b1Sdrh# Create a trigger that refers to a table that might not exist.
256f0f258b1Sdrh#
25753c0f748Sdanielk1977ifcapable tempdb {
258f0f258b1Sdrh  do_test trigger1-3.1 {
259f0f258b1Sdrh    execsql {
260f0f258b1Sdrh      CREATE TEMP TABLE t2(x,y);
261f0f258b1Sdrh    }
262f0f258b1Sdrh    catchsql {
263f0f258b1Sdrh      CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN
264f0f258b1Sdrh        INSERT INTO t2 VALUES(NEW.a,NEW.b);
265f0f258b1Sdrh      END;
266f0f258b1Sdrh    }
267f0f258b1Sdrh  } {0 {}}
2683038cfe9Smistachkin  do_test trigger1-3.2 {
269f0f258b1Sdrh    catchsql {
270f0f258b1Sdrh      INSERT INTO t1 VALUES(1,2);
271f0f258b1Sdrh      SELECT * FROM t2;
272f0f258b1Sdrh    }
273f26e09c8Sdrh  } {1 {no such table: main.t2}}
2743038cfe9Smistachkin  do_test trigger1-3.3 {
275f0f258b1Sdrh    db close
276ef4ac8f9Sdrh    set rc [catch {sqlite3 db test.db} err]
277f0f258b1Sdrh    if {$rc} {lappend rc $err}
278f0f258b1Sdrh    set rc
279f0f258b1Sdrh  } {0}
2803038cfe9Smistachkin  do_test trigger1-3.4 {
281f0f258b1Sdrh    catchsql {
282f0f258b1Sdrh      INSERT INTO t1 VALUES(1,2);
283f0f258b1Sdrh      SELECT * FROM t2;
284f0f258b1Sdrh    }
285f26e09c8Sdrh  } {1 {no such table: main.t2}}
2863038cfe9Smistachkin  do_test trigger1-3.5 {
287f0f258b1Sdrh    catchsql {
288f0f258b1Sdrh      CREATE TEMP TABLE t2(x,y);
289f0f258b1Sdrh      INSERT INTO t1 VALUES(1,2);
290f0f258b1Sdrh      SELECT * FROM t2;
291f0f258b1Sdrh    }
292f26e09c8Sdrh  } {1 {no such table: main.t2}}
2933038cfe9Smistachkin  do_test trigger1-3.6.1 {
294f0f258b1Sdrh    catchsql {
295f0f258b1Sdrh      DROP TRIGGER r1;
296f0f258b1Sdrh      CREATE TEMP TRIGGER r1 AFTER INSERT ON t1 BEGIN
2977b113babSdrh        INSERT INTO t2 VALUES(NEW.a,NEW.b), (NEW.b*100, NEW.a*100);
2987b113babSdrh      END;
2997b113babSdrh      INSERT INTO t1 VALUES(1,2);
3007b113babSdrh      SELECT * FROM t2;
3017b113babSdrh    }
3027b113babSdrh  } {0 {1 2 200 100}}
3033038cfe9Smistachkin  do_test trigger1-3.6.2 {
3047b113babSdrh    catchsql {
3057b113babSdrh      DROP TRIGGER r1;
3067b113babSdrh      DELETE FROM t1;
3077b113babSdrh      DELETE FROM t2;
3087b113babSdrh      CREATE TEMP TRIGGER r1 AFTER INSERT ON t1 BEGIN
309f0f258b1Sdrh        INSERT INTO t2 VALUES(NEW.a,NEW.b);
310f0f258b1Sdrh      END;
311f0f258b1Sdrh      INSERT INTO t1 VALUES(1,2);
312f0f258b1Sdrh      SELECT * FROM t2;
313f0f258b1Sdrh    }
314f0f258b1Sdrh  } {0 {1 2}}
3153038cfe9Smistachkin  do_test trigger1-3.7 {
316f0f258b1Sdrh    execsql {
317f0f258b1Sdrh      DROP TABLE t2;
318f0f258b1Sdrh      CREATE TABLE t2(x,y);
319f0f258b1Sdrh      SELECT * FROM t2;
320f0f258b1Sdrh    }
321f0f258b1Sdrh  } {}
32227c77438Sdanielk1977
3233038cfe9Smistachkin  # There are two versions of trigger1-3.8 and trigger1-3.9. One that uses
32427c77438Sdanielk1977  # compound SELECT statements, and another that does not.
32527c77438Sdanielk1977  ifcapable compound {
32653c0f748Sdanielk1977  do_test trigger1-3.8 {
327f0f258b1Sdrh    execsql {
328f0f258b1Sdrh      INSERT INTO t1 VALUES(3,4);
329f0f258b1Sdrh      SELECT * FROM t1 UNION ALL SELECT * FROM t2;
330f0f258b1Sdrh    }
331f0f258b1Sdrh  } {1 2 3 4 3 4}
33253c0f748Sdanielk1977  do_test trigger1-3.9 {
333f0f258b1Sdrh    db close
334ef4ac8f9Sdrh    sqlite3 db test.db
335f0f258b1Sdrh    execsql {
336f0f258b1Sdrh      INSERT INTO t1 VALUES(5,6);
337f0f258b1Sdrh      SELECT * FROM t1 UNION ALL SELECT * FROM t2;
338f0f258b1Sdrh    }
339f0f258b1Sdrh  } {1 2 3 4 5 6 3 4}
34027c77438Sdanielk1977  } ;# ifcapable compound
34127c77438Sdanielk1977  ifcapable !compound {
34253c0f748Sdanielk1977  do_test trigger1-3.8 {
34327c77438Sdanielk1977    execsql {
34427c77438Sdanielk1977      INSERT INTO t1 VALUES(3,4);
34527c77438Sdanielk1977      SELECT * FROM t1;
34627c77438Sdanielk1977      SELECT * FROM t2;
34727c77438Sdanielk1977    }
34827c77438Sdanielk1977  } {1 2 3 4 3 4}
34953c0f748Sdanielk1977  do_test trigger1-3.9 {
35027c77438Sdanielk1977    db close
35127c77438Sdanielk1977    sqlite3 db test.db
35227c77438Sdanielk1977    execsql {
35327c77438Sdanielk1977      INSERT INTO t1 VALUES(5,6);
35427c77438Sdanielk1977      SELECT * FROM t1;
35527c77438Sdanielk1977      SELECT * FROM t2;
35627c77438Sdanielk1977    }
35727c77438Sdanielk1977  } {1 2 3 4 5 6 3 4}
35827c77438Sdanielk1977  } ;# ifcapable !compound
359f0f258b1Sdrh
36053c0f748Sdanielk1977  do_test trigger1-4.1 {
36179a519c0Sdrh    execsql {
36279a519c0Sdrh      CREATE TEMP TRIGGER r1 BEFORE INSERT ON t1 BEGIN
36379a519c0Sdrh        INSERT INTO t2 VALUES(NEW.a,NEW.b);
36479a519c0Sdrh      END;
36579a519c0Sdrh      INSERT INTO t1 VALUES(7,8);
36679a519c0Sdrh      SELECT * FROM t2;
36779a519c0Sdrh    }
36879a519c0Sdrh  } {3 4 7 8}
36953c0f748Sdanielk1977  do_test trigger1-4.2 {
370ef4ac8f9Sdrh    sqlite3 db2 test.db
37179a519c0Sdrh    execsql {
37279a519c0Sdrh      INSERT INTO t1 VALUES(9,10);
37379a519c0Sdrh    } db2;
37479a519c0Sdrh    db2 close
37579a519c0Sdrh    execsql {
37679a519c0Sdrh      SELECT * FROM t2;
37779a519c0Sdrh    }
37879a519c0Sdrh  } {3 4 7 8}
37953c0f748Sdanielk1977  do_test trigger1-4.3 {
38079a519c0Sdrh    execsql {
38179a519c0Sdrh      DROP TABLE t1;
38279a519c0Sdrh      SELECT * FROM t2;
38379a519c0Sdrh    };
38479a519c0Sdrh  } {3 4 7 8}
38553c0f748Sdanielk1977  do_test trigger1-4.4 {
38679a519c0Sdrh    db close
387ef4ac8f9Sdrh    sqlite3 db test.db
38879a519c0Sdrh    execsql {
38979a519c0Sdrh      SELECT * FROM t2;
39079a519c0Sdrh    };
39179a519c0Sdrh  } {3 4 7 8}
39253c0f748Sdanielk1977} else {
39353c0f748Sdanielk1977  execsql {
39453c0f748Sdanielk1977    CREATE TABLE t2(x,y);
39553c0f748Sdanielk1977    DROP TABLE t1;
39653c0f748Sdanielk1977    INSERT INTO t2 VALUES(3, 4);
39753c0f748Sdanielk1977    INSERT INTO t2 VALUES(7, 8);
39853c0f748Sdanielk1977  }
39953c0f748Sdanielk1977}
40079a519c0Sdrh
40153c0f748Sdanielk1977
40253c0f748Sdanielk1977integrity_check trigger1-5.1
40379a519c0Sdrh
4049b1b01bbSdrh# Create a trigger with the same name as a table.  Make sure the
4059b1b01bbSdrh# trigger works.  Then drop the trigger.  Make sure the table is
4069b1b01bbSdrh# still there.
4079b1b01bbSdrh#
40812525478Sdanielk1977set view_v1 {}
40912525478Sdanielk1977ifcapable view {
41012525478Sdanielk1977  set view_v1 {view v1}
41112525478Sdanielk1977}
41253c0f748Sdanielk1977do_test trigger1-6.1 {
4139b1b01bbSdrh  execsql {SELECT type, name FROM sqlite_master}
41412525478Sdanielk1977} [concat $view_v1 {table t2}]
41553c0f748Sdanielk1977do_test trigger1-6.2 {
4169b1b01bbSdrh  execsql {
4179b1b01bbSdrh    CREATE TRIGGER t2 BEFORE DELETE ON t2 BEGIN
418165921a7Sdan      SELECT RAISE(ABORT,'deletes are not permitted');
4199b1b01bbSdrh    END;
4209b1b01bbSdrh    SELECT type, name FROM sqlite_master;
4219b1b01bbSdrh  }
42212525478Sdanielk1977} [concat $view_v1 {table t2 trigger t2}]
42353c0f748Sdanielk1977do_test trigger1-6.3 {
4249b1b01bbSdrh  catchsql {DELETE FROM t2}
425165921a7Sdan} {1 {deletes are not permitted}}
426433dccfbSdrhverify_ex_errcode trigger1-6.3b SQLITE_CONSTRAINT_TRIGGER
42753c0f748Sdanielk1977do_test trigger1-6.4 {
4289b1b01bbSdrh  execsql {SELECT * FROM t2}
4299b1b01bbSdrh} {3 4 7 8}
43053c0f748Sdanielk1977do_test trigger1-6.5 {
4319b1b01bbSdrh  db close
432ef4ac8f9Sdrh  sqlite3 db test.db
4339b1b01bbSdrh  execsql {SELECT type, name FROM sqlite_master}
43412525478Sdanielk1977} [concat $view_v1 {table t2 trigger t2}]
43553c0f748Sdanielk1977do_test trigger1-6.6 {
4369b1b01bbSdrh  execsql {
4379b1b01bbSdrh    DROP TRIGGER t2;
4389b1b01bbSdrh    SELECT type, name FROM sqlite_master;
4399b1b01bbSdrh  }
44012525478Sdanielk1977} [concat $view_v1 {table t2}]
44153c0f748Sdanielk1977do_test trigger1-6.7 {
4429b1b01bbSdrh  execsql {SELECT * FROM t2}
4439b1b01bbSdrh} {3 4 7 8}
44453c0f748Sdanielk1977do_test trigger1-6.8 {
4459b1b01bbSdrh  db close
446ef4ac8f9Sdrh  sqlite3 db test.db
4479b1b01bbSdrh  execsql {SELECT * FROM t2}
4489b1b01bbSdrh} {3 4 7 8}
4499b1b01bbSdrh
4503038cfe9Smistachkinintegrity_check trigger1-7.1
451191c0323Sdrh
452191c0323Sdrh# Check to make sure the name of a trigger can be quoted so that keywords
453191c0323Sdrh# can be used as trigger names.  Ticket #468
454191c0323Sdrh#
45553c0f748Sdanielk1977do_test trigger1-8.1 {
456191c0323Sdrh  execsql {
457191c0323Sdrh    CREATE TRIGGER 'trigger' AFTER INSERT ON t2 BEGIN SELECT 1; END;
458191c0323Sdrh    SELECT name FROM sqlite_master WHERE type='trigger';
459191c0323Sdrh  }
460191c0323Sdrh} {trigger}
46153c0f748Sdanielk1977do_test trigger1-8.2 {
462191c0323Sdrh  execsql {
463191c0323Sdrh    DROP TRIGGER 'trigger';
464191c0323Sdrh    SELECT name FROM sqlite_master WHERE type='trigger';
465191c0323Sdrh  }
466191c0323Sdrh} {}
46753c0f748Sdanielk1977do_test trigger1-8.3 {
468191c0323Sdrh  execsql {
469191c0323Sdrh    CREATE TRIGGER "trigger" AFTER INSERT ON t2 BEGIN SELECT 1; END;
470191c0323Sdrh    SELECT name FROM sqlite_master WHERE type='trigger';
471191c0323Sdrh  }
472191c0323Sdrh} {trigger}
47353c0f748Sdanielk1977do_test trigger1-8.4 {
474191c0323Sdrh  execsql {
475191c0323Sdrh    DROP TRIGGER "trigger";
476191c0323Sdrh    SELECT name FROM sqlite_master WHERE type='trigger';
477191c0323Sdrh  }
478191c0323Sdrh} {}
47953c0f748Sdanielk1977do_test trigger1-8.5 {
480191c0323Sdrh  execsql {
481191c0323Sdrh    CREATE TRIGGER [trigger] AFTER INSERT ON t2 BEGIN SELECT 1; END;
482191c0323Sdrh    SELECT name FROM sqlite_master WHERE type='trigger';
483191c0323Sdrh  }
484191c0323Sdrh} {trigger}
48553c0f748Sdanielk1977do_test trigger1-8.6 {
486191c0323Sdrh  execsql {
487191c0323Sdrh    DROP TRIGGER [trigger];
488191c0323Sdrh    SELECT name FROM sqlite_master WHERE type='trigger';
489191c0323Sdrh  }
490191c0323Sdrh} {}
4919b1b01bbSdrh
4923bdca9c9Sdanielk1977ifcapable conflict {
4933054efeeSdrh  # Make sure REPLACE works inside of triggers.
4943054efeeSdrh  #
4953038cfe9Smistachkin  # There are two versions of trigger1-9.1 and trigger1-9.2. One that uses
49627c77438Sdanielk1977  # compound SELECT statements, and another that does not.
49727c77438Sdanielk1977  ifcapable compound {
49853c0f748Sdanielk1977    do_test trigger1-9.1 {
4993054efeeSdrh      execsql {
5003054efeeSdrh        CREATE TABLE t3(a,b);
5013054efeeSdrh        CREATE TABLE t4(x UNIQUE, b);
5023054efeeSdrh        CREATE TRIGGER r34 AFTER INSERT ON t3 BEGIN
5033054efeeSdrh          REPLACE INTO t4 VALUES(new.a,new.b);
5043054efeeSdrh        END;
5053054efeeSdrh        INSERT INTO t3 VALUES(1,2);
5063054efeeSdrh        SELECT * FROM t3 UNION ALL SELECT 99, 99 UNION ALL SELECT * FROM t4;
5073054efeeSdrh      }
5083054efeeSdrh    } {1 2 99 99 1 2}
50953c0f748Sdanielk1977    do_test trigger1-9.2 {
5103054efeeSdrh      execsql {
5113054efeeSdrh        INSERT INTO t3 VALUES(1,3);
5123054efeeSdrh        SELECT * FROM t3 UNION ALL SELECT 99, 99 UNION ALL SELECT * FROM t4;
5133054efeeSdrh      }
5143054efeeSdrh    } {1 2 1 3 99 99 1 3}
5153bdca9c9Sdanielk1977  } else {
51653c0f748Sdanielk1977    do_test trigger1-9.1 {
51727c77438Sdanielk1977      execsql {
51827c77438Sdanielk1977        CREATE TABLE t3(a,b);
51927c77438Sdanielk1977        CREATE TABLE t4(x UNIQUE, b);
52027c77438Sdanielk1977        CREATE TRIGGER r34 AFTER INSERT ON t3 BEGIN
52127c77438Sdanielk1977          REPLACE INTO t4 VALUES(new.a,new.b);
52227c77438Sdanielk1977        END;
52327c77438Sdanielk1977        INSERT INTO t3 VALUES(1,2);
52427c77438Sdanielk1977        SELECT * FROM t3; SELECT 99, 99; SELECT * FROM t4;
52527c77438Sdanielk1977      }
52627c77438Sdanielk1977    } {1 2 99 99 1 2}
52753c0f748Sdanielk1977    do_test trigger1-9.2 {
52827c77438Sdanielk1977      execsql {
52927c77438Sdanielk1977        INSERT INTO t3 VALUES(1,3);
53027c77438Sdanielk1977        SELECT * FROM t3; SELECT 99, 99; SELECT * FROM t4;
53127c77438Sdanielk1977      }
53227c77438Sdanielk1977    } {1 2 1 3 99 99 1 3}
53327c77438Sdanielk1977  }
534d008cfe3Sdanielk1977  execsql {
535d008cfe3Sdanielk1977    DROP TABLE t3;
536d008cfe3Sdanielk1977    DROP TABLE t4;
537d008cfe3Sdanielk1977  }
5383bdca9c9Sdanielk1977}
5393bdca9c9Sdanielk1977
540d008cfe3Sdanielk1977
541d008cfe3Sdanielk1977# Ticket #764. At one stage TEMP triggers would fail to re-install when the
542d008cfe3Sdanielk1977# schema was reloaded. The following tests ensure that TEMP triggers are
543d008cfe3Sdanielk1977# correctly re-installed.
544d008cfe3Sdanielk1977#
545d008cfe3Sdanielk1977# Also verify that references within trigger programs are resolved at
546d008cfe3Sdanielk1977# statement compile time, not trigger installation time. This means, for
547d008cfe3Sdanielk1977# example, that you can drop and re-create tables referenced by triggers.
5485a8f9374Sdanielk1977ifcapable tempdb&&attach {
54953c0f748Sdanielk1977  do_test trigger1-10.0 {
550fda06befSmistachkin    forcedelete test2.db
551fda06befSmistachkin    forcedelete test2.db-journal
552d008cfe3Sdanielk1977    execsql {
553d008cfe3Sdanielk1977      ATTACH 'test2.db' AS aux;
554d008cfe3Sdanielk1977    }
555d008cfe3Sdanielk1977  } {}
55653c0f748Sdanielk1977  do_test trigger1-10.1 {
557d008cfe3Sdanielk1977    execsql {
558d008cfe3Sdanielk1977      CREATE TABLE main.t4(a, b, c);
559d008cfe3Sdanielk1977      CREATE TABLE temp.t4(a, b, c);
560d008cfe3Sdanielk1977      CREATE TABLE aux.t4(a, b, c);
561d008cfe3Sdanielk1977      CREATE TABLE insert_log(db, a, b, c);
562d008cfe3Sdanielk1977    }
563d008cfe3Sdanielk1977  } {}
56453c0f748Sdanielk1977  do_test trigger1-10.2 {
565d008cfe3Sdanielk1977    execsql {
566d008cfe3Sdanielk1977      CREATE TEMP TRIGGER trig1 AFTER INSERT ON main.t4 BEGIN
567d008cfe3Sdanielk1977        INSERT INTO insert_log VALUES('main', new.a, new.b, new.c);
568d008cfe3Sdanielk1977      END;
569d008cfe3Sdanielk1977      CREATE TEMP TRIGGER trig2 AFTER INSERT ON temp.t4 BEGIN
570d008cfe3Sdanielk1977        INSERT INTO insert_log VALUES('temp', new.a, new.b, new.c);
571d008cfe3Sdanielk1977      END;
572d008cfe3Sdanielk1977      CREATE TEMP TRIGGER trig3 AFTER INSERT ON aux.t4 BEGIN
573d008cfe3Sdanielk1977        INSERT INTO insert_log VALUES('aux', new.a, new.b, new.c);
574d008cfe3Sdanielk1977      END;
575d008cfe3Sdanielk1977    }
576d008cfe3Sdanielk1977  } {}
57753c0f748Sdanielk1977  do_test trigger1-10.3 {
578d008cfe3Sdanielk1977    execsql {
579d008cfe3Sdanielk1977      INSERT INTO main.t4 VALUES(1, 2, 3);
580d008cfe3Sdanielk1977      INSERT INTO temp.t4 VALUES(4, 5, 6);
581d008cfe3Sdanielk1977      INSERT INTO aux.t4  VALUES(7, 8, 9);
582d008cfe3Sdanielk1977    }
583d008cfe3Sdanielk1977  } {}
58453c0f748Sdanielk1977  do_test trigger1-10.4 {
585d008cfe3Sdanielk1977    execsql {
586d008cfe3Sdanielk1977      SELECT * FROM insert_log;
587d008cfe3Sdanielk1977    }
588d008cfe3Sdanielk1977  } {main 1 2 3 temp 4 5 6 aux 7 8 9}
58953c0f748Sdanielk1977  do_test trigger1-10.5 {
590d008cfe3Sdanielk1977    execsql {
591d008cfe3Sdanielk1977      BEGIN;
592d008cfe3Sdanielk1977      INSERT INTO main.t4 VALUES(1, 2, 3);
593d008cfe3Sdanielk1977      INSERT INTO temp.t4 VALUES(4, 5, 6);
594d008cfe3Sdanielk1977      INSERT INTO aux.t4  VALUES(7, 8, 9);
595d008cfe3Sdanielk1977      ROLLBACK;
596d008cfe3Sdanielk1977    }
597d008cfe3Sdanielk1977  } {}
59853c0f748Sdanielk1977  do_test trigger1-10.6 {
599d008cfe3Sdanielk1977    execsql {
600d008cfe3Sdanielk1977      SELECT * FROM insert_log;
601d008cfe3Sdanielk1977    }
602d008cfe3Sdanielk1977  } {main 1 2 3 temp 4 5 6 aux 7 8 9}
60353c0f748Sdanielk1977  do_test trigger1-10.7 {
604d008cfe3Sdanielk1977    execsql {
605d008cfe3Sdanielk1977      DELETE FROM insert_log;
606d008cfe3Sdanielk1977      INSERT INTO main.t4 VALUES(11, 12, 13);
607d008cfe3Sdanielk1977      INSERT INTO temp.t4 VALUES(14, 15, 16);
608d008cfe3Sdanielk1977      INSERT INTO aux.t4  VALUES(17, 18, 19);
609d008cfe3Sdanielk1977    }
610d008cfe3Sdanielk1977  } {}
61153c0f748Sdanielk1977  do_test trigger1-10.8 {
612d008cfe3Sdanielk1977    execsql {
613d008cfe3Sdanielk1977      SELECT * FROM insert_log;
614d008cfe3Sdanielk1977    }
615d008cfe3Sdanielk1977  } {main 11 12 13 temp 14 15 16 aux 17 18 19}
6163038cfe9Smistachkin  do_test trigger1-10.9 {
617d008cfe3Sdanielk1977  # Drop and re-create the insert_log table in a different database. Note
618d008cfe3Sdanielk1977  # that we can change the column names because the trigger programs don't
619d008cfe3Sdanielk1977  # use them explicitly.
620d008cfe3Sdanielk1977    execsql {
621d008cfe3Sdanielk1977      DROP TABLE insert_log;
622d008cfe3Sdanielk1977      CREATE TABLE aux.insert_log(db, d, e, f);
623d008cfe3Sdanielk1977    }
624d008cfe3Sdanielk1977  } {}
62553c0f748Sdanielk1977  do_test trigger1-10.10 {
626d008cfe3Sdanielk1977    execsql {
627d008cfe3Sdanielk1977      INSERT INTO main.t4 VALUES(21, 22, 23);
628d008cfe3Sdanielk1977      INSERT INTO temp.t4 VALUES(24, 25, 26);
629d008cfe3Sdanielk1977      INSERT INTO aux.t4  VALUES(27, 28, 29);
630d008cfe3Sdanielk1977    }
631d008cfe3Sdanielk1977  } {}
63253c0f748Sdanielk1977  do_test trigger1-10.11 {
633d008cfe3Sdanielk1977    execsql {
634d008cfe3Sdanielk1977      SELECT * FROM insert_log;
635d008cfe3Sdanielk1977    }
636d008cfe3Sdanielk1977  } {main 21 22 23 temp 24 25 26 aux 27 28 29}
63753c0f748Sdanielk1977}
6383054efeeSdrh
639bb7ac00bSdrhdo_test trigger1-11.1 {
640bb7ac00bSdrh  catchsql {SELECT raise(abort,'message');}
641bb7ac00bSdrh} {1 {RAISE() may only be used within a trigger-program}}
642bb7ac00bSdrh
643510f9659Sdanielk1977do_test trigger1-15.1 {
644510f9659Sdanielk1977  execsql {
645510f9659Sdanielk1977    CREATE TABLE tA(a INTEGER PRIMARY KEY, b, c);
646510f9659Sdanielk1977    CREATE TRIGGER tA_trigger BEFORE UPDATE ON "tA" BEGIN SELECT 1; END;
647510f9659Sdanielk1977    INSERT INTO tA VALUES(1, 2, 3);
648510f9659Sdanielk1977  }
649510f9659Sdanielk1977  catchsql { UPDATE tA SET a = 'abc' }
650510f9659Sdanielk1977} {1 {datatype mismatch}}
651510f9659Sdanielk1977do_test trigger1-15.2 {
652510f9659Sdanielk1977  catchsql { INSERT INTO tA VALUES('abc', 2, 3) }
653510f9659Sdanielk1977} {1 {datatype mismatch}}
654bb7ac00bSdrh
655b1819a0bSdrh# Ticket #3947:  Do not allow qualified table names on INSERT, UPDATE, and
656b1819a0bSdrh# DELETE statements within triggers.  Actually, this has never been allowed
657b1819a0bSdrh# by the grammar.  But the error message is confusing: one simply gets a
658b1819a0bSdrh# "syntax error".  That has now been changed to give a full error message.
659b1819a0bSdrh#
660b1819a0bSdrhdo_test trigger1-16.1 {
661b1819a0bSdrh  db eval {
662b1819a0bSdrh    CREATE TABLE t16(a,b,c);
663b1819a0bSdrh    CREATE INDEX t16a ON t16(a);
664b1819a0bSdrh    CREATE INDEX t16b ON t16(b);
665b1819a0bSdrh  }
666b1819a0bSdrh  catchsql {
667b1819a0bSdrh    CREATE TRIGGER main.t16err1 AFTER INSERT ON tA BEGIN
668b1819a0bSdrh      INSERT INTO main.t16 VALUES(1,2,3);
669b1819a0bSdrh    END;
670b1819a0bSdrh  }
671b1819a0bSdrh} {1 {qualified table names are not allowed on INSERT, UPDATE, and DELETE statements within triggers}}
672b1819a0bSdrhdo_test trigger1-16.2 {
673b1819a0bSdrh  catchsql {
674b1819a0bSdrh    CREATE TRIGGER main.t16err2 AFTER INSERT ON tA BEGIN
675b1819a0bSdrh      UPDATE main.t16 SET rowid=rowid+1;
676b1819a0bSdrh    END;
677b1819a0bSdrh  }
678b1819a0bSdrh} {1 {qualified table names are not allowed on INSERT, UPDATE, and DELETE statements within triggers}}
679b1819a0bSdrhdo_test trigger1-16.3 {
680b1819a0bSdrh  catchsql {
681b1819a0bSdrh    CREATE TRIGGER main.t16err3 AFTER INSERT ON tA BEGIN
682b1819a0bSdrh      DELETE FROM main.t16;
683b1819a0bSdrh    END;
684b1819a0bSdrh  }
685b1819a0bSdrh} {1 {qualified table names are not allowed on INSERT, UPDATE, and DELETE statements within triggers}}
686b1819a0bSdrhdo_test trigger1-16.4 {
687b1819a0bSdrh  catchsql {
688b1819a0bSdrh    CREATE TRIGGER main.t16err4 AFTER INSERT ON tA BEGIN
689b1819a0bSdrh      UPDATE t16 NOT INDEXED SET rowid=rowid+1;
690b1819a0bSdrh    END;
691b1819a0bSdrh  }
692b1819a0bSdrh} {1 {the NOT INDEXED clause is not allowed on UPDATE or DELETE statements within triggers}}
693b1819a0bSdrhdo_test trigger1-16.5 {
694b1819a0bSdrh  catchsql {
695b1819a0bSdrh    CREATE TRIGGER main.t16err5 AFTER INSERT ON tA BEGIN
696b1819a0bSdrh      UPDATE t16 INDEXED BY t16a SET rowid=rowid+1 WHERE a=1;
697b1819a0bSdrh    END;
698b1819a0bSdrh  }
699b1819a0bSdrh} {1 {the INDEXED BY clause is not allowed on UPDATE or DELETE statements within triggers}}
700b1819a0bSdrhdo_test trigger1-16.6 {
701b1819a0bSdrh  catchsql {
702b1819a0bSdrh    CREATE TRIGGER main.t16err6 AFTER INSERT ON tA BEGIN
703b1819a0bSdrh      DELETE FROM t16 NOT INDEXED WHERE a=123;
704b1819a0bSdrh    END;
705b1819a0bSdrh  }
706b1819a0bSdrh} {1 {the NOT INDEXED clause is not allowed on UPDATE or DELETE statements within triggers}}
707b1819a0bSdrhdo_test trigger1-16.7 {
708b1819a0bSdrh  catchsql {
709b1819a0bSdrh    CREATE TRIGGER main.t16err7 AFTER INSERT ON tA BEGIN
710b1819a0bSdrh      DELETE FROM t16 INDEXED BY t16a WHERE a=123;
711b1819a0bSdrh    END;
712b1819a0bSdrh  }
713b1819a0bSdrh} {1 {the INDEXED BY clause is not allowed on UPDATE or DELETE statements within triggers}}
714b1819a0bSdrh
715dde548cbSdan#-------------------------------------------------------------------------
716dde548cbSdan# Test that bug [34cd55d68e0e6e7c] has been fixed.
717dde548cbSdan#
718dde548cbSdando_execsql_test trigger1-17.0 {
719dde548cbSdan  CREATE TABLE t17a(ii INT);
720dde548cbSdan  CREATE TABLE t17b(tt TEXT PRIMARY KEY, ss);
721dde548cbSdan  CREATE TRIGGER t17a_ai AFTER INSERT ON t17a BEGIN
722dde548cbSdan    INSERT INTO t17b(tt) VALUES(new.ii);
723dde548cbSdan  END;
724dde548cbSdan  CREATE TRIGGER t17b_ai AFTER INSERT ON t17b BEGIN
725dde548cbSdan    UPDATE t17b SET ss = 4;
726dde548cbSdan  END;
727dde548cbSdan  INSERT INTO t17a(ii) VALUES('1');
728dde548cbSdan  PRAGMA integrity_check;
729dde548cbSdan} {ok}
730dde548cbSdan
731de7ca50dSdrh# 2018-04-26
732de7ca50dSdrh# When a BEFORE UPDATE trigger changes a column value in a row being
733de7ca50dSdrh# updated, and that column value is used by the UPDATE to change other
734de7ca50dSdrh# column, the value used to compute the update is from before the trigger.
735de7ca50dSdrh# In the example that follows, the value of "b" in "c=b" is 2 (the value
736de7ca50dSdrh# prior to running the BEFORE UPDATE trigger) not 1000.
737de7ca50dSdrh#
738de7ca50dSdrhdo_execsql_test trigger1-18.0 {
739de7ca50dSdrh  CREATE TABLE t18(a PRIMARY KEY,b,c);
740de7ca50dSdrh  INSERT INTO t18(a,b,c) VALUES(1,2,3);
741de7ca50dSdrh  CREATE TRIGGER t18r1 BEFORE UPDATE ON t18 BEGIN
742de7ca50dSdrh    UPDATE t18 SET b=1000 WHERE a=old.a;
743de7ca50dSdrh  END;
744de7ca50dSdrh  UPDATE t18 SET c=b WHERE a=1;
745de7ca50dSdrh  SELECT * FROM t18;
746de7ca50dSdrh} {1 1000 2}  ;# Not: 1 1000 1000
747de7ca50dSdrhdo_execsql_test trigger1-18.1 {
748de7ca50dSdrh  DELETE FROM t18;
749de7ca50dSdrh  INSERT INTO t18(a,b,c) VALUES(1,2,3);
750de7ca50dSdrh  UPDATE t18 SET c=b, b=b+1 WHERE a=1;
751de7ca50dSdrh  SELECT * FROM t18;
752de7ca50dSdrh} {1 3 2}     ;# Not: 1 1001 1000
753de7ca50dSdrh
754909066bbSdrh# 2018-04-26 ticket [https://www.sqlite.org/src/tktview/d85fffd6ffe856092e]
755909066bbSdrh# VDBE Program uses an expired value.
756909066bbSdrh#
757909066bbSdrhdo_execsql_test trigger1-19.0 {
758909066bbSdrh  CREATE TABLE t19(a INT PRIMARY KEY, b, c)WITHOUT ROWID;
759909066bbSdrh  INSERT INTO t19(a,b,c) VALUES(1,2,3);
760909066bbSdrh  CREATE TRIGGER t19r3 BEFORE UPDATE ON t19 BEGIN SELECT new.b; END;
761909066bbSdrh  UPDATE t19 SET c=b WHERE a=1;
762909066bbSdrh  SELECT * FROM t19;
763909066bbSdrh} {1 2 2}
7646876dccbSdrhdo_execsql_test trigger1-19.1 {
7656876dccbSdrh  DELETE FROM t19;
7666876dccbSdrh  INSERT INTO t19(a,b,c) VALUES(1,2,3);
7676876dccbSdrh  UPDATE t19 SET c=CASE WHEN b=2 THEN b ELSE b+99 END WHERE a=1;
7686876dccbSdrh  SELECT * FROM t19;
7696876dccbSdrh} {1 2 2}
770909066bbSdrh
7716397a78bSdrh# 2019-08-26 Chromium sqlite3_fts3_lpm_fuzzer find.
7726397a78bSdrh#
7736397a78bSdrhdb close
7746397a78bSdrhsqlite3 db :memory:
7756397a78bSdrhdo_execsql_test trigger1-20.1 {
7766397a78bSdrh  CREATE TABLE t20_1(x);
7776397a78bSdrh  ATTACH ':memory:' AS aux;
7786397a78bSdrh  CREATE TABLE aux.t20_2(y);
7796397a78bSdrh  CREATE TABLE aux.t20_3(z);
7806397a78bSdrh  CREATE TEMP TRIGGER r20_3 AFTER INSERT ON t20_2 BEGIN UPDATE t20_3 SET z=z+1; END;
7816397a78bSdrh  DETACH aux;
7826397a78bSdrh  DROP TRIGGER r20_3;
7836397a78bSdrh} {}
7846397a78bSdrh
78506baba54Sdrh# 2019-10-24 ticket 50c09fc2cf0d91ce
78606baba54Sdrh#
78706baba54Sdrhdb close
78806baba54Sdrhsqlite3 db :memory:
78906baba54Sdrhdo_execsql_test trigger1-21.1 {
79006baba54Sdrh  PRAGMA recursive_triggers = true;
79106baba54Sdrh  CREATE TABLE t0(a, b, c UNIQUE);
79206baba54Sdrh  CREATE UNIQUE INDEX i0 ON t0(b) WHERE a;
79306baba54Sdrh  CREATE TRIGGER tr0 AFTER DELETE ON t0 BEGIN
79406baba54Sdrh    DELETE FROM t0;
79506baba54Sdrh  END;
79606baba54Sdrh  INSERT INTO t0(a,b,c) VALUES(0,0,9),(1,1,1);
79706baba54Sdrh  REPLACE INTO t0(a,b,c) VALUES(2,0,9);
79806baba54Sdrh  SELECT * FROM t0;
79906baba54Sdrh} {2 0 9}
80006baba54Sdrh
801f6ea97eaSdrh# 2020-01-04 From Yongheng
802f6ea97eaSdrh# The test case below caused problems for the register validity
803f6ea97eaSdrh# tracking logic.  There was no bug in the release build.  The
804f6ea97eaSdrh# only problem was a false-positive in the register validity
805f6ea97eaSdrh# tracking.
806f6ea97eaSdrh#
807f6ea97eaSdrhreset_db
808f6ea97eaSdrhdo_execsql_test trigger1-22.10 {
809f6ea97eaSdrh  CREATE TABLE t1(
810f6ea97eaSdrh    a INTEGER PRIMARY KEY,
811f6ea97eaSdrh    b DOUBLE
812f6ea97eaSdrh  );
813f6ea97eaSdrh  CREATE TRIGGER x AFTER UPDATE ON t1 BEGIN
814f6ea97eaSdrh   SELECT sum(b)OVER(ORDER BY (SELECT b FROM t1 AS x
815f6ea97eaSdrh                               WHERE b IN (t1.a,127,t1.b)
816f6ea97eaSdrh                               GROUP BY b))
817f6ea97eaSdrh     FROM t1
818f6ea97eaSdrh     GROUP BY a;
819f6ea97eaSdrh  END;
820f6ea97eaSdrh  CREATE TEMP TRIGGER x BEFORE INSERT ON t1 BEGIN
821f6ea97eaSdrh    UPDATE t1
822f6ea97eaSdrh       SET b=randomblob(10)
823f6ea97eaSdrh     WHERE b >= 'E'
824f6ea97eaSdrh       AND a < (SELECT a FROM t1 WHERE a<22 GROUP BY b);
825f6ea97eaSdrh  END;
826f6ea97eaSdrh  INSERT INTO t1(b) VALUES('Y'),('X'),('Z');
827f6ea97eaSdrh  SELECT a, CASE WHEN typeof(b)='text' THEN quote(b) ELSE '<blob>' END, '|' FROM t1;
828f6ea97eaSdrh} {1 <blob> | 2 'X' | 3 'Z' |}
829f6ea97eaSdrh
830*4c460bbfSdrh# 2022-03-06 https://sqlite.org/forum/forumpost/2024e94071
831*4c460bbfSdrh# Harmless assertion fault following a syntax error.
832*4c460bbfSdrh#
833*4c460bbfSdrhreset_db
834*4c460bbfSdrhdo_catchsql_test trigger1-23.1 {
835*4c460bbfSdrh  CREATE TABLE t1(a INT);
836*4c460bbfSdrh  CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN
837*4c460bbfSdrh    INSERT INTO t1 SELECT e_master LIMIT 1,#1;
838*4c460bbfSdrh  END;
839*4c460bbfSdrh} {1 {near "#1": syntax error}}
840*4c460bbfSdrh
841c3f9bad2Sdanielk1977finish_test
842