summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <msvensson@neptunus.(none)>2006-05-10 21:38:48 +0200
committerunknown <msvensson@neptunus.(none)>2006-05-10 21:38:48 +0200
commitad97a0d0abce3afa4a5280fad26eca26a76aaa57 (patch)
treefd9fbfa816d4fd7444cef1e362ae1fb005d07f7c
parentfad18fe995e1801bdb243b50141278726c931abf (diff)
parente9399dc2863597cf08f32968f845c0d9ddb4a829 (diff)
downloadmariadb-git-ad97a0d0abce3afa4a5280fad26eca26a76aaa57.tar.gz
Merge neptunus.(none):/home/msvensson/mysql/tmp/tmp_merge
into neptunus.(none):/home/msvensson/mysql/mysql-5.1 BitKeeper/deleted/.del-changelog-5.0.xml~f4c50926ccdd7434: Auto merged mysql-test/r/ndb_condition_pushdown.result: Auto merged mysql-test/t/ndb_condition_pushdown.test: Auto merged storage/ndb/include/ndbapi/NdbOperation.hpp: Auto merged storage/ndb/include/util/NdbSqlUtil.hpp: Auto merged storage/ndb/src/common/util/NdbSqlUtil.cpp: Auto merged
-rw-r--r--mysql-test/r/ndb_condition_pushdown.result60
-rw-r--r--mysql-test/t/ndb_condition_pushdown.test37
-rw-r--r--storage/ndb/include/ndbapi/NdbOperation.hpp4
-rw-r--r--storage/ndb/include/util/NdbSqlUtil.hpp9
-rw-r--r--storage/ndb/src/common/util/NdbSqlUtil.cpp24
5 files changed, 117 insertions, 17 deletions
diff --git a/mysql-test/r/ndb_condition_pushdown.result b/mysql-test/r/ndb_condition_pushdown.result
index 24fe30604ae..140324a21d8 100644
--- a/mysql-test/r/ndb_condition_pushdown.result
+++ b/mysql-test/r/ndb_condition_pushdown.result
@@ -1782,5 +1782,65 @@ select * from t5 where b like '%jo%' order by a;
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;
diff --git a/mysql-test/t/ndb_condition_pushdown.test b/mysql-test/t/ndb_condition_pushdown.test
index 44740c1a486..3b53f7b3431 100644
--- a/mysql-test/t/ndb_condition_pushdown.test
+++ b/mysql-test/t/ndb_condition_pushdown.test
@@ -1649,5 +1649,42 @@ set engine_condition_pushdown = on;
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;
diff --git a/storage/ndb/include/ndbapi/NdbOperation.hpp b/storage/ndb/include/ndbapi/NdbOperation.hpp
index e747dedb84b..d64e86c3136 100644
--- a/storage/ndb/include/ndbapi/NdbOperation.hpp
+++ b/storage/ndb/include/ndbapi/NdbOperation.hpp
@@ -636,6 +636,10 @@ public:
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,
diff --git a/storage/ndb/include/util/NdbSqlUtil.hpp b/storage/ndb/include/util/NdbSqlUtil.hpp
index 36a75136c45..ff2d9766f81 100644
--- a/storage/ndb/include/util/NdbSqlUtil.hpp
+++ b/storage/ndb/include/util/NdbSqlUtil.hpp
@@ -45,14 +45,11 @@ public:
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);
diff --git a/storage/ndb/src/common/util/NdbSqlUtil.cpp b/storage/ndb/src/common/util/NdbSqlUtil.cpp
index f2506eda6d4..f3d70a5734a 100644
--- a/storage/ndb/src/common/util/NdbSqlUtil.cpp
+++ b/storage/ndb/src/common/util/NdbSqlUtil.cpp
@@ -805,7 +805,9 @@ NdbSqlUtil::likeChar(const void* info, const void* p1, unsigned n1, const void*
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 @@ int
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 @@ int
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;
}
}