blob: 81c17d8a3c7a3308c6287d2c9e3effde6da8a077 [file] [log] [blame]
drhdb5ed6d2001-09-18 22:17:44 +00001# 2001 September 15
2#
3# The author disclaims copyright to this source code. In place of
4# a legal notice, here is a blessing:
5#
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.
9#
10#***********************************************************************
11# This file implements regression tests for SQLite library.
12#
13# This file implements tests for miscellanous features that were
14# left out of other test files.
15#
drhfec19aa2004-05-19 20:41:03 +000016# $Id: misc1.test,v 1.24 2004/05/19 20:41:04 drh Exp $
drhdb5ed6d2001-09-18 22:17:44 +000017
18set testdir [file dirname $argv0]
19source $testdir/tester.tcl
20
21# Test the creation and use of tables that have a large number
22# of columns.
23#
24do_test misc1-1.1 {
25 set cmd "CREATE TABLE manycol(x0 text"
26 for {set i 1} {$i<=99} {incr i} {
27 append cmd ",x$i text"
28 }
29 append cmd ")";
30 execsql $cmd
31 set cmd "INSERT INTO manycol VALUES(0"
32 for {set i 1} {$i<=99} {incr i} {
33 append cmd ",$i"
34 }
35 append cmd ")";
36 execsql $cmd
37 execsql "SELECT x99 FROM manycol"
38} 99
39do_test misc1-1.2 {
40 execsql {SELECT x0, x10, x25, x50, x75 FROM manycol}
41} {0 10 25 50 75}
drha9e99ae2002-08-13 23:02:57 +000042do_test misc1-1.3.1 {
drhdb5ed6d2001-09-18 22:17:44 +000043 for {set j 100} {$j<=1000} {incr j 100} {
44 set cmd "INSERT INTO manycol VALUES($j"
45 for {set i 1} {$i<=99} {incr i} {
46 append cmd ",[expr {$i+$j}]"
47 }
48 append cmd ")"
49 execsql $cmd
50 }
drha9e99ae2002-08-13 23:02:57 +000051 execsql {SELECT x50 FROM manycol ORDER BY x80+0}
drhdb5ed6d2001-09-18 22:17:44 +000052} {50 150 250 350 450 550 650 750 850 950 1050}
drha9e99ae2002-08-13 23:02:57 +000053do_test misc1-1.3.2 {
54 execsql {SELECT x50 FROM manycol ORDER BY x80}
55} {1050 150 250 350 450 550 650 750 50 850 950}
drhdb5ed6d2001-09-18 22:17:44 +000056do_test misc1-1.4 {
57 execsql {SELECT x75 FROM manycol WHERE x50=350}
58} 375
59do_test misc1-1.5 {
60 execsql {SELECT x50 FROM manycol WHERE x99=599}
61} 550
62do_test misc1-1.6 {
63 execsql {CREATE INDEX manycol_idx1 ON manycol(x99)}
64 execsql {SELECT x50 FROM manycol WHERE x99=899}
65} 850
66do_test misc1-1.7 {
67 execsql {SELECT count(*) FROM manycol}
68} 11
69do_test misc1-1.8 {
70 execsql {DELETE FROM manycol WHERE x98=1234}
71 execsql {SELECT count(*) FROM manycol}
72} 11
73do_test misc1-1.9 {
74 execsql {DELETE FROM manycol WHERE x98=998}
75 execsql {SELECT count(*) FROM manycol}
76} 10
77do_test misc1-1.10 {
78 execsql {DELETE FROM manycol WHERE x99=500}
79 execsql {SELECT count(*) FROM manycol}
80} 10
81do_test misc1-1.11 {
82 execsql {DELETE FROM manycol WHERE x99=599}
83 execsql {SELECT count(*) FROM manycol}
84} 9
85
86# Check GROUP BY expressions that name two or more columns.
87#
88do_test misc1-2.1 {
89 execsql {
90 BEGIN TRANSACTION;
91 CREATE TABLE agger(one text, two text, three text, four text);
92 INSERT INTO agger VALUES(1, 'one', 'hello', 'yes');
93 INSERT INTO agger VALUES(2, 'two', 'howdy', 'no');
94 INSERT INTO agger VALUES(3, 'thr', 'howareya', 'yes');
95 INSERT INTO agger VALUES(4, 'two', 'lothere', 'yes');
96 INSERT INTO agger VALUES(5, 'one', 'atcha', 'yes');
97 INSERT INTO agger VALUES(6, 'two', 'hello', 'no');
98 COMMIT
99 }
100 execsql {SELECT count(*) FROM agger}
101} 6
102do_test misc1-2.2 {
103 execsql {SELECT sum(one), two, four FROM agger
104 GROUP BY two, four ORDER BY sum(one) desc}
105} {8 two no 6 one yes 4 two yes 3 thr yes}
drh6977fea2002-10-22 23:38:04 +0000106do_test misc1-2.3 {
107 execsql {SELECT sum((one)), (two), (four) FROM agger
108 GROUP BY (two), (four) ORDER BY sum(one) desc}
109} {8 two no 6 one yes 4 two yes 3 thr yes}
drhdb5ed6d2001-09-18 22:17:44 +0000110
drh97665872002-02-13 23:22:53 +0000111# Here's a test for a bug found by Joel Lucsy. The code below
112# was causing an assertion failure.
113#
114do_test misc1-3.1 {
115 set r [execsql {
116 CREATE TABLE t1(a);
117 INSERT INTO t1 VALUES('hi');
118 PRAGMA full_column_names=on;
119 SELECT rowid, * FROM t1;
120 }]
121 lindex $r 1
122} {hi}
123
drh1e336b42002-02-14 12:50:33 +0000124# Here's a test for yet another bug found by Joel Lucsy. The code
125# below was causing an assertion failure.
126#
127do_test misc1-4.1 {
128 execsql {
129 BEGIN;
130 CREATE TABLE t2(a);
131 INSERT INTO t2 VALUES('This is a long string to use up a lot of disk -');
132 UPDATE t2 SET a=a||a||a||a;
133 INSERT INTO t2 SELECT '1 - ' || a FROM t2;
134 INSERT INTO t2 SELECT '2 - ' || a FROM t2;
135 INSERT INTO t2 SELECT '3 - ' || a FROM t2;
136 INSERT INTO t2 SELECT '4 - ' || a FROM t2;
137 INSERT INTO t2 SELECT '5 - ' || a FROM t2;
138 INSERT INTO t2 SELECT '6 - ' || a FROM t2;
139 COMMIT;
140 SELECT count(*) FROM t2;
141 }
142} {64}
143
drh094b2bb2002-03-13 18:54:07 +0000144# Make sure we actually see a semicolon or end-of-file in the SQL input
145# before executing a command. Thus if "WHERE" is misspelled on an UPDATE,
146# the user won't accidently update every record.
147#
148do_test misc1-5.1 {
149 catchsql {
150 CREATE TABLE t3(a,b);
151 INSERT INTO t3 VALUES(1,2);
152 INSERT INTO t3 VALUES(3,4);
153 UPDATE t3 SET a=0 WHEREwww b=2;
154 }
155} {1 {near "WHEREwww": syntax error}}
156do_test misc1-5.2 {
157 execsql {
158 SELECT * FROM t3 ORDER BY a;
159 }
160} {1 2 3 4}
161
drhf18543c2002-03-30 15:26:50 +0000162# Certain keywords (especially non-standard keywords like "REPLACE") can
163# also be used as identifiers. The way this works in the parser is that
164# the parser first detects a syntax error, the error handling routine
165# sees that the special keyword caused the error, then replaces the keyword
166# with "ID" and tries again.
167#
168# Check the operation of this logic.
169#
170do_test misc1-6.1 {
171 catchsql {
172 CREATE TABLE t4(
173 abort, asc, begin, cluster, conflict, copy, delimiters, desc, end,
174 explain, fail, ignore, key, offset, pragma, replace, temp,
175 vacuum, view
176 );
177 }
178} {0 {}}
179do_test misc1-6.2 {
180 catchsql {
181 INSERT INTO t4
182 VALUES(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19);
183 }
184} {0 {}}
185do_test misc1-6.3 {
186 execsql {
187 SELECT * FROM t4
188 }
189} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19}
190do_test misc1-6.4 {
191 execsql {
192 SELECT abort+asc,max(key,pragma,temp) FROM t4
193 }
194} {3 17}
drh2e392e22002-05-24 02:14:50 +0000195
196# Test for multi-column primary keys, and for multiple primary keys.
197#
198do_test misc1-7.1 {
199 catchsql {
200 CREATE TABLE error1(
201 a TYPE PRIMARY KEY,
202 b TYPE PRIMARY KEY
203 );
204 }
205} {1 {table "error1" has more than one primary key}}
206do_test misc1-7.2 {
207 catchsql {
208 CREATE TABLE error1(
209 a INTEGER PRIMARY KEY,
210 b TYPE PRIMARY KEY
211 );
212 }
213} {1 {table "error1" has more than one primary key}}
214do_test misc1-7.3 {
215 execsql {
216 CREATE TABLE t5(a,b,c,PRIMARY KEY(a,b));
217 INSERT INTO t5 VALUES(1,2,3);
218 SELECT * FROM t5 ORDER BY a;
219 }
220} {1 2 3}
221do_test misc1-7.4 {
222 catchsql {
223 INSERT INTO t5 VALUES(1,2,4);
224 }
drh37ed48e2003-08-05 13:13:38 +0000225} {1 {columns a, b are not unique}}
drh2e392e22002-05-24 02:14:50 +0000226do_test misc1-7.5 {
227 catchsql {
228 INSERT INTO t5 VALUES(0,2,4);
229 }
230} {0 {}}
231do_test misc1-7.6 {
232 execsql {
233 SELECT * FROM t5 ORDER BY a;
234 }
235} {0 2 4 1 2 3}
236
drhf5db2d32002-06-06 23:42:27 +0000237do_test misc1-8.1 {
238 catchsql {
239 SELECT *;
240 }
241} {1 {no tables specified}}
242do_test misc1-8.2 {
243 catchsql {
244 SELECT t1.*;
245 }
246} {1 {no such table: t1}}
247
drhd9e30932002-06-09 01:16:01 +0000248execsql {
249 DROP TABLE t1;
250 DROP TABLE t2;
251 DROP TABLE t3;
252 DROP TABLE t4;
253}
254
drhfec19aa2004-05-19 20:41:03 +0000255# 64-bit integers are represented exactly.
drhd9e30932002-06-09 01:16:01 +0000256#
257do_test misc1-9.1 {
258 catchsql {
259 CREATE TABLE t1(a unique not null, b unique not null);
drhfec19aa2004-05-19 20:41:03 +0000260 INSERT INTO t1 VALUES('a',1234567890123456789);
261 INSERT INTO t1 VALUES('b',1234567891123456789);
262 INSERT INTO t1 VALUES('c',1234567892123456789);
drhd9e30932002-06-09 01:16:01 +0000263 SELECT * FROM t1;
264 }
drhfec19aa2004-05-19 20:41:03 +0000265} {0 {a 1234567890123456789 b 1234567891123456789 c 1234567892123456789}}
drhd9e30932002-06-09 01:16:01 +0000266
drh83dcb1a2002-06-28 01:02:38 +0000267# A WHERE clause is not allowed to contain more than 99 terms. Check to
268# make sure this limit is enforced.
269#
270do_test misc1-10.0 {
271 execsql {SELECT count(*) FROM manycol}
272} {9}
273do_test misc1-10.1 {
274 set ::where {WHERE x0>=0}
275 for {set i 1} {$i<=99} {incr i} {
276 append ::where " AND x$i<>0"
277 }
278 catchsql "SELECT count(*) FROM manycol $::where"
279} {0 9}
280do_test misc1-10.2 {
281 catchsql "SELECT count(*) FROM manycol $::where AND rowid>0"
282} {1 {WHERE clause too complex - no more than 100 terms allowed}}
283do_test misc1-10.3 {
284 regsub "x0>=0" $::where "x0=0" ::where
285 catchsql "DELETE FROM manycol $::where"
286} {0 {}}
287do_test misc1-10.4 {
288 execsql {SELECT count(*) FROM manycol}
289} {8}
290do_test misc1-10.5 {
291 catchsql "DELETE FROM manycol $::where AND rowid>0"
292} {1 {WHERE clause too complex - no more than 100 terms allowed}}
293do_test misc1-10.6 {
294 execsql {SELECT x1 FROM manycol WHERE x0=100}
295} {101}
296do_test misc1-10.7 {
297 regsub "x0=0" $::where "x0=100" ::where
298 catchsql "UPDATE manycol SET x1=x1+1 $::where"
299} {0 {}}
300do_test misc1-10.8 {
301 execsql {SELECT x1 FROM manycol WHERE x0=100}
302} {102}
303do_test misc1-10.9 {
304 catchsql "UPDATE manycol SET x1=x1+1 $::where AND rowid>0"
305} {1 {WHERE clause too complex - no more than 100 terms allowed}}
306do_test misc1-10.10 {
307 execsql {SELECT x1 FROM manycol WHERE x0=100}
308} {102}
309
drh92ed08a2002-07-30 18:43:40 +0000310# Make sure the initialization works even if a database is opened while
311# another process has the database locked.
312#
313do_test misc1-11.1 {
314 execsql {BEGIN}
315 sqlite db2 test.db
316 set rc [catch {db2 eval {SELECT count(*) FROM t1}} msg]
317 lappend rc $msg
318} {1 {database is locked}}
319do_test misc1-11.2 {
320 execsql {COMMIT}
321 set rc [catch {db2 eval {SELECT count(*) FROM t1}} msg]
322 db2 close
323 lappend rc $msg
324} {0 3}
325
drh310ae7b2002-08-15 11:48:13 +0000326# Make sure string comparisons really do compare strings in format4+.
327# Similar tests in the format3.test file show that for format3 and earlier
328# all comparisions where numeric if either operand looked like a number.
329#
330do_test misc1-12.1 {
331 execsql {SELECT '0'=='0.0'}
drhfec19aa2004-05-19 20:41:03 +0000332} {1}
drh310ae7b2002-08-15 11:48:13 +0000333do_test misc1-12.2 {
334 execsql {SELECT '0'==0.0}
335} {1}
336do_test misc1-12.3 {
337 execsql {SELECT '12345678901234567890'=='12345678901234567891'}
338} {0}
339do_test misc1-12.4 {
340 execsql {
341 CREATE TABLE t6(a INT UNIQUE, b TEXT UNIQUE);
342 INSERT INTO t6 VALUES('0','0.0');
343 SELECT * FROM t6;
344 }
345} {0 0.0}
346do_test misc1-12.5 {
347 execsql {
348 INSERT OR IGNORE INTO t6 VALUES(0.0,'x');
349 SELECT * FROM t6;
350 }
351} {0 0.0}
352do_test misc1-12.6 {
353 execsql {
354 INSERT OR IGNORE INTO t6 VALUES('y',0);
355 SELECT * FROM t6;
356 }
357} {0 0.0 y 0}
358do_test misc1-12.7 {
359 execsql {
360 CREATE TABLE t7(x INTEGER, y TEXT, z);
361 INSERT INTO t7 VALUES(0,0,1);
362 INSERT INTO t7 VALUES(0.0,0,2);
363 INSERT INTO t7 VALUES(0,0.0,3);
364 INSERT INTO t7 VALUES(0.0,0.0,4);
365 SELECT DISTINCT x, y FROM t7 ORDER BY z;
366 }
367} {0 0 0 0.0}
drhf04d5082002-08-18 22:41:22 +0000368do_test misc1-12.8 {
369 execsql {
370 SELECT min(z), max(z), count(z) FROM t7 GROUP BY x ORDER BY 1;
371 }
372} {1 4 4}
373do_test misc1-12.9 {
374 execsql {
375 SELECT min(z), max(z), count(z) FROM t7 GROUP BY y ORDER BY 1;
376 }
377} {1 2 2 3 4 2}
drhfcb78a42003-01-18 20:11:05 +0000378
379# This used to be an error. But we changed the code so that arbitrary
380# identifiers can be used as a collating sequence. Collation is by text
381# if the identifier contains "text", "blob", or "clob" and is numeric
382# otherwise.
drhf04d5082002-08-18 22:41:22 +0000383do_test misc1-12.10 {
384 catchsql {
385 SELECT * FROM t6 ORDER BY a COLLATE unknown;
386 }
drhfcb78a42003-01-18 20:11:05 +0000387} {0 {0 0.0 y 0}}
drhf04d5082002-08-18 22:41:22 +0000388do_test misc1-12.11 {
389 execsql {
390 CREATE TABLE t8(x TEXT COLLATE numeric, y INTEGER COLLATE text, z);
391 INSERT INTO t8 VALUES(0,0,1);
392 INSERT INTO t8 VALUES(0.0,0,2);
393 INSERT INTO t8 VALUES(0,0.0,3);
394 INSERT INTO t8 VALUES(0.0,0.0,4);
395 SELECT DISTINCT x, y FROM t8 ORDER BY z;
396 }
drhfec19aa2004-05-19 20:41:03 +0000397} {0 0 0.0 0}
drhf04d5082002-08-18 22:41:22 +0000398do_test misc1-12.12 {
399 execsql {
400 SELECT min(z), max(z), count(z) FROM t8 GROUP BY x ORDER BY 1;
401 }
drhfec19aa2004-05-19 20:41:03 +0000402} {1 3 2 2 4 2}
drhf04d5082002-08-18 22:41:22 +0000403do_test misc1-12.13 {
404 execsql {
405 SELECT min(z), max(z), count(z) FROM t8 GROUP BY y ORDER BY 1;
406 }
drhfec19aa2004-05-19 20:41:03 +0000407} {1 4 4}
drhf04d5082002-08-18 22:41:22 +0000408
drh3e56c042002-09-17 03:20:46 +0000409# There was a problem with realloc() in the OP_MemStore operation of
410# the VDBE. A buffer was being reallocated but some pointers into
411# the old copy of the buffer were not being moved over to the new copy.
412# The following code tests for the problem.
413#
414do_test misc1-13.1 {
415 execsql {
416 CREATE TABLE t9(x,y);
417 INSERT INTO t9 VALUES('one',1);
418 INSERT INTO t9 VALUES('two',2);
419 INSERT INTO t9 VALUES('three',3);
420 INSERT INTO t9 VALUES('four',4);
421 INSERT INTO t9 VALUES('five',5);
422 INSERT INTO t9 VALUES('six',6);
423 INSERT INTO t9 VALUES('seven',7);
424 INSERT INTO t9 VALUES('eight',8);
425 INSERT INTO t9 VALUES('nine',9);
426 INSERT INTO t9 VALUES('ten',10);
427 INSERT INTO t9 VALUES('eleven',11);
428 SELECT y FROM t9
429 WHERE x=(SELECT x FROM t9 WHERE y=1)
430 OR x=(SELECT x FROM t9 WHERE y=2)
431 OR x=(SELECT x FROM t9 WHERE y=3)
432 OR x=(SELECT x FROM t9 WHERE y=4)
433 OR x=(SELECT x FROM t9 WHERE y=5)
434 OR x=(SELECT x FROM t9 WHERE y=6)
435 OR x=(SELECT x FROM t9 WHERE y=7)
436 OR x=(SELECT x FROM t9 WHERE y=8)
437 OR x=(SELECT x FROM t9 WHERE y=9)
438 OR x=(SELECT x FROM t9 WHERE y=10)
439 OR x=(SELECT x FROM t9 WHERE y=11)
440 OR x=(SELECT x FROM t9 WHERE y=12)
441 OR x=(SELECT x FROM t9 WHERE y=13)
442 OR x=(SELECT x FROM t9 WHERE y=14)
443 ;
444 }
445} {1 2 3 4 5 6 7 8 9 10 11}
drh310ae7b2002-08-15 11:48:13 +0000446
drh3e7a6092002-12-07 21:45:14 +0000447# Make sure a database connection still works after changing the
448# working directory.
449#
450do_test misc1-14.1 {
451 file mkdir tempdir
452 cd tempdir
453 execsql {BEGIN}
454 file exists ./test.db-journal
455} {0}
456do_test misc1-14.2 {
457 file exists ../test.db-journal
458} {1}
459do_test misc1-14.3 {
460 cd ..
461 file delete tempdir
462 execsql {COMMIT}
463 file exists ./test.db-journal
464} {0}
465
drh17e9e292003-02-01 13:53:28 +0000466# A failed create table should not leave the table in the internal
467# data structures. Ticket #238.
468#
469do_test misc1-15.1 {
470 catchsql {
471 CREATE TABLE t10 AS SELECT c1;
472 }
473} {1 {no such column: c1}}
474do_test misc1-15.2 {
475 catchsql {
476 CREATE TABLE t10 AS SELECT 1;
477 }
478 # The bug in ticket #238 causes the statement above to fail with
479 # the error "table t10 alread exists"
480} {0 {}}
drh3e7a6092002-12-07 21:45:14 +0000481
drhe0194f22003-02-26 13:52:51 +0000482# Test for memory leaks when a CREATE TABLE containing a primary key
483# fails. Ticket #249.
484#
485do_test misc1-16.1 {
486 catchsql {SELECT name FROM sqlite_master LIMIT 1}
487 catchsql {
488 CREATE TABLE test(a integer, primary key(a));
489 }
490} {0 {}}
491do_test misc1-16.2 {
492 catchsql {
493 CREATE TABLE test(a integer, primary key(a));
494 }
495} {1 {table test already exists}}
496do_test misc1-16.3 {
497 catchsql {
498 CREATE TABLE test2(a text primary key, b text, primary key(a,b));
499 }
500} {1 {table "test2" has more than one primary key}}
501do_test misc1-16.4 {
502 execsql {
503 INSERT INTO test VALUES(1);
504 SELECT rowid, a FROM test;
505 }
506} {1 1}
507do_test misc1-16.5 {
508 execsql {
509 INSERT INTO test VALUES(5);
510 SELECT rowid, a FROM test;
511 }
512} {1 1 5 5}
513do_test misc1-16.6 {
514 execsql {
515 INSERT INTO test VALUES(NULL);
516 SELECT rowid, a FROM test;
517 }
518} {1 1 5 5 6 6}
519
drh4312db52003-06-03 01:47:11 +0000520# Ticket #333: Temp triggers that modify persistent tables.
521#
522do_test misc1-17.1 {
523 execsql {
524 BEGIN;
525 CREATE TABLE RealTable(TestID INTEGER PRIMARY KEY, TestString TEXT);
526 CREATE TEMP TABLE TempTable(TestID INTEGER PRIMARY KEY, TestString TEXT);
527 CREATE TEMP TRIGGER trigTest_1 AFTER UPDATE ON TempTable BEGIN
528 INSERT INTO RealTable(TestString)
529 SELECT new.TestString FROM TempTable LIMIT 1;
530 END;
531 INSERT INTO TempTable(TestString) VALUES ('1');
532 INSERT INTO TempTable(TestString) VALUES ('2');
533 UPDATE TempTable SET TestString = TestString + 1 WHERE TestID IN (1, 2);
534 COMMIT;
535 SELECT TestString FROM RealTable ORDER BY 1;
536 }
537} {2 3}
drhe0194f22003-02-26 13:52:51 +0000538
drhdb5ed6d2001-09-18 22:17:44 +0000539finish_test