DRH and Sqlite Community,
 
 Provide two sql functions: toupper() and tolower() that can be applied. And 
always use binary comparison.
 
 so:
 select x from where toupper(y) = 'HELLO' ;
 would return 1 row...
 
 But here is the gotcha, more than likely applying that function would negate 
the use of an index that would be on column y. I would think that apply a 
function transformation for use on an indexed column would have pretty bad 
performance. 
 
 On the other hand something like:
 select y from where x= tolower('HELLO' ) ;
 would also return 1 row. And should have no problems utilizing an existing 
indices since the function is only applied once to the sql, not to the stored 
index data values.
 
 Also other systems such as Oracle for instance use things like NLS_COMP, 
NLS_SORT to manipulate sorting characteristics. These can be environment 
variables ora can be set as part of an "alter session" command (Similar to a 
sqlite PRAGMA).
 
 Regards,
 Ken
 
 
 
 
 
 

[EMAIL PROTECTED] wrote: SQLite has supported collating sequences since version 
3.0.0.
A collating sequence is really a specification on how comparison
operators work on strings.

You can have arbitrary collating sequences in SQLite.  But for
the sake of this discussion, lets focus on just two:  BINARY
which is the default collating sequence, and NOCASE which does
case insensitive comparisons (on US-ASCII).

Consider this example table:

   CREATE TABLE t1(
     x TEXT COLLATE BINARY,
     y TEXT COLLATE NOCASE
   );
   INSERT INTO t1 VALUES('hello','Hello');

This query returns one row because comparisons against column y
ignore case:

   SELECT * FROM t1 WHERE y='HELLO';

This query returns no rows because comparisons against column x
take case into account.

   SELECT * FROM t1 WHERE x='HELLO';

When comparing two columns, the column on the left determines which
collating sequence to use.  In the first of the following two queries,
the column on the left uses NOCASE so one row is returned.  But in
the second query, the columns are reversed and the left-most column
uses BINARY.  As a result, no rows are returned from the second
query:

   SELECT * FROM t1 WHERE y=x;
   SELECT * FROM t1 WHERE x=y;

This last point seems a little goofy, but SQLite is documented as
working that way and the situation comes up so very rarely that nobody
has yet complained.

The problem with all of the above is that the collating sequence
on a column is specified when the column is declared and cannot
be changed.  What many people would like to have is some way to 
specify a different collating sequence to override the default
collating sequence for a single comparison.  The question is, what
should the syntax be.  Here are some ideas:

    SELECT * FROM t1 WHERE x='HELLO' COLLATE NOCASE;

Here the = operator has some added syntax at the end.  There some
parsing abiguities with this approach, but they can be dealt with
just as they are with the EXCEPT clause on a LIKE operator.  The
comparison operator syntax would be like this:

       [COLLATE ]

Another idea is to use CAST:

     SELECT * FROM t1 WHERE CAST(x AS TEXT COLLATE NOCASE)='HELLO';

Or perhaps

     SELECT * FROM t1 WHERE CASE(x COLLATE NOCASE)='HELLO';

A third idea is to invent entirely new syntax, perhaps like this:

     SELECT * FROM t1 WHERE COLLATE NOCASE(x='HELLO')

Please note that while I have used the = operator in all of the
examples above, everything applies equally to !=, <, <=, >, and >=.

Questions for SQLite community members:

  (1)  Is there some standard SQL syntax that I do not know about
       for doing this kind of thing?

  (2)  How do other SQL engines do this kind of thing?

  (3)  Do you have any additional (hopefully better) ideas for
       specifying alternative collating sequences on individual
       comparison operators.

  (4)  What syntax do you prefer?

--
D. Richard Hipp  



-----------------------------------------------------------------------------
To unsubscribe, send email to [EMAIL PROTECTED]
-----------------------------------------------------------------------------


Reply via email to