mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
ndb - bug#14007 5.0 *** does not automerge into 5.1 ***
This commit is contained in:
@@ -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
|
||||
jonas %
|
||||
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
|
||||
aaabb
|
||||
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';
|
||||
#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;
|
||||
|
||||
|
@@ -685,22 +685,16 @@ Dbtup::checkUpdateOfPrimaryKey(Uint32* updateBuffer, Tablerec* const regTabPtr)
|
||||
Uint32 attrDescriptor = tableDescriptor[attrDescriptorIndex].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);
|
||||
if (charsetFlag) {
|
||||
Uint32 csPos = AttributeOffset::getCharsetPos(attributeOffset);
|
||||
CHARSET_INFO* cs = regTabPtr->charsetArray[csPos];
|
||||
Uint32 sizeInBytes = AttributeDescriptor::getSizeInBytes(attrDescriptor);
|
||||
Uint32 sizeInWords = AttributeDescriptor::getSizeInWords(attrDescriptor);
|
||||
const uchar* srcPtr = (uchar*)&updateBuffer[1];
|
||||
uchar* dstPtr = (uchar*)&xfrmBuffer[1];
|
||||
Uint32 n =
|
||||
(*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;
|
||||
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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
Uint32 srcBytes =
|
||||
AttributeDescriptor::getSizeInBytes(keyAttr.attributeDescriptor);
|
||||
return dstPos;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -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);
|
||||
@@ -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));
|
||||
@@ -1911,10 +1920,7 @@ SimulatedBlock::xfrm_key(Uint32 tab, const Uint32* src,
|
||||
}
|
||||
dstPos += dstWords;
|
||||
srcPos += srcWords;
|
||||
keyPartLen[i++] = dstWords;
|
||||
}
|
||||
|
||||
return dstPos;
|
||||
return dstWords;
|
||||
}
|
||||
|
||||
Uint32
|
||||
|
@@ -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;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
Reference in New Issue
Block a user