diff --git a/mysql-test/r/ndb_basic.result b/mysql-test/r/ndb_basic.result index 993afcc5860..00308720792 100644 --- a/mysql-test/r/ndb_basic.result +++ b/mysql-test/r/ndb_basic.result @@ -677,3 +677,19 @@ select * from atablewithareallylongandirritatingname; a 2 drop table atablewithareallylongandirritatingname; +create table t1 (f1 varchar(50), f2 text,f3 int, primary key(f1)) engine=NDB; +insert into t1 (f1,f2,f3)VALUES("111111","aaaaaa",1); +insert into t1 (f1,f2,f3)VALUES("222222","bbbbbb",2); +select * from t1 order by f1; +f1 f2 f3 +111111 aaaaaa 1 +222222 bbbbbb 2 +select * from t1 order by f2; +f1 f2 f3 +111111 aaaaaa 1 +222222 bbbbbb 2 +select * from t1 order by f3; +f1 f2 f3 +111111 aaaaaa 1 +222222 bbbbbb 2 +drop table t1; diff --git a/mysql-test/t/ndb_basic.test b/mysql-test/t/ndb_basic.test index 0510651a417..12aca73d82b 100644 --- a/mysql-test/t/ndb_basic.test +++ b/mysql-test/t/ndb_basic.test @@ -623,3 +623,14 @@ create table atablewithareallylongandirritatingname (a int); insert into atablewithareallylongandirritatingname values (2); select * from atablewithareallylongandirritatingname; drop table atablewithareallylongandirritatingname; + +# +# Bug#15682 +# +create table t1 (f1 varchar(50), f2 text,f3 int, primary key(f1)) engine=NDB; +insert into t1 (f1,f2,f3)VALUES("111111","aaaaaa",1); +insert into t1 (f1,f2,f3)VALUES("222222","bbbbbb",2); +select * from t1 order by f1; +select * from t1 order by f2; +select * from t1 order by f3; +drop table t1; diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 75ee136c916..050a6ea8af8 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -3014,8 +3014,26 @@ void ha_ndbcluster::position(const byte *record) } *buff++= 0; } - memcpy(buff, record + key_part->offset, key_part->length); - buff += key_part->length; + + size_t len = key_part->length; + const byte * ptr = record + key_part->offset; + Field *field = key_part->field; + if ((field->type() == MYSQL_TYPE_VARCHAR) && + ((Field_varstring*)field)->length_bytes == 1) + { + /** + * Keys always use 2 bytes length + */ + buff[0] = ptr[0]; + buff[1] = 0; + memcpy(buff+2, ptr + 1, len); + len += 2; + } + else + { + memcpy(buff, ptr, len); + } + buff += len; } } else diff --git a/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp b/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp index 1270e56de56..5e9f6f6e6ba 100644 --- a/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp +++ b/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp @@ -141,6 +141,8 @@ #define ZALREADYEXIST 630 #define ZINCONSISTENTHASHINDEX 892 #define ZNOTUNIQUE 893 + +#define ZINVALID_KEY 290 #endif class Dbtc: public SimulatedBlock { diff --git a/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp index 6d66f5c9aad..2645075abd9 100644 --- a/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp +++ b/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp @@ -2314,7 +2314,10 @@ Dbtc::handle_special_hash(Uint32 dstHash[4], Uint32* src, Uint32 srcLen, { keyPartLenPtr = keyPartLen; dstPos = xfrm_key(tabPtrI, src, dst, sizeof(Tmp) >> 2, keyPartLenPtr); - ndbrequire(dstPos); + if (unlikely(dstPos == 0)) + { + goto error; + } } else { @@ -2335,6 +2338,10 @@ Dbtc::handle_special_hash(Uint32 dstHash[4], Uint32* src, Uint32 srcLen, dstHash[1] = tmp[1]; } return true; // success + +error: + terrorCode = ZINVALID_KEY; + return false; } /* @@ -2944,7 +2951,15 @@ void Dbtc::tckeyreq050Lab(Signal* signal) UintR tnoOfStandby; UintR tnodeinfo; + terrorCode = 0; + hash(signal); /* NOW IT IS TIME TO CALCULATE THE HASH VALUE*/ + + if (unlikely(terrorCode)) + { + releaseAtErrorLab(signal); + return; + } CacheRecord * const regCachePtr = cachePtr.p; TcConnectRecord * const regTcPtr = tcConnectptr.p; diff --git a/storage/ndb/src/ndbapi/ndberror.c b/storage/ndb/src/ndbapi/ndberror.c index fc166445555..73f08e8ac77 100644 --- a/storage/ndb/src/ndbapi/ndberror.c +++ b/storage/ndb/src/ndbapi/ndberror.c @@ -236,6 +236,7 @@ ErrorBundle ErrorCodes[] = { { 277, DMEC, IE, "277" }, { 278, DMEC, IE, "278" }, { 287, DMEC, IE, "Index corrupted" }, + { 290, DMEC, IE, "Corrupt key in TC, unable to xfrm" }, { 631, DMEC, IE, "631" }, { 632, DMEC, IE, "632" }, { 702, DMEC, IE, "Request to non-master" }, @@ -303,7 +304,6 @@ ErrorBundle ErrorCodes[] = { { 4608, DMEC, AE, "You can not takeOverScan unless you have used openScanExclusive"}, { 4609, DMEC, AE, "You must call nextScanResult before trying to takeOverScan"}, { 4232, DMEC, AE, "Parallelism can only be between 1 and 240" }, - { 290, DMEC, AE, "Scan not started or has been closed by kernel due to timeout" }, /** * Event schema errors