blob: 10839ab5836a0e897936c5808f3fecef435d27f1 [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#
drhfaa59552005-12-29 23:33:54 +000014# $Id: table.test,v 1.43 2005/12/29 23:33:54 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 {
drhfaa59552005-12-29 23:33:54 +0000106 catchsql {CREATE TABLE IF NOT EXISTS test2(x,y)}
107} {0 {}}
108do_test table-2.1e {
drh28037572000-08-02 13:47:41 +0000109 execsql {DROP TABLE test2; SELECT name FROM sqlite_master WHERE type!='meta'}
drhb24fcbe2000-05-29 23:30:50 +0000110} {}
111
112# Verify that we cannot make a table with the same name as an index
113#
drhdcc581c2000-05-30 13:44:19 +0000114do_test table-2.2a {
drhb24fcbe2000-05-29 23:30:50 +0000115 execsql {CREATE TABLE test2(one text); CREATE INDEX test3 ON test2(one)}
116 set v [catch {execsql {CREATE TABLE test3(two text)}} msg]
117 lappend v $msg
drh1d37e282000-05-30 03:12:21 +0000118} {1 {there is already an index named test3}}
drh1b6a71f2000-05-29 23:58:11 +0000119do_test table-2.2b {
drhb24fcbe2000-05-29 23:30:50 +0000120 db close
drhef4ac8f2004-06-19 00:16:31 +0000121 sqlite3 db test.db
drhb24fcbe2000-05-29 23:30:50 +0000122 set v [catch {execsql {CREATE TABLE test3(two text)}} msg]
123 lappend v $msg
drh1d37e282000-05-30 03:12:21 +0000124} {1 {there is already an index named test3}}
drh1b6a71f2000-05-29 23:58:11 +0000125do_test table-2.2c {
drh3fc190c2001-09-14 03:24:23 +0000126 execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
127} {test2 test3}
128do_test table-2.2d {
drhb24fcbe2000-05-29 23:30:50 +0000129 execsql {DROP INDEX test3}
130 set v [catch {execsql {CREATE TABLE test3(two text)}} msg]
131 lappend v $msg
132} {0 {}}
drh3fc190c2001-09-14 03:24:23 +0000133do_test table-2.2e {
drh28037572000-08-02 13:47:41 +0000134 execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
drhb24fcbe2000-05-29 23:30:50 +0000135} {test2 test3}
drh3fc190c2001-09-14 03:24:23 +0000136do_test table-2.2f {
drhb24fcbe2000-05-29 23:30:50 +0000137 execsql {DROP TABLE test2; DROP TABLE test3}
drh28037572000-08-02 13:47:41 +0000138 execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
drhb24fcbe2000-05-29 23:30:50 +0000139} {}
140
141# Create a table with many field names
142#
143set big_table \
144{CREATE TABLE big(
145 f1 varchar(20),
146 f2 char(10),
drhdcc581c2000-05-30 13:44:19 +0000147 f3 varchar(30) primary key,
drhb24fcbe2000-05-29 23:30:50 +0000148 f4 text,
149 f5 text,
150 f6 text,
151 f7 text,
152 f8 text,
153 f9 text,
154 f10 text,
155 f11 text,
156 f12 text,
157 f13 text,
158 f14 text,
159 f15 text,
160 f16 text,
161 f17 text,
162 f18 text,
163 f19 text,
164 f20 text
165)}
drh1b6a71f2000-05-29 23:58:11 +0000166do_test table-3.1 {
drhb24fcbe2000-05-29 23:30:50 +0000167 execsql $big_table
drhadbca9c2001-09-27 15:11:53 +0000168 execsql {SELECT sql FROM sqlite_master WHERE type=='table'}
drhb24fcbe2000-05-29 23:30:50 +0000169} \{$big_table\}
drh1b6a71f2000-05-29 23:58:11 +0000170do_test table-3.2 {
drhb24fcbe2000-05-29 23:30:50 +0000171 set v [catch {execsql {CREATE TABLE BIG(xyz foo)}} msg]
172 lappend v $msg
drh1d37e282000-05-30 03:12:21 +0000173} {1 {table BIG already exists}}
drh1b6a71f2000-05-29 23:58:11 +0000174do_test table-3.3 {
drhb24fcbe2000-05-29 23:30:50 +0000175 set v [catch {execsql {CREATE TABLE biG(xyz foo)}} msg]
176 lappend v $msg
drh1d37e282000-05-30 03:12:21 +0000177} {1 {table biG already exists}}
drh1b6a71f2000-05-29 23:58:11 +0000178do_test table-3.4 {
drhb24fcbe2000-05-29 23:30:50 +0000179 set v [catch {execsql {CREATE TABLE bIg(xyz foo)}} msg]
180 lappend v $msg
drh1d37e282000-05-30 03:12:21 +0000181} {1 {table bIg already exists}}
drh1b6a71f2000-05-29 23:58:11 +0000182do_test table-3.5 {
drhb24fcbe2000-05-29 23:30:50 +0000183 db close
drhef4ac8f2004-06-19 00:16:31 +0000184 sqlite3 db test.db
drhb24fcbe2000-05-29 23:30:50 +0000185 set v [catch {execsql {CREATE TABLE Big(xyz foo)}} msg]
186 lappend v $msg
drh1d37e282000-05-30 03:12:21 +0000187} {1 {table Big already exists}}
drh1b6a71f2000-05-29 23:58:11 +0000188do_test table-3.6 {
drhb24fcbe2000-05-29 23:30:50 +0000189 execsql {DROP TABLE big}
drh28037572000-08-02 13:47:41 +0000190 execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
drhb24fcbe2000-05-29 23:30:50 +0000191} {}
192
193# Try creating large numbers of tables
194#
195set r {}
196for {set i 1} {$i<=100} {incr i} {
drha9e99ae2002-08-13 23:02:57 +0000197 lappend r [format test%03d $i]
drhb24fcbe2000-05-29 23:30:50 +0000198}
drh1b6a71f2000-05-29 23:58:11 +0000199do_test table-4.1 {
drhb24fcbe2000-05-29 23:30:50 +0000200 for {set i 1} {$i<=100} {incr i} {
drha9e99ae2002-08-13 23:02:57 +0000201 set sql "CREATE TABLE [format test%03d $i] ("
drhb24fcbe2000-05-29 23:30:50 +0000202 for {set k 1} {$k<$i} {incr k} {
203 append sql "field$k text,"
204 }
205 append sql "last_field text)"
206 execsql $sql
207 }
drh28037572000-08-02 13:47:41 +0000208 execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
drhb24fcbe2000-05-29 23:30:50 +0000209} $r
drh1b6a71f2000-05-29 23:58:11 +0000210do_test table-4.1b {
drhb24fcbe2000-05-29 23:30:50 +0000211 db close
drhef4ac8f2004-06-19 00:16:31 +0000212 sqlite3 db test.db
drh28037572000-08-02 13:47:41 +0000213 execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
drhb24fcbe2000-05-29 23:30:50 +0000214} $r
215
drhc4a3c772001-04-04 11:48:57 +0000216# Drop the even numbered tables
drhb24fcbe2000-05-29 23:30:50 +0000217#
218set r {}
219for {set i 1} {$i<=100} {incr i 2} {
drha9e99ae2002-08-13 23:02:57 +0000220 lappend r [format test%03d $i]
drhb24fcbe2000-05-29 23:30:50 +0000221}
drh1b6a71f2000-05-29 23:58:11 +0000222do_test table-4.2 {
drhb24fcbe2000-05-29 23:30:50 +0000223 for {set i 2} {$i<=100} {incr i 2} {
drh428ae8c2003-01-04 16:48:09 +0000224 # if {$i==38} {execsql {pragma vdbe_trace=on}}
drha9e99ae2002-08-13 23:02:57 +0000225 set sql "DROP TABLE [format TEST%03d $i]"
drhb24fcbe2000-05-29 23:30:50 +0000226 execsql $sql
227 }
drh28037572000-08-02 13:47:41 +0000228 execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
drhb24fcbe2000-05-29 23:30:50 +0000229} $r
drh3fc190c2001-09-14 03:24:23 +0000230#exit
drhb24fcbe2000-05-29 23:30:50 +0000231
232# Drop the odd number tables
233#
drh1b6a71f2000-05-29 23:58:11 +0000234do_test table-4.3 {
drhb24fcbe2000-05-29 23:30:50 +0000235 for {set i 1} {$i<=100} {incr i 2} {
drha9e99ae2002-08-13 23:02:57 +0000236 set sql "DROP TABLE [format test%03d $i]"
drhb24fcbe2000-05-29 23:30:50 +0000237 execsql $sql
238 }
drh28037572000-08-02 13:47:41 +0000239 execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
drhb24fcbe2000-05-29 23:30:50 +0000240} {}
241
drh1b6a71f2000-05-29 23:58:11 +0000242# Try to drop a table that does not exist
243#
drha0733842005-12-29 01:11:36 +0000244do_test table-5.1.1 {
245 catchsql {DROP TABLE test009}
drha9e99ae2002-08-13 23:02:57 +0000246} {1 {no such table: test009}}
drha0733842005-12-29 01:11:36 +0000247do_test table-5.1.2 {
248 catchsql {DROP TABLE IF EXISTS test009}
249} {0 {}}
drh1b6a71f2000-05-29 23:58:11 +0000250
251# Try to drop sqlite_master
252#
253do_test table-5.2 {
drha0733842005-12-29 01:11:36 +0000254 catchsql {DROP TABLE IF EXISTS sqlite_master}
drh1d37e282000-05-30 03:12:21 +0000255} {1 {table sqlite_master may not be dropped}}
drh1b6a71f2000-05-29 23:58:11 +0000256
257# Make sure an EXPLAIN does not really create a new table
258#
259do_test table-5.3 {
drh6bf89572004-11-03 16:27:01 +0000260 ifcapable {explain} {
261 execsql {EXPLAIN CREATE TABLE test1(f1 int)}
262 }
drh28037572000-08-02 13:47:41 +0000263 execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
drh1b6a71f2000-05-29 23:58:11 +0000264} {}
265
266# Make sure an EXPLAIN does not really drop an existing table
267#
268do_test table-5.4 {
269 execsql {CREATE TABLE test1(f1 int)}
drh6bf89572004-11-03 16:27:01 +0000270 ifcapable {explain} {
271 execsql {EXPLAIN DROP TABLE test1}
272 }
drh28037572000-08-02 13:47:41 +0000273 execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
drh1b6a71f2000-05-29 23:58:11 +0000274} {test1}
275
drh4cfa7932000-06-08 15:10:46 +0000276# Create a table with a goofy name
277#
drh3fc190c2001-09-14 03:24:23 +0000278#do_test table-6.1 {
279# execsql {CREATE TABLE 'Spaces In This Name!'(x int)}
280# execsql {INSERT INTO 'spaces in this name!' VALUES(1)}
281# set list [glob -nocomplain testdb/spaces*.tbl]
282#} {testdb/spaces+in+this+name+.tbl}
drh4cfa7932000-06-08 15:10:46 +0000283
drhc4a3c772001-04-04 11:48:57 +0000284# Try using keywords as table names or column names.
285#
286do_test table-7.1 {
287 set v [catch {execsql {
288 CREATE TABLE weird(
289 desc text,
290 asc text,
drh6bf89572004-11-03 16:27:01 +0000291 key int,
drh17f71932002-02-21 12:01:27 +0000292 [14_vac] boolean,
293 fuzzy_dog_12 varchar(10),
drhd4007282001-04-12 23:21:58 +0000294 begin blob,
295 end clob
drhc4a3c772001-04-04 11:48:57 +0000296 )
297 }} msg]
298 lappend v $msg
299} {0 {}}
300do_test table-7.2 {
301 execsql {
drhd4007282001-04-12 23:21:58 +0000302 INSERT INTO weird VALUES('a','b',9,0,'xyz','hi','y''all');
drhc4a3c772001-04-04 11:48:57 +0000303 SELECT * FROM weird;
304 }
drhd4007282001-04-12 23:21:58 +0000305} {a b 9 0 xyz hi y'all}
drhc4a3c772001-04-04 11:48:57 +0000306do_test table-7.3 {
307 execsql2 {
308 SELECT * FROM weird;
309 }
drh6bf89572004-11-03 16:27:01 +0000310} {desc a asc b key 9 14_vac 0 fuzzy_dog_12 xyz begin hi end y'all}
drhc4a3c772001-04-04 11:48:57 +0000311
drh969fa7c2002-02-18 18:30:32 +0000312# Try out the CREATE TABLE AS syntax
313#
314do_test table-8.1 {
315 execsql2 {
316 CREATE TABLE t2 AS SELECT * FROM weird;
317 SELECT * FROM t2;
318 }
drh6bf89572004-11-03 16:27:01 +0000319} {desc a asc b key 9 14_vac 0 fuzzy_dog_12 xyz begin hi end y'all}
drh17f71932002-02-21 12:01:27 +0000320do_test table-8.1.1 {
321 execsql {
322 SELECT sql FROM sqlite_master WHERE name='t2';
323 }
324} {{CREATE TABLE t2(
drh234c39d2004-07-24 03:30:47 +0000325 "desc" text,
326 "asc" text,
drh6bf89572004-11-03 16:27:01 +0000327 "key" int,
drh234c39d2004-07-24 03:30:47 +0000328 "14_vac" boolean,
danielk1977517eb642004-06-07 10:00:31 +0000329 fuzzy_dog_12 varchar(10),
drh234c39d2004-07-24 03:30:47 +0000330 "begin" blob,
331 "end" clob
drh17f71932002-02-21 12:01:27 +0000332)}}
drh969fa7c2002-02-18 18:30:32 +0000333do_test table-8.2 {
334 execsql {
drh234c39d2004-07-24 03:30:47 +0000335 CREATE TABLE "t3""xyz"(a,b,c);
336 INSERT INTO [t3"xyz] VALUES(1,2,3);
337 SELECT * FROM [t3"xyz];
drh969fa7c2002-02-18 18:30:32 +0000338 }
339} {1 2 3}
340do_test table-8.3 {
341 execsql2 {
drh234c39d2004-07-24 03:30:47 +0000342 CREATE TABLE [t4"abc] AS SELECT count(*) as cnt, max(b+c) FROM [t3"xyz];
343 SELECT * FROM [t4"abc];
drh969fa7c2002-02-18 18:30:32 +0000344 }
drh17f71932002-02-21 12:01:27 +0000345} {cnt 1 max(b+c) 5}
danielk197700e279d2004-06-21 07:36:32 +0000346
347# Update for v3: The declaration type of anything except a column is now a
348# NULL pointer, so the created table has no column types. (Changed result
drh234c39d2004-07-24 03:30:47 +0000349# from {{CREATE TABLE 't4"abc'(cnt NUMERIC,"max(b+c)" NUMERIC)}}).
drh17f71932002-02-21 12:01:27 +0000350do_test table-8.3.1 {
351 execsql {
drh234c39d2004-07-24 03:30:47 +0000352 SELECT sql FROM sqlite_master WHERE name='t4"abc'
drh17f71932002-02-21 12:01:27 +0000353 }
drh234c39d2004-07-24 03:30:47 +0000354} {{CREATE TABLE "t4""abc"(cnt,"max(b+c)")}}
danielk197753c0f742005-03-29 03:10:59 +0000355
356ifcapable tempdb {
357 do_test table-8.4 {
358 execsql2 {
359 CREATE TEMPORARY TABLE t5 AS SELECT count(*) AS [y'all] FROM [t3"xyz];
360 SELECT * FROM t5;
361 }
362 } {y'all 1}
363}
364
drh969fa7c2002-02-18 18:30:32 +0000365do_test table-8.5 {
366 db close
drhef4ac8f2004-06-19 00:16:31 +0000367 sqlite3 db test.db
drh969fa7c2002-02-18 18:30:32 +0000368 execsql2 {
drh234c39d2004-07-24 03:30:47 +0000369 SELECT * FROM [t4"abc];
drh969fa7c2002-02-18 18:30:32 +0000370 }
drh17f71932002-02-21 12:01:27 +0000371} {cnt 1 max(b+c) 5}
drh969fa7c2002-02-18 18:30:32 +0000372do_test table-8.6 {
373 execsql2 {
374 SELECT * FROM t2;
375 }
drh6bf89572004-11-03 16:27:01 +0000376} {desc a asc b key 9 14_vac 0 fuzzy_dog_12 xyz begin hi end y'all}
drh969fa7c2002-02-18 18:30:32 +0000377do_test table-8.7 {
378 catchsql {
379 SELECT * FROM t5;
380 }
381} {1 {no such table: t5}}
drh17f71932002-02-21 12:01:27 +0000382do_test table-8.8 {
383 catchsql {
384 CREATE TABLE t5 AS SELECT * FROM no_such_table;
385 }
386} {1 {no such table: no_such_table}}
drh969fa7c2002-02-18 18:30:32 +0000387
drh97fc3d02002-05-22 21:27:03 +0000388# Make sure we cannot have duplicate column names within a table.
389#
390do_test table-9.1 {
391 catchsql {
392 CREATE TABLE t6(a,b,a);
393 }
394} {1 {duplicate column name: a}}
drhd8919672005-09-10 15:35:06 +0000395do_test table-9.2 {
396 catchsql {
397 CREATE TABLE t6(a varchar(100), b blob, a integer);
398 }
399} {1 {duplicate column name: a}}
drh97fc3d02002-05-22 21:27:03 +0000400
drh04738cb2002-06-02 18:19:00 +0000401# Check the foreign key syntax.
402#
drh6bf89572004-11-03 16:27:01 +0000403ifcapable {foreignkey} {
drh04738cb2002-06-02 18:19:00 +0000404do_test table-10.1 {
405 catchsql {
406 CREATE TABLE t6(a REFERENCES t4(a) NOT NULL);
407 INSERT INTO t6 VALUES(NULL);
408 }
drh483750b2003-01-29 18:46:51 +0000409} {1 {t6.a may not be NULL}}
drh04738cb2002-06-02 18:19:00 +0000410do_test table-10.2 {
411 catchsql {
412 DROP TABLE t6;
413 CREATE TABLE t6(a REFERENCES t4(a) MATCH PARTIAL);
414 }
415} {0 {}}
416do_test table-10.3 {
417 catchsql {
418 DROP TABLE t6;
419 CREATE TABLE t6(a REFERENCES t4 MATCH FULL ON DELETE SET NULL NOT NULL);
420 }
421} {0 {}}
422do_test table-10.4 {
423 catchsql {
424 DROP TABLE t6;
425 CREATE TABLE t6(a REFERENCES t4 MATCH FULL ON UPDATE SET DEFAULT DEFAULT 1);
426 }
427} {0 {}}
428do_test table-10.5 {
429 catchsql {
430 DROP TABLE t6;
431 CREATE TABLE t6(a NOT NULL NOT DEFERRABLE INITIALLY IMMEDIATE);
432 }
433} {0 {}}
434do_test table-10.6 {
435 catchsql {
436 DROP TABLE t6;
437 CREATE TABLE t6(a NOT NULL DEFERRABLE INITIALLY DEFERRED);
438 }
439} {0 {}}
440do_test table-10.7 {
441 catchsql {
442 DROP TABLE t6;
443 CREATE TABLE t6(a,
444 FOREIGN KEY (a) REFERENCES t4(b) DEFERRABLE INITIALLY DEFERRED
445 );
446 }
447} {0 {}}
448do_test table-10.8 {
449 catchsql {
450 DROP TABLE t6;
451 CREATE TABLE t6(a,b,c,
452 FOREIGN KEY (b,c) REFERENCES t4(x,y) MATCH PARTIAL
453 ON UPDATE SET NULL ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED
454 );
455 }
456} {0 {}}
drhc2eef3b2002-08-31 18:53:06 +0000457do_test table-10.9 {
458 catchsql {
459 DROP TABLE t6;
460 CREATE TABLE t6(a,b,c,
461 FOREIGN KEY (b,c) REFERENCES t4(x)
462 );
463 }
464} {1 {number of columns in foreign key does not match the number of columns in the referenced table}}
465do_test table-10.10 {
466 catchsql {DROP TABLE t6}
467 catchsql {
468 CREATE TABLE t6(a,b,c,
469 FOREIGN KEY (b,c) REFERENCES t4(x,y,z)
470 );
471 }
472} {1 {number of columns in foreign key does not match the number of columns in the referenced table}}
473do_test table-10.11 {
474 catchsql {DROP TABLE t6}
475 catchsql {
476 CREATE TABLE t6(a,b, c REFERENCES t4(x,y));
477 }
478} {1 {foreign key on c should reference only one column of table t4}}
479do_test table-10.12 {
480 catchsql {DROP TABLE t6}
481 catchsql {
482 CREATE TABLE t6(a,b,c,
483 FOREIGN KEY (b,x) REFERENCES t4(x,y)
484 );
485 }
486} {1 {unknown column "x" in foreign key definition}}
487do_test table-10.13 {
488 catchsql {DROP TABLE t6}
489 catchsql {
490 CREATE TABLE t6(a,b,c,
491 FOREIGN KEY (x,b) REFERENCES t4(x,y)
492 );
493 }
494} {1 {unknown column "x" in foreign key definition}}
drh6bf89572004-11-03 16:27:01 +0000495} ;# endif foreignkey
drh04738cb2002-06-02 18:19:00 +0000496
danielk197735bb9d02004-05-24 12:55:54 +0000497# Test for the "typeof" function. More tests for the
498# typeof() function are found in bind.test and types.test.
drh38640e12002-07-05 21:42:36 +0000499#
500do_test table-11.1 {
501 execsql {
502 CREATE TABLE t7(
503 a integer primary key,
504 b number(5,10),
505 c character varying (8),
506 d VARCHAR(9),
507 e clob,
508 f BLOB,
509 g Text,
510 h
511 );
512 INSERT INTO t7(a) VALUES(1);
513 SELECT typeof(a), typeof(b), typeof(c), typeof(d),
514 typeof(e), typeof(f), typeof(g), typeof(h)
515 FROM t7 LIMIT 1;
516 }
danielk197735bb9d02004-05-24 12:55:54 +0000517} {integer null null null null null null null}
drh38640e12002-07-05 21:42:36 +0000518do_test table-11.2 {
519 execsql {
520 SELECT typeof(a+b), typeof(a||b), typeof(c+d), typeof(c||d)
521 FROM t7 LIMIT 1;
522 }
danielk197735bb9d02004-05-24 12:55:54 +0000523} {null null null null}
drh97fc3d02002-05-22 21:27:03 +0000524
danielk197700e279d2004-06-21 07:36:32 +0000525# Test that when creating a table using CREATE TABLE AS, column types are
526# assigned correctly for (SELECT ...) and 'x AS y' expressions.
527do_test table-12.1 {
danielk19773e8c37e2005-01-21 03:12:14 +0000528 ifcapable subquery {
529 execsql {
530 CREATE TABLE t8 AS SELECT b, h, a as i, (SELECT f FROM t7) as j FROM t7;
531 }
532 } else {
533 execsql {
534 CREATE TABLE t8 AS SELECT b, h, a as i, f as j FROM t7;
535 }
danielk197700e279d2004-06-21 07:36:32 +0000536 }
537} {}
538do_test table-12.2 {
539 execsql {
540 SELECT sql FROM sqlite_master WHERE tbl_name = 't8'
541 }
542} {{CREATE TABLE t8(b number(5,10),h,i integer,j BLOB)}}
543
danielk1977e6efa742004-11-10 11:55:10 +0000544#--------------------------------------------------------------------
545# Test cases table-13.*
546#
danielk19777977a172004-11-09 12:44:37 +0000547# Test the ability to have default values of CURRENT_TIME, CURRENT_DATE
548# and CURRENT_TIMESTAMP.
549#
550do_test table-13.1 {
551 execsql {
552 CREATE TABLE tablet8(
553 a integer primary key,
554 tm text DEFAULT CURRENT_TIME,
555 dt text DEFAULT CURRENT_DATE,
556 dttm text DEFAULT CURRENT_TIMESTAMP
557 );
558 SELECT * FROM tablet8;
559 }
560} {}
561set i 0
562foreach {date time} {
563 1976-07-04 12:00:00
564 1994-04-16 14:00:00
565 2000-01-01 00:00:00
566 2003-12-31 12:34:56
567} {
568 incr i
danielk1977e6efa742004-11-10 11:55:10 +0000569 set sqlite_current_time [clock scan "$date $time" -gmt 1]
570 # set sqlite_current_time [execsql "SELECT strftime('%s','$date $time')"]
danielk19777977a172004-11-09 12:44:37 +0000571 do_test table-13.2.$i {
572 execsql "
573 INSERT INTO tablet8(a) VALUES($i);
574 SELECT tm, dt, dttm FROM tablet8 WHERE a=$i;
575 "
576 } [list $time $date [list $date $time]]
577}
578set sqlite_current_time 0
579
danielk1977e6efa742004-11-10 11:55:10 +0000580#--------------------------------------------------------------------
581# Test cases table-14.*
582#
583# Test that a table cannot be created or dropped while other virtual
584# machines are active. This is required because otherwise when in
585# auto-vacuum mode the btree-layer may need to move the root-pages of
586# a table for which there is an open cursor.
587#
588
danielk1977a21c6b62005-01-24 10:25:59 +0000589# db eval {
590# pragma vdbe_trace = 0;
591# }
danielk1977e6efa742004-11-10 11:55:10 +0000592# Try to create a table from within a callback:
drh251b0672004-11-23 22:16:39 +0000593unset -nocomplain result
danielk1977e6efa742004-11-10 11:55:10 +0000594do_test table-14.1 {
595 set rc [
596 catch {
597 db eval {SELECT * FROM tablet8 LIMIT 1} {} {
598 db eval {CREATE TABLE t9(a, b, c)}
599 }
600 } msg
601 ]
602 set result [list $rc $msg]
603} {1 {database table is locked}}
604
605do_test table-14.2 {
606 execsql {
607 CREATE TABLE t9(a, b, c)
608 }
609} {}
610
611# Try to drop a table from within a callback:
612do_test table-14.3 {
613 set rc [
614 catch {
615 db eval {SELECT * FROM tablet8 LIMIT 1} {} {
616 db eval {DROP TABLE t9;}
617 }
618 } msg
619 ]
620 set result [list $rc $msg]
621} {1 {database table is locked}}
622
623# Now attach a database and ensure that a table can be created in the
624# attached database whilst in a callback from a query on the main database.
625do_test table-14.4 {
626 file delete -force test2.db
627 file delete -force test2.db-journal
628 execsql {
629 attach 'test2.db' as aux;
630 }
631 db eval {SELECT * FROM tablet8 LIMIT 1} {} {
632 db eval {CREATE TABLE aux.t1(a, b, c)}
633 }
634} {}
635
636# On the other hand, it should be impossible to drop a table when any VMs
637# are active. This is because VerifyCookie instructions may have already
638# been executed, and btree root-pages may not move after this (which a
639# delete table might do).
640do_test table-14.4 {
641 set rc [
642 catch {
643 db eval {SELECT * FROM tablet8 LIMIT 1} {} {
644 db eval {DROP TABLE aux.t1;}
645 }
646 } msg
647 ]
648 set result [list $rc $msg]
649} {1 {database table is locked}}
650
danielk1977ae825582004-11-23 09:06:55 +0000651# Create and drop 2000 tables. This is to check that the balance_shallow()
652# routine works correctly on the sqlite_master table. At one point it
653# contained a bug that would prevent the right-child pointer of the
654# child page from being copied to the root page.
655#
656do_test table-15.1 {
657 execsql {BEGIN}
658 for {set i 0} {$i<2000} {incr i} {
659 execsql "CREATE TABLE tbl$i (a, b, c)"
660 }
661 execsql {COMMIT}
662} {}
663do_test table-15.2 {
664 execsql {BEGIN}
665 for {set i 0} {$i<2000} {incr i} {
666 execsql "DROP TABLE tbl$i"
667 }
668 execsql {COMMIT}
669} {}
670
drh348784e2000-05-29 20:41:49 +0000671finish_test