18b023cf5Sdan# 2020 April 29 28b023cf5Sdan# 38b023cf5Sdan# The author disclaims copyright to this source code. In place of 48b023cf5Sdan# a legal notice, here is a blessing: 58b023cf5Sdan# 68b023cf5Sdan# May you do good and not evil. 78b023cf5Sdan# May you find forgiveness for yourself and forgive others. 88b023cf5Sdan# May you share freely, never taking more than you give. 98b023cf5Sdan# 108b023cf5Sdan#*********************************************************************** 118b023cf5Sdan# 128b023cf5Sdan 138b023cf5Sdanset testdir [file dirname $argv0] 148b023cf5Sdansource $testdir/tester.tcl 158b023cf5Sdanset testprefix upfromfault 168b023cf5Sdan 178b023cf5Sdanforeach {tn sql} { 188b023cf5Sdan 1 { 198b023cf5Sdan CREATE TABLE t1(x PRIMARY KEY, y, z UNIQUE); 208b023cf5Sdan CREATE INDEX t1y ON t1(y); 218b023cf5Sdan } 228b023cf5Sdan 2 { 238b023cf5Sdan CREATE TABLE t1(x PRIMARY KEY, y, z UNIQUE) WITHOUT ROWID; 248b023cf5Sdan CREATE INDEX t1y ON t1(y); 258b023cf5Sdan } 268b023cf5Sdan 3 { 278b023cf5Sdan CREATE TABLE t1(x, y, z UNIQUE, PRIMARY KEY(x,y)) WITHOUT ROWID; 288b023cf5Sdan } 298b023cf5Sdan 4 { 308b023cf5Sdan CREATE VIRTUAL TABLE t1 USING fts5(x, y, z); 318b023cf5Sdan } 328b023cf5Sdan 5 { 338b023cf5Sdan CREATE TABLE real(x, y, z); 348b023cf5Sdan CREATE VIEW t1 AS SELECT * FROM real; 358b023cf5Sdan CREATE TRIGGER t1_insert INSTEAD OF INSERT ON t1 BEGIN 368b023cf5Sdan INSERT INTO real VALUES(new.x, new.y, new.z); 378b023cf5Sdan END; 388b023cf5Sdan CREATE TRIGGER t1_update INSTEAD OF UPDATE ON t1 BEGIN 398b023cf5Sdan INSERT INTO log VALUES(old.z || '->' || new.z); 408b023cf5Sdan UPDATE real SET y=new.y, z=new.z WHERE x=old.x; 418b023cf5Sdan END; 428b023cf5Sdan } 438b023cf5Sdan} { 448b023cf5Sdanif {$tn<5} continue 458b023cf5Sdan reset_db 468b023cf5Sdan 478b023cf5Sdan ifcapable !fts5 { if {$tn==4} continue } 488b023cf5Sdan 498b023cf5Sdan execsql $sql 508b023cf5Sdan do_execsql_test 1.$tn.0 { 518b023cf5Sdan CREATE TABLE log(t TEXT); 528b023cf5Sdan 538b023cf5Sdan INSERT INTO t1 VALUES(1, 'i', 'one'); 548b023cf5Sdan INSERT INTO t1 VALUES(2, 'ii', 'two'); 558b023cf5Sdan INSERT INTO t1 VALUES(3, 'iii', 'three'); 568b023cf5Sdan INSERT INTO t1 VALUES(4, 'iv', 'four'); 578b023cf5Sdan } 588b023cf5Sdan if {$tn!=4 && $tn!=5} { 598b023cf5Sdan do_execsql_test 1.$tn.0b { 608b023cf5Sdan CREATE TRIGGER tr1 BEFORE UPDATE ON t1 BEGIN 618b023cf5Sdan INSERT INTO log VALUES(old.z || '->' || new.z); 628b023cf5Sdan END; 638b023cf5Sdan CREATE TRIGGER tr2 AFTER UPDATE ON t1 BEGIN 648b023cf5Sdan INSERT INTO log VALUES(old.y || '->' || new.y); 658b023cf5Sdan END; 668b023cf5Sdan } 678b023cf5Sdan } 688b023cf5Sdan 698b023cf5Sdan faultsim_save_and_close 708b023cf5Sdan 718b023cf5Sdan do_faultsim_test 1.$tn -prep { 728b023cf5Sdan faultsim_restore_and_reopen 738b023cf5Sdan execsql { SELECT * FROM t1 } 748b023cf5Sdan } -body { 758b023cf5Sdan execsql { 768b023cf5Sdan WITH data(k, v) AS ( 778b023cf5Sdan VALUES(3, 'thirty'), (1, 'ten') 788b023cf5Sdan ) 798b023cf5Sdan UPDATE t1 SET z=v FROM data WHERE x=k; 808b023cf5Sdan } 818b023cf5Sdan } -test { 828b023cf5Sdan faultsim_test_result {0 {}} {1 {vtable constructor failed: t1}} 838b023cf5Sdan if {$testrc==0} { 848b023cf5Sdan set res [execsql { SELECT * FROM t1 }] 858b023cf5Sdan if {$res!="1 i ten 2 ii two 3 iii thirty 4 iv four"} { 868b023cf5Sdan error "unexpected result: $res" 878b023cf5Sdan } 888b023cf5Sdan } 898b023cf5Sdan } 908b023cf5Sdan} 918b023cf5Sdan 92*01b2344bSdanreset_db 93*01b2344bSdando_execsql_test 2.0 { 94*01b2344bSdan CREATE TABLE t1(a, b, c); 95*01b2344bSdan CREATE TABLE t2(x, y, z); 96*01b2344bSdan} 97*01b2344bSdanfaultsim_save_and_close 98*01b2344bSdando_faultsim_test 2.1 -prep { 99*01b2344bSdan faultsim_restore_and_reopen 100*01b2344bSdan} -body { 101*01b2344bSdan execsql { 102*01b2344bSdan CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN 103*01b2344bSdan UPDATE t2 SET x=a FROM t1 WHERE c=z; 104*01b2344bSdan END; 105*01b2344bSdan } 106*01b2344bSdan} -test { 107*01b2344bSdan faultsim_test_result {0 {}} 108*01b2344bSdan} 109*01b2344bSdan 110*01b2344bSdanfaultsim_restore_and_reopen 111*01b2344bSdando_execsql_test 2.2 { 112*01b2344bSdan CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN 113*01b2344bSdan UPDATE t1 SET a=x FROM t2 WHERE c=z; 114*01b2344bSdan END; 115*01b2344bSdan 116*01b2344bSdan INSERT INTO t2 VALUES(1, 1, 1); 117*01b2344bSdan INSERT INTO t2 VALUES(2, 2, 2); 118*01b2344bSdan INSERT INTO t2 VALUES(3, 3, 3); 119*01b2344bSdan} 120*01b2344bSdanfaultsim_save_and_close 121*01b2344bSdan 122*01b2344bSdando_faultsim_test 2.3 -prep { 123*01b2344bSdan faultsim_restore_and_reopen 124*01b2344bSdan} -body { 125*01b2344bSdan execsql { 126*01b2344bSdan INSERT INTO t1 VALUES(NULL, NULL, 1), (NULL, NULL, 3); 127*01b2344bSdan } 128*01b2344bSdan} -test { 129*01b2344bSdan faultsim_test_result {0 {}} 130*01b2344bSdan if {$testrc==0} { 131*01b2344bSdan set res [execsql { SELECT * FROM t1 }] 132*01b2344bSdan if {$res!="1 {} 1 3 {} 3"} { 133*01b2344bSdan error "unexpected result: $res" 134*01b2344bSdan } 135*01b2344bSdan } 136*01b2344bSdan} 137*01b2344bSdan 1388b023cf5Sdan 1398b023cf5Sdanfinish_test 140