Commit defa8e84 authored by unknown's avatar unknown
Browse files

ndb - bug#14007 5.1 (merge 5.0->5.1)


mysql-test/r/ndb_charset.result:
  bug#14007 5.1 (merge 5.0->5.1)
mysql-test/t/ndb_charset.test:
  bug#14007 5.1 (merge 5.0->5.1)
storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp:
  bug#14007 5.1 (merge 5.0->5.1)
storage/ndb/src/kernel/vm/SimulatedBlock.cpp:
  bug#14007 5.1 (merge 5.0->5.1)
parent a93a2a90
Loading
Loading
Loading
Loading
+15 −5
Original line number Diff line number Diff line
@@ -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;
+10 −5
Original line number Diff line number Diff line
@@ -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;

+26 −11
Original line number Diff line number Diff line
@@ -807,6 +807,21 @@ Dbtup::checkUpdateOfPrimaryKey(KeyReqStruct* req_struct,
  Uint32 attrDescriptorIndex = attributeId << ZAD_LOG_SIZE;
  Uint32 attrDescriptor = attr_descr[attrDescriptorIndex].tabDescr;
  Uint32 attributeOffset = attr_descr[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);
@@ -815,7 +830,7 @@ Dbtup::checkUpdateOfPrimaryKey(KeyReqStruct* req_struct,
  req_struct->attr_descriptor = attrDescriptor;

  bool tmp = req_struct->xfrm_flag;
  req_struct->xfrm_flag = false;
  req_struct->xfrm_flag = true;
  ndbrequire((this->*f)(&keyReadBuffer[0],
                        req_struct,
                        ahOut,
+81 −73
Original line number Diff line number Diff line
@@ -1882,17 +1882,37 @@ 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;
  }

  if (0)
  {
    for(Uint32 i = 0; i<dstPos; i++)
    {
      printf("%.8x ", dst[i]);
    }
    printf("\n");
  }
  return dstPos;
}

Uint32
SimulatedBlock::xfrm_attr(Uint32 attrDesc, CHARSET_INFO* cs,
                          const Uint32* src, Uint32 & srcPos,
                          Uint32* dst, Uint32 & dstPos, Uint32 dstSize) const
{
  Uint32 array = 
      AttributeDescriptor::getArrayType(keyAttr.attributeDescriptor);
    AttributeDescriptor::getArrayType(attrDesc);
  Uint32 srcBytes = 
      AttributeDescriptor::getSizeInBytes(keyAttr.attributeDescriptor);
    AttributeDescriptor::getSizeInBytes(attrDesc);

  Uint32 srcWords = ~0;
  Uint32 dstWords = ~0;
  uchar* dstPtr = (uchar*)&dst[dstPos];
  const uchar* srcPtr = (const uchar*)&src[srcPos];
    CHARSET_INFO* cs = keyAttr.charsetInfo;
  
  if (cs == NULL)
  {
@@ -1929,7 +1949,7 @@ SimulatedBlock::xfrm_key(Uint32 tab, const Uint32* src,
  {
    jam();
    Uint32 typeId =
	AttributeDescriptor::getType(keyAttr.attributeDescriptor);
      AttributeDescriptor::getType(attrDesc);
    Uint32 lb, len;
    bool ok = NdbSqlUtil::get_var_length(typeId, srcPtr, srcBytes, lb, len);
    ndbrequire(ok);
@@ -1937,9 +1957,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));
@@ -1955,18 +1974,7 @@ SimulatedBlock::xfrm_key(Uint32 tab, const Uint32* src,

  dstPos += dstWords;
  srcPos += srcWords;
    keyPartLen[i++] = dstWords;
  }

  if (0)
  {
    for(Uint32 i = 0; i<dstPos; i++)
    {
      printf("%.8x ", dst[i]);
    }
    printf("\n");
  }
  return dstPos;
  return dstWords;
}

Uint32