xref: /onnv-gate/usr/src/lib/libsqlite/test/memdb.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 in-memory database backend.
16*4520Snw141292#
17*4520Snw141292# $Id: memdb.test,v 1.6 2003/08/05 13:13:39 drh Exp $
18*4520Snw141292
19*4520Snw141292
20*4520Snw141292set testdir [file dirname $argv0]
21*4520Snw141292source $testdir/tester.tcl
22*4520Snw141292
23*4520Snw141292# In the following sequence of tests, compute the MD5 sum of the content
24*4520Snw141292# of a table, make lots of modifications to that table, then do a rollback.
25*4520Snw141292# Verify that after the rollback, the MD5 checksum is unchanged.
26*4520Snw141292#
27*4520Snw141292# These tests were browed from trans.tcl.
28*4520Snw141292#
29*4520Snw141292do_test memdb-1.1 {
30*4520Snw141292  db close
31*4520Snw141292  sqlite db :memory:
32*4520Snw141292  # sqlite db test.db
33*4520Snw141292  execsql {
34*4520Snw141292    BEGIN;
35*4520Snw141292    CREATE TABLE t3(x TEXT);
36*4520Snw141292    INSERT INTO t3 VALUES(randstr(10,400));
37*4520Snw141292    INSERT INTO t3 VALUES(randstr(10,400));
38*4520Snw141292    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
39*4520Snw141292    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
40*4520Snw141292    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
41*4520Snw141292    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
42*4520Snw141292    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
43*4520Snw141292    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
44*4520Snw141292    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
45*4520Snw141292    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
46*4520Snw141292    INSERT INTO t3 SELECT randstr(10,400) FROM t3;
47*4520Snw141292    COMMIT;
48*4520Snw141292    SELECT count(*) FROM t3;
49*4520Snw141292  }
50*4520Snw141292} {1024}
51*4520Snw141292
52*4520Snw141292# The following procedure computes a "signature" for table "t3".  If
53*4520Snw141292# T3 changes in any way, the signature should change.
54*4520Snw141292#
55*4520Snw141292# This is used to test ROLLBACK.  We gather a signature for t3, then
56*4520Snw141292# make lots of changes to t3, then rollback and take another signature.
57*4520Snw141292# The two signatures should be the same.
58*4520Snw141292#
59*4520Snw141292proc signature {{fn {}}} {
60*4520Snw141292  set rx [db eval {SELECT x FROM t3}]
61*4520Snw141292  # set r1 [md5 $rx\n]
62*4520Snw141292  if {$fn!=""} {
63*4520Snw141292    # set fd [open $fn w]
64*4520Snw141292    # puts $fd $rx
65*4520Snw141292    # close $fd
66*4520Snw141292  }
67*4520Snw141292  # set r [db eval {SELECT count(*), md5sum(x) FROM t3}]
68*4520Snw141292  # puts "SIG($fn)=$r1"
69*4520Snw141292  return [list [string length $rx] $rx]
70*4520Snw141292}
71*4520Snw141292
72*4520Snw141292# Do rollbacks.  Make sure the signature does not change.
73*4520Snw141292#
74*4520Snw141292set limit 10
75*4520Snw141292for {set i 2} {$i<=$limit} {incr i} {
76*4520Snw141292  set ::sig [signature one]
77*4520Snw141292  # puts "sig=$sig"
78*4520Snw141292  set cnt [lindex $::sig 0]
79*4520Snw141292  set ::journal_format [expr {($i%3)+1}]
80*4520Snw141292  if {$i%2==0} {
81*4520Snw141292    execsql {PRAGMA synchronous=FULL}
82*4520Snw141292  } else {
83*4520Snw141292    execsql {PRAGMA synchronous=NORMAL}
84*4520Snw141292  }
85*4520Snw141292  do_test memdb-1.$i.1-$cnt {
86*4520Snw141292     execsql {
87*4520Snw141292       BEGIN;
88*4520Snw141292       DELETE FROM t3 WHERE random()%10!=0;
89*4520Snw141292       INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
90*4520Snw141292       INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
91*4520Snw141292       ROLLBACK;
92*4520Snw141292     }
93*4520Snw141292     set sig2 [signature two]
94*4520Snw141292  } $sig
95*4520Snw141292  # puts "sig2=$sig2"
96*4520Snw141292  # if {$sig2!=$sig} exit
97*4520Snw141292  do_test memdb-1.$i.2-$cnt {
98*4520Snw141292     execsql {
99*4520Snw141292       BEGIN;
100*4520Snw141292       DELETE FROM t3 WHERE random()%10!=0;
101*4520Snw141292       INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
102*4520Snw141292       DELETE FROM t3 WHERE random()%10!=0;
103*4520Snw141292       INSERT INTO t3 SELECT randstr(10,10)||x FROM t3;
104*4520Snw141292       ROLLBACK;
105*4520Snw141292     }
106*4520Snw141292     signature
107*4520Snw141292  } $sig
108*4520Snw141292  if {$i<$limit} {
109*4520Snw141292    do_test memdb-1.$i.9-$cnt {
110*4520Snw141292       execsql {
111*4520Snw141292         INSERT INTO t3 SELECT randstr(10,400) FROM t3 WHERE random()%10==0;
112*4520Snw141292       }
113*4520Snw141292    } {}
114*4520Snw141292  }
115*4520Snw141292  set ::pager_old_format 0
116*4520Snw141292}
117*4520Snw141292
118*4520Snw141292do_test memdb-2.1 {
119*4520Snw141292  execsql {
120*4520Snw141292    PRAGMA integrity_check
121*4520Snw141292  }
122*4520Snw141292} {ok}
123*4520Snw141292
124*4520Snw141292do_test memdb-3.1 {
125*4520Snw141292  execsql {
126*4520Snw141292    CREATE TABLE t4(a,b,c,d);
127*4520Snw141292    BEGIN;
128*4520Snw141292    INSERT INTO t4 VALUES(1,2,3,4);
129*4520Snw141292    SELECT * FROM t4;
130*4520Snw141292  }
131*4520Snw141292} {1 2 3 4}
132*4520Snw141292do_test memdb-3.2 {
133*4520Snw141292  execsql {
134*4520Snw141292    SELECT name FROM sqlite_master WHERE type='table';
135*4520Snw141292  }
136*4520Snw141292} {t3 t4}
137*4520Snw141292do_test memdb-3.3 {
138*4520Snw141292  execsql {
139*4520Snw141292    DROP TABLE t4;
140*4520Snw141292    SELECT name FROM sqlite_master WHERE type='table';
141*4520Snw141292  }
142*4520Snw141292} {t3}
143*4520Snw141292do_test memdb-3.4 {
144*4520Snw141292  execsql {
145*4520Snw141292    ROLLBACK;
146*4520Snw141292    SELECT name FROM sqlite_master WHERE type='table';
147*4520Snw141292  }
148*4520Snw141292} {t3 t4}
149*4520Snw141292
150*4520Snw141292# Create tables for the first group of tests.
151*4520Snw141292#
152*4520Snw141292do_test memdb-4.0 {
153*4520Snw141292  execsql {
154*4520Snw141292    CREATE TABLE t1(a, b, c, UNIQUE(a,b));
155*4520Snw141292    CREATE TABLE t2(x);
156*4520Snw141292    SELECT c FROM t1 ORDER BY c;
157*4520Snw141292  }
158*4520Snw141292} {}
159*4520Snw141292
160*4520Snw141292# Six columns of configuration data as follows:
161*4520Snw141292#
162*4520Snw141292#   i      The reference number of the test
163*4520Snw141292#   conf   The conflict resolution algorithm on the BEGIN statement
164*4520Snw141292#   cmd    An INSERT or REPLACE command to execute against table t1
165*4520Snw141292#   t0     True if there is an error from $cmd
166*4520Snw141292#   t1     Content of "c" column of t1 assuming no error in $cmd
167*4520Snw141292#   t2     Content of "x" column of t2
168*4520Snw141292#
169*4520Snw141292foreach {i conf cmd t0 t1 t2} {
170*4520Snw141292  1 {}       INSERT                  1 {}  1
171*4520Snw141292  2 {}       {INSERT OR IGNORE}      0 3   1
172*4520Snw141292  3 {}       {INSERT OR REPLACE}     0 4   1
173*4520Snw141292  4 {}       REPLACE                 0 4   1
174*4520Snw141292  5 {}       {INSERT OR FAIL}        1 {}  1
175*4520Snw141292  6 {}       {INSERT OR ABORT}       1 {}  1
176*4520Snw141292  7 {}       {INSERT OR ROLLBACK}    1 {}  {}
177*4520Snw141292  8 IGNORE   INSERT                  0 3   1
178*4520Snw141292  9 IGNORE   {INSERT OR IGNORE}      0 3   1
179*4520Snw141292 10 IGNORE   {INSERT OR REPLACE}     0 4   1
180*4520Snw141292 11 IGNORE   REPLACE                 0 4   1
181*4520Snw141292 12 IGNORE   {INSERT OR FAIL}        1 {}  1
182*4520Snw141292 13 IGNORE   {INSERT OR ABORT}       1 {}  1
183*4520Snw141292 14 IGNORE   {INSERT OR ROLLBACK}    1 {}  {}
184*4520Snw141292 15 REPLACE  INSERT                  0 4   1
185*4520Snw141292 16 FAIL     INSERT                  1 {}  1
186*4520Snw141292 17 ABORT    INSERT                  1 {}  1
187*4520Snw141292 18 ROLLBACK INSERT                  1 {}  {}
188*4520Snw141292} {
189*4520Snw141292  do_test memdb-4.$i {
190*4520Snw141292    if {$conf!=""} {set conf "ON CONFLICT $conf"}
191*4520Snw141292    set r0 [catch {execsql [subst {
192*4520Snw141292      DELETE FROM t1;
193*4520Snw141292      DELETE FROM t2;
194*4520Snw141292      INSERT INTO t1 VALUES(1,2,3);
195*4520Snw141292      BEGIN $conf;
196*4520Snw141292      INSERT INTO t2 VALUES(1);
197*4520Snw141292      $cmd INTO t1 VALUES(1,2,4);
198*4520Snw141292    }]} r1]
199*4520Snw141292    catch {execsql {COMMIT}}
200*4520Snw141292    if {$r0} {set r1 {}} {set r1 [execsql {SELECT c FROM t1}]}
201*4520Snw141292    set r2 [execsql {SELECT x FROM t2}]
202*4520Snw141292    list $r0 $r1 $r2
203*4520Snw141292  } [list $t0 $t1 $t2]
204*4520Snw141292}
205*4520Snw141292
206*4520Snw141292do_test memdb-5.0 {
207*4520Snw141292  execsql {
208*4520Snw141292    DROP TABLE t2;
209*4520Snw141292    DROP TABLE t3;
210*4520Snw141292    CREATE TABLE t2(a,b,c);
211*4520Snw141292    INSERT INTO t2 VALUES(1,2,1);
212*4520Snw141292    INSERT INTO t2 VALUES(2,3,2);
213*4520Snw141292    INSERT INTO t2 VALUES(3,4,1);
214*4520Snw141292    INSERT INTO t2 VALUES(4,5,4);
215*4520Snw141292    SELECT c FROM t2 ORDER BY b;
216*4520Snw141292    CREATE TABLE t3(x);
217*4520Snw141292    INSERT INTO t3 VALUES(1);
218*4520Snw141292  }
219*4520Snw141292} {1 2 1 4}
220*4520Snw141292
221*4520Snw141292# Six columns of configuration data as follows:
222*4520Snw141292#
223*4520Snw141292#   i      The reference number of the test
224*4520Snw141292#   conf1  The conflict resolution algorithm on the UNIQUE constraint
225*4520Snw141292#   conf2  The conflict resolution algorithm on the BEGIN statement
226*4520Snw141292#   cmd    An UPDATE command to execute against table t1
227*4520Snw141292#   t0     True if there is an error from $cmd
228*4520Snw141292#   t1     Content of "b" column of t1 assuming no error in $cmd
229*4520Snw141292#   t2     Content of "x" column of t3
230*4520Snw141292#
231*4520Snw141292foreach {i conf1 conf2 cmd t0 t1 t2} {
232*4520Snw141292  1 {}       {}       UPDATE                  1 {6 7 8 9}  1
233*4520Snw141292  2 REPLACE  {}       UPDATE                  0 {7 6 9}    1
234*4520Snw141292  3 IGNORE   {}       UPDATE                  0 {6 7 3 9}  1
235*4520Snw141292  4 FAIL     {}       UPDATE                  1 {6 7 3 4}  1
236*4520Snw141292  5 ABORT    {}       UPDATE                  1 {1 2 3 4}  1
237*4520Snw141292  6 ROLLBACK {}       UPDATE                  1 {1 2 3 4}  0
238*4520Snw141292  7 REPLACE  {}       {UPDATE OR IGNORE}      0 {6 7 3 9}  1
239*4520Snw141292  8 IGNORE   {}       {UPDATE OR REPLACE}     0 {7 6 9}    1
240*4520Snw141292  9 FAIL     {}       {UPDATE OR IGNORE}      0 {6 7 3 9}  1
241*4520Snw141292 10 ABORT    {}       {UPDATE OR REPLACE}     0 {7 6 9}    1
242*4520Snw141292 11 ROLLBACK {}       {UPDATE OR IGNORE}      0 {6 7 3 9}   1
243*4520Snw141292 12 {}       {}       {UPDATE OR IGNORE}      0 {6 7 3 9}  1
244*4520Snw141292 13 {}       {}       {UPDATE OR REPLACE}     0 {7 6 9}    1
245*4520Snw141292 14 {}       {}       {UPDATE OR FAIL}        1 {6 7 3 4}  1
246*4520Snw141292 15 {}       {}       {UPDATE OR ABORT}       1 {1 2 3 4}  1
247*4520Snw141292 16 {}       {}       {UPDATE OR ROLLBACK}    1 {1 2 3 4}  0
248*4520Snw141292 17 {}       IGNORE   UPDATE                  0 {6 7 3 9}  1
249*4520Snw141292 18 {}       REPLACE  UPDATE                  0 {7 6 9}    1
250*4520Snw141292 19 {}       FAIL     UPDATE                  1 {6 7 3 4}  1
251*4520Snw141292 20 {}       ABORT    UPDATE                  1 {1 2 3 4}  1
252*4520Snw141292 21 {}       ROLLBACK UPDATE                  1 {1 2 3 4}  0
253*4520Snw141292 22 REPLACE  IGNORE   UPDATE                  0 {6 7 3 9}  1
254*4520Snw141292 23 IGNORE   REPLACE  UPDATE                  0 {7 6 9}    1
255*4520Snw141292 24 REPLACE  FAIL     UPDATE                  1 {6 7 3 4}  1
256*4520Snw141292 25 IGNORE   ABORT    UPDATE                  1 {1 2 3 4}  1
257*4520Snw141292 26 REPLACE  ROLLBACK UPDATE                  1 {1 2 3 4}  0
258*4520Snw141292} {
259*4520Snw141292  if {$t0} {set t1 {column a is not unique}}
260*4520Snw141292  do_test memdb-5.$i {
261*4520Snw141292    if {$conf1!=""} {set conf1 "ON CONFLICT $conf1"}
262*4520Snw141292    if {$conf2!=""} {set conf2 "ON CONFLICT $conf2"}
263*4520Snw141292    set r0 [catch {execsql [subst {
264*4520Snw141292      DROP TABLE t1;
265*4520Snw141292      CREATE TABLE t1(a,b,c, UNIQUE(a) $conf1);
266*4520Snw141292      INSERT INTO t1 SELECT * FROM t2;
267*4520Snw141292      UPDATE t3 SET x=0;
268*4520Snw141292      BEGIN $conf2;
269*4520Snw141292      $cmd t3 SET x=1;
270*4520Snw141292      $cmd t1 SET b=b*2;
271*4520Snw141292      $cmd t1 SET a=c+5;
272*4520Snw141292    }]} r1]
273*4520Snw141292    catch {execsql {COMMIT}}
274*4520Snw141292    if {!$r0} {set r1 [execsql {SELECT a FROM t1 ORDER BY b}]}
275*4520Snw141292    set r2 [execsql {SELECT x FROM t3}]
276*4520Snw141292    list $r0 $r1 $r2
277*4520Snw141292  } [list $t0 $t1 $t2]
278*4520Snw141292}
279*4520Snw141292
280*4520Snw141292do_test memdb-6.1 {
281*4520Snw141292  execsql {
282*4520Snw141292    SELECT * FROM t2;
283*4520Snw141292  }
284*4520Snw141292} {1 2 1 2 3 2 3 4 1 4 5 4}
285*4520Snw141292do_test memdb-6.2 {
286*4520Snw141292  execsql {
287*4520Snw141292    BEGIN;
288*4520Snw141292    DROP TABLE t2;
289*4520Snw141292    SELECT name FROM sqlite_master WHERE type='table' ORDER BY 1;
290*4520Snw141292  }
291*4520Snw141292} {t1 t3 t4}
292*4520Snw141292do_test memdb-6.3 {
293*4520Snw141292  execsql {
294*4520Snw141292    ROLLBACK;
295*4520Snw141292    SELECT name FROM sqlite_master WHERE type='table' ORDER BY 1;
296*4520Snw141292  }
297*4520Snw141292} {t1 t2 t3 t4}
298*4520Snw141292do_test memdb-6.4 {
299*4520Snw141292  execsql {
300*4520Snw141292    SELECT * FROM t2;
301*4520Snw141292  }
302*4520Snw141292} {1 2 1 2 3 2 3 4 1 4 5 4}
303*4520Snw141292do_test memdb-6.5 {
304*4520Snw141292  execsql {
305*4520Snw141292    SELECT a FROM t2 UNION SELECT b FROM t2 ORDER BY 1;
306*4520Snw141292  }
307*4520Snw141292} {1 2 3 4 5}
308*4520Snw141292do_test memdb-6.6 {
309*4520Snw141292  execsql {
310*4520Snw141292    CREATE INDEX i2 ON t2(c);
311*4520Snw141292    SELECT a FROM t2 ORDER BY c;
312*4520Snw141292  }
313*4520Snw141292} {1 3 2 4}
314*4520Snw141292do_test memdb-6.6 {
315*4520Snw141292  execsql {
316*4520Snw141292    SELECT a FROM t2 ORDER BY c DESC;
317*4520Snw141292  }
318*4520Snw141292} {4 2 3 1}
319*4520Snw141292do_test memdb-6.7 {
320*4520Snw141292  execsql {
321*4520Snw141292    BEGIN;
322*4520Snw141292    CREATE TABLE t5(x,y);
323*4520Snw141292    INSERT INTO t5 VALUES(1,2);
324*4520Snw141292    SELECT * FROM t5;
325*4520Snw141292  }
326*4520Snw141292} {1 2}
327*4520Snw141292do_test memdb-6.8 {
328*4520Snw141292  execsql {
329*4520Snw141292    SELECT name FROM sqlite_master WHERE type='table' ORDER BY 1;
330*4520Snw141292  }
331*4520Snw141292} {t1 t2 t3 t4 t5}
332*4520Snw141292do_test memdb-6.9 {
333*4520Snw141292  execsql {
334*4520Snw141292    ROLLBACK;
335*4520Snw141292    SELECT name FROM sqlite_master WHERE type='table' ORDER BY 1;
336*4520Snw141292  }
337*4520Snw141292} {t1 t2 t3 t4}
338*4520Snw141292do_test memdb-6.10 {
339*4520Snw141292  execsql {
340*4520Snw141292    CREATE TABLE t5(x PRIMARY KEY, y UNIQUE);
341*4520Snw141292    SELECT * FROM t5;
342*4520Snw141292  }
343*4520Snw141292} {}
344*4520Snw141292do_test memdb-6.11 {
345*4520Snw141292  execsql {
346*4520Snw141292    SELECT * FROM t5 ORDER BY y DESC;
347*4520Snw141292  }
348*4520Snw141292} {}
349*4520Snw141292do_test memdb-6.12 {
350*4520Snw141292  execsql {
351*4520Snw141292    INSERT INTO t5 VALUES(1,2);
352*4520Snw141292    INSERT INTO t5 VALUES(3,4);
353*4520Snw141292    REPLACE INTO t5 VALUES(1,4);
354*4520Snw141292    SELECT rowid,* FROM t5;
355*4520Snw141292  }
356*4520Snw141292} {3 1 4}
357*4520Snw141292do_test memdb-6.13 {
358*4520Snw141292  execsql {
359*4520Snw141292    DELETE FROM t5 WHERE x>5;
360*4520Snw141292    SELECT * FROM t5;
361*4520Snw141292  }
362*4520Snw141292} {1 4}
363*4520Snw141292do_test memdb-6.14 {
364*4520Snw141292  execsql {
365*4520Snw141292    DELETE FROM t5 WHERE y<3;
366*4520Snw141292    SELECT * FROM t5;
367*4520Snw141292  }
368*4520Snw141292} {1 4}
369*4520Snw141292do_test memdb-6.15 {
370*4520Snw141292  execsql {
371*4520Snw141292    DELETE FROM t5 WHERE x>0;
372*4520Snw141292    SELECT * FROM t5;
373*4520Snw141292  }
374*4520Snw141292} {}
375*4520Snw141292
376*4520Snw141292do_test memdb-7.1 {
377*4520Snw141292  execsql {
378*4520Snw141292    CREATE TABLE t6(x);
379*4520Snw141292    INSERT INTO t6 VALUES(1);
380*4520Snw141292    INSERT INTO t6 SELECT x+1 FROM t6;
381*4520Snw141292    INSERT INTO t6 SELECT x+2 FROM t6;
382*4520Snw141292    INSERT INTO t6 SELECT x+4 FROM t6;
383*4520Snw141292    INSERT INTO t6 SELECT x+8 FROM t6;
384*4520Snw141292    INSERT INTO t6 SELECT x+16 FROM t6;
385*4520Snw141292    INSERT INTO t6 SELECT x+32 FROM t6;
386*4520Snw141292    INSERT INTO t6 SELECT x+64 FROM t6;
387*4520Snw141292    INSERT INTO t6 SELECT x+128 FROM t6;
388*4520Snw141292    SELECT count(*) FROM (SELECT DISTINCT x FROM t6);
389*4520Snw141292  }
390*4520Snw141292} {256}
391*4520Snw141292for {set i 1} {$i<=256} {incr i} {
392*4520Snw141292  do_test memdb-7.2.$i {
393*4520Snw141292     execsql "DELETE FROM t6 WHERE x=\
394*4520Snw141292              (SELECT x FROM t6 ORDER BY random() LIMIT 1)"
395*4520Snw141292     execsql {SELECT count(*) FROM t6}
396*4520Snw141292  } [expr {256-$i}]
397*4520Snw141292}
398*4520Snw141292
399*4520Snw141292finish_test
400