1c3da667bSdan# 2011 October 28 2c3da667bSdan# 3c3da667bSdan# The author disclaims copyright to this source code. In place of 4c3da667bSdan# a legal notice, here is a blessing: 5c3da667bSdan# 6c3da667bSdan# May you do good and not evil. 7c3da667bSdan# May you find forgiveness for yourself and forgive others. 8c3da667bSdan# May you share freely, never taking more than you give. 9c3da667bSdan# 10c3da667bSdan#*********************************************************************** 11c3da667bSdan# 12c3da667bSdan 13c3da667bSdanset testdir [file dirname $argv0] 14c3da667bSdansource $testdir/tester.tcl 15c3da667bSdanset testprefix e_changes 16c3da667bSdan 17c3da667bSdan# Like [do_execsql_test], except it appends the value returned by 18c3da667bSdan# [db changes] to the result of executing the SQL script. 19c3da667bSdan# 20c3da667bSdanproc do_changes_test {tn sql res} { 21c3da667bSdan uplevel [list \ 22c3da667bSdan do_test $tn "concat \[execsql {$sql}\] \[db changes\]" $res 23c3da667bSdan ] 24c3da667bSdan} 25c3da667bSdan 26c3da667bSdan 27c3da667bSdan#-------------------------------------------------------------------------- 28c0bd26a2Sdrh# EVIDENCE-OF: R-58361-29089 The changes() function returns the number 29c0bd26a2Sdrh# of database rows that were changed or inserted or deleted by the most 30c0bd26a2Sdrh# recently completed INSERT, DELETE, or UPDATE statement, exclusive of 31c0bd26a2Sdrh# statements in lower-level triggers. 32c3da667bSdan# 33c3da667bSdando_execsql_test 1.0 { 34c3da667bSdan CREATE TABLE t1(a, b); 35c3da667bSdan CREATE TABLE t2(x, y, PRIMARY KEY(x, y)) WITHOUT ROWID; 36c3da667bSdan CREATE INDEX i1 ON t1(a); 37c3da667bSdan CREATE INDEX i2 ON t2(y); 38c3da667bSdan} 39c3da667bSdanforeach {tn schema} { 40c3da667bSdan 1 { 41c3da667bSdan CREATE TABLE t1(a, b); 42c3da667bSdan CREATE INDEX i1 ON t1(b); 43c3da667bSdan } 44c3da667bSdan 2 { 45c3da667bSdan CREATE TABLE t1(a, b, PRIMARY KEY(a, b)) WITHOUT ROWID; 46c3da667bSdan CREATE INDEX i1 ON t1(b); 47c3da667bSdan } 48c3da667bSdan} { 49c3da667bSdan reset_db 50c3da667bSdan execsql $schema 51c3da667bSdan 52c3da667bSdan # Insert 1 row. 53c3da667bSdan do_changes_test 1.$tn.1 { INSERT INTO t1 VALUES(0, 0) } 1 54c3da667bSdan 55c3da667bSdan # Insert 10 rows. 56c3da667bSdan do_changes_test 1.$tn.2 { 57c3da667bSdan WITH rows(i, j) AS ( 58c3da667bSdan SELECT 1, 1 UNION ALL SELECT i+1, j+i FROM rows WHERE i<10 59c3da667bSdan ) 60c3da667bSdan INSERT INTO t1 SELECT * FROM rows 61c3da667bSdan } 10 62c3da667bSdan 63c3da667bSdan # Modify 5 rows. 64c3da667bSdan do_changes_test 1.$tn.3 { 65c3da667bSdan UPDATE t1 SET b=b+1 WHERE a<5; 66c3da667bSdan } 5 67c3da667bSdan 68c3da667bSdan # Delete 4 rows 69c3da667bSdan do_changes_test 1.$tn.4 { 70c3da667bSdan DELETE FROM t1 WHERE a>6 71c3da667bSdan } 4 72c3da667bSdan 73c3da667bSdan # Check the "on the database connecton specified" part of hte 74c3da667bSdan # requirement - changes made by other connections do not show up in 75c3da667bSdan # the return value of sqlite3_changes(). 76c3da667bSdan do_test 1.$tn.5 { 77c3da667bSdan sqlite3 db2 test.db 78c3da667bSdan execsql { INSERT INTO t1 VALUES(-1, -1) } db2 79c3da667bSdan db2 changes 80c3da667bSdan } 1 81c3da667bSdan do_test 1.$tn.6 { 82c3da667bSdan db changes 83c3da667bSdan } 4 84c3da667bSdan db2 close 85c3da667bSdan 86c3da667bSdan # Test that statements that modify no rows because they hit UNIQUE 87c3da667bSdan # constraints set the sqlite3_changes() value to 0. Regardless of 88c3da667bSdan # whether or not they are executed inside an explicit transaction. 89c3da667bSdan # 90c3da667bSdan # 1.$tn.8-9: outside of a transaction 91c3da667bSdan # 1.$tn.10-12: inside a transaction 92c3da667bSdan # 93c3da667bSdan do_changes_test 1.$tn.7 { 94c3da667bSdan CREATE UNIQUE INDEX i2 ON t1(a); 95c3da667bSdan } 4 96c3da667bSdan do_catchsql_test 1.$tn.8 { 97c3da667bSdan INSERT INTO t1 VALUES('a', 0), ('b', 0), ('c', 0), (0, 11); 98c3da667bSdan } {1 {UNIQUE constraint failed: t1.a}} 99c3da667bSdan do_test 1.$tn.9 { db changes } 0 100c3da667bSdan do_catchsql_test 1.$tn.10 { 101c3da667bSdan BEGIN; 102c3da667bSdan INSERT INTO t1 VALUES('a', 0), ('b', 0), ('c', 0), (0, 11); 103c3da667bSdan } {1 {UNIQUE constraint failed: t1.a}} 104c3da667bSdan do_test 1.$tn.11 { db changes } 0 105c3da667bSdan do_changes_test 1.$tn.12 COMMIT 0 106c3da667bSdan 107c3da667bSdan} 108c3da667bSdan 109c3da667bSdan 110c3da667bSdan#-------------------------------------------------------------------------- 111c0bd26a2Sdrh# X-EVIDENCE-OF: R-44877-05564 Executing any other type of SQL statement 112c3da667bSdan# does not modify the value returned by this function. 113c3da667bSdan# 114c3da667bSdanreset_db 115c3da667bSdando_changes_test 2.1 { CREATE TABLE t1(x) } 0 116c3da667bSdando_changes_test 2.2 { 117c3da667bSdan WITH d(y) AS (SELECT 1 UNION ALL SELECT y+1 FROM d WHERE y<47) 118c3da667bSdan INSERT INTO t1 SELECT y FROM d; 119c3da667bSdan} 47 120c3da667bSdan 121c3da667bSdan# The statement above set changes() to 47. Check that none of the following 122c3da667bSdan# modify this. 123c3da667bSdando_changes_test 2.3 { SELECT count(x) FROM t1 } {47 47} 124c3da667bSdando_changes_test 2.4 { DROP TABLE t1 } 47 125c3da667bSdando_changes_test 2.5 { CREATE TABLE t1(x) } 47 126*37f3ac8fSdanifcapable altertable { 127c3da667bSdan do_changes_test 2.6 { ALTER TABLE t1 ADD COLUMN b } 47 128*37f3ac8fSdan} 129c3da667bSdan 130c3da667bSdan 131c3da667bSdan#-------------------------------------------------------------------------- 132c3da667bSdan# EVIDENCE-OF: R-53938-27527 Only changes made directly by the INSERT, 133c3da667bSdan# UPDATE or DELETE statement are considered - auxiliary changes caused 134c3da667bSdan# by triggers, foreign key actions or REPLACE constraint resolution are 135c3da667bSdan# not counted. 136c3da667bSdan# 137c3da667bSdan# 3.1.*: triggers 138c3da667bSdan# 3.2.*: foreign key actions 139c3da667bSdan# 3.3.*: replace constraints 140c3da667bSdan# 141c3da667bSdanreset_db 142c3da667bSdando_execsql_test 3.1.0 { 143c3da667bSdan CREATE TABLE log(x); 144c3da667bSdan CREATE TABLE p1(one PRIMARY KEY, two); 145c3da667bSdan 146c3da667bSdan CREATE TRIGGER tr_ai AFTER INSERT ON p1 BEGIN 147c3da667bSdan INSERT INTO log VALUES('insert'); 148c3da667bSdan END; 149c3da667bSdan CREATE TRIGGER tr_bd BEFORE DELETE ON p1 BEGIN 150c3da667bSdan INSERT INTO log VALUES('delete'); 151c3da667bSdan END; 152c3da667bSdan CREATE TRIGGER tr_au AFTER UPDATE ON p1 BEGIN 153c3da667bSdan INSERT INTO log VALUES('update'); 154c3da667bSdan END; 155c3da667bSdan 156c3da667bSdan} 157c3da667bSdan 158c3da667bSdando_changes_test 3.1.1 { 159c3da667bSdan INSERT INTO p1 VALUES('a', 'A'), ('b', 'B'), ('c', 'C'); 160c3da667bSdan} 3 161c3da667bSdando_changes_test 3.1.2 { 162c3da667bSdan UPDATE p1 SET two = two||two; 163c3da667bSdan} 3 164c3da667bSdando_changes_test 3.1.3 { 165c3da667bSdan DELETE FROM p1 WHERE one IN ('a', 'c'); 166c3da667bSdan} 2 167c3da667bSdando_execsql_test 3.1.4 { 168c3da667bSdan -- None of the inserts on table log were counted. 169c3da667bSdan SELECT count(*) FROM log 170c3da667bSdan} 8 171c3da667bSdan 172c3da667bSdando_execsql_test 3.2.0 { 173c3da667bSdan DELETE FROM p1; 174c3da667bSdan INSERT INTO p1 VALUES('a', 'A'), ('b', 'B'), ('c', 'C'); 175c3da667bSdan 176c3da667bSdan CREATE TABLE c1(a, b, FOREIGN KEY(a) REFERENCES p1 ON DELETE SET NULL); 177c3da667bSdan CREATE TABLE c2(a, b, FOREIGN KEY(a) REFERENCES p1 ON DELETE SET DEFAULT); 178c3da667bSdan CREATE TABLE c3(a, b, FOREIGN KEY(a) REFERENCES p1 ON DELETE CASCADE); 179c3da667bSdan INSERT INTO c1 VALUES('a', 'aaa'); 180c3da667bSdan INSERT INTO c2 VALUES('b', 'bbb'); 181c3da667bSdan INSERT INTO c3 VALUES('c', 'ccc'); 182c3da667bSdan 183c3da667bSdan INSERT INTO p1 VALUES('d', 'D'), ('e', 'E'), ('f', 'F'); 184c3da667bSdan CREATE TABLE c4(a, b, FOREIGN KEY(a) REFERENCES p1 ON UPDATE SET NULL); 185c3da667bSdan CREATE TABLE c5(a, b, FOREIGN KEY(a) REFERENCES p1 ON UPDATE SET DEFAULT); 186c3da667bSdan CREATE TABLE c6(a, b, FOREIGN KEY(a) REFERENCES p1 ON UPDATE CASCADE); 187c3da667bSdan INSERT INTO c4 VALUES('d', 'aaa'); 188c3da667bSdan INSERT INTO c5 VALUES('e', 'bbb'); 189c3da667bSdan INSERT INTO c6 VALUES('f', 'ccc'); 190c3da667bSdan 191c3da667bSdan PRAGMA foreign_keys = ON; 192c3da667bSdan} 193c3da667bSdan 194c3da667bSdando_changes_test 3.2.1 { DELETE FROM p1 WHERE one = 'a' } 1 195c3da667bSdando_changes_test 3.2.2 { DELETE FROM p1 WHERE one = 'b' } 1 196c3da667bSdando_changes_test 3.2.3 { DELETE FROM p1 WHERE one = 'c' } 1 197c3da667bSdando_execsql_test 3.2.4 { 198c3da667bSdan SELECT * FROM c1; 199c3da667bSdan SELECT * FROM c2; 200c3da667bSdan SELECT * FROM c3; 201c3da667bSdan} {{} aaa {} bbb} 202c3da667bSdan 203c3da667bSdando_changes_test 3.2.5 { UPDATE p1 SET one = 'g' WHERE one = 'd' } 1 204c3da667bSdando_changes_test 3.2.6 { UPDATE p1 SET one = 'h' WHERE one = 'e' } 1 205c3da667bSdando_changes_test 3.2.7 { UPDATE p1 SET one = 'i' WHERE one = 'f' } 1 206c3da667bSdando_execsql_test 3.2.8 { 207c3da667bSdan SELECT * FROM c4; 208c3da667bSdan SELECT * FROM c5; 209c3da667bSdan SELECT * FROM c6; 210c3da667bSdan} {{} aaa {} bbb i ccc} 211c3da667bSdan 212c3da667bSdando_execsql_test 3.3.0 { 213c3da667bSdan CREATE TABLE r1(a UNIQUE, b UNIQUE); 214c3da667bSdan INSERT INTO r1 VALUES('i', 'i'); 215c3da667bSdan INSERT INTO r1 VALUES('ii', 'ii'); 216c3da667bSdan INSERT INTO r1 VALUES('iii', 'iii'); 217c3da667bSdan INSERT INTO r1 VALUES('iv', 'iv'); 218c3da667bSdan INSERT INTO r1 VALUES('v', 'v'); 219c3da667bSdan INSERT INTO r1 VALUES('vi', 'vi'); 220c3da667bSdan INSERT INTO r1 VALUES('vii', 'vii'); 221c3da667bSdan} 222c3da667bSdan 223c3da667bSdando_changes_test 3.3.1 { INSERT OR REPLACE INTO r1 VALUES('i', 1) } 1 224c3da667bSdando_changes_test 3.3.2 { INSERT OR REPLACE INTO r1 VALUES('iv', 'v') } 1 225c3da667bSdando_changes_test 3.3.3 { UPDATE OR REPLACE r1 SET b='v' WHERE a='iii' } 1 226c3da667bSdando_changes_test 3.3.4 { UPDATE OR REPLACE r1 SET b='vi',a='vii' WHERE a='ii' } 1 227c3da667bSdando_execsql_test 3.3.5 { 228c3da667bSdan SELECT * FROM r1 ORDER BY a; 229c3da667bSdan} {i 1 iii v vii vi} 230c3da667bSdan 231c3da667bSdan 232c3da667bSdan#-------------------------------------------------------------------------- 233c3da667bSdan# EVIDENCE-OF: R-09813-48563 The value returned by sqlite3_changes() 234c3da667bSdan# immediately after an INSERT, UPDATE or DELETE statement run on a view 235c3da667bSdan# is always zero. 236c3da667bSdan# 237c3da667bSdanreset_db 238c3da667bSdando_execsql_test 4.1 { 239c3da667bSdan CREATE TABLE log(log); 240c3da667bSdan CREATE TABLE t1(x, y); 241c3da667bSdan INSERT INTO t1 VALUES(1, 2); 242c3da667bSdan INSERT INTO t1 VALUES(3, 4); 243c3da667bSdan INSERT INTO t1 VALUES(5, 6); 244c3da667bSdan 245c3da667bSdan CREATE VIEW v1 AS SELECT * FROM t1; 246c3da667bSdan CREATE TRIGGER v1_i INSTEAD OF INSERT ON v1 BEGIN 247c3da667bSdan INSERT INTO log VALUES('insert'); 248c3da667bSdan END; 249c3da667bSdan CREATE TRIGGER v1_u INSTEAD OF UPDATE ON v1 BEGIN 250c3da667bSdan INSERT INTO log VALUES('update'), ('update'); 251c3da667bSdan END; 252c3da667bSdan CREATE TRIGGER v1_d INSTEAD OF DELETE ON v1 BEGIN 253c3da667bSdan INSERT INTO log VALUES('delete'), ('delete'), ('delete'); 254c3da667bSdan END; 255c3da667bSdan} 256c3da667bSdan 257c3da667bSdando_changes_test 4.2.1 { INSERT INTO t1 SELECT * FROM t1 } 3 258c3da667bSdando_changes_test 4.2.2 { INSERT INTO v1 VALUES(1, 2) } 0 259c3da667bSdan 260c3da667bSdando_changes_test 4.3.1 { INSERT INTO t1 SELECT * FROM t1 } 6 261c3da667bSdando_changes_test 4.3.2 { UPDATE v1 SET y='xyz' WHERE x=1 } 0 262c3da667bSdan 263c3da667bSdando_changes_test 4.4.1 { INSERT INTO t1 SELECT * FROM t1 } 12 264c3da667bSdando_changes_test 4.4.2 { DELETE FROM v1 WHERE x=5 } 0 265c3da667bSdan 266c3da667bSdan 267c3da667bSdan#-------------------------------------------------------------------------- 268c3da667bSdan# EVIDENCE-OF: R-32918-61474 Before entering a trigger program the value 269c3da667bSdan# returned by sqlite3_changes() function is saved. After the trigger 270c3da667bSdan# program has finished, the original value is restored. 271c3da667bSdan# 272c3da667bSdanreset_db 273c3da667bSdandb func my_changes my_changes 274c3da667bSdanset ::changes [list] 275c3da667bSdanproc my_changes {x} { 276c3da667bSdan set res [db changes] 277c3da667bSdan lappend ::changes $x $res 278c3da667bSdan return $res 279c3da667bSdan} 280c3da667bSdan 281c3da667bSdando_execsql_test 5.1.0 { 282c3da667bSdan CREATE TABLE t1(a INTEGER PRIMARY KEY, b); 283c3da667bSdan CREATE TABLE t2(x); 284c3da667bSdan INSERT INTO t1 VALUES(1, NULL); 285c3da667bSdan INSERT INTO t1 VALUES(2, NULL); 286c3da667bSdan INSERT INTO t1 VALUES(3, NULL); 287c3da667bSdan CREATE TRIGGER AFTER UPDATE ON t1 BEGIN 288c3da667bSdan INSERT INTO t2 VALUES('a'), ('b'), ('c'); 289c3da667bSdan SELECT my_changes('trigger'); 290c3da667bSdan END; 291c3da667bSdan} 292c3da667bSdan 293c3da667bSdando_execsql_test 5.1.1 { 294c3da667bSdan INSERT INTO t2 VALUES('a'), ('b'); 295c3da667bSdan UPDATE t1 SET b = my_changes('update'); 296c3da667bSdan SELECT * FROM t1; 297c3da667bSdan} {1 2 2 2 3 2} 298c3da667bSdan 299c3da667bSdan# Value is being restored to "2" when the trigger program exits. 300c3da667bSdando_test 5.1.2 { 301c3da667bSdan set ::changes 302c3da667bSdan} {update 2 trigger 3 update 2 trigger 3 update 2 trigger 3} 303c3da667bSdan 304c3da667bSdan 305c3da667bSdanreset_db 306c3da667bSdando_execsql_test 5.2.0 { 307c3da667bSdan CREATE TABLE t1(a, b); 308c3da667bSdan CREATE TABLE log(x); 309c3da667bSdan INSERT INTO t1 VALUES(1, 0); 310c3da667bSdan INSERT INTO t1 VALUES(2, 0); 311c3da667bSdan INSERT INTO t1 VALUES(3, 0); 312c3da667bSdan CREATE TRIGGER t1_a_u AFTER UPDATE ON t1 BEGIN 313c3da667bSdan INSERT INTO log VALUES(old.b || ' -> ' || new.b || ' c = ' || changes() ); 314c3da667bSdan END; 315c3da667bSdan CREATE TABLE t2(a); 316c3da667bSdan INSERT INTO t2 VALUES(1), (2), (3); 317c3da667bSdan UPDATE t1 SET b = changes(); 318c3da667bSdan} 319c3da667bSdando_execsql_test 5.2.1 { 320c3da667bSdan SELECT * FROM t1; 321c3da667bSdan} {1 3 2 3 3 3} 322c3da667bSdando_execsql_test 5.2.2 { 323c3da667bSdan SELECT * FROM log; 324c3da667bSdan} {{0 -> 3 c = 3} {0 -> 3 c = 3} {0 -> 3 c = 3}} 325c3da667bSdan 326c3da667bSdan 327c3da667bSdan#-------------------------------------------------------------------------- 328c3da667bSdan# EVIDENCE-OF: R-17146-37073 Within a trigger program each INSERT, 329c3da667bSdan# UPDATE and DELETE statement sets the value returned by 330c3da667bSdan# sqlite3_changes() upon completion as normal. Of course, this value 331c3da667bSdan# will not include any changes performed by sub-triggers, as the 332c3da667bSdan# sqlite3_changes() value will be saved and restored after each 333c3da667bSdan# sub-trigger has run. 334c3da667bSdanreset_db 335c3da667bSdando_execsql_test 6.0 { 336c3da667bSdan 337c3da667bSdan CREATE TABLE t1(a, b); 338c3da667bSdan CREATE TABLE t2(a, b); 339c3da667bSdan CREATE TABLE t3(a, b); 340c3da667bSdan CREATE TABLE log(x); 341c3da667bSdan 342c3da667bSdan CREATE TRIGGER t1_i BEFORE INSERT ON t1 BEGIN 343c3da667bSdan INSERT INTO t2 VALUES(new.a, new.b), (new.a, new.b); 344c3da667bSdan INSERT INTO log VALUES('t2->' || changes()); 345c3da667bSdan END; 346c3da667bSdan 347c3da667bSdan CREATE TRIGGER t2_i AFTER INSERT ON t2 BEGIN 348c3da667bSdan INSERT INTO t3 VALUES(new.a, new.b), (new.a, new.b), (new.a, new.b); 349c3da667bSdan INSERT INTO log VALUES('t3->' || changes()); 350c3da667bSdan END; 351c3da667bSdan 352c3da667bSdan CREATE TRIGGER t1_u AFTER UPDATE ON t1 BEGIN 353c3da667bSdan UPDATE t2 SET b=new.b WHERE a=old.a; 354c3da667bSdan INSERT INTO log VALUES('t2->' || changes()); 355c3da667bSdan END; 356c3da667bSdan 357c3da667bSdan CREATE TRIGGER t2_u BEFORE UPDATE ON t2 BEGIN 358c3da667bSdan UPDATE t3 SET b=new.b WHERE a=old.a; 359c3da667bSdan INSERT INTO log VALUES('t3->' || changes()); 360c3da667bSdan END; 361c3da667bSdan 362c3da667bSdan CREATE TRIGGER t1_d AFTER DELETE ON t1 BEGIN 363c3da667bSdan DELETE FROM t2 WHERE a=old.a AND b=old.b; 364c3da667bSdan INSERT INTO log VALUES('t2->' || changes()); 365c3da667bSdan END; 366c3da667bSdan 367c3da667bSdan CREATE TRIGGER t2_d BEFORE DELETE ON t2 BEGIN 368c3da667bSdan DELETE FROM t3 WHERE a=old.a AND b=old.b; 369c3da667bSdan INSERT INTO log VALUES('t3->' || changes()); 370c3da667bSdan END; 371c3da667bSdan} 372c3da667bSdan 373c3da667bSdando_changes_test 6.1 { 374c3da667bSdan INSERT INTO t1 VALUES('+', 'o'); 375c3da667bSdan SELECT * FROM log; 376c3da667bSdan} {t3->3 t3->3 t2->2 1} 377c3da667bSdan 378c3da667bSdando_changes_test 6.2 { 379c3da667bSdan DELETE FROM log; 380c3da667bSdan UPDATE t1 SET b='*'; 381c3da667bSdan SELECT * FROM log; 382c3da667bSdan} {t3->6 t3->6 t2->2 1} 383c3da667bSdan 384c3da667bSdando_changes_test 6.3 { 385c3da667bSdan DELETE FROM log; 386c3da667bSdan DELETE FROM t1; 387c3da667bSdan SELECT * FROM log; 388c3da667bSdan} {t3->6 t3->0 t2->2 1} 389c3da667bSdan 390c3da667bSdan 391c3da667bSdan#-------------------------------------------------------------------------- 392c3da667bSdan# EVIDENCE-OF: R-43399-09409 This means that if the changes() SQL 393c3da667bSdan# function (or similar) is used by the first INSERT, UPDATE or DELETE 394c3da667bSdan# statement within a trigger, it returns the value as set when the 395c3da667bSdan# calling statement began executing. 396c3da667bSdan# 397c3da667bSdan# EVIDENCE-OF: R-53215-27584 If it is used by the second or subsequent 398c3da667bSdan# such statement within a trigger program, the value returned reflects 399c3da667bSdan# the number of rows modified by the previous INSERT, UPDATE or DELETE 400c3da667bSdan# statement within the same trigger. 401c3da667bSdan# 402c3da667bSdanreset_db 403c3da667bSdando_execsql_test 7.1 { 404c3da667bSdan CREATE TABLE q1(t); 405c3da667bSdan CREATE TABLE q2(u, v); 406c3da667bSdan CREATE TABLE q3(w); 407c3da667bSdan 408c3da667bSdan CREATE TRIGGER q2_insert BEFORE INSERT ON q2 BEGIN 409c3da667bSdan 410c3da667bSdan /* changes() returns value from previous I/U/D in callers context */ 411c3da667bSdan INSERT INTO q1 VALUES('1:' || changes()); 412c3da667bSdan 413c3da667bSdan /* changes() returns value of previous I/U/D in this context */ 414c3da667bSdan INSERT INTO q3 VALUES(changes()), (2), (3); 415c3da667bSdan INSERT INTO q1 VALUES('2:' || changes()); 416c3da667bSdan INSERT INTO q3 VALUES(changes() + 3), (changes()+4); 417c3da667bSdan SELECT 'this does not affect things!'; 418c3da667bSdan INSERT INTO q1 VALUES('3:' || changes()); 419c3da667bSdan UPDATE q3 SET w = w+10 WHERE w%2; 420c3da667bSdan INSERT INTO q1 VALUES('4:' || changes()); 421c3da667bSdan DELETE FROM q3; 422c3da667bSdan INSERT INTO q1 VALUES('5:' || changes()); 423c3da667bSdan END; 424c3da667bSdan} 425c3da667bSdan 426c3da667bSdando_execsql_test 7.2 { 427c3da667bSdan INSERT INTO q2 VALUES('x', 'y'); 428c3da667bSdan SELECT * FROM q1; 429c3da667bSdan} { 430c3da667bSdan 1:0 2:3 3:2 4:3 5:5 431c3da667bSdan} 432c3da667bSdan 433c3da667bSdando_execsql_test 7.3 { 434c3da667bSdan DELETE FROM q1; 435c3da667bSdan INSERT INTO q2 VALUES('x', 'y'); 436c3da667bSdan SELECT * FROM q1; 437c3da667bSdan} { 438c3da667bSdan 1:5 2:3 3:2 4:3 5:5 439c3da667bSdan} 440c3da667bSdan 441c3da667bSdan 442c3da667bSdan 443c3da667bSdanfinish_test 444