blob: c4b432070fb76324465dbdac34862a2821fc74de [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#
drh38640e12002-07-05 21:42:36 +000014# $Id: table.test,v 1.18 2002/07/05 21:42:38 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
drh3fc190c2001-09-14 03:24:23 +000048 sqlite 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
drh3fc190c2001-09-14 03:24:23 +000064 sqlite 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
drh1d37e282000-05-30 03:12:21 +000099} {1 {table sqlite_master already exists}}
drh1b6a71f2000-05-29 23:58:11 +0000100do_test table-2.1c {
drhb24fcbe2000-05-29 23:30:50 +0000101 db close
drh3fc190c2001-09-14 03:24:23 +0000102 sqlite 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
drh1d37e282000-05-30 03:12:21 +0000105} {1 {table sqlite_master already exists}}
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
drh3fc190c2001-09-14 03:24:23 +0000119 sqlite 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
drh3fc190c2001-09-14 03:24:23 +0000182 sqlite 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} {
195 lappend r test$i
196}
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} {
199 set sql "CREATE TABLE test$i ("
200 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
drh3fc190c2001-09-14 03:24:23 +0000210 sqlite 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} {
218 lappend r test$i
219}
drh3fc190c2001-09-14 03:24:23 +0000220#execsql {--vdbe-trace-on--}
drh1b6a71f2000-05-29 23:58:11 +0000221do_test table-4.2 {
drhb24fcbe2000-05-29 23:30:50 +0000222 for {set i 2} {$i<=100} {incr i 2} {
223 set sql "DROP TABLE TEST$i"
224 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} {
234 set sql "DROP TABLE test$i"
235 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 {
243 set v [catch {execsql {DROP TABLE test9}} msg]
244 lappend v $msg
245} {1 {no such table: test9}}
246
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 {
257 execsql {EXPLAIN CREATE TABLE test1(f1 int)}
drh28037572000-08-02 13:47:41 +0000258 execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
drh1b6a71f2000-05-29 23:58:11 +0000259} {}
260
261# Make sure an EXPLAIN does not really drop an existing table
262#
263do_test table-5.4 {
264 execsql {CREATE TABLE test1(f1 int)}
265 execsql {EXPLAIN DROP TABLE test1}
drh28037572000-08-02 13:47:41 +0000266 execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
drh1b6a71f2000-05-29 23:58:11 +0000267} {test1}
268
drh4cfa7932000-06-08 15:10:46 +0000269# Create a table with a goofy name
270#
drh3fc190c2001-09-14 03:24:23 +0000271#do_test table-6.1 {
272# execsql {CREATE TABLE 'Spaces In This Name!'(x int)}
273# execsql {INSERT INTO 'spaces in this name!' VALUES(1)}
274# set list [glob -nocomplain testdb/spaces*.tbl]
275#} {testdb/spaces+in+this+name+.tbl}
drh4cfa7932000-06-08 15:10:46 +0000276
drhc4a3c772001-04-04 11:48:57 +0000277# Try using keywords as table names or column names.
278#
279do_test table-7.1 {
280 set v [catch {execsql {
281 CREATE TABLE weird(
282 desc text,
283 asc text,
284 explain int,
drh17f71932002-02-21 12:01:27 +0000285 [14_vac] boolean,
286 fuzzy_dog_12 varchar(10),
drhd4007282001-04-12 23:21:58 +0000287 begin blob,
288 end clob
drhc4a3c772001-04-04 11:48:57 +0000289 )
290 }} msg]
291 lappend v $msg
292} {0 {}}
293do_test table-7.2 {
294 execsql {
drhd4007282001-04-12 23:21:58 +0000295 INSERT INTO weird VALUES('a','b',9,0,'xyz','hi','y''all');
drhc4a3c772001-04-04 11:48:57 +0000296 SELECT * FROM weird;
297 }
drhd4007282001-04-12 23:21:58 +0000298} {a b 9 0 xyz hi y'all}
drhc4a3c772001-04-04 11:48:57 +0000299do_test table-7.3 {
300 execsql2 {
301 SELECT * FROM weird;
302 }
drh17f71932002-02-21 12:01:27 +0000303} {desc a asc b explain 9 14_vac 0 fuzzy_dog_12 xyz begin hi end y'all}
drhc4a3c772001-04-04 11:48:57 +0000304
drh969fa7c2002-02-18 18:30:32 +0000305# Try out the CREATE TABLE AS syntax
306#
307do_test table-8.1 {
308 execsql2 {
309 CREATE TABLE t2 AS SELECT * FROM weird;
310 SELECT * FROM t2;
311 }
drh17f71932002-02-21 12:01:27 +0000312} {desc a asc b explain 9 14_vac 0 fuzzy_dog_12 xyz begin hi end y'all}
313do_test table-8.1.1 {
314 execsql {
315 SELECT sql FROM sqlite_master WHERE name='t2';
316 }
317} {{CREATE TABLE t2(
318 'desc',
319 'asc',
320 'explain',
321 '14_vac',
322 fuzzy_dog_12,
323 'begin',
324 'end'
325)}}
drh969fa7c2002-02-18 18:30:32 +0000326do_test table-8.2 {
327 execsql {
328 CREATE TABLE 't3''xyz'(a,b,c);
329 INSERT INTO [t3'xyz] VALUES(1,2,3);
330 SELECT * FROM [t3'xyz];
331 }
332} {1 2 3}
333do_test table-8.3 {
334 execsql2 {
drh17f71932002-02-21 12:01:27 +0000335 CREATE TABLE [t4'abc] AS SELECT count(*) as cnt, max(b+c) FROM [t3'xyz];
drh969fa7c2002-02-18 18:30:32 +0000336 SELECT * FROM [t4'abc];
337 }
drh17f71932002-02-21 12:01:27 +0000338} {cnt 1 max(b+c) 5}
339do_test table-8.3.1 {
340 execsql {
341 SELECT sql FROM sqlite_master WHERE name='t4''abc'
342 }
343} {{CREATE TABLE 't4''abc'(cnt,'max(b+c)')}}
drh969fa7c2002-02-18 18:30:32 +0000344do_test table-8.4 {
345 execsql2 {
346 CREATE TEMPORARY TABLE t5 AS SELECT count(*) AS [y'all] FROM [t3'xyz];
347 SELECT * FROM t5;
348 }
349} {y'all 1}
350do_test table-8.5 {
351 db close
352 sqlite db test.db
353 execsql2 {
354 SELECT * FROM [t4'abc];
355 }
drh17f71932002-02-21 12:01:27 +0000356} {cnt 1 max(b+c) 5}
drh969fa7c2002-02-18 18:30:32 +0000357do_test table-8.6 {
358 execsql2 {
359 SELECT * FROM t2;
360 }
drh17f71932002-02-21 12:01:27 +0000361} {desc a asc b explain 9 14_vac 0 fuzzy_dog_12 xyz begin hi end y'all}
drh969fa7c2002-02-18 18:30:32 +0000362do_test table-8.7 {
363 catchsql {
364 SELECT * FROM t5;
365 }
366} {1 {no such table: t5}}
drh17f71932002-02-21 12:01:27 +0000367do_test table-8.8 {
368 catchsql {
369 CREATE TABLE t5 AS SELECT * FROM no_such_table;
370 }
371} {1 {no such table: no_such_table}}
drh969fa7c2002-02-18 18:30:32 +0000372
drh97fc3d02002-05-22 21:27:03 +0000373# Make sure we cannot have duplicate column names within a table.
374#
375do_test table-9.1 {
376 catchsql {
377 CREATE TABLE t6(a,b,a);
378 }
379} {1 {duplicate column name: a}}
380
drh04738cb2002-06-02 18:19:00 +0000381# Check the foreign key syntax.
382#
383do_test table-10.1 {
384 catchsql {
385 CREATE TABLE t6(a REFERENCES t4(a) NOT NULL);
386 INSERT INTO t6 VALUES(NULL);
387 }
388} {1 {constraint failed}}
389do_test table-10.2 {
390 catchsql {
391 DROP TABLE t6;
392 CREATE TABLE t6(a REFERENCES t4(a) MATCH PARTIAL);
393 }
394} {0 {}}
395do_test table-10.3 {
396 catchsql {
397 DROP TABLE t6;
398 CREATE TABLE t6(a REFERENCES t4 MATCH FULL ON DELETE SET NULL NOT NULL);
399 }
400} {0 {}}
401do_test table-10.4 {
402 catchsql {
403 DROP TABLE t6;
404 CREATE TABLE t6(a REFERENCES t4 MATCH FULL ON UPDATE SET DEFAULT DEFAULT 1);
405 }
406} {0 {}}
407do_test table-10.5 {
408 catchsql {
409 DROP TABLE t6;
410 CREATE TABLE t6(a NOT NULL NOT DEFERRABLE INITIALLY IMMEDIATE);
411 }
412} {0 {}}
413do_test table-10.6 {
414 catchsql {
415 DROP TABLE t6;
416 CREATE TABLE t6(a NOT NULL DEFERRABLE INITIALLY DEFERRED);
417 }
418} {0 {}}
419do_test table-10.7 {
420 catchsql {
421 DROP TABLE t6;
422 CREATE TABLE t6(a,
423 FOREIGN KEY (a) REFERENCES t4(b) DEFERRABLE INITIALLY DEFERRED
424 );
425 }
426} {0 {}}
427do_test table-10.8 {
428 catchsql {
429 DROP TABLE t6;
430 CREATE TABLE t6(a,b,c,
431 FOREIGN KEY (b,c) REFERENCES t4(x,y) MATCH PARTIAL
432 ON UPDATE SET NULL ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED
433 );
434 }
435} {0 {}}
436
drh38640e12002-07-05 21:42:36 +0000437# Test for the "typeof" function.
438#
439do_test table-11.1 {
440 execsql {
441 CREATE TABLE t7(
442 a integer primary key,
443 b number(5,10),
444 c character varying (8),
445 d VARCHAR(9),
446 e clob,
447 f BLOB,
448 g Text,
449 h
450 );
451 INSERT INTO t7(a) VALUES(1);
452 SELECT typeof(a), typeof(b), typeof(c), typeof(d),
453 typeof(e), typeof(f), typeof(g), typeof(h)
454 FROM t7 LIMIT 1;
455 }
456} {numeric numeric text text text text text numeric}
457do_test table-11.2 {
458 execsql {
459 SELECT typeof(a+b), typeof(a||b), typeof(c+d), typeof(c||d)
460 FROM t7 LIMIT 1;
461 }
462} {numeric text numeric text}
drh97fc3d02002-05-22 21:27:03 +0000463
drh348784e2000-05-29 20:41:49 +0000464finish_test