From: pekka Date: May 4 2006 10:53pm Subject: bk commit into 5.0 tree (pekka:1.2111) BUG#17421 List-Archive: http://lists.mysql.com/commits/5986 X-Bug: 17421 Message-Id: <200605042253.k44Mrnh3021435@orca.ndb.mysql.com> Below is the list of changes that have just been committed into a local 5.0 repository of pekka. When pekka does a push these changes will be propagated to the main repository and, within 24 hours after the push, to the public repository. For information on how to access the public repository see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html ChangeSet 1.2111 06/05/05 00:53:34 pekka@stripped +5 -0 ndb - bug#17421, changes NDB API pushdown LIKE arg to plain char ndb/src/common/util/NdbSqlUtil.cpp 1.31 06/05/05 00:52:29 pekka@stripped +13 -11 bug#17421, changes NDB API pushdown LIKE arg to plain char ndb/include/util/NdbSqlUtil.hpp 1.25 06/05/05 00:52:29 pekka@stripped +3 -6 bug#17421, changes NDB API pushdown LIKE arg to plain char ndb/include/ndbapi/NdbOperation.hpp 1.34 06/05/05 00:52:29 pekka@stripped +4 -0 bug#17421, changes NDB API pushdown LIKE arg to plain char mysql-test/t/ndb_condition_pushdown.test 1.17 06/05/05 00:52:29 pekka@stripped +37 -0 bug#17421, changes NDB API pushdown LIKE arg to plain char mysql-test/r/ndb_condition_pushdown.result 1.18 06/05/05 00:52:28 pekka@stripped +60 -0 bug#17421, changes NDB API pushdown LIKE arg to plain char # This is a BitKeeper patch. What follows are the unified diffs for the # set of deltas contained in the patch. The rest of the patch, the part # that BitKeeper cares about, is below these diffs. # User: pekka # Host: orca.ndb.mysql.com # Root: /space/pekka/ndb/version/my50-work --- 1.33/ndb/include/ndbapi/NdbOperation.hpp 2006-03-23 09:57:45 +01:00 +++ 1.34/ndb/include/ndbapi/NdbOperation.hpp 2006-05-05 00:52:29 +02:00 @@ -631,6 +631,10 @@ bool nopad, Uint32 Label); int branch_col_ge(Uint32 ColId, const void * val, Uint32 len, bool nopad, Uint32 Label); + /** + * The argument is always plain char, even if the field is varchar + * (changed in 5.0.22). + */ int branch_col_like(Uint32 ColId, const void *, Uint32 len, bool nopad, Uint32 Label); int branch_col_notlike(Uint32 ColId, const void *, Uint32 len, --- 1.24/ndb/include/util/NdbSqlUtil.hpp 2006-04-20 12:05:53 +02:00 +++ 1.25/ndb/include/util/NdbSqlUtil.hpp 2006-05-05 00:52:29 +02:00 @@ -45,14 +45,11 @@ typedef int Cmp(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full); /** - * Prototype for "like" comparison. Defined for string types. Second - * argument must have same type-specific format. Returns 0 on match, - * +1 on no match, and -1 on bad data. + * Prototype for "like" comparison. Defined for string types. First + * argument can be fixed or var* type, second argument is fixed. + * Returns 0 on match, +1 on no match, and -1 on bad data. * * Uses default special chars ( \ % _ ). - * - * TODO convert special chars to the cs so that ucs2 etc works - * TODO allow user-defined escape ( \ ) */ typedef int Like(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2); --- 1.30/ndb/src/common/util/NdbSqlUtil.cpp 2006-04-20 12:05:53 +02:00 +++ 1.31/ndb/src/common/util/NdbSqlUtil.cpp 2006-05-05 00:52:29 +02:00 @@ -805,7 +805,9 @@ const char* v1 = (const char*)p1; const char* v2 = (const char*)p2; CHARSET_INFO* cs = (CHARSET_INFO*)(info); - int k = (cs->coll->wildcmp)(cs, v1, v1 + n1, v2, v2 + n2, ndb_wild_prefix, ndb_wild_one, ndb_wild_many); + // strip end spaces to match (incorrect) MySQL behaviour + n1 = (*cs->cset->lengthsp)(cs, v1, n1); + int k = (*cs->coll->wildcmp)(cs, v1, v1 + n1, v2, v2 + n2, ndb_wild_prefix, ndb_wild_one, ndb_wild_many); return k == 0 ? 0 : +1; } @@ -820,16 +822,16 @@ NdbSqlUtil::likeVarchar(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2) { const unsigned lb = 1; - if (n1 >= lb && n2 >= lb) { + if (n1 >= lb) { const uchar* v1 = (const uchar*)p1; const uchar* v2 = (const uchar*)p2; unsigned m1 = *v1; - unsigned m2 = *v2; - if (lb + m1 <= n1 && lb + m2 <= n2) { + unsigned m2 = n2; + if (lb + m1 <= n1) { const char* w1 = (const char*)v1 + lb; - const char* w2 = (const char*)v2 + lb; + const char* w2 = (const char*)v2; CHARSET_INFO* cs = (CHARSET_INFO*)(info); - int k = (cs->coll->wildcmp)(cs, w1, w1 + m1, w2, w2 + m2, ndb_wild_prefix, ndb_wild_one, ndb_wild_many); + int k = (*cs->coll->wildcmp)(cs, w1, w1 + m1, w2, w2 + m2, ndb_wild_prefix, ndb_wild_one, ndb_wild_many); return k == 0 ? 0 : +1; } } @@ -847,16 +849,16 @@ NdbSqlUtil::likeLongvarchar(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2) { const unsigned lb = 2; - if (n1 >= lb && n2 >= lb) { + if (n1 >= lb) { const uchar* v1 = (const uchar*)p1; const uchar* v2 = (const uchar*)p2; unsigned m1 = uint2korr(v1); - unsigned m2 = uint2korr(v2); - if (lb + m1 <= n1 && lb + m2 <= n2) { + unsigned m2 = n2; + if (lb + m1 <= n1) { const char* w1 = (const char*)v1 + lb; - const char* w2 = (const char*)v2 + lb; + const char* w2 = (const char*)v2; CHARSET_INFO* cs = (CHARSET_INFO*)(info); - int k = (cs->coll->wildcmp)(cs, w1, w1 + m1, w2, w2 + m2, ndb_wild_prefix, ndb_wild_one, ndb_wild_many); + int k = (*cs->coll->wildcmp)(cs, w1, w1 + m1, w2, w2 + m2, ndb_wild_prefix, ndb_wild_one, ndb_wild_many); return k == 0 ? 0 : +1; } } --- 1.17/mysql-test/r/ndb_condition_pushdown.result 2006-03-28 09:58:49 +02:00 +++ 1.18/mysql-test/r/ndb_condition_pushdown.result 2006-05-05 00:52:28 +02:00 @@ -1782,5 +1782,65 @@ a b 1 jonas 3 johan +drop table t1; +create table t1 (a int, b varchar(3), primary key using hash(a)) +engine=ndb; +insert into t1 values (1,'a'), (2,'ab'), (3,'abc'); +set engine_condition_pushdown = off; +select * from t1 where b like 'ab'; +a b +2 ab +select * from t1 where b like 'ab' or b like 'ab'; +a b +2 ab +select * from t1 where b like 'abc'; +a b +3 abc +select * from t1 where b like 'abc' or b like 'abc'; +a b +3 abc +set engine_condition_pushdown = on; +select * from t1 where b like 'ab'; +a b +2 ab +select * from t1 where b like 'ab' or b like 'ab'; +a b +2 ab +select * from t1 where b like 'abc'; +a b +3 abc +select * from t1 where b like 'abc' or b like 'abc'; +a b +3 abc +drop table t1; +create table t1 (a int, b char(3), primary key using hash(a)) +engine=ndb; +insert into t1 values (1,'a'), (2,'ab'), (3,'abc'); +set engine_condition_pushdown = off; +select * from t1 where b like 'ab'; +a b +2 ab +select * from t1 where b like 'ab' or b like 'ab'; +a b +2 ab +select * from t1 where b like 'abc'; +a b +3 abc +select * from t1 where b like 'abc' or b like 'abc'; +a b +3 abc +set engine_condition_pushdown = on; +select * from t1 where b like 'ab'; +a b +2 ab +select * from t1 where b like 'ab' or b like 'ab'; +a b +2 ab +select * from t1 where b like 'abc'; +a b +3 abc +select * from t1 where b like 'abc' or b like 'abc'; +a b +3 abc set engine_condition_pushdown = @old_ecpd; DROP TABLE t1,t2,t3,t4,t5; --- 1.16/mysql-test/t/ndb_condition_pushdown.test 2006-03-28 09:58:49 +02:00 +++ 1.17/mysql-test/t/ndb_condition_pushdown.test 2006-05-05 00:52:29 +02:00 @@ -1649,5 +1649,42 @@ explain select * from t5 where b like '%jo%'; select * from t5 where b like '%jo%' order by a; +# bug#17421 -1 +drop table t1; +create table t1 (a int, b varchar(3), primary key using hash(a)) +engine=ndb; +insert into t1 values (1,'a'), (2,'ab'), (3,'abc'); +# in TUP the constants 'ab' 'abc' were expected in varchar format +# "like" returned error which became "false" +# scan filter negates "or" which exposes the bug +set engine_condition_pushdown = off; +select * from t1 where b like 'ab'; +select * from t1 where b like 'ab' or b like 'ab'; +select * from t1 where b like 'abc'; +select * from t1 where b like 'abc' or b like 'abc'; +set engine_condition_pushdown = on; +select * from t1 where b like 'ab'; +select * from t1 where b like 'ab' or b like 'ab'; +select * from t1 where b like 'abc'; +select * from t1 where b like 'abc' or b like 'abc'; + +# bug#17421 -2 +drop table t1; +create table t1 (a int, b char(3), primary key using hash(a)) +engine=ndb; +insert into t1 values (1,'a'), (2,'ab'), (3,'abc'); +# test that incorrect MySQL behaviour is preserved +# 'ab ' LIKE 'ab' is true in MySQL +set engine_condition_pushdown = off; +select * from t1 where b like 'ab'; +select * from t1 where b like 'ab' or b like 'ab'; +select * from t1 where b like 'abc'; +select * from t1 where b like 'abc' or b like 'abc'; +set engine_condition_pushdown = on; +select * from t1 where b like 'ab'; +select * from t1 where b like 'ab' or b like 'ab'; +select * from t1 where b like 'abc'; +select * from t1 where b like 'abc' or b like 'abc'; + set engine_condition_pushdown = @old_ecpd; DROP TABLE t1,t2,t3,t4,t5;