]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Faster version of patternCompare() that uses new return values rather than pattern-compare-optimization
authordrh <drh@noemail.net>
Thu, 1 Dec 2016 18:49:40 +0000 (18:49 +0000)
committerdrh <drh@noemail.net>
Thu, 1 Dec 2016 18:49:40 +0000 (18:49 +0000)
an extra parameter to communicate wildcard information back up to parent
searches.

FossilOrigin-Name: a1e2b6ce3af690ae91bda3d056357205c4018da7

manifest
manifest.uuid
src/func.c

index 8c10ea1dbf89899b9b19f450e55f91563a285376..b0f600d00251251130407a9567bd99b6592b02bf 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Modify\sthe\spatternCompare()\sfunction\s(used\sfor\sGLOB,\sLIKE)\sto\sbetter\shandle\npatterns\scontaining\smultiple\swildcard\scharacters\s("*",\s"%").
-D 2016-12-01T17:34:59.799
+C Faster\sversion\sof\spatternCompare()\sthat\suses\snew\sreturn\svalues\srather\sthan\nan\sextra\sparameter\sto\scommunicate\swildcard\sinformation\sback\sup\sto\sparent\nsearches.
+D 2016-12-01T18:49:40.948
 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da
@@ -344,7 +344,7 @@ F src/delete.c cac97d1117a3008934da3a6a587b3608e65e1495
 F src/expr.c b22e09630f874c52db0770973b7ce55ee50c1dde
 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
 F src/fkey.c b9ca262f6ad4d030a3cab737ebf9b0b3c8b4ac80
-F src/func.c 528e92597efe1bb80b5dfc18184bd6cbf50d0cf9
+F src/func.c 43916c1d8e6da5d107d91d2b212577d4f69a876a
 F src/global.c 9da4ca5d74b90715f0ec4957f3d17a4749009f34
 F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd
 F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4
@@ -1536,10 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P d2d30914d81022d7d4e1670caf9326524520deaf
-R e10a8ca94d0faea9fbbc7bdc7c3a49de
-T *branch * pattern-compare-optimization
-T *sym-pattern-compare-optimization *
-T -sym-trunk *
-U dan
-Z 02660061daf6ca9953ba412794b057ac
+P c5e5614d98a752738c081fecdd1e349a1a92b0e5
+R 7fd404505e6cb7c0d4a931aa83fe2cab
+U drh
+Z 7c186ec4fef5aa272b546661aa8fedfc
index 9b8ba94419b93c3fe1a709f38844a8202849839f..b7832d7eab269b9d446ed090103d2ee94f862e3c 100644 (file)
@@ -1 +1 @@
-c5e5614d98a752738c081fecdd1e349a1a92b0e5
\ No newline at end of file
+a1e2b6ce3af690ae91bda3d056357205c4018da7
\ No newline at end of file
index 54f5df46aafa71076da3071486c83a1e3c71f301..5b8ed6dd2bf3c51f07adf5b35a54c639a7187693 100644 (file)
@@ -598,9 +598,19 @@ static const struct compareInfo likeInfoNorm = { '%', '_',   0, 1 };
 static const struct compareInfo likeInfoAlt = { '%', '_',   0, 0 };
 
 /*
-** Compare two UTF-8 strings for equality where the first string can
-** potentially be a "glob" or "like" expression.  Return true (1) if they
-** are the same and false (0) if they are different.
+** Possible error returns from patternMatch()
+*/
+#define SQLITE_MATCH             0
+#define SQLITE_NOMATCH           1
+#define SQLITE_NOWILDCARDMATCH   2
+
+/*
+** Compare two UTF-8 strings for equality where the first string is
+** a GLOB or LIKE expression.  Return values:
+**
+**    SQLITE_MATCH:            Match
+**    SQLITE_NOMATCH:          No match
+**    SQLITE_NOWILDCARDMATCH:  No match in spite of having * or % wildcards.
 **
 ** Globbing rules:
 **
@@ -636,8 +646,7 @@ static int patternCompare(
   const u8 *zPattern,              /* The glob pattern */
   const u8 *zString,               /* The string to compare against the glob */
   const struct compareInfo *pInfo, /* Information about how to do the compare */
-  u32 matchOther,                  /* The escape char (LIKE) or '[' (GLOB) */
-  int *pbSeenMatchAll              /* OUT: True if have seen matchAll */
+  u32 matchOther                   /* The escape char (LIKE) or '[' (GLOB) */
 ){
   u32 c, c2;                       /* Next pattern and input string chars */
   u32 matchOne = pInfo->matchOne;  /* "?" or "_" */
@@ -650,30 +659,27 @@ static int patternCompare(
       /* Skip over multiple "*" characters in the pattern.  If there
       ** are also "?" characters, skip those as well, but consume a
       ** single character of the input string for each "?" skipped */
-      *pbSeenMatchAll = 1;
       while( (c=Utf8Read(zPattern)) == matchAll || c == matchOne ){
         if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){
-          return 0;
+          return SQLITE_NOWILDCARDMATCH;
         }
       }
       if( c==0 ){
-        return 1;   /* "*" at the end of the pattern matches */
+        return SQLITE_MATCH;   /* "*" at the end of the pattern matches */
       }else if( c==matchOther ){
         if( pInfo->matchSet==0 ){
           c = sqlite3Utf8Read(&zPattern);
-          if( c==0 ) return 0;
+          if( c==0 ) return SQLITE_NOWILDCARDMATCH;
         }else{
-          int bMA = 0;            /* True if patternCompare sees matchAll */
           /* "[...]" immediately follows the "*".  We have to do a slow
           ** recursive search in this case, but it is an unusual case. */
           assert( matchOther<0x80 );  /* '[' is a single-byte character */
-          while( *zString
-            && patternCompare(&zPattern[-1],zString,pInfo,matchOther,&bMA)==0
-          ){
-            if( bMA ) return 0;
+          while( *zString ){
+            int bMatch = patternCompare(&zPattern[-1],zString,pInfo,matchOther);
+            if( bMatch!=SQLITE_NOMATCH ) return bMatch;
             SQLITE_SKIP_UTF8(zString);
           }
-          return *zString!=0;
+          return SQLITE_NOWILDCARDMATCH;
         }
       }
 
@@ -688,7 +694,7 @@ static int patternCompare(
       */
       if( c<=0x80 ){
         u32 cx;
-        int bMatchAll = 0;
+        int bMatch;
         if( noCase ){
           cx = sqlite3Toupper(c);
           c = sqlite3Tolower(c);
@@ -697,34 +703,30 @@ static int patternCompare(
         }
         while( (c2 = *(zString++))!=0 ){
           if( c2!=c && c2!=cx ) continue;
-          if( patternCompare(zPattern,zString,pInfo,matchOther, &bMatchAll) ){
-            return 1;
-          }
-          if( bMatchAll ) break;
+          bMatch = patternCompare(zPattern,zString,pInfo,matchOther);
+          if( bMatch!=SQLITE_NOMATCH ) return bMatch;
         }
       }else{
-        int bMatchAll = 0;
+        int bMatch;
         while( (c2 = Utf8Read(zString))!=0 ){
           if( c2!=c ) continue;
-          if( patternCompare(zPattern,zString,pInfo,matchOther, &bMatchAll) ){
-            return 1;
-          }
-          if( bMatchAll ) break;
+          bMatch = patternCompare(zPattern,zString,pInfo,matchOther);
+          if( bMatch!=SQLITE_NOMATCH ) return bMatch;
         }
       }
-      return 0;
+      return SQLITE_NOWILDCARDMATCH;
     }
     if( c==matchOther ){
       if( pInfo->matchSet==0 ){
         c = sqlite3Utf8Read(&zPattern);
-        if( c==0 ) return 0;
+        if( c==0 ) return SQLITE_NOMATCH;
         zEscaped = zPattern;
       }else{
         u32 prior_c = 0;
         int seen = 0;
         int invert = 0;
         c = sqlite3Utf8Read(&zString);
-        if( c==0 ) return 0;
+        if( c==0 ) return SQLITE_NOMATCH;
         c2 = sqlite3Utf8Read(&zPattern);
         if( c2=='^' ){
           invert = 1;
@@ -748,7 +750,7 @@ static int patternCompare(
           c2 = sqlite3Utf8Read(&zPattern);
         }
         if( c2==0 || (seen ^ invert)==0 ){
-          return 0;
+          return SQLITE_NOMATCH;
         }
         continue;
       }
@@ -759,25 +761,25 @@ static int patternCompare(
       continue;
     }
     if( c==matchOne && zPattern!=zEscaped && c2!=0 ) continue;
-    return 0;
+    return SQLITE_NOMATCH;
   }
-  return *zString==0;
+  return *zString==0 ? SQLITE_MATCH : SQLITE_NOMATCH;
 }
 
 /*
-** The sqlite3_strglob() interface.
+** The sqlite3_strglob() interface.  Return 0 on a match (like strcmp()) and
+** non-zero if there is no match.
 */
 int sqlite3_strglob(const char *zGlobPattern, const char *zString){
-  int dummy = 0;
-  return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, '[', &dummy)==0;
+  return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, '[');
 }
 
 /*
-** The sqlite3_strlike() interface.
+** The sqlite3_strlike() interface.  Return 0 on a match and non-zero for
+** a miss - like strcmp().
 */
 int sqlite3_strlike(const char *zPattern, const char *zStr, unsigned int esc){
-  int dummy = 0;
-  return patternCompare((u8*)zPattern, (u8*)zStr, &likeInfoNorm, esc, &dummy)==0;
+  return patternCompare((u8*)zPattern, (u8*)zStr, &likeInfoNorm, esc);
 }
 
 /*
@@ -855,11 +857,10 @@ static void likeFunc(
     escape = pInfo->matchSet;
   }
   if( zA && zB ){
-    int dummy = 0;
 #ifdef SQLITE_TEST
     sqlite3_like_count++;
 #endif
-    sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape, &dummy));
+    sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape)==SQLITE_MATCH);
   }
 }