3 # The author disclaims copyright to this source code. In place of
4 # a legal notice, here is a blessing:
6 # 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.
10 #***********************************************************************
11 # This file implements regression tests for SQLite library. The
12 # focus of this file is testing the CREATE TABLE statement.
14 # $Id: table.test,v 1.39 2005/03/29 03:11:00 danielk1977 Exp $
16 set testdir [file dirname $argv0]
17 source $testdir/tester.tcl
19 # Create a basic table and verify it is added to sqlite_master
29 SELECT sql FROM sqlite_master WHERE type!='meta'
31 } {{CREATE TABLE test1 (
37 # Verify the other fields of the sqlite_master file.
40 execsql {SELECT name, tbl_name, type FROM sqlite_master WHERE type!='meta'}
43 # Close and reopen the database. Verify that everything is
49 execsql {SELECT name, tbl_name, type from sqlite_master WHERE type!='meta'}
52 # Drop the database and make sure it disappears.
55 execsql {DROP TABLE test1}
56 execsql {SELECT * FROM sqlite_master WHERE type!='meta'}
59 # Close and reopen the database. Verify that the table is
65 execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
68 # Repeat the above steps, but this time quote the table name.
71 execsql {CREATE TABLE "create" (f1 int)}
72 execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
75 execsql {DROP TABLE "create"}
76 execsql {SELECT name FROM "sqlite_master" WHERE type!='meta'}
79 execsql {CREATE TABLE test1("f1 ho" int)}
80 execsql {SELECT name as "X" FROM sqlite_master WHERE type!='meta'}
83 execsql {DROP TABLE "TEST1"}
84 execsql {SELECT name FROM "sqlite_master" WHERE type!='meta'}
89 # Verify that we cannot make two tables with the same name
92 execsql {CREATE TABLE TEST2(one text)}
93 set v [catch {execsql {CREATE TABLE test2(two text)}} msg]
95 } {1 {table test2 already exists}}
97 set v [catch {execsql {CREATE TABLE sqlite_master(two text)}} msg]
99 } {1 {object name reserved for internal use: sqlite_master}}
103 set v [catch {execsql {CREATE TABLE sqlite_master(two text)}} msg]
105 } {1 {object name reserved for internal use: sqlite_master}}
107 execsql {DROP TABLE test2; SELECT name FROM sqlite_master WHERE type!='meta'}
110 # Verify that we cannot make a table with the same name as an index
113 execsql {CREATE TABLE test2(one text); CREATE INDEX test3 ON test2(one)}
114 set v [catch {execsql {CREATE TABLE test3(two text)}} msg]
116 } {1 {there is already an index named test3}}
120 set v [catch {execsql {CREATE TABLE test3(two text)}} msg]
122 } {1 {there is already an index named test3}}
124 execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
127 execsql {DROP INDEX test3}
128 set v [catch {execsql {CREATE TABLE test3(two text)}} msg]
132 execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
135 execsql {DROP TABLE test2; DROP TABLE test3}
136 execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
139 # Create a table with many field names
145 f3 varchar(30) primary key,
166 execsql {SELECT sql FROM sqlite_master WHERE type=='table'}
169 set v [catch {execsql {CREATE TABLE BIG(xyz foo)}} msg]
171 } {1 {table BIG already exists}}
173 set v [catch {execsql {CREATE TABLE biG(xyz foo)}} msg]
175 } {1 {table biG already exists}}
177 set v [catch {execsql {CREATE TABLE bIg(xyz foo)}} msg]
179 } {1 {table bIg already exists}}
183 set v [catch {execsql {CREATE TABLE Big(xyz foo)}} msg]
185 } {1 {table Big already exists}}
187 execsql {DROP TABLE big}
188 execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
191 # Try creating large numbers of tables
194 for {set i 1} {$i<=100} {incr i} {
195 lappend r [format test%03d $i]
198 for {set i 1} {$i<=100} {incr i} {
199 set sql "CREATE TABLE [format test%03d $i] ("
200 for {set k 1} {$k<$i} {incr k} {
201 append sql "field$k text,"
203 append sql "last_field text)"
206 execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
211 execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
214 # Drop the even numbered tables
217 for {set i 1} {$i<=100} {incr i 2} {
218 lappend r [format test%03d $i]
221 for {set i 2} {$i<=100} {incr i 2} {
222 # if {$i==38} {execsql {pragma vdbe_trace=on}}
223 set sql "DROP TABLE [format TEST%03d $i]"
226 execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
230 # Drop the odd number tables
233 for {set i 1} {$i<=100} {incr i 2} {
234 set sql "DROP TABLE [format test%03d $i]"
237 execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
240 # Try to drop a table that does not exist
243 set v [catch {execsql {DROP TABLE test009}} msg]
245 } {1 {no such table: test009}}
247 # Try to drop sqlite_master
250 set v [catch {execsql {DROP TABLE sqlite_master}} msg]
252 } {1 {table sqlite_master may not be dropped}}
254 # Make sure an EXPLAIN does not really create a new table
257 ifcapable {explain} {
258 execsql {EXPLAIN CREATE TABLE test1(f1 int)}
260 execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
263 # Make sure an EXPLAIN does not really drop an existing table
266 execsql {CREATE TABLE test1(f1 int)}
267 ifcapable {explain} {
268 execsql {EXPLAIN DROP TABLE test1}
270 execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
273 # Create a table with a goofy name
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}
281 # Try using keywords as table names or column names.
284 set v [catch {execsql {
290 fuzzy_dog_12 varchar(10),
299 INSERT INTO weird VALUES('a','b',9,0,'xyz','hi','y''all');
302 } {a b 9 0 xyz hi y'all}
307 } {desc a asc b key 9 14_vac 0 fuzzy_dog_12 xyz begin hi end y'all}
309 # Try out the CREATE TABLE AS syntax
313 CREATE TABLE t2 AS SELECT * FROM weird;
316 } {desc a asc b key 9 14_vac 0 fuzzy_dog_12 xyz begin hi end y'all}
317 do_test table-8.1.1 {
319 SELECT sql FROM sqlite_master WHERE name='t2';
326 fuzzy_dog_12 varchar(10),
332 CREATE TABLE "t3""xyz"(a,b,c);
333 INSERT INTO [t3"xyz] VALUES(1,2,3);
334 SELECT * FROM [t3"xyz];
339 CREATE TABLE [t4"abc] AS SELECT count(*) as cnt, max(b+c) FROM [t3"xyz];
340 SELECT * FROM [t4"abc];
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
346 # from {{CREATE TABLE 't4"abc'(cnt NUMERIC,"max(b+c)" NUMERIC)}}).
347 do_test table-8.3.1 {
349 SELECT sql FROM sqlite_master WHERE name='t4"abc'
351 } {{CREATE TABLE "t4""abc"(cnt,"max(b+c)")}}
356 CREATE TEMPORARY TABLE t5 AS SELECT count(*) AS [y'all] FROM [t3"xyz];
366 SELECT * FROM [t4"abc];
373 } {desc a asc b key 9 14_vac 0 fuzzy_dog_12 xyz begin hi end y'all}
378 } {1 {no such table: t5}}
381 CREATE TABLE t5 AS SELECT * FROM no_such_table;
383 } {1 {no such table: no_such_table}}
385 # Make sure we cannot have duplicate column names within a table.
389 CREATE TABLE t6(a,b,a);
391 } {1 {duplicate column name: a}}
393 # Check the foreign key syntax.
395 ifcapable {foreignkey} {
398 CREATE TABLE t6(a REFERENCES t4(a) NOT NULL);
399 INSERT INTO t6 VALUES(NULL);
401 } {1 {t6.a may not be NULL}}
405 CREATE TABLE t6(a REFERENCES t4(a) MATCH PARTIAL);
411 CREATE TABLE t6(a REFERENCES t4 MATCH FULL ON DELETE SET NULL NOT NULL);
417 CREATE TABLE t6(a REFERENCES t4 MATCH FULL ON UPDATE SET DEFAULT DEFAULT 1);
423 CREATE TABLE t6(a NOT NULL NOT DEFERRABLE INITIALLY IMMEDIATE);
429 CREATE TABLE t6(a NOT NULL DEFERRABLE INITIALLY DEFERRED);
436 FOREIGN KEY (a) REFERENCES t4(b) DEFERRABLE INITIALLY DEFERRED
443 CREATE TABLE t6(a,b,c,
444 FOREIGN KEY (b,c) REFERENCES t4(x,y) MATCH PARTIAL
445 ON UPDATE SET NULL ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED
452 CREATE TABLE t6(a,b,c,
453 FOREIGN KEY (b,c) REFERENCES t4(x)
456 } {1 {number of columns in foreign key does not match the number of columns in the referenced table}}
457 do_test table-10.10 {
458 catchsql {DROP TABLE t6}
460 CREATE TABLE t6(a,b,c,
461 FOREIGN KEY (b,c) REFERENCES t4(x,y,z)
464 } {1 {number of columns in foreign key does not match the number of columns in the referenced table}}
465 do_test table-10.11 {
466 catchsql {DROP TABLE t6}
468 CREATE TABLE t6(a,b, c REFERENCES t4(x,y));
470 } {1 {foreign key on c should reference only one column of table t4}}
471 do_test table-10.12 {
472 catchsql {DROP TABLE t6}
474 CREATE TABLE t6(a,b,c,
475 FOREIGN KEY (b,x) REFERENCES t4(x,y)
478 } {1 {unknown column "x" in foreign key definition}}
479 do_test table-10.13 {
480 catchsql {DROP TABLE t6}
482 CREATE TABLE t6(a,b,c,
483 FOREIGN KEY (x,b) REFERENCES t4(x,y)
486 } {1 {unknown column "x" in foreign key definition}}
487 } ;# endif foreignkey
489 # Test for the "typeof" function. More tests for the
490 # typeof() function are found in bind.test and types.test.
495 a integer primary key,
497 c character varying (8),
504 INSERT INTO t7(a) VALUES(1);
505 SELECT typeof(a), typeof(b), typeof(c), typeof(d),
506 typeof(e), typeof(f), typeof(g), typeof(h)
509 } {integer null null null null null null null}
512 SELECT typeof(a+b), typeof(a||b), typeof(c+d), typeof(c||d)
515 } {null null null null}
517 # Test that when creating a table using CREATE TABLE AS, column types are
518 # assigned correctly for (SELECT ...) and 'x AS y' expressions.
522 CREATE TABLE t8 AS SELECT b, h, a as i, (SELECT f FROM t7) as j FROM t7;
526 CREATE TABLE t8 AS SELECT b, h, a as i, f as j FROM t7;
532 SELECT sql FROM sqlite_master WHERE tbl_name = 't8'
534 } {{CREATE TABLE t8(b number(5,10),h,i integer,j BLOB)}}
536 #--------------------------------------------------------------------
537 # Test cases table-13.*
539 # Test the ability to have default values of CURRENT_TIME, CURRENT_DATE
540 # and CURRENT_TIMESTAMP.
544 CREATE TABLE tablet8(
545 a integer primary key,
546 tm text DEFAULT CURRENT_TIME,
547 dt text DEFAULT CURRENT_DATE,
548 dttm text DEFAULT CURRENT_TIMESTAMP
550 SELECT * FROM tablet8;
554 foreach {date time} {
561 set sqlite_current_time [clock scan "$date $time" -gmt 1]
562 # set sqlite_current_time [execsql "SELECT strftime('%s','$date $time')"]
563 do_test table-13.2.$i {
565 INSERT INTO tablet8(a) VALUES($i);
566 SELECT tm, dt, dttm FROM tablet8 WHERE a=$i;
568 } [list $time $date [list $date $time]]
570 set sqlite_current_time 0
572 #--------------------------------------------------------------------
573 # Test cases table-14.*
575 # Test that a table cannot be created or dropped while other virtual
576 # machines are active. This is required because otherwise when in
577 # auto-vacuum mode the btree-layer may need to move the root-pages of
578 # a table for which there is an open cursor.
582 # pragma vdbe_trace = 0;
584 # Try to create a table from within a callback:
585 unset -nocomplain result
589 db eval {SELECT * FROM tablet8 LIMIT 1} {} {
590 db eval {CREATE TABLE t9(a, b, c)}
594 set result [list $rc $msg]
595 } {1 {database table is locked}}
599 CREATE TABLE t9(a, b, c)
603 # Try to drop a table from within a callback:
607 db eval {SELECT * FROM tablet8 LIMIT 1} {} {
608 db eval {DROP TABLE t9;}
612 set result [list $rc $msg]
613 } {1 {database table is locked}}
615 # Now attach a database and ensure that a table can be created in the
616 # attached database whilst in a callback from a query on the main database.
618 file delete -force test2.db
619 file delete -force test2.db-journal
621 attach 'test2.db' as aux;
623 db eval {SELECT * FROM tablet8 LIMIT 1} {} {
624 db eval {CREATE TABLE aux.t1(a, b, c)}
628 # On the other hand, it should be impossible to drop a table when any VMs
629 # are active. This is because VerifyCookie instructions may have already
630 # been executed, and btree root-pages may not move after this (which a
631 # delete table might do).
635 db eval {SELECT * FROM tablet8 LIMIT 1} {} {
636 db eval {DROP TABLE aux.t1;}
640 set result [list $rc $msg]
641 } {1 {database table is locked}}
643 # Create and drop 2000 tables. This is to check that the balance_shallow()
644 # routine works correctly on the sqlite_master table. At one point it
645 # contained a bug that would prevent the right-child pointer of the
646 # child page from being copied to the root page.
650 for {set i 0} {$i<2000} {incr i} {
651 execsql "CREATE TABLE tbl$i (a, b, c)"
657 for {set i 0} {$i<2000} {incr i} {
658 execsql "DROP TABLE tbl$i"