xref: /illumos-gate/usr/src/lib/libsqlite/test/table.test (revision 8b80e8cb6855118d46f605e91b5ed4ce83417395)
1
2#pragma ident	"%Z%%M%	%I%	%E% SMI"
3
4# 2001 September 15
5#
6# The author disclaims copyright to this source code.  In place of
7# a legal notice, here is a blessing:
8#
9#    May you do good and not evil.
10#    May you find forgiveness for yourself and forgive others.
11#    May you share freely, never taking more than you give.
12#
13#***********************************************************************
14# This file implements regression tests for SQLite library.  The
15# focus of this file is testing the CREATE TABLE statement.
16#
17# $Id: table.test,v 1.22 2003/01/29 18:46:54 drh Exp $
18
19set testdir [file dirname $argv0]
20source $testdir/tester.tcl
21
22# Create a basic table and verify it is added to sqlite_master
23#
24do_test table-1.1 {
25  execsql {
26    CREATE TABLE test1 (
27      one varchar(10),
28      two text
29    )
30  }
31  execsql {
32    SELECT sql FROM sqlite_master WHERE type!='meta'
33  }
34} {{CREATE TABLE test1 (
35      one varchar(10),
36      two text
37    )}}
38
39
40# Verify the other fields of the sqlite_master file.
41#
42do_test table-1.3 {
43  execsql {SELECT name, tbl_name, type FROM sqlite_master WHERE type!='meta'}
44} {test1 test1 table}
45
46# Close and reopen the database.  Verify that everything is
47# still the same.
48#
49do_test table-1.4 {
50  db close
51  sqlite db test.db
52  execsql {SELECT name, tbl_name, type from sqlite_master WHERE type!='meta'}
53} {test1 test1 table}
54
55# Drop the database and make sure it disappears.
56#
57do_test table-1.5 {
58  execsql {DROP TABLE test1}
59  execsql {SELECT * FROM sqlite_master WHERE type!='meta'}
60} {}
61
62# Close and reopen the database.  Verify that the table is
63# still gone.
64#
65do_test table-1.6 {
66  db close
67  sqlite db test.db
68  execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
69} {}
70
71# Repeat the above steps, but this time quote the table name.
72#
73do_test table-1.10 {
74  execsql {CREATE TABLE "create" (f1 int)}
75  execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
76} {create}
77do_test table-1.11 {
78  execsql {DROP TABLE "create"}
79  execsql {SELECT name FROM "sqlite_master" WHERE type!='meta'}
80} {}
81do_test table-1.12 {
82  execsql {CREATE TABLE test1("f1 ho" int)}
83  execsql {SELECT name as "X" FROM sqlite_master WHERE type!='meta'}
84} {test1}
85do_test table-1.13 {
86  execsql {DROP TABLE "TEST1"}
87  execsql {SELECT name FROM "sqlite_master" WHERE type!='meta'}
88} {}
89
90
91
92# Verify that we cannot make two tables with the same name
93#
94do_test table-2.1 {
95  execsql {CREATE TABLE TEST2(one text)}
96  set v [catch {execsql {CREATE TABLE test2(two text)}} msg]
97  lappend v $msg
98} {1 {table test2 already exists}}
99do_test table-2.1b {
100  set v [catch {execsql {CREATE TABLE sqlite_master(two text)}} msg]
101  lappend v $msg
102} {1 {table sqlite_master already exists}}
103do_test table-2.1c {
104  db close
105  sqlite db test.db
106  set v [catch {execsql {CREATE TABLE sqlite_master(two text)}} msg]
107  lappend v $msg
108} {1 {table sqlite_master already exists}}
109do_test table-2.1d {
110  execsql {DROP TABLE test2; SELECT name FROM sqlite_master WHERE type!='meta'}
111} {}
112
113# Verify that we cannot make a table with the same name as an index
114#
115do_test table-2.2a {
116  execsql {CREATE TABLE test2(one text); CREATE INDEX test3 ON test2(one)}
117  set v [catch {execsql {CREATE TABLE test3(two text)}} msg]
118  lappend v $msg
119} {1 {there is already an index named test3}}
120do_test table-2.2b {
121  db close
122  sqlite db test.db
123  set v [catch {execsql {CREATE TABLE test3(two text)}} msg]
124  lappend v $msg
125} {1 {there is already an index named test3}}
126do_test table-2.2c {
127  execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
128} {test2 test3}
129do_test table-2.2d {
130  execsql {DROP INDEX test3}
131  set v [catch {execsql {CREATE TABLE test3(two text)}} msg]
132  lappend v $msg
133} {0 {}}
134do_test table-2.2e {
135  execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
136} {test2 test3}
137do_test table-2.2f {
138  execsql {DROP TABLE test2; DROP TABLE test3}
139  execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
140} {}
141
142# Create a table with many field names
143#
144set big_table \
145{CREATE TABLE big(
146  f1 varchar(20),
147  f2 char(10),
148  f3 varchar(30) primary key,
149  f4 text,
150  f5 text,
151  f6 text,
152  f7 text,
153  f8 text,
154  f9 text,
155  f10 text,
156  f11 text,
157  f12 text,
158  f13 text,
159  f14 text,
160  f15 text,
161  f16 text,
162  f17 text,
163  f18 text,
164  f19 text,
165  f20 text
166)}
167do_test table-3.1 {
168  execsql $big_table
169  execsql {SELECT sql FROM sqlite_master WHERE type=='table'}
170} \{$big_table\}
171do_test table-3.2 {
172  set v [catch {execsql {CREATE TABLE BIG(xyz foo)}} msg]
173  lappend v $msg
174} {1 {table BIG already exists}}
175do_test table-3.3 {
176  set v [catch {execsql {CREATE TABLE biG(xyz foo)}} msg]
177  lappend v $msg
178} {1 {table biG already exists}}
179do_test table-3.4 {
180  set v [catch {execsql {CREATE TABLE bIg(xyz foo)}} msg]
181  lappend v $msg
182} {1 {table bIg already exists}}
183do_test table-3.5 {
184  db close
185  sqlite db test.db
186  set v [catch {execsql {CREATE TABLE Big(xyz foo)}} msg]
187  lappend v $msg
188} {1 {table Big already exists}}
189do_test table-3.6 {
190  execsql {DROP TABLE big}
191  execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
192} {}
193
194# Try creating large numbers of tables
195#
196set r {}
197for {set i 1} {$i<=100} {incr i} {
198  lappend r [format test%03d $i]
199}
200do_test table-4.1 {
201  for {set i 1} {$i<=100} {incr i} {
202    set sql "CREATE TABLE [format test%03d $i] ("
203    for {set k 1} {$k<$i} {incr k} {
204      append sql "field$k text,"
205    }
206    append sql "last_field text)"
207    execsql $sql
208  }
209  execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
210} $r
211do_test table-4.1b {
212  db close
213  sqlite db test.db
214  execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
215} $r
216
217# Drop the even numbered tables
218#
219set r {}
220for {set i 1} {$i<=100} {incr i 2} {
221  lappend r [format test%03d $i]
222}
223do_test table-4.2 {
224  for {set i 2} {$i<=100} {incr i 2} {
225    # if {$i==38} {execsql {pragma vdbe_trace=on}}
226    set sql "DROP TABLE [format TEST%03d $i]"
227    execsql $sql
228  }
229  execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
230} $r
231#exit
232
233# Drop the odd number tables
234#
235do_test table-4.3 {
236  for {set i 1} {$i<=100} {incr i 2} {
237    set sql "DROP TABLE [format test%03d $i]"
238    execsql $sql
239  }
240  execsql {SELECT name FROM sqlite_master WHERE type!='meta' ORDER BY name}
241} {}
242
243# Try to drop a table that does not exist
244#
245do_test table-5.1 {
246  set v [catch {execsql {DROP TABLE test009}} msg]
247  lappend v $msg
248} {1 {no such table: test009}}
249
250# Try to drop sqlite_master
251#
252do_test table-5.2 {
253  set v [catch {execsql {DROP TABLE sqlite_master}} msg]
254  lappend v $msg
255} {1 {table sqlite_master may not be dropped}}
256
257# Make sure an EXPLAIN does not really create a new table
258#
259do_test table-5.3 {
260  execsql {EXPLAIN CREATE TABLE test1(f1 int)}
261  execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
262} {}
263
264# Make sure an EXPLAIN does not really drop an existing table
265#
266do_test table-5.4 {
267  execsql {CREATE TABLE test1(f1 int)}
268  execsql {EXPLAIN DROP TABLE test1}
269  execsql {SELECT name FROM sqlite_master WHERE type!='meta'}
270} {test1}
271
272# Create a table with a goofy name
273#
274#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}
279
280# 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,
287      explain int,
288      [14_vac] boolean,
289      fuzzy_dog_12 varchar(10),
290      begin blob,
291      end clob
292    )
293  }} msg]
294  lappend v $msg
295} {0 {}}
296do_test table-7.2 {
297  execsql {
298    INSERT INTO weird VALUES('a','b',9,0,'xyz','hi','y''all');
299    SELECT * FROM weird;
300  }
301} {a b 9 0 xyz hi y'all}
302do_test table-7.3 {
303  execsql2 {
304    SELECT * FROM weird;
305  }
306} {desc a asc b explain 9 14_vac 0 fuzzy_dog_12 xyz begin hi end y'all}
307
308# 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  }
315} {desc a asc b explain 9 14_vac 0 fuzzy_dog_12 xyz begin hi end y'all}
316do_test table-8.1.1 {
317  execsql {
318    SELECT sql FROM sqlite_master WHERE name='t2';
319  }
320} {{CREATE TABLE t2(
321  'desc',
322  'asc',
323  'explain',
324  '14_vac',
325  fuzzy_dog_12,
326  'begin',
327  'end'
328)}}
329do_test table-8.2 {
330  execsql {
331    CREATE TABLE 't3''xyz'(a,b,c);
332    INSERT INTO [t3'xyz] VALUES(1,2,3);
333    SELECT * FROM [t3'xyz];
334  }
335} {1 2 3}
336do_test table-8.3 {
337  execsql2 {
338    CREATE TABLE [t4'abc] AS SELECT count(*) as cnt, max(b+c) FROM [t3'xyz];
339    SELECT * FROM [t4'abc];
340  }
341} {cnt 1 max(b+c) 5}
342do_test table-8.3.1 {
343  execsql {
344    SELECT sql FROM sqlite_master WHERE name='t4''abc'
345  }
346} {{CREATE TABLE 't4''abc'(cnt,'max(b+c)')}}
347do_test table-8.4 {
348  execsql2 {
349    CREATE TEMPORARY TABLE t5 AS SELECT count(*) AS [y'all] FROM [t3'xyz];
350    SELECT * FROM t5;
351  }
352} {y'all 1}
353do_test table-8.5 {
354  db close
355  sqlite db test.db
356  execsql2 {
357    SELECT * FROM [t4'abc];
358  }
359} {cnt 1 max(b+c) 5}
360do_test table-8.6 {
361  execsql2 {
362    SELECT * FROM t2;
363  }
364} {desc a asc b explain 9 14_vac 0 fuzzy_dog_12 xyz begin hi end y'all}
365do_test table-8.7 {
366  catchsql {
367    SELECT * FROM t5;
368  }
369} {1 {no such table: t5}}
370do_test table-8.8 {
371  catchsql {
372    CREATE TABLE t5 AS SELECT * FROM no_such_table;
373  }
374} {1 {no such table: no_such_table}}
375
376# Make sure we cannot have duplicate column names within a table.
377#
378do_test table-9.1 {
379  catchsql {
380    CREATE TABLE t6(a,b,a);
381  }
382} {1 {duplicate column name: a}}
383
384# Check the foreign key syntax.
385#
386do_test table-10.1 {
387  catchsql {
388    CREATE TABLE t6(a REFERENCES t4(a) NOT NULL);
389    INSERT INTO t6 VALUES(NULL);
390  }
391} {1 {t6.a may not be NULL}}
392do_test table-10.2 {
393  catchsql {
394    DROP TABLE t6;
395    CREATE TABLE t6(a REFERENCES t4(a) MATCH PARTIAL);
396  }
397} {0 {}}
398do_test table-10.3 {
399  catchsql {
400    DROP TABLE t6;
401    CREATE TABLE t6(a REFERENCES t4 MATCH FULL ON DELETE SET NULL NOT NULL);
402  }
403} {0 {}}
404do_test table-10.4 {
405  catchsql {
406    DROP TABLE t6;
407    CREATE TABLE t6(a REFERENCES t4 MATCH FULL ON UPDATE SET DEFAULT DEFAULT 1);
408  }
409} {0 {}}
410do_test table-10.5 {
411  catchsql {
412    DROP TABLE t6;
413    CREATE TABLE t6(a NOT NULL NOT DEFERRABLE INITIALLY IMMEDIATE);
414  }
415} {0 {}}
416do_test table-10.6 {
417  catchsql {
418    DROP TABLE t6;
419    CREATE TABLE t6(a NOT NULL DEFERRABLE INITIALLY DEFERRED);
420  }
421} {0 {}}
422do_test table-10.7 {
423  catchsql {
424    DROP TABLE t6;
425    CREATE TABLE t6(a,
426      FOREIGN KEY (a) REFERENCES t4(b) DEFERRABLE INITIALLY DEFERRED
427    );
428  }
429} {0 {}}
430do_test table-10.8 {
431  catchsql {
432    DROP TABLE t6;
433    CREATE TABLE t6(a,b,c,
434      FOREIGN KEY (b,c) REFERENCES t4(x,y) MATCH PARTIAL
435        ON UPDATE SET NULL ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED
436    );
437  }
438} {0 {}}
439do_test table-10.9 {
440  catchsql {
441    DROP TABLE t6;
442    CREATE TABLE t6(a,b,c,
443      FOREIGN KEY (b,c) REFERENCES t4(x)
444    );
445  }
446} {1 {number of columns in foreign key does not match the number of columns in the referenced table}}
447do_test table-10.10 {
448  catchsql {DROP TABLE t6}
449  catchsql {
450    CREATE TABLE t6(a,b,c,
451      FOREIGN KEY (b,c) REFERENCES t4(x,y,z)
452    );
453  }
454} {1 {number of columns in foreign key does not match the number of columns in the referenced table}}
455do_test table-10.11 {
456  catchsql {DROP TABLE t6}
457  catchsql {
458    CREATE TABLE t6(a,b, c REFERENCES t4(x,y));
459  }
460} {1 {foreign key on c should reference only one column of table t4}}
461do_test table-10.12 {
462  catchsql {DROP TABLE t6}
463  catchsql {
464    CREATE TABLE t6(a,b,c,
465      FOREIGN KEY (b,x) REFERENCES t4(x,y)
466    );
467  }
468} {1 {unknown column "x" in foreign key definition}}
469do_test table-10.13 {
470  catchsql {DROP TABLE t6}
471  catchsql {
472    CREATE TABLE t6(a,b,c,
473      FOREIGN KEY (x,b) REFERENCES t4(x,y)
474    );
475  }
476} {1 {unknown column "x" in foreign key definition}}
477
478
479# Test for the "typeof" function.
480#
481do_test table-11.1 {
482  execsql {
483    CREATE TABLE t7(
484       a integer primary key,
485       b number(5,10),
486       c character varying (8),
487       d VARCHAR(9),
488       e clob,
489       f BLOB,
490       g Text,
491       h
492    );
493    INSERT INTO t7(a) VALUES(1);
494    SELECT typeof(a), typeof(b), typeof(c), typeof(d),
495           typeof(e), typeof(f), typeof(g), typeof(h)
496    FROM t7 LIMIT 1;
497  }
498} {numeric numeric text text text text text numeric}
499do_test table-11.2 {
500  execsql {
501    SELECT typeof(a+b), typeof(a||b), typeof(c+d), typeof(c||d)
502    FROM t7 LIMIT 1;
503  }
504} {numeric text numeric text}
505
506finish_test
507