os/persistentdata/persistentstorage/sqlite3api/TEST/TclScript/collate3.test
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 # 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.  The
    12 # focus of this script is page cache subsystem.
    13 #
    14 # $Id: collate3.test,v 1.13 2008/08/20 16:35:10 drh Exp $
    15 
    16 set testdir [file dirname $argv0]
    17 source $testdir/tester.tcl
    18 
    19 #
    20 # Tests are organised as follows:
    21 #
    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.
    27 #
    28 
    29 #
    30 # These tests ensure that when a user executes a statement with an 
    31 # unknown collation sequence an error is returned.
    32 #
    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}}
    53 
    54 execsql {
    55   DROP TABLE collate3t1;
    56 }
    57 
    58 #
    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
    65 # * an expression (=)
    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.
    72 #
    73 do_test collate3-2.0 {
    74   db collate string_compare {string compare}
    75   execsql {
    76     CREATE TABLE collate3t1(c1 COLLATE string_compare, c2);
    77   }
    78   db close
    79   sqlite3 db test.db
    80   expr 0
    81 } 0
    82 do_test collate3-2.1 {
    83   catchsql {
    84     SELECT * FROM collate3t1 ORDER BY 1 COLLATE string_compare;
    85   }
    86 } {1 {no such collation sequence: string_compare}} 
    87 do_test collate3-2.2 {
    88   catchsql {
    89     SELECT * FROM collate3t1 ORDER BY c1;
    90   }
    91 } {1 {no such collation sequence: string_compare}} 
    92 do_test collate3-2.3 {
    93   catchsql {
    94     SELECT * FROM collate3t1 WHERE c1 = 'xxx';
    95   }
    96 } {1 {no such collation sequence: string_compare}} 
    97 do_test collate3-2.4 {
    98   catchsql {
    99     CREATE TABLE collate3t2(c1 COLLATE string_compare);
   100   }
   101 } {1 {no such collation sequence: string_compare}} 
   102 do_test collate3-2.5 {
   103   catchsql {
   104     CREATE INDEX collate3t1_i1 ON collate3t1(c1);
   105   }
   106 } {1 {no such collation sequence: string_compare}}
   107 do_test collate3-2.6 {
   108   catchsql {
   109     SELECT * FROM collate3t1;
   110   }
   111 } {0 {}}
   112 do_test collate3-2.7.1 {
   113   catchsql {
   114     SELECT count(*) FROM collate3t1 GROUP BY c1;
   115   }
   116 } {1 {no such collation sequence: string_compare}} 
   117 # do_test collate3-2.7.2 {
   118 #   catchsql {
   119 #     SELECT * FROM collate3t1 GROUP BY c1;
   120 #   }
   121 # } {1 {GROUP BY may only be used on aggregate queries}}
   122 do_test collate3-2.7.2 {
   123   catchsql {
   124     SELECT * FROM collate3t1 GROUP BY c1;
   125   }
   126 } {1 {no such collation sequence: string_compare}} 
   127 do_test collate3-2.8 {
   128   catchsql {
   129     SELECT DISTINCT c1 FROM collate3t1;
   130   }
   131 } {1 {no such collation sequence: string_compare}} 
   132 
   133 ifcapable compound {
   134   do_test collate3-2.9 {
   135     catchsql {
   136       SELECT c1 FROM collate3t1 UNION SELECT c1 FROM collate3t1;
   137     }
   138   } {1 {no such collation sequence: string_compare}} 
   139   do_test collate3-2.10 {
   140     catchsql {
   141       SELECT c1 FROM collate3t1 EXCEPT SELECT c1 FROM collate3t1;
   142     }
   143   } {1 {no such collation sequence: string_compare}} 
   144   do_test collate3-2.11 {
   145     catchsql {
   146       SELECT c1 FROM collate3t1 INTERSECT SELECT c1 FROM collate3t1;
   147     }
   148   } {1 {no such collation sequence: string_compare}} 
   149   do_test collate3-2.12 {
   150     catchsql {
   151       SELECT c1 FROM collate3t1 UNION ALL SELECT c1 FROM collate3t1;
   152     }
   153   } {0 {}}
   154   do_test collate3-2.13 {
   155     catchsql {
   156       SELECT 10 UNION ALL SELECT 20 ORDER BY 1 COLLATE string_compare;
   157     }
   158   } {1 {no such collation sequence: string_compare}} 
   159   do_test collate3-2.14 {
   160     catchsql {
   161       SELECT 10 INTERSECT SELECT 20 ORDER BY 1 COLLATE string_compare;
   162     }
   163   } {1 {no such collation sequence: string_compare}} 
   164   do_test collate3-2.15 {
   165     catchsql {
   166       SELECT 10 EXCEPT SELECT 20 ORDER BY 1 COLLATE string_compare;
   167     }
   168   } {1 {no such collation sequence: string_compare}} 
   169   do_test collate3-2.16 {
   170     catchsql {
   171       SELECT 10 UNION SELECT 20 ORDER BY 1 COLLATE string_compare;
   172     }
   173   } {1 {no such collation sequence: string_compare}} 
   174   do_test collate3-2.17 {
   175     catchsql {
   176       SELECT c1 FROM collate3t1 UNION ALL SELECT c1 FROM collate3t1 ORDER BY 1;
   177     }
   178   } {1 {no such collation sequence: string_compare}} 
   179 } ;# ifcapable compound
   180 
   181 #
   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 
   185 # * An INSERT fails,
   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
   190 #
   191 # Also, ensure that the restrictions tested by collate3-2.* still
   192 # apply after the index has been created.
   193 #
   194 do_test collate3-3.0 {
   195   db collate string_compare {string compare}
   196   execsql {
   197     CREATE INDEX collate3t1_i1 ON collate3t1(c1);
   198     INSERT INTO collate3t1 VALUES('xxx', 'yyy');
   199   }
   200   db close
   201   sqlite3 db test.db
   202   expr 0
   203 } 0
   204 db eval {select * from collate3t1}
   205 do_test collate3-3.1 {
   206   catchsql {
   207     INSERT INTO collate3t1 VALUES('xxx', 0);
   208   }
   209 } {1 {no such collation sequence: string_compare}} 
   210 do_test collate3-3.2 {
   211   catchsql {
   212     UPDATE collate3t1 SET c1 = 'xxx';
   213   }
   214 } {1 {no such collation sequence: string_compare}} 
   215 do_test collate3-3.3 {
   216   catchsql {
   217     UPDATE collate3t1 SET c2 = 'xxx';
   218   }
   219 } {0 {}}
   220 do_test collate3-3.4 {
   221   catchsql {
   222     DELETE FROM collate3t1 WHERE 1;
   223   }
   224 } {1 {no such collation sequence: string_compare}} 
   225 do_test collate3-3.5 {
   226   catchsql {
   227     SELECT * FROM collate3t1;
   228   }
   229 } {0 {xxx xxx}}
   230 do_test collate3-3.6 {
   231   catchsql {
   232     DELETE FROM collate3t1;
   233   }
   234 } {0 {}}
   235 ifcapable {integrityck} {
   236   do_test collate3-3.8 {
   237     catchsql {
   238       PRAGMA integrity_check
   239     }
   240   } {1 {no such collation sequence: string_compare}}
   241 }
   242 do_test collate3-3.9 {
   243   catchsql {
   244     SELECT * FROM collate3t1;
   245   }
   246 } {0 {}}
   247 do_test collate3-3.10 {
   248   catchsql {
   249     SELECT * FROM collate3t1 ORDER BY 1 COLLATE string_compare;
   250   }
   251 } {1 {no such collation sequence: string_compare}} 
   252 do_test collate3-3.11 {
   253   catchsql {
   254     SELECT * FROM collate3t1 ORDER BY c1;
   255   }
   256 } {1 {no such collation sequence: string_compare}} 
   257 do_test collate3-3.12 {
   258   catchsql {
   259     SELECT * FROM collate3t1 WHERE c1 = 'xxx';
   260   }
   261 } {1 {no such collation sequence: string_compare}} 
   262 do_test collate3-3.13 {
   263   catchsql {
   264     CREATE TABLE collate3t2(c1 COLLATE string_compare);
   265   }
   266 } {1 {no such collation sequence: string_compare}} 
   267 do_test collate3-3.14 {
   268   catchsql {
   269     CREATE INDEX collate3t1_i2 ON collate3t1(c1);
   270   }
   271 } {1 {no such collation sequence: string_compare}} 
   272 do_test collate3-3.15 {
   273   execsql {
   274     DROP TABLE collate3t1;
   275   }
   276 } {}
   277 
   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"
   282   execsql {
   283     CREATE TABLE collate3t1(a, b);
   284     INSERT INTO collate3t1 VALUES('hello', NULL);
   285     CREATE INDEX collate3i1 ON collate3t1(a COLLATE user_defined);
   286   }
   287 } {}
   288 do_test collate3-4.7 {
   289   db close
   290   sqlite3 db test.db
   291   catchsql {
   292     SELECT * FROM collate3t1 ORDER BY a COLLATE user_defined;
   293   }
   294 } {1 {no such collation sequence: user_defined}}
   295 do_test collate3-4.8.1 {
   296   db collate user_defined "string compare"
   297   catchsql {
   298     SELECT * FROM collate3t1 ORDER BY a COLLATE user_defined;
   299   }
   300 } {0 {hello {}}}
   301 do_test collate3-4.8.2 {
   302   db close
   303   lindex [catch {
   304     sqlite3 db test.db
   305   }] 0
   306 } {0}
   307 do_test collate3-4.8.3 {
   308   execsql {
   309     DROP TABLE collate3t1;
   310   }
   311 } {}
   312 
   313 # Compare strings as numbers.
   314 proc numeric_compare {lhs rhs} {
   315   if {$rhs > $lhs} {
   316     set res -1
   317   } else {
   318     set res [expr ($lhs > $rhs)?1:0]
   319   }
   320   return $res
   321 }
   322 
   323 # Check we can create a view that uses an explicit collation 
   324 # sequence and then close and re-open the database.
   325 ifcapable view {
   326 do_test collate3-4.9 {
   327   db collate user_defined numeric_compare
   328   execsql {
   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;
   336   }
   337 } {2 {} 12 {} 101 {}}
   338 do_test collate3-4.10 {
   339   db close
   340   sqlite3 db test.db
   341   catchsql {
   342     SELECT * FROM collate3v1;
   343   }
   344 } {1 {no such collation sequence: user_defined}}
   345 do_test collate3-4.11 {
   346   db collate user_defined numeric_compare
   347   catchsql {
   348     SELECT * FROM collate3v1;
   349   }
   350 } {0 {2 {} 12 {} 101 {}}}
   351 do_test collate3-4.12 {
   352   execsql {
   353     DROP TABLE collate3t1;
   354   }
   355 } {}
   356 } ;# ifcapable view
   357 
   358 #
   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.
   362 #
   363 do_test collate3-5.0 {
   364   catchsql {
   365     CREATE TABLE collate3t1(a);
   366     INSERT INTO collate3t1 VALUES(10);
   367     SELECT a FROM collate3t1 ORDER BY 1 COLLATE unk;
   368   }
   369 } {1 {no such collation sequence: unk}}
   370 do_test collate3-5.1 {
   371   set ::cfact_cnt 0
   372   proc cfact {nm} {
   373     db collate $nm {string compare}
   374     incr ::cfact_cnt
   375   }
   376   db collation_needed cfact
   377 } {}
   378 do_test collate3-5.2 {
   379   catchsql {
   380     SELECT a FROM collate3t1 ORDER BY 1 COLLATE unk;
   381   }
   382 } {0 10}
   383 do_test collate3-5.3 {
   384   set ::cfact_cnt
   385 } {1}
   386 do_test collate3-5.4 {
   387   catchsql {
   388     SELECT a FROM collate3t1 ORDER BY 1 COLLATE unk;
   389   }
   390 } {0 10}
   391 do_test collate3-5.5 {
   392   set ::cfact_cnt
   393 } {1}
   394 do_test collate3-5.6 {
   395   catchsql {
   396     SELECT a FROM collate3t1 ORDER BY 1 COLLATE unk;
   397   }
   398 } {0 10}
   399 do_test collate3-5.7 {
   400   execsql {
   401     DROP TABLE collate3t1;
   402     CREATE TABLE collate3t1(a COLLATE unk);
   403   }
   404   db close
   405   sqlite3 db test.db
   406   catchsql {
   407     SELECT a FROM collate3t1 ORDER BY 1;
   408   }
   409 } {1 {no such collation sequence: unk}}
   410 do_test collate3-5.8 {
   411   set ::cfact_cnt 0
   412   proc cfact {nm} {
   413     db collate $nm {string compare}
   414     incr ::cfact_cnt
   415   }
   416   db collation_needed cfact
   417   catchsql {
   418     SELECT a FROM collate3t1 ORDER BY 1;
   419   }
   420 } {0 {}}
   421 
   422 do_test collate3-5.9 {
   423   execsql {
   424     DROP TABLE collate3t1;
   425   }
   426 } {}
   427 
   428 finish_test