os/persistentdata/persistentstorage/sqlite3api/TEST/TclScript/temptable.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 October 7
     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.
    12 #
    13 # This file implements tests for temporary tables and indices.
    14 #
    15 # $Id: temptable.test,v 1.19 2007/10/09 08:29:33 danielk1977 Exp $
    16 
    17 set testdir [file dirname $argv0]
    18 source $testdir/tester.tcl
    19 
    20 ifcapable !tempdb {
    21   finish_test
    22   return
    23 }
    24 
    25 # Create an alternative connection to the database
    26 #
    27 do_test temptable-1.0 {
    28   sqlite3 db2 ./test.db
    29   set dummy {}
    30 } {}
    31 
    32 # Create a permanent table.
    33 #
    34 do_test temptable-1.1 {
    35   execsql {CREATE TABLE t1(a,b,c);}
    36   execsql {INSERT INTO t1 VALUES(1,2,3);}
    37   execsql {SELECT * FROM t1}
    38 } {1 2 3}
    39 do_test temptable-1.2 {
    40   catch {db2 eval {SELECT * FROM sqlite_master}}
    41   db2 eval {SELECT * FROM t1}
    42 } {1 2 3}
    43 do_test temptable-1.3 {
    44   execsql {SELECT name FROM sqlite_master}
    45 } {t1}
    46 do_test temptable-1.4 {
    47   db2 eval {SELECT name FROM sqlite_master}
    48 } {t1}
    49 
    50 # Create a temporary table.  Verify that only one of the two
    51 # processes can see it.
    52 #
    53 do_test temptable-1.5 {
    54   db2 eval {
    55     CREATE TEMP TABLE t2(x,y,z);
    56     INSERT INTO t2 VALUES(4,5,6);
    57   }
    58   db2 eval {SELECT * FROM t2}
    59 } {4 5 6}
    60 do_test temptable-1.6 {
    61   catch {execsql {SELECT * FROM sqlite_master}}
    62   catchsql {SELECT * FROM t2}
    63 } {1 {no such table: t2}}
    64 do_test temptable-1.7 {
    65   catchsql {INSERT INTO t2 VALUES(8,9,0);}
    66 } {1 {no such table: t2}}
    67 do_test temptable-1.8 {
    68   db2 eval {INSERT INTO t2 VALUES(8,9,0);}
    69   db2 eval {SELECT * FROM t2 ORDER BY x}
    70 } {4 5 6 8 9 0}
    71 do_test temptable-1.9 {
    72   db2 eval {DELETE FROM t2 WHERE x==8}
    73   db2 eval {SELECT * FROM t2 ORDER BY x}
    74 } {4 5 6}
    75 do_test temptable-1.10 {
    76   db2 eval {DELETE FROM t2}
    77   db2 eval {SELECT * FROM t2}
    78 } {}
    79 do_test temptable-1.11 {
    80   db2 eval {
    81      INSERT INTO t2 VALUES(7,6,5);
    82      INSERT INTO t2 VALUES(4,3,2);
    83      SELECT * FROM t2 ORDER BY x;
    84   }
    85 } {4 3 2 7 6 5}
    86 do_test temptable-1.12 {
    87   db2 eval {DROP TABLE t2;}
    88   set r [catch {db2 eval {SELECT * FROM t2}} msg]
    89   lappend r $msg
    90 } {1 {no such table: t2}}
    91 
    92 # Make sure temporary tables work with transactions
    93 #
    94 do_test temptable-2.1 {
    95   execsql {
    96     BEGIN TRANSACTION;
    97     CREATE TEMPORARY TABLE t2(x,y);
    98     INSERT INTO t2 VALUES(1,2);
    99     SELECT * FROM t2;
   100   }
   101 } {1 2}
   102 do_test temptable-2.2 {
   103   execsql {ROLLBACK}
   104   catchsql {SELECT * FROM t2}
   105 } {1 {no such table: t2}}
   106 do_test temptable-2.3 {
   107   execsql {
   108     BEGIN TRANSACTION;
   109     CREATE TEMPORARY TABLE t2(x,y);
   110     INSERT INTO t2 VALUES(1,2);
   111     SELECT * FROM t2;
   112   }
   113 } {1 2}
   114 do_test temptable-2.4 {
   115   execsql {COMMIT}
   116   catchsql {SELECT * FROM t2}
   117 } {0 {1 2}}
   118 do_test temptable-2.5 {
   119   set r [catch {db2 eval {SELECT * FROM t2}} msg]
   120   lappend r $msg
   121 } {1 {no such table: t2}}
   122 
   123 # Make sure indices on temporary tables are also temporary.
   124 #
   125 do_test temptable-3.1 {
   126   execsql {
   127     CREATE INDEX i2 ON t2(x);
   128     SELECT name FROM sqlite_master WHERE type='index';
   129   }
   130 } {}
   131 do_test temptable-3.2 {
   132   execsql {
   133     SELECT y FROM t2 WHERE x=1;
   134   }
   135 } {2}
   136 do_test temptable-3.3 {
   137   execsql {
   138     DROP INDEX i2;
   139     SELECT y FROM t2 WHERE x=1;
   140   }
   141 } {2}
   142 do_test temptable-3.4 {
   143   execsql {
   144     CREATE INDEX i2 ON t2(x);
   145     DROP TABLE t2;
   146   }
   147   catchsql {DROP INDEX i2}
   148 } {1 {no such index: i2}}
   149 
   150 # Check for correct name collision processing. A name collision can
   151 # occur when process A creates a temporary table T then process B
   152 # creates a permanent table also named T.  The temp table in process A
   153 # hides the existance of the permanent table.
   154 #
   155 do_test temptable-4.1 {
   156   execsql {
   157     CREATE TEMP TABLE t2(x,y);
   158     INSERT INTO t2 VALUES(10,20);
   159     SELECT * FROM t2;
   160   } db2
   161 } {10 20}
   162 do_test temptable-4.2 {
   163   execsql {
   164     CREATE TABLE t2(x,y,z);
   165     INSERT INTO t2 VALUES(9,8,7);
   166     SELECT * FROM t2;
   167   }
   168 } {9 8 7}
   169 do_test temptable-4.3 {
   170   catchsql {
   171     SELECT * FROM t2;
   172   } db2
   173 } {0 {10 20}}
   174 do_test temptable-4.4.1 {
   175   catchsql {
   176     SELECT * FROM temp.t2;
   177   } db2
   178 } {0 {10 20}}
   179 do_test temptable-4.4.2 {
   180   catchsql {
   181     SELECT * FROM main.t2;
   182   } db2
   183 } {1 {no such table: main.t2}}
   184 #do_test temptable-4.4.3 {
   185 #  catchsql {
   186 #    SELECT name FROM main.sqlite_master WHERE type='table';
   187 #  } db2
   188 #} {1 {database schema has changed}}
   189 do_test temptable-4.4.4 {
   190   catchsql {
   191     SELECT name FROM main.sqlite_master WHERE type='table';
   192   } db2
   193 } {0 {t1 t2}}
   194 do_test temptable-4.4.5 {
   195   catchsql {
   196     SELECT * FROM main.t2;
   197   } db2
   198 } {0 {9 8 7}}
   199 do_test temptable-4.4.6 {
   200   # TEMP takes precedence over MAIN
   201   catchsql {
   202     SELECT * FROM t2;
   203   } db2
   204 } {0 {10 20}}
   205 do_test temptable-4.5 {
   206   catchsql {
   207     DROP TABLE t2;     -- should drop TEMP
   208     SELECT * FROM t2;  -- data should be from MAIN
   209   } db2
   210 } {0 {9 8 7}}
   211 do_test temptable-4.6 {
   212   db2 close
   213   sqlite3 db2 ./test.db
   214   catchsql {
   215     SELECT * FROM t2;
   216   } db2
   217 } {0 {9 8 7}}
   218 do_test temptable-4.7 {
   219   catchsql {
   220     DROP TABLE t2;
   221     SELECT * FROM t2;
   222   }
   223 } {1 {no such table: t2}}
   224 do_test temptable-4.8 {
   225   db2 close
   226   sqlite3 db2 ./test.db
   227   execsql {
   228     CREATE TEMP TABLE t2(x unique,y);
   229     INSERT INTO t2 VALUES(1,2);
   230     SELECT * FROM t2;
   231   } db2
   232 } {1 2}
   233 do_test temptable-4.9 {
   234   execsql {
   235     CREATE TABLE t2(x unique, y);
   236     INSERT INTO t2 VALUES(3,4);
   237     SELECT * FROM t2;
   238   }
   239 } {3 4}
   240 do_test temptable-4.10.1 {
   241   catchsql {
   242     SELECT * FROM t2;
   243   } db2
   244 } {0 {1 2}}
   245 # Update: The schema is reloaded in test temptable-4.10.1. And tclsqlite.c
   246 #         handles it and retries the query anyway.
   247 # do_test temptable-4.10.2 {
   248 #   catchsql {
   249 #     SELECT name FROM sqlite_master WHERE type='table'
   250 #   } db2
   251 # } {1 {database schema has changed}}
   252 do_test temptable-4.10.3 {
   253   catchsql {
   254     SELECT name FROM sqlite_master WHERE type='table'
   255   } db2
   256 } {0 {t1 t2}}
   257 do_test temptable-4.11 {
   258   execsql {
   259     SELECT * FROM t2;
   260   } db2
   261 } {1 2}
   262 do_test temptable-4.12 {
   263   execsql {
   264     SELECT * FROM t2;
   265   }
   266 } {3 4}
   267 do_test temptable-4.13 {
   268   catchsql {
   269     DROP TABLE t2;     -- drops TEMP.T2
   270     SELECT * FROM t2;  -- uses MAIN.T2
   271   } db2
   272 } {0 {3 4}}
   273 do_test temptable-4.14 {
   274   execsql {
   275     SELECT * FROM t2;
   276   }
   277 } {3 4}
   278 do_test temptable-4.15 {
   279   db2 close
   280   sqlite3 db2 ./test.db
   281   execsql {
   282     SELECT * FROM t2;
   283   } db2
   284 } {3 4}
   285 
   286 # Now create a temporary table in db2 and a permanent index in db.  The
   287 # temporary table in db2 should mask the name of the permanent index,
   288 # but the permanent index should still be accessible and should still
   289 # be updated when its corresponding table changes.
   290 #
   291 do_test temptable-5.1 {
   292   execsql {
   293     CREATE TEMP TABLE mask(a,b,c)
   294   } db2
   295   execsql {
   296     CREATE INDEX mask ON t2(x);
   297     SELECT * FROM t2;
   298   }
   299 } {3 4}
   300 #do_test temptable-5.2 {
   301 #  catchsql {
   302 #    SELECT * FROM t2;
   303 #  } db2
   304 #} {1 {database schema has changed}}
   305 do_test temptable-5.3 {
   306   catchsql {
   307     SELECT * FROM t2;
   308   } db2
   309 } {0 {3 4}}
   310 do_test temptable-5.4 {
   311   execsql {
   312     SELECT y FROM t2 WHERE x=3
   313   }
   314 } {4}
   315 do_test temptable-5.5 {
   316   execsql {
   317     SELECT y FROM t2 WHERE x=3
   318   } db2
   319 } {4}
   320 do_test temptable-5.6 {
   321   execsql {
   322     INSERT INTO t2 VALUES(1,2);
   323     SELECT y FROM t2 WHERE x=1;
   324   } db2
   325 } {2}
   326 do_test temptable-5.7 {
   327   execsql {
   328     SELECT y FROM t2 WHERE x=3
   329   } db2
   330 } {4}
   331 do_test temptable-5.8 {
   332   execsql {
   333     SELECT y FROM t2 WHERE x=1;
   334   }
   335 } {2}
   336 do_test temptable-5.9 {
   337   execsql {
   338     SELECT y FROM t2 WHERE x=3
   339   }
   340 } {4}
   341 
   342 db2 close
   343 
   344 # Test for correct operation of read-only databases
   345 #
   346 do_test temptable-6.1 {
   347   execsql {
   348     CREATE TABLE t8(x);
   349     INSERT INTO t8 VALUES('xyzzy');
   350     SELECT * FROM t8;
   351   }
   352 } {xyzzy}
   353 do_test temptable-6.2 {
   354   db close
   355   catch {file attributes test.db -permissions 0444}
   356   catch {file attributes test.db -readonly 1}
   357   sqlite3 db test.db
   358   if {[file writable test.db]} {
   359     error "Unable to make the database file test.db readonly - rerun this test as an unprivileged user"
   360   }
   361   execsql {
   362     SELECT * FROM t8;
   363   }
   364 } {xyzzy}
   365 do_test temptable-6.3 {
   366   if {[file writable test.db]} {
   367     error "Unable to make the database file test.db readonly - rerun this test as an unprivileged user"
   368   }
   369   catchsql {
   370     CREATE TABLE t9(x,y);
   371   }
   372 } {1 {attempt to write a readonly database}}
   373 do_test temptable-6.4 {
   374   catchsql {
   375     CREATE TEMP TABLE t9(x,y);
   376   }
   377 } {0 {}}
   378 do_test temptable-6.5 {
   379   catchsql {
   380     INSERT INTO t9 VALUES(1,2);
   381     SELECT * FROM t9;
   382   }
   383 } {0 {1 2}}
   384 do_test temptable-6.6 {
   385   if {[file writable test.db]} {
   386     error "Unable to make the database file test.db readonly - rerun this test as an unprivileged user"
   387   }
   388   catchsql {
   389     INSERT INTO t8 VALUES('hello');
   390     SELECT * FROM t8;
   391   }
   392 } {1 {attempt to write a readonly database}}
   393 do_test temptable-6.7 {
   394   catchsql {
   395     SELECT * FROM t8,t9;
   396   }
   397 } {0 {xyzzy 1 2}}
   398 do_test temptable-6.8 {
   399   db close
   400   sqlite3 db test.db
   401   catchsql {
   402     SELECT * FROM t8,t9;
   403   }
   404 } {1 {no such table: t9}}
   405 
   406 file delete -force test2.db test2.db-journal
   407 ifcapable attach {
   408   do_test temptable-7.1 {
   409     catchsql {
   410       ATTACH 'test2.db' AS two;
   411       CREATE TEMP TABLE two.abc(x,y);
   412     }
   413   } {1 {temporary table name must be unqualified}}
   414 }
   415 
   416 # Need to do the following for tcl 8.5 on mac. On that configuration, the
   417 # -readonly flag is taken so seriously that a subsequent [file delete -force]
   418 # (required before the next test file can be executed) will fail.
   419 #
   420 catch {file attributes test.db -readonly 0}
   421 
   422 finish_test