Test cases added. Comments fixed. Proposed solution for

ticket [05f43be8fdda9fbd9].

FossilOrigin-Name: 6b993bd54035b67f4d84941e3f444ca79b7feee1
This commit is contained in:
drh 2015-03-06 20:49:52 +00:00
parent 8f1a7ed33f
commit a9c18a9067
8 changed files with 105 additions and 35 deletions

View File

@ -1,5 +1,5 @@
C Fix\sthe\sLIKE\soptimization\seven\swhen\scomparing\smixed-case\sBLOBs.
D 2015-03-06T19:47:38.505
C Test\scases\sadded.\s\sComments\sfixed.\s\sProposed\ssolution\sfor\nticket\s[05f43be8fdda9fbd9].
D 2015-03-06T20:49:52.770
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -293,7 +293,7 @@ F src/update.c 3c4ecc282accf12d39edb8d524cf089645e55a13
F src/utf.c fc6b889ba0779b7722634cdeaa25f1930d93820c
F src/util.c 98a7627ca48ad3265b6940915a1d08355eb3fc7e
F src/vacuum.c 9460b9de7b2d4e34b0d374894aa6c8a0632be8ec
F src/vdbe.c 6bee3b85a2f013a8fdc496996089d3b6bedfb525
F src/vdbe.c c9f4ad2c62bccebed38b1fd253064ed2a2c659ae
F src/vdbe.h 6fc69d9c5e146302c56e163cb4b31d1ee64a18c3
F src/vdbeInt.h bb56fd199d8af1a2c1b9639ee2f70724b4338e3a
F src/vdbeapi.c dac0d0d8009a8aa549cd77d9c29da44c0344f0c4
@ -307,7 +307,7 @@ F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
F src/wal.c 39303f2c9db02a4e422cd8eb2c8760420c6a51fe
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804
F src/where.c cace7eef1838ea22f549e824236eaaa4195b83e6
F src/where.c 8cd4fc29addda0945b28b1f849a7998e3749d8b9
F src/whereInt.h cbe4aa57326998d89e7698ca65bb7c28541d483c
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
@ -321,7 +321,7 @@ F test/alter4.test c461150723ac957f3b2214aa0b11552cd72023ec
F test/altermalloc.test e81ac9657ed25c6c5bb09bebfa5a047cd8e4acfc
F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f
F test/analyze.test 1772936d66471c65221e437b6d1999c3a03166c4
F test/analyze3.test bf41f0f680dd1e0d44eed5e769531e93a5320275
F test/analyze3.test 75b9e42ea1e4edc919250450dc5762186965d4e6
F test/analyze4.test eff2df19b8dd84529966420f29ea52edc6b56213
F test/analyze5.test 765c4e284aa69ca172772aa940946f55629bc8c4
F test/analyze6.test f1c552ce39cca4ec922a7e4e0e5d0203d6b3281f
@ -689,8 +689,9 @@ F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff
F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63
F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200
F test/like.test e191e536d0fcd722a6b965e7cd1ee0bfd12a5991
F test/like.test 4f2a71d36a536233727f71995fef900756705e56
F test/like2.test 3b2ee13149ba4a8a60b59756f4e5d345573852da
F test/like3.test 9c85587224f739c81b51d8cdd2727c11ec678526
F test/limit.test 0c99a27a87b14c646a9d583c7c89fd06c352663e
F test/loadext.test 648cb95f324d1775c54a55c12271b2d1156b633b
F test/loadext2.test 0408380b57adca04004247179837a18e866a74f7
@ -1158,7 +1159,7 @@ F test/where4.test d8420ceeb8323a41ceff1f1841fc528e824e1ecf
F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2
F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b
F test/where7.test 5a4b0abc207d71da4deecd734ad8579e8dd40aa8
F test/where8.test 806f1dcec4088be2b826b33f757fe6e17c3236a1
F test/where8.test 2eafe74e01cc10355985874e1ff868ac03dbae5e
F test/where8m.test da346596e19d54f0aba35ebade032a7c47d79739
F test/where9.test 729c3ba9b47e8f9f1aab96bae7dad2a524f1d1a2
F test/whereA.test 4d253178d135ec46d1671e440cd8f2b916aa6e6b
@ -1240,7 +1241,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 5757e803cb5759b476bbc6453c58340089611420
R 1a18426c5e280ce5513288eef4bf379e
P a58aafdb4e1422b6a8ffc07a67984928bbedf919
R d75eaf03976986bf457292a7b369e1ff
U drh
Z 4902bd060fa099614e1fc5278ee9e5b6
Z 9b58e75e5227e2cbfcfb68532871937f

View File

@ -1 +1 @@
a58aafdb4e1422b6a8ffc07a67984928bbedf919
6b993bd54035b67f4d84941e3f444ca79b7feee1

View File

@ -1053,9 +1053,9 @@ case OP_String8: { /* same as TK_STRING, out2-prerelease */
** The string value P4 of length P1 (bytes) is stored in register P2.
**
** If P5!=0 and the content of register P3 is greater than zero, then
** the datatype of the register P2 is convert to BLOB. The content is
** the same string text, it is merely interpreted as a BLOB as if it
** had been CAST.
** the datatype of the register P2 is converted to BLOB. The content is
** the same sequence of bytes, it is merely interpreted as a BLOB instead
** of a string, as if it had been CAST.
*/
case OP_String: { /* out2-prerelease */
assert( pOp->p4.z!=0 );

View File

@ -1109,7 +1109,7 @@ static void exprAnalyze(
Bitmask extraRight = 0; /* Extra dependencies on LEFT JOIN */
Expr *pStr1 = 0; /* RHS of LIKE/GLOB operator */
int isComplete = 0; /* RHS of LIKE/GLOB ends with wildcard */
int noCase = 0; /* LIKE/GLOB distinguishes case */
int noCase = 0; /* uppercase equivalent to lowercase */
int op; /* Top-level operator. pExpr->op */
Parse *pParse = pWInfo->pParse; /* Parsing context */
sqlite3 *db = pParse->db; /* Database connection */
@ -1247,12 +1247,15 @@ static void exprAnalyze(
/* Add constraints to reduce the search space on a LIKE or GLOB
** operator.
**
** A like pattern of the form "x LIKE 'abc%'" is changed into constraints
** A like pattern of the form "x LIKE 'aBc%'" is changed into constraints
**
** x>='abc' AND x<'abd' AND x LIKE 'abc%'
** x>='ABC' AND x<'abd' AND x LIKE 'aBc%'
**
** The last character of the prefix "abc" is incremented to form the
** termination condition "abd".
** termination condition "abd". If case is not significant (the default
** for LIKE) then the lower-bound is made all uppercase and the upper-
** bound is made all lowercase so that the bounds also work when comparing
** BLOBs.
*/
if( pWC->op==TK_AND
&& isLikeOrGlob(pParse, pExpr, &pStr1, &isComplete, &noCase)
@ -1266,7 +1269,6 @@ static void exprAnalyze(
Token sCollSeqName; /* Name of collating sequence */
const u16 wtFlags = TERM_LIKEOPT | TERM_VIRTUAL | TERM_DYNAMIC;
pTerm->wtFlags |= TERM_LIKE;
pLeft = pExpr->x.pList->a[1].pExpr;
pStr2 = sqlite3ExprDup(db, pStr1, 0);
@ -1277,6 +1279,7 @@ static void exprAnalyze(
if( noCase && !pParse->db->mallocFailed ){
int i;
char c;
pTerm->wtFlags |= TERM_LIKE;
for(i=0; (c = pStr1->u.zToken[i])!=0; i++){
pStr1->u.zToken[i] = sqlite3Toupper(c);
pStr2->u.zToken[i] = sqlite3Tolower(c);
@ -2502,6 +2505,12 @@ static int whereInScanEst(
** and child2 terms were added by the LIKE optimization. If both of
** the virtual child terms are valid, then testing of the parent can be
** skipped.
**
** Usually the parent term is marked as TERM_CODED. But if the parent
** term was originally TERM_LIKE, then the parent gets TERM_LIKECOND instead.
** The TERM_LIKECOND marking indicates that the term should be coded inside
** a conditional such that is only evaluated on the second pass of a
** LIKE-optimization loop, when scanning BLOBs instead of strings.
*/
static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
int nLoop = 0;

View File

@ -281,35 +281,35 @@ do_eqp_test analyze3-2.3 {
do_test analyze3-2.4 {
sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE 'a%' }
} {101 0 100}
} {102 0 100}
do_test analyze3-2.5 {
sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE '%a' }
} {999 999 100}
do_test analyze3-2.4 {
do_test analyze3-2.6 {
set like "a%"
sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
} {101 0 100}
do_test analyze3-2.5 {
} {102 0 100}
do_test analyze3-2.7 {
set like "%a"
sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
} {999 999 100}
do_test analyze3-2.6 {
do_test analyze3-2.8 {
set like "a"
sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
} {101 0 0}
do_test analyze3-2.7 {
} {102 0 0}
do_test analyze3-2.9 {
set like "ab"
sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
} {11 0 0}
do_test analyze3-2.8 {
} {12 0 0}
do_test analyze3-2.10 {
set like "abc"
sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
} {2 0 1}
do_test analyze3-2.9 {
} {3 0 1}
do_test analyze3-2.11 {
set like "a_c"
sf_execsql { SELECT count(*) FROM t1 WHERE b LIKE $like }
} {101 0 10}
} {102 0 10}
#-------------------------------------------------------------------------

View File

@ -749,7 +749,7 @@ ifcapable like_opt&&!icu {
count {
SELECT a FROM t10 WHERE f LIKE '12%' ORDER BY +a;
}
} {12 123 scan 3 like 0}
} {12 123 scan 4 like 0}
do_test like-10.6 {
count {
SELECT a FROM t10 WHERE a LIKE '12%' ORDER BY +a;
@ -790,7 +790,7 @@ ifcapable like_opt&&!icu {
count {
SELECT a FROM t10b WHERE f GLOB '12*' ORDER BY +a;
}
} {12 123 scan 3 like 0}
} {12 123 scan 4 like 0}
do_test like-10.15 {
count {
SELECT a FROM t10b WHERE a GLOB '12*' ORDER BY +a;

60
test/like3.test Normal file
View File

@ -0,0 +1,60 @@
# 2015-03-06
#
# The author disclaims copyright to this source code. In place of
# a legal notice, here is a blessing:
#
# May you do good and not evil.
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
#
# This file implements regression tests for SQLite library. The
# focus of this file is testing the LIKE and GLOB operators and
# in particular the optimizations that occur to help those operators
# run faster and that those optimizations work correctly when there
# are both strings and blobs being tested.
#
# Ticket 05f43be8fdda9fbd948d374319b99b054140bc36 shows that the following
# SQL was not working correctly:
#
# CREATE TABLE t1(x TEXT UNIQUE COLLATE nocase);
# INSERT INTO t1(x) VALUES(x'616263');
# SELECT 'query-1', x FROM t1 WHERE x LIKE 'a%';
# SELECT 'query-2', x FROM t1 WHERE +x LIKE 'a%';
#
# This script verifies that it works right now.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
do_execsql_test like3-1.1 {
PRAGMA encoding=UTF8;
CREATE TABLE t1(a,b TEXT COLLATE nocase);
INSERT INTO t1(a,b)
VALUES(1,'abc'),
(2,'ABX'),
(3,'BCD'),
(4,x'616263'),
(5,x'414258'),
(6,x'424344');
CREATE INDEX t1ba ON t1(b,a);
SELECT a, b FROM t1 WHERE b LIKE 'aB%' ORDER BY +a;
} {1 abc 2 ABX 4 abc 5 ABX}
do_execsql_test like3-1.2 {
SELECT a, b FROM t1 WHERE +b LIKE 'aB%' ORDER BY +a;
} {1 abc 2 ABX 4 abc 5 ABX}
do_execsql_test like3-1.3 {
CREATE TABLE t2(a, b TEXT);
INSERT INTO t2 SELECT a, b FROM t1;
CREATE INDEX t2ba ON t2(b,a);
SELECT a, b FROM t2 WHERE b GLOB 'ab*' ORDER BY +a;
} {1 abc 4 abc}
do_execsql_test like3-1.4 {
SELECT a, b FROM t2 WHERE +b GLOB 'ab*' ORDER BY +a;
} {1 abc 4 abc}
finish_test

View File

@ -66,11 +66,11 @@ do_test where8-1.3 {
do_test where8-1.4 {
execsql_status2 { SELECT c FROM t1 WHERE a > 8 OR b GLOB 't*' }
} {IX X III II 0 0 9}
} {IX X III II 0 0 10}
do_test where8-1.5 {
execsql_status2 { SELECT c FROM t1 WHERE a > 8 OR b GLOB 'f*' }
} {IX X V IV 0 0 9}
} {IX X V IV 0 0 10}
do_test where8-1.6 {
execsql_status { SELECT c FROM t1 WHERE a = 1 OR b = 'three' ORDER BY rowid }