xref: /sqlite-3.40.0/test/temptrigger.test (revision e0a04a36)
12f886d1dSdanielk1977# 2009 February 27
22f886d1dSdanielk1977#
32f886d1dSdanielk1977# The author disclaims copyright to this source code.  In place of
42f886d1dSdanielk1977# a legal notice, here is a blessing:
52f886d1dSdanielk1977#
62f886d1dSdanielk1977#    May you do good and not evil.
72f886d1dSdanielk1977#    May you find forgiveness for yourself and forgive others.
82f886d1dSdanielk1977#    May you share freely, never taking more than you give.
92f886d1dSdanielk1977#
102f886d1dSdanielk1977#***********************************************************************
112f886d1dSdanielk1977#
12b8180087Sdrh# $Id: temptrigger.test,v 1.3 2009/04/15 13:07:19 drh Exp $
132f886d1dSdanielk1977
142f886d1dSdanielk1977set testdir [file dirname $argv0]
152f886d1dSdanielk1977source $testdir/tester.tcl
16197bc20cSdanset testprefix temptrigger
172f886d1dSdanielk1977
18b8180087Sdrhifcapable {!trigger || !shared_cache} { finish_test ; return }
192943c372Sdanielk1977
202f886d1dSdanielk1977# Test cases:
212f886d1dSdanielk1977#
222f886d1dSdanielk1977#   temptrigger-1.*: Shared cache problem.
232f886d1dSdanielk1977#   temptrigger-2.*: A similar shared cache problem.
242f886d1dSdanielk1977#   temptrigger-3.*: Attached database problem.
252f886d1dSdanielk1977#
262f886d1dSdanielk1977
272f886d1dSdanielk1977#-------------------------------------------------------------------------
282f886d1dSdanielk1977# Test case temptrigger-1.* demonstrates a problem with temp triggers
292f886d1dSdanielk1977# in shared-cache mode. If process 1 connections to a shared-cache and
302f886d1dSdanielk1977# creates a temp trigger, the temp trigger is linked into the shared-cache
312f886d1dSdanielk1977# schema. If process 2 reloads the shared-cache schema from disk, then
322f886d1dSdanielk1977# it does not recreate the temp trigger belonging to process 1. From the
332f886d1dSdanielk1977# point of view of process 1, the temp trigger just disappeared.
342f886d1dSdanielk1977#
352f886d1dSdanielk1977#   temptrigger-1.1: In shared cache mode, create a table in the main
362f886d1dSdanielk1977#                    database and add a temp trigger to it.
372f886d1dSdanielk1977#
382f886d1dSdanielk1977#   temptrigger-1.2: Check that the temp trigger is correctly fired. Check
392f886d1dSdanielk1977#                    that the temp trigger is not fired by statements
402f886d1dSdanielk1977#                    executed by a second connection connected to the
412f886d1dSdanielk1977#                    same shared cache.
422f886d1dSdanielk1977#
432f886d1dSdanielk1977#   temptrigger-1.3: Using the second connection to the shared-cache, cause
442f886d1dSdanielk1977#                    the shared-cache schema to be reloaded.
452f886d1dSdanielk1977#
462f886d1dSdanielk1977#   temptrigger-1.4: Check that the temp trigger is still fired correctly.
472f886d1dSdanielk1977#
482f886d1dSdanielk1977#   temptrigger-1.5: Check that the temp trigger can be dropped without error.
492f886d1dSdanielk1977#
502f886d1dSdanielk1977db close
512f886d1dSdanielk1977set ::enable_shared_cache [sqlite3_enable_shared_cache]
522f886d1dSdanielk1977sqlite3_enable_shared_cache 1
532f886d1dSdanielk1977
542f886d1dSdanielk1977sqlite3 db test.db
552f886d1dSdanielk1977sqlite3 db2 test.db
562f886d1dSdanielk1977
572f886d1dSdanielk1977do_test temptrigger-1.1 {
582f886d1dSdanielk1977  execsql {
592f886d1dSdanielk1977    CREATE TABLE t1(a, b);
602f886d1dSdanielk1977    CREATE TEMP TABLE tt1(a, b);
612f886d1dSdanielk1977    CREATE TEMP TRIGGER tr1 AFTER INSERT ON t1 BEGIN
622f886d1dSdanielk1977      INSERT INTO tt1 VALUES(new.a, new.b);
632f886d1dSdanielk1977    END;
642f886d1dSdanielk1977  }
652f886d1dSdanielk1977} {}
662f886d1dSdanielk1977
672f886d1dSdanielk1977do_test temptrigger-1.2.1 {
682f886d1dSdanielk1977  execsql { INSERT INTO t1 VALUES(1, 2) }
692f886d1dSdanielk1977  execsql { SELECT * FROM t1 }
702f886d1dSdanielk1977} {1 2}
712f886d1dSdanielk1977do_test temptrigger-1.2.2 {
722f886d1dSdanielk1977  execsql { SELECT * FROM tt1 }
732f886d1dSdanielk1977} {1 2}
742f886d1dSdanielk1977do_test temptrigger-1.2.3 {
752f886d1dSdanielk1977  execsql { INSERT INTO t1 VALUES(3, 4) } db2
762f886d1dSdanielk1977  execsql { SELECT * FROM t1 }
772f886d1dSdanielk1977} {1 2 3 4}
782f886d1dSdanielk1977do_test temptrigger-1.2.4 {
792f886d1dSdanielk1977  execsql { SELECT * FROM tt1 }
802f886d1dSdanielk1977} {1 2}
812f886d1dSdanielk1977
822f886d1dSdanielk1977# Cause the shared-cache schema to be reloaded.
832f886d1dSdanielk1977#
842f886d1dSdanielk1977do_test temptrigger-1.3 {
852f886d1dSdanielk1977  execsql { BEGIN; CREATE TABLE t3(a, b); ROLLBACK; } db2
862f886d1dSdanielk1977} {}
872f886d1dSdanielk1977
882f886d1dSdanielk1977do_test temptrigger-1.4 {
892f886d1dSdanielk1977  execsql { INSERT INTO t1 VALUES(5, 6) }
902f886d1dSdanielk1977  execsql { SELECT * FROM tt1 }
912f886d1dSdanielk1977} {1 2 5 6}
922f886d1dSdanielk1977
932f886d1dSdanielk1977do_test temptrigger-1.5 {
942f886d1dSdanielk1977  # Before the bug was fixed, the following 'DROP TRIGGER' hit an
952f886d1dSdanielk1977  # assert if executed.
962f886d1dSdanielk1977  #execsql { DROP TRIGGER tr1 }
972f886d1dSdanielk1977} {}
982f886d1dSdanielk1977
992f886d1dSdanielk1977catch {db close}
1002f886d1dSdanielk1977catch {db2 close}
1012f886d1dSdanielk1977
1022f886d1dSdanielk1977#-------------------------------------------------------------------------
1032f886d1dSdanielk1977# Tests temptrigger-2.* are similar to temptrigger-1.*, except that
1042f886d1dSdanielk1977# temptrigger-2.3 simply opens and closes a connection to the shared-cache.
1052f886d1dSdanielk1977# It does not do anything special to cause the schema to be reloaded.
1062f886d1dSdanielk1977#
1072f886d1dSdanielk1977do_test temptrigger-2.1 {
1082f886d1dSdanielk1977  sqlite3 db test.db
1092f886d1dSdanielk1977  execsql {
1102f886d1dSdanielk1977    DELETE FROM t1;
1112f886d1dSdanielk1977    CREATE TEMP TABLE tt1(a, b);
1122f886d1dSdanielk1977    CREATE TEMP TRIGGER tr1 AFTER INSERT ON t1 BEGIN
1132f886d1dSdanielk1977      INSERT INTO tt1 VALUES(new.a, new.b);
1142f886d1dSdanielk1977    END;
1152f886d1dSdanielk1977  }
1162f886d1dSdanielk1977} {}
1172f886d1dSdanielk1977do_test temptrigger-2.2 {
1182f886d1dSdanielk1977  execsql {
1192f886d1dSdanielk1977    INSERT INTO t1 VALUES(10, 20);
1202f886d1dSdanielk1977    SELECT * FROM tt1;
1212f886d1dSdanielk1977  }
1222f886d1dSdanielk1977} {10 20}
1232f886d1dSdanielk1977do_test temptrigger-2.3 {
1242f886d1dSdanielk1977  sqlite3 db2 test.db
1252f886d1dSdanielk1977  db2 close
1262f886d1dSdanielk1977} {}
1272f886d1dSdanielk1977do_test temptrigger-2.4 {
1282f886d1dSdanielk1977  execsql {
1292f886d1dSdanielk1977    INSERT INTO t1 VALUES(30, 40);
1302f886d1dSdanielk1977    SELECT * FROM tt1;
1312f886d1dSdanielk1977  }
1322f886d1dSdanielk1977} {10 20 30 40}
1332f886d1dSdanielk1977do_test temptrigger-2.5 {
1342f886d1dSdanielk1977  #execsql { DROP TRIGGER tr1 }
1352f886d1dSdanielk1977} {}
1362f886d1dSdanielk1977
1372f886d1dSdanielk1977catch {db close}
1382f886d1dSdanielk1977catch {db2 close}
1392f886d1dSdanielk1977sqlite3_enable_shared_cache $::enable_shared_cache
1402f886d1dSdanielk1977
1412f886d1dSdanielk1977#-------------------------------------------------------------------------
1422f886d1dSdanielk1977# Test case temptrigger-3.* demonstrates a problem with temp triggers
1432f886d1dSdanielk1977# on tables located in attached databases. At one point when SQLite reloaded
1442f886d1dSdanielk1977# the schema of an attached database (because some other connection had
1452f886d1dSdanielk1977# changed the schema cookie) it was not re-creating temp triggers attached
1462f886d1dSdanielk1977# to tables located within the attached database.
1472f886d1dSdanielk1977#
1482f886d1dSdanielk1977#   temptrigger-3.1: Attach database 'test2.db' to connection [db]. Add a
1492f886d1dSdanielk1977#                    temp trigger to a table in 'test2.db'.
1502f886d1dSdanielk1977#
1512f886d1dSdanielk1977#   temptrigger-3.2: Check that the temp trigger is correctly fired.
1522f886d1dSdanielk1977#
1532f886d1dSdanielk1977#   temptrigger-3.3: Update the schema of 'test2.db' using an external
1542f886d1dSdanielk1977#                    connection. This forces [db] to reload the 'test2.db'
1552f886d1dSdanielk1977#                    schema. Check that the temp trigger is still fired
1562f886d1dSdanielk1977#                    correctly.
1572f886d1dSdanielk1977#
1582f886d1dSdanielk1977#   temptrigger-3.4: Check that the temp trigger can be dropped without error.
1592f886d1dSdanielk1977#
1602f886d1dSdanielk1977do_test temptrigger-3.1 {
161fda06befSmistachkin  catch { forcedelete test2.db test2.db-journal }
162fda06befSmistachkin  catch { forcedelete test.db test.db-journal }
1632f886d1dSdanielk1977  sqlite3 db test.db
1642f886d1dSdanielk1977  sqlite3 db2 test2.db
1652f886d1dSdanielk1977  execsql { CREATE TABLE t2(a, b) } db2
1662f886d1dSdanielk1977  execsql {
1672f886d1dSdanielk1977    ATTACH 'test2.db' AS aux;
1682f886d1dSdanielk1977    CREATE TEMP TABLE tt2(a, b);
1692f886d1dSdanielk1977    CREATE TEMP TRIGGER tr2 AFTER INSERT ON aux.t2 BEGIN
1702f886d1dSdanielk1977      INSERT INTO tt2 VALUES(new.a, new.b);
1712f886d1dSdanielk1977    END;
1722f886d1dSdanielk1977  }
1732f886d1dSdanielk1977} {}
1742f886d1dSdanielk1977
1752f886d1dSdanielk1977do_test temptrigger-3.2.1 {
1762f886d1dSdanielk1977  execsql {
1772f886d1dSdanielk1977    INSERT INTO aux.t2 VALUES(1, 2);
1782f886d1dSdanielk1977    SELECT * FROM aux.t2;
1792f886d1dSdanielk1977  }
1802f886d1dSdanielk1977} {1 2}
1812f886d1dSdanielk1977do_test temptrigger-3.2.2 {
1822f886d1dSdanielk1977  execsql { SELECT * FROM tt2 }
1832f886d1dSdanielk1977} {1 2}
1842f886d1dSdanielk1977
1852f886d1dSdanielk1977do_test temptrigger-3.3.1 {
1862f886d1dSdanielk1977  execsql { CREATE TABLE t3(a, b) } db2
1872f886d1dSdanielk1977  execsql {
1882f886d1dSdanielk1977    INSERT INTO aux.t2 VALUES(3, 4);
1892f886d1dSdanielk1977    SELECT * FROM aux.t2;
1902f886d1dSdanielk1977  }
1912f886d1dSdanielk1977} {1 2 3 4}
1922f886d1dSdanielk1977do_test temptrigger-3.3.2 {
1932f886d1dSdanielk1977  execsql { SELECT * FROM tt2 }
1942f886d1dSdanielk1977} {1 2 3 4}
1952f886d1dSdanielk1977
1962f886d1dSdanielk1977do_test temptrigger-3.4 {
1972f886d1dSdanielk1977  # Before the bug was fixed, the following 'DROP TRIGGER' hit an
1982f886d1dSdanielk1977  # assert if executed.
1992f886d1dSdanielk1977  #execsql { DROP TRIGGER tr2 }
2002f886d1dSdanielk1977} {}
2012f886d1dSdanielk1977
2022f886d1dSdanielk1977catch { db close }
2032f886d1dSdanielk1977catch { db2 close }
2042f886d1dSdanielk1977
205197bc20cSdan
206197bc20cSdan#-------------------------------------------------------------------------
207197bc20cSdan# Test that creating a temp table after a temp trigger on the same name
208197bc20cSdan# has been created is an error.
209197bc20cSdan#
210197bc20cSdanreset_db
211197bc20cSdando_execsql_test 4.0 {
212197bc20cSdan  CREATE TABLE t1(x);
213197bc20cSdan  CREATE TEMP TRIGGER tr1 BEFORE INSERT ON t1 BEGIN
214197bc20cSdan    SELECT 1,2,3;
215197bc20cSdan  END;
216197bc20cSdan}
217197bc20cSdan
218197bc20cSdando_execsql_test 4.1 {
219197bc20cSdan  CREATE TEMP TABLE t1(x);
220197bc20cSdan}
221197bc20cSdan
222197bc20cSdan#-------------------------------------------------------------------------
223197bc20cSdan# Test that no harm is done if the table a temp trigger is attached to is
224197bc20cSdan# deleted by an external connection.
225197bc20cSdan#
226197bc20cSdanreset_db
227197bc20cSdando_execsql_test 5.0 {
228197bc20cSdan  CREATE TABLE t1(x);
229197bc20cSdan  CREATE TEMP TRIGGER tr1 BEFORE INSERT ON t1 BEGIN SELECT 1,2,3; END;
230197bc20cSdan}
231197bc20cSdan
232197bc20cSdando_test 5.1 {
233197bc20cSdan  sqlite3 db2 test.db
234197bc20cSdan  execsql { DROP TABLE t1 } db2
235197bc20cSdan} {}
236197bc20cSdan
237197bc20cSdando_execsql_test 5.2 {
238197bc20cSdan  SELECT * FROM sqlite_master;
239*e0a04a36Sdrh  SELECT * FROM temp.sqlite_master;
240197bc20cSdan} {
241197bc20cSdan  trigger tr1 t1 0
242197bc20cSdan  {CREATE TRIGGER tr1 BEFORE INSERT ON t1 BEGIN SELECT 1,2,3; END}
243197bc20cSdan}
244197bc20cSdandb2 close
245197bc20cSdan
246197bc20cSdan#-------------------------------------------------------------------------
247197bc20cSdan# Check that if a second connection creates a table in an attached database
248197bc20cSdan# with the same name as a table in the main database that has a temp
249197bc20cSdan# trigger attached to it nothing goes awry.
250197bc20cSdan#
251197bc20cSdanreset_db
252197bc20cSdanforcedelete test.db2
253197bc20cSdan
254197bc20cSdando_execsql_test 6.0 {
255197bc20cSdan  CREATE TABLE t1(x);
256197bc20cSdan  CREATE TEMP TRIGGER tr1 BEFORE INSERT ON t1 BEGIN
257197bc20cSdan    SELECT raise(ABORT, 'error');
258197bc20cSdan  END;
259197bc20cSdan  ATTACH 'test.db2' AS aux;
260197bc20cSdan}
261197bc20cSdan
262197bc20cSdando_test 6.1 {
263197bc20cSdan  sqlite3 db2 test.db2
264197bc20cSdan  execsql { CREATE TABLE t1(a, b, c); } db2
265197bc20cSdan} {}
266197bc20cSdan
267197bc20cSdando_execsql_test 6.2 {
26819be738bSdan  SELECT type,name,tbl_name,sql FROM aux.sqlite_master;
269197bc20cSdan  INSERT INTO aux.t1 VALUES(1,2,3);
270197bc20cSdan} {
27119be738bSdan  table t1 t1 {CREATE TABLE t1(a, b, c)}
272197bc20cSdan}
273197bc20cSdan
274197bc20cSdando_catchsql_test 6.3 {
275197bc20cSdan  INSERT INTO main.t1 VALUES(1);
276197bc20cSdan} {1 error}
277197bc20cSdandb2 close
278197bc20cSdan
2792f886d1dSdanielk1977finish_test
280