set testprefix session1
-do_execsql_test 1.0 {
- CREATE TABLE t1(x PRIMARY KEY, y);
+# Run all tests in this file twice. Once with "WITHOUT ROWID", and once
+# with regular rowid tables.
+#
+foreach {tn trailing} {
+ 1 ""
+ 2 " WITHOUT ROWID "
+} {
+eval [string map [list %WR% $trailing] {
+
+db close
+forcedelete test.db test.db2
+reset_db
+
+do_execsql_test $tn.1.0 {
+ CREATE TABLE t1(x PRIMARY KEY, y) %WR%;
INSERT INTO t1 VALUES('abc', 'def');
}
#-------------------------------------------------------------------------
# Test creating, attaching tables to and deleting session objects.
#
-do_test 1.1 { sqlite3session S db main } {S}
-do_test 1.2 { S delete } {}
-do_test 1.3 { sqlite3session S db main } {S}
-do_test 1.4 { S attach t1 } {}
-do_test 1.5 { S delete } {}
-do_test 1.6 { sqlite3session S db main } {S}
-do_test 1.7 { S attach t1 ; S attach t2 ; S attach t3 } {}
-do_test 1.8 { S attach t1 ; S attach t2 ; S attach t3 } {}
-do_test 1.9 { S delete } {}
-do_test 1.10 {
+do_test $tn.1.1 { sqlite3session S db main } {S}
+do_test $tn.1.2 { S delete } {}
+do_test $tn.1.3 { sqlite3session S db main } {S}
+do_test $tn.1.4 { S attach t1 } {}
+do_test $tn.1.5 { S delete } {}
+do_test $tn.1.6 { sqlite3session S db main } {S}
+do_test $tn.1.7 { S attach t1 ; S attach t2 ; S attach t3 } {}
+do_test $tn.1.8 { S attach t1 ; S attach t2 ; S attach t3 } {}
+do_test $tn.1.9 { S delete } {}
+do_test $tn.1.10 {
sqlite3session S db main
S attach t1
execsql { INSERT INTO t1 VALUES('ghi', 'jkl') }
} {}
-do_test 1.11 { S delete } {}
-do_test 1.12 {
- sqlite3session S db main
- S attach t1
- execsql { INSERT INTO t1 VALUES('mno', 'pqr') }
- execsql { UPDATE t1 SET x = 111 WHERE rowid = 1 }
- execsql { DELETE FROM t1 WHERE rowid = 2 }
-} {}
-do_test 1.13 {
- S changeset
- S delete
-} {}
+do_test $tn.1.11 { S delete } {}
+if {$tn==1} {
+ do_test $tn.1.12 {
+ sqlite3session S db main
+ S attach t1
+ execsql { INSERT INTO t1 VALUES('mno', 'pqr') }
+ execsql { UPDATE t1 SET x = 111 WHERE rowid = 1 }
+ execsql { DELETE FROM t1 WHERE rowid = 2 }
+ } {}
+ do_test $tn.1.13 {
+ S changeset
+ S delete
+ } {}
+}
#-------------------------------------------------------------------------
# Simple changeset tests. Also test the sqlite3changeset_invert()
# function.
#
-do_test 2.1.1 {
+do_test $tn.2.1.1 {
execsql { DELETE FROM t1 }
sqlite3session S db main
S attach t1
execsql { INSERT INTO t1 VALUES(2, 'Ayutthaya') }
execsql { INSERT INTO t1 VALUES(3, 'Thonburi') }
} {}
-do_changeset_test 2.1.2 S {
+do_changeset_test $tn.2.1.2 S {
{INSERT t1 0 X. {} {i 1 t Sukhothai}}
{INSERT t1 0 X. {} {i 2 t Ayutthaya}}
{INSERT t1 0 X. {} {i 3 t Thonburi}}
}
-do_changeset_invert_test 2.1.3 S {
+do_changeset_invert_test $tn.2.1.3 S {
{DELETE t1 0 X. {i 1 t Sukhothai} {}}
{DELETE t1 0 X. {i 2 t Ayutthaya} {}}
{DELETE t1 0 X. {i 3 t Thonburi} {}}
}
-do_test 2.1.4 { S delete } {}
+do_test $tn.2.1.4 { S delete } {}
-do_test 2.2.1 {
+do_test $tn.2.2.1 {
sqlite3session S db main
S attach t1
execsql { DELETE FROM t1 WHERE 1 }
} {}
-do_changeset_test 2.2.2 S {
+do_changeset_test $tn.2.2.2 S {
{DELETE t1 0 X. {i 1 t Sukhothai} {}}
{DELETE t1 0 X. {i 2 t Ayutthaya} {}}
{DELETE t1 0 X. {i 3 t Thonburi} {}}
}
-do_changeset_invert_test 2.2.3 S {
+do_changeset_invert_test $tn.2.2.3 S {
{INSERT t1 0 X. {} {i 1 t Sukhothai}}
{INSERT t1 0 X. {} {i 2 t Ayutthaya}}
{INSERT t1 0 X. {} {i 3 t Thonburi}}
}
-do_test 2.2.4 { S delete } {}
+do_test $tn.2.2.4 { S delete } {}
-do_test 2.3.1 {
+do_test $tn.2.3.1 {
execsql { DELETE FROM t1 }
sqlite3session S db main
execsql { INSERT INTO t1 VALUES(1, 'Sukhothai') }
}
} {}
-do_changeset_test 2.3.2 S {
+do_changeset_test $tn.2.3.2 S {
{INSERT t1 0 X. {} {i 10 t Sukhothai}}
{DELETE t1 0 X. {i 1 t Sukhothai} {}}
{UPDATE t1 0 X. {i 2 t Ayutthaya} {{} {} t Surin}}
{INSERT t1 0 X. {} {i 20 t Thapae}}
}
-do_changeset_invert_test 2.3.3 S {
+do_changeset_invert_test $tn.2.3.3 S {
{DELETE t1 0 X. {i 10 t Sukhothai} {}}
{INSERT t1 0 X. {} {i 1 t Sukhothai}}
{UPDATE t1 0 X. {i 2 t Surin} {{} {} t Ayutthaya}}
{INSERT t1 0 X. {} {i 3 t Thonburi}}
{DELETE t1 0 X. {i 20 t Thapae} {}}
}
-do_test 2.3.4 { S delete } {}
+do_test $tn.2.3.4 { S delete } {}
-do_test 2.4.1 {
+do_test $tn.2.4.1 {
sqlite3session S db main
S attach t1
execsql { INSERT INTO t1 VALUES(100, 'Bangkok') }
execsql { DELETE FROM t1 WHERE x = 100 }
} {}
-do_changeset_test 2.4.2 S {}
-do_changeset_invert_test 2.4.3 S {}
-do_test 2.4.4 { S delete } {}
+do_changeset_test $tn.2.4.2 S {}
+do_changeset_invert_test $tn.2.4.3 S {}
+do_test $tn.2.4.4 { S delete } {}
#-------------------------------------------------------------------------
# Test the application of simple changesets. These tests also test that
# Test INSERT changesets.
#
-do_test 3.1.0 {
- execsql { CREATE TABLE t1(a PRIMARY KEY, b NOT NULL) } db2
+do_test $tn.3.1.0 {
+ execsql { CREATE TABLE t1(a PRIMARY KEY, b NOT NULL) %WR% } db2
execsql {
- CREATE TABLE t1(a PRIMARY KEY, b);
+ CREATE TABLE t1(a PRIMARY KEY, b) %WR%;
INSERT INTO t1 VALUES(1, 'one');
INSERT INTO t1 VALUES(2, 'two');
} db
} {}
-do_db2_test 3.1.1 "INSERT INTO t1 VALUES(6, 'VI')"
-do_conflict_test 3.1.2 -tables t1 -sql {
+do_db2_test $tn.3.1.1 "INSERT INTO t1 VALUES(6, 'VI')"
+do_conflict_test $tn.3.1.2 -tables t1 -sql {
INSERT INTO t1 VALUES(3, 'three');
INSERT INTO t1 VALUES(4, 'four');
INSERT INTO t1 VALUES(5, 'five');
{INSERT t1 CONSTRAINT {i 8 n {}}}
}
-do_db2_test 3.1.3 "SELECT * FROM t1" {
- 6 VI 3 three 4 four 5 five 7 seven
+do_db2_test $tn.3.1.3 "SELECT * FROM t1 ORDER BY a" {
+ 3 three 4 four 5 five 6 VI 7 seven
}
-do_execsql_test 3.1.4 "SELECT * FROM t1" {
+do_execsql_test $tn.3.1.4 "SELECT * FROM t1" {
1 one 2 two 3 three 4 four 5 five 6 six 7 seven 8 {}
}
# Test DELETE changesets.
#
-do_execsql_test 3.2.1 {
+do_execsql_test $tn.3.2.1 {
PRAGMA foreign_keys = on;
- CREATE TABLE t2(a PRIMARY KEY, b);
+ CREATE TABLE t2(a PRIMARY KEY, b)%WR%;
CREATE TABLE t3(c, d REFERENCES t2);
INSERT INTO t2 VALUES(1, 'one');
INSERT INTO t2 VALUES(2, 'two');
INSERT INTO t2 VALUES(3, 'three');
INSERT INTO t2 VALUES(4, 'four');
}
-do_db2_test 3.2.2 {
+do_db2_test $tn.3.2.2 {
PRAGMA foreign_keys = on;
- CREATE TABLE t2(a PRIMARY KEY, b);
+ CREATE TABLE t2(a PRIMARY KEY, b)%WR%;
CREATE TABLE t3(c, d REFERENCES t2);
INSERT INTO t2 VALUES(1, 'one');
INSERT INTO t2 VALUES(2, 'two');
INSERT INTO t2 VALUES(4, 'five');
INSERT INTO t3 VALUES('i', 1);
}
-do_conflict_test 3.2.3 -tables t2 -sql {
+do_conflict_test $tn.3.2.3 -tables t2 -sql {
DELETE FROM t2 WHERE a = 1;
DELETE FROM t2 WHERE a = 2;
DELETE FROM t2 WHERE a = 3;
{DELETE t2 DATA {i 4 t four} {i 4 t five}}
{FOREIGN_KEY 1}
}
-do_execsql_test 3.2.4 "SELECT * FROM t2" {}
-do_db2_test 3.2.5 "SELECT * FROM t2" {4 five}
+do_execsql_test $tn.3.2.4 "SELECT * FROM t2" {}
+do_db2_test $tn.3.2.5 "SELECT * FROM t2" {4 five}
# Test UPDATE changesets.
#
-do_execsql_test 3.3.1 {
- CREATE TABLE t4(a, b, c, PRIMARY KEY(b, c));
+do_execsql_test $tn.3.3.1 {
+ CREATE TABLE t4(a, b, c, PRIMARY KEY(b, c))%WR%;
INSERT INTO t4 VALUES(1, 2, 3);
INSERT INTO t4 VALUES(4, 5, 6);
INSERT INTO t4 VALUES(7, 8, 9);
INSERT INTO t4 VALUES(10, 11, 12);
}
-do_db2_test 3.3.2 {
- CREATE TABLE t4(a NOT NULL, b, c, PRIMARY KEY(b, c));
+do_db2_test $tn.3.3.2 {
+ CREATE TABLE t4(a NOT NULL, b, c, PRIMARY KEY(b, c))%WR%;
INSERT INTO t4 VALUES(0, 2, 3);
INSERT INTO t4 VALUES(4, 5, 7);
INSERT INTO t4 VALUES(7, 8, 9);
INSERT INTO t4 VALUES(10, 11, 12);
}
-do_conflict_test 3.3.3 -tables t4 -sql {
+do_conflict_test $tn.3.3.3 -tables t4 -sql {
UPDATE t4 SET a = -1 WHERE b = 2;
UPDATE t4 SET a = -1 WHERE b = 5;
UPDATE t4 SET a = NULL WHERE c = 9;
{UPDATE t4 NOTFOUND {i 4 i 5 i 6} {i -1 {} {} {} {}}}
{UPDATE t4 CONSTRAINT {i 7 i 8 i 9} {n {} {} {} {} {}}}
}
-do_db2_test 3.3.4 { SELECT * FROM t4 } {0 2 3 4 5 7 7 8 9 x 11 12}
-do_execsql_test 3.3.5 { SELECT * FROM t4 } {-1 2 3 -1 5 6 {} 8 9 x 11 12}
+do_db2_test $tn.3.3.4 { SELECT * FROM t4 } {0 2 3 4 5 7 7 8 9 x 11 12}
+do_execsql_test $tn.3.3.5 { SELECT * FROM t4 } {-1 2 3 -1 5 6 {} 8 9 x 11 12}
#-------------------------------------------------------------------------
# This next block of tests verifies that values returned by the conflict
return $::conflict_return
}
-foreach {tn conflict_return after} {
+foreach {tn2 conflict_return after} {
1 OMIT {1 2 value1 4 5 7 10 x x}
2 REPLACE {1 2 value1 4 5 value2 10 8 9}
} {
test_reset
- do_test 4.$tn.1 {
+ do_test $tn.4.$tn2.1 {
foreach db {db db2} {
execsql {
- CREATE TABLE t1(a, b, c, PRIMARY KEY(a));
+ CREATE TABLE t1(a, b, c, PRIMARY KEY(a))%WR%;
INSERT INTO t1 VALUES(1, 2, 3);
INSERT INTO t1 VALUES(4, 5, 6);
INSERT INTO t1 VALUES(7, 8, 9);
} db2
} {}
- do_conflict_test 4.$tn.2 -tables t1 -sql {
+ do_conflict_test $tn.4.$tn2.2 -tables t1 -sql {
UPDATE t1 SET c = 'value1' WHERE a = 1; -- no conflict
UPDATE t1 SET c = 'value2' WHERE a = 4; -- DATA conflict
UPDATE t1 SET a = 10 WHERE a = 7; -- CONFLICT conflict
{UPDATE t1 DATA {i 4 {} {} i 6} {{} {} {} {} t value2} {i 4 i 5 i 7}}
}
- do_db2_test 4.$tn.3 "SELECT * FROM t1 ORDER BY a" $after
+ do_db2_test $tn.4.$tn2.3 "SELECT * FROM t1 ORDER BY a" $after
}
-foreach {tn conflict_return} {
+foreach {tn2 conflict_return} {
1 OMIT
2 REPLACE
} {
test_reset
- do_test 5.$tn.1 {
+ do_test $tn.5.$tn2.1 {
# Create an identical schema in both databases.
set schema {
- CREATE TABLE "'foolish name'"(x, y, z, PRIMARY KEY(x, y));
+ CREATE TABLE "'foolish name'"(x, y, z, PRIMARY KEY(x, y))%WR%;
}
execsql $schema db
execsql $schema db2
} {}
- do_conflict_test 5.$tn.2 -tables {{'foolish name'}} -sql {
+ do_conflict_test $tn.5.$tn2.2 -tables {{'foolish name'}} -sql {
INSERT INTO "'foolish name'" VALUES('one', 'two', 2);
} -conflicts {
{INSERT {'foolish name'} CONFLICT {t one t two i 2} {t one t two t i}}
set res(REPLACE) {one one ii one two 2 two two ii}
set res(OMIT) {one one ii one two i two two ii}
- do_db2_test 5.$tn.3 {
+ do_db2_test $tn.5.$tn2.3 {
SELECT * FROM "'foolish name'" ORDER BY x, y
} $res($conflict_return)
- do_test 5.$tn.1 {
+ do_test $tn.5.$tn2.1 {
set schema {
- CREATE TABLE d1("z""z" PRIMARY KEY, y);
+ CREATE TABLE d1("z""z" PRIMARY KEY, y)%WR%;
INSERT INTO d1 VALUES(1, 'one');
INSERT INTO d1 VALUES(2, 'two');
}
} {}
- do_conflict_test 5.$tn.2 -tables d1 -sql {
+ do_conflict_test $tn.5.$tn2.2 -tables d1 -sql {
DELETE FROM d1 WHERE "z""z" = 2;
} -conflicts {
{DELETE d1 DATA {i 2 t two} {i 2 t TWO}}
set res(REPLACE) {1 one}
set res(OMIT) {1 one 2 TWO}
- do_db2_test 5.$tn.3 "SELECT * FROM d1" $res($conflict_return)
+ do_db2_test $tn.5.$tn2.3 "SELECT * FROM d1" $res($conflict_return)
}
#-------------------------------------------------------------------------
#
test_reset
set schema {
- CREATE TABLE t1(a COLLATE nocase PRIMARY KEY, b);
- CREATE TABLE t2(a, b PRIMARY KEY);
+ CREATE TABLE t1(a COLLATE nocase PRIMARY KEY, b)%WR%;
+ CREATE TABLE t2(a, b PRIMARY KEY)%WR%;
}
-do_test 6.0 {
+do_test $tn.6.0 {
execsql $schema db
execsql $schema db2
execsql {
} {}
set conflict_return ""
-do_conflict_test 6.1 -tables {t1 t2} -sql {
+do_conflict_test $tn.6.1 -tables {t1 t2} -sql {
INSERT INTO t1 VALUES('1', '2');
INSERT INTO t1 VALUES('A', 'B');
INSERT INTO t2 VALUES('A', 'B');
{INSERT t1 CONFLICT {t A t B} {t a t b}}
}
-do_db2_test 6.2 "SELECT * FROM t1" {a b 1 2}
-do_db2_test 6.3 "SELECT * FROM t2" {a b A B}
+do_db2_test $tn.6.2 "SELECT * FROM t1 ORDER BY a" {1 2 a b}
+do_db2_test $tn.6.3 "SELECT * FROM t2 ORDER BY a" {A B a b}
#-------------------------------------------------------------------------
# Test that session objects are not confused by changes to table in
catch { db2 close }
drop_all_tables
forcedelete test.db2
-do_iterator_test 7.1 * {
+do_iterator_test $tn.7.1 * {
ATTACH 'test.db2' AS aux;
- CREATE TABLE main.t1(x PRIMARY KEY, y);
- CREATE TABLE aux.t1(x PRIMARY KEY, y);
+ CREATE TABLE main.t1(x PRIMARY KEY, y)%WR%;
+ CREATE TABLE aux.t1(x PRIMARY KEY, y)%WR%;
INSERT INTO main.t1 VALUES('one', 1);
INSERT INTO main.t1 VALUES('two', 2);
#-------------------------------------------------------------------------
# Test the sqlite3session_isempty() function.
#
-do_test 8.1 {
+do_test $tn.8.1 {
execsql {
- CREATE TABLE t5(x PRIMARY KEY, y);
- CREATE TABLE t6(x PRIMARY KEY, y);
+ CREATE TABLE t5(x PRIMARY KEY, y)%WR%;
+ CREATE TABLE t6(x PRIMARY KEY, y)%WR%;
INSERT INTO t5 VALUES('a', 'b');
INSERT INTO t6 VALUES('a', 'b');
}
S isempty
} {1}
-do_test 8.2 {
+do_test $tn.8.2 {
execsql { DELETE FROM t5 }
S isempty
} {0}
-do_test 8.3 {
+do_test $tn.8.3 {
S delete
sqlite3session S db main
S attach t5
execsql { DELETE FROM t5 }
S isempty
} {1}
-do_test 8.4 { S delete } {}
+do_test $tn.8.4 { S delete } {}
-do_test 8.5 {
+do_test $tn.8.5 {
sqlite3session S db main
S attach t5
S attach t6
S isempty
} {0}
-do_test 8.6 {
+do_test $tn.8.6 {
S delete
sqlite3session S db main
S attach t5
execsql { INSERT INTO t6 VALUES(1, 2) }
S isempty
} {0}
-do_test 8.7 { S delete } {}
+do_test $tn.8.7 { S delete } {}
#-------------------------------------------------------------------------
#
-do_execsql_test 9.1 {
- CREATE TABLE t7(a, b, c, d, e PRIMARY KEY, f, g);
+do_execsql_test $tn.9.1 {
+ CREATE TABLE t7(a, b, c, d, e PRIMARY KEY, f, g)%WR%;
INSERT INTO t7 VALUES(1, 1, 1, 1, 1, 1, 1);
}
-do_test 9.2 {
+do_test $tn.9.2 {
sqlite3session S db main
S attach *
execsql { UPDATE t7 SET b=2, d=2 }
} {}
-do_changeset_test 9.2 S {{UPDATE t7 0 ....X.. {{} {} i 1 {} {} i 1 i 1 {} {} {} {}} {{} {} i 2 {} {} i 2 {} {} {} {} {} {}}}}
+do_changeset_test $tn.9.2 S {{UPDATE t7 0 ....X.. {{} {} i 1 {} {} i 1 i 1 {} {} {} {}} {{} {} i 2 {} {} i 2 {} {} {} {} {} {}}}}
S delete
catch { db2 close }
#
reset_db
set tblname [string repeat tblname123 100]
-do_test 10.1.1 {
+do_test $tn.10.1.1 {
execsql "
- CREATE TABLE $tblname (a PRIMARY KEY, b);
+ CREATE TABLE $tblname (a PRIMARY KEY, b)%WR%;
INSERT INTO $tblname VALUES('xyz', 'def');
"
sqlite3session S db main
"
} {}
breakpoint
-do_changeset_test 10.1.2 S "
+do_changeset_test $tn.10.1.2 S "
{INSERT $tblname 0 X. {} {t uvw t abc}}
{DELETE $tblname 0 X. {t xyz t def} {}}
"
-do_test 10.1.4 { S delete } {}
+do_test $tn.10.1.4 { S delete } {}
#---------------------------------------------------------------
reset_db
-do_execsql_test 11.1 {
+do_execsql_test $tn.11.1 {
CREATE TABLE t1(a, b);
}
-do_test 11.2 {
+do_test $tn.11.2 {
sqlite3session S db main
S attach t1
execsql {
#
reset_db
set tblname [string repeat tblname123 100]
-do_test 10.1.1 {
+do_test $tn.10.1.1 {
execsql "
- CREATE TABLE $tblname (a PRIMARY KEY, b);
+ CREATE TABLE $tblname (a PRIMARY KEY, b)%WR%;
INSERT INTO $tblname VALUES('xyz', 'def');
"
sqlite3session S db main
"
} {}
breakpoint
-do_changeset_test 10.1.2 S "
+do_changeset_test $tn.10.1.2 S "
{INSERT $tblname 0 X. {} {t uvw t abc}}
{DELETE $tblname 0 X. {t xyz t def} {}}
"
-do_test 10.1.4 { S delete } {}
+do_test $tn.10.1.4 { S delete } {}
#-------------------------------------------------------------------------
# Test the effect of updating a column from 0.0 to 0.0.
#
reset_db
-do_execsql_test 11.1 {
- CREATE TABLE t1(a INTEGER PRIMARY KEY, b REAL);
+do_execsql_test $tn.11.1 {
+ CREATE TABLE t1(a INTEGER PRIMARY KEY, b REAL)%WR%;
INSERT INTO t1 VALUES(1, 0.0);
}
-do_iterator_test 11.2 * {
+do_iterator_test $tn.11.2 * {
UPDATE t1 SET b = 0.0;
} {
}
reset_db
-do_execsql_test 12.1 {
- CREATE TABLE t1(r INTEGER PRIMARY KEY, a, b);
+do_execsql_test $tn.12.1 {
+ CREATE TABLE t1(r INTEGER PRIMARY KEY, a, b)%WR%;
CREATE INDEX i1 ON t1(a);
INSERT INTO t1 VALUES(1, 1, 1);
INSERT INTO t1 VALUES(2, 1, 2);
INSERT INTO t1 VALUES(3, 1, 3);
}
-do_iterator_test 12.2 * {
+do_iterator_test $tn.12.2 * {
UPDATE t1 SET b='one' WHERE a=1;
} {
{UPDATE t1 0 X.. {i 1 {} {} i 1} {{} {} {} {} t one}}
{UPDATE t1 0 X.. {i 3 {} {} i 3} {{} {} {} {} t one}}
}
+}]
+}
finish_test
--- /dev/null
+# 2017 Jan 30
+#
+# The author disclaims copyright to this source code. In place of
+# a legal notice, here is a blessing:
+#
+# May you do good and not evil.
+# May you find forgiveness for yourself and forgive others.
+# May you share freely, never taking more than you give.
+#
+#***********************************************************************
+# The tests in this file focus on the pre-update hook.
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+set ::testprefix hook2
+
+ifcapable !preupdate {
+ finish_test
+ return
+}
+
+#-------------------------------------------------------------------------
+proc do_preupdate_test {tn sql x} {
+ set X [list]
+ foreach elem $x {lappend X $elem}
+ uplevel do_test $tn [list "
+ set ::preupdate \[list\]
+ execsql { $sql }
+ set ::preupdate
+ "] [list $X]
+}
+
+proc preupdate_hook {args} {
+ set type [lindex $args 0]
+ eval lappend ::preupdate $args
+ if {$type != "INSERT"} {
+ for {set i 0} {$i < [db preupdate count]} {incr i} {
+ lappend ::preupdate [db preupdate old $i]
+ }
+ }
+ if {$type != "DELETE"} {
+ for {set i 0} {$i < [db preupdate count]} {incr i} {
+ set rc [catch { db preupdate new $i } v]
+ lappend ::preupdate $v
+ }
+ }
+}
+
+#-------------------------------------------------------------------------
+# Simple tests - INSERT, UPDATE and DELETE on a WITHOUT ROWID table.
+#
+db preupdate hook preupdate_hook
+do_execsql_test 1.0 {
+ CREATE TABLE t1(a PRIMARY KEY, b) WITHOUT ROWID;
+}
+do_preupdate_test 1.1 {
+ INSERT INTO t1 VALUES('one', 1);
+} {
+ INSERT main t1 0 0 one 1
+}
+do_preupdate_test 1.2 {
+ UPDATE t1 SET b=2 WHERE a='one';
+} {
+ UPDATE main t1 0 0 one 1 one 2
+}
+do_preupdate_test 1.3 {
+ DELETE FROM t1 WHERE a='one';
+} {
+ DELETE main t1 0 0 one 2
+}
+
+#-------------------------------------------------------------------------
+# Some more complex tests for the pre-update callback on WITHOUT ROWID
+# tables.
+#
+# 2.1.1 - INSERT statement.
+# 2.1.2 - INSERT INTO ... SELECT statement.
+# 2.1.3 - REPLACE INTO ... (PK conflict)
+# 2.1.4 - REPLACE INTO ... (other index conflicts)
+# 2.1.5 - REPLACE INTO ... (both PK and other index conflicts)
+#
+# 2.2.1 - DELETE statement.
+# 2.2.2 - DELETE statement that uses the truncate optimization.
+#
+# 2.3.1 - UPDATE statement.
+# 2.3.2 - UPDATE statement that modifies the PK.
+# 2.3.3 - UPDATE OR REPLACE ... (PK conflict).
+# 2.3.4 - UPDATE OR REPLACE ... (other index conflicts)
+# 2.3.4 - UPDATE OR REPLACE ... (both PK and other index conflicts)
+#
+do_execsql_test 2.0 {
+ CREATE TABLE t2(a DEFAULT 4, b, c, PRIMARY KEY(b, c)) WITHOUT ROWID;
+ CREATE UNIQUE INDEX t2a ON t2(a);
+}
+
+do_preupdate_test 2.1.1 {
+ INSERT INTO t2(b, c) VALUES(1, 1);
+} {
+ INSERT main t2 0 0 4 1 1
+}
+
+do_execsql_test 2.1.2.0 {
+ CREATE TABLE d1(a DEFAULT 4, b, c, PRIMARY KEY(b, c)) WITHOUT ROWID;
+ CREATE UNIQUE INDEX d1a ON d1(a);
+ INSERT INTO d1 VALUES(1, 2, 3);
+ INSERT INTO d1 VALUES(11, 12, 13);
+}
+do_preupdate_test 2.1.2.1 {
+ INSERT INTO t2 SELECT * FROM d1;
+} {
+ INSERT main t2 0 0 1 2 3
+ INSERT main t2 0 0 11 12 13
+}
+do_preupdate_test 2.1.2.2 {
+ INSERT INTO t2 SELECT a+20, b+20, c+20 FROM d1;
+} {
+ INSERT main t2 0 0 21 22 23
+ INSERT main t2 0 0 31 32 33
+}
+do_execsql_test 2.1.2.3 {
+ SELECT * FROM t2 ORDER BY b, c;
+} {
+ 4 1 1
+ 1 2 3
+ 11 12 13
+ 21 22 23
+ 31 32 33
+}
+do_preupdate_test 2.1.3 {
+ REPLACE INTO t2 VALUES(45, 22, 23);
+} {
+ DELETE main t2 0 0 21 22 23
+ INSERT main t2 0 0 45 22 23
+}
+do_preupdate_test 2.1.4 {
+ REPLACE INTO t2 VALUES(11, 100, 100);
+} {
+ DELETE main t2 0 0 11 12 13
+ INSERT main t2 0 0 11 100 100
+}
+do_preupdate_test 2.1.5 {
+ REPLACE INTO t2(c, b) VALUES(33, 32)
+} {
+ DELETE main t2 0 0 4 1 1
+ DELETE main t2 0 0 31 32 33
+ INSERT main t2 0 0 4 32 33
+}
+
+do_execsql_test 2.2.0 {
+ SELECT * FROM t2 ORDER BY b,c;
+} {
+ 1 2 3
+ 45 22 23
+ 4 32 33
+ 11 100 100
+}
+do_preupdate_test 2.2.1 {
+ DELETE FROM t2 WHERE b=22;
+} {
+ DELETE main t2 0 0 45 22 23
+}
+do_preupdate_test 2.2.2 {
+ DELETE FROM t2;
+} {
+ DELETE main t2 0 0 1 2 3
+ DELETE main t2 0 0 4 32 33
+ DELETE main t2 0 0 11 100 100
+}
+
+do_execsql_test 2.3.0 {
+ CREATE TABLE t3(x, y PRIMARY KEY, z UNIQUE) WITHOUT ROWID;
+ INSERT INTO t3 VALUES('a', 'b', 'c');
+ INSERT INTO t3 VALUES('d', 'e', 'f');
+
+ INSERT INTO t3 VALUES(1, 1, 1);
+ INSERT INTO t3 VALUES(2, 2, 2);
+ INSERT INTO t3 VALUES(3, 3, 3);
+}
+
+do_preupdate_test 2.3.1 {
+ UPDATE t3 SET x=4 WHERE y IN ('b', 'e', 'x');
+} {
+ UPDATE main t3 0 0 a b c 4 b c
+ UPDATE main t3 0 0 d e f 4 e f
+}
+
+do_preupdate_test 2.3.2 {
+ UPDATE t3 SET y=y||y WHERE z IN('c', 'f');
+} {
+ UPDATE main t3 0 0 4 b c 4 bb c
+ UPDATE main t3 0 0 4 e f 4 ee f
+}
+
+do_preupdate_test 2.3.3 {
+ UPDATE OR REPLACE t3 SET y='bb' WHERE z='f'
+} {
+ DELETE main t3 0 0 4 bb c
+ UPDATE main t3 0 0 4 ee f 4 bb f
+}
+
+do_preupdate_test 2.3.4 {
+ UPDATE OR REPLACE t3 SET z=2 WHERE y=1;
+} {
+ DELETE main t3 0 0 2 2 2
+ UPDATE main t3 0 0 1 1 1 1 1 2
+}
+
+do_preupdate_test 2.3.5 {
+ UPDATE OR REPLACE t3 SET z=2, y='bb' WHERE y=3;
+} {
+ DELETE main t3 0 0 1 1 2
+ DELETE main t3 0 0 4 bb f
+ UPDATE main t3 0 0 3 3 3 3 bb 2
+}
+
+
+finish_test