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