persistentstorage/sqlite3api/TEST/TclScript/memdb.test
changeset 0 08ec8eefde2f
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     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