xref: /sqlite-3.40.0/test/upfrom2.test (revision f2972b60)
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