144748f27Sdan# 2018 October 18
244748f27Sdan#
344748f27Sdan# The author disclaims copyright to this source code.  In place of
444748f27Sdan# a legal notice, here is a blessing:
544748f27Sdan#
644748f27Sdan#    May you do good and not evil.
744748f27Sdan#    May you find forgiveness for yourself and forgive others.
844748f27Sdan#    May you share freely, never taking more than you give.
944748f27Sdan#
1044748f27Sdan#***********************************************************************
1144748f27Sdan# This file implements regression tests for SQLite library.
1244748f27Sdan#
1344748f27Sdan
1444748f27Sdanif {![info exists testdir]} {
1544748f27Sdan  set testdir [file join [file dirname [info script]] .. .. test]
1644748f27Sdan}
1744748f27Sdansource [file join [file dirname [info script]] session_common.tcl]
1844748f27Sdansource $testdir/tester.tcl
1944748f27Sdanifcapable !session {finish_test; return}
2044748f27Sdan
2144748f27Sdanset testprefix sessioninvert
2244748f27Sdan
2346de0728Sdanproc iter_invert {C} {
2446de0728Sdan  set x [list]
2546de0728Sdan  sqlite3session_foreach -invert c $C { lappend x $c }
2646de0728Sdan  set x
2746de0728Sdan}
2846de0728Sdan
2946de0728Sdanproc do_invert_test {tn sql {iter {}}} {
3044748f27Sdan
3144748f27Sdan  forcecopy test.db test.db2
3244748f27Sdan  sqlite3 db2 test.db2
3344748f27Sdan
3444748f27Sdan  set C [changeset_from_sql $sql]
3544748f27Sdan
3644748f27Sdan  forcecopy test.db test.db3
3744748f27Sdan  sqlite3 db3 test.db3
3844748f27Sdan  uplevel [list do_test $tn.1 [list compare_db db db3] {}]
3944748f27Sdan
4044748f27Sdan  set I [sqlite3changeset_invert $C]
4144748f27Sdan  sqlite3changeset_apply db $I {}
4244748f27Sdan  uplevel [list do_test $tn.2 [list compare_db db db2] {}]
4344748f27Sdan
4444748f27Sdan  sqlite3changeset_apply_v2 -invert db3 $C {}
4544748f27Sdan  uplevel [list do_test $tn.3 [list compare_db db db3] {}]
4644748f27Sdan
4746de0728Sdan  if {$iter!=""} {
4846de0728Sdan    uplevel [list do_test $tn.4 [list iter_invert $C] [list {*}$iter]]
4946de0728Sdan  }
5046de0728Sdan
5144748f27Sdan  catch { db2 close }
5244748f27Sdan  catch { db3 close }
5344748f27Sdan}
5444748f27Sdan
5544748f27Sdando_execsql_test 1.0 {
5644748f27Sdan  CREATE TABLE t1(a PRIMARY KEY, b, c);
5744748f27Sdan  CREATE TABLE t2(d, e, f, PRIMARY KEY(e, f));
5844748f27Sdan
5944748f27Sdan  INSERT INTO t1 VALUES(1, 'one', 'i');
6044748f27Sdan  INSERT INTO t1 VALUES(2, 'two', 'ii');
6144748f27Sdan  INSERT INTO t1 VALUES(3, 'three', 'iii');
6244748f27Sdan  INSERT INTO t1 VALUES(4, 'four', 'iv');
6344748f27Sdan  INSERT INTO t1 VALUES(5, 'five', 'v');
6444748f27Sdan  INSERT INTO t1 VALUES(6, 'six', 'vi');
6544748f27Sdan
6644748f27Sdan  INSERT INTO t2 SELECT * FROM t1;
6744748f27Sdan}
6844748f27Sdan
6944748f27Sdando_invert_test 1.1 {
7044748f27Sdan  INSERT INTO t1 VALUES(7, 'seven', 'vii');
7146de0728Sdan} {
7246de0728Sdan  {DELETE t1 0 X.. {i 7 t seven t vii} {}}
7344748f27Sdan}
7444748f27Sdan
7544748f27Sdando_invert_test 1.2 {
7644748f27Sdan  DELETE FROM t1 WHERE a<4;
7746de0728Sdan} {
7846de0728Sdan  {INSERT t1 0 X.. {} {i 1 t one t i}}
7946de0728Sdan  {INSERT t1 0 X.. {} {i 2 t two t ii}}
8046de0728Sdan  {INSERT t1 0 X.. {} {i 3 t three t iii}}
8144748f27Sdan}
8244748f27Sdan
8344748f27Sdando_invert_test 1.3 {
8446de0728Sdan  UPDATE t1 SET c=5;
8546de0728Sdan} {
8646de0728Sdan  {UPDATE t1 0 X.. {i 1 {} {} i 5} {{} {} {} {} t i}}
8746de0728Sdan  {UPDATE t1 0 X.. {i 2 {} {} i 5} {{} {} {} {} t ii}}
8846de0728Sdan  {UPDATE t1 0 X.. {i 3 {} {} i 5} {{} {} {} {} t iii}}
8946de0728Sdan  {UPDATE t1 0 X.. {i 4 {} {} i 5} {{} {} {} {} t iv}}
9046de0728Sdan  {UPDATE t1 0 X.. {i 5 {} {} i 5} {{} {} {} {} t v}}
9146de0728Sdan  {UPDATE t1 0 X.. {i 6 {} {} i 5} {{} {} {} {} t vi}}
9246de0728Sdan}
9346de0728Sdan
9446de0728Sdando_invert_test 1.4 {
9544748f27Sdan  UPDATE t1 SET b = a+1 WHERE a%2;
9644748f27Sdan  DELETE FROM t2;
9744748f27Sdan  INSERT INTO t1 VALUES(10, 'ten', NULL);
9844748f27Sdan}
9944748f27Sdan
10046de0728Sdando_invert_test 1.5 {
10144748f27Sdan  UPDATE t2 SET d = d-1;
10246de0728Sdan} {
10346de0728Sdan  {UPDATE t2 0 .XX {i 2 t three t iii} {i 3 {} {} {} {}}}
10446de0728Sdan  {UPDATE t2 0 .XX {i 1 t two t ii} {i 2 {} {} {} {}}}
10546de0728Sdan  {UPDATE t2 0 .XX {i 5 t six t vi} {i 6 {} {} {} {}}}
10646de0728Sdan  {UPDATE t2 0 .XX {i 3 t four t iv} {i 4 {} {} {} {}}}
10746de0728Sdan  {UPDATE t2 0 .XX {i 0 t one t i} {i 1 {} {} {} {}}}
10846de0728Sdan  {UPDATE t2 0 .XX {i 4 t five t v} {i 5 {} {} {} {}}}
10944748f27Sdan}
11044748f27Sdan
11144748f27Sdando_execsql_test 2.0 {
11244748f27Sdan  ANALYZE;
11344748f27Sdan  PRAGMA writable_schema = 1;
11444748f27Sdan  DROP TABLE IF EXISTS sqlite_stat4;
11544748f27Sdan  SELECT * FROM sqlite_stat1;
11644748f27Sdan} {
11744748f27Sdan  t2 sqlite_autoindex_t2_1 {6 1 1}
11844748f27Sdan  t1 sqlite_autoindex_t1_1 {6 1}
11944748f27Sdan}
12044748f27Sdan
12144748f27Sdando_invert_test 2.1 {
12244748f27Sdan  INSERT INTO sqlite_stat1 VALUES('t3', 'idx2', '1 2 3');
12346de0728Sdan} {
12446de0728Sdan  {DELETE sqlite_stat1 0 XX. {t t3 t idx2 t {1 2 3}} {}}
12544748f27Sdan}
12644748f27Sdan
12744748f27Sdando_invert_test 2.2 {
12844748f27Sdan  DELETE FROM sqlite_stat1;
12946de0728Sdan} {
13046de0728Sdan  {INSERT sqlite_stat1 0 XX. {} {t t1 t sqlite_autoindex_t1_1 t {6 1}}}
13146de0728Sdan  {INSERT sqlite_stat1 0 XX. {} {t t2 t sqlite_autoindex_t2_1 t {6 1 1}}}
13244748f27Sdan}
13344748f27Sdan
13444748f27Sdando_invert_test 2.3 {
13544748f27Sdan  UPDATE sqlite_stat1 SET stat = 'hello world';
13644748f27Sdan}
13744748f27Sdan
13844748f27Sdando_test 3.0 {
13944748f27Sdan  forcecopy test.db test.db2
14044748f27Sdan  sqlite3 db2 test.db2
14144748f27Sdan  set P [patchset_from_sql {
14244748f27Sdan    INSERT INTO t2 VALUES(1, 2, 3);
14344748f27Sdan    DELETE FROM t2 WHERE d = 3;
14444748f27Sdan  }]
14544748f27Sdan
14644748f27Sdan  list [catch { sqlite3changeset_apply_v2 -invert db2 $P {} } msg] $msg
14744748f27Sdan} {1 SQLITE_CORRUPT}
14844748f27Sdan
14944748f27Sdando_test 3.1 {
15046de0728Sdan  list [catch { sqlite3session_foreach -invert db2 $P {} } msg] $msg
15146de0728Sdan} {1 SQLITE_CORRUPT}
15246de0728Sdan
15346de0728Sdando_test 3.2 {
15444748f27Sdan  sqlite3changeset_apply_v2 db2 $P {}
15544748f27Sdan  compare_db db db2
15644748f27Sdan} {}
15744748f27Sdan
158*5d237bfaSdan#-------------------------------------------------------------------------
159*5d237bfaSdan#
160*5d237bfaSdanreset_db
161*5d237bfaSdando_execsql_test 4.0 {
162*5d237bfaSdan  CREATE TABLE t1(a INTEGER PRIMARY KEY, b UNIQUE);
163*5d237bfaSdan  INSERT INTO t1 VALUES(1, 'one');
164*5d237bfaSdan  INSERT INTO t1 VALUES(2, 'two');
165*5d237bfaSdan  INSERT INTO t1 VALUES(3, 'three');
166*5d237bfaSdan  INSERT INTO t1 VALUES(4, 'four');
167*5d237bfaSdan}
168*5d237bfaSdan
169*5d237bfaSdando_invert_test 4.1 {
170*5d237bfaSdan  DELETE FROM t1;
171*5d237bfaSdan  INSERT INTO t1 VALUES(1, 'two');
172*5d237bfaSdan  INSERT INTO t1 VALUES(2, 'five');
173*5d237bfaSdan  INSERT INTO t1 VALUES(3, 'one');
174*5d237bfaSdan  INSERT INTO t1 VALUES(4, 'three');
175*5d237bfaSdan} {
176*5d237bfaSdan  {UPDATE t1 0 X. {i 1 t two} {{} {} t one}}
177*5d237bfaSdan  {UPDATE t1 0 X. {i 2 t five} {{} {} t two}}
178*5d237bfaSdan  {UPDATE t1 0 X. {i 3 t one} {{} {} t three}}
179*5d237bfaSdan  {UPDATE t1 0 X. {i 4 t three} {{} {} t four}}
180*5d237bfaSdan}
181*5d237bfaSdan
18244748f27Sdan
18344748f27Sdanfinish_test
184