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