diff options
Diffstat (limited to 'ndb/src/kernel/blocks/dbtup')
-rw-r--r-- | ndb/src/kernel/blocks/dbtup/Dbtup.hpp | 20 | ||||
-rw-r--r-- | ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp | 113 | ||||
-rw-r--r-- | ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp | 8 | ||||
-rw-r--r-- | ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp | 12 | ||||
-rw-r--r-- | ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp | 169 | ||||
-rw-r--r-- | ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp | 6 |
6 files changed, 150 insertions, 178 deletions
diff --git a/ndb/src/kernel/blocks/dbtup/Dbtup.hpp b/ndb/src/kernel/blocks/dbtup/Dbtup.hpp index 1c7662c5d55..6d169d20d16 100644 --- a/ndb/src/kernel/blocks/dbtup/Dbtup.hpp +++ b/ndb/src/kernel/blocks/dbtup/Dbtup.hpp @@ -207,6 +207,8 @@ #define ZTUPLE_DELETED_ERROR 626 #define ZINSERT_ERROR 630 +#define ZINVALID_CHAR_FORMAT 744 + /* SOME WORD POSITIONS OF FIELDS IN SOME HEADERS */ #define ZPAGE_STATE_POS 0 /* POSITION OF PAGE STATE */ @@ -1020,14 +1022,14 @@ public: * for md5 summing and when returning keyinfo. Returns number of * words or negative (-terrorCode) on error. */ - int tuxReadPk(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* dataOut); + int tuxReadPk(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* dataOut, bool xfrmFlag); /* * ACC reads primary key without headers into an array of words. At * this point in ACC deconstruction, ACC still uses logical references * to fragment and tuple. */ - int accReadPk(Uint32 tableId, Uint32 fragId, Uint32 fragPageId, Uint32 pageIndex, Uint32* dataOut); + int accReadPk(Uint32 tableId, Uint32 fragId, Uint32 fragPageId, Uint32 pageIndex, Uint32* dataOut, bool xfrmFlag); /* * TUX checks if tuple is visible to scan. @@ -1637,20 +1639,6 @@ private: bool readBitsNotNULL(Uint32* outBuffer, AttributeHeader*, Uint32, Uint32); bool updateBitsNotNULL(Uint32* inBuffer, Uint32, Uint32); -// ***************************************************************** -// Read char routines optionally (tXfrmFlag) apply strxfrm -// ***************************************************************** - - bool readCharNotNULL(Uint32* outBuffer, - AttributeHeader* ahOut, - Uint32 attrDescriptor, - Uint32 attrDes2); - - bool readCharNULLable(Uint32* outBuffer, - AttributeHeader* ahOut, - Uint32 attrDescriptor, - Uint32 attrDes2); - //------------------------------------------------------------------ //------------------------------------------------------------------ bool nullFlagCheck(Uint32 attrDes2); diff --git a/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp b/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp index 8e3ca6528c2..9778c938e0f 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp @@ -858,6 +858,8 @@ void Dbtup::sendTUPKEYCONF(Signal* signal, return; }//Dbtup::sendTUPKEYCONF() +#define MAX_READ (sizeof(signal->theData) > MAX_MESSAGE_SIZE ? MAX_MESSAGE_SIZE : sizeof(signal->theData)) + /* ---------------------------------------------------------------- */ /* ----------------------------- READ ---------------------------- */ /* ---------------------------------------------------------------- */ @@ -878,7 +880,7 @@ int Dbtup::handleReadReq(Signal* signal, }//if Uint32 * dst = &signal->theData[25]; - Uint32 dstLen = (sizeof(signal->theData) / 4) - 25; + Uint32 dstLen = (MAX_READ / 4) - 25; const Uint32 node = refToNode(sendBref); if(node != 0 && node != getOwnNodeId()) { ; @@ -888,7 +890,7 @@ int Dbtup::handleReadReq(Signal* signal, * execute direct */ dst = &signal->theData[3]; - dstLen = (sizeof(signal->theData) / 4) - 3; + dstLen = (MAX_READ / 4) - 3; } if (regOperPtr->interpretedExec != 1) { @@ -1228,7 +1230,7 @@ int Dbtup::interpreterStartLab(Signal* signal, const BlockReference sendBref = regOperPtr->recBlockref; Uint32 * dst = &signal->theData[25]; - Uint32 dstLen = (sizeof(signal->theData) / 4) - 25; + Uint32 dstLen = (MAX_READ / 4) - 25; const Uint32 node = refToNode(sendBref); if(node != 0 && node != getOwnNodeId()) { ; @@ -1238,7 +1240,7 @@ int Dbtup::interpreterStartLab(Signal* signal, * execute direct */ dst = &signal->theData[3]; - dstLen = (sizeof(signal->theData) / 4) - 3; + dstLen = (MAX_READ / 4) - 3; } RtotalLen = RinitReadLen; @@ -1538,13 +1540,8 @@ int Dbtup::interpreterNextLab(Signal* signal, // Calculate the number of words of this attribute. // We allow writes into arrays as long as they fit into the 64 bit // register size. - //TEST_MR See to that TattrNoOfWords can be - // read faster from attribute description. /* --------------------------------------------------------------- */ - Uint32 TarraySize = (TattrDesc1 >> 16); - Uint32 TattrLogLen = (TattrDesc1 >> 4) & 0xf; - Uint32 TattrNoOfBits = TarraySize << TattrLogLen; - Uint32 TattrNoOfWords = (TattrNoOfBits + 31) >> 5; + Uint32 TattrNoOfWords = AttributeDescriptor::getSizeInWords(TattrDesc1); Uint32 Toptype = operPtr.p->optype; Uint32 TdataForUpdate[3]; @@ -1821,9 +1818,6 @@ int Dbtup::interpreterNextLab(Signal* signal, case Interpreter::BRANCH_ATTR_OP_ARG:{ jam(); Uint32 cond = Interpreter::getBinaryCondition(theInstruction); - Uint32 diff = Interpreter::getArrayLengthDiff(theInstruction); - Uint32 vchr = Interpreter::isVarchar(theInstruction); - Uint32 nopad =Interpreter::isNopad(theInstruction); Uint32 ins2 = TcurrentProgram[TprogramCounter]; Uint32 attrId = Interpreter::getBranchCol_AttrId(ins2) << 16; Uint32 argLen = Interpreter::getBranchCol_Len(ins2); @@ -1842,84 +1836,81 @@ int Dbtup::interpreterNextLab(Signal* signal, } tmpHabitant = attrId; } - - AttributeHeader ah(tmpArea[0]); + attrId >>= 16; + AttributeHeader ah(tmpArea[0]); + const char* s1 = (char*)&tmpArea[1]; const char* s2 = (char*)&TcurrentProgram[TprogramCounter+1]; - Uint32 attrLen = (4 * ah.getDataSize()) - diff; - if (vchr) { -#if NDB_VERSION_MAJOR >= 3 - bool vok = false; - if (attrLen >= 2) { - Uint32 vlen = (s1[0] << 8) | s1[1]; // big-endian - s1 += 2; - attrLen -= 2; - if (attrLen >= vlen) { - attrLen = vlen; - vok = true; - } - } - if (!vok) { - terrorCode = ZREGISTER_INIT_ERROR; - tupkeyErrorLab(signal); - return -1; - } -#else - Uint32 tmp; - if (attrLen >= 2) { - unsigned char* ss = (unsigned char*)&s1[attrLen - 2]; - tmp = (ss[0] << 8) | ss[1]; - if (tmp <= attrLen - 2) - attrLen = tmp; - } - // XXX handle bad data -#endif - } - bool res = false; - + Uint32 attrLen = (4 * ah.getDataSize()); + Uint32 TattrDescrIndex = tabptr.p->tabDescriptor + + (attrId << ZAD_LOG_SIZE); + Uint32 TattrDesc1 = tableDescriptor[TattrDescrIndex].tabDescr; + Uint32 TattrDesc2 = tableDescriptor[TattrDescrIndex+1].tabDescr; + Uint32 typeId = AttributeDescriptor::getType(TattrDesc1); + void * cs = 0; + if(AttributeOffset::getCharsetFlag(TattrDesc2)) + { + Uint32 pos = AttributeOffset::getCharsetPos(TattrDesc2); + cs = tabptr.p->charsetArray[pos]; + } + const NdbSqlUtil::Type& sqlType = NdbSqlUtil::getType(typeId); + + bool r1_null = ah.isNULL(); + bool r2_null = argLen == 0; + int res; + if(r1_null || r2_null) + { + res = r1_null && r2_null ? 0 : r1_null ? -1 : 1; + } + else + { + res = (*sqlType.m_cmp)(cs, s1, attrLen, s2, argLen, true); + } + switch ((Interpreter::BinaryCondition)cond) { case Interpreter::EQ: - res = NdbSqlUtil::char_compare(s1, attrLen, s2, argLen, !nopad) == 0; + res = (res == 0); break; case Interpreter::NE: - res = NdbSqlUtil::char_compare(s1, attrLen, s2, argLen, !nopad) != 0; + res = (res != 0); break; // note the condition is backwards case Interpreter::LT: - res = NdbSqlUtil::char_compare(s1, attrLen, s2, argLen, !nopad) > 0; + res = (res > 0); break; case Interpreter::LE: - res = NdbSqlUtil::char_compare(s1, attrLen, s2, argLen, !nopad) >= 0; + res = (res >= 0); break; case Interpreter::GT: - res = NdbSqlUtil::char_compare(s1, attrLen, s2, argLen, !nopad) < 0; + res = (res < 0); break; case Interpreter::GE: - res = NdbSqlUtil::char_compare(s1, attrLen, s2, argLen, !nopad) <= 0; + res = (res <= 0); break; case Interpreter::LIKE: - res = NdbSqlUtil::char_like(s1, attrLen, s2, argLen, !nopad); + res = NdbSqlUtil::char_like(s1, attrLen, s2, argLen, false); break; case Interpreter::NOT_LIKE: - res = ! NdbSqlUtil::char_like(s1, attrLen, s2, argLen, !nopad); + res = ! NdbSqlUtil::char_like(s1, attrLen, s2, argLen, false); break; - // XXX handle invalid value + // XXX handle invalid value } #ifdef TRACE_INTERPRETER - ndbout_c("cond=%u diff=%d vc=%d nopad=%d attr(%d) = >%.*s<(%d) str=>%.*s<(%d) -> res = %d", - cond, diff, vchr, nopad, - attrId >> 16, attrLen, s1, attrLen, argLen, s2, argLen, res); + ndbout_c("cond=%u diff=%d vc=%d nopad=%d attr(%d) = >%.*s<(%d) str=>%.*s<(%d) -> res = %d", + cond, diff, vchr, nopad, + attrId >> 16, attrLen, s1, attrLen, argLen, s2, argLen, res); #endif if (res) TprogramCounter = brancher(theInstruction, TprogramCounter); - else { - Uint32 tmp = (Interpreter::mod4(argLen) >> 2) + 1; + else + { + Uint32 tmp = ((argLen + 3) >> 2) + 1; TprogramCounter += tmp; } break; } - + case Interpreter::BRANCH_ATTR_EQ_NULL:{ jam(); Uint32 ins2 = TcurrentProgram[TprogramCounter]; diff --git a/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp b/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp index 3b0ba1c196f..ab6e0642e11 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp @@ -173,7 +173,7 @@ Dbtup::tuxReadAttrs(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32 tu } int -Dbtup::tuxReadPk(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* dataOut) +Dbtup::tuxReadPk(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* dataOut, bool xfrmFlag) { ljamEntry(); // use own variables instead of globals @@ -200,7 +200,7 @@ Dbtup::tuxReadPk(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* data operPtr.i = RNIL; operPtr.p = NULL; // do it - int ret = readAttributes(pagePtr.p, pageOffset, attrIds, numAttrs, dataOut, ZNIL, true); + int ret = readAttributes(pagePtr.p, pageOffset, attrIds, numAttrs, dataOut, ZNIL, xfrmFlag); // restore globals tabptr = tabptr_old; fragptr = fragptr_old; @@ -229,7 +229,7 @@ Dbtup::tuxReadPk(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* data } int -Dbtup::accReadPk(Uint32 tableId, Uint32 fragId, Uint32 fragPageId, Uint32 pageIndex, Uint32* dataOut) +Dbtup::accReadPk(Uint32 tableId, Uint32 fragId, Uint32 fragPageId, Uint32 pageIndex, Uint32* dataOut, bool xfrmFlag) { ljamEntry(); // get table @@ -245,7 +245,7 @@ Dbtup::accReadPk(Uint32 tableId, Uint32 fragId, Uint32 fragPageId, Uint32 pageIn ndbrequire((pageIndex & 0x1) == 0); Uint32 pageOffset = ZPAGE_HEADER_SIZE + (pageIndex >> 1) * tablePtr.p->tupheadsize; // use TUX routine - optimize later - int ret = tuxReadPk(fragPtr.i, pageId, pageOffset, dataOut); + int ret = tuxReadPk(fragPtr.i, pageId, pageOffset, dataOut, xfrmFlag); return ret; } diff --git a/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp b/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp index 56ae861270c..4ce807528c4 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp @@ -288,8 +288,7 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* signal) ptrCheckGuard(fragOperPtr, cnoOfFragoprec, fragoperrec); Uint32 attrId = signal->theData[2]; Uint32 attrDescriptor = signal->theData[3]; - // DICT sends extended type (ignored) and charset number - Uint32 extType = (signal->theData[4] & 0xFF); + // DICT sends charset number in upper half Uint32 csNumber = (signal->theData[4] >> 16); regTabPtr.i = fragOperPtr.p->tableidFrag; @@ -364,13 +363,8 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* signal) ndbrequire(false); }//if if (csNumber != 0) { - CHARSET_INFO* cs = get_charset(csNumber, MYF(0)); - if (cs == NULL) { - ljam(); - terrorCode = TupAddAttrRef::InvalidCharset; - addattrrefuseLab(signal, regFragPtr, fragOperPtr, regTabPtr.p, fragId); - return; - } + CHARSET_INFO* cs = all_charsets[csNumber]; + ndbrequire(cs != NULL); Uint32 i = 0; while (i < fragOperPtr.p->charsetIndex) { ljam(); diff --git a/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp b/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp index 5bcbb482a8c..3c25e675a5e 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp @@ -59,10 +59,11 @@ Dbtup::setUpQueryRoutines(Tablerec* const regTabPtr) } else { ndbrequire(false); }//if - // replace read function of char attribute + // replace functions for char attribute if (AttributeOffset::getCharsetFlag(attrOffset)) { ljam(); - regTabPtr->readFunctionArray[i] = &Dbtup::readCharNotNULL; + regTabPtr->readFunctionArray[i] = &Dbtup::readFixedSizeTHManyWordNotNULL; + regTabPtr->updateFunctionArray[i] = &Dbtup::updateFixedSizeTHManyWordNotNULL; } } else { if (AttributeDescriptor::getSize(attrDescriptor) == 0){ @@ -86,10 +87,11 @@ Dbtup::setUpQueryRoutines(Tablerec* const regTabPtr) regTabPtr->readFunctionArray[i] = &Dbtup::readFixedSizeTHZeroWordNULLable; regTabPtr->updateFunctionArray[i] = &Dbtup::updateFixedSizeTHManyWordNULLable; }//if - // replace read function of char attribute + // replace functions for char attribute if (AttributeOffset::getCharsetFlag(attrOffset)) { ljam(); - regTabPtr->readFunctionArray[i] = &Dbtup::readCharNULLable; + regTabPtr->readFunctionArray[i] = &Dbtup::readFixedSizeTHManyWordNULLable; + regTabPtr->updateFunctionArray[i] = &Dbtup::updateFixedSizeTHManyWordNULLable; } }//if } else if (AttributeDescriptor::getArrayType(attrDescriptor) == ZVAR_ARRAY) { @@ -337,25 +339,68 @@ Dbtup::readFixedSizeTHManyWordNotNULL(Uint32* outBuffer, Uint32 attrDes2) { Uint32 indexBuf = tOutBufIndex; + Uint32 charsetFlag = AttributeOffset::getCharsetFlag(attrDes2); Uint32 readOffset = AttributeOffset::getOffset(attrDes2); Uint32 attrNoOfWords = AttributeDescriptor::getSizeInWords(attrDescriptor); - Uint32 newIndexBuf = indexBuf + attrNoOfWords; Uint32 maxRead = tMaxRead; ndbrequire((readOffset + attrNoOfWords - 1) < tCheckOffset); - if (newIndexBuf <= maxRead) { - ljam(); - ahOut->setDataSize(attrNoOfWords); - MEMCOPY_NO_WORDS(&outBuffer[indexBuf], - &tTupleHeader[readOffset], - attrNoOfWords); - tOutBufIndex = newIndexBuf; - return true; + if (! charsetFlag || ! tXfrmFlag) { + Uint32 newIndexBuf = indexBuf + attrNoOfWords; + if (newIndexBuf <= maxRead) { + ljam(); + ahOut->setDataSize(attrNoOfWords); + MEMCOPY_NO_WORDS(&outBuffer[indexBuf], + &tTupleHeader[readOffset], + attrNoOfWords); + tOutBufIndex = newIndexBuf; + return true; + } else { + ljam(); + terrorCode = ZTRY_TO_READ_TOO_MUCH_ERROR; + }//if } else { ljam(); - terrorCode = ZTRY_TO_READ_TOO_MUCH_ERROR; - return false; - }//if + Tablerec* regTabPtr = tabptr.p; + Uint32 srcBytes = AttributeDescriptor::getSizeInBytes(attrDescriptor); + Uint32 i = AttributeOffset::getCharsetPos(attrDes2); + ndbrequire(i < regTabPtr->noOfCharsets); + CHARSET_INFO* cs = regTabPtr->charsetArray[i]; + Uint32 xmul = cs->strxfrm_multiply; + if (xmul == 0) + xmul = 1; + Uint32 dstLen = xmul * srcBytes; + Uint32 maxIndexBuf = indexBuf + (dstLen >> 2); + if (maxIndexBuf <= maxRead) { + ljam(); + uchar* dstPtr = (uchar*)&outBuffer[indexBuf]; + const uchar* srcPtr = (uchar*)&tTupleHeader[readOffset]; + const char* ssrcPtr = (const char*)srcPtr; + // could verify data format optionally + if (true || + (*cs->cset->well_formed_len)(cs, ssrcPtr, ssrcPtr + srcBytes, ZNIL) == srcBytes) { + ljam(); + // normalize + Uint32 n = (*cs->coll->strnxfrm)(cs, dstPtr, dstLen, srcPtr, srcBytes); + while ((n & 3) != 0) { + dstPtr[n++] = 0; + } + Uint32 dstWords = (n >> 2); + ahOut->setDataSize(dstWords); + Uint32 newIndexBuf = indexBuf + dstWords; + ndbrequire(newIndexBuf <= maxRead); + tOutBufIndex = newIndexBuf; + return true; + } else { + ljam(); + terrorCode = ZTUPLE_CORRUPTED_ERROR; + } + } else { + ljam(); + terrorCode = ZTRY_TO_READ_TOO_MUCH_ERROR; + } + } + return false; }//Dbtup::readFixedSizeTHManyWordNotNULL() bool @@ -402,7 +447,6 @@ Dbtup::readFixedSizeTHManyWordNULLable(Uint32* outBuffer, Uint32 attrDescriptor, Uint32 attrDes2) { -ljam(); if (!nullFlagCheck(attrDes2)) { ljam(); return readFixedSizeTHManyWordNotNULL(outBuffer, @@ -563,74 +607,6 @@ Dbtup::readDynSmallVarSize(Uint32* outBuffer, return false; }//Dbtup::readDynSmallVarSize() - -bool -Dbtup::readCharNotNULL(Uint32* outBuffer, - AttributeHeader* ahOut, - Uint32 attrDescriptor, - Uint32 attrDes2) -{ - Uint32 indexBuf = tOutBufIndex; - Uint32 readOffset = AttributeOffset::getOffset(attrDes2); - Uint32 attrNoOfWords = AttributeDescriptor::getSizeInWords(attrDescriptor); - Uint32 newIndexBuf = indexBuf + attrNoOfWords; - Uint32 maxRead = tMaxRead; - - ndbrequire((readOffset + attrNoOfWords - 1) < tCheckOffset); - if (newIndexBuf <= maxRead) { - ljam(); - ahOut->setDataSize(attrNoOfWords); - if (! tXfrmFlag) { - MEMCOPY_NO_WORDS(&outBuffer[indexBuf], - &tTupleHeader[readOffset], - attrNoOfWords); - } else { - ljam(); - Tablerec* regTabPtr = tabptr.p; - Uint32 i = AttributeOffset::getCharsetPos(attrDes2); - ndbrequire(i < tabptr.p->noOfCharsets); - // not const in MySQL - CHARSET_INFO* cs = tabptr.p->charsetArray[i]; - // XXX should strip Uint32 null padding - const unsigned nBytes = attrNoOfWords << 2; - unsigned n = - (*cs->coll->strnxfrm)(cs, - (uchar*)&outBuffer[indexBuf], - nBytes, - (const uchar*)&tTupleHeader[readOffset], - nBytes); - // pad with ascii spaces - while (n < nBytes) - ((uchar*)&outBuffer[indexBuf])[n++] = 0x20; - } - tOutBufIndex = newIndexBuf; - return true; - } else { - ljam(); - terrorCode = ZTRY_TO_READ_TOO_MUCH_ERROR; - return false; - } -} - -bool -Dbtup::readCharNULLable(Uint32* outBuffer, - AttributeHeader* ahOut, - Uint32 attrDescriptor, - Uint32 attrDes2) -{ - if (!nullFlagCheck(attrDes2)) { - ljam(); - return readCharNotNULL(outBuffer, - ahOut, - attrDescriptor, - attrDes2); - } else { - ljam(); - ahOut->setNULL(); - return true; - } -} - /* ---------------------------------------------------------------------- */ /* THIS ROUTINE IS USED TO UPDATE A NUMBER OF ATTRIBUTES. IT IS */ /* USED BY THE INSERT ROUTINE, THE UPDATE ROUTINE AND IT CAN BE */ @@ -818,6 +794,7 @@ Dbtup::updateFixedSizeTHManyWordNotNULL(Uint32* inBuffer, Uint32 indexBuf = tInBufIndex; Uint32 inBufLen = tInBufLen; Uint32 updateOffset = AttributeOffset::getOffset(attrDes2); + Uint32 charsetFlag = AttributeOffset::getCharsetFlag(attrDes2); AttributeHeader ahIn(inBuffer[indexBuf]); Uint32 nullIndicator = ahIn.isNULL(); Uint32 noOfWords = AttributeDescriptor::getSizeInWords(attrDescriptor); @@ -827,6 +804,21 @@ Dbtup::updateFixedSizeTHManyWordNotNULL(Uint32* inBuffer, if (newIndex <= inBufLen) { if (!nullIndicator) { ljam(); + if (charsetFlag) { + ljam(); + Tablerec* regTabPtr = tabptr.p; + Uint32 bytes = AttributeDescriptor::getSizeInBytes(attrDescriptor); + Uint32 i = AttributeOffset::getCharsetPos(attrDes2); + ndbrequire(i < regTabPtr->noOfCharsets); + // not const in MySQL + CHARSET_INFO* cs = regTabPtr->charsetArray[i]; + const char* ssrc = (const char*)&inBuffer[tInBufIndex + 1]; + if ((*cs->cset->well_formed_len)(cs, ssrc, ssrc + bytes, ZNIL) != bytes) { + ljam(); + terrorCode = ZINVALID_CHAR_FORMAT; + return false; + } + } tInBufIndex = newIndex; MEMCOPY_NO_WORDS(&tTupleHeader[updateOffset], &inBuffer[indexBuf + 1], @@ -1012,6 +1004,13 @@ Dbtup::read_psuedo(Uint32 attrId, Uint32* outBuffer){ outBuffer[0] = signal->theData[0]; outBuffer[1] = signal->theData[1]; return 2; + case AttributeHeader::RANGE_NO: + signal->theData[0] = operPtr.p->userpointer; + signal->theData[1] = attrId; + + EXECUTE_DIRECT(DBLQH, GSN_READ_PSUEDO_REQ, signal, 2); + outBuffer[0] = signal->theData[0]; + return 1; default: return 0; } diff --git a/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp b/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp index aac5c326cad..476a4b5724b 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp @@ -753,7 +753,7 @@ bool Dbtup::readTriggerInfo(TupTriggerData* const trigPtr, regTabPtr->noOfKeyAttr, keyBuffer, ZATTR_BUFFER_SIZE, - true); + false); ndbrequire(ret != -1); noPrimKey= ret; @@ -796,7 +796,7 @@ bool Dbtup::readTriggerInfo(TupTriggerData* const trigPtr, numAttrsToRead, mainBuffer, ZATTR_BUFFER_SIZE, - true); + false); ndbrequire(ret != -1); noMainWords= ret; } else { @@ -822,7 +822,7 @@ bool Dbtup::readTriggerInfo(TupTriggerData* const trigPtr, numAttrsToRead, copyBuffer, ZATTR_BUFFER_SIZE, - true); + false); ndbrequire(ret != -1); noCopyWords = ret; |