Fix documentation typo.
[sqlite.git] / test / e_totalchanges.test
blobbb5cfba8a51234440f44a29c5e08461c55e651e7
1 # 2011 May 06
3 # The author disclaims copyright to this source code.  In place of
4 # a legal notice, here is a blessing:
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.
10 #***********************************************************************
13 set testdir [file dirname $argv0]
14 source $testdir/tester.tcl
15 set testprefix e_totalchanges
17 # Like [do_execsql_test], except it appends the value returned by 
18 # [db total_changes] to the result of executing the SQL script.
20 proc do_tc_test {tn sql res} {
21   uplevel [list \
22     do_test $tn "concat \[execsql {$sql}\] \[db total_changes\]" $res
23   ]
26 do_execsql_test 1.0 {
27   CREATE TABLE t1(a, b);
28   CREATE INDEX t1_b ON t1(b);
29   CREATE TABLE t2(x, y, PRIMARY KEY(x, y)) WITHOUT ROWID;
30   CREATE INDEX t2_y ON t2(y);
34 #--------------------------------------------------------------------------
35 # EVIDENCE-OF: R-38914-26427 The total_changes() function returns the
36 # number of row changes caused by INSERT, UPDATE or DELETE statements
37 # since the current database connection was opened.
39 #   1.1.*: different types of I/U/D statements,
40 #   1.2.*: trigger programs.
42 do_tc_test 1.1.1 {
43   INSERT INTO t1 VALUES(1, 2);
44   INSERT INTO t1 VALUES(3, 4);
45   UPDATE t1 SET a = a+1;
46   DELETE FROM t1;
47 } {6}
48 do_tc_test 1.1.2 {
49   DELETE FROM t1
50 } {6}
52 do_tc_test 1.1.3 {
53   WITH data(a,b) AS (
54       SELECT 0, 0 UNION ALL SELECT a+1, b+1 FROM data WHERE a<99
55   )
56   INSERT INTO t1 SELECT * FROM data;
57 } {106}
59 do_tc_test 1.1.4 {
60   INSERT INTO t2 SELECT * FROM t1 WHERE a<50;
61   UPDATE t2 SET y=y+1;
62 } {206}
64 do_tc_test 1.1.5 {
65   DELETE FROM t2 WHERE y<=25
66 } {231}
68 do_execsql_test 1.2.1 {
69   DELETE FROM t1;
70   DELETE FROM t2;
72 sqlite3 db test.db     ; # To reset total_changes
73 do_tc_test 1.2.2 {
74   CREATE TABLE log(detail);
75   CREATE TRIGGER t1_after_insert AFTER INSERT ON t1 BEGIN 
76     INSERT INTO log VALUES('inserted into t1');
77   END;
79   CREATE TRIGGER t1_before_delete BEFORE DELETE ON t1 BEGIN 
80     INSERT INTO log VALUES('deleting from t1');
81     INSERT INTO log VALUES('here we go!');
82   END;
84   CREATE TRIGGER t1_after_update AFTER UPDATE ON t1 BEGIN 
85     INSERT INTO log VALUES('update');
86     DELETE FROM log;
87   END;
89   INSERT INTO t1 VALUES('a', 'b');   -- 1 + 1
90   UPDATE t1 SET b='c';               -- 1 + 1 + 2
91   DELETE FROM t1;                    -- 1 + 1 + 1
92 } {9}
94 #--------------------------------------------------------------------------
95 # EVIDENCE-OF: R-61766-15253 Executing any other type of SQL statement
96 # does not affect the value returned by sqlite3_total_changes().
97 ifcapable altertable {
98   do_tc_test 2.1 {
99     INSERT INTO t1 VALUES(1, 2), (3, 4);
100     INSERT INTO t2 VALUES(1, 2), (3, 4);
101   } {15}
102   do_tc_test 2.2 {
103     SELECT count(*) FROM t1;
104   } {2 15}
105   do_tc_test 2.3 {
106     CREATE TABLE t4(a, b);
107     ALTER TABLE t4 ADD COLUMN c;
108     CREATE INDEX i4 ON t4(c);
109     ALTER TABLE t4 RENAME TO t5;
110     ANALYZE;
111     BEGIN;
112     DROP TABLE t2;
113     ROLLBACK;
114     VACUUM;
115   } {15}
119 #--------------------------------------------------------------------------
120 # EVIDENCE-OF: R-36043-10590 Changes made as part of foreign key
121 # actions are included in the count, but those made as part of REPLACE
122 # constraint resolution are not.
124 #   3.1.*: foreign key actions
125 #   3.2.*: REPLACE constraints.
127 sqlite3 db test.db     ; # To reset total_changes
128 do_tc_test 3.1.1 {
129   CREATE TABLE p1(c PRIMARY KEY, d);
130   CREATE TABLE c1(a, b, FOREIGN KEY(a) REFERENCES p1 ON DELETE SET NULL);
131   CREATE TABLE c2(a, b, FOREIGN KEY(a) REFERENCES p1 ON DELETE CASCADE);
132   CREATE TABLE c3(a, b, FOREIGN KEY(a) REFERENCES p1 ON DELETE SET DEFAULT);
134   INSERT INTO p1 VALUES(1, 'one');
135   INSERT INTO p1 VALUES(2, 'two');
136   INSERT INTO p1 VALUES(3, 'three');
137   INSERT INTO p1 VALUES(4, 'four');
139   INSERT INTO c1 VALUES(1, 'i');
140   INSERT INTO c2 VALUES(2, 'ii');
141   INSERT INTO c3 VALUES(3, 'iii');
142   PRAGMA foreign_keys = ON;
143 } {7}
145 do_tc_test 3.1.2 { DELETE FROM p1 WHERE c=1; } {9}
146 do_tc_test 3.1.3 { DELETE FROM p1 WHERE c=2; } {11}
147 do_tc_test 3.1.4 { DELETE FROM p1 WHERE c=3; } {13}
148 do_tc_test 3.1.5 { DELETE FROM p1 WHERE c=4; } {14}  ; # only 1 this time.
150 sqlite3 db test.db     ; # To reset total_changes
151 do_tc_test 3.1.6 {
152   DROP TABLE c1;
153   DROP TABLE c2;
154   DROP TABLE c3;
155   CREATE TABLE c1(a, b, FOREIGN KEY(a) REFERENCES p1 ON UPDATE SET NULL);
156   CREATE TABLE c2(a, b, FOREIGN KEY(a) REFERENCES p1 ON UPDATE CASCADE);
157   CREATE TABLE c3(a, b, FOREIGN KEY(a) REFERENCES p1 ON UPDATE SET DEFAULT);
159   INSERT INTO p1 VALUES(1, 'one');
160   INSERT INTO p1 VALUES(2, 'two');
161   INSERT INTO p1 VALUES(3, 'three');
162   INSERT INTO p1 VALUES(4, 'four');
164   INSERT INTO c1 VALUES(1, 'i');
165   INSERT INTO c2 VALUES(2, 'ii');
166   INSERT INTO c3 VALUES(3, 'iii');
167   PRAGMA foreign_keys = ON;
168 } {7}
170 do_tc_test 3.1.7  { UPDATE p1 SET c=c+4 WHERE c=1; } {9}
171 do_tc_test 3.1.8  { UPDATE p1 SET c=c+4 WHERE c=2; } {11}
172 do_tc_test 3.1.9  { UPDATE p1 SET c=c+4 WHERE c=3; } {13}
173 do_tc_test 3.1.10 { UPDATE p1 SET c=c+4 WHERE c=4; } {14}  ; # only 1 this time.
175 sqlite3 db test.db     ; # To reset total_changes
176 do_tc_test 3.2.1 {
177   CREATE TABLE t3(a UNIQUE, b UNIQUE);
178   INSERT INTO t3 VALUES('one', 'one');
179   INSERT INTO t3 VALUES('two', 'two');
180   INSERT OR REPLACE INTO t3 VALUES('one', 'two');
181 } {3}
183 do_tc_test 3.2.2 {
184   INSERT INTO t3 VALUES('three', 'one');
185   UPDATE OR REPLACE t3 SET b='two' WHERE b='one';
186   SELECT * FROM t3;
187 } {three two 5}
189 #--------------------------------------------------------------------------
190 # EVIDENCE-OF: R-54872-08741 Changes to a view that are intercepted by
191 # INSTEAD OF triggers are not counted.
193 sqlite3 db test.db     ; # To reset total_changes
194 do_tc_test 4.1 {
195   CREATE TABLE t6(x);
196   CREATE VIEW v1 AS SELECT * FROM t6;
197   CREATE TRIGGER v1_tr1 INSTEAD OF INSERT ON v1 BEGIN
198     SELECT 'no-op';
199   END;
201   INSERT INTO v1 VALUES('a');
202   INSERT INTO v1 VALUES('b');
203 } {0}
204 do_tc_test 4.2 {
205   CREATE TRIGGER v1_tr2 INSTEAD OF INSERT ON v1 BEGIN
206     INSERT INTO t6 VALUES(new.x);
207   END;
209   INSERT INTO v1 VALUES('c');
210   INSERT INTO v1 VALUES('d');
211 } {2}
214 finish_test