blob: bc868e0c43915cd769dd8d1eb547df55e5bf7aac [file] [log] [blame]
drhb19a2bc2001-09-16 00:13:26 +00001# 2001 September 15
drh348784e2000-05-29 20:41:49 +00002#
drhb19a2bc2001-09-16 00:13:26 +00003# The author disclaims copyright to this source code. In place of
4# a legal notice, here is a blessing:
drh348784e2000-05-29 20:41:49 +00005#
drhb19a2bc2001-09-16 00:13:26 +00006# 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.
drh348784e2000-05-29 20:41:49 +00009#
10#***********************************************************************
11# This file implements regression tests for SQLite library. The
12# focus of this file is testing the CREATE TABLE statement.
13#
danielk197732554c12005-01-22 03:39:39 +000014# $Id: table.test,v 1.37 2005/01/22 03:39:39 danielk1977 Exp $
drh348784e2000-05-29 20:41:49 +000015
16set testdir [file dirname $argv0]
17source $testdir/tester.tcl
18
19# Create a basic table and verify it is added to sqlite_master
20#
drh1b6a71f2000-05-29 23:58:11 +000021do_test table-1.1 {
drh348784e2000-05-29 20:41:49 +000022 execsql {
23 CREATE TABLE test1 (
24 one varchar(10),
25 two text
26 )
27 }
28 execsql {
drh28037572000-08-02 13:47:41 +000029 SELECT sql FROM sqlite_master WHERE type!='meta'
drh348784e2000-05-29 20:41:49 +000030 }
31} {{CREATE TABLE test1 (
32 one varchar(10),
33 two text
34 )}}
35
drh348784e2000-05-29 20:41:49 +000036
37# Verify the other fields of the sqlite_master file.
38#
drh1b6a71f2000-05-29 23:58:11 +000039do_test table-1.3 {
drh28037572000-08-02 13:47:41 +000040 execsql {SELECT name, tbl_name, type FROM sqlite_master WHERE type!='meta'}
drh348784e2000-05-29 20:41:49 +000041} {test1 test1 table}
42
43# Close and reopen the database. Verify that everything is
44# still the same.
45#
drh1b6a71f2000-05-29 23:58:11 +000046do_test table-1.4 {
drh348784e2000-05-29 20:41:49 +000047 db close
drhef4ac8f2004-06-19 00:16:31 +000048 sqlite3 db test.db
drh28037572000-08-02 13:47:41 +000049 execsql {SELECT name, tbl_name, type from sqlite_master WHERE type!='meta'}
drh348784e2000-05-29 20:41:49 +000050} {test1 test1 table}
51
52# Drop the database and make sure it disappears.
53#
drh1b6a71f2000-05-29 23:58:11 +000054do_test table-1.5 {
drh348784e2000-05-29 20:41:49 +000055 execsql {DROP TABLE test1}
drh28037572000-08-02 13:47:41 +000056 execsql {SELECT * FROM sqlite_master WHERE type!='meta'}
drh348784e2000-05-29 20:41:49 +000057} {}
58
drh348784e2000-05-29 20:41:49 +000059# Close and reopen the database. Verify that the table is
60# still gone.
61#
drh1b6a71f2000-05-29 23:58:11 +000062do_test table-1.6 {
drh348784e2000-05-29 20:41:49 +000063 db close
drhef4ac8f2004-06-19 00:16:31 +000064 sqlite3 db test.db
drh28037572000-08-02 13:47:41 +000065 execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
drh348784e2000-05-29 20:41:49 +000066} {}
67
drh982cef72000-05-30 16:27:03 +000068# Repeat the above steps, but this time quote the table name.
69#
70do_test table-1.10 {
71 execsql {CREATE TABLE "create" (f1 int)}
drh28037572000-08-02 13:47:41 +000072 execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
drh982cef72000-05-30 16:27:03 +000073} {create}
74do_test table-1.11 {
75 execsql {DROP TABLE "create"}
drh28037572000-08-02 13:47:41 +000076 execsql {SELECT name FROM "sqlite_master" WHERE type!='meta'}
drh982cef72000-05-30 16:27:03 +000077} {}
78do_test table-1.12 {
79 execsql {CREATE TABLE test1("f1 ho" int)}
drh28037572000-08-02 13:47:41 +000080 execsql {SELECT name as "X" FROM sqlite_master WHERE type!='meta'}
drh982cef72000-05-30 16:27:03 +000081} {test1}
82do_test table-1.13 {
83 execsql {DROP TABLE "TEST1"}
drh28037572000-08-02 13:47:41 +000084 execsql {SELECT name FROM "sqlite_master" WHERE type!='meta'}
drh982cef72000-05-30 16:27:03 +000085} {}
86
87
drhb24fcbe2000-05-29 23:30:50 +000088
89# Verify that we cannot make two tables with the same name
90#
drh1b6a71f2000-05-29 23:58:11 +000091do_test table-2.1 {
drh4cfa7932000-06-08 15:10:46 +000092 execsql {CREATE TABLE TEST2(one text)}
drhb24fcbe2000-05-29 23:30:50 +000093 set v [catch {execsql {CREATE TABLE test2(two text)}} msg]
94 lappend v $msg
drh1d37e282000-05-30 03:12:21 +000095} {1 {table test2 already exists}}
drh1b6a71f2000-05-29 23:58:11 +000096do_test table-2.1b {
drhb24fcbe2000-05-29 23:30:50 +000097 set v [catch {execsql {CREATE TABLE sqlite_master(two text)}} msg]
98 lappend v $msg
danielk1977d8123362004-06-12 09:25:12 +000099} {1 {object name reserved for internal use: sqlite_master}}
drh1b6a71f2000-05-29 23:58:11 +0000100do_test table-2.1c {
drhb24fcbe2000-05-29 23:30:50 +0000101 db close
drhef4ac8f2004-06-19 00:16:31 +0000102 sqlite3 db test.db
drhb24fcbe2000-05-29 23:30:50 +0000103 set v [catch {execsql {CREATE TABLE sqlite_master(two text)}} msg]
104 lappend v $msg
danielk1977d8123362004-06-12 09:25:12 +0000105} {1 {object name reserved for internal use: sqlite_master}}
drh1b6a71f2000-05-29 23:58:11 +0000106do_test table-2.1d {
drh28037572000-08-02 13:47:41 +0000107 execsql {DROP TABLE test2; SELECT name FROM sqlite_master WHERE type!='meta'}
drhb24fcbe2000-05-29 23:30:50 +0000108} {}
109
110# Verify that we cannot make a table with the same name as an index
111#
drhdcc581c2000-05-30 13:44:19 +0000112do_test table-2.2a {
drhb24fcbe2000-05-29 23:30:50 +0000113 execsql {CREATE TABLE test2(one text); CREATE INDEX test3 ON test2(one)}
114 set v [catch {execsql {CREATE TABLE test3(two text)}} msg]
115 lappend v $msg
drh1d37e282000-05-30 03:12:21 +0000116} {1 {there is already an index named test3}}
drh1b6a71f2000-05-29 23:58:11 +0000117do_test table-2.2b {
drhb24fcbe2000-05-29 23:30:50 +0000118 db close
drhef4ac8f2004-06-19 00:16:31 +0000119 sqlite3 db test.db
drhb24fcbe2000-05-29 23:30:50 +0000120 set v [catch {execsql {CREATE TABLE test3(two text)}} msg]
121 lappend v $msg
drh1d37e282000-05-30 03:12:21 +0000122} {1 {there is already an index named test3}}
drh1b6a71f2000-05-29 23:58:11 +0000123do_test table-2.2c {
drh3fc190c2001-09-14 03:24:23 +0000124 execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
125} {test2 test3}
126do_test table-2.2d {
drhb24fcbe2000-05-29 23:30:50 +0000127 execsql {DROP INDEX test3}
128 set v [catch {execsql {CREATE TABLE test3(two text)}} msg]
129 lappend v $msg
130} {0 {}}
drh3fc190c2001-09-14 03:24:23 +0000131do_test table-2.2e {
drh28037572000-08-02 13:47:41 +0000132 execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
drhb24fcbe2000-05-29 23:30:50 +0000133} {test2 test3}
drh3fc190c2001-09-14 03:24:23 +0000134do_test table-2.2f {
drhb24fcbe2000-05-29 23:30:50 +0000135 execsql {DROP TABLE test2; DROP TABLE test3}
drh28037572000-08-02 13:47:41 +0000136 execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
drhb24fcbe2000-05-29 23:30:50 +0000137} {}
138
139# Create a table with many field names
140#
141set big_table \
142{CREATE TABLE big(
143 f1 varchar(20),
144 f2 char(10),
drhdcc581c2000-05-30 13:44:19 +0000145 f3 varchar(30) primary key,
drhb24fcbe2000-05-29 23:30:50 +0000146 f4 text,
147 f5 text,
148 f6 text,
149 f7 text,
150 f8 text,
151 f9 text,
152 f10 text,
153 f11 text,
154 f12 text,
155 f13 text,
156 f14 text,
157 f15 text,
158 f16 text,
159 f17 text,
160 f18 text,
161 f19 text,
162 f20 text
163)}
drh1b6a71f2000-05-29 23:58:11 +0000164do_test table-3.1 {
drhb24fcbe2000-05-29 23:30:50 +0000165 execsql $big_table
drhadbca9c2001-09-27 15:11:53 +0000166 execsql {SELECT sql FROM sqlite_master WHERE type=='table'}
drhb24fcbe2000-05-29 23:30:50 +0000167} \{$big_table\}
drh1b6a71f2000-05-29 23:58:11 +0000168do_test table-3.2 {
drhb24fcbe2000-05-29 23:30:50 +0000169 set v [catch {execsql {CREATE TABLE BIG(xyz foo)}} msg]
170 lappend v $msg
drh1d37e282000-05-30 03:12:21 +0000171} {1 {table BIG already exists}}
drh1b6a71f2000-05-29 23:58:11 +0000172do_test table-3.3 {
drhb24fcbe2000-05-29 23:30:50 +0000173 set v [catch {execsql {CREATE TABLE biG(xyz foo)}} msg]
174 lappend v $msg
drh1d37e282000-05-30 03:12:21 +0000175} {1 {table biG already exists}}
drh1b6a71f2000-05-29 23:58:11 +0000176do_test table-3.4 {
drhb24fcbe2000-05-29 23:30:50 +0000177 set v [catch {execsql {CREATE TABLE bIg(xyz foo)}} msg]
178 lappend v $msg
drh1d37e282000-05-30 03:12:21 +0000179} {1 {table bIg already exists}}
drh1b6a71f2000-05-29 23:58:11 +0000180do_test table-3.5 {
drhb24fcbe2000-05-29 23:30:50 +0000181 db close
drhef4ac8f2004-06-19 00:16:31 +0000182 sqlite3 db test.db
drhb24fcbe2000-05-29 23:30:50 +0000183 set v [catch {execsql {CREATE TABLE Big(xyz foo)}} msg]
184 lappend v $msg
drh1d37e282000-05-30 03:12:21 +0000185} {1 {table Big already exists}}
drh1b6a71f2000-05-29 23:58:11 +0000186do_test table-3.6 {
drhb24fcbe2000-05-29 23:30:50 +0000187 execsql {DROP TABLE big}
drh28037572000-08-02 13:47:41 +0000188 execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
drhb24fcbe2000-05-29 23:30:50 +0000189} {}
190
191# Try creating large numbers of tables
192#
193set r {}
194for {set i 1} {$i<=100} {incr i} {
drha9e99ae2002-08-13 23:02:57 +0000195 lappend r [format test%03d $i]
drhb24fcbe2000-05-29 23:30:50 +0000196}
drh1b6a71f2000-05-29 23:58:11 +0000197do_test table-4.1 {
drhb24fcbe2000-05-29 23:30:50 +0000198 for {set i 1} {$i<=100} {incr i} {
drha9e99ae2002-08-13 23:02:57 +0000199 set sql "CREATE TABLE [format test%03d $i] ("
drhb24fcbe2000-05-29 23:30:50 +0000200 for {set k 1} {$k<$i} {incr k} {
201 append sql "field$k text,"
202 }
203 append sql "last_field text)"
204 execsql $sql
205 }
drh28037572000-08-02 13:47:41 +0000206 execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
drhb24fcbe2000-05-29 23:30:50 +0000207} $r
drh1b6a71f2000-05-29 23:58:11 +0000208do_test table-4.1b {
drhb24fcbe2000-05-29 23:30:50 +0000209 db close
drhef4ac8f2004-06-19 00:16:31 +0000210 sqlite3 db test.db
drh28037572000-08-02 13:47:41 +0000211 execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
drhb24fcbe2000-05-29 23:30:50 +0000212} $r
213
drhc4a3c772001-04-04 11:48:57 +0000214# Drop the even numbered tables
drhb24fcbe2000-05-29 23:30:50 +0000215#
216set r {}
217for {set i 1} {$i<=100} {incr i 2} {
drha9e99ae2002-08-13 23:02:57 +0000218 lappend r [format test%03d $i]
drhb24fcbe2000-05-29 23:30:50 +0000219}
drh1b6a71f2000-05-29 23:58:11 +0000220do_test table-4.2 {
drhb24fcbe2000-05-29 23:30:50 +0000221 for {set i 2} {$i<=100} {incr i 2} {
drh428ae8c2003-01-04 16:48:09 +0000222 # if {$i==38} {execsql {pragma vdbe_trace=on}}
drha9e99ae2002-08-13 23:02:57 +0000223 set sql "DROP TABLE [format TEST%03d $i]"
drhb24fcbe2000-05-29 23:30:50 +0000224 execsql $sql
225 }
drh28037572000-08-02 13:47:41 +0000226 execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
drhb24fcbe2000-05-29 23:30:50 +0000227} $r
drh3fc190c2001-09-14 03:24:23 +0000228#exit
drhb24fcbe2000-05-29 23:30:50 +0000229
230# Drop the odd number tables
231#
drh1b6a71f2000-05-29 23:58:11 +0000232do_test table-4.3 {
drhb24fcbe2000-05-29 23:30:50 +0000233 for {set i 1} {$i<=100} {incr i 2} {
drha9e99ae2002-08-13 23:02:57 +0000234 set sql "DROP TABLE [format test%03d $i]"
drhb24fcbe2000-05-29 23:30:50 +0000235 execsql $sql
236 }
drh28037572000-08-02 13:47:41 +0000237 execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
drhb24fcbe2000-05-29 23:30:50 +0000238} {}
239
drh1b6a71f2000-05-29 23:58:11 +0000240# Try to drop a table that does not exist
241#
242do_test table-5.1 {
drha9e99ae2002-08-13 23:02:57 +0000243 set v [catch {execsql {DROP TABLE test009}} msg]
drh1b6a71f2000-05-29 23:58:11 +0000244 lappend v $msg
drha9e99ae2002-08-13 23:02:57 +0000245} {1 {no such table: test009}}
drh1b6a71f2000-05-29 23:58:11 +0000246
247# Try to drop sqlite_master
248#
249do_test table-5.2 {
250 set v [catch {execsql {DROP TABLE sqlite_master}} msg]
251 lappend v $msg
drh1d37e282000-05-30 03:12:21 +0000252} {1 {table sqlite_master may not be dropped}}
drh1b6a71f2000-05-29 23:58:11 +0000253
254# Make sure an EXPLAIN does not really create a new table
255#
256do_test table-5.3 {
drh6bf89572004-11-03 16:27:01 +0000257 ifcapable {explain} {
258 execsql {EXPLAIN CREATE TABLE test1(f1 int)}
259 }
drh28037572000-08-02 13:47:41 +0000260 execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
drh1b6a71f2000-05-29 23:58:11 +0000261} {}
262
263# Make sure an EXPLAIN does not really drop an existing table
264#
265do_test table-5.4 {
266 execsql {CREATE TABLE test1(f1 int)}
drh6bf89572004-11-03 16:27:01 +0000267 ifcapable {explain} {
268 execsql {EXPLAIN DROP TABLE test1}
269 }
drh28037572000-08-02 13:47:41 +0000270 execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
drh1b6a71f2000-05-29 23:58:11 +0000271} {test1}
272
drh4cfa7932000-06-08 15:10:46 +0000273# Create a table with a goofy name
274#
drh3fc190c2001-09-14 03:24:23 +0000275#do_test table-6.1 {
276# execsql {CREATE TABLE 'Spaces In This Name!'(x int)}
277# execsql {INSERT INTO 'spaces in this name!' VALUES(1)}
278# set list [glob -nocomplain testdb/spaces*.tbl]
279#} {testdb/spaces+in+this+name+.tbl}
drh4cfa7932000-06-08 15:10:46 +0000280
drhc4a3c772001-04-04 11:48:57 +0000281# Try using keywords as table names or column names.
282#
283do_test table-7.1 {
284 set v [catch {execsql {
285 CREATE TABLE weird(
286 desc text,
287 asc text,
drh6bf89572004-11-03 16:27:01 +0000288 key int,
drh17f71932002-02-21 12:01:27 +0000289 [14_vac] boolean,
290 fuzzy_dog_12 varchar(10),
drhd4007282001-04-12 23:21:58 +0000291 begin blob,
292 end clob
drhc4a3c772001-04-04 11:48:57 +0000293 )
294 }} msg]
295 lappend v $msg
296} {0 {}}
297do_test table-7.2 {
298 execsql {
drhd4007282001-04-12 23:21:58 +0000299 INSERT INTO weird VALUES('a','b',9,0,'xyz','hi','y''all');
drhc4a3c772001-04-04 11:48:57 +0000300 SELECT * FROM weird;
301 }
drhd4007282001-04-12 23:21:58 +0000302} {a b 9 0 xyz hi y'all}
drhc4a3c772001-04-04 11:48:57 +0000303do_test table-7.3 {
304 execsql2 {
305 SELECT * FROM weird;
306 }
drh6bf89572004-11-03 16:27:01 +0000307} {desc a asc b key 9 14_vac 0 fuzzy_dog_12 xyz begin hi end y'all}
drhc4a3c772001-04-04 11:48:57 +0000308
drh969fa7c2002-02-18 18:30:32 +0000309# Try out the CREATE TABLE AS syntax
310#
311do_test table-8.1 {
312 execsql2 {
313 CREATE TABLE t2 AS SELECT * FROM weird;
314 SELECT * FROM t2;
315 }
drh6bf89572004-11-03 16:27:01 +0000316} {desc a asc b key 9 14_vac 0 fuzzy_dog_12 xyz begin hi end y'all}
drh17f71932002-02-21 12:01:27 +0000317do_test table-8.1.1 {
318 execsql {
319 SELECT sql FROM sqlite_master WHERE name='t2';
320 }
321} {{CREATE TABLE t2(
drh234c39d2004-07-24 03:30:47 +0000322 "desc" text,
323 "asc" text,
drh6bf89572004-11-03 16:27:01 +0000324 "key" int,
drh234c39d2004-07-24 03:30:47 +0000325 "14_vac" boolean,
danielk1977517eb642004-06-07 10:00:31 +0000326 fuzzy_dog_12 varchar(10),
drh234c39d2004-07-24 03:30:47 +0000327 "begin" blob,
328 "end" clob
drh17f71932002-02-21 12:01:27 +0000329)}}
drh969fa7c2002-02-18 18:30:32 +0000330do_test table-8.2 {
331 execsql {
drh234c39d2004-07-24 03:30:47 +0000332 CREATE TABLE "t3""xyz"(a,b,c);
333 INSERT INTO [t3"xyz] VALUES(1,2,3);
334 SELECT * FROM [t3"xyz];
drh969fa7c2002-02-18 18:30:32 +0000335 }
336} {1 2 3}
337do_test table-8.3 {
338 execsql2 {
drh234c39d2004-07-24 03:30:47 +0000339 CREATE TABLE [t4"abc] AS SELECT count(*) as cnt, max(b+c) FROM [t3"xyz];
340 SELECT * FROM [t4"abc];
drh969fa7c2002-02-18 18:30:32 +0000341 }
drh17f71932002-02-21 12:01:27 +0000342} {cnt 1 max(b+c) 5}
danielk197700e279d2004-06-21 07:36:32 +0000343
344# Update for v3: The declaration type of anything except a column is now a
345# NULL pointer, so the created table has no column types. (Changed result
drh234c39d2004-07-24 03:30:47 +0000346# from {{CREATE TABLE 't4"abc'(cnt NUMERIC,"max(b+c)" NUMERIC)}}).
drh17f71932002-02-21 12:01:27 +0000347do_test table-8.3.1 {
348 execsql {
drh234c39d2004-07-24 03:30:47 +0000349 SELECT sql FROM sqlite_master WHERE name='t4"abc'
drh17f71932002-02-21 12:01:27 +0000350 }
drh234c39d2004-07-24 03:30:47 +0000351} {{CREATE TABLE "t4""abc"(cnt,"max(b+c)")}}
drh969fa7c2002-02-18 18:30:32 +0000352do_test table-8.4 {
353 execsql2 {
drh234c39d2004-07-24 03:30:47 +0000354 CREATE TEMPORARY TABLE t5 AS SELECT count(*) AS [y'all] FROM [t3"xyz];
drh969fa7c2002-02-18 18:30:32 +0000355 SELECT * FROM t5;
356 }
357} {y'all 1}
358do_test table-8.5 {
359 db close
drhef4ac8f2004-06-19 00:16:31 +0000360 sqlite3 db test.db
drh969fa7c2002-02-18 18:30:32 +0000361 execsql2 {
drh234c39d2004-07-24 03:30:47 +0000362 SELECT * FROM [t4"abc];
drh969fa7c2002-02-18 18:30:32 +0000363 }
drh17f71932002-02-21 12:01:27 +0000364} {cnt 1 max(b+c) 5}
drh969fa7c2002-02-18 18:30:32 +0000365do_test table-8.6 {
366 execsql2 {
367 SELECT * FROM t2;
368 }
drh6bf89572004-11-03 16:27:01 +0000369} {desc a asc b key 9 14_vac 0 fuzzy_dog_12 xyz begin hi end y'all}
drh969fa7c2002-02-18 18:30:32 +0000370do_test table-8.7 {
371 catchsql {
372 SELECT * FROM t5;
373 }
374} {1 {no such table: t5}}
drh17f71932002-02-21 12:01:27 +0000375do_test table-8.8 {
376 catchsql {
377 CREATE TABLE t5 AS SELECT * FROM no_such_table;
378 }
379} {1 {no such table: no_such_table}}
drh969fa7c2002-02-18 18:30:32 +0000380
drh97fc3d02002-05-22 21:27:03 +0000381# Make sure we cannot have duplicate column names within a table.
382#
383do_test table-9.1 {
384 catchsql {
385 CREATE TABLE t6(a,b,a);
386 }
387} {1 {duplicate column name: a}}
388
drh04738cb2002-06-02 18:19:00 +0000389# Check the foreign key syntax.
390#
drh6bf89572004-11-03 16:27:01 +0000391ifcapable {foreignkey} {
drh04738cb2002-06-02 18:19:00 +0000392do_test table-10.1 {
393 catchsql {
394 CREATE TABLE t6(a REFERENCES t4(a) NOT NULL);
395 INSERT INTO t6 VALUES(NULL);
396 }
drh483750b2003-01-29 18:46:51 +0000397} {1 {t6.a may not be NULL}}
drh04738cb2002-06-02 18:19:00 +0000398do_test table-10.2 {
399 catchsql {
400 DROP TABLE t6;
401 CREATE TABLE t6(a REFERENCES t4(a) MATCH PARTIAL);
402 }
403} {0 {}}
404do_test table-10.3 {
405 catchsql {
406 DROP TABLE t6;
407 CREATE TABLE t6(a REFERENCES t4 MATCH FULL ON DELETE SET NULL NOT NULL);
408 }
409} {0 {}}
410do_test table-10.4 {
411 catchsql {
412 DROP TABLE t6;
413 CREATE TABLE t6(a REFERENCES t4 MATCH FULL ON UPDATE SET DEFAULT DEFAULT 1);
414 }
415} {0 {}}
416do_test table-10.5 {
417 catchsql {
418 DROP TABLE t6;
419 CREATE TABLE t6(a NOT NULL NOT DEFERRABLE INITIALLY IMMEDIATE);
420 }
421} {0 {}}
422do_test table-10.6 {
423 catchsql {
424 DROP TABLE t6;
425 CREATE TABLE t6(a NOT NULL DEFERRABLE INITIALLY DEFERRED);
426 }
427} {0 {}}
428do_test table-10.7 {
429 catchsql {
430 DROP TABLE t6;
431 CREATE TABLE t6(a,
432 FOREIGN KEY (a) REFERENCES t4(b) DEFERRABLE INITIALLY DEFERRED
433 );
434 }
435} {0 {}}
436do_test table-10.8 {
437 catchsql {
438 DROP TABLE t6;
439 CREATE TABLE t6(a,b,c,
440 FOREIGN KEY (b,c) REFERENCES t4(x,y) MATCH PARTIAL
441 ON UPDATE SET NULL ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED
442 );
443 }
444} {0 {}}
drhc2eef3b2002-08-31 18:53:06 +0000445do_test table-10.9 {
446 catchsql {
447 DROP TABLE t6;
448 CREATE TABLE t6(a,b,c,
449 FOREIGN KEY (b,c) REFERENCES t4(x)
450 );
451 }
452} {1 {number of columns in foreign key does not match the number of columns in the referenced table}}
453do_test table-10.10 {
454 catchsql {DROP TABLE t6}
455 catchsql {
456 CREATE TABLE t6(a,b,c,
457 FOREIGN KEY (b,c) REFERENCES t4(x,y,z)
458 );
459 }
460} {1 {number of columns in foreign key does not match the number of columns in the referenced table}}
461do_test table-10.11 {
462 catchsql {DROP TABLE t6}
463 catchsql {
464 CREATE TABLE t6(a,b, c REFERENCES t4(x,y));
465 }
466} {1 {foreign key on c should reference only one column of table t4}}
467do_test table-10.12 {
468 catchsql {DROP TABLE t6}
469 catchsql {
470 CREATE TABLE t6(a,b,c,
471 FOREIGN KEY (b,x) REFERENCES t4(x,y)
472 );
473 }
474} {1 {unknown column "x" in foreign key definition}}
475do_test table-10.13 {
476 catchsql {DROP TABLE t6}
477 catchsql {
478 CREATE TABLE t6(a,b,c,
479 FOREIGN KEY (x,b) REFERENCES t4(x,y)
480 );
481 }
482} {1 {unknown column "x" in foreign key definition}}
drh6bf89572004-11-03 16:27:01 +0000483} ;# endif foreignkey
drh04738cb2002-06-02 18:19:00 +0000484
danielk197735bb9d02004-05-24 12:55:54 +0000485# Test for the "typeof" function. More tests for the
486# typeof() function are found in bind.test and types.test.
drh38640e12002-07-05 21:42:36 +0000487#
488do_test table-11.1 {
489 execsql {
490 CREATE TABLE t7(
491 a integer primary key,
492 b number(5,10),
493 c character varying (8),
494 d VARCHAR(9),
495 e clob,
496 f BLOB,
497 g Text,
498 h
499 );
500 INSERT INTO t7(a) VALUES(1);
501 SELECT typeof(a), typeof(b), typeof(c), typeof(d),
502 typeof(e), typeof(f), typeof(g), typeof(h)
503 FROM t7 LIMIT 1;
504 }
danielk197735bb9d02004-05-24 12:55:54 +0000505} {integer null null null null null null null}
drh38640e12002-07-05 21:42:36 +0000506do_test table-11.2 {
507 execsql {
508 SELECT typeof(a+b), typeof(a||b), typeof(c+d), typeof(c||d)
509 FROM t7 LIMIT 1;
510 }
danielk197735bb9d02004-05-24 12:55:54 +0000511} {null null null null}
drh97fc3d02002-05-22 21:27:03 +0000512
danielk197700e279d2004-06-21 07:36:32 +0000513# Test that when creating a table using CREATE TABLE AS, column types are
514# assigned correctly for (SELECT ...) and 'x AS y' expressions.
515do_test table-12.1 {
danielk19773e8c37e2005-01-21 03:12:14 +0000516 ifcapable subquery {
517 execsql {
518 CREATE TABLE t8 AS SELECT b, h, a as i, (SELECT f FROM t7) as j FROM t7;
519 }
520 } else {
521 execsql {
522 CREATE TABLE t8 AS SELECT b, h, a as i, f as j FROM t7;
523 }
danielk197700e279d2004-06-21 07:36:32 +0000524 }
525} {}
526do_test table-12.2 {
527 execsql {
528 SELECT sql FROM sqlite_master WHERE tbl_name = 't8'
529 }
530} {{CREATE TABLE t8(b number(5,10),h,i integer,j BLOB)}}
531
danielk1977e6efa742004-11-10 11:55:10 +0000532#--------------------------------------------------------------------
533# Test cases table-13.*
534#
danielk19777977a172004-11-09 12:44:37 +0000535# Test the ability to have default values of CURRENT_TIME, CURRENT_DATE
536# and CURRENT_TIMESTAMP.
537#
538do_test table-13.1 {
539 execsql {
540 CREATE TABLE tablet8(
541 a integer primary key,
542 tm text DEFAULT CURRENT_TIME,
543 dt text DEFAULT CURRENT_DATE,
544 dttm text DEFAULT CURRENT_TIMESTAMP
545 );
546 SELECT * FROM tablet8;
547 }
548} {}
549set i 0
550foreach {date time} {
551 1976-07-04 12:00:00
552 1994-04-16 14:00:00
553 2000-01-01 00:00:00
554 2003-12-31 12:34:56
555} {
556 incr i
danielk1977e6efa742004-11-10 11:55:10 +0000557 set sqlite_current_time [clock scan "$date $time" -gmt 1]
558 # set sqlite_current_time [execsql "SELECT strftime('%s','$date $time')"]
danielk19777977a172004-11-09 12:44:37 +0000559 do_test table-13.2.$i {
560 execsql "
561 INSERT INTO tablet8(a) VALUES($i);
562 SELECT tm, dt, dttm FROM tablet8 WHERE a=$i;
563 "
564 } [list $time $date [list $date $time]]
565}
566set sqlite_current_time 0
567
danielk1977e6efa742004-11-10 11:55:10 +0000568#--------------------------------------------------------------------
569# Test cases table-14.*
570#
571# Test that a table cannot be created or dropped while other virtual
572# machines are active. This is required because otherwise when in
573# auto-vacuum mode the btree-layer may need to move the root-pages of
574# a table for which there is an open cursor.
575#
576
577# Try to create a table from within a callback:
drh251b0672004-11-23 22:16:39 +0000578unset -nocomplain result
danielk1977e6efa742004-11-10 11:55:10 +0000579do_test table-14.1 {
580 set rc [
581 catch {
582 db eval {SELECT * FROM tablet8 LIMIT 1} {} {
583 db eval {CREATE TABLE t9(a, b, c)}
584 }
585 } msg
586 ]
587 set result [list $rc $msg]
588} {1 {database table is locked}}
589
590do_test table-14.2 {
591 execsql {
592 CREATE TABLE t9(a, b, c)
593 }
594} {}
595
596# Try to drop a table from within a callback:
597do_test table-14.3 {
598 set rc [
599 catch {
600 db eval {SELECT * FROM tablet8 LIMIT 1} {} {
601 db eval {DROP TABLE t9;}
602 }
603 } msg
604 ]
605 set result [list $rc $msg]
606} {1 {database table is locked}}
607
608# Now attach a database and ensure that a table can be created in the
609# attached database whilst in a callback from a query on the main database.
610do_test table-14.4 {
611 file delete -force test2.db
612 file delete -force test2.db-journal
613 execsql {
614 attach 'test2.db' as aux;
615 }
616 db eval {SELECT * FROM tablet8 LIMIT 1} {} {
617 db eval {CREATE TABLE aux.t1(a, b, c)}
618 }
619} {}
620
621# On the other hand, it should be impossible to drop a table when any VMs
622# are active. This is because VerifyCookie instructions may have already
623# been executed, and btree root-pages may not move after this (which a
624# delete table might do).
625do_test table-14.4 {
626 set rc [
627 catch {
628 db eval {SELECT * FROM tablet8 LIMIT 1} {} {
629 db eval {DROP TABLE aux.t1;}
630 }
631 } msg
632 ]
633 set result [list $rc $msg]
634} {1 {database table is locked}}
635
danielk1977ae825582004-11-23 09:06:55 +0000636# Create and drop 2000 tables. This is to check that the balance_shallow()
637# routine works correctly on the sqlite_master table. At one point it
638# contained a bug that would prevent the right-child pointer of the
639# child page from being copied to the root page.
640#
641do_test table-15.1 {
642 execsql {BEGIN}
643 for {set i 0} {$i<2000} {incr i} {
644 execsql "CREATE TABLE tbl$i (a, b, c)"
645 }
646 execsql {COMMIT}
647} {}
648do_test table-15.2 {
649 execsql {BEGIN}
650 for {set i 0} {$i<2000} {incr i} {
651 execsql "DROP TABLE tbl$i"
652 }
653 execsql {COMMIT}
654} {}
655
drh348784e2000-05-29 20:41:49 +0000656finish_test