Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / sqlite / src / test / collate3.test
blob2c051cb9a74fbdca4b60cdebace083de0cc4d090
1 # 2001 September 15
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 {
34   execsql {
35     CREATE TABLE collate3t1(c1);
36   }
37 } {}
38 do_test collate3-1.1 {
39   catchsql {
40     SELECT * FROM collate3t1 ORDER BY 1 collate garbage;
41   }
42 } {1 {no such collation sequence: garbage}}
43 do_test collate3-1.2 {
44   catchsql {
45     CREATE TABLE collate3t2(c1 collate garbage);
46   }
47 } {1 {no such collation sequence: garbage}}
48 do_test collate3-1.3 {
49   catchsql {
50     CREATE INDEX collate3i1 ON collate3t1(c1 COLLATE garbage);
51   }
52 } {1 {no such collation sequence: garbage}}
54 execsql {
55   DROP TABLE collate3t1;
58 proc caseless {a b} { string compare -nocase $a $b }
59 do_test collate3-1.4 {
60   db collate caseless caseless
61   execsql { 
62     CREATE TABLE t1(a COLLATE caseless); 
63     INSERT INTO t1 VALUES('Abc2');
64     INSERT INTO t1 VALUES('abc1');
65     INSERT INTO t1 VALUES('aBc3');
66   }
67   execsql { SELECT * FROM t1 ORDER BY a }
68 } {abc1 Abc2 aBc3}
70 do_test collate3-1.5 {
71   db close
72   sqlite3 db test.db
73   catchsql { SELECT * FROM t1 ORDER BY a }
74 } {1 {no such collation sequence: caseless}}
76 do_test collate3-1.6.1 {
77   db collate caseless caseless
78   execsql { CREATE INDEX i1 ON t1(a) }
79   execsql { SELECT * FROM t1 ORDER BY a }
80 } {abc1 Abc2 aBc3}
82 do_test collate3-1.6.2 {
83   db close
84   sqlite3 db test.db
85   catchsql { SELECT * FROM t1 ORDER BY a }
86 } {1 {no such collation sequence: caseless}}
88 do_test collate3-1.6.3 {
89   db close
90   sqlite3 db test.db
91   catchsql { PRAGMA integrity_check }
92 } {1 {no such collation sequence: caseless}}
94 do_test collate3-1.6.4 {
95   db close
96   sqlite3 db test.db
97   catchsql { REINDEX }
98 } {1 {no such collation sequence: caseless}}
100 do_test collate3-1.7.1 {
101   db collate caseless caseless
102   execsql {
103     DROP TABLE t1;
104     CREATE TABLE t1(a);
105     CREATE INDEX i1 ON t1(a COLLATE caseless);
106     INSERT INTO t1 VALUES('Abc2');
107     INSERT INTO t1 VALUES('abc1');
108     INSERT INTO t1 VALUES('aBc3');
109     SELECT * FROM t1 ORDER BY a COLLATE caseless;
110   }
111 } {abc1 Abc2 aBc3}
113 do_test collate3-1.7.2 {
114   db close
115   sqlite3 db test.db
116   catchsql { SELECT * FROM t1 ORDER BY a COLLATE caseless}
117 } {1 {no such collation sequence: caseless}}
119 do_test collate3-1.7.4 {
120   db close
121   sqlite3 db test.db
122   catchsql { REINDEX }
123 } {1 {no such collation sequence: caseless}}
125 do_test collate3-1.7.3 {
126   db close
127   sqlite3 db test.db
128   catchsql { PRAGMA integrity_check }
129 } {1 {no such collation sequence: caseless}}
131 do_test collate3-1.7.4 {
132   db close
133   sqlite3 db test.db
134   catchsql { REINDEX }
135 } {1 {no such collation sequence: caseless}}
137 do_test collate3-1.7.5 {
138   db close
139   sqlite3 db test.db
140   db collate caseless caseless
141   catchsql { PRAGMA integrity_check }
142 } {0 ok}
144 proc needed {nm} { db collate caseless caseless }
145 do_test collate3-1.7.6 {
146   db close
147   sqlite3 db test.db
148   db collation_needed needed
149   catchsql { PRAGMA integrity_check }
150 } {0 ok}
152 do_test collate3-1.8 {
153   execsql { DROP TABLE t1 }
154 } {}
157 # Create a table with a default collation sequence, then close
158 # and re-open the database without re-registering the collation
159 # sequence. Then make sure the library stops us from using
160 # the collation sequence in:
161 # * an explicitly collated ORDER BY
162 # * an ORDER BY that uses the default collation sequence
163 # * an expression (=)
164 # * a CREATE TABLE statement
165 # * a CREATE INDEX statement that uses a default collation sequence
166 # * a GROUP BY that uses the default collation sequence
167 # * a SELECT DISTINCT that uses the default collation sequence
168 # * Compound SELECTs that uses the default collation sequence
169 # * An ORDER BY on a compound SELECT with an explicit ORDER BY.
171 do_test collate3-2.0 {
172   db collate string_compare {string compare}
173   execsql {
174     CREATE TABLE collate3t1(c1 COLLATE string_compare, c2);
175   }
176   db close
177   sqlite3 db test.db
178   expr 0
179 } 0
180 do_test collate3-2.1 {
181   catchsql {
182     SELECT * FROM collate3t1 ORDER BY 1 COLLATE string_compare;
183   }
184 } {1 {no such collation sequence: string_compare}} 
185 do_test collate3-2.2 {
186   catchsql {
187     SELECT * FROM collate3t1 ORDER BY c1;
188   }
189 } {1 {no such collation sequence: string_compare}} 
190 do_test collate3-2.3 {
191   catchsql {
192     SELECT * FROM collate3t1 WHERE c1 = 'xxx';
193   }
194 } {1 {no such collation sequence: string_compare}} 
195 do_test collate3-2.4 {
196   catchsql {
197     CREATE TABLE collate3t2(c1 COLLATE string_compare);
198   }
199 } {1 {no such collation sequence: string_compare}} 
200 do_test collate3-2.5 {
201   catchsql {
202     CREATE INDEX collate3t1_i1 ON collate3t1(c1);
203   }
204 } {1 {no such collation sequence: string_compare}}
205 do_test collate3-2.6 {
206   catchsql {
207     SELECT * FROM collate3t1;
208   }
209 } {0 {}}
210 do_test collate3-2.7.1 {
211   catchsql {
212     SELECT count(*) FROM collate3t1 GROUP BY c1;
213   }
214 } {1 {no such collation sequence: string_compare}} 
215 # do_test collate3-2.7.2 {
216 #   catchsql {
217 #     SELECT * FROM collate3t1 GROUP BY c1;
218 #   }
219 # } {1 {GROUP BY may only be used on aggregate queries}}
220 do_test collate3-2.7.2 {
221   catchsql {
222     SELECT * FROM collate3t1 GROUP BY c1;
223   }
224 } {1 {no such collation sequence: string_compare}} 
225 do_test collate3-2.8 {
226   catchsql {
227     SELECT DISTINCT c1 FROM collate3t1;
228   }
229 } {1 {no such collation sequence: string_compare}} 
231 ifcapable compound {
232   do_test collate3-2.9 {
233     catchsql {
234       SELECT c1 FROM collate3t1 UNION SELECT c1 FROM collate3t1;
235     }
236   } {1 {no such collation sequence: string_compare}} 
237   do_test collate3-2.10 {
238     catchsql {
239       SELECT c1 FROM collate3t1 EXCEPT SELECT c1 FROM collate3t1;
240     }
241   } {1 {no such collation sequence: string_compare}} 
242   do_test collate3-2.11 {
243     catchsql {
244       SELECT c1 FROM collate3t1 INTERSECT SELECT c1 FROM collate3t1;
245     }
246   } {1 {no such collation sequence: string_compare}} 
247   do_test collate3-2.12 {
248     catchsql {
249       SELECT c1 FROM collate3t1 UNION ALL SELECT c1 FROM collate3t1;
250     }
251   } {0 {}}
252   do_test collate3-2.13 {
253     catchsql {
254       SELECT 10 UNION ALL SELECT 20 ORDER BY 1 COLLATE string_compare;
255     }
256   } {1 {no such collation sequence: string_compare}} 
257   do_test collate3-2.14 {
258     catchsql {
259       SELECT 10 INTERSECT SELECT 20 ORDER BY 1 COLLATE string_compare;
260     }
261   } {1 {no such collation sequence: string_compare}} 
262   do_test collate3-2.15 {
263     catchsql {
264       SELECT 10 EXCEPT SELECT 20 ORDER BY 1 COLLATE string_compare;
265     }
266   } {1 {no such collation sequence: string_compare}} 
267   do_test collate3-2.16 {
268     catchsql {
269       SELECT 10 UNION SELECT 20 ORDER BY 1 COLLATE string_compare;
270     }
271   } {1 {no such collation sequence: string_compare}} 
272   do_test collate3-2.17 {
273     catchsql {
274       SELECT c1 FROM collate3t1 UNION ALL SELECT c1 FROM collate3t1 ORDER BY 1;
275     }
276   } {1 {no such collation sequence: string_compare}} 
277 } ;# ifcapable compound
280 # Create an index that uses a collation sequence then close and
281 # re-open the database without re-registering the collation
282 # sequence. Then check that for the table with the index 
283 # * An INSERT fails,
284 # * An UPDATE on the column with the index fails,
285 # * An UPDATE on a different column succeeds.
286 # * A DELETE with a WHERE clause fails
287 # * A DELETE without a WHERE clause succeeds
289 # Also, ensure that the restrictions tested by collate3-2.* still
290 # apply after the index has been created.
292 do_test collate3-3.0 {
293   db collate string_compare {string compare}
294   execsql {
295     CREATE INDEX collate3t1_i1 ON collate3t1(c1);
296     INSERT INTO collate3t1 VALUES('xxx', 'yyy');
297   }
298   db close
299   sqlite3 db test.db
300   expr 0
301 } 0
302 db eval {select * from collate3t1}
303 do_test collate3-3.1 {
304   catchsql {
305     INSERT INTO collate3t1 VALUES('xxx', 0);
306   }
307 } {1 {no such collation sequence: string_compare}} 
308 do_test collate3-3.2 {
309   catchsql {
310     UPDATE collate3t1 SET c1 = 'xxx';
311   }
312 } {1 {no such collation sequence: string_compare}} 
313 do_test collate3-3.3 {
314   catchsql {
315     UPDATE collate3t1 SET c2 = 'xxx';
316   }
317 } {0 {}}
318 do_test collate3-3.4 {
319   catchsql {
320     DELETE FROM collate3t1 WHERE 1;
321   }
322 } {1 {no such collation sequence: string_compare}} 
323 do_test collate3-3.5 {
324   catchsql {
325     SELECT * FROM collate3t1;
326   }
327 } {0 {xxx xxx}}
328 do_test collate3-3.6 {
329   catchsql {
330     DELETE FROM collate3t1;
331   }
332 } {0 {}}
333 ifcapable {integrityck} {
334   do_test collate3-3.8 {
335     catchsql {
336       PRAGMA integrity_check
337     }
338   } {1 {no such collation sequence: string_compare}}
340 do_test collate3-3.9 {
341   catchsql {
342     SELECT * FROM collate3t1;
343   }
344 } {0 {}}
345 do_test collate3-3.10 {
346   catchsql {
347     SELECT * FROM collate3t1 ORDER BY 1 COLLATE string_compare;
348   }
349 } {1 {no such collation sequence: string_compare}} 
350 do_test collate3-3.11 {
351   catchsql {
352     SELECT * FROM collate3t1 ORDER BY c1;
353   }
354 } {1 {no such collation sequence: string_compare}} 
355 do_test collate3-3.12 {
356   catchsql {
357     SELECT * FROM collate3t1 WHERE c1 = 'xxx';
358   }
359 } {1 {no such collation sequence: string_compare}} 
360 do_test collate3-3.13 {
361   catchsql {
362     CREATE TABLE collate3t2(c1 COLLATE string_compare);
363   }
364 } {1 {no such collation sequence: string_compare}} 
365 do_test collate3-3.14 {
366   catchsql {
367     CREATE INDEX collate3t1_i2 ON collate3t1(c1);
368   }
369 } {1 {no such collation sequence: string_compare}} 
370 do_test collate3-3.15 {
371   execsql {
372     DROP TABLE collate3t1;
373   }
374 } {}
376 # Check we can create an index that uses an explicit collation 
377 # sequence and then close and re-open the database.
378 do_test collate3-4.6 {
379   db collate user_defined "string compare"
380   execsql {
381     CREATE TABLE collate3t1(a, b);
382     INSERT INTO collate3t1 VALUES('hello', NULL);
383     CREATE INDEX collate3i1 ON collate3t1(a COLLATE user_defined);
384   }
385 } {}
386 do_test collate3-4.7 {
387   db close
388   sqlite3 db test.db
389   catchsql {
390     SELECT * FROM collate3t1 ORDER BY a COLLATE user_defined;
391   }
392 } {1 {no such collation sequence: user_defined}}
393 do_test collate3-4.8.1 {
394   db collate user_defined "string compare"
395   catchsql {
396     SELECT * FROM collate3t1 ORDER BY a COLLATE user_defined;
397   }
398 } {0 {hello {}}}
399 do_test collate3-4.8.2 {
400   db close
401   lindex [catch {
402     sqlite3 db test.db
403   }] 0
404 } {0}
405 do_test collate3-4.8.3 {
406   execsql {
407     DROP TABLE collate3t1;
408   }
409 } {}
411 # Compare strings as numbers.
412 proc numeric_compare {lhs rhs} {
413   if {$rhs > $lhs} {
414     set res -1
415   } else {
416     set res [expr ($lhs > $rhs)?1:0]
417   }
418   return $res
421 # Check we can create a view that uses an explicit collation 
422 # sequence and then close and re-open the database.
423 ifcapable view {
424 do_test collate3-4.9 {
425   db collate user_defined numeric_compare
426   execsql {
427     CREATE TABLE collate3t1(a, b);
428     INSERT INTO collate3t1 VALUES('2', NULL);
429     INSERT INTO collate3t1 VALUES('101', NULL);
430     INSERT INTO collate3t1 VALUES('12', NULL);
431     CREATE VIEW collate3v1 AS SELECT * FROM collate3t1 
432         ORDER BY 1 COLLATE user_defined;
433     SELECT * FROM collate3v1;
434   }
435 } {2 {} 12 {} 101 {}}
436 do_test collate3-4.10 {
437   db close
438   sqlite3 db test.db
439   catchsql {
440     SELECT * FROM collate3v1;
441   }
442 } {1 {no such collation sequence: user_defined}}
443 do_test collate3-4.11 {
444   db collate user_defined numeric_compare
445   catchsql {
446     SELECT * FROM collate3v1;
447   }
448 } {0 {2 {} 12 {} 101 {}}}
449 do_test collate3-4.12 {
450   execsql {
451     DROP TABLE collate3t1;
452   }
453 } {}
454 } ;# ifcapable view
457 # Test the collation factory. In the code, the "no such collation sequence"
458 # message is only generated in two places. So these tests just test that
459 # the collation factory can be called once from each of those points.
461 do_test collate3-5.0 {
462   catchsql {
463     CREATE TABLE collate3t1(a);
464     INSERT INTO collate3t1 VALUES(10);
465     SELECT a FROM collate3t1 ORDER BY 1 COLLATE unk;
466   }
467 } {1 {no such collation sequence: unk}}
468 do_test collate3-5.1 {
469   set ::cfact_cnt 0
470   proc cfact {nm} {
471     db collate $nm {string compare}
472     incr ::cfact_cnt
473   }
474   db collation_needed cfact
475 } {}
476 do_test collate3-5.2 {
477   catchsql {
478     SELECT a FROM collate3t1 ORDER BY 1 COLLATE unk;
479   }
480 } {0 10}
481 do_test collate3-5.3 {
482   set ::cfact_cnt
483 } {1}
484 do_test collate3-5.4 {
485   catchsql {
486     SELECT a FROM collate3t1 ORDER BY 1 COLLATE unk;
487   }
488 } {0 10}
489 do_test collate3-5.5 {
490   set ::cfact_cnt
491 } {1}
492 do_test collate3-5.6 {
493   catchsql {
494     SELECT a FROM collate3t1 ORDER BY 1 COLLATE unk;
495   }
496 } {0 10}
497 do_test collate3-5.7 {
498   execsql {
499     DROP TABLE collate3t1;
500     CREATE TABLE collate3t1(a COLLATE unk);
501   }
502   db close
503   sqlite3 db test.db
504   catchsql {
505     SELECT a FROM collate3t1 ORDER BY 1;
506   }
507 } {1 {no such collation sequence: unk}}
508 do_test collate3-5.8 {
509   set ::cfact_cnt 0
510   proc cfact {nm} {
511     db collate $nm {string compare}
512     incr ::cfact_cnt
513   }
514   db collation_needed cfact
515   catchsql {
516     SELECT a FROM collate3t1 ORDER BY 1;
517   }
518 } {0 {}}
520 do_test collate3-5.9 {
521   execsql {
522     DROP TABLE collate3t1;
523   }
524 } {}
526 finish_test