/ Check-in [0bf4e7fe]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add the RTRIM collating sequence. Only implemented for UTF8. Still considered experimental and may be removed if we find adverse impact elsewhere in the system. (CVS 4732)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 0bf4e7fefdbbf7be4e32195473563158f22f1869
User & Date: drh 2008-01-20 23:19:57
References
2019-06-14
13:25 Fixed ticket [f1580ba1]: Built-in RTRIM collating sequence yields incorrect comparisons plus 8 other changes artifact: 71c96e66 user: drh
Context
2008-01-21
13:04
Remove some unused branches from internal function sqlite3PagerDontRollback(). (CVS 4733) check-in: 3d4252b0 user: danielk1977 tags: trunk
2008-01-20
23:19
Add the RTRIM collating sequence. Only implemented for UTF8. Still considered experimental and may be removed if we find adverse impact elsewhere in the system. (CVS 4732) check-in: 0bf4e7fe user: drh tags: trunk
2008-01-19
23:50
Additional test coverage improvements. Test coverage now stands at 98.73%. (CVS 4731) check-in: 010f7b78 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/main.c.

    10     10   **
    11     11   *************************************************************************
    12     12   ** Main file for the SQLite library.  The routines in this file
    13     13   ** implement the programmer interface to the library.  Routines in
    14     14   ** other files are for internal use by SQLite and should not be
    15     15   ** accessed by users of the library.
    16     16   **
    17         -** $Id: main.c,v 1.409 2007/12/07 18:55:28 drh Exp $
           17  +** $Id: main.c,v 1.410 2008/01/20 23:19:57 drh Exp $
    18     18   */
    19     19   #include "sqliteInt.h"
    20     20   #include <ctype.h>
    21     21   
    22     22   /*
    23     23   ** The version of the library
    24     24   */
................................................................................
    40     40   ** name of a directory, then that directory will be used to store
    41     41   ** temporary files.
    42     42   **
    43     43   ** See also the "PRAGMA temp_store_directory" SQL command.
    44     44   */
    45     45   char *sqlite3_temp_directory = 0;
    46     46   
           47  +
           48  +/*
           49  +** Return true if the buffer z[0..n-1] contains all spaces.
           50  +*/
           51  +static int allSpaces(const char *z, int n){
           52  +  while( n>0 && z[--n]==' ' ){}
           53  +  return n==0;
           54  +}
    47     55   
    48     56   /*
    49     57   ** This is the default collating function named "BINARY" which is always
    50     58   ** available.
           59  +**
           60  +** If the padFlag argument is not NULL then space padding at the end
           61  +** of strings is ignored.  This implements the RTRIM collation.
    51     62   */
    52     63   static int binCollFunc(
    53         -  void *NotUsed,
           64  +  void *padFlag,
    54     65     int nKey1, const void *pKey1,
    55     66     int nKey2, const void *pKey2
    56     67   ){
    57     68     int rc, n;
    58     69     n = nKey1<nKey2 ? nKey1 : nKey2;
    59     70     rc = memcmp(pKey1, pKey2, n);
    60     71     if( rc==0 ){
    61         -    rc = nKey1 - nKey2;
           72  +    if( padFlag
           73  +     && allSpaces(((char*)pKey1)+n, nKey1-n)
           74  +     && allSpaces(((char*)pKey2)+n, nKey2-n)
           75  +    ){
           76  +      /* Leave rc unchanged at 0 */
           77  +    }else{
           78  +      rc = nKey1 - nKey2;
           79  +    }
    62     80     }
    63     81     return rc;
    64     82   }
    65     83   
    66     84   /*
    67     85   ** Another built-in collating sequence: NOCASE. 
    68     86   **
................................................................................
   990   1008     /* Add the default collation sequence BINARY. BINARY works for both UTF-8
   991   1009     ** and UTF-16, so add a version for each to avoid any unnecessary
   992   1010     ** conversions. The only error that can occur here is a malloc() failure.
   993   1011     */
   994   1012     if( createCollation(db, "BINARY", SQLITE_UTF8, 0, binCollFunc, 0) ||
   995   1013         createCollation(db, "BINARY", SQLITE_UTF16BE, 0, binCollFunc, 0) ||
   996   1014         createCollation(db, "BINARY", SQLITE_UTF16LE, 0, binCollFunc, 0) ||
         1015  +      createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0) ||
   997   1016         (db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 6, 0))==0 
   998   1017     ){
   999   1018       assert( db->mallocFailed );
  1000   1019       db->magic = SQLITE_MAGIC_CLOSED;
  1001   1020       goto opendb_out;
  1002   1021     }
  1003   1022   

Added test/collateA.test.

            1  +#
            2  +# 2008 January 20
            3  +#
            4  +# The author disclaims copyright to this source code.  In place of
            5  +# a legal notice, here is a blessing:
            6  +#
            7  +#    May you do good and not evil.
            8  +#    May you find forgiveness for yourself and forgive others.
            9  +#    May you share freely, never taking more than you give.
           10  +#
           11  +#***********************************************************************
           12  +# This file implements regression tests for SQLite library.  The
           13  +# focus of this script is the built-in RTRIM collating
           14  +# API.
           15  +#
           16  +# $Id: collateA.test,v 1.1 2008/01/20 23:19:58 drh Exp $
           17  +
           18  +set testdir [file dirname $argv0]
           19  +source $testdir/tester.tcl
           20  +
           21  +do_test collateA-1.1 {
           22  +  execsql {
           23  +    CREATE TABLE t1(
           24  +      a INTEGER PRIMARY KEY,
           25  +      b TEXT COLLATE BINARY,
           26  +      c TEXT COLLATE RTRIM
           27  +    );
           28  +    INSERT INTO t1 VALUES(1, 'hello','hello');
           29  +    INSERT INTO t1 VALUES(2, 'xyzzy ','xyzzy ');
           30  +    INSERT INTO t1 VALUES(3, 'xyzzy  ','xyzzy  ');
           31  +    INSERT INTO t1 VALUES(4, 'xyzzy   ','xyzzy   ');
           32  +    SELECT count(*) FROM t1;
           33  +  }
           34  +} {4}
           35  +do_test collateA-1.2 {
           36  +  execsql {SELECT a FROM t1 WHERE b='hello     '}
           37  +} {}
           38  +do_test collateA-1.3 {
           39  +  execsql {SELECT a FROM t1 WHERE c='hello     '}
           40  +} {1}
           41  +do_test collateA-1.4 {
           42  +  execsql {SELECT a FROM t1 WHERE b='xyzzy'}
           43  +} {}
           44  +do_test collateA-1.5 {
           45  +  execsql {SELECT a FROM t1 WHERE c='xyzzy'}
           46  +} {2 3 4}
           47  +do_test collateA-1.6 {
           48  +  execsql {SELECT a FROM t1 WHERE c='xyzzy '}
           49  +} {2 3 4}
           50  +do_test collateA-1.7 {
           51  +  execsql {SELECT a FROM t1 WHERE c='xyzzy  '}
           52  +} {2 3 4}
           53  +do_test collateA-1.8 {
           54  +  execsql {SELECT a FROM t1 WHERE c='xyzzy   '}
           55  +} {2 3 4}
           56  +do_test collateA-1.9 {
           57  +  execsql {SELECT a FROM t1 WHERE c='xyzzy    '}
           58  +} {2 3 4}
           59  +do_test collateA-1.10 {
           60  +  execsql {SELECT a FROM t1 WHERE c='xyzzy                                  '}
           61  +} {2 3 4}
           62  +do_test collateA-1.11 {
           63  +  execsql {SELECT 'abc123'='abc123                         ' COLLATE RTRIM;}
           64  +} {1}
           65  +do_test collateA-1.12 {
           66  +  execsql {SELECT 'abc123                         '='abc123' COLLATE RTRIM;}
           67  +} {1}
           68  +
           69  +do_test collateA-2.1 {
           70  +  execsql {
           71  +    CREATE INDEX i1b ON t1(b);
           72  +    CREATE INDEX i1c ON t1(c);
           73  +    PRAGMA integrity_check;
           74  +  }
           75  +} {ok}
           76  +do_test collateA-2.2 {
           77  +  execsql {SELECT a FROM t1 WHERE b='hello     '}
           78  +} {}
           79  +do_test collateA-2.3 {
           80  +  execsql {SELECT a FROM t1 WHERE c='hello     '}
           81  +} {1}
           82  +do_test collateA-2.4 {
           83  +  execsql {SELECT a FROM t1 WHERE b='xyzzy'}
           84  +} {}
           85  +do_test collateA-2.5 {
           86  +  execsql {SELECT a FROM t1 WHERE c='xyzzy'}
           87  +} {2 3 4}
           88  +do_test collateA-2.6 {
           89  +  execsql {SELECT a FROM t1 WHERE c='xyzzy '}
           90  +} {2 3 4}
           91  +do_test collateA-2.7 {
           92  +  execsql {SELECT a FROM t1 WHERE c='xyzzy  '}
           93  +} {2 3 4}
           94  +do_test collateA-2.8 {
           95  +  execsql {SELECT a FROM t1 WHERE c='xyzzy   '}
           96  +} {2 3 4}
           97  +do_test collateA-2.9 {
           98  +  execsql {SELECT a FROM t1 WHERE c='xyzzy    '}
           99  +} {2 3 4}
          100  +do_test collateA-2.10 {
          101  +  execsql {SELECT a FROM t1 WHERE c='xyzzy                                  '}
          102  +} {2 3 4}
          103  +
          104  +do_test collateA-3.1 {
          105  +  db close
          106  +  sqlite3 db test.db
          107  +  execsql {
          108  +    REINDEX;
          109  +    PRAGMA integrity_check;
          110  +  }
          111  +} {ok}
          112  +do_test collateA-3.2 {
          113  +  execsql {SELECT a FROM t1 WHERE b='hello     '}
          114  +} {}
          115  +do_test collateA-3.3 {
          116  +  execsql {SELECT a FROM t1 WHERE c='hello     '}
          117  +} {1}
          118  +do_test collateA-3.4 {
          119  +  execsql {SELECT a FROM t1 WHERE b='xyzzy'}
          120  +} {}
          121  +do_test collateA-3.5 {
          122  +  execsql {SELECT a FROM t1 WHERE c='xyzzy'}
          123  +} {2 3 4}
          124  +do_test collateA-3.6 {
          125  +  execsql {SELECT a FROM t1 WHERE c='xyzzy '}
          126  +} {2 3 4}
          127  +do_test collateA-3.7 {
          128  +  execsql {SELECT a FROM t1 WHERE c='xyzzy  '}
          129  +} {2 3 4}
          130  +do_test collateA-3.8 {
          131  +  execsql {SELECT a FROM t1 WHERE c='xyzzy   '}
          132  +} {2 3 4}
          133  +do_test collateA-3.9 {
          134  +  execsql {SELECT a FROM t1 WHERE c='xyzzy    '}
          135  +} {2 3 4}
          136  +do_test collateA-3.10 {
          137  +  execsql {SELECT a FROM t1 WHERE c='xyzzy                                  '}
          138  +} {2 3 4}
          139  +
          140  +
          141  +finish_test

Changes to test/pragma.test.

     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.
    12     12   #
    13     13   # This file implements tests for the PRAGMA command.
    14     14   #
    15         -# $Id: pragma.test,v 1.56 2007/12/29 13:39:21 danielk1977 Exp $
           15  +# $Id: pragma.test,v 1.57 2008/01/20 23:19:58 drh Exp $
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
    19     19   
    20     20   # Test organization:
    21     21   #
    22     22   # pragma-1.*: Test cache_size, default_cache_size and synchronous on main db.
................................................................................
   974    974   } ;# ifcapable trigger
   975    975   
   976    976   ifcapable schema_pragmas {
   977    977     do_test pragma-11.1 {
   978    978       execsql2 {
   979    979         pragma collation_list;
   980    980       }
   981         -  } {seq 0 name NOCASE seq 1 name BINARY}
          981  +  } {seq 0 name NOCASE seq 1 name RTRIM seq 2 name BINARY}
   982    982     do_test pragma-11.2 {
   983    983       db collate New_Collation blah...
   984    984       execsql {
   985    985         pragma collation_list;
   986    986       }
   987         -  } {0 New_Collation 1 NOCASE 2 BINARY}
          987  +  } {0 New_Collation 1 NOCASE 2 RTRIM 3 BINARY}
   988    988   }
   989    989   
   990    990   ifcapable schema_pragmas&&tempdb {
   991    991     do_test pragma-12.1 {
   992    992       sqlite3 db2 test.db
   993    993       execsql {
   994    994         PRAGMA temp.table_info('abc');