diff options
author | drh <drh@noemail.net> | 2017-07-27 20:24:29 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2017-07-27 20:24:29 +0000 |
commit | 1d42ea71c241af62344843218a2cde683322f091 (patch) | |
tree | c0e55cb51a8b3c26ac65f80f6ea45c1800137199 /src/func.c | |
parent | 01d837df9cd473414c9fe2320b91ee62cb25bd3a (diff) | |
download | sqlite-1d42ea71c241af62344843218a2cde683322f091.tar.gz sqlite-1d42ea71c241af62344843218a2cde683322f091.zip |
Enhance the like optimization so that it works with an ESCAPE clause.
FossilOrigin-Name: f5d330f495d07a704e115595bbdf5422ddb68fd8191114c5a12c9c873d983f7c
Diffstat (limited to 'src/func.c')
-rw-r--r-- | src/func.c | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/src/func.c b/src/func.c index fd5458ad3..2bb9a91de 100644 --- a/src/func.c +++ b/src/func.c @@ -1706,9 +1706,14 @@ void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){ /* ** pExpr points to an expression which implements a function. If ** it is appropriate to apply the LIKE optimization to that function -** then set aWc[0] through aWc[2] to the wildcard characters and -** return TRUE. If the function is not a LIKE-style function then -** return FALSE. +** then set aWc[0] through aWc[2] to the wildcard characters and the +** escape character and then return TRUE. If the function is not a +** LIKE-style function then return FALSE. +** +** The expression "a LIKE b ESCAPE c" is only considered a valid LIKE +** operator if c is a string literal that is exactly one byte in length. +** That one byte is stored in aWc[3]. aWc[3] is set to zero if there is +** no ESCAPE clause. ** ** *pIsNocase is set to true if uppercase and lowercase are equivalent for ** the function (default for LIKE). If the function makes the distinction @@ -1717,17 +1722,26 @@ void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){ */ int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){ FuncDef *pDef; - if( pExpr->op!=TK_FUNCTION - || !pExpr->x.pList - || pExpr->x.pList->nExpr!=2 - ){ + int nExpr; + if( pExpr->op!=TK_FUNCTION || !pExpr->x.pList ){ return 0; } assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); - pDef = sqlite3FindFunction(db, pExpr->u.zToken, 2, SQLITE_UTF8, 0); + nExpr = pExpr->x.pList->nExpr; + pDef = sqlite3FindFunction(db, pExpr->u.zToken, nExpr, SQLITE_UTF8, 0); if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_FUNC_LIKE)==0 ){ return 0; } + if( nExpr<3 ){ + aWc[3] = 0; + }else{ + Expr *pEscape = pExpr->x.pList->a[2].pExpr; + char *zEscape; + if( pEscape->op!=TK_STRING ) return 0; + zEscape = pEscape->u.zToken; + if( zEscape[0]==0 || zEscape[1]!=0 ) return 0; + aWc[3] = zEscape[0]; + } /* The memcpy() statement assumes that the wildcard characters are ** the first three statements in the compareInfo structure. The |