blob: 1817105a625140130d620edf4d0aa02dd4e34c3a [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#
drhd8919672005-09-10 15:35:06 +000014# $Id: table.test,v 1.41 2005/09/10 15:35:07 drh 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)}
drh42b9d7c2005-08-13 00:56:27 +000093 catchsql {CREATE TABLE test2(two text default 'hi')}
drh1d37e282000-05-30 03:12:21 +000094} {1 {table test2 already exists}}
drh1b6a71f2000-05-29 23:58:11 +000095do_test table-2.1b {
drhb24fcbe2000-05-29 23:30:50 +000096 set v [catch {execsql {CREATE TABLE sqlite_master(two text)}} msg]
97 lappend v $msg
danielk1977d8123362004-06-12 09:25:12 +000098} {1 {object name reserved for internal use: sqlite_master}}
drh1b6a71f2000-05-29 23:58:11 +000099do_test table-2.1c {
drhb24fcbe2000-05-29 23:30:50 +0000100 db close
drhef4ac8f2004-06-19 00:16:31 +0000101 sqlite3 db test.db
drhb24fcbe2000-05-29 23:30:50 +0000102 set v [catch {execsql {CREATE TABLE sqlite_master(two text)}} msg]
103 lappend v $msg
danielk1977d8123362004-06-12 09:25:12 +0000104} {1 {object name reserved for internal use: sqlite_master}}
drh1b6a71f2000-05-29 23:58:11 +0000105do_test table-2.1d {
drh28037572000-08-02 13:47:41 +0000106 execsql {DROP TABLE test2; SELECT name FROM sqlite_master WHERE type!='meta'}
drhb24fcbe2000-05-29 23:30:50 +0000107} {}
108
109# Verify that we cannot make a table with the same name as an index
110#
drhdcc581c2000-05-30 13:44:19 +0000111do_test table-2.2a {
drhb24fcbe2000-05-29 23:30:50 +0000112 execsql {CREATE TABLE test2(one text); CREATE INDEX test3 ON test2(one)}
113 set v [catch {execsql {CREATE TABLE test3(two text)}} msg]
114 lappend v $msg
drh1d37e282000-05-30 03:12:21 +0000115} {1 {there is already an index named test3}}
drh1b6a71f2000-05-29 23:58:11 +0000116do_test table-2.2b {
drhb24fcbe2000-05-29 23:30:50 +0000117 db close
drhef4ac8f2004-06-19 00:16:31 +0000118 sqlite3 db test.db
drhb24fcbe2000-05-29 23:30:50 +0000119 set v [catch {execsql {CREATE TABLE test3(two text)}} msg]
120 lappend v $msg
drh1d37e282000-05-30 03:12:21 +0000121} {1 {there is already an index named test3}}
drh1b6a71f2000-05-29 23:58:11 +0000122do_test table-2.2c {
drh3fc190c2001-09-14 03:24:23 +0000123 execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
124} {test2 test3}
125do_test table-2.2d {
drhb24fcbe2000-05-29 23:30:50 +0000126 execsql {DROP INDEX test3}
127 set v [catch {execsql {CREATE TABLE test3(two text)}} msg]
128 lappend v $msg
129} {0 {}}
drh3fc190c2001-09-14 03:24:23 +0000130do_test table-2.2e {
drh28037572000-08-02 13:47:41 +0000131 execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
drhb24fcbe2000-05-29 23:30:50 +0000132} {test2 test3}
drh3fc190c2001-09-14 03:24:23 +0000133do_test table-2.2f {
drhb24fcbe2000-05-29 23:30:50 +0000134 execsql {DROP TABLE test2; DROP TABLE test3}
drh28037572000-08-02 13:47:41 +0000135 execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
drhb24fcbe2000-05-29 23:30:50 +0000136} {}
137
138# Create a table with many field names
139#
140set big_table \
141{CREATE TABLE big(
142 f1 varchar(20),
143 f2 char(10),
drhdcc581c2000-05-30 13:44:19 +0000144 f3 varchar(30) primary key,
drhb24fcbe2000-05-29 23:30:50 +0000145 f4 text,
146 f5 text,
147 f6 text,
148 f7 text,
149 f8 text,
150 f9 text,
151 f10 text,
152 f11 text,
153 f12 text,
154 f13 text,
155 f14 text,
156 f15 text,
157 f16 text,
158 f17 text,
159 f18 text,
160 f19 text,
161 f20 text
162)}
drh1b6a71f2000-05-29 23:58:11 +0000163do_test table-3.1 {
drhb24fcbe2000-05-29 23:30:50 +0000164 execsql $big_table
drhadbca9c2001-09-27 15:11:53 +0000165 execsql {SELECT sql FROM sqlite_master WHERE type=='table'}
drhb24fcbe2000-05-29 23:30:50 +0000166} \{$big_table\}
drh1b6a71f2000-05-29 23:58:11 +0000167do_test table-3.2 {
drhb24fcbe2000-05-29 23:30:50 +0000168 set v [catch {execsql {CREATE TABLE BIG(xyz foo)}} msg]
169 lappend v $msg
drh1d37e282000-05-30 03:12:21 +0000170} {1 {table BIG already exists}}
drh1b6a71f2000-05-29 23:58:11 +0000171do_test table-3.3 {
drhb24fcbe2000-05-29 23:30:50 +0000172 set v [catch {execsql {CREATE TABLE biG(xyz foo)}} msg]
173 lappend v $msg
drh1d37e282000-05-30 03:12:21 +0000174} {1 {table biG already exists}}
drh1b6a71f2000-05-29 23:58:11 +0000175do_test table-3.4 {
drhb24fcbe2000-05-29 23:30:50 +0000176 set v [catch {execsql {CREATE TABLE bIg(xyz foo)}} msg]
177 lappend v $msg
drh1d37e282000-05-30 03:12:21 +0000178} {1 {table bIg already exists}}
drh1b6a71f2000-05-29 23:58:11 +0000179do_test table-3.5 {
drhb24fcbe2000-05-29 23:30:50 +0000180 db close
drhef4ac8f2004-06-19 00:16:31 +0000181 sqlite3 db test.db
drhb24fcbe2000-05-29 23:30:50 +0000182 set v [catch {execsql {CREATE TABLE Big(xyz foo)}} msg]
183 lappend v $msg
drh1d37e282000-05-30 03:12:21 +0000184} {1 {table Big already exists}}
drh1b6a71f2000-05-29 23:58:11 +0000185do_test table-3.6 {
drhb24fcbe2000-05-29 23:30:50 +0000186 execsql {DROP TABLE big}
drh28037572000-08-02 13:47:41 +0000187 execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
drhb24fcbe2000-05-29 23:30:50 +0000188} {}
189
190# Try creating large numbers of tables
191#
192set r {}
193for {set i 1} {$i<=100} {incr i} {
drha9e99ae2002-08-13 23:02:57 +0000194 lappend r [format test%03d $i]
drhb24fcbe2000-05-29 23:30:50 +0000195}
drh1b6a71f2000-05-29 23:58:11 +0000196do_test table-4.1 {
drhb24fcbe2000-05-29 23:30:50 +0000197 for {set i 1} {$i<=100} {incr i} {
drha9e99ae2002-08-13 23:02:57 +0000198 set sql "CREATE TABLE [format test%03d $i] ("
drhb24fcbe2000-05-29 23:30:50 +0000199 for {set k 1} {$k<$i} {incr k} {
200 append sql "field$k text,"
201 }
202 append sql "last_field text)"
203 execsql $sql
204 }
drh28037572000-08-02 13:47:41 +0000205 execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
drhb24fcbe2000-05-29 23:30:50 +0000206} $r
drh1b6a71f2000-05-29 23:58:11 +0000207do_test table-4.1b {
drhb24fcbe2000-05-29 23:30:50 +0000208 db close
drhef4ac8f2004-06-19 00:16:31 +0000209 sqlite3 db test.db
drh28037572000-08-02 13:47:41 +0000210 execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
drhb24fcbe2000-05-29 23:30:50 +0000211} $r
212
drhc4a3c772001-04-04 11:48:57 +0000213# Drop the even numbered tables
drhb24fcbe2000-05-29 23:30:50 +0000214#
215set r {}
216for {set i 1} {$i<=100} {incr i 2} {
drha9e99ae2002-08-13 23:02:57 +0000217 lappend r [format test%03d $i]
drhb24fcbe2000-05-29 23:30:50 +0000218}
drh1b6a71f2000-05-29 23:58:11 +0000219do_test table-4.2 {
drhb24fcbe2000-05-29 23:30:50 +0000220 for {set i 2} {$i<=100} {incr i 2} {
drh428ae8c2003-01-04 16:48:09 +0000221 # if {$i==38} {execsql {pragma vdbe_trace=on}}
drha9e99ae2002-08-13 23:02:57 +0000222 set sql "DROP TABLE [format TEST%03d $i]"
drhb24fcbe2000-05-29 23:30:50 +0000223 execsql $sql
224 }
drh28037572000-08-02 13:47:41 +0000225 execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
drhb24fcbe2000-05-29 23:30:50 +0000226} $r
drh3fc190c2001-09-14 03:24:23 +0000227#exit
drhb24fcbe2000-05-29 23:30:50 +0000228
229# Drop the odd number tables
230#
drh1b6a71f2000-05-29 23:58:11 +0000231do_test table-4.3 {
drhb24fcbe2000-05-29 23:30:50 +0000232 for {set i 1} {$i<=100} {incr i 2} {
drha9e99ae2002-08-13 23:02:57 +0000233 set sql "DROP TABLE [format test%03d $i]"
drhb24fcbe2000-05-29 23:30:50 +0000234 execsql $sql
235 }
drh28037572000-08-02 13:47:41 +0000236 execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
drhb24fcbe2000-05-29 23:30:50 +0000237} {}
238
drh1b6a71f2000-05-29 23:58:11 +0000239# Try to drop a table that does not exist
240#
241do_test table-5.1 {
drha9e99ae2002-08-13 23:02:57 +0000242 set v [catch {execsql {DROP TABLE test009}} msg]
drh1b6a71f2000-05-29 23:58:11 +0000243 lappend v $msg
drha9e99ae2002-08-13 23:02:57 +0000244} {1 {no such table: test009}}
drh1b6a71f2000-05-29 23:58:11 +0000245
246# Try to drop sqlite_master
247#
248do_test table-5.2 {
249 set v [catch {execsql {DROP TABLE sqlite_master}} msg]
250 lappend v $msg
drh1d37e282000-05-30 03:12:21 +0000251} {1 {table sqlite_master may not be dropped}}
drh1b6a71f2000-05-29 23:58:11 +0000252
253# Make sure an EXPLAIN does not really create a new table
254#
255do_test table-5.3 {
drh6bf89572004-11-03 16:27:01 +0000256 ifcapable {explain} {
257 execsql {EXPLAIN CREATE TABLE test1(f1 int)}
258 }
drh28037572000-08-02 13:47:41 +0000259 execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
drh1b6a71f2000-05-29 23:58:11 +0000260} {}
261
262# Make sure an EXPLAIN does not really drop an existing table
263#
264do_test table-5.4 {
265 execsql {CREATE TABLE test1(f1 int)}
drh6bf89572004-11-03 16:27:01 +0000266 ifcapable {explain} {
267 execsql {EXPLAIN DROP TABLE test1}
268 }
drh28037572000-08-02 13:47:41 +0000269 execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
drh1b6a71f2000-05-29 23:58:11 +0000270} {test1}
271
drh4cfa7932000-06-08 15:10:46 +0000272# Create a table with a goofy name
273#
drh3fc190c2001-09-14 03:24:23 +0000274#do_test table-6.1 {
275# execsql {CREATE TABLE 'Spaces In This Name!'(x int)}
276# execsql {INSERT INTO 'spaces in this name!' VALUES(1)}
277# set list [glob -nocomplain testdb/spaces*.tbl]
278#} {testdb/spaces+in+this+name+.tbl}
drh4cfa7932000-06-08 15:10:46 +0000279
drhc4a3c772001-04-04 11:48:57 +0000280# Try using keywords as table names or column names.
281#
282do_test table-7.1 {
283 set v [catch {execsql {
284 CREATE TABLE weird(
285 desc text,
286 asc text,
drh6bf89572004-11-03 16:27:01 +0000287 key int,
drh17f71932002-02-21 12:01:27 +0000288 [14_vac] boolean,
289 fuzzy_dog_12 varchar(10),
drhd4007282001-04-12 23:21:58 +0000290 begin blob,
291 end clob
drhc4a3c772001-04-04 11:48:57 +0000292 )
293 }} msg]
294 lappend v $msg
295} {0 {}}
296do_test table-7.2 {
297 execsql {
drhd4007282001-04-12 23:21:58 +0000298 INSERT INTO weird VALUES('a','b',9,0,'xyz','hi','y''all');
drhc4a3c772001-04-04 11:48:57 +0000299 SELECT * FROM weird;
300 }
drhd4007282001-04-12 23:21:58 +0000301} {a b 9 0 xyz hi y'all}
drhc4a3c772001-04-04 11:48:57 +0000302do_test table-7.3 {
303 execsql2 {
304 SELECT * FROM weird;
305 }
drh6bf89572004-11-03 16:27:01 +0000306} {desc a asc b key 9 14_vac 0 fuzzy_dog_12 xyz begin hi end y'all}
drhc4a3c772001-04-04 11:48:57 +0000307
drh969fa7c2002-02-18 18:30:32 +0000308# Try out the CREATE TABLE AS syntax
309#
310do_test table-8.1 {
311 execsql2 {
312 CREATE TABLE t2 AS SELECT * FROM weird;
313 SELECT * FROM t2;
314 }
drh6bf89572004-11-03 16:27:01 +0000315} {desc a asc b key 9 14_vac 0 fuzzy_dog_12 xyz begin hi end y'all}
drh17f71932002-02-21 12:01:27 +0000316do_test table-8.1.1 {
317 execsql {
318 SELECT sql FROM sqlite_master WHERE name='t2';
319 }
320} {{CREATE TABLE t2(
drh234c39d2004-07-24 03:30:47 +0000321 "desc" text,
322 "asc" text,
drh6bf89572004-11-03 16:27:01 +0000323 "key" int,
drh234c39d2004-07-24 03:30:47 +0000324 "14_vac" boolean,
danielk1977517eb642004-06-07 10:00:31 +0000325 fuzzy_dog_12 varchar(10),
drh234c39d2004-07-24 03:30:47 +0000326 "begin" blob,
327 "end" clob
drh17f71932002-02-21 12:01:27 +0000328)}}
drh969fa7c2002-02-18 18:30:32 +0000329do_test table-8.2 {
330 execsql {
drh234c39d2004-07-24 03:30:47 +0000331 CREATE TABLE "t3""xyz"(a,b,c);
332 INSERT INTO [t3"xyz] VALUES(1,2,3);
333 SELECT * FROM [t3"xyz];
drh969fa7c2002-02-18 18:30:32 +0000334 }
335} {1 2 3}
336do_test table-8.3 {
337 execsql2 {
drh234c39d2004-07-24 03:30:47 +0000338 CREATE TABLE [t4"abc] AS SELECT count(*) as cnt, max(b+c) FROM [t3"xyz];
339 SELECT * FROM [t4"abc];
drh969fa7c2002-02-18 18:30:32 +0000340 }
drh17f71932002-02-21 12:01:27 +0000341} {cnt 1 max(b+c) 5}
danielk197700e279d2004-06-21 07:36:32 +0000342
343# Update for v3: The declaration type of anything except a column is now a
344# NULL pointer, so the created table has no column types. (Changed result
drh234c39d2004-07-24 03:30:47 +0000345# from {{CREATE TABLE 't4"abc'(cnt NUMERIC,"max(b+c)" NUMERIC)}}).
drh17f71932002-02-21 12:01:27 +0000346do_test table-8.3.1 {
347 execsql {
drh234c39d2004-07-24 03:30:47 +0000348 SELECT sql FROM sqlite_master WHERE name='t4"abc'
drh17f71932002-02-21 12:01:27 +0000349 }
drh234c39d2004-07-24 03:30:47 +0000350} {{CREATE TABLE "t4""abc"(cnt,"max(b+c)")}}
danielk197753c0f742005-03-29 03:10:59 +0000351
352ifcapable tempdb {
353 do_test table-8.4 {
354 execsql2 {
355 CREATE TEMPORARY TABLE t5 AS SELECT count(*) AS [y'all] FROM [t3"xyz];
356 SELECT * FROM t5;
357 }
358 } {y'all 1}
359}
360
drh969fa7c2002-02-18 18:30:32 +0000361do_test table-8.5 {
362 db close
drhef4ac8f2004-06-19 00:16:31 +0000363 sqlite3 db test.db
drh969fa7c2002-02-18 18:30:32 +0000364 execsql2 {
drh234c39d2004-07-24 03:30:47 +0000365 SELECT * FROM [t4"abc];
drh969fa7c2002-02-18 18:30:32 +0000366 }
drh17f71932002-02-21 12:01:27 +0000367} {cnt 1 max(b+c) 5}
drh969fa7c2002-02-18 18:30:32 +0000368do_test table-8.6 {
369 execsql2 {
370 SELECT * FROM t2;
371 }
drh6bf89572004-11-03 16:27:01 +0000372} {desc a asc b key 9 14_vac 0 fuzzy_dog_12 xyz begin hi end y'all}
drh969fa7c2002-02-18 18:30:32 +0000373do_test table-8.7 {
374 catchsql {
375 SELECT * FROM t5;
376 }
377} {1 {no such table: t5}}
drh17f71932002-02-21 12:01:27 +0000378do_test table-8.8 {
379 catchsql {
380 CREATE TABLE t5 AS SELECT * FROM no_such_table;
381 }
382} {1 {no such table: no_such_table}}
drh969fa7c2002-02-18 18:30:32 +0000383
drh97fc3d02002-05-22 21:27:03 +0000384# Make sure we cannot have duplicate column names within a table.
385#
386do_test table-9.1 {
387 catchsql {
388 CREATE TABLE t6(a,b,a);
389 }
390} {1 {duplicate column name: a}}
drhd8919672005-09-10 15:35:06 +0000391do_test table-9.2 {
392 catchsql {
393 CREATE TABLE t6(a varchar(100), b blob, a integer);
394 }
395} {1 {duplicate column name: a}}
drh97fc3d02002-05-22 21:27:03 +0000396
drh04738cb2002-06-02 18:19:00 +0000397# Check the foreign key syntax.
398#
drh6bf89572004-11-03 16:27:01 +0000399ifcapable {foreignkey} {
drh04738cb2002-06-02 18:19:00 +0000400do_test table-10.1 {
401 catchsql {
402 CREATE TABLE t6(a REFERENCES t4(a) NOT NULL);
403 INSERT INTO t6 VALUES(NULL);
404 }
drh483750b2003-01-29 18:46:51 +0000405} {1 {t6.a may not be NULL}}
drh04738cb2002-06-02 18:19:00 +0000406do_test table-10.2 {
407 catchsql {
408 DROP TABLE t6;
409 CREATE TABLE t6(a REFERENCES t4(a) MATCH PARTIAL);
410 }
411} {0 {}}
412do_test table-10.3 {
413 catchsql {
414 DROP TABLE t6;
415 CREATE TABLE t6(a REFERENCES t4 MATCH FULL ON DELETE SET NULL NOT NULL);
416 }
417} {0 {}}
418do_test table-10.4 {
419 catchsql {
420 DROP TABLE t6;
421 CREATE TABLE t6(a REFERENCES t4 MATCH FULL ON UPDATE SET DEFAULT DEFAULT 1);
422 }
423} {0 {}}
424do_test table-10.5 {
425 catchsql {
426 DROP TABLE t6;
427 CREATE TABLE t6(a NOT NULL NOT DEFERRABLE INITIALLY IMMEDIATE);
428 }
429} {0 {}}
430do_test table-10.6 {
431 catchsql {
432 DROP TABLE t6;
433 CREATE TABLE t6(a NOT NULL DEFERRABLE INITIALLY DEFERRED);
434 }
435} {0 {}}
436do_test table-10.7 {
437 catchsql {
438 DROP TABLE t6;
439 CREATE TABLE t6(a,
440 FOREIGN KEY (a) REFERENCES t4(b) DEFERRABLE INITIALLY DEFERRED
441 );
442 }
443} {0 {}}
444do_test table-10.8 {
445 catchsql {
446 DROP TABLE t6;
447 CREATE TABLE t6(a,b,c,
448 FOREIGN KEY (b,c) REFERENCES t4(x,y) MATCH PARTIAL
449 ON UPDATE SET NULL ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED
450 );
451 }
452} {0 {}}
drhc2eef3b2002-08-31 18:53:06 +0000453do_test table-10.9 {
454 catchsql {
455 DROP TABLE t6;
456 CREATE TABLE t6(a,b,c,
457 FOREIGN KEY (b,c) REFERENCES t4(x)
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.10 {
462 catchsql {DROP TABLE t6}
463 catchsql {
464 CREATE TABLE t6(a,b,c,
465 FOREIGN KEY (b,c) REFERENCES t4(x,y,z)
466 );
467 }
468} {1 {number of columns in foreign key does not match the number of columns in the referenced table}}
469do_test table-10.11 {
470 catchsql {DROP TABLE t6}
471 catchsql {
472 CREATE TABLE t6(a,b, c REFERENCES t4(x,y));
473 }
474} {1 {foreign key on c should reference only one column of table t4}}
475do_test table-10.12 {
476 catchsql {DROP TABLE t6}
477 catchsql {
478 CREATE TABLE t6(a,b,c,
479 FOREIGN KEY (b,x) REFERENCES t4(x,y)
480 );
481 }
482} {1 {unknown column "x" in foreign key definition}}
483do_test table-10.13 {
484 catchsql {DROP TABLE t6}
485 catchsql {
486 CREATE TABLE t6(a,b,c,
487 FOREIGN KEY (x,b) REFERENCES t4(x,y)
488 );
489 }
490} {1 {unknown column "x" in foreign key definition}}
drh6bf89572004-11-03 16:27:01 +0000491} ;# endif foreignkey
drh04738cb2002-06-02 18:19:00 +0000492
danielk197735bb9d02004-05-24 12:55:54 +0000493# Test for the "typeof" function. More tests for the
494# typeof() function are found in bind.test and types.test.
drh38640e12002-07-05 21:42:36 +0000495#
496do_test table-11.1 {
497 execsql {
498 CREATE TABLE t7(
499 a integer primary key,
500 b number(5,10),
501 c character varying (8),
502 d VARCHAR(9),
503 e clob,
504 f BLOB,
505 g Text,
506 h
507 );
508 INSERT INTO t7(a) VALUES(1);
509 SELECT typeof(a), typeof(b), typeof(c), typeof(d),
510 typeof(e), typeof(f), typeof(g), typeof(h)
511 FROM t7 LIMIT 1;
512 }
danielk197735bb9d02004-05-24 12:55:54 +0000513} {integer null null null null null null null}
drh38640e12002-07-05 21:42:36 +0000514do_test table-11.2 {
515 execsql {
516 SELECT typeof(a+b), typeof(a||b), typeof(c+d), typeof(c||d)
517 FROM t7 LIMIT 1;
518 }
danielk197735bb9d02004-05-24 12:55:54 +0000519} {null null null null}
drh97fc3d02002-05-22 21:27:03 +0000520
danielk197700e279d2004-06-21 07:36:32 +0000521# Test that when creating a table using CREATE TABLE AS, column types are
522# assigned correctly for (SELECT ...) and 'x AS y' expressions.
523do_test table-12.1 {
danielk19773e8c37e2005-01-21 03:12:14 +0000524 ifcapable subquery {
525 execsql {
526 CREATE TABLE t8 AS SELECT b, h, a as i, (SELECT f FROM t7) as j FROM t7;
527 }
528 } else {
529 execsql {
530 CREATE TABLE t8 AS SELECT b, h, a as i, f as j FROM t7;
531 }
danielk197700e279d2004-06-21 07:36:32 +0000532 }
533} {}
534do_test table-12.2 {
535 execsql {
536 SELECT sql FROM sqlite_master WHERE tbl_name = 't8'
537 }
538} {{CREATE TABLE t8(b number(5,10),h,i integer,j BLOB)}}
539
danielk1977e6efa742004-11-10 11:55:10 +0000540#--------------------------------------------------------------------
541# Test cases table-13.*
542#
danielk19777977a172004-11-09 12:44:37 +0000543# Test the ability to have default values of CURRENT_TIME, CURRENT_DATE
544# and CURRENT_TIMESTAMP.
545#
546do_test table-13.1 {
547 execsql {
548 CREATE TABLE tablet8(
549 a integer primary key,
550 tm text DEFAULT CURRENT_TIME,
551 dt text DEFAULT CURRENT_DATE,
552 dttm text DEFAULT CURRENT_TIMESTAMP
553 );
554 SELECT * FROM tablet8;
555 }
556} {}
557set i 0
558foreach {date time} {
559 1976-07-04 12:00:00
560 1994-04-16 14:00:00
561 2000-01-01 00:00:00
562 2003-12-31 12:34:56
563} {
564 incr i
danielk1977e6efa742004-11-10 11:55:10 +0000565 set sqlite_current_time [clock scan "$date $time" -gmt 1]
566 # set sqlite_current_time [execsql "SELECT strftime('%s','$date $time')"]
danielk19777977a172004-11-09 12:44:37 +0000567 do_test table-13.2.$i {
568 execsql "
569 INSERT INTO tablet8(a) VALUES($i);
570 SELECT tm, dt, dttm FROM tablet8 WHERE a=$i;
571 "
572 } [list $time $date [list $date $time]]
573}
574set sqlite_current_time 0
575
danielk1977e6efa742004-11-10 11:55:10 +0000576#--------------------------------------------------------------------
577# Test cases table-14.*
578#
579# Test that a table cannot be created or dropped while other virtual
580# machines are active. This is required because otherwise when in
581# auto-vacuum mode the btree-layer may need to move the root-pages of
582# a table for which there is an open cursor.
583#
584
danielk1977a21c6b62005-01-24 10:25:59 +0000585# db eval {
586# pragma vdbe_trace = 0;
587# }
danielk1977e6efa742004-11-10 11:55:10 +0000588# Try to create a table from within a callback:
drh251b0672004-11-23 22:16:39 +0000589unset -nocomplain result
danielk1977e6efa742004-11-10 11:55:10 +0000590do_test table-14.1 {
591 set rc [
592 catch {
593 db eval {SELECT * FROM tablet8 LIMIT 1} {} {
594 db eval {CREATE TABLE t9(a, b, c)}
595 }
596 } msg
597 ]
598 set result [list $rc $msg]
599} {1 {database table is locked}}
600
601do_test table-14.2 {
602 execsql {
603 CREATE TABLE t9(a, b, c)
604 }
605} {}
606
607# Try to drop a table from within a callback:
608do_test table-14.3 {
609 set rc [
610 catch {
611 db eval {SELECT * FROM tablet8 LIMIT 1} {} {
612 db eval {DROP TABLE t9;}
613 }
614 } msg
615 ]
616 set result [list $rc $msg]
617} {1 {database table is locked}}
618
619# Now attach a database and ensure that a table can be created in the
620# attached database whilst in a callback from a query on the main database.
621do_test table-14.4 {
622 file delete -force test2.db
623 file delete -force test2.db-journal
624 execsql {
625 attach 'test2.db' as aux;
626 }
627 db eval {SELECT * FROM tablet8 LIMIT 1} {} {
628 db eval {CREATE TABLE aux.t1(a, b, c)}
629 }
630} {}
631
632# On the other hand, it should be impossible to drop a table when any VMs
633# are active. This is because VerifyCookie instructions may have already
634# been executed, and btree root-pages may not move after this (which a
635# delete table might do).
636do_test table-14.4 {
637 set rc [
638 catch {
639 db eval {SELECT * FROM tablet8 LIMIT 1} {} {
640 db eval {DROP TABLE aux.t1;}
641 }
642 } msg
643 ]
644 set result [list $rc $msg]
645} {1 {database table is locked}}
646
danielk1977ae825582004-11-23 09:06:55 +0000647# Create and drop 2000 tables. This is to check that the balance_shallow()
648# routine works correctly on the sqlite_master table. At one point it
649# contained a bug that would prevent the right-child pointer of the
650# child page from being copied to the root page.
651#
652do_test table-15.1 {
653 execsql {BEGIN}
654 for {set i 0} {$i<2000} {incr i} {
655 execsql "CREATE TABLE tbl$i (a, b, c)"
656 }
657 execsql {COMMIT}
658} {}
659do_test table-15.2 {
660 execsql {BEGIN}
661 for {set i 0} {$i<2000} {incr i} {
662 execsql "DROP TABLE tbl$i"
663 }
664 execsql {COMMIT}
665} {}
666
drh348784e2000-05-29 20:41:49 +0000667finish_test