Index: third_party/sqlite/src/test/triggerC.test |
diff --git a/third_party/sqlite/src/test/triggerC.test b/third_party/sqlite/src/test/triggerC.test |
index 807a50afd7b676afcfcffff07372af517fa00d89..694d069d71181c721b846a4b690d412eeefdaa9f 100644 |
--- a/third_party/sqlite/src/test/triggerC.test |
+++ b/third_party/sqlite/src/test/triggerC.test |
@@ -304,12 +304,12 @@ do_test triggerC-3.2.2 { |
do_test triggerC-3.3.1 { |
catchsql { |
- INSERT INTO t3b VALUES(1000); |
+ INSERT INTO t3b VALUES(1001); |
} |
} {0 {}} |
do_test triggerC-3.3.2 { |
db eval {SELECT count(*), max(x), min(x) FROM t3b} |
-} {1001 2000 1000} |
+} {1000 2000 1001} |
do_test triggerC-3.4.1 { |
catchsql { |
@@ -324,17 +324,17 @@ do_test triggerC-3.4.2 { |
do_test triggerC-3.5.1 { |
sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 100 |
catchsql { |
- INSERT INTO t3b VALUES(1900); |
+ INSERT INTO t3b VALUES(1901); |
} |
} {0 {}} |
do_test triggerC-3.5.2 { |
db eval {SELECT count(*), max(x), min(x) FROM t3b} |
-} {101 2000 1900} |
+} {100 2000 1901} |
do_test triggerC-3.5.3 { |
catchsql { |
DELETE FROM t3b; |
- INSERT INTO t3b VALUES(1899); |
+ INSERT INTO t3b VALUES(1900); |
} |
} {1 {too many levels of trigger recursion}} |
do_test triggerC-3.5.4 { |
@@ -344,17 +344,17 @@ do_test triggerC-3.5.4 { |
do_test triggerC-3.6.1 { |
sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 1 |
catchsql { |
- INSERT INTO t3b VALUES(1999); |
+ INSERT INTO t3b VALUES(2000); |
} |
} {0 {}} |
do_test triggerC-3.6.2 { |
db eval {SELECT count(*), max(x), min(x) FROM t3b} |
-} {2 2000 1999} |
+} {1 2000 2000} |
do_test triggerC-3.6.3 { |
catchsql { |
DELETE FROM t3b; |
- INSERT INTO t3b VALUES(1998); |
+ INSERT INTO t3b VALUES(1999); |
} |
} {1 {too many levels of trigger recursion}} |
do_test triggerC-3.6.4 { |
@@ -761,5 +761,194 @@ do_test triggerC-7.9 { |
} |
} {2 3 4 3 5 6 8 1 2} |
+# Ticket [e25d9ea771febc9c311928c1c01c3163dcb26643] |
+# |
+do_test triggerC-9.1 { |
+ execsql { |
+ CREATE TABLE t9(a,b); |
+ CREATE INDEX t9b ON t9(b); |
+ INSERT INTO t9 VALUES(1,0); |
+ INSERT INTO t9 VALUES(2,1); |
+ INSERT INTO t9 VALUES(3,2); |
+ INSERT INTO t9 SELECT a+3, a+2 FROM t9; |
+ INSERT INTO t9 SELECT a+6, a+5 FROM t9; |
+ SELECT a FROM t9 ORDER BY a; |
+ } |
+} {1 2 3 4 5 6 7 8 9 10 11 12} |
+do_test triggerC-9.2 { |
+ execsql { |
+ CREATE TRIGGER t9r1 AFTER DELETE ON t9 BEGIN |
+ DELETE FROM t9 WHERE b=old.a; |
+ END; |
+ DELETE FROM t9 WHERE b=4; |
+ SELECT a FROM t9 ORDER BY a; |
+ } |
+} {1 2 3 4} |
+ |
+# At one point (between versions 3.6.18 and 3.6.20 inclusive), an UPDATE |
+# that fired a BEFORE trigger that itself updated the same row as the |
+# statement causing it to fire was causing a strange side-effect: The |
+# values updated by the statement within the trigger were being overwritten |
+# by the values in the new.* array, even if those values were not |
+# themselves written by the parent UPDATE statement. |
+# |
+# Technically speaking this was not a bug. The SQLite documentation says |
+# that if a BEFORE UPDATE or BEFORE DELETE trigger modifies or deletes the |
+# row that the parent statement is operating on the results are undefined. |
+# But as of 3.6.21 behaviour is restored to the way it was in versions |
+# 3.6.17 and earlier to avoid causing unnecessary difficulties. |
+# |
+do_test triggerC-10.1 { |
+ execsql { |
+ CREATE TABLE t10(a, updatecnt DEFAULT 0); |
+ CREATE TRIGGER t10_bu BEFORE UPDATE OF a ON t10 BEGIN |
+ UPDATE t10 SET updatecnt = updatecnt+1 WHERE rowid = old.rowid; |
+ END; |
+ INSERT INTO t10(a) VALUES('hello'); |
+ } |
+ |
+ # Before the problem was fixed, table t10 would contain the tuple |
+ # (world, 0) after running the following script (because the value |
+ # 1 written to column "updatecnt" was clobbered by the old value 0). |
+ # |
+ execsql { |
+ UPDATE t10 SET a = 'world'; |
+ SELECT * FROM t10; |
+ } |
+} {world 1} |
+ |
+do_test triggerC-10.2 { |
+ execsql { |
+ UPDATE t10 SET a = 'tcl', updatecnt = 5; |
+ SELECT * FROM t10; |
+ } |
+} {tcl 5} |
+ |
+do_test triggerC-10.3 { |
+ execsql { |
+ CREATE TABLE t11( |
+ c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, |
+ c11, c12, c13, c14, c15, c16, c17, c18, c19, c20, |
+ c21, c22, c23, c24, c25, c26, c27, c28, c29, c30, |
+ c31, c32, c33, c34, c35, c36, c37, c38, c39, c40 |
+ ); |
+ |
+ CREATE TRIGGER t11_bu BEFORE UPDATE OF c1 ON t11 BEGIN |
+ UPDATE t11 SET c31 = c31+1, c32=c32+1 WHERE rowid = old.rowid; |
+ END; |
+ |
+ INSERT INTO t11 VALUES( |
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, |
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, |
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, |
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 |
+ ); |
+ } |
+ |
+ # Before the problem was fixed, table t10 would contain the tuple |
+ # (world, 0) after running the following script (because the value |
+ # 1 written to column "updatecnt" was clobbered by the old value 0). |
+ # |
+ execsql { |
+ UPDATE t11 SET c4=35, c33=22, c1=5; |
+ SELECT * FROM t11; |
+ } |
+} {5 2 3 35 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 32 33 22 34 35 36 37 38 39 40} |
+ |
+#------------------------------------------------------------------------- |
+# Test that bug [371bab5d65] has been fixed. BEFORE INSERT and INSTEAD OF |
+# INSERT triggers with the DEFAULT VALUES INSERT syntax. |
+# |
+do_test triggerC-11.0 { |
+ catchsql { DROP TABLE log } |
+ execsql { CREATE TABLE log(a, b) } |
+} {} |
+ |
+foreach {testno tbl defaults} { |
+ 1 "CREATE TABLE t1(a, b)" {{} {}} |
+ 2 "CREATE TABLE t1(a DEFAULT 1, b DEFAULT 'abc')" {1 abc} |
+ 3 "CREATE TABLE t1(a, b DEFAULT 4.5)" {{} 4.5} |
+} { |
+ do_test triggerC-11.$testno.1 { |
+ catchsql { DROP TABLE t1 } |
+ execsql { DELETE FROM log } |
+ execsql $tbl |
+ execsql { |
+ CREATE TRIGGER tt1 BEFORE INSERT ON t1 BEGIN |
+ INSERT INTO log VALUES(new.a, new.b); |
+ END; |
+ INSERT INTO t1 DEFAULT VALUES; |
+ SELECT * FROM log; |
+ } |
+ } $defaults |
+ |
+ do_test triggerC-11.$testno.2 { |
+ execsql { DELETE FROM log } |
+ execsql { |
+ CREATE TRIGGER tt2 AFTER INSERT ON t1 BEGIN |
+ INSERT INTO log VALUES(new.a, new.b); |
+ END; |
+ INSERT INTO t1 DEFAULT VALUES; |
+ SELECT * FROM log; |
+ } |
+ } [concat $defaults $defaults] |
+ |
+ do_test triggerC-11.$testno.3 { |
+ execsql { DROP TRIGGER tt1 } |
+ execsql { DELETE FROM log } |
+ execsql { |
+ INSERT INTO t1 DEFAULT VALUES; |
+ SELECT * FROM log; |
+ } |
+ } $defaults |
+} |
+do_test triggerC-11.4 { |
+ catchsql { DROP TABLE t2 } |
+ execsql { |
+ DELETE FROM log; |
+ CREATE TABLE t2(a, b); |
+ CREATE VIEW v2 AS SELECT * FROM t2; |
+ CREATE TRIGGER tv2 INSTEAD OF INSERT ON v2 BEGIN |
+ INSERT INTO log VALUES(new.a, new.b); |
+ END; |
+ INSERT INTO v2 DEFAULT VALUES; |
+ SELECT a, b, a IS NULL, b IS NULL FROM log; |
+ } |
+} {{} {} 1 1} |
+ |
+do_test triggerC-12.1 { |
+ db close |
+ file delete -force test.db |
+ sqlite3 db test.db |
+ |
+ execsql { |
+ CREATE TABLE t1(a, b); |
+ INSERT INTO t1 VALUES(1, 2); |
+ INSERT INTO t1 VALUES(3, 4); |
+ INSERT INTO t1 VALUES(5, 6); |
+ CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN SELECT 1 ; END ; |
+ SELECT count(*) FROM sqlite_master; |
+ } |
+} {2} |
+do_test triggerC-12.2 { |
+ db eval { SELECT * FROM t1 } { |
+ if {$a == 3} { execsql { DROP TRIGGER tr1 } } |
+ } |
+ execsql { SELECT count(*) FROM sqlite_master } |
+} {1} |
+ |
+do_execsql_test triggerC-13.1 { |
+ PRAGMA recursive_triggers = ON; |
+ CREATE TABLE t12(a, b); |
+ INSERT INTO t12 VALUES(1, 2); |
+ CREATE TRIGGER tr12 AFTER UPDATE ON t12 BEGIN |
+ UPDATE t12 SET a=new.a+1, b=new.b+1; |
+ END; |
+} {} |
+do_catchsql_test triggerC-13.2 { |
+ UPDATE t12 SET a=a+1, b=b+1; |
+} {1 {too many levels of trigger recursion}} |
+ |
+ |
finish_test |