xref: /onnv-gate/usr/src/lib/libsqlite/test/trans.test (revision 4520:7dbeadedd7fe)
1*4520Snw141292
2*4520Snw141292#pragma ident	"%Z%%M%	%I%	%E% SMI"
3*4520Snw141292
4*4520Snw141292# 2001 September 15
5*4520Snw141292#
6*4520Snw141292# The author disclaims copyright to this source code.  In place of
7*4520Snw141292# a legal notice, here is a blessing:
8*4520Snw141292#
9*4520Snw141292#    May you do good and not evil.
10*4520Snw141292#    May you find forgiveness for yourself and forgive others.
11*4520Snw141292#    May you share freely, never taking more than you give.
12*4520Snw141292#
13*4520Snw141292#***********************************************************************
14*4520Snw141292# This file implements regression tests for SQLite library.  The
15*4520Snw141292# focus of this script is database locks.
16*4520Snw141292#
17*4520Snw141292# $Id: trans.test,v 1.19 2004/03/08 13:26:18 drh Exp $
18*4520Snw141292
19*4520Snw141292
20*4520Snw141292set testdir [file dirname $argv0]
21*4520Snw141292source $testdir/tester.tcl
22*4520Snw141292
23*4520Snw141292
24*4520Snw141292# Create several tables to work with.
25*4520Snw141292#
26*4520Snw141292do_test trans-1.0 {
27*4520Snw141292  execsql {
28*4520Snw141292    CREATE TABLE one(a int PRIMARY KEY, b text);
29*4520Snw141292    INSERT INTO one VALUES(1,'one');
30*4520Snw141292    INSERT INTO one VALUES(2,'two');
31*4520Snw141292    INSERT INTO one VALUES(3,'three');
32*4520Snw141292    SELECT b FROM one ORDER BY a;
33*4520Snw141292  }
34*4520Snw141292} {one two three}
35*4520Snw141292do_test trans-1.1 {
36*4520Snw141292  execsql {
37*4520Snw141292    CREATE TABLE two(a int PRIMARY KEY, b text);
38*4520Snw141292    INSERT INTO two VALUES(1,'I');
39*4520Snw141292    INSERT INTO two VALUES(5,'V');
40*4520Snw141292    INSERT INTO two VALUES(10,'X');
41*4520Snw141292    SELECT b FROM two ORDER BY a;
42*4520Snw141292  }
43*4520Snw141292} {I V X}
44*4520Snw141292do_test trans-1.9 {
45*4520Snw141292  sqlite altdb test.db
46*4520Snw141292  execsql {SELECT b FROM one ORDER BY a} altdb
47*4520Snw141292} {one two three}
48*4520Snw141292do_test trans-1.10 {
49*4520Snw141292  execsql {SELECT b FROM two ORDER BY a} altdb
50*4520Snw141292} {I V X}
51*4520Snw141292integrity_check trans-1.11
52*4520Snw141292
53*4520Snw141292# Basic transactions
54*4520Snw141292#
55*4520Snw141292do_test trans-2.1 {
56*4520Snw141292  set v [catch {execsql {BEGIN}} msg]
57*4520Snw141292  lappend v $msg
58*4520Snw141292} {0 {}}
59*4520Snw141292do_test trans-2.2 {
60*4520Snw141292  set v [catch {execsql {END}} msg]
61*4520Snw141292  lappend v $msg
62*4520Snw141292} {0 {}}
63*4520Snw141292do_test trans-2.3 {
64*4520Snw141292  set v [catch {execsql {BEGIN TRANSACTION}} msg]
65*4520Snw141292  lappend v $msg
66*4520Snw141292} {0 {}}
67*4520Snw141292do_test trans-2.4 {
68*4520Snw141292  set v [catch {execsql {COMMIT TRANSACTION}} msg]
69*4520Snw141292  lappend v $msg
70*4520Snw141292} {0 {}}
71*4520Snw141292do_test trans-2.5 {
72*4520Snw141292  set v [catch {execsql {BEGIN TRANSACTION 'foo'}} msg]
73*4520Snw141292  lappend v $msg
74*4520Snw141292} {0 {}}
75*4520Snw141292do_test trans-2.6 {
76*4520Snw141292  set v [catch {execsql {ROLLBACK TRANSACTION 'foo'}} msg]
77*4520Snw141292  lappend v $msg
78*4520Snw141292} {0 {}}
79*4520Snw141292do_test trans-2.10 {
80*4520Snw141292  execsql {
81*4520Snw141292    BEGIN;
82*4520Snw141292    SELECT a FROM one ORDER BY a;
83*4520Snw141292    SELECT a FROM two ORDER BY a;
84*4520Snw141292    END;
85*4520Snw141292  }
86*4520Snw141292} {1 2 3 1 5 10}
87*4520Snw141292integrity_check trans-2.11
88*4520Snw141292
89*4520Snw141292# Check the locking behavior
90*4520Snw141292#
91*4520Snw141292do_test trans-3.1 {
92*4520Snw141292  execsql {
93*4520Snw141292    BEGIN;
94*4520Snw141292    SELECT a FROM one ORDER BY a;
95*4520Snw141292  }
96*4520Snw141292} {1 2 3}
97*4520Snw141292do_test trans-3.2 {
98*4520Snw141292  set v [catch {execsql {
99*4520Snw141292    SELECT a FROM two ORDER BY a;
100*4520Snw141292  } altdb} msg]
101*4520Snw141292  lappend v $msg
102*4520Snw141292} {1 {database is locked}}
103*4520Snw141292do_test trans-3.3 {
104*4520Snw141292  set v [catch {execsql {
105*4520Snw141292    SELECT a FROM one ORDER BY a;
106*4520Snw141292  } altdb} msg]
107*4520Snw141292  lappend v $msg
108*4520Snw141292} {1 {database is locked}}
109*4520Snw141292do_test trans-3.4 {
110*4520Snw141292  set v [catch {execsql {
111*4520Snw141292    INSERT INTO one VALUES(4,'four');
112*4520Snw141292  }} msg]
113*4520Snw141292  lappend v $msg
114*4520Snw141292} {0 {}}
115*4520Snw141292do_test trans-3.5 {
116*4520Snw141292  set v [catch {execsql {
117*4520Snw141292    SELECT a FROM two ORDER BY a;
118*4520Snw141292  } altdb} msg]
119*4520Snw141292  lappend v $msg
120*4520Snw141292} {1 {database is locked}}
121*4520Snw141292do_test trans-3.6 {
122*4520Snw141292  set v [catch {execsql {
123*4520Snw141292    SELECT a FROM one ORDER BY a;
124*4520Snw141292  } altdb} msg]
125*4520Snw141292  lappend v $msg
126*4520Snw141292} {1 {database is locked}}
127*4520Snw141292do_test trans-3.7 {
128*4520Snw141292  set v [catch {execsql {
129*4520Snw141292    INSERT INTO two VALUES(4,'IV');
130*4520Snw141292  }} msg]
131*4520Snw141292  lappend v $msg
132*4520Snw141292} {0 {}}
133*4520Snw141292do_test trans-3.8 {
134*4520Snw141292  set v [catch {execsql {
135*4520Snw141292    SELECT a FROM two ORDER BY a;
136*4520Snw141292  } altdb} msg]
137*4520Snw141292  lappend v $msg
138*4520Snw141292} {1 {database is locked}}
139*4520Snw141292do_test trans-3.9 {
140*4520Snw141292  set v [catch {execsql {
141*4520Snw141292    SELECT a FROM one ORDER BY a;
142*4520Snw141292  } altdb} msg]
143*4520Snw141292  lappend v $msg
144*4520Snw141292} {1 {database is locked}}
145*4520Snw141292do_test trans-3.10 {
146*4520Snw141292  execsql {END TRANSACTION}
147*4520Snw141292} {}
148*4520Snw141292do_test trans-3.11 {
149*4520Snw141292  set v [catch {execsql {
150*4520Snw141292    SELECT a FROM two ORDER BY a;
151*4520Snw141292  } altdb} msg]
152*4520Snw141292  lappend v $msg
153*4520Snw141292} {0 {1 4 5 10}}
154*4520Snw141292do_test trans-3.12 {
155*4520Snw141292  set v [catch {execsql {
156*4520Snw141292    SELECT a FROM one ORDER BY a;
157*4520Snw141292  } altdb} msg]
158*4520Snw141292  lappend v $msg
159*4520Snw141292} {0 {1 2 3 4}}
160*4520Snw141292do_test trans-3.13 {
161*4520Snw141292  set v [catch {execsql {
162*4520Snw141292    SELECT a FROM two ORDER BY a;
163*4520Snw141292  } db} msg]
164*4520Snw141292  lappend v $msg
165*4520Snw141292} {0 {1 4 5 10}}
166*4520Snw141292do_test trans-3.14 {
167*4520Snw141292  set v [catch {execsql {
168*4520Snw141292    SELECT a FROM one ORDER BY a;
169*4520Snw141292  } db} msg]
170*4520Snw141292  lappend v $msg
171*4520Snw141292} {0 {1 2 3 4}}
172*4520Snw141292integrity_check trans-3.15
173*4520Snw141292
174*4520Snw141292do_test trans-4.1 {
175*4520Snw141292  set v [catch {execsql {
176*4520Snw141292    COMMIT;
177*4520Snw141292  } db} msg]
178*4520Snw141292  lappend v $msg
179*4520Snw141292} {1 {cannot commit - no transaction is active}}
180*4520Snw141292do_test trans-4.2 {
181*4520Snw141292  set v [catch {execsql {
182*4520Snw141292    ROLLBACK;
183*4520Snw141292  } db} msg]
184*4520Snw141292  lappend v $msg
185*4520Snw141292} {1 {cannot rollback - no transaction is active}}
186*4520Snw141292do_test trans-4.3 {
187*4520Snw141292  set v [catch {execsql {
188*4520Snw141292    BEGIN TRANSACTION;
189*4520Snw141292    SELECT a FROM two ORDER BY a;
190*4520Snw141292  } db} msg]
191*4520Snw141292  lappend v $msg
192*4520Snw141292} {0 {1 4 5 10}}
193*4520Snw141292do_test trans-4.4 {
194*4520Snw141292  set v [catch {execsql {
195*4520Snw141292    SELECT a FROM two ORDER BY a;
196*4520Snw141292  } altdb} msg]
197*4520Snw141292  lappend v $msg
198*4520Snw141292} {1 {database is locked}}
199*4520Snw141292do_test trans-4.5 {
200*4520Snw141292  set v [catch {execsql {
201*4520Snw141292    SELECT a FROM one ORDER BY a;
202*4520Snw141292  } altdb} msg]
203*4520Snw141292  lappend v $msg
204*4520Snw141292} {1 {database is locked}}
205*4520Snw141292do_test trans-4.6 {
206*4520Snw141292  set v [catch {execsql {
207*4520Snw141292    BEGIN TRANSACTION;
208*4520Snw141292    SELECT a FROM one ORDER BY a;
209*4520Snw141292  } db} msg]
210*4520Snw141292  lappend v $msg
211*4520Snw141292} {1 {cannot start a transaction within a transaction}}
212*4520Snw141292do_test trans-4.7 {
213*4520Snw141292  set v [catch {execsql {
214*4520Snw141292    SELECT a FROM two ORDER BY a;
215*4520Snw141292  } altdb} msg]
216*4520Snw141292  lappend v $msg
217*4520Snw141292} {1 {database is locked}}
218*4520Snw141292do_test trans-4.8 {
219*4520Snw141292  set v [catch {execsql {
220*4520Snw141292    SELECT a FROM one ORDER BY a;
221*4520Snw141292  } altdb} msg]
222*4520Snw141292  lappend v $msg
223*4520Snw141292} {1 {database is locked}}
224*4520Snw141292do_test trans-4.9 {
225*4520Snw141292  set v [catch {execsql {
226*4520Snw141292    END TRANSACTION;
227*4520Snw141292    SELECT a FROM two ORDER BY a;
228*4520Snw141292  } db} msg]
229*4520Snw141292  lappend v $msg
230*4520Snw141292} {0 {1 4 5 10}}
231*4520Snw141292do_test trans-4.10 {
232*4520Snw141292  set v [catch {execsql {
233*4520Snw141292    SELECT a FROM two ORDER BY a;
234*4520Snw141292  } altdb} msg]
235*4520Snw141292  lappend v $msg
236*4520Snw141292} {0 {1 4 5 10}}
237*4520Snw141292do_test trans-4.11 {
238*4520Snw141292  set v [catch {execsql {
239*4520Snw141292    SELECT a FROM one ORDER BY a;
240*4520Snw141292  } altdb} msg]
241*4520Snw141292  lappend v $msg
242*4520Snw141292} {0 {1 2 3 4}}
243*4520Snw141292integrity_check trans-4.12
244*4520Snw141292do_test trans-4.98 {
245*4520Snw141292  altdb close
246*4520Snw141292  execsql {
247*4520Snw141292    DROP TABLE one;
248*4520Snw141292    DROP TABLE two;
249*4520Snw141292  }
250*4520Snw141292} {}
251*4520Snw141292integrity_check trans-4.99
252*4520Snw141292
253*4520Snw141292# Check out the commit/rollback behavior of the database
254*4520Snw141292#
255*4520Snw141292do_test trans-5.1 {
256*4520Snw141292  execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
257*4520Snw141292} {}
258*4520Snw141292do_test trans-5.2 {
259*4520Snw141292  execsql {BEGIN TRANSACTION}
260*4520Snw141292  execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
261*4520Snw141292} {}
262*4520Snw141292do_test trans-5.3 {
263*4520Snw141292  execsql {CREATE TABLE one(a text, b int)}
264*4520Snw141292  execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
265*4520Snw141292} {one}
266*4520Snw141292do_test trans-5.4 {
267*4520Snw141292  execsql {SELECT a,b FROM one ORDER BY b}
268*4520Snw141292} {}
269*4520Snw141292do_test trans-5.5 {
270*4520Snw141292  execsql {INSERT INTO one(a,b) VALUES('hello', 1)}
271*4520Snw141292  execsql {SELECT a,b FROM one ORDER BY b}
272*4520Snw141292} {hello 1}
273*4520Snw141292do_test trans-5.6 {
274*4520Snw141292  execsql {ROLLBACK}
275*4520Snw141292  execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name}
276*4520Snw141292} {}
277*4520Snw141292do_test trans-5.7 {
278*4520Snw141292  set v [catch {
279*4520Snw141292    execsql {SELECT a,b FROM one ORDER BY b}
280*4520Snw141292  } msg]
281*4520Snw141292  lappend v $msg
282*4520Snw141292} {1 {no such table: one}}
283*4520Snw141292
284*4520Snw141292# Test commits and rollbacks of table CREATE TABLEs, CREATE INDEXs
285*4520Snw141292# DROP TABLEs and DROP INDEXs
286*4520Snw141292#
287*4520Snw141292do_test trans-5.8 {
288*4520Snw141292  execsql {
289*4520Snw141292    SELECT name fROM sqlite_master
290*4520Snw141292    WHERE type='table' OR type='index'
291*4520Snw141292    ORDER BY name
292*4520Snw141292  }
293*4520Snw141292} {}
294*4520Snw141292do_test trans-5.9 {
295*4520Snw141292  execsql {
296*4520Snw141292    BEGIN TRANSACTION;
297*4520Snw141292    CREATE TABLE t1(a int, b int, c int);
298*4520Snw141292    SELECT name fROM sqlite_master
299*4520Snw141292    WHERE type='table' OR type='index'
300*4520Snw141292    ORDER BY name;
301*4520Snw141292  }
302*4520Snw141292} {t1}
303*4520Snw141292do_test trans-5.10 {
304*4520Snw141292  execsql {
305*4520Snw141292    CREATE INDEX i1 ON t1(a);
306*4520Snw141292    SELECT name fROM sqlite_master
307*4520Snw141292    WHERE type='table' OR type='index'
308*4520Snw141292    ORDER BY name;
309*4520Snw141292  }
310*4520Snw141292} {i1 t1}
311*4520Snw141292do_test trans-5.11 {
312*4520Snw141292  execsql {
313*4520Snw141292    COMMIT;
314*4520Snw141292    SELECT name fROM sqlite_master
315*4520Snw141292    WHERE type='table' OR type='index'
316*4520Snw141292    ORDER BY name;
317*4520Snw141292  }
318*4520Snw141292} {i1 t1}
319*4520Snw141292do_test trans-5.12 {
320*4520Snw141292  execsql {
321*4520Snw141292    BEGIN TRANSACTION;
322*4520Snw141292    CREATE TABLE t2(a int, b int, c int);
323*4520Snw141292    CREATE INDEX i2a ON t2(a);
324*4520Snw141292    CREATE INDEX i2b ON t2(b);
325*4520Snw141292    DROP TABLE t1;
326*4520Snw141292    SELECT name fROM sqlite_master
327*4520Snw141292    WHERE type='table' OR type='index'
328*4520Snw141292    ORDER BY name;
329*4520Snw141292  }
330*4520Snw141292} {i2a i2b t2}
331*4520Snw141292do_test trans-5.13 {
332*4520Snw141292  execsql {
333*4520Snw141292    ROLLBACK;
334*4520Snw141292    SELECT name fROM sqlite_master
335*4520Snw141292    WHERE type='table' OR type='index'
336*4520Snw141292    ORDER BY name;
337*4520Snw141292  }
338*4520Snw141292} {i1 t1}
339*4520Snw141292do_test trans-5.14 {
340*4520Snw141292  execsql {
341*4520Snw141292    BEGIN TRANSACTION;
342*4520Snw141292    DROP INDEX i1;
343*4520Snw141292    SELECT name fROM sqlite_master
344*4520Snw141292    WHERE type='table' OR type='index'
345*4520Snw141292    ORDER BY name;
346*4520Snw141292  }
347*4520Snw141292} {t1}
348*4520Snw141292do_test trans-5.15 {
349*4520Snw141292  execsql {
350*4520Snw141292    ROLLBACK;
351*4520Snw141292    SELECT name fROM sqlite_master
352*4520Snw141292    WHERE type='table' OR type='index'
353*4520Snw141292    ORDER BY name;
354*4520Snw141292  }
355*4520Snw141292} {i1 t1}
356*4520Snw141292do_test trans-5.16 {
357*4520Snw141292  execsql {
358*4520Snw141292    BEGIN TRANSACTION;
359*4520Snw141292    DROP INDEX i1;
360*4520Snw141292    CREATE TABLE t2(x int, y int, z int);
361*4520Snw141292    CREATE INDEX i2x ON t2(x);
362*4520Snw141292    CREATE INDEX i2y ON t2(y);
363*4520Snw141292    INSERT INTO t2 VALUES(1,2,3);
364*4520Snw141292    SELECT name fROM sqlite_master
365*4520Snw141292    WHERE type='table' OR type='index'
366*4520Snw141292    ORDER BY name;
367*4520Snw141292  }
368*4520Snw141292} {i2x i2y t1 t2}
369*4520Snw141292do_test trans-5.17 {
370*4520Snw141292  execsql {
371*4520Snw141292    COMMIT;
372*4520Snw141292    SELECT name fROM sqlite_master
373*4520Snw141292    WHERE type='table' OR type='index'
374*4520Snw141292    ORDER BY name;
375*4520Snw141292  }
376*4520Snw141292} {i2x i2y t1 t2}
377*4520Snw141292do_test trans-5.18 {
378*4520Snw141292  execsql {
379*4520Snw141292    SELECT * FROM t2;
380*4520Snw141292  }
381*4520Snw141292} {1 2 3}
382*4520Snw141292do_test trans-5.19 {
383*4520Snw141292  execsql {
384*4520Snw141292    SELECT x FROM t2 WHERE y=2;
385*4520Snw141292  }
386*4520Snw141292} {1}
387*4520Snw141292do_test trans-5.20 {
388*4520Snw141292  execsql {
389*4520Snw141292    BEGIN TRANSACTION;
390*4520Snw141292    DROP TABLE t1;
391*4520Snw141292    DROP TABLE t2;
392*4520Snw141292    SELECT name fROM sqlite_master
393*4520Snw141292    WHERE type='table' OR type='index'
394*4520Snw141292    ORDER BY name;
395*4520Snw141292  }
396*4520Snw141292} {}
397*4520Snw141292do_test trans-5.21 {
398*4520Snw141292  set r [catch {execsql {
399*4520Snw141292    SELECT * FROM t2
400*4520Snw141292  }} msg]
401*4520Snw141292  lappend r $msg
402*4520Snw141292} {1 {no such table: t2}}
403*4520Snw141292do_test trans-5.22 {
404*4520Snw141292  execsql {
405*4520Snw141292    ROLLBACK;
406*4520Snw141292    SELECT name fROM sqlite_master
407*4520Snw141292    WHERE type='table' OR type='index'
408*4520Snw141292    ORDER BY name;
409*4520Snw141292  }
410*4520Snw141292} {i2x i2y t1 t2}
411*4520Snw141292do_test trans-5.23 {
412*4520Snw141292  execsql {
413*4520Snw141292    SELECT * FROM t2;
414*4520Snw141292  }
415*4520Snw141292} {1 2 3}
416*4520Snw141292integrity_check trans-5.23
417*4520Snw141292
418*4520Snw141292
419*4520Snw141292# Try to DROP and CREATE tables and indices with the same name
420*4520Snw141292# within a transaction.  Make sure ROLLBACK works.
421*4520Snw141292#
422*4520Snw141292do_test trans-6.1 {
423*4520Snw141292  execsql2 {
424*4520Snw141292    INSERT INTO t1 VALUES(1,2,3);
425*4520Snw141292    BEGIN TRANSACTION;
426*4520Snw141292    DROP TABLE t1;
427*4520Snw141292    CREATE TABLE t1(p,q,r);
428*4520Snw141292    ROLLBACK;
429*4520Snw141292    SELECT * FROM t1;
430*4520Snw141292  }
431*4520Snw141292} {a 1 b 2 c 3}
432*4520Snw141292do_test trans-6.2 {
433*4520Snw141292  execsql2 {
434*4520Snw141292    INSERT INTO t1 VALUES(1,2,3);
435*4520Snw141292    BEGIN TRANSACTION;
436*4520Snw141292    DROP TABLE t1;
437*4520Snw141292    CREATE TABLE t1(p,q,r);
438*4520Snw141292    COMMIT;
439*4520Snw141292    SELECT * FROM t1;
440*4520Snw141292  }
441*4520Snw141292} {}
442*4520Snw141292do_test trans-6.3 {
443*4520Snw141292  execsql2 {
444*4520Snw141292    INSERT INTO t1 VALUES(1,2,3);
445*4520Snw141292    SELECT * FROM t1;
446*4520Snw141292  }
447*4520Snw141292} {p 1 q 2 r 3}
448*4520Snw141292do_test trans-6.4 {
449*4520Snw141292  execsql2 {
450*4520Snw141292    BEGIN TRANSACTION;
451*4520Snw141292    DROP TABLE t1;
452*4520Snw141292    CREATE TABLE t1(a,b,c);
453*4520Snw141292    INSERT INTO t1 VALUES(4,5,6);
454*4520Snw141292    SELECT * FROM t1;
455*4520Snw141292    DROP TABLE t1;
456*4520Snw141292  }
457*4520Snw141292} {a 4 b 5 c 6}
458*4520Snw141292do_test trans-6.5 {
459*4520Snw141292  execsql2 {
460*4520Snw141292    ROLLBACK;
461*4520Snw141292    SELECT * FROM t1;
462*4520Snw141292  }
463*4520Snw141292} {p 1 q 2 r 3}
464*4520Snw141292do_test trans-6.6 {
465*4520Snw141292  execsql2 {
466*4520Snw141292    BEGIN TRANSACTION;
467*4520Snw141292    DROP TABLE t1;
468*4520Snw141292    CREATE TABLE t1(a,b,c);
469*4520Snw141292    INSERT INTO t1 VALUES(4,5,6);
470*4520Snw141292    SELECT * FROM t1;
471*4520Snw141292    DROP TABLE t1;
472*4520Snw141292  }
473*4520Snw141292} {a 4 b 5 c 6}
474*4520Snw141292do_test trans-6.7 {
475*4520Snw141292  catchsql {
476*4520Snw141292    COMMIT;
477*4520Snw141292    SELECT * FROM t1;
478*4520Snw141292  }
479*4520Snw141292} {1 {no such table: t1}}
480*4520Snw141292
481*4520Snw141292# Repeat on a table with an automatically generated index.
482*4520Snw141292#
483*4520Snw141292do_test trans-6.10 {
484*4520Snw141292  execsql2 {
485*4520Snw141292    CREATE TABLE t1(a unique,b,c);
486*4520Snw141292    INSERT INTO t1 VALUES(1,2,3);
487*4520Snw141292    BEGIN TRANSACTION;
488*4520Snw141292    DROP TABLE t1;
489*4520Snw141292    CREATE TABLE t1(p unique,q,r);
490*4520Snw141292    ROLLBACK;
491*4520Snw141292    SELECT * FROM t1;
492*4520Snw141292  }
493*4520Snw141292} {a 1 b 2 c 3}
494*4520Snw141292do_test trans-6.11 {
495*4520Snw141292  execsql2 {
496*4520Snw141292    BEGIN TRANSACTION;
497*4520Snw141292    DROP TABLE t1;
498*4520Snw141292    CREATE TABLE t1(p unique,q,r);
499*4520Snw141292    COMMIT;
500*4520Snw141292    SELECT * FROM t1;
501*4520Snw141292  }
502*4520Snw141292} {}
503*4520Snw141292do_test trans-6.12 {
504*4520Snw141292  execsql2 {
505*4520Snw141292    INSERT INTO t1 VALUES(1,2,3);
506*4520Snw141292    SELECT * FROM t1;
507*4520Snw141292  }
508*4520Snw141292} {p 1 q 2 r 3}
509*4520Snw141292do_test trans-6.13 {
510*4520Snw141292  execsql2 {
511*4520Snw141292    BEGIN TRANSACTION;
512*4520Snw141292    DROP TABLE t1;
513*4520Snw141292    CREATE TABLE t1(a unique,b,c);
514*4520Snw141292    INSERT INTO t1 VALUES(4,5,6);
515*4520Snw141292    SELECT * FROM t1;
516*4520Snw141292    DROP TABLE t1;
517*4520Snw141292  }
518*4520Snw141292} {a 4 b 5 c 6}
519*4520Snw141292do_test trans-6.14 {
520*4520Snw141292  execsql2 {
521*4520Snw141292    ROLLBACK;
522*4520Snw141292    SELECT * FROM t1;
523*4520Snw141292  }
524*4520Snw141292} {p 1 q 2 r 3}
525*4520Snw141292do_test trans-6.15 {
526*4520Snw141292  execsql2 {
527*4520Snw141292    BEGIN TRANSACTION;
528*4520Snw141292    DROP TABLE t1;
529*4520Snw141292    CREATE TABLE t1(a unique,b,c);
530*4520Snw141292    INSERT INTO t1 VALUES(4,5,6);
531*4520Snw141292    SELECT * FROM t1;
532*4520Snw141292    DROP TABLE t1;
533*4520Snw141292  }
534*4520Snw141292} {a 4 b 5 c 6}
535*4520Snw141292do_test trans-6.16 {
536*4520Snw141292  catchsql {
537*4520Snw141292    COMMIT;
538*4520Snw141292    SELECT * FROM t1;
539*4520Snw141292  }
540*4520Snw141292} {1 {no such table: t1}}
541*4520Snw141292
542*4520Snw141292do_test trans-6.20 {
543*4520Snw141292  execsql {
544*4520Snw141292    CREATE TABLE t1(a integer primary key,b,c);
545*4520Snw141292    INSERT INTO t1 VALUES(1,-2,-3);
546*4520Snw141292    INSERT INTO t1 VALUES(4,-5,-6);
547*4520Snw141292    SELECT * FROM t1;
548*4520Snw141292  }
549*4520Snw141292} {1 -2 -3 4 -5 -6}
550*4520Snw141292do_test trans-6.21 {
551*4520Snw141292  execsql {
552*4520Snw141292    CREATE INDEX i1 ON t1(b);
553*4520Snw141292    SELECT * FROM t1 WHERE b<1;
554*4520Snw141292  }
555*4520Snw141292} {4 -5 -6 1 -2 -3}
556*4520Snw141292do_test trans-6.22 {
557*4520Snw141292  execsql {
558*4520Snw141292    BEGIN TRANSACTION;
559*4520Snw141292    DROP INDEX i1;
560*4520Snw141292    SELECT * FROM t1 WHERE b<1;
561*4520Snw141292    ROLLBACK;
562*4520Snw141292  }
563*4520Snw141292} {1 -2 -3 4 -5 -6}
564*4520Snw141292do_test trans-6.23 {
565*4520Snw141292  execsql {
566*4520Snw141292    SELECT * FROM t1 WHERE b<1;
567*4520Snw141292  }
568*4520Snw141292} {4 -5 -6 1 -2 -3}
569*4520Snw141292do_test trans-6.24 {
570*4520Snw141292  execsql {
571*4520Snw141292    BEGIN TRANSACTION;
572*4520Snw141292    DROP TABLE t1;
573*4520Snw141292    ROLLBACK;
574*4520Snw141292    SELECT * FROM t1 WHERE b<1;
575*4520Snw141292  }
576*4520Snw141292} {4 -5 -6 1 -2 -3}
577*4520Snw141292
578*4520Snw141292do_test trans-6.25 {
579*4520Snw141292  execsql {
580*4520Snw141292    BEGIN TRANSACTION;
581*4520Snw141292    DROP INDEX i1;
582*4520Snw141292    CREATE INDEX i1 ON t1(c);
583*4520Snw141292    SELECT * FROM t1 WHERE b<1;
584*4520Snw141292  }
585*4520Snw141292} {1 -2 -3 4 -5 -6}
586*4520Snw141292do_test trans-6.26 {
587*4520Snw141292  execsql {
588*4520Snw141292    SELECT * FROM t1 WHERE c<1;
589*4520Snw141292  }
590*4520Snw141292} {4 -5 -6 1 -2 -3}
591*4520Snw141292do_test trans-6.27 {
592*4520Snw141292  execsql {
593*4520Snw141292    ROLLBACK;
594*4520Snw141292    SELECT * FROM t1 WHERE b<1;
595*4520Snw141292  }
596*4520Snw141292} {4 -5 -6 1 -2 -3}
597*4520Snw141292do_test trans-6.28 {
598*4520Snw141292  execsql {
599*4520Snw141292    SELECT * FROM t1 WHERE c<1;
600*4520Snw141292  }
601*4520Snw141292} {1 -2 -3 4 -5 -6}
602*4520Snw141292
603*4520Snw141292# The following repeats steps 6.20 through 6.28, but puts a "unique"
604*4520Snw141292# constraint the first field of the table in order to generate an
605*4520Snw141292# automatic index.
606*4520Snw141292#
607*4520Snw141292do_test trans-6.30 {
608*4520Snw141292  execsql {
609*4520Snw141292    BEGIN TRANSACTION;
610*4520Snw141292    DROP TABLE t1;
611*4520Snw141292    CREATE TABLE t1(a int unique,b,c);
612*4520Snw141292    COMMIT;
613*4520Snw141292    INSERT INTO t1 VALUES(1,-2,-3);
614*4520Snw141292    INSERT INTO t1 VALUES(4,-5,-6);
615*4520Snw141292    SELECT * FROM t1 ORDER BY a;
616*4520Snw141292  }
617*4520Snw141292} {1 -2 -3 4 -5 -6}
618*4520Snw141292do_test trans-6.31 {
619*4520Snw141292  execsql {
620*4520Snw141292    CREATE INDEX i1 ON t1(b);
621*4520Snw141292    SELECT * FROM t1 WHERE b<1;
622*4520Snw141292  }
623*4520Snw141292} {4 -5 -6 1 -2 -3}
624*4520Snw141292do_test trans-6.32 {
625*4520Snw141292  execsql {
626*4520Snw141292    BEGIN TRANSACTION;
627*4520Snw141292    DROP INDEX i1;
628*4520Snw141292    SELECT * FROM t1 WHERE b<1;
629*4520Snw141292    ROLLBACK;
630*4520Snw141292  }
631*4520Snw141292} {1 -2 -3 4 -5 -6}
632*4520Snw141292do_test trans-6.33 {
633*4520Snw141292  execsql {
634*4520Snw141292    SELECT * FROM t1 WHERE b<1;
635*4520Snw141292  }
636*4520Snw141292} {4 -5 -6 1 -2 -3}
637*4520Snw141292do_test trans-6.34 {
638*4520Snw141292  execsql {
639*4520Snw141292    BEGIN TRANSACTION;
640*4520Snw141292    DROP TABLE t1;
641*4520Snw141292    ROLLBACK;
642*4520Snw141292    SELECT * FROM t1 WHERE b<1;
643*4520Snw141292  }
644*4520Snw141292} {4 -5 -6 1 -2 -3}
645*4520Snw141292
646*4520Snw141292do_test trans-6.35 {
647*4520Snw141292  execsql {
648*4520Snw141292    BEGIN TRANSACTION;
649*4520Snw141292    DROP INDEX i1;
650*4520Snw141292    CREATE INDEX i1 ON t1(c);
651*4520Snw141292    SELECT * FROM t1 WHERE b<1;
652*4520Snw141292  }
653*4520Snw141292} {1 -2 -3 4 -5 -6}
654*4520Snw141292do_test trans-6.36 {
655*4520Snw141292  execsql {
656*4520Snw141292    SELECT * FROM t1 WHERE c<1;
657*4520Snw141292  }
658*4520Snw141292} {4 -5 -6 1 -2 -3}
659*4520Snw141292do_test trans-6.37 {
660*4520Snw141292  execsql {
661*4520Snw141292    DROP INDEX i1;
662*4520Snw141292    SELECT * FROM t1 WHERE c<1;
663*4520Snw141292  }
664*4520Snw141292} {1 -2 -3 4 -5 -6}
665*4520Snw141292do_test trans-6.38 {
666*4520Snw141292  execsql {
667*4520Snw141292    ROLLBACK;
668*4520Snw141292    SELECT * FROM t1 WHERE b<1;
669*4520Snw141292  }
670*4520Snw141292} {4 -5 -6 1 -2 -3}
671*4520Snw141292do_test trans-6.39 {
672*4520Snw141292  execsql {
673*4520Snw141292    SELECT * FROM t1 WHERE c<1;
674*4520Snw141292  }
675*4520Snw141292} {1 -2 -3 4 -5 -6}
676*4520Snw141292integrity_check trans-6.40
677*4520Snw141292
678*4520Snw141292# Test to make sure rollback restores the database back to its original
679*4520Snw141292# state.
680*4520Snw141292#
681*4520Snw141292do_test trans-7.1 {
682*4520Snw141292  execsql {BEGIN}
683*4520Snw141292  for {set i 0} {$i<1000} {incr i} {
684*4520Snw141292    set r1 [expr {rand()}]
685*4520Snw141292    set r2 [expr {rand()}]
686*4520Snw141292    set r3 [expr {rand()}]
687*4520Snw141292    execsql "INSERT INTO t2 VALUES($r1,$r2,$r3)"
688*4520Snw141292  }
689*4520Snw141292  execsql {COMMIT}
690*4520Snw141292  set ::checksum [execsql {SELECT md5sum(x,y,z) FROM t2}]
691*4520Snw141292  set ::checksum2 [
692*4520Snw141292    execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
693*4520Snw141292  ]
694*4520Snw141292  execsql {SELECT count(*) FROM t2}
695*4520Snw141292} {1001}
696*4520Snw141292do_test trans-7.2 {
697*4520Snw141292  execsql {SELECT md5sum(x,y,z) FROM t2}
698*4520Snw141292} $checksum
699*4520Snw141292do_test trans-7.2.1 {
700*4520Snw141292  execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
701*4520Snw141292} $checksum2
702*4520Snw141292do_test trans-7.3 {
703*4520Snw141292  execsql {
704*4520Snw141292    BEGIN;
705*4520Snw141292    DELETE FROM t2;
706*4520Snw141292    ROLLBACK;
707*4520Snw141292    SELECT md5sum(x,y,z) FROM t2;
708*4520Snw141292  }
709*4520Snw141292} $checksum
710*4520Snw141292do_test trans-7.4 {
711*4520Snw141292  execsql {
712*4520Snw141292    BEGIN;
713*4520Snw141292    INSERT INTO t2 SELECT * FROM t2;
714*4520Snw141292    ROLLBACK;
715*4520Snw141292    SELECT md5sum(x,y,z) FROM t2;
716*4520Snw141292  }
717*4520Snw141292} $checksum
718*4520Snw141292do_test trans-7.5 {
719*4520Snw141292  execsql {
720*4520Snw141292    BEGIN;
721*4520Snw141292    DELETE FROM t2;
722*4520Snw141292    ROLLBACK;
723*4520Snw141292    SELECT md5sum(x,y,z) FROM t2;
724*4520Snw141292  }
725*4520Snw141292} $checksum
726*4520Snw141292do_test trans-7.6 {
727*4520Snw141292  execsql {
728*4520Snw141292    BEGIN;
729*4520Snw141292    INSERT INTO t2 SELECT * FROM t2;
730*4520Snw141292    ROLLBACK;
731*4520Snw141292    SELECT md5sum(x,y,z) FROM t2;
732*4520Snw141292  }
733*4520Snw141292} $checksum
734*4520Snw141292do_test trans-7.7 {
735*4520Snw141292  execsql {
736*4520Snw141292    BEGIN;
737*4520Snw141292    CREATE TABLE t3 AS SELECT * FROM t2;
738*4520Snw141292    INSERT INTO t2 SELECT * FROM t3;
739*4520Snw141292    ROLLBACK;
740*4520Snw141292    SELECT md5sum(x,y,z) FROM t2;
741*4520Snw141292  }
742*4520Snw141292} $checksum
743*4520Snw141292do_test trans-7.8 {
744*4520Snw141292  execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
745*4520Snw141292} $checksum2
746*4520Snw141292do_test trans-7.9 {
747*4520Snw141292  execsql {
748*4520Snw141292    BEGIN;
749*4520Snw141292    CREATE TEMP TABLE t3 AS SELECT * FROM t2;
750*4520Snw141292    INSERT INTO t2 SELECT * FROM t3;
751*4520Snw141292    ROLLBACK;
752*4520Snw141292    SELECT md5sum(x,y,z) FROM t2;
753*4520Snw141292  }
754*4520Snw141292} $checksum
755*4520Snw141292do_test trans-7.10 {
756*4520Snw141292  execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
757*4520Snw141292} $checksum2
758*4520Snw141292do_test trans-7.11 {
759*4520Snw141292  execsql {
760*4520Snw141292    BEGIN;
761*4520Snw141292    CREATE TEMP TABLE t3 AS SELECT * FROM t2;
762*4520Snw141292    INSERT INTO t2 SELECT * FROM t3;
763*4520Snw141292    DROP INDEX i2x;
764*4520Snw141292    DROP INDEX i2y;
765*4520Snw141292    CREATE INDEX i3a ON t3(x);
766*4520Snw141292    ROLLBACK;
767*4520Snw141292    SELECT md5sum(x,y,z) FROM t2;
768*4520Snw141292  }
769*4520Snw141292} $checksum
770*4520Snw141292do_test trans-7.12 {
771*4520Snw141292  execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
772*4520Snw141292} $checksum2
773*4520Snw141292do_test trans-7.13 {
774*4520Snw141292  execsql {
775*4520Snw141292    BEGIN;
776*4520Snw141292    DROP TABLE t2;
777*4520Snw141292    ROLLBACK;
778*4520Snw141292    SELECT md5sum(x,y,z) FROM t2;
779*4520Snw141292  }
780*4520Snw141292} $checksum
781*4520Snw141292do_test trans-7.14 {
782*4520Snw141292  execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
783*4520Snw141292} $checksum2
784*4520Snw141292integrity_check trans-7.15
785*4520Snw141292
786*4520Snw141292# Arrange for another process to begin modifying the database but abort
787*4520Snw141292# and die in the middle of the modification.  Then have this process read
788*4520Snw141292# the database.  This process should detect the journal file and roll it
789*4520Snw141292# back.  Verify that this happens correctly.
790*4520Snw141292#
791*4520Snw141292set fd [open test.tcl w]
792*4520Snw141292puts $fd {
793*4520Snw141292  sqlite db test.db
794*4520Snw141292  db eval {
795*4520Snw141292    PRAGMA default_cache_size=20;
796*4520Snw141292    BEGIN;
797*4520Snw141292    CREATE TABLE t3 AS SELECT * FROM t2;
798*4520Snw141292    DELETE FROM t2;
799*4520Snw141292  }
800*4520Snw141292  sqlite_abort
801*4520Snw141292}
802*4520Snw141292close $fd
803*4520Snw141292do_test trans-8.1 {
804*4520Snw141292  catch {exec [info nameofexec] test.tcl}
805*4520Snw141292  execsql {SELECT md5sum(x,y,z) FROM t2}
806*4520Snw141292} $checksum
807*4520Snw141292do_test trans-8.2 {
808*4520Snw141292  execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master}
809*4520Snw141292} $checksum2
810*4520Snw141292integrity_check trans-8.3
811*4520Snw141292
812*4520Snw141292# In the following sequence of tests, compute the MD5 sum of the content
813*4520Snw141292# of a table, make lots of modifications to that table, then do a rollback.
814*4520Snw141292# Verify that after the rollback, the MD5 checksum is unchanged.
815*4520Snw141292#
816*4520Snw141292do_test trans-9.1 {
817*4520Snw141292  execsql {
818*4520Snw141292    PRAGMA default_cache_size=10;
819*4520Snw141292  }
820*4520Snw141292  db close
821*4520Snw141292  sqlite db test.db
822*4520Snw141292  execsql {
823*4520Snw141292    BEGIN;
824*4520Snw141292    CREATE TABLE t3(x TEXT);
825*4520Snw141292    INSERT INTO t3 VALUES(randstr(10,400));
826*4520Snw141292    INSERT INTO t3 VALUES(randstr(10,400));
827*4520Snw141292    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
828*4520Snw141292    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
829*4520Snw141292    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
830*4520Snw141292    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
831*4520Snw141292    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
832*4520Snw141292    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
833*4520Snw141292    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
834*4520Snw141292    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
835*4520Snw141292    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
836*4520Snw141292    COMMIT;
837*4520Snw141292    SELECT count(*) FROM t3;
838*4520Snw141292  }
839*4520Snw141292} {1024}
840*4520Snw141292
841*4520Snw141292# The following procedure computes a "signature" for table "t3".  If
842*4520Snw141292# T3 changes in any way, the signature should change.
843*4520Snw141292#
844*4520Snw141292# This is used to test ROLLBACK.  We gather a signature for t3, then
845*4520Snw141292# make lots of changes to t3, then rollback and take another signature.
846*4520Snw141292# The two signatures should be the same.
847*4520Snw141292#
848*4520Snw141292proc signature {} {
849*4520Snw141292  return [db eval {SELECT count(*), md5sum(x) FROM t3}]
850*4520Snw141292}
851*4520Snw141292
852*4520Snw141292# Repeat the following group of tests 20 times for quick testing and
853*4520Snw141292# 40 times for full testing.  Each iteration of the test makes table
854*4520Snw141292# t3 a little larger, and thus takes a little longer, so doing 40 tests
855*4520Snw141292# is more than 2.0 times slower than doing 20 tests.  Considerably more.
856*4520Snw141292#
857*4520Snw141292if {[info exists ISQUICK]} {
858*4520Snw141292  set limit 20
859*4520Snw141292} else {
860*4520Snw141292  set limit 40
861*4520Snw141292}
862*4520Snw141292
863*4520Snw141292# Do rollbacks.  Make sure the signature does not change.
864*4520Snw141292#
865*4520Snw141292for {set i 2} {$i<=$limit} {incr i} {
866*4520Snw141292  set ::sig [signature]
867*4520Snw141292  set cnt [lindex $::sig 0]
868*4520Snw141292  set ::journal_format [expr {($i%3)+1}]
869*4520Snw141292  if {$i%2==0} {
870*4520Snw141292    execsql {PRAGMA synchronous=FULL}
871*4520Snw141292  } else {
872*4520Snw141292    execsql {PRAGMA synchronous=NORMAL}
873*4520Snw141292  }
874*4520Snw141292  do_test trans-9.$i.1-$cnt {
875*4520Snw141292     execsql {
876*4520Snw141292       BEGIN;
877*4520Snw141292       DELETE FROM t3 WHERE random()%10!=0;
878*4520Snw141292       INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
879*4520Snw141292       INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
880*4520Snw141292       ROLLBACK;
881*4520Snw141292     }
882*4520Snw141292     signature
883*4520Snw141292  } $sig
884*4520Snw141292  do_test trans-9.$i.2-$cnt {
885*4520Snw141292     execsql {
886*4520Snw141292       BEGIN;
887*4520Snw141292       DELETE FROM t3 WHERE random()%10!=0;
888*4520Snw141292       INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
889*4520Snw141292       DELETE FROM t3 WHERE random()%10!=0;
890*4520Snw141292       INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
891*4520Snw141292       ROLLBACK;
892*4520Snw141292     }
893*4520Snw141292     signature
894*4520Snw141292  } $sig
895*4520Snw141292  if {$i<$limit} {
896*4520Snw141292    do_test trans-9.$i.9-$cnt {
897*4520Snw141292       execsql {
898*4520Snw141292         INSERT INTO t3 SELECT randstr(10,400) FROM t3 WHERE random()%10==0;
899*4520Snw141292       }
900*4520Snw141292    } {}
901*4520Snw141292  }
902*4520Snw141292  set ::pager_old_format 0
903*4520Snw141292}
904*4520Snw141292
905*4520Snw141292finish_test
906