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