xref: /sqlite-3.40.0/test/hook2.test (revision cb9a3643)
1*cb9a3643Sdan# 2017 Jan 30
2*cb9a3643Sdan#
3*cb9a3643Sdan# The author disclaims copyright to this source code.  In place of
4*cb9a3643Sdan# a legal notice, here is a blessing:
5*cb9a3643Sdan#
6*cb9a3643Sdan#    May you do good and not evil.
7*cb9a3643Sdan#    May you find forgiveness for yourself and forgive others.
8*cb9a3643Sdan#    May you share freely, never taking more than you give.
9*cb9a3643Sdan#
10*cb9a3643Sdan#***********************************************************************
11*cb9a3643Sdan# The tests in this file focus on the pre-update hook.
12*cb9a3643Sdan#
13*cb9a3643Sdan
14*cb9a3643Sdanset testdir [file dirname $argv0]
15*cb9a3643Sdansource $testdir/tester.tcl
16*cb9a3643Sdanset ::testprefix hook2
17*cb9a3643Sdan
18*cb9a3643Sdanifcapable !preupdate {
19*cb9a3643Sdan  finish_test
20*cb9a3643Sdan  return
21*cb9a3643Sdan}
22*cb9a3643Sdan
23*cb9a3643Sdan#-------------------------------------------------------------------------
24*cb9a3643Sdanproc do_preupdate_test {tn sql x} {
25*cb9a3643Sdan  set X [list]
26*cb9a3643Sdan  foreach elem $x {lappend X $elem}
27*cb9a3643Sdan  uplevel do_test $tn [list "
28*cb9a3643Sdan    set ::preupdate \[list\]
29*cb9a3643Sdan    execsql { $sql }
30*cb9a3643Sdan    set ::preupdate
31*cb9a3643Sdan  "] [list $X]
32*cb9a3643Sdan}
33*cb9a3643Sdan
34*cb9a3643Sdanproc preupdate_hook {args} {
35*cb9a3643Sdan  set type [lindex $args 0]
36*cb9a3643Sdan  eval lappend ::preupdate $args
37*cb9a3643Sdan  if {$type != "INSERT"} {
38*cb9a3643Sdan    for {set i 0} {$i < [db preupdate count]} {incr i} {
39*cb9a3643Sdan      lappend ::preupdate [db preupdate old $i]
40*cb9a3643Sdan    }
41*cb9a3643Sdan  }
42*cb9a3643Sdan  if {$type != "DELETE"} {
43*cb9a3643Sdan    for {set i 0} {$i < [db preupdate count]} {incr i} {
44*cb9a3643Sdan      set rc [catch { db preupdate new $i } v]
45*cb9a3643Sdan      lappend ::preupdate $v
46*cb9a3643Sdan    }
47*cb9a3643Sdan  }
48*cb9a3643Sdan}
49*cb9a3643Sdan
50*cb9a3643Sdan#-------------------------------------------------------------------------
51*cb9a3643Sdan# Simple tests - INSERT, UPDATE and DELETE on a WITHOUT ROWID table.
52*cb9a3643Sdan#
53*cb9a3643Sdandb preupdate hook preupdate_hook
54*cb9a3643Sdando_execsql_test 1.0 {
55*cb9a3643Sdan  CREATE TABLE t1(a PRIMARY KEY, b) WITHOUT ROWID;
56*cb9a3643Sdan}
57*cb9a3643Sdando_preupdate_test 1.1 {
58*cb9a3643Sdan  INSERT INTO t1 VALUES('one', 1);
59*cb9a3643Sdan} {
60*cb9a3643Sdan  INSERT main t1 0 0  one 1
61*cb9a3643Sdan}
62*cb9a3643Sdando_preupdate_test 1.2 {
63*cb9a3643Sdan  UPDATE t1 SET b=2 WHERE a='one';
64*cb9a3643Sdan} {
65*cb9a3643Sdan  UPDATE main t1 0 0  one 1 one 2
66*cb9a3643Sdan}
67*cb9a3643Sdando_preupdate_test 1.3 {
68*cb9a3643Sdan  DELETE FROM t1 WHERE a='one';
69*cb9a3643Sdan} {
70*cb9a3643Sdan  DELETE main t1 0 0  one 2
71*cb9a3643Sdan}
72*cb9a3643Sdan
73*cb9a3643Sdan#-------------------------------------------------------------------------
74*cb9a3643Sdan# Some more complex tests for the pre-update callback on WITHOUT ROWID
75*cb9a3643Sdan# tables.
76*cb9a3643Sdan#
77*cb9a3643Sdan#   2.1.1 - INSERT statement.
78*cb9a3643Sdan#   2.1.2 - INSERT INTO ... SELECT statement.
79*cb9a3643Sdan#   2.1.3 - REPLACE INTO ... (PK conflict)
80*cb9a3643Sdan#   2.1.4 - REPLACE INTO ... (other index conflicts)
81*cb9a3643Sdan#   2.1.5 - REPLACE INTO ... (both PK and other index conflicts)
82*cb9a3643Sdan#
83*cb9a3643Sdan#   2.2.1 - DELETE statement.
84*cb9a3643Sdan#   2.2.2 - DELETE statement that uses the truncate optimization.
85*cb9a3643Sdan#
86*cb9a3643Sdan#   2.3.1 - UPDATE statement.
87*cb9a3643Sdan#   2.3.2 - UPDATE statement that modifies the PK.
88*cb9a3643Sdan#   2.3.3 - UPDATE OR REPLACE ... (PK conflict).
89*cb9a3643Sdan#   2.3.4 - UPDATE OR REPLACE ... (other index conflicts)
90*cb9a3643Sdan#   2.3.4 - UPDATE OR REPLACE ... (both PK and other index conflicts)
91*cb9a3643Sdan#
92*cb9a3643Sdando_execsql_test 2.0 {
93*cb9a3643Sdan  CREATE TABLE t2(a DEFAULT 4, b, c, PRIMARY KEY(b, c)) WITHOUT ROWID;
94*cb9a3643Sdan  CREATE UNIQUE INDEX t2a ON t2(a);
95*cb9a3643Sdan}
96*cb9a3643Sdan
97*cb9a3643Sdando_preupdate_test 2.1.1 {
98*cb9a3643Sdan  INSERT INTO t2(b, c) VALUES(1, 1);
99*cb9a3643Sdan} {
100*cb9a3643Sdan  INSERT main t2 0 0  4 1 1
101*cb9a3643Sdan}
102*cb9a3643Sdan
103*cb9a3643Sdando_execsql_test 2.1.2.0 {
104*cb9a3643Sdan  CREATE TABLE d1(a DEFAULT 4, b, c, PRIMARY KEY(b, c)) WITHOUT ROWID;
105*cb9a3643Sdan  CREATE UNIQUE INDEX d1a ON d1(a);
106*cb9a3643Sdan  INSERT INTO d1 VALUES(1, 2, 3);
107*cb9a3643Sdan  INSERT INTO d1 VALUES(11, 12, 13);
108*cb9a3643Sdan}
109*cb9a3643Sdando_preupdate_test 2.1.2.1 {
110*cb9a3643Sdan  INSERT INTO t2 SELECT * FROM d1;
111*cb9a3643Sdan} {
112*cb9a3643Sdan  INSERT main t2 0 0  1 2 3
113*cb9a3643Sdan  INSERT main t2 0 0  11 12 13
114*cb9a3643Sdan}
115*cb9a3643Sdando_preupdate_test 2.1.2.2 {
116*cb9a3643Sdan  INSERT INTO t2 SELECT a+20, b+20, c+20 FROM d1;
117*cb9a3643Sdan} {
118*cb9a3643Sdan  INSERT main t2 0 0  21 22 23
119*cb9a3643Sdan  INSERT main t2 0 0  31 32 33
120*cb9a3643Sdan}
121*cb9a3643Sdando_execsql_test 2.1.2.3 {
122*cb9a3643Sdan  SELECT * FROM t2 ORDER BY b, c;
123*cb9a3643Sdan} {
124*cb9a3643Sdan  4 1 1
125*cb9a3643Sdan  1 2 3
126*cb9a3643Sdan  11 12 13
127*cb9a3643Sdan  21 22 23
128*cb9a3643Sdan  31 32 33
129*cb9a3643Sdan}
130*cb9a3643Sdando_preupdate_test 2.1.3 {
131*cb9a3643Sdan  REPLACE INTO t2 VALUES(45, 22, 23);
132*cb9a3643Sdan} {
133*cb9a3643Sdan  DELETE main t2 0 0 21 22 23
134*cb9a3643Sdan  INSERT main t2 0 0 45 22 23
135*cb9a3643Sdan}
136*cb9a3643Sdando_preupdate_test 2.1.4 {
137*cb9a3643Sdan  REPLACE INTO t2 VALUES(11, 100, 100);
138*cb9a3643Sdan} {
139*cb9a3643Sdan  DELETE main t2 0 0 11 12 13
140*cb9a3643Sdan  INSERT main t2 0 0 11 100 100
141*cb9a3643Sdan}
142*cb9a3643Sdando_preupdate_test 2.1.5 {
143*cb9a3643Sdan  REPLACE INTO t2(c, b) VALUES(33, 32)
144*cb9a3643Sdan} {
145*cb9a3643Sdan  DELETE main t2 0 0 4 1 1
146*cb9a3643Sdan  DELETE main t2 0 0 31 32 33
147*cb9a3643Sdan  INSERT main t2 0 0 4 32 33
148*cb9a3643Sdan}
149*cb9a3643Sdan
150*cb9a3643Sdando_execsql_test 2.2.0 {
151*cb9a3643Sdan  SELECT * FROM t2 ORDER BY b,c;
152*cb9a3643Sdan} {
153*cb9a3643Sdan  1    2   3
154*cb9a3643Sdan  45  22  23
155*cb9a3643Sdan  4   32  33
156*cb9a3643Sdan  11 100 100
157*cb9a3643Sdan}
158*cb9a3643Sdando_preupdate_test 2.2.1 {
159*cb9a3643Sdan  DELETE FROM t2 WHERE b=22;
160*cb9a3643Sdan} {
161*cb9a3643Sdan  DELETE main t2 0 0  45 22 23
162*cb9a3643Sdan}
163*cb9a3643Sdando_preupdate_test 2.2.2 {
164*cb9a3643Sdan  DELETE FROM t2;
165*cb9a3643Sdan} {
166*cb9a3643Sdan  DELETE main t2 0 0 1 2 3
167*cb9a3643Sdan  DELETE main t2 0 0 4 32 33
168*cb9a3643Sdan  DELETE main t2 0 0 11 100 100
169*cb9a3643Sdan}
170*cb9a3643Sdan
171*cb9a3643Sdando_execsql_test 2.3.0 {
172*cb9a3643Sdan  CREATE TABLE t3(x, y PRIMARY KEY, z UNIQUE) WITHOUT ROWID;
173*cb9a3643Sdan  INSERT INTO t3 VALUES('a', 'b', 'c');
174*cb9a3643Sdan  INSERT INTO t3 VALUES('d', 'e', 'f');
175*cb9a3643Sdan
176*cb9a3643Sdan  INSERT INTO t3 VALUES(1, 1, 1);
177*cb9a3643Sdan  INSERT INTO t3 VALUES(2, 2, 2);
178*cb9a3643Sdan  INSERT INTO t3 VALUES(3, 3, 3);
179*cb9a3643Sdan}
180*cb9a3643Sdan
181*cb9a3643Sdando_preupdate_test 2.3.1 {
182*cb9a3643Sdan  UPDATE t3 SET x=4 WHERE y IN ('b', 'e', 'x');
183*cb9a3643Sdan} {
184*cb9a3643Sdan  UPDATE main t3 0 0  a b c   4 b c
185*cb9a3643Sdan  UPDATE main t3 0 0  d e f   4 e f
186*cb9a3643Sdan}
187*cb9a3643Sdan
188*cb9a3643Sdando_preupdate_test 2.3.2 {
189*cb9a3643Sdan  UPDATE t3 SET y=y||y WHERE z IN('c', 'f');
190*cb9a3643Sdan} {
191*cb9a3643Sdan  UPDATE main t3 0 0  4 b c   4 bb c
192*cb9a3643Sdan  UPDATE main t3 0 0  4 e f   4 ee f
193*cb9a3643Sdan}
194*cb9a3643Sdan
195*cb9a3643Sdando_preupdate_test 2.3.3 {
196*cb9a3643Sdan  UPDATE OR REPLACE t3 SET y='bb' WHERE z='f'
197*cb9a3643Sdan} {
198*cb9a3643Sdan  DELETE main t3 0 0  4 bb c
199*cb9a3643Sdan  UPDATE main t3 0 0  4 ee f   4 bb f
200*cb9a3643Sdan}
201*cb9a3643Sdan
202*cb9a3643Sdando_preupdate_test 2.3.4 {
203*cb9a3643Sdan  UPDATE OR REPLACE t3 SET z=2 WHERE y=1;
204*cb9a3643Sdan} {
205*cb9a3643Sdan  DELETE main t3 0 0  2 2 2
206*cb9a3643Sdan  UPDATE main t3 0 0  1 1 1  1 1 2
207*cb9a3643Sdan}
208*cb9a3643Sdan
209*cb9a3643Sdando_preupdate_test 2.3.5 {
210*cb9a3643Sdan  UPDATE OR REPLACE t3 SET z=2, y='bb' WHERE y=3;
211*cb9a3643Sdan} {
212*cb9a3643Sdan  DELETE main t3 0 0  1 1 2
213*cb9a3643Sdan  DELETE main t3 0 0  4 bb f
214*cb9a3643Sdan  UPDATE main t3 0 0  3 3 3  3 bb 2
215*cb9a3643Sdan}
216*cb9a3643Sdan
217*cb9a3643Sdan
218*cb9a3643Sdanfinish_test
219