mirror of https://github.com/sqlite/sqlite
Modify the patternCompare() function (used for GLOB, LIKE) to better handle
patterns containing multiple wildcard characters ("*", "%"). FossilOrigin-Name: c5e5614d98a752738c081fecdd1e349a1a92b0e5
This commit is contained in:
parent
c9c81dc6d7
commit
1a4a73764c
18
manifest
18
manifest
|
@ -1,5 +1,5 @@
|
|||
C Add\sthe\sremember(V,PTR)\sextension\sfunction\swhich\scopies\san\sSQL\svalue\sinto\nan\sapplication\svariable.
|
||||
D 2016-11-30T16:54:52.848
|
||||
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
|
||||
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 7057bc2c105b82faa668d8e2ec85fad4540e5c51
|
||||
F src/func.c 528e92597efe1bb80b5dfc18184bd6cbf50d0cf9
|
||||
F src/global.c 9da4ca5d74b90715f0ec4957f3d17a4749009f34
|
||||
F src/hash.c 63d0ee752a3b92d4695b2b1f5259c4621b2cfebd
|
||||
F src/hash.h ab34c5c54a9e9de2e790b24349ba5aab3dbb4fd4
|
||||
|
@ -1536,8 +1536,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 3816bb415ecfd4f36430d0fcbc878e382975de60 f0942c362f45ca1e986e142dbdd3ad957626dfb1
|
||||
R cd510c86291ec9069bea94544a3e0b95
|
||||
T +closed f0942c362f45ca1e986e142dbdd3ad957626dfb1
|
||||
U drh
|
||||
Z 6b290cfef4656939d1e961e713e76c69
|
||||
P d2d30914d81022d7d4e1670caf9326524520deaf
|
||||
R e10a8ca94d0faea9fbbc7bdc7c3a49de
|
||||
T *branch * pattern-compare-optimization
|
||||
T *sym-pattern-compare-optimization *
|
||||
T -sym-trunk *
|
||||
U dan
|
||||
Z 02660061daf6ca9953ba412794b057ac
|
||||
|
|
|
@ -1 +1 @@
|
|||
d2d30914d81022d7d4e1670caf9326524520deaf
|
||||
c5e5614d98a752738c081fecdd1e349a1a92b0e5
|
32
src/func.c
32
src/func.c
|
@ -636,7 +636,8 @@ 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) */
|
||||
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 matchOne = pInfo->matchOne; /* "?" or "_" */
|
||||
|
@ -649,6 +650,7 @@ 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;
|
||||
|
@ -661,11 +663,14 @@ static int patternCompare(
|
|||
c = sqlite3Utf8Read(&zPattern);
|
||||
if( c==0 ) return 0;
|
||||
}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)==0 ){
|
||||
&& patternCompare(&zPattern[-1],zString,pInfo,matchOther,&bMA)==0
|
||||
){
|
||||
if( bMA ) return 0;
|
||||
SQLITE_SKIP_UTF8(zString);
|
||||
}
|
||||
return *zString!=0;
|
||||
|
@ -674,7 +679,7 @@ static int patternCompare(
|
|||
|
||||
/* At this point variable c contains the first character of the
|
||||
** pattern string past the "*". Search in the input string for the
|
||||
** first matching character and recursively contine the match from
|
||||
** first matching character and recursively continue the match from
|
||||
** that point.
|
||||
**
|
||||
** For a case-insensitive search, set variable cx to be the same as
|
||||
|
@ -683,6 +688,7 @@ static int patternCompare(
|
|||
*/
|
||||
if( c<=0x80 ){
|
||||
u32 cx;
|
||||
int bMatchAll = 0;
|
||||
if( noCase ){
|
||||
cx = sqlite3Toupper(c);
|
||||
c = sqlite3Tolower(c);
|
||||
|
@ -691,12 +697,19 @@ static int patternCompare(
|
|||
}
|
||||
while( (c2 = *(zString++))!=0 ){
|
||||
if( c2!=c && c2!=cx ) continue;
|
||||
if( patternCompare(zPattern,zString,pInfo,matchOther) ) return 1;
|
||||
if( patternCompare(zPattern,zString,pInfo,matchOther, &bMatchAll) ){
|
||||
return 1;
|
||||
}
|
||||
if( bMatchAll ) break;
|
||||
}
|
||||
}else{
|
||||
int bMatchAll = 0;
|
||||
while( (c2 = Utf8Read(zString))!=0 ){
|
||||
if( c2!=c ) continue;
|
||||
if( patternCompare(zPattern,zString,pInfo,matchOther) ) return 1;
|
||||
if( patternCompare(zPattern,zString,pInfo,matchOther, &bMatchAll) ){
|
||||
return 1;
|
||||
}
|
||||
if( bMatchAll ) break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -755,14 +768,16 @@ static int patternCompare(
|
|||
** The sqlite3_strglob() interface.
|
||||
*/
|
||||
int sqlite3_strglob(const char *zGlobPattern, const char *zString){
|
||||
return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, '[')==0;
|
||||
int dummy = 0;
|
||||
return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, '[', &dummy)==0;
|
||||
}
|
||||
|
||||
/*
|
||||
** The sqlite3_strlike() interface.
|
||||
*/
|
||||
int sqlite3_strlike(const char *zPattern, const char *zStr, unsigned int esc){
|
||||
return patternCompare((u8*)zPattern, (u8*)zStr, &likeInfoNorm, esc)==0;
|
||||
int dummy = 0;
|
||||
return patternCompare((u8*)zPattern, (u8*)zStr, &likeInfoNorm, esc, &dummy)==0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -840,10 +855,11 @@ 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));
|
||||
sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape, &dummy));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue