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