Commit 74dcfd25 authored by unknown's avatar unknown

ndb - bug#14007 5.0 *** does not automerge into 5.1 ***


mysql-test/r/ndb_charset.result:
  bug#14007 5.0
mysql-test/t/ndb_charset.test:
  bug#14007 5.0
ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp:
  bug#14007 5.0
ndb/src/kernel/vm/SimulatedBlock.cpp:
  bug#14007 5.0
ndb/src/kernel/vm/SimulatedBlock.hpp:
  bug#14007 5.0
parent 821cd17c
...@@ -306,11 +306,21 @@ count(*) ...@@ -306,11 +306,21 @@ count(*)
drop table t1; drop table t1;
create table t1 ( create table t1 (
a char(10) primary key a char(10) primary key
) engine=ndb; ) engine=ndbcluster default charset=latin1;
insert into t1 values ('jonas % '); insert into t1 values ('aaabb');
replace into t1 values ('jonas % '); select * from t1;
replace into t1 values ('jonas % '); 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; select * from t1;
a a
jonas % aaabb
drop table t1; drop table t1;
...@@ -237,13 +237,18 @@ drop table t1; ...@@ -237,13 +237,18 @@ drop table t1;
#select a,b,length(a),length(b) from t1 where a='c' and b='c'; #select a,b,length(a),length(b) from t1 where a='c' and b='c';
#drop table t1; #drop table t1;
# bug # bug#14007
create table t1 ( create table t1 (
a char(10) primary key a char(10) primary key
) engine=ndb; ) engine=ndbcluster default charset=latin1;
insert into t1 values ('jonas % ');
replace into t1 values ('jonas % '); insert into t1 values ('aaabb');
replace into t1 values ('jonas % '); 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; select * from t1;
drop table t1; drop table t1;
......
...@@ -685,22 +685,16 @@ Dbtup::checkUpdateOfPrimaryKey(Uint32* updateBuffer, Tablerec* const regTabPtr) ...@@ -685,22 +685,16 @@ Dbtup::checkUpdateOfPrimaryKey(Uint32* updateBuffer, Tablerec* const regTabPtr)
Uint32 attrDescriptor = tableDescriptor[attrDescriptorIndex].tabDescr; Uint32 attrDescriptor = tableDescriptor[attrDescriptorIndex].tabDescr;
Uint32 attributeOffset = tableDescriptor[attrDescriptorIndex + 1].tabDescr; Uint32 attributeOffset = tableDescriptor[attrDescriptorIndex + 1].tabDescr;
Uint32 xfrmBuffer[1 + MAX_KEY_SIZE_IN_WORDS * 1]; // strxfrm_multiply == 1 Uint32 xfrmBuffer[1 + MAX_KEY_SIZE_IN_WORDS * MAX_XFRM_MULTIPLY];
Uint32 charsetFlag = AttributeOffset::getCharsetFlag(attributeOffset); Uint32 charsetFlag = AttributeOffset::getCharsetFlag(attributeOffset);
if (charsetFlag) { if (charsetFlag) {
Uint32 csPos = AttributeOffset::getCharsetPos(attributeOffset); Uint32 csIndex = AttributeOffset::getCharsetPos(attributeOffset);
CHARSET_INFO* cs = regTabPtr->charsetArray[csPos]; CHARSET_INFO* cs = regTabPtr->charsetArray[csIndex];
Uint32 sizeInBytes = AttributeDescriptor::getSizeInBytes(attrDescriptor); Uint32 srcPos = 0;
Uint32 sizeInWords = AttributeDescriptor::getSizeInWords(attrDescriptor); Uint32 dstPos = 0;
const uchar* srcPtr = (uchar*)&updateBuffer[1]; xfrm_attr(attrDescriptor, cs, &updateBuffer[1], srcPos,
uchar* dstPtr = (uchar*)&xfrmBuffer[1]; &xfrmBuffer[1], dstPos, MAX_KEY_SIZE_IN_WORDS * MAX_XFRM_MULTIPLY);
Uint32 n = ahIn.setDataSize(dstPos);
(*cs->coll->strnxfrm)(cs, dstPtr, sizeInBytes, srcPtr, sizeInBytes);
// pad with blanks (unlikely) and zeroes to match NDB API behaviour
while (n < sizeInBytes)
dstPtr[n++] = 0x20;
while (n < 4 * sizeInWords)
dstPtr[n++] = 0;
xfrmBuffer[0] = ahIn.m_value; xfrmBuffer[0] = ahIn.m_value;
updateBuffer = xfrmBuffer; updateBuffer = xfrmBuffer;
} }
......
...@@ -1868,14 +1868,25 @@ SimulatedBlock::xfrm_key(Uint32 tab, const Uint32* src, ...@@ -1868,14 +1868,25 @@ SimulatedBlock::xfrm_key(Uint32 tab, const Uint32* src,
while (i < noOfKeyAttr) while (i < noOfKeyAttr)
{ {
const KeyDescriptor::KeyAttr& keyAttr = desc->keyAttr[i]; 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 = Uint32
AttributeDescriptor::getSizeInBytes(keyAttr.attributeDescriptor); 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 srcWords = (srcBytes + 3) / 4;
Uint32 dstWords = ~0; Uint32 dstWords = ~0;
uchar* dstPtr = (uchar*)&dst[dstPos]; uchar* dstPtr = (uchar*)&dst[dstPos];
const uchar* srcPtr = (const uchar*)&src[srcPos]; const uchar* srcPtr = (const uchar*)&src[srcPos];
CHARSET_INFO* cs = keyAttr.charsetInfo;
if (cs == NULL) if (cs == NULL)
{ {
...@@ -1886,8 +1897,7 @@ SimulatedBlock::xfrm_key(Uint32 tab, const Uint32* src, ...@@ -1886,8 +1897,7 @@ SimulatedBlock::xfrm_key(Uint32 tab, const Uint32* src,
else else
{ {
jam(); jam();
Uint32 typeId = Uint32 typeId = AttributeDescriptor::getType(attrDesc);
AttributeDescriptor::getType(keyAttr.attributeDescriptor);
Uint32 lb, len; Uint32 lb, len;
bool ok = NdbSqlUtil::get_var_length(typeId, srcPtr, srcBytes, lb, len); bool ok = NdbSqlUtil::get_var_length(typeId, srcPtr, srcBytes, lb, len);
ndbrequire(ok); ndbrequire(ok);
...@@ -1895,9 +1905,8 @@ SimulatedBlock::xfrm_key(Uint32 tab, const Uint32* src, ...@@ -1895,9 +1905,8 @@ SimulatedBlock::xfrm_key(Uint32 tab, const Uint32* src,
if (xmul == 0) if (xmul == 0)
xmul = 1; xmul = 1;
/* /*
* Varchar is really Char. End spaces do not matter. To get * Varchar end-spaces are ignored in comparisons. To get same hash
* same hash we blank-pad to maximum length via strnxfrm. * we blank-pad to maximum length via strnxfrm.
* TODO use MySQL charset-aware hash function instead
*/ */
Uint32 dstLen = xmul * (srcBytes - lb); Uint32 dstLen = xmul * (srcBytes - lb);
ndbrequire(dstLen <= ((dstSize - dstPos) << 2)); ndbrequire(dstLen <= ((dstSize - dstPos) << 2));
...@@ -1911,10 +1920,7 @@ SimulatedBlock::xfrm_key(Uint32 tab, const Uint32* src, ...@@ -1911,10 +1920,7 @@ SimulatedBlock::xfrm_key(Uint32 tab, const Uint32* src,
} }
dstPos += dstWords; dstPos += dstWords;
srcPos += srcWords; srcPos += srcWords;
keyPartLen[i++] = dstWords; return dstWords;
}
return dstPos;
} }
Uint32 Uint32
......
...@@ -395,9 +395,13 @@ protected: ...@@ -395,9 +395,13 @@ protected:
* @return length * @return length
*/ */
Uint32 xfrm_key(Uint32 tab, const Uint32* src, Uint32 xfrm_key(Uint32 tab, const Uint32* src,
Uint32 *dst, Uint32 dstLen, Uint32 *dst, Uint32 dstSize,
Uint32 keyPartLen[MAX_ATTRIBUTES_IN_INDEX]) const; 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;
/** /**
* *
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment