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 script is page cache subsystem.
14 # $Id: collate3.test,v 1.13 2008/08/20 16:35:10 drh Exp $
16 set testdir [file dirname $argv0]
17 source $testdir/tester.tcl
20 # Tests are organised as follows:
22 # collate3.1.* - Errors related to unknown collation sequences.
23 # collate3.2.* - Errors related to undefined collation sequences.
24 # collate3.3.* - Writing to a table that has an index with an undefined c.s.
25 # collate3.4.* - Misc errors.
26 # collate3.5.* - Collation factory.
30 # These tests ensure that when a user executes a statement with an
31 # unknown collation sequence an error is returned.
33 do_test collate3-1.0 {
35 CREATE TABLE collate3t1(c1);
38 do_test collate3-1.1 {
40 SELECT * FROM collate3t1 ORDER BY 1 collate garbage;
42 } {1 {no such collation sequence: garbage}}
43 do_test collate3-1.2 {
45 CREATE TABLE collate3t2(c1 collate garbage);
47 } {1 {no such collation sequence: garbage}}
48 do_test collate3-1.3 {
50 CREATE INDEX collate3i1 ON collate3t1(c1 COLLATE garbage);
52 } {1 {no such collation sequence: garbage}}
55 DROP TABLE collate3t1;
59 # Create a table with a default collation sequence, then close
60 # and re-open the database without re-registering the collation
61 # sequence. Then make sure the library stops us from using
62 # the collation sequence in:
63 # * an explicitly collated ORDER BY
64 # * an ORDER BY that uses the default collation sequence
66 # * a CREATE TABLE statement
67 # * a CREATE INDEX statement that uses a default collation sequence
68 # * a GROUP BY that uses the default collation sequence
69 # * a SELECT DISTINCT that uses the default collation sequence
70 # * Compound SELECTs that uses the default collation sequence
71 # * An ORDER BY on a compound SELECT with an explicit ORDER BY.
73 do_test collate3-2.0 {
74 db collate string_compare {string compare}
76 CREATE TABLE collate3t1(c1 COLLATE string_compare, c2);
82 do_test collate3-2.1 {
84 SELECT * FROM collate3t1 ORDER BY 1 COLLATE string_compare;
86 } {1 {no such collation sequence: string_compare}}
87 do_test collate3-2.2 {
89 SELECT * FROM collate3t1 ORDER BY c1;
91 } {1 {no such collation sequence: string_compare}}
92 do_test collate3-2.3 {
94 SELECT * FROM collate3t1 WHERE c1 = 'xxx';
96 } {1 {no such collation sequence: string_compare}}
97 do_test collate3-2.4 {
99 CREATE TABLE collate3t2(c1 COLLATE string_compare);
101 } {1 {no such collation sequence: string_compare}}
102 do_test collate3-2.5 {
104 CREATE INDEX collate3t1_i1 ON collate3t1(c1);
106 } {1 {no such collation sequence: string_compare}}
107 do_test collate3-2.6 {
109 SELECT * FROM collate3t1;
112 do_test collate3-2.7.1 {
114 SELECT count(*) FROM collate3t1 GROUP BY c1;
116 } {1 {no such collation sequence: string_compare}}
117 # do_test collate3-2.7.2 {
119 # SELECT * FROM collate3t1 GROUP BY c1;
121 # } {1 {GROUP BY may only be used on aggregate queries}}
122 do_test collate3-2.7.2 {
124 SELECT * FROM collate3t1 GROUP BY c1;
126 } {1 {no such collation sequence: string_compare}}
127 do_test collate3-2.8 {
129 SELECT DISTINCT c1 FROM collate3t1;
131 } {1 {no such collation sequence: string_compare}}
134 do_test collate3-2.9 {
136 SELECT c1 FROM collate3t1 UNION SELECT c1 FROM collate3t1;
138 } {1 {no such collation sequence: string_compare}}
139 do_test collate3-2.10 {
141 SELECT c1 FROM collate3t1 EXCEPT SELECT c1 FROM collate3t1;
143 } {1 {no such collation sequence: string_compare}}
144 do_test collate3-2.11 {
146 SELECT c1 FROM collate3t1 INTERSECT SELECT c1 FROM collate3t1;
148 } {1 {no such collation sequence: string_compare}}
149 do_test collate3-2.12 {
151 SELECT c1 FROM collate3t1 UNION ALL SELECT c1 FROM collate3t1;
154 do_test collate3-2.13 {
156 SELECT 10 UNION ALL SELECT 20 ORDER BY 1 COLLATE string_compare;
158 } {1 {no such collation sequence: string_compare}}
159 do_test collate3-2.14 {
161 SELECT 10 INTERSECT SELECT 20 ORDER BY 1 COLLATE string_compare;
163 } {1 {no such collation sequence: string_compare}}
164 do_test collate3-2.15 {
166 SELECT 10 EXCEPT SELECT 20 ORDER BY 1 COLLATE string_compare;
168 } {1 {no such collation sequence: string_compare}}
169 do_test collate3-2.16 {
171 SELECT 10 UNION SELECT 20 ORDER BY 1 COLLATE string_compare;
173 } {1 {no such collation sequence: string_compare}}
174 do_test collate3-2.17 {
176 SELECT c1 FROM collate3t1 UNION ALL SELECT c1 FROM collate3t1 ORDER BY 1;
178 } {1 {no such collation sequence: string_compare}}
179 } ;# ifcapable compound
182 # Create an index that uses a collation sequence then close and
183 # re-open the database without re-registering the collation
184 # sequence. Then check that for the table with the index
186 # * An UPDATE on the column with the index fails,
187 # * An UPDATE on a different column succeeds.
188 # * A DELETE with a WHERE clause fails
189 # * A DELETE without a WHERE clause succeeds
191 # Also, ensure that the restrictions tested by collate3-2.* still
192 # apply after the index has been created.
194 do_test collate3-3.0 {
195 db collate string_compare {string compare}
197 CREATE INDEX collate3t1_i1 ON collate3t1(c1);
198 INSERT INTO collate3t1 VALUES('xxx', 'yyy');
204 db eval {select * from collate3t1}
205 do_test collate3-3.1 {
207 INSERT INTO collate3t1 VALUES('xxx', 0);
209 } {1 {no such collation sequence: string_compare}}
210 do_test collate3-3.2 {
212 UPDATE collate3t1 SET c1 = 'xxx';
214 } {1 {no such collation sequence: string_compare}}
215 do_test collate3-3.3 {
217 UPDATE collate3t1 SET c2 = 'xxx';
220 do_test collate3-3.4 {
222 DELETE FROM collate3t1 WHERE 1;
224 } {1 {no such collation sequence: string_compare}}
225 do_test collate3-3.5 {
227 SELECT * FROM collate3t1;
230 do_test collate3-3.6 {
232 DELETE FROM collate3t1;
235 ifcapable {integrityck} {
236 do_test collate3-3.8 {
238 PRAGMA integrity_check
240 } {1 {no such collation sequence: string_compare}}
242 do_test collate3-3.9 {
244 SELECT * FROM collate3t1;
247 do_test collate3-3.10 {
249 SELECT * FROM collate3t1 ORDER BY 1 COLLATE string_compare;
251 } {1 {no such collation sequence: string_compare}}
252 do_test collate3-3.11 {
254 SELECT * FROM collate3t1 ORDER BY c1;
256 } {1 {no such collation sequence: string_compare}}
257 do_test collate3-3.12 {
259 SELECT * FROM collate3t1 WHERE c1 = 'xxx';
261 } {1 {no such collation sequence: string_compare}}
262 do_test collate3-3.13 {
264 CREATE TABLE collate3t2(c1 COLLATE string_compare);
266 } {1 {no such collation sequence: string_compare}}
267 do_test collate3-3.14 {
269 CREATE INDEX collate3t1_i2 ON collate3t1(c1);
271 } {1 {no such collation sequence: string_compare}}
272 do_test collate3-3.15 {
274 DROP TABLE collate3t1;
278 # Check we can create an index that uses an explicit collation
279 # sequence and then close and re-open the database.
280 do_test collate3-4.6 {
281 db collate user_defined "string compare"
283 CREATE TABLE collate3t1(a, b);
284 INSERT INTO collate3t1 VALUES('hello', NULL);
285 CREATE INDEX collate3i1 ON collate3t1(a COLLATE user_defined);
288 do_test collate3-4.7 {
292 SELECT * FROM collate3t1 ORDER BY a COLLATE user_defined;
294 } {1 {no such collation sequence: user_defined}}
295 do_test collate3-4.8.1 {
296 db collate user_defined "string compare"
298 SELECT * FROM collate3t1 ORDER BY a COLLATE user_defined;
301 do_test collate3-4.8.2 {
307 do_test collate3-4.8.3 {
309 DROP TABLE collate3t1;
313 # Compare strings as numbers.
314 proc numeric_compare {lhs rhs} {
318 set res [expr ($lhs > $rhs)?1:0]
323 # Check we can create a view that uses an explicit collation
324 # sequence and then close and re-open the database.
326 do_test collate3-4.9 {
327 db collate user_defined numeric_compare
329 CREATE TABLE collate3t1(a, b);
330 INSERT INTO collate3t1 VALUES('2', NULL);
331 INSERT INTO collate3t1 VALUES('101', NULL);
332 INSERT INTO collate3t1 VALUES('12', NULL);
333 CREATE VIEW collate3v1 AS SELECT * FROM collate3t1
334 ORDER BY 1 COLLATE user_defined;
335 SELECT * FROM collate3v1;
337 } {2 {} 12 {} 101 {}}
338 do_test collate3-4.10 {
342 SELECT * FROM collate3v1;
344 } {1 {no such collation sequence: user_defined}}
345 do_test collate3-4.11 {
346 db collate user_defined numeric_compare
348 SELECT * FROM collate3v1;
350 } {0 {2 {} 12 {} 101 {}}}
351 do_test collate3-4.12 {
353 DROP TABLE collate3t1;
359 # Test the collation factory. In the code, the "no such collation sequence"
360 # message is only generated in two places. So these tests just test that
361 # the collation factory can be called once from each of those points.
363 do_test collate3-5.0 {
365 CREATE TABLE collate3t1(a);
366 INSERT INTO collate3t1 VALUES(10);
367 SELECT a FROM collate3t1 ORDER BY 1 COLLATE unk;
369 } {1 {no such collation sequence: unk}}
370 do_test collate3-5.1 {
373 db collate $nm {string compare}
376 db collation_needed cfact
378 do_test collate3-5.2 {
380 SELECT a FROM collate3t1 ORDER BY 1 COLLATE unk;
383 do_test collate3-5.3 {
386 do_test collate3-5.4 {
388 SELECT a FROM collate3t1 ORDER BY 1 COLLATE unk;
391 do_test collate3-5.5 {
394 do_test collate3-5.6 {
396 SELECT a FROM collate3t1 ORDER BY 1 COLLATE unk;
399 do_test collate3-5.7 {
401 DROP TABLE collate3t1;
402 CREATE TABLE collate3t1(a COLLATE unk);
407 SELECT a FROM collate3t1 ORDER BY 1;
409 } {1 {no such collation sequence: unk}}
410 do_test collate3-5.8 {
413 db collate $nm {string compare}
416 db collation_needed cfact
418 SELECT a FROM collate3t1 ORDER BY 1;
422 do_test collate3-5.9 {
424 DROP TABLE collate3t1;