Faster version of patternCompare() that uses new return values rather than
an extra parameter to communicate wildcard information back up to parent searches. FossilOrigin-Name: a1e2b6ce3af690ae91bda3d056357205c4018da7
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
C Modify\sthe\spatternCompare()\sfunction\s(used\sfor\sGLOB,\sLIKE)\sto\sbetter\shandle\npatterns\scontaining\smultiple\swildcard\scharacters\s("*",\s"%").
|
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-01T17:34:59.799
|
D 2016-12-01T18:49:40.948
|
||||||
F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d
|
F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d
|
||||||
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
|
||||||
F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da
|
F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da
|
||||||
@@ -344,7 +344,7 @@ F src/delete.c cac97d1117a3008934da3a6a587b3608e65e1495
|
|||||||
F src/expr.c b22e09630f874c52db0770973b7ce55ee50c1dde
|
F src/expr.c b22e09630f874c52db0770973b7ce55ee50c1dde
|
||||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||||
F src/fkey.c b9ca262f6ad4d030a3cab737ebf9b0b3c8b4ac80
|
F src/fkey.c b9ca262f6ad4d030a3cab737ebf9b0b3c8b4ac80
|
||||||
F src/func.c 528e92597efe1bb80b5dfc18184bd6cbf50d0cf9
|
F src/func.c 43916c1d8e6da5d107d91d2b212577d4f69a876a
|
||||||
F src/global.c 9da4ca5d74b90715f0ec4957f3d17a4749009f34
|
F src/global.c 9da4ca5d74b90715f0ec4957f3d17a4749009f34
|
||||||
F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd
|
F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd
|
||||||
F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4
|
F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4
|
||||||
@@ -1536,10 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P d2d30914d81022d7d4e1670caf9326524520deaf
|
P c5e5614d98a752738c081fecdd1e349a1a92b0e5
|
||||||
R e10a8ca94d0faea9fbbc7bdc7c3a49de
|
R 7fd404505e6cb7c0d4a931aa83fe2cab
|
||||||
T *branch * pattern-compare-optimization
|
U drh
|
||||||
T *sym-pattern-compare-optimization *
|
Z 7c186ec4fef5aa272b546661aa8fedfc
|
||||||
T -sym-trunk *
|
|
||||||
U dan
|
|
||||||
Z 02660061daf6ca9953ba412794b057ac
|
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
c5e5614d98a752738c081fecdd1e349a1a92b0e5
|
a1e2b6ce3af690ae91bda3d056357205c4018da7
|
||||||
+40
-39
@@ -598,9 +598,19 @@ static const struct compareInfo likeInfoNorm = { '%', '_', 0, 1 };
|
|||||||
static const struct compareInfo likeInfoAlt = { '%', '_', 0, 0 };
|
static const struct compareInfo likeInfoAlt = { '%', '_', 0, 0 };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Compare two UTF-8 strings for equality where the first string can
|
** Possible error returns from patternMatch()
|
||||||
** potentially be a "glob" or "like" expression. Return true (1) if they
|
*/
|
||||||
** are the same and false (0) if they are different.
|
#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:
|
** Globbing rules:
|
||||||
**
|
**
|
||||||
@@ -636,8 +646,7 @@ static int patternCompare(
|
|||||||
const u8 *zPattern, /* The glob pattern */
|
const u8 *zPattern, /* The glob pattern */
|
||||||
const u8 *zString, /* The string to compare against the glob */
|
const u8 *zString, /* The string to compare against the glob */
|
||||||
const struct compareInfo *pInfo, /* Information about how to do the compare */
|
const struct compareInfo *pInfo, /* Information about how to do the compare */
|
||||||
u32 matchOther, /* The escape char (LIKE) or '[' (GLOB) */
|
u32 matchOther /* The escape char (LIKE) or '[' (GLOB) */
|
||||||
int *pbSeenMatchAll /* OUT: True if have seen matchAll */
|
|
||||||
){
|
){
|
||||||
u32 c, c2; /* Next pattern and input string chars */
|
u32 c, c2; /* Next pattern and input string chars */
|
||||||
u32 matchOne = pInfo->matchOne; /* "?" or "_" */
|
u32 matchOne = pInfo->matchOne; /* "?" or "_" */
|
||||||
@@ -650,30 +659,27 @@ static int patternCompare(
|
|||||||
/* Skip over multiple "*" characters in the pattern. If there
|
/* Skip over multiple "*" characters in the pattern. If there
|
||||||
** are also "?" characters, skip those as well, but consume a
|
** are also "?" characters, skip those as well, but consume a
|
||||||
** single character of the input string for each "?" skipped */
|
** single character of the input string for each "?" skipped */
|
||||||
*pbSeenMatchAll = 1;
|
|
||||||
while( (c=Utf8Read(zPattern)) == matchAll || c == matchOne ){
|
while( (c=Utf8Read(zPattern)) == matchAll || c == matchOne ){
|
||||||
if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){
|
if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){
|
||||||
return 0;
|
return SQLITE_NOWILDCARDMATCH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( c==0 ){
|
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 ){
|
}else if( c==matchOther ){
|
||||||
if( pInfo->matchSet==0 ){
|
if( pInfo->matchSet==0 ){
|
||||||
c = sqlite3Utf8Read(&zPattern);
|
c = sqlite3Utf8Read(&zPattern);
|
||||||
if( c==0 ) return 0;
|
if( c==0 ) return SQLITE_NOWILDCARDMATCH;
|
||||||
}else{
|
}else{
|
||||||
int bMA = 0; /* True if patternCompare sees matchAll */
|
|
||||||
/* "[...]" immediately follows the "*". We have to do a slow
|
/* "[...]" immediately follows the "*". We have to do a slow
|
||||||
** recursive search in this case, but it is an unusual case. */
|
** recursive search in this case, but it is an unusual case. */
|
||||||
assert( matchOther<0x80 ); /* '[' is a single-byte character */
|
assert( matchOther<0x80 ); /* '[' is a single-byte character */
|
||||||
while( *zString
|
while( *zString ){
|
||||||
&& patternCompare(&zPattern[-1],zString,pInfo,matchOther,&bMA)==0
|
int bMatch = patternCompare(&zPattern[-1],zString,pInfo,matchOther);
|
||||||
){
|
if( bMatch!=SQLITE_NOMATCH ) return bMatch;
|
||||||
if( bMA ) return 0;
|
|
||||||
SQLITE_SKIP_UTF8(zString);
|
SQLITE_SKIP_UTF8(zString);
|
||||||
}
|
}
|
||||||
return *zString!=0;
|
return SQLITE_NOWILDCARDMATCH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -688,7 +694,7 @@ static int patternCompare(
|
|||||||
*/
|
*/
|
||||||
if( c<=0x80 ){
|
if( c<=0x80 ){
|
||||||
u32 cx;
|
u32 cx;
|
||||||
int bMatchAll = 0;
|
int bMatch;
|
||||||
if( noCase ){
|
if( noCase ){
|
||||||
cx = sqlite3Toupper(c);
|
cx = sqlite3Toupper(c);
|
||||||
c = sqlite3Tolower(c);
|
c = sqlite3Tolower(c);
|
||||||
@@ -697,34 +703,30 @@ static int patternCompare(
|
|||||||
}
|
}
|
||||||
while( (c2 = *(zString++))!=0 ){
|
while( (c2 = *(zString++))!=0 ){
|
||||||
if( c2!=c && c2!=cx ) continue;
|
if( c2!=c && c2!=cx ) continue;
|
||||||
if( patternCompare(zPattern,zString,pInfo,matchOther, &bMatchAll) ){
|
bMatch = patternCompare(zPattern,zString,pInfo,matchOther);
|
||||||
return 1;
|
if( bMatch!=SQLITE_NOMATCH ) return bMatch;
|
||||||
}
|
|
||||||
if( bMatchAll ) break;
|
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
int bMatchAll = 0;
|
int bMatch;
|
||||||
while( (c2 = Utf8Read(zString))!=0 ){
|
while( (c2 = Utf8Read(zString))!=0 ){
|
||||||
if( c2!=c ) continue;
|
if( c2!=c ) continue;
|
||||||
if( patternCompare(zPattern,zString,pInfo,matchOther, &bMatchAll) ){
|
bMatch = patternCompare(zPattern,zString,pInfo,matchOther);
|
||||||
return 1;
|
if( bMatch!=SQLITE_NOMATCH ) return bMatch;
|
||||||
}
|
|
||||||
if( bMatchAll ) break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return SQLITE_NOWILDCARDMATCH;
|
||||||
}
|
}
|
||||||
if( c==matchOther ){
|
if( c==matchOther ){
|
||||||
if( pInfo->matchSet==0 ){
|
if( pInfo->matchSet==0 ){
|
||||||
c = sqlite3Utf8Read(&zPattern);
|
c = sqlite3Utf8Read(&zPattern);
|
||||||
if( c==0 ) return 0;
|
if( c==0 ) return SQLITE_NOMATCH;
|
||||||
zEscaped = zPattern;
|
zEscaped = zPattern;
|
||||||
}else{
|
}else{
|
||||||
u32 prior_c = 0;
|
u32 prior_c = 0;
|
||||||
int seen = 0;
|
int seen = 0;
|
||||||
int invert = 0;
|
int invert = 0;
|
||||||
c = sqlite3Utf8Read(&zString);
|
c = sqlite3Utf8Read(&zString);
|
||||||
if( c==0 ) return 0;
|
if( c==0 ) return SQLITE_NOMATCH;
|
||||||
c2 = sqlite3Utf8Read(&zPattern);
|
c2 = sqlite3Utf8Read(&zPattern);
|
||||||
if( c2=='^' ){
|
if( c2=='^' ){
|
||||||
invert = 1;
|
invert = 1;
|
||||||
@@ -748,7 +750,7 @@ static int patternCompare(
|
|||||||
c2 = sqlite3Utf8Read(&zPattern);
|
c2 = sqlite3Utf8Read(&zPattern);
|
||||||
}
|
}
|
||||||
if( c2==0 || (seen ^ invert)==0 ){
|
if( c2==0 || (seen ^ invert)==0 ){
|
||||||
return 0;
|
return SQLITE_NOMATCH;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -759,25 +761,25 @@ static int patternCompare(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if( c==matchOne && zPattern!=zEscaped && c2!=0 ) 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 sqlite3_strglob(const char *zGlobPattern, const char *zString){
|
||||||
int dummy = 0;
|
return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, '[');
|
||||||
return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, '[', &dummy)==0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** 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 sqlite3_strlike(const char *zPattern, const char *zStr, unsigned int esc){
|
||||||
int dummy = 0;
|
return patternCompare((u8*)zPattern, (u8*)zStr, &likeInfoNorm, esc);
|
||||||
return patternCompare((u8*)zPattern, (u8*)zStr, &likeInfoNorm, esc, &dummy)==0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -855,11 +857,10 @@ static void likeFunc(
|
|||||||
escape = pInfo->matchSet;
|
escape = pInfo->matchSet;
|
||||||
}
|
}
|
||||||
if( zA && zB ){
|
if( zA && zB ){
|
||||||
int dummy = 0;
|
|
||||||
#ifdef SQLITE_TEST
|
#ifdef SQLITE_TEST
|
||||||
sqlite3_like_count++;
|
sqlite3_like_count++;
|
||||||
#endif
|
#endif
|
||||||
sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape, &dummy));
|
sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape)==SQLITE_MATCH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user