Loading mysql-test/r/ndb_charset.result +15 −5 Original line number Diff line number Diff line Loading @@ -306,11 +306,21 @@ count(*) drop table t1; create table t1 ( a char(10) primary key ) engine=ndb; insert into t1 values ('jonas % '); replace into t1 values ('jonas % '); replace into t1 values ('jonas % '); ) engine=ndbcluster default charset=latin1; insert into t1 values ('aaabb'); select * from t1; a aaabb replace into t1 set a = 'AAABB'; select * from t1; a AAABB replace into t1 set a = 'aAaBb'; select * from t1; a aAaBb replace into t1 set a = 'aaabb'; select * from t1; a jonas % aaabb drop table t1; mysql-test/t/ndb_charset.test +10 −5 Original line number Diff line number Diff line Loading @@ -237,13 +237,18 @@ drop table t1; #select a,b,length(a),length(b) from t1 where a='c' and b='c'; #drop table t1; # bug # bug#14007 create table t1 ( a char(10) primary key ) engine=ndb; insert into t1 values ('jonas % '); replace into t1 values ('jonas % '); replace into t1 values ('jonas % '); ) engine=ndbcluster default charset=latin1; insert into t1 values ('aaabb'); select * from t1; replace into t1 set a = 'AAABB'; select * from t1; replace into t1 set a = 'aAaBb'; select * from t1; replace into t1 set a = 'aaabb'; select * from t1; drop table t1; Loading ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp +16 −1 Original line number Diff line number Diff line Loading @@ -684,6 +684,21 @@ Dbtup::checkUpdateOfPrimaryKey(Uint32* updateBuffer, Tablerec* const regTabPtr) Uint32 attrDescriptorIndex = regTabPtr->tabDescriptor + (attributeId << ZAD_LOG_SIZE); Uint32 attrDescriptor = tableDescriptor[attrDescriptorIndex].tabDescr; Uint32 attributeOffset = tableDescriptor[attrDescriptorIndex + 1].tabDescr; Uint32 xfrmBuffer[1 + MAX_KEY_SIZE_IN_WORDS * MAX_XFRM_MULTIPLY]; Uint32 charsetFlag = AttributeOffset::getCharsetFlag(attributeOffset); if (charsetFlag) { Uint32 csIndex = AttributeOffset::getCharsetPos(attributeOffset); CHARSET_INFO* cs = regTabPtr->charsetArray[csIndex]; Uint32 srcPos = 0; Uint32 dstPos = 0; xfrm_attr(attrDescriptor, cs, &updateBuffer[1], srcPos, &xfrmBuffer[1], dstPos, MAX_KEY_SIZE_IN_WORDS * MAX_XFRM_MULTIPLY); ahIn.setDataSize(dstPos); xfrmBuffer[0] = ahIn.m_value; updateBuffer = xfrmBuffer; } ReadFunction f = regTabPtr->readFunctionArray[attributeId]; AttributeHeader::init(&attributeHeader, attributeId, 0); Loading @@ -691,7 +706,7 @@ Dbtup::checkUpdateOfPrimaryKey(Uint32* updateBuffer, Tablerec* const regTabPtr) tMaxRead = MAX_KEY_SIZE_IN_WORDS; bool tmp = tXfrmFlag; tXfrmFlag = false; tXfrmFlag = true; ndbrequire((this->*f)(&keyReadBuffer[0], ahOut, attrDescriptor, attributeOffset)); tXfrmFlag = tmp; ndbrequire(tOutBufIndex == ahOut->getDataSize()); Loading ndb/src/kernel/vm/SimulatedBlock.cpp +49 −43 Original line number Diff line number Diff line Loading @@ -1868,14 +1868,25 @@ SimulatedBlock::xfrm_key(Uint32 tab, const Uint32* src, while (i < noOfKeyAttr) { const KeyDescriptor::KeyAttr& keyAttr = desc->keyAttr[i]; Uint32 dstWords = xfrm_attr(keyAttr.attributeDescriptor, keyAttr.charsetInfo, src, srcPos, dst, dstPos, dstSize); keyPartLen[i++] = dstWords; } return dstPos; } Uint32 srcBytes = AttributeDescriptor::getSizeInBytes(keyAttr.attributeDescriptor); Uint32 SimulatedBlock::xfrm_attr(Uint32 attrDesc, CHARSET_INFO* cs, const Uint32* src, Uint32 & srcPos, Uint32* dst, Uint32 & dstPos, Uint32 dstSize) const { Uint32 srcBytes = AttributeDescriptor::getSizeInBytes(attrDesc); Uint32 srcWords = (srcBytes + 3) / 4; Uint32 dstWords = ~0; uchar* dstPtr = (uchar*)&dst[dstPos]; const uchar* srcPtr = (const uchar*)&src[srcPos]; CHARSET_INFO* cs = keyAttr.charsetInfo; if (cs == NULL) { Loading @@ -1886,8 +1897,7 @@ SimulatedBlock::xfrm_key(Uint32 tab, const Uint32* src, else { jam(); Uint32 typeId = AttributeDescriptor::getType(keyAttr.attributeDescriptor); Uint32 typeId = AttributeDescriptor::getType(attrDesc); Uint32 lb, len; bool ok = NdbSqlUtil::get_var_length(typeId, srcPtr, srcBytes, lb, len); ndbrequire(ok); Loading @@ -1895,9 +1905,8 @@ SimulatedBlock::xfrm_key(Uint32 tab, const Uint32* src, if (xmul == 0) xmul = 1; /* * Varchar is really Char. End spaces do not matter. To get * same hash we blank-pad to maximum length via strnxfrm. * TODO use MySQL charset-aware hash function instead * Varchar end-spaces are ignored in comparisons. To get same hash * we blank-pad to maximum length via strnxfrm. */ Uint32 dstLen = xmul * (srcBytes - lb); ndbrequire(dstLen <= ((dstSize - dstPos) << 2)); Loading @@ -1911,10 +1920,7 @@ SimulatedBlock::xfrm_key(Uint32 tab, const Uint32* src, } dstPos += dstWords; srcPos += srcWords; keyPartLen[i++] = dstWords; } return dstPos; return dstWords; } Uint32 Loading ndb/src/kernel/vm/SimulatedBlock.hpp +5 −1 Original line number Diff line number Diff line Loading @@ -395,9 +395,13 @@ protected: * @return length */ Uint32 xfrm_key(Uint32 tab, const Uint32* src, Uint32 *dst, Uint32 dstLen, Uint32 *dst, Uint32 dstSize, Uint32 keyPartLen[MAX_ATTRIBUTES_IN_INDEX]) const; Uint32 xfrm_attr(Uint32 attrDesc, CHARSET_INFO* cs, const Uint32* src, Uint32 & srcPos, Uint32* dst, Uint32 & dstPos, Uint32 dstSize) const; /** * */ Loading Loading
mysql-test/r/ndb_charset.result +15 −5 Original line number Diff line number Diff line Loading @@ -306,11 +306,21 @@ count(*) drop table t1; create table t1 ( a char(10) primary key ) engine=ndb; insert into t1 values ('jonas % '); replace into t1 values ('jonas % '); replace into t1 values ('jonas % '); ) engine=ndbcluster default charset=latin1; insert into t1 values ('aaabb'); select * from t1; a aaabb replace into t1 set a = 'AAABB'; select * from t1; a AAABB replace into t1 set a = 'aAaBb'; select * from t1; a aAaBb replace into t1 set a = 'aaabb'; select * from t1; a jonas % aaabb drop table t1;
mysql-test/t/ndb_charset.test +10 −5 Original line number Diff line number Diff line Loading @@ -237,13 +237,18 @@ drop table t1; #select a,b,length(a),length(b) from t1 where a='c' and b='c'; #drop table t1; # bug # bug#14007 create table t1 ( a char(10) primary key ) engine=ndb; insert into t1 values ('jonas % '); replace into t1 values ('jonas % '); replace into t1 values ('jonas % '); ) engine=ndbcluster default charset=latin1; insert into t1 values ('aaabb'); select * from t1; replace into t1 set a = 'AAABB'; select * from t1; replace into t1 set a = 'aAaBb'; select * from t1; replace into t1 set a = 'aaabb'; select * from t1; drop table t1; Loading
ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp +16 −1 Original line number Diff line number Diff line Loading @@ -684,6 +684,21 @@ Dbtup::checkUpdateOfPrimaryKey(Uint32* updateBuffer, Tablerec* const regTabPtr) Uint32 attrDescriptorIndex = regTabPtr->tabDescriptor + (attributeId << ZAD_LOG_SIZE); Uint32 attrDescriptor = tableDescriptor[attrDescriptorIndex].tabDescr; Uint32 attributeOffset = tableDescriptor[attrDescriptorIndex + 1].tabDescr; Uint32 xfrmBuffer[1 + MAX_KEY_SIZE_IN_WORDS * MAX_XFRM_MULTIPLY]; Uint32 charsetFlag = AttributeOffset::getCharsetFlag(attributeOffset); if (charsetFlag) { Uint32 csIndex = AttributeOffset::getCharsetPos(attributeOffset); CHARSET_INFO* cs = regTabPtr->charsetArray[csIndex]; Uint32 srcPos = 0; Uint32 dstPos = 0; xfrm_attr(attrDescriptor, cs, &updateBuffer[1], srcPos, &xfrmBuffer[1], dstPos, MAX_KEY_SIZE_IN_WORDS * MAX_XFRM_MULTIPLY); ahIn.setDataSize(dstPos); xfrmBuffer[0] = ahIn.m_value; updateBuffer = xfrmBuffer; } ReadFunction f = regTabPtr->readFunctionArray[attributeId]; AttributeHeader::init(&attributeHeader, attributeId, 0); Loading @@ -691,7 +706,7 @@ Dbtup::checkUpdateOfPrimaryKey(Uint32* updateBuffer, Tablerec* const regTabPtr) tMaxRead = MAX_KEY_SIZE_IN_WORDS; bool tmp = tXfrmFlag; tXfrmFlag = false; tXfrmFlag = true; ndbrequire((this->*f)(&keyReadBuffer[0], ahOut, attrDescriptor, attributeOffset)); tXfrmFlag = tmp; ndbrequire(tOutBufIndex == ahOut->getDataSize()); Loading
ndb/src/kernel/vm/SimulatedBlock.cpp +49 −43 Original line number Diff line number Diff line Loading @@ -1868,14 +1868,25 @@ SimulatedBlock::xfrm_key(Uint32 tab, const Uint32* src, while (i < noOfKeyAttr) { const KeyDescriptor::KeyAttr& keyAttr = desc->keyAttr[i]; Uint32 dstWords = xfrm_attr(keyAttr.attributeDescriptor, keyAttr.charsetInfo, src, srcPos, dst, dstPos, dstSize); keyPartLen[i++] = dstWords; } return dstPos; } Uint32 srcBytes = AttributeDescriptor::getSizeInBytes(keyAttr.attributeDescriptor); Uint32 SimulatedBlock::xfrm_attr(Uint32 attrDesc, CHARSET_INFO* cs, const Uint32* src, Uint32 & srcPos, Uint32* dst, Uint32 & dstPos, Uint32 dstSize) const { Uint32 srcBytes = AttributeDescriptor::getSizeInBytes(attrDesc); Uint32 srcWords = (srcBytes + 3) / 4; Uint32 dstWords = ~0; uchar* dstPtr = (uchar*)&dst[dstPos]; const uchar* srcPtr = (const uchar*)&src[srcPos]; CHARSET_INFO* cs = keyAttr.charsetInfo; if (cs == NULL) { Loading @@ -1886,8 +1897,7 @@ SimulatedBlock::xfrm_key(Uint32 tab, const Uint32* src, else { jam(); Uint32 typeId = AttributeDescriptor::getType(keyAttr.attributeDescriptor); Uint32 typeId = AttributeDescriptor::getType(attrDesc); Uint32 lb, len; bool ok = NdbSqlUtil::get_var_length(typeId, srcPtr, srcBytes, lb, len); ndbrequire(ok); Loading @@ -1895,9 +1905,8 @@ SimulatedBlock::xfrm_key(Uint32 tab, const Uint32* src, if (xmul == 0) xmul = 1; /* * Varchar is really Char. End spaces do not matter. To get * same hash we blank-pad to maximum length via strnxfrm. * TODO use MySQL charset-aware hash function instead * Varchar end-spaces are ignored in comparisons. To get same hash * we blank-pad to maximum length via strnxfrm. */ Uint32 dstLen = xmul * (srcBytes - lb); ndbrequire(dstLen <= ((dstSize - dstPos) << 2)); Loading @@ -1911,10 +1920,7 @@ SimulatedBlock::xfrm_key(Uint32 tab, const Uint32* src, } dstPos += dstWords; srcPos += srcWords; keyPartLen[i++] = dstWords; } return dstPos; return dstWords; } Uint32 Loading
ndb/src/kernel/vm/SimulatedBlock.hpp +5 −1 Original line number Diff line number Diff line Loading @@ -395,9 +395,13 @@ protected: * @return length */ Uint32 xfrm_key(Uint32 tab, const Uint32* src, Uint32 *dst, Uint32 dstLen, Uint32 *dst, Uint32 dstSize, Uint32 keyPartLen[MAX_ATTRIBUTES_IN_INDEX]) const; Uint32 xfrm_attr(Uint32 attrDesc, CHARSET_INFO* cs, const Uint32* src, Uint32 & srcPos, Uint32* dst, Uint32 & dstPos, Uint32 dstSize) const; /** * */ Loading