os/persistentdata/persistentstorage/sqlite3api/TEST/TclScript/table.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 September 15
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.  The
sl@0
    12
# focus of this file is testing the CREATE TABLE statement.
sl@0
    13
#
sl@0
    14
# $Id: table.test,v 1.48 2007/10/09 08:29:33 danielk1977 Exp $
sl@0
    15
sl@0
    16
set testdir [file dirname $argv0]
sl@0
    17
source $testdir/tester.tcl
sl@0
    18
sl@0
    19
# Create a basic table and verify it is added to sqlite_master
sl@0
    20
#
sl@0
    21
do_test table-1.1 {
sl@0
    22
  execsql {
sl@0
    23
    CREATE TABLE test1 (
sl@0
    24
      one varchar(10),
sl@0
    25
      two text
sl@0
    26
    )
sl@0
    27
  }
sl@0
    28
  execsql {
sl@0
    29
    SELECT sql FROM sqlite_master WHERE type!='meta'
sl@0
    30
  }
sl@0
    31
} {{CREATE TABLE test1 (
sl@0
    32
      one varchar(10),
sl@0
    33
      two text
sl@0
    34
    )}}
sl@0
    35
sl@0
    36
sl@0
    37
# Verify the other fields of the sqlite_master file.
sl@0
    38
#
sl@0
    39
do_test table-1.3 {
sl@0
    40
  execsql {SELECT name, tbl_name, type FROM sqlite_master WHERE type!='meta'}
sl@0
    41
} {test1 test1 table}
sl@0
    42
sl@0
    43
# Close and reopen the database.  Verify that everything is
sl@0
    44
# still the same.
sl@0
    45
#
sl@0
    46
do_test table-1.4 {
sl@0
    47
  db close
sl@0
    48
  sqlite3 db test.db
sl@0
    49
  execsql {SELECT name, tbl_name, type from sqlite_master WHERE type!='meta'}
sl@0
    50
} {test1 test1 table}
sl@0
    51
sl@0
    52
# Drop the database and make sure it disappears.
sl@0
    53
#
sl@0
    54
do_test table-1.5 {
sl@0
    55
  execsql {DROP TABLE test1}
sl@0
    56
  execsql {SELECT * FROM sqlite_master WHERE type!='meta'}
sl@0
    57
} {}
sl@0
    58
sl@0
    59
# Close and reopen the database.  Verify that the table is
sl@0
    60
# still gone.
sl@0
    61
#
sl@0
    62
do_test table-1.6 {
sl@0
    63
  db close
sl@0
    64
  sqlite3 db test.db
sl@0
    65
  execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
sl@0
    66
} {}
sl@0
    67
sl@0
    68
# Repeat the above steps, but this time quote the table name.
sl@0
    69
#
sl@0
    70
do_test table-1.10 {
sl@0
    71
  execsql {CREATE TABLE "create" (f1 int)}
sl@0
    72
  execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
sl@0
    73
} {create}
sl@0
    74
do_test table-1.11 {
sl@0
    75
  execsql {DROP TABLE "create"}
sl@0
    76
  execsql {SELECT name FROM "sqlite_master" WHERE type!='meta'}
sl@0
    77
} {}
sl@0
    78
do_test table-1.12 {
sl@0
    79
  execsql {CREATE TABLE test1("f1 ho" int)}
sl@0
    80
  execsql {SELECT name as "X" FROM sqlite_master WHERE type!='meta'}
sl@0
    81
} {test1}
sl@0
    82
do_test table-1.13 {
sl@0
    83
  execsql {DROP TABLE "TEST1"}
sl@0
    84
  execsql {SELECT name FROM "sqlite_master" WHERE type!='meta'}
sl@0
    85
} {}
sl@0
    86
sl@0
    87
sl@0
    88
sl@0
    89
# Verify that we cannot make two tables with the same name
sl@0
    90
#
sl@0
    91
do_test table-2.1 {
sl@0
    92
  execsql {CREATE TABLE TEST2(one text)}
sl@0
    93
  catchsql {CREATE TABLE test2(two text default 'hi')}
sl@0
    94
} {1 {table test2 already exists}}
sl@0
    95
do_test table-2.1.1 {
sl@0
    96
  catchsql {CREATE TABLE "test2" (two)}
sl@0
    97
} {1 {table "test2" already exists}}
sl@0
    98
do_test table-2.1b {
sl@0
    99
  set v [catch {execsql {CREATE TABLE sqlite_master(two text)}} msg]
sl@0
   100
  lappend v $msg
sl@0
   101
} {1 {object name reserved for internal use: sqlite_master}}
sl@0
   102
do_test table-2.1c {
sl@0
   103
  db close
sl@0
   104
  sqlite3 db test.db
sl@0
   105
  set v [catch {execsql {CREATE TABLE sqlite_master(two text)}} msg]
sl@0
   106
  lappend v $msg
sl@0
   107
} {1 {object name reserved for internal use: sqlite_master}}
sl@0
   108
do_test table-2.1d {
sl@0
   109
  catchsql {CREATE TABLE IF NOT EXISTS test2(x,y)}
sl@0
   110
} {0 {}}
sl@0
   111
do_test table-2.1e {
sl@0
   112
  catchsql {CREATE TABLE IF NOT EXISTS test2(x UNIQUE, y TEXT PRIMARY KEY)}
sl@0
   113
} {0 {}}
sl@0
   114
do_test table-2.1f {
sl@0
   115
  execsql {DROP TABLE test2; SELECT name FROM sqlite_master WHERE type!='meta'}
sl@0
   116
} {}
sl@0
   117
sl@0
   118
# Verify that we cannot make a table with the same name as an index
sl@0
   119
#
sl@0
   120
do_test table-2.2a {
sl@0
   121
  execsql {CREATE TABLE test2(one text); CREATE INDEX test3 ON test2(one)}
sl@0
   122
  set v [catch {execsql {CREATE TABLE test3(two text)}} msg]
sl@0
   123
  lappend v $msg
sl@0
   124
} {1 {there is already an index named test3}}
sl@0
   125
do_test table-2.2b {
sl@0
   126
  db close
sl@0
   127
  sqlite3 db test.db
sl@0
   128
  set v [catch {execsql {CREATE TABLE test3(two text)}} msg]
sl@0
   129
  lappend v $msg
sl@0
   130
} {1 {there is already an index named test3}}
sl@0
   131
do_test table-2.2c {
sl@0
   132
  execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
sl@0
   133
} {test2 test3}
sl@0
   134
do_test table-2.2d {
sl@0
   135
  execsql {DROP INDEX test3}
sl@0
   136
  set v [catch {execsql {CREATE TABLE test3(two text)}} msg]
sl@0
   137
  lappend v $msg
sl@0
   138
} {0 {}}
sl@0
   139
do_test table-2.2e {
sl@0
   140
  execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
sl@0
   141
} {test2 test3}
sl@0
   142
do_test table-2.2f {
sl@0
   143
  execsql {DROP TABLE test2; DROP TABLE test3}
sl@0
   144
  execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
sl@0
   145
} {}
sl@0
   146
sl@0
   147
# Create a table with many field names
sl@0
   148
#
sl@0
   149
set big_table \
sl@0
   150
{CREATE TABLE big(
sl@0
   151
  f1 varchar(20),
sl@0
   152
  f2 char(10),
sl@0
   153
  f3 varchar(30) primary key,
sl@0
   154
  f4 text,
sl@0
   155
  f5 text,
sl@0
   156
  f6 text,
sl@0
   157
  f7 text,
sl@0
   158
  f8 text,
sl@0
   159
  f9 text,
sl@0
   160
  f10 text,
sl@0
   161
  f11 text,
sl@0
   162
  f12 text,
sl@0
   163
  f13 text,
sl@0
   164
  f14 text,
sl@0
   165
  f15 text,
sl@0
   166
  f16 text,
sl@0
   167
  f17 text,
sl@0
   168
  f18 text,
sl@0
   169
  f19 text,
sl@0
   170
  f20 text
sl@0
   171
)}
sl@0
   172
do_test table-3.1 {
sl@0
   173
  execsql $big_table
sl@0
   174
  execsql {SELECT sql FROM sqlite_master WHERE type=='table'}
sl@0
   175
} \{$big_table\}
sl@0
   176
do_test table-3.2 {
sl@0
   177
  set v [catch {execsql {CREATE TABLE BIG(xyz foo)}} msg]
sl@0
   178
  lappend v $msg
sl@0
   179
} {1 {table BIG already exists}}
sl@0
   180
do_test table-3.3 {
sl@0
   181
  set v [catch {execsql {CREATE TABLE biG(xyz foo)}} msg]
sl@0
   182
  lappend v $msg
sl@0
   183
} {1 {table biG already exists}}
sl@0
   184
do_test table-3.4 {
sl@0
   185
  set v [catch {execsql {CREATE TABLE bIg(xyz foo)}} msg]
sl@0
   186
  lappend v $msg
sl@0
   187
} {1 {table bIg already exists}}
sl@0
   188
do_test table-3.5 {
sl@0
   189
  db close
sl@0
   190
  sqlite3 db test.db
sl@0
   191
  set v [catch {execsql {CREATE TABLE Big(xyz foo)}} msg]
sl@0
   192
  lappend v $msg
sl@0
   193
} {1 {table Big already exists}}
sl@0
   194
do_test table-3.6 {
sl@0
   195
  execsql {DROP TABLE big}
sl@0
   196
  execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
sl@0
   197
} {}
sl@0
   198
sl@0
   199
# Try creating large numbers of tables
sl@0
   200
#
sl@0
   201
set r {}
sl@0
   202
for {set i 1} {$i<=100} {incr i} {
sl@0
   203
  lappend r [format test%03d $i]
sl@0
   204
}
sl@0
   205
do_test table-4.1 {
sl@0
   206
  for {set i 1} {$i<=100} {incr i} {
sl@0
   207
    set sql "CREATE TABLE [format test%03d $i] ("
sl@0
   208
    for {set k 1} {$k<$i} {incr k} {
sl@0
   209
      append sql "field$k text,"
sl@0
   210
    }
sl@0
   211
    append sql "last_field text)"
sl@0
   212
    execsql $sql
sl@0
   213
  }
sl@0
   214
  execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
sl@0
   215
} $r
sl@0
   216
do_test table-4.1b {
sl@0
   217
  db close
sl@0
   218
  sqlite3 db test.db
sl@0
   219
  execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
sl@0
   220
} $r
sl@0
   221
sl@0
   222
# Drop the even numbered tables
sl@0
   223
#
sl@0
   224
set r {}
sl@0
   225
for {set i 1} {$i<=100} {incr i 2} {
sl@0
   226
  lappend r [format test%03d $i]
sl@0
   227
}
sl@0
   228
do_test table-4.2 {
sl@0
   229
  for {set i 2} {$i<=100} {incr i 2} {
sl@0
   230
    # if {$i==38} {execsql {pragma vdbe_trace=on}}
sl@0
   231
    set sql "DROP TABLE [format TEST%03d $i]"
sl@0
   232
    execsql $sql
sl@0
   233
  }
sl@0
   234
  execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
sl@0
   235
} $r
sl@0
   236
#exit
sl@0
   237
sl@0
   238
# Drop the odd number tables
sl@0
   239
#
sl@0
   240
do_test table-4.3 {
sl@0
   241
  for {set i 1} {$i<=100} {incr i 2} {
sl@0
   242
    set sql "DROP TABLE [format test%03d $i]"
sl@0
   243
    execsql $sql
sl@0
   244
  }
sl@0
   245
  execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
sl@0
   246
} {}
sl@0
   247
sl@0
   248
# Try to drop a table that does not exist
sl@0
   249
#
sl@0
   250
do_test table-5.1.1 {
sl@0
   251
  catchsql {DROP TABLE test009}
sl@0
   252
} {1 {no such table: test009}}
sl@0
   253
do_test table-5.1.2 {
sl@0
   254
  catchsql {DROP TABLE IF EXISTS test009}
sl@0
   255
} {0 {}}
sl@0
   256
sl@0
   257
# Try to drop sqlite_master
sl@0
   258
#
sl@0
   259
do_test table-5.2 {
sl@0
   260
  catchsql {DROP TABLE IF EXISTS sqlite_master}
sl@0
   261
} {1 {table sqlite_master may not be dropped}}
sl@0
   262
sl@0
   263
# Make sure an EXPLAIN does not really create a new table
sl@0
   264
#
sl@0
   265
do_test table-5.3 {
sl@0
   266
  ifcapable {explain} {
sl@0
   267
    execsql {EXPLAIN CREATE TABLE test1(f1 int)}
sl@0
   268
  }
sl@0
   269
  execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
sl@0
   270
} {}
sl@0
   271
sl@0
   272
# Make sure an EXPLAIN does not really drop an existing table
sl@0
   273
#
sl@0
   274
do_test table-5.4 {
sl@0
   275
  execsql {CREATE TABLE test1(f1 int)}
sl@0
   276
  ifcapable {explain} {
sl@0
   277
    execsql {EXPLAIN DROP TABLE test1}
sl@0
   278
  }
sl@0
   279
  execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
sl@0
   280
} {test1}
sl@0
   281
sl@0
   282
# Create a table with a goofy name
sl@0
   283
#
sl@0
   284
#do_test table-6.1 {
sl@0
   285
#  execsql {CREATE TABLE 'Spaces In This Name!'(x int)}
sl@0
   286
#  execsql {INSERT INTO 'spaces in this name!' VALUES(1)}
sl@0
   287
#  set list [glob -nocomplain testdb/spaces*.tbl]
sl@0
   288
#} {testdb/spaces+in+this+name+.tbl}
sl@0
   289
sl@0
   290
# Try using keywords as table names or column names.
sl@0
   291
# 
sl@0
   292
do_test table-7.1 {
sl@0
   293
  set v [catch {execsql {
sl@0
   294
    CREATE TABLE weird(
sl@0
   295
      desc text,
sl@0
   296
      asc text,
sl@0
   297
      key int,
sl@0
   298
      [14_vac] boolean,
sl@0
   299
      fuzzy_dog_12 varchar(10),
sl@0
   300
      begin blob,
sl@0
   301
      end clob
sl@0
   302
    )
sl@0
   303
  }} msg]
sl@0
   304
  lappend v $msg
sl@0
   305
} {0 {}}
sl@0
   306
do_test table-7.2 {
sl@0
   307
  execsql {
sl@0
   308
    INSERT INTO weird VALUES('a','b',9,0,'xyz','hi','y''all');
sl@0
   309
    SELECT * FROM weird;
sl@0
   310
  }
sl@0
   311
} {a b 9 0 xyz hi y'all}
sl@0
   312
do_test table-7.3 {
sl@0
   313
  execsql2 {
sl@0
   314
    SELECT * FROM weird;
sl@0
   315
  }
sl@0
   316
} {desc a asc b key 9 14_vac 0 fuzzy_dog_12 xyz begin hi end y'all}
sl@0
   317
sl@0
   318
# Try out the CREATE TABLE AS syntax
sl@0
   319
#
sl@0
   320
do_test table-8.1 {
sl@0
   321
  execsql2 {
sl@0
   322
    CREATE TABLE t2 AS SELECT * FROM weird;
sl@0
   323
    SELECT * FROM t2;
sl@0
   324
  }
sl@0
   325
} {desc a asc b key 9 14_vac 0 fuzzy_dog_12 xyz begin hi end y'all}
sl@0
   326
do_test table-8.1.1 {
sl@0
   327
  execsql {
sl@0
   328
    SELECT sql FROM sqlite_master WHERE name='t2';
sl@0
   329
  }
sl@0
   330
} {{CREATE TABLE t2(
sl@0
   331
  "desc" text,
sl@0
   332
  "asc" text,
sl@0
   333
  "key" int,
sl@0
   334
  "14_vac" boolean,
sl@0
   335
  fuzzy_dog_12 varchar(10),
sl@0
   336
  "begin" blob,
sl@0
   337
  "end" clob
sl@0
   338
)}}
sl@0
   339
do_test table-8.2 {
sl@0
   340
  execsql {
sl@0
   341
    CREATE TABLE "t3""xyz"(a,b,c);
sl@0
   342
    INSERT INTO [t3"xyz] VALUES(1,2,3);
sl@0
   343
    SELECT * FROM [t3"xyz];
sl@0
   344
  }
sl@0
   345
} {1 2 3}
sl@0
   346
do_test table-8.3 {
sl@0
   347
  execsql2 {
sl@0
   348
    CREATE TABLE [t4"abc] AS SELECT count(*) as cnt, max(b+c) FROM [t3"xyz];
sl@0
   349
    SELECT * FROM [t4"abc];
sl@0
   350
  }
sl@0
   351
} {cnt 1 max(b+c) 5}
sl@0
   352
sl@0
   353
# Update for v3: The declaration type of anything except a column is now a
sl@0
   354
# NULL pointer, so the created table has no column types. (Changed result
sl@0
   355
# from {{CREATE TABLE 't4"abc'(cnt NUMERIC,"max(b+c)" NUMERIC)}}).
sl@0
   356
do_test table-8.3.1 {
sl@0
   357
  execsql {
sl@0
   358
    SELECT sql FROM sqlite_master WHERE name='t4"abc'
sl@0
   359
  }
sl@0
   360
} {{CREATE TABLE "t4""abc"(cnt,"max(b+c)")}}
sl@0
   361
sl@0
   362
ifcapable tempdb {
sl@0
   363
  do_test table-8.4 {
sl@0
   364
    execsql2 {
sl@0
   365
      CREATE TEMPORARY TABLE t5 AS SELECT count(*) AS [y'all] FROM [t3"xyz];
sl@0
   366
      SELECT * FROM t5;
sl@0
   367
    }
sl@0
   368
  } {y'all 1}
sl@0
   369
}
sl@0
   370
sl@0
   371
do_test table-8.5 {
sl@0
   372
  db close
sl@0
   373
  sqlite3 db test.db
sl@0
   374
  execsql2 {
sl@0
   375
    SELECT * FROM [t4"abc];
sl@0
   376
  }
sl@0
   377
} {cnt 1 max(b+c) 5}
sl@0
   378
do_test table-8.6 {
sl@0
   379
  execsql2 {
sl@0
   380
    SELECT * FROM t2;
sl@0
   381
  }
sl@0
   382
} {desc a asc b key 9 14_vac 0 fuzzy_dog_12 xyz begin hi end y'all}
sl@0
   383
do_test table-8.7 {
sl@0
   384
  catchsql {
sl@0
   385
    SELECT * FROM t5;
sl@0
   386
  }
sl@0
   387
} {1 {no such table: t5}}
sl@0
   388
do_test table-8.8 {
sl@0
   389
  catchsql {
sl@0
   390
    CREATE TABLE t5 AS SELECT * FROM no_such_table;
sl@0
   391
  }
sl@0
   392
} {1 {no such table: no_such_table}}
sl@0
   393
sl@0
   394
# Make sure we cannot have duplicate column names within a table.
sl@0
   395
#
sl@0
   396
do_test table-9.1 {
sl@0
   397
  catchsql {
sl@0
   398
    CREATE TABLE t6(a,b,a);
sl@0
   399
  }
sl@0
   400
} {1 {duplicate column name: a}}
sl@0
   401
do_test table-9.2 {
sl@0
   402
  catchsql {
sl@0
   403
    CREATE TABLE t6(a varchar(100), b blob, a integer);
sl@0
   404
  }
sl@0
   405
} {1 {duplicate column name: a}}
sl@0
   406
sl@0
   407
# Check the foreign key syntax.
sl@0
   408
#
sl@0
   409
ifcapable {foreignkey} {
sl@0
   410
do_test table-10.1 {
sl@0
   411
  catchsql {
sl@0
   412
    CREATE TABLE t6(a REFERENCES t4(a) NOT NULL);
sl@0
   413
    INSERT INTO t6 VALUES(NULL);
sl@0
   414
  }
sl@0
   415
} {1 {t6.a may not be NULL}}
sl@0
   416
do_test table-10.2 {
sl@0
   417
  catchsql {
sl@0
   418
    DROP TABLE t6;
sl@0
   419
    CREATE TABLE t6(a REFERENCES t4(a) MATCH PARTIAL);
sl@0
   420
  }
sl@0
   421
} {0 {}}
sl@0
   422
do_test table-10.3 {
sl@0
   423
  catchsql {
sl@0
   424
    DROP TABLE t6;
sl@0
   425
    CREATE TABLE t6(a REFERENCES t4 MATCH FULL ON DELETE SET NULL NOT NULL);
sl@0
   426
  }
sl@0
   427
} {0 {}}
sl@0
   428
do_test table-10.4 {
sl@0
   429
  catchsql {
sl@0
   430
    DROP TABLE t6;
sl@0
   431
    CREATE TABLE t6(a REFERENCES t4 MATCH FULL ON UPDATE SET DEFAULT DEFAULT 1);
sl@0
   432
  }
sl@0
   433
} {0 {}}
sl@0
   434
do_test table-10.5 {
sl@0
   435
  catchsql {
sl@0
   436
    DROP TABLE t6;
sl@0
   437
    CREATE TABLE t6(a NOT NULL NOT DEFERRABLE INITIALLY IMMEDIATE);
sl@0
   438
  }
sl@0
   439
} {0 {}}
sl@0
   440
do_test table-10.6 {
sl@0
   441
  catchsql {
sl@0
   442
    DROP TABLE t6;
sl@0
   443
    CREATE TABLE t6(a NOT NULL DEFERRABLE INITIALLY DEFERRED);
sl@0
   444
  }
sl@0
   445
} {0 {}}
sl@0
   446
do_test table-10.7 {
sl@0
   447
  catchsql {
sl@0
   448
    DROP TABLE t6;
sl@0
   449
    CREATE TABLE t6(a,
sl@0
   450
      FOREIGN KEY (a) REFERENCES t4(b) DEFERRABLE INITIALLY DEFERRED
sl@0
   451
    );
sl@0
   452
  }
sl@0
   453
} {0 {}}
sl@0
   454
do_test table-10.8 {
sl@0
   455
  catchsql {
sl@0
   456
    DROP TABLE t6;
sl@0
   457
    CREATE TABLE t6(a,b,c,
sl@0
   458
      FOREIGN KEY (b,c) REFERENCES t4(x,y) MATCH PARTIAL
sl@0
   459
        ON UPDATE SET NULL ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED
sl@0
   460
    );
sl@0
   461
  }
sl@0
   462
} {0 {}}
sl@0
   463
do_test table-10.9 {
sl@0
   464
  catchsql {
sl@0
   465
    DROP TABLE t6;
sl@0
   466
    CREATE TABLE t6(a,b,c,
sl@0
   467
      FOREIGN KEY (b,c) REFERENCES t4(x)
sl@0
   468
    );
sl@0
   469
  }
sl@0
   470
} {1 {number of columns in foreign key does not match the number of columns in the referenced table}}
sl@0
   471
do_test table-10.10 {
sl@0
   472
  catchsql {DROP TABLE t6}
sl@0
   473
  catchsql {
sl@0
   474
    CREATE TABLE t6(a,b,c,
sl@0
   475
      FOREIGN KEY (b,c) REFERENCES t4(x,y,z)
sl@0
   476
    );
sl@0
   477
  }
sl@0
   478
} {1 {number of columns in foreign key does not match the number of columns in the referenced table}}
sl@0
   479
do_test table-10.11 {
sl@0
   480
  catchsql {DROP TABLE t6}
sl@0
   481
  catchsql {
sl@0
   482
    CREATE TABLE t6(a,b, c REFERENCES t4(x,y));
sl@0
   483
  }
sl@0
   484
} {1 {foreign key on c should reference only one column of table t4}}
sl@0
   485
do_test table-10.12 {
sl@0
   486
  catchsql {DROP TABLE t6}
sl@0
   487
  catchsql {
sl@0
   488
    CREATE TABLE t6(a,b,c,
sl@0
   489
      FOREIGN KEY (b,x) REFERENCES t4(x,y)
sl@0
   490
    );
sl@0
   491
  }
sl@0
   492
} {1 {unknown column "x" in foreign key definition}}
sl@0
   493
do_test table-10.13 {
sl@0
   494
  catchsql {DROP TABLE t6}
sl@0
   495
  catchsql {
sl@0
   496
    CREATE TABLE t6(a,b,c,
sl@0
   497
      FOREIGN KEY (x,b) REFERENCES t4(x,y)
sl@0
   498
    );
sl@0
   499
  }
sl@0
   500
} {1 {unknown column "x" in foreign key definition}}
sl@0
   501
} ;# endif foreignkey
sl@0
   502
sl@0
   503
# Test for the "typeof" function. More tests for the
sl@0
   504
# typeof() function are found in bind.test and types.test.
sl@0
   505
#
sl@0
   506
do_test table-11.1 {
sl@0
   507
  execsql {
sl@0
   508
    CREATE TABLE t7(
sl@0
   509
       a integer primary key,
sl@0
   510
       b number(5,10),
sl@0
   511
       c character varying (8),
sl@0
   512
       d VARCHAR(9),
sl@0
   513
       e clob,
sl@0
   514
       f BLOB,
sl@0
   515
       g Text,
sl@0
   516
       h
sl@0
   517
    );
sl@0
   518
    INSERT INTO t7(a) VALUES(1);
sl@0
   519
    SELECT typeof(a), typeof(b), typeof(c), typeof(d),
sl@0
   520
           typeof(e), typeof(f), typeof(g), typeof(h)
sl@0
   521
    FROM t7 LIMIT 1;
sl@0
   522
  }
sl@0
   523
} {integer null null null null null null null} 
sl@0
   524
do_test table-11.2 {
sl@0
   525
  execsql {
sl@0
   526
    SELECT typeof(a+b), typeof(a||b), typeof(c+d), typeof(c||d)
sl@0
   527
    FROM t7 LIMIT 1;
sl@0
   528
  }
sl@0
   529
} {null null null null}
sl@0
   530
sl@0
   531
# Test that when creating a table using CREATE TABLE AS, column types are
sl@0
   532
# assigned correctly for (SELECT ...) and 'x AS y' expressions.
sl@0
   533
do_test table-12.1 {
sl@0
   534
  ifcapable subquery {
sl@0
   535
    execsql {
sl@0
   536
      CREATE TABLE t8 AS SELECT b, h, a as i, (SELECT f FROM t7) as j FROM t7;
sl@0
   537
    }
sl@0
   538
  } else {
sl@0
   539
    execsql {
sl@0
   540
      CREATE TABLE t8 AS SELECT b, h, a as i, f as j FROM t7;
sl@0
   541
    }
sl@0
   542
  }
sl@0
   543
} {}
sl@0
   544
do_test table-12.2 {
sl@0
   545
  execsql {
sl@0
   546
    SELECT sql FROM sqlite_master WHERE tbl_name = 't8'
sl@0
   547
  }
sl@0
   548
} {{CREATE TABLE t8(b number(5,10),h,i integer,j BLOB)}}
sl@0
   549
sl@0
   550
#--------------------------------------------------------------------
sl@0
   551
# Test cases table-13.*
sl@0
   552
#
sl@0
   553
# Test the ability to have default values of CURRENT_TIME, CURRENT_DATE
sl@0
   554
# and CURRENT_TIMESTAMP.
sl@0
   555
#
sl@0
   556
do_test table-13.1 {
sl@0
   557
  execsql {
sl@0
   558
    CREATE TABLE tablet8(
sl@0
   559
       a integer primary key,
sl@0
   560
       tm text DEFAULT CURRENT_TIME,
sl@0
   561
       dt text DEFAULT CURRENT_DATE,
sl@0
   562
       dttm text DEFAULT CURRENT_TIMESTAMP
sl@0
   563
    );
sl@0
   564
    SELECT * FROM tablet8;
sl@0
   565
  }
sl@0
   566
} {}
sl@0
   567
set i 0
sl@0
   568
foreach {date time seconds} {
sl@0
   569
  1976-07-04 12:00:00 205329600
sl@0
   570
  1994-04-16 14:00:00 766504800
sl@0
   571
  2000-01-01 00:00:00 946684800
sl@0
   572
  2003-12-31 12:34:56 1072874096
sl@0
   573
} {
sl@0
   574
  incr i
sl@0
   575
  set sqlite_current_time $seconds
sl@0
   576
  do_test table-13.2.$i {
sl@0
   577
    execsql "
sl@0
   578
      INSERT INTO tablet8(a) VALUES($i);
sl@0
   579
      SELECT tm, dt, dttm FROM tablet8 WHERE a=$i;
sl@0
   580
    "
sl@0
   581
  } [list $time $date [list $date $time]]
sl@0
   582
}
sl@0
   583
set sqlite_current_time 0
sl@0
   584
sl@0
   585
#--------------------------------------------------------------------
sl@0
   586
# Test cases table-14.*
sl@0
   587
#
sl@0
   588
# Test that a table cannot be created or dropped while other virtual
sl@0
   589
# machines are active. This is required because otherwise when in 
sl@0
   590
# auto-vacuum mode the btree-layer may need to move the root-pages of 
sl@0
   591
# a table for which there is an open cursor.
sl@0
   592
#
sl@0
   593
# 2007-05-02:  A open btree cursor no longer blocks CREATE TABLE.
sl@0
   594
# But DROP TABLE is still prohibited because we do not want to
sl@0
   595
# delete a table out from under a running query.
sl@0
   596
#
sl@0
   597
sl@0
   598
# db eval {
sl@0
   599
#   pragma vdbe_trace = 0;
sl@0
   600
# }
sl@0
   601
# Try to create a table from within a callback:
sl@0
   602
unset -nocomplain result
sl@0
   603
do_test table-14.1 {
sl@0
   604
  set rc [
sl@0
   605
    catch {
sl@0
   606
      db eval {SELECT * FROM tablet8 LIMIT 1} {} {
sl@0
   607
        db eval {CREATE TABLE t9(a, b, c)}
sl@0
   608
      }
sl@0
   609
    } msg
sl@0
   610
  ]
sl@0
   611
  set result [list $rc $msg]
sl@0
   612
} {0 {}}
sl@0
   613
sl@0
   614
# Try to drop a table from within a callback:
sl@0
   615
do_test table-14.2 {
sl@0
   616
  set rc [
sl@0
   617
    catch {
sl@0
   618
      db eval {SELECT * FROM tablet8 LIMIT 1} {} {
sl@0
   619
        db eval {DROP TABLE t9;}
sl@0
   620
      }
sl@0
   621
    } msg
sl@0
   622
  ] 
sl@0
   623
  set result [list $rc $msg]
sl@0
   624
} {1 {database table is locked}}
sl@0
   625
sl@0
   626
ifcapable attach {
sl@0
   627
  # Now attach a database and ensure that a table can be created in the 
sl@0
   628
  # attached database whilst in a callback from a query on the main database.
sl@0
   629
  do_test table-14.3 {
sl@0
   630
    file delete -force test2.db
sl@0
   631
    file delete -force test2.db-journal
sl@0
   632
    execsql {
sl@0
   633
      ATTACH 'test2.db' as aux;
sl@0
   634
    }
sl@0
   635
    db eval {SELECT * FROM tablet8 LIMIT 1} {} {
sl@0
   636
      db eval {CREATE TABLE aux.t1(a, b, c)}
sl@0
   637
    }
sl@0
   638
  } {}
sl@0
   639
  
sl@0
   640
  # On the other hand, it should be impossible to drop a table when any VMs 
sl@0
   641
  # are active. This is because VerifyCookie instructions may have already
sl@0
   642
  # been executed, and btree root-pages may not move after this (which a
sl@0
   643
  # delete table might do).
sl@0
   644
  do_test table-14.4 {
sl@0
   645
    set rc [
sl@0
   646
      catch {
sl@0
   647
        db eval {SELECT * FROM tablet8 LIMIT 1} {} {
sl@0
   648
          db eval {DROP TABLE aux.t1;}
sl@0
   649
        }
sl@0
   650
      } msg
sl@0
   651
    ] 
sl@0
   652
    set result [list $rc $msg]
sl@0
   653
  } {1 {database table is locked}}
sl@0
   654
}
sl@0
   655
sl@0
   656
# Create and drop 2000 tables. This is to check that the balance_shallow()
sl@0
   657
# routine works correctly on the sqlite_master table. At one point it
sl@0
   658
# contained a bug that would prevent the right-child pointer of the
sl@0
   659
# child page from being copied to the root page.
sl@0
   660
#
sl@0
   661
do_test table-15.1 {
sl@0
   662
  execsql {BEGIN}
sl@0
   663
  for {set i 0} {$i<2000} {incr i} {
sl@0
   664
    execsql "CREATE TABLE tbl$i (a, b, c)"
sl@0
   665
  }
sl@0
   666
  execsql {COMMIT}
sl@0
   667
} {}
sl@0
   668
do_test table-15.2 {
sl@0
   669
  execsql {BEGIN}
sl@0
   670
  for {set i 0} {$i<2000} {incr i} {
sl@0
   671
    execsql "DROP TABLE tbl$i"
sl@0
   672
  }
sl@0
   673
  execsql {COMMIT}
sl@0
   674
} {}
sl@0
   675
sl@0
   676
finish_test