1# 2020 April 29 2# 3# The author disclaims copyright to this source code. In place of 4# a legal notice, here is a blessing: 5# 6# May you do good and not evil. 7# May you find forgiveness for yourself and forgive others. 8# May you share freely, never taking more than you give. 9# 10#*********************************************************************** 11# 12 13set testdir [file dirname $argv0] 14source $testdir/tester.tcl 15set testprefix upfrom2 16 17# Test cases: 18# 19# 1.*: Test that triggers are fired correctly for UPDATE FROM statements, 20# and only once for each row. Except for INSTEAD OF triggers on 21# views - these are fired once for each row returned by the join, 22# including duplicates. 23# 24# 2.*: Test adding ORDER BY and LIMIT clauses with UPDATE FROM statements. 25# 26 27foreach {tn wo} { 28 1 "" 29 2 "WITHOUT ROWID" 30} { 31 reset_db 32 33 eval [string map [list %WO% $wo %TN% $tn] { 34 do_execsql_test 1.%TN%.0 { 35 CREATE TABLE log(t TEXT); 36 CREATE TABLE t1(x PRIMARY KEY, y, z UNIQUE) %WO%; 37 CREATE INDEX t1y ON t1(y); 38 39 INSERT INTO t1 VALUES(1, 'i', 'one'); 40 INSERT INTO t1 VALUES(2, 'ii', 'two'); 41 INSERT INTO t1 VALUES(3, 'iii', 'three'); 42 INSERT INTO t1 VALUES(4, 'iv', 'four'); 43 44 CREATE TRIGGER tr1 BEFORE UPDATE ON t1 BEGIN 45 INSERT INTO log VALUES(old.z || '->' || new.z); 46 END; 47 CREATE TRIGGER tr2 AFTER UPDATE ON t1 BEGIN 48 INSERT INTO log VALUES(old.y || '->' || new.y); 49 END; 50 } 51 52 do_execsql_test 1.%TN%.1 { 53 WITH data(k, v) AS ( 54 VALUES(3, 'thirty'), (1, 'ten') 55 ) 56 UPDATE t1 SET z=v FROM data WHERE x=k; 57 58 SELECT * FROM t1; 59 SELECT * FROM log; 60 } { 61 1 i ten 2 ii two 3 iii thirty 4 iv four 62 one->ten i->i 63 three->thirty iii->iii 64 } 65 66 do_execsql_test 1.%TN%.2 { 67 CREATE TABLE t2(a, b); 68 CREATE TABLE t3(k, v); 69 70 INSERT INTO t3 VALUES(5, 'v'); 71 INSERT INTO t3 VALUES(12, 'xii'); 72 73 INSERT INTO t2 VALUES(2, 12); 74 INSERT INTO t2 VALUES(3, 5); 75 76 DELETE FROM log; 77 UPDATE t1 SET y=v FROM t2, t3 WHERE t1.x=t2.a AND t3.k=t2.b; 78 79 SELECT * FROM t1; 80 SELECT * FROM log; 81 } { 82 1 i ten 2 xii two 3 v thirty 4 iv four 83 two->two ii->xii 84 thirty->thirty iii->v 85 } 86 87 do_execsql_test 1.%TN%.3 { 88 DELETE FROM log; 89 WITH data(k, v) AS ( 90 VALUES(1, 'seven'), (1, 'eight'), (2, 'eleven'), (2, 'twelve') 91 ) 92 UPDATE t1 SET z=v FROM data WHERE x=k; 93 94 SELECT * FROM t1; 95 SELECT * FROM log; 96 } { 97 1 i eight 2 xii twelve 3 v thirty 4 iv four 98 ten->eight i->i 99 two->twelve xii->xii 100 } 101 102 do_test 1.%TN%.4 { db changes } {2} 103 104 do_execsql_test 1.%TN%.5 { 105 CREATE VIEW v1 AS SELECT * FROM t1; 106 CREATE TRIGGER v1tr INSTEAD OF UPDATE ON v1 BEGIN 107 UPDATE t1 SET y=new.y, z=new.z WHERE x=new.x; 108 END; 109 110 DELETE FROM log; 111 WITH data(k, v) AS ( 112 VALUES(3, 'thirteen'), (3, 'fourteen'), (4, 'fifteen'), (4, 'sixteen') 113 ) 114 UPDATE v1 SET z=v FROM data WHERE x=k; 115 } 116 117 do_execsql_test 1.%TN%.6 { 118 SELECT * FROM v1; 119 SELECT * FROM log; 120 } { 121 1 i eight 2 xii twelve 3 v fourteen 4 iv sixteen 122 thirty->thirteen v->v 123 thirteen->fourteen v->v 124 four->fifteen iv->iv 125 fifteen->sixteen iv->iv 126 } 127 128}] 129} 130 131ifcapable update_delete_limit { 132foreach {tn wo} { 133 1 "" 134 2 "WITHOUT ROWID" 135} { 136 reset_db 137 138eval [string map [list %WO% $wo %TN% $tn] { 139 do_execsql_test 2.%TN%.1 { 140 CREATE TABLE x1(a INTEGER PRIMARY KEY, b) %WO%; 141 INSERT INTO x1 VALUES 142 (1, 'one'), (2, 'two'), (3, 'three'), (4, 'four'), 143 (5, 'five'), (6, 'six'), (7, 'seven'), (8, 'eight'); 144 } 145 146 do_execsql_test 2.%TN%.2 { 147 CREATE TABLE data1(x, y); 148 INSERT INTO data1 VALUES 149 (1, 'eleven'), (1, 'twenty-one'), (2, 'twelve'), (2, 'twenty-two'), 150 (3, 'thirteen'), (3, 'twenty-three'), (4, 'fourteen'), (4, 'twenty-four'); 151 } 152 153 do_execsql_test 2.%TN%.3 { 154 UPDATE x1 SET b=y FROM data1 WHERE a=x ORDER BY a LIMIT 3; 155 SELECT * FROM x1; 156 } { 157 1 eleven 2 twelve 3 thirteen 4 four 5 five 6 six 7 seven 8 eight 158 } 159 160 do_execsql_test 2.%TN%.4 { 161 UPDATE x1 SET b=b||y FROM data1 WHERE a=x ORDER BY b LIMIT 3; 162 SELECT * FROM x1; 163 } { 164 1 eleveneleven 2 twelve 3 thirteenthirteen 4 fourfourteen 165 5 five 6 six 7 seven 8 eight 166 } 167 168}] 169}} 170 171 172finish_test 173 174