/ Check-in [c89d7726]
Login

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

Overview
Comment:Performance optimization and comment fixes for the LIKE and GLOB operators.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: c89d772628564a808173f6f73bc1798ec714276b
User & Date: drh 2015-06-17 13:20:54
Context
2015-06-17
17:08
Fix a uninitialized variable use in the command-line shell when the ".open" command is invoked without any arguments. check-in: fc4f4d1e user: drh tags: trunk
13:20
Performance optimization and comment fixes for the LIKE and GLOB operators. check-in: c89d7726 user: drh tags: trunk
02:11
Make getCellInfo() a real function instead of a macro, for a size reduction and a 0.2% performance gain. check-in: 55c393ea user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/func.c.

   571    571     u8 matchOne;
   572    572     u8 matchSet;
   573    573     u8 noCase;
   574    574   };
   575    575   
   576    576   /*
   577    577   ** For LIKE and GLOB matching on EBCDIC machines, assume that every
   578         -** character is exactly one byte in size.  Also, all characters are
   579         -** able to participate in upper-case-to-lower-case mappings in EBCDIC
   580         -** whereas only characters less than 0x80 do in ASCII.
          578  +** character is exactly one byte in size.  Also, provde the Utf8Read()
          579  +** macro for fast reading of the next character in the common case where
          580  +** the next character is ASCII.
   581    581   */
   582    582   #if defined(SQLITE_EBCDIC)
   583    583   # define sqlite3Utf8Read(A)        (*((*A)++))
   584         -# define GlobUpperToLower(A)       A = sqlite3UpperToLower[A]
   585         -# define GlobUpperToLowerAscii(A)  A = sqlite3UpperToLower[A]
          584  +# define Utf8Read(A)               (*(A++))
   586    585   #else
   587         -# define GlobUpperToLower(A)       if( A<=0x7f ){ A = sqlite3UpperToLower[A]; }
   588         -# define GlobUpperToLowerAscii(A)  A = sqlite3UpperToLower[A]
          586  +# define Utf8Read(A)               (A[0]<0x80?*(A++):sqlite3Utf8Read(&A))
   589    587   #endif
   590    588   
   591    589   static const struct compareInfo globInfo = { '*', '?', '[', 0 };
   592    590   /* The correct SQL-92 behavior is for the LIKE operator to ignore
   593    591   ** case.  Thus  'a' LIKE 'A' would be true. */
   594    592   static const struct compareInfo likeInfoNorm = { '%', '_',   0, 1 };
   595    593   /* If SQLITE_CASE_SENSITIVE_LIKE is defined, then the LIKE operator
................................................................................
   623    621   **      '%'       Matches any sequence of zero or more characters
   624    622   **
   625    623   ***     '_'       Matches any one character
   626    624   **
   627    625   **      Ec        Where E is the "esc" character and c is any other
   628    626   **                character, including '%', '_', and esc, match exactly c.
   629    627   **
   630         -** The comments through this routine usually assume glob matching.
          628  +** The comments within this routine usually assume glob matching.
   631    629   **
   632    630   ** This routine is usually quick, but can be N**2 in the worst case.
   633    631   */
   634    632   static int patternCompare(
   635    633     const u8 *zPattern,              /* The glob pattern */
   636    634     const u8 *zString,               /* The string to compare against the glob */
   637    635     const struct compareInfo *pInfo, /* Information about how to do the compare */
................................................................................
   647    645     /* The GLOB operator does not have an ESCAPE clause.  And LIKE does not
   648    646     ** have the matchSet operator.  So we either have to look for one or
   649    647     ** the other, never both.  Hence the single variable matchOther is used
   650    648     ** to store the one we have to look for.
   651    649     */
   652    650     matchOther = esc ? esc : pInfo->matchSet;
   653    651   
   654         -  while( (c = sqlite3Utf8Read(&zPattern))!=0 ){
          652  +  while( (c = Utf8Read(zPattern))!=0 ){
   655    653       if( c==matchAll ){  /* Match "*" */
   656    654         /* Skip over multiple "*" characters in the pattern.  If there
   657    655         ** are also "?" characters, skip those as well, but consume a
   658    656         ** single character of the input string for each "?" skipped */
   659         -      while( (c=sqlite3Utf8Read(&zPattern)) == matchAll
   660         -               || c == matchOne ){
          657  +      while( (c=Utf8Read(zPattern)) == matchAll || c == matchOne ){
   661    658           if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){
   662    659             return 0;
   663    660           }
   664    661         }
   665    662         if( c==0 ){
   666    663           return 1;   /* "*" at the end of the pattern matches */
   667    664         }else if( c==matchOther ){
................................................................................
   698    695             cx = c;
   699    696           }
   700    697           while( (c2 = *(zString++))!=0 ){
   701    698             if( c2!=c && c2!=cx ) continue;
   702    699             if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
   703    700           }
   704    701         }else{
   705         -        while( (c2 = sqlite3Utf8Read(&zString))!=0 ){
          702  +        while( (c2 = Utf8Read(zString))!=0 ){
   706    703             if( c2!=c ) continue;
   707    704             if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
   708    705           }
   709    706         }
   710    707         return 0;
   711    708       }
   712    709       if( c==matchOther ){
................................................................................
   744    741           }
   745    742           if( c2==0 || (seen ^ invert)==0 ){
   746    743             return 0;
   747    744           }
   748    745           continue;
   749    746         }
   750    747       }
   751         -    c2 = sqlite3Utf8Read(&zString);
          748  +    c2 = Utf8Read(zString);
   752    749       if( c==c2 ) continue;
   753    750       if( noCase && c<0x80 && c2<0x80 && sqlite3Tolower(c)==sqlite3Tolower(c2) ){
   754    751         continue;
   755    752       }
   756    753       if( c==matchOne && zPattern!=zEscaped && c2!=0 ) continue;
   757    754       return 0;
   758    755     }