From 785e6c91bd48d55e260b749b4473d31fdfbe8d6d Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Wed, 19 Apr 2017 22:45:23 +0100 Subject: [PATCH] MCOL-670 Fix UPDATE with BLOB/TEXT * Don't cache > 8000 bytes during update * Fix PrimProc case where token is used more than once --- primitives/primproc/dictstep.cpp | 17 +++++++++++++---- writeengine/dictionary/we_dctnry.cpp | 8 ++++++-- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/primitives/primproc/dictstep.cpp b/primitives/primproc/dictstep.cpp index 29f9b2ac5..68576899b 100644 --- a/primitives/primproc/dictstep.cpp +++ b/primitives/primproc/dictstep.cpp @@ -520,6 +520,7 @@ void DictStep::_projectToRG(RowGroup &rg, uint32_t col) } else { uint32_t firstTmpResultCounter = tmpResultCounter; + std::map result; for (i = curResultCounter; i < firstTmpResultCounter; i++) { rg.getRow(newRidList[i].pos, &r); // If this is a multi-block blob, get all the blocks @@ -530,7 +531,14 @@ void DictStep::_projectToRG(RowGroup &rg, uint32_t col) { StringPtr multi_part[1]; uint16_t old_offset = primMsg->tokens[0].offset; - string *result = new string((char*)tmpStrings[i].ptr, tmpStrings[i].len); + if (result.empty()) + { + // String copy here because tmpStrings pointers will be blown away below + for (uint32_t x = curResultCounter; x < firstTmpResultCounter; x++) + { + result[x] = new string((char*)tmpStrings[x].ptr, tmpStrings[x].len); + } + } uint64_t origin_lbid = primMsg->LBID; uint32_t lbid_count = newRidList[i].token >> 46; primMsg->tokens[0].offset = 1; // first offset of a sig @@ -542,12 +550,13 @@ void DictStep::_projectToRG(RowGroup &rg, uint32_t col) primMsg->tokens[0].LBID = origin_lbid + j; issuePrimitive(false); projectResult(multi_part); - result->append((char*)multi_part[0].ptr, multi_part[0].len); + result[i]->append((char*)multi_part[0].ptr, multi_part[0].len); } primMsg->tokens[0].offset = old_offset; + primMsg->LBID = origin_lbid; tmpResultCounter = firstTmpResultCounter; - r.setVarBinaryField((unsigned char*)result->c_str(), result->length(), col); - delete result; + r.setVarBinaryField((unsigned char*)result[i]->c_str(), result[i]->length(), col); + delete result[i]; } else { diff --git a/writeengine/dictionary/we_dctnry.cpp b/writeengine/dictionary/we_dctnry.cpp index da669f3bf..8a4b9d2af 100644 --- a/writeengine/dictionary/we_dctnry.cpp +++ b/writeengine/dictionary/we_dctnry.cpp @@ -1374,7 +1374,9 @@ int Dctnry::updateDctnry(unsigned char* sigValue, int& sigSize, sig.size = sigSize; // Look for string in cache - if (m_arraySize < MAX_STRING_CACHE_SIZE) + // As long as the string <= 8000 bytes + if ((m_arraySize < MAX_STRING_CACHE_SIZE) && + (sigSize <= MAX_SIGNATURE_SIZE)) { bool found = false; found = getTokenFromArray(sig); @@ -1389,7 +1391,9 @@ int Dctnry::updateDctnry(unsigned char* sigValue, int& sigSize, rc = insertDctnry(sigSize, sigValue, token); //Add the new signature and token into cache - if (m_arraySize < MAX_STRING_CACHE_SIZE) + //As long as the string is <= 8000 bytes + if ((m_arraySize < MAX_STRING_CACHE_SIZE) && + (sigSize <= MAX_SIGNATURE_SIZE)) { Signature sig; sig.size = sigSize;