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