/ Check-in [86fa0087]
Login

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

Overview
Comment:Fix the implementation of the built-in RTRIM collating sequence so that it works for control characters at the end of the string. Ticket [f1580ba1b574e9e9]
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 86fa0087cd1f5c79ed51b99a226ec2eef5b0fa0a23981d469bec0e02fadf2a68
User & Date: drh 2019-06-14 13:24:46
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
2019-06-14
17:37
Deprecate the SQLITE_ALLOW_COVERING_INDEX_SCAN compile-time option when it is turned off. This probably will impact no-one. If it does, they will get an error message instructing them to contact developers, so that we can get feedback that somebody is actually using this feature. Start-time disabling of covering index scan is not affected. check-in: 23e49f99 user: drh tags: trunk
13:24
Fix the implementation of the built-in RTRIM collating sequence so that it works for control characters at the end of the string. Ticket [f1580ba1b574e9e9] check-in: 86fa0087 user: drh tags: trunk
12:28
Refactor the LIKE optimization decision logic so that it uses sqlite3AtoF() on both boundary keys to determine if the optimization can be used when the LHS is something that might not have TEXT affinity. Ticket [ce8717f0885af975]. See also [c94369cae9b561b1], [b043a54c3de54b28], [fd76310a5e843e07], and [158290c0abafde67]. check-in: b4a9e09e user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/main.c.

   871    871         break;
   872    872       }
   873    873     }
   874    874     va_end(ap);
   875    875     return rc;
   876    876   }
   877    877   
   878         -
   879         -/*
   880         -** Return true if the buffer z[0..n-1] contains all spaces.
   881         -*/
   882         -static int allSpaces(const char *z, int n){
   883         -  while( n>0 && z[n-1]==' ' ){ n--; }
   884         -  return n==0;
   885         -}
   886         -
   887    878   /*
   888    879   ** This is the default collating function named "BINARY" which is always
   889    880   ** available.
   890         -**
   891         -** If the padFlag argument is not NULL then space padding at the end
   892         -** of strings is ignored.  This implements the RTRIM collation.
   893    881   */
   894    882   static int binCollFunc(
   895         -  void *padFlag,
          883  +  void *NotUsed,
   896    884     int nKey1, const void *pKey1,
   897    885     int nKey2, const void *pKey2
   898    886   ){
   899    887     int rc, n;
          888  +  UNUSED_PARAMETER(NotUsed);
   900    889     n = nKey1<nKey2 ? nKey1 : nKey2;
   901    890     /* EVIDENCE-OF: R-65033-28449 The built-in BINARY collation compares
   902    891     ** strings byte by byte using the memcmp() function from the standard C
   903    892     ** library. */
   904    893     assert( pKey1 && pKey2 );
   905    894     rc = memcmp(pKey1, pKey2, n);
   906    895     if( rc==0 ){
   907         -    if( padFlag
   908         -     && allSpaces(((char*)pKey1)+n, nKey1-n)
   909         -     && allSpaces(((char*)pKey2)+n, nKey2-n)
   910         -    ){
   911         -      /* EVIDENCE-OF: R-31624-24737 RTRIM is like BINARY except that extra
   912         -      ** spaces at the end of either string do not change the result. In other
   913         -      ** words, strings will compare equal to one another as long as they
   914         -      ** differ only in the number of spaces at the end.
   915         -      */
   916         -    }else{
   917         -      rc = nKey1 - nKey2;
   918         -    }
          896  +    rc = nKey1 - nKey2;
   919    897     }
   920    898     return rc;
   921    899   }
          900  +
          901  +/*
          902  +** This is the collating function named "RTRIM" which is always
          903  +** available.  Ignore trailing spaces.
          904  +*/
          905  +static int rtrimCollFunc(
          906  +  void *pUser,
          907  +  int nKey1, const void *pKey1,
          908  +  int nKey2, const void *pKey2
          909  +){
          910  +  const u8 *pK1 = (const u8*)pKey1;
          911  +  const u8 *pK2 = (const u8*)pKey2;
          912  +  while( nKey1 && pK1[nKey1-1]==' ' ) nKey1--;
          913  +  while( nKey2 && pK2[nKey2-1]==' ' ) nKey2--;
          914  +  return binCollFunc(pUser, nKey1, pKey1, nKey2, pKey2);
          915  +}
   922    916   
   923    917   /*
   924    918   ** Return true if CollSeq is the default built-in BINARY.
   925    919   */
   926    920   int sqlite3IsBinary(const CollSeq *p){
   927         -  assert( p==0 || p->xCmp!=binCollFunc || p->pUser!=0
   928         -            || strcmp(p->zName,"BINARY")==0 );
   929         -  return p==0 || (p->xCmp==binCollFunc && p->pUser==0);
          921  +  assert( p==0 || p->xCmp!=binCollFunc || strcmp(p->zName,"BINARY")==0 );
          922  +  return p==0 || p->xCmp==binCollFunc;
   930    923   }
   931    924   
   932    925   /*
   933    926   ** Another built-in collating sequence: NOCASE. 
   934    927   **
   935    928   ** This collating sequence is intended to be used for "case independent
   936    929   ** comparison". SQLite's knowledge of upper and lower case equivalents
................................................................................
  3124   3117     ** EVIDENCE-OF: R-52786-44878 SQLite defines three built-in collating
  3125   3118     ** functions:
  3126   3119     */
  3127   3120     createCollation(db, sqlite3StrBINARY, SQLITE_UTF8, 0, binCollFunc, 0);
  3128   3121     createCollation(db, sqlite3StrBINARY, SQLITE_UTF16BE, 0, binCollFunc, 0);
  3129   3122     createCollation(db, sqlite3StrBINARY, SQLITE_UTF16LE, 0, binCollFunc, 0);
  3130   3123     createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0);
  3131         -  createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0);
         3124  +  createCollation(db, "RTRIM", SQLITE_UTF8, 0, rtrimCollFunc, 0);
  3132   3125     if( db->mallocFailed ){
  3133   3126       goto opendb_out;
  3134   3127     }
  3135   3128     /* EVIDENCE-OF: R-08308-17224 The default collating function for all
  3136   3129     ** strings is BINARY. 
  3137   3130     */
  3138   3131     db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, sqlite3StrBINARY, 0);

Changes to test/collate1.test.

   396    396       ORDER BY 1 COLLATE nocase COLLATE nocase COLLATE nocase COLLATE binary;
   397    397   } {DEF abc}
   398    398   do_execsql_test 7.2 {
   399    399      SELECT 'abc' UNION ALL SELECT 'DEF'
   400    400       ORDER BY 1 COLLATE binary COLLATE binary COLLATE binary COLLATE nocase;
   401    401   } {abc DEF}
   402    402   
          403  +# 2019-06-14
          404  +# https://sqlite.org/src/info/f1580ba1b574e9e9
          405  +#
          406  +do_execsql_test 8.0 {
          407  +  SELECT ' ' > char(20) COLLATE rtrim;
          408  +} 0
          409  +do_execsql_test 8.1 {
          410  +  SELECT '' < char(20) COLLATE rtrim;
          411  +} 1
          412  +do_execsql_test 8.2 {
          413  +  DROP TABLE IF EXISTS t0;
          414  +  CREATE TABLE t0(c0 COLLATE RTRIM, c1 BLOB UNIQUE,
          415  +                  PRIMARY KEY (c0, c1)) WITHOUT ROWID;
          416  +  INSERT INTO t0 VALUES (123, 3), (' ', 1), ('	', 2), ('', 4);
          417  +  SELECT * FROM t0 WHERE c1 = 1;
          418  +} {{ } 1}
   403    419   
   404    420   finish_test