From: Jan Wedvik Date: October 20 2011 12:46pm Subject: bzr push into mysql-5.1-telco-7.0 branch (jan.wedvik:4610 to 4611) List-Archive: http://lists.mysql.com/commits/141516 Message-Id: <20111020124613.A70DFD1E@atum17.no.oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 4611 Jan Wedvik 2011-10-20 This commit concerns SPJ (i.e. pushed queries). The commit fixes two errors that may happend when there is a pruned child scan operation: 1. The api did not set SIP_PRUNE_PARAMS as it should. 2. There was an error in Dbspj::parseScanIndex(). When it called Dbspj::expand() to process prune keys, it used to start reading query parameters from after whatever parseDA() had consumed. Now it starts from the beginning of the query parameters (for that operation). In other words, the parameter values are only sent once, and these values are used for building both the scan bounds and the prune key. modified: storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp storage/ndb/src/ndbapi/NdbQueryBuilder.cpp storage/ndb/src/ndbapi/NdbQueryBuilderImpl.hpp storage/ndb/src/ndbapi/NdbQueryOperation.cpp 4610 Frazer Clement 2011-10-20 Bug#13117187 NDB : BAD CONNECT_REP STATE ASSERTION Initial patch to clean up existing code. Reuse of nodePtr var for running and connecting node removed. Running node in ZAPI_ states case branches turned into errors. Further work required to handle case of connectedNode in ZPREPARE_FAIL (Waiting for president to commit failure handling), and potentially other connectedNode states. modified: storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp === modified file 'storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp' --- a/storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp 2011-09-29 11:43:27 +0000 +++ b/storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp 2011-10-20 12:45:36 +0000 @@ -3601,6 +3601,7 @@ Dbspj::computeHash(Signal* signal, (MAX_KEY_SIZE_IN_WORDS + 1) / 2; Uint64 tmp64[MAX_KEY_SIZE_IN_LONG_WORDS]; Uint32 *tmp32 = (Uint32*)tmp64; + ndbassert(ptr.sz <= MAX_KEY_SIZE_IN_WORDS); copy(tmp32, ptr); const KeyDescriptor* desc = g_key_descriptor_pool.getPtr(tableId); @@ -3639,6 +3640,7 @@ Dbspj::computePartitionHash(Signal* sign Uint64 *tmp64 = _space; Uint32 *tmp32 = (Uint32*)tmp64; Uint32 sz = ptr.sz; + ndbassert(ptr.sz <= MAX_KEY_SIZE_IN_WORDS); copy(tmp32, ptr); const KeyDescriptor* desc = g_key_descriptor_pool.getPtr(tableId); @@ -4456,6 +4458,12 @@ Dbspj::parseScanIndex(Build_context& ctx data.m_firstExecution = true; data.m_batch_chunks = 0; + /** + * We will need to look at the parameters again if the scan is pruned and the prune + * key uses parameter values. Therefore, we keep a reference to the start of the + * parameter buffer. + */ + DABuffer origParam = param; err = parseDA(ctx, requestPtr, treeNodePtr, tree, treeBits, param, paramBits); if (unlikely(err != 0)) @@ -4482,7 +4490,7 @@ Dbspj::parseScanIndex(Build_context& ctx /** * Expand pattern into a new pattern (with linked values) */ - err = expand(pattern, treeNodePtr, tree, len, param, cnt); + err = expand(pattern, treeNodePtr, tree, len, origParam, cnt); if (unlikely(err != 0)) break; @@ -4501,7 +4509,7 @@ Dbspj::parseScanIndex(Build_context& ctx */ Uint32 prunePtrI = RNIL; bool hasNull; - err = expand(prunePtrI, tree, len, param, cnt, hasNull); + err = expand(prunePtrI, tree, len, origParam, cnt, hasNull); if (unlikely(err != 0)) break; @@ -6189,6 +6197,7 @@ Uint32 Dbspj::appendToPattern(Local_pattern_store & pattern, DABuffer & tree, Uint32 len) { + jam(); if (unlikely(tree.ptr + len > tree.end)) return DbspjErr::InvalidTreeNodeSpecification; @@ -6203,6 +6212,7 @@ Uint32 Dbspj::appendParamToPattern(Local_pattern_store& dst, const RowPtr::Linear & row, Uint32 col) { + jam(); /** * TODO handle errors */ @@ -6218,6 +6228,7 @@ Uint32 Dbspj::appendParamHeadToPattern(Local_pattern_store& dst, const RowPtr::Linear & row, Uint32 col) { + jam(); /** * TODO handle errors */ @@ -6235,6 +6246,7 @@ Dbspj::appendTreeToSection(Uint32 & ptrI /** * TODO handle errors */ + jam(); Uint32 SZ = 16; Uint32 tmp[16]; while (len > SZ) @@ -6293,6 +6305,7 @@ Uint32 Dbspj::appendColToSection(Uint32 & dst, const RowPtr::Section & row, Uint32 col, bool& hasNull) { + jam(); /** * TODO handle errors */ @@ -6316,6 +6329,7 @@ Uint32 Dbspj::appendColToSection(Uint32 & dst, const RowPtr::Linear & row, Uint32 col, bool& hasNull) { + jam(); /** * TODO handle errors */ @@ -6335,6 +6349,7 @@ Uint32 Dbspj::appendAttrinfoToSection(Uint32 & dst, const RowPtr::Linear & row, Uint32 col, bool& hasNull) { + jam(); /** * TODO handle errors */ @@ -6353,6 +6368,7 @@ Uint32 Dbspj::appendAttrinfoToSection(Uint32 & dst, const RowPtr::Section & row, Uint32 col, bool& hasNull) { + jam(); /** * TODO handle errors */ @@ -6378,6 +6394,7 @@ Dbspj::appendAttrinfoToSection(Uint32 & Uint32 Dbspj::appendPkColToSection(Uint32 & dst, const RowPtr::Section & row, Uint32 col) { + jam(); /** * TODO handle errors */ @@ -6400,6 +6417,7 @@ Dbspj::appendPkColToSection(Uint32 & dst Uint32 Dbspj::appendPkColToSection(Uint32 & dst, const RowPtr::Linear & row, Uint32 col) { + jam(); Uint32 offset = row.m_header->m_offset[col]; Uint32 tmp = row.m_data[offset]; Uint32 len = AttributeHeader::getDataSize(tmp); @@ -6413,6 +6431,7 @@ Dbspj::appendFromParent(Uint32 & dst, Lo Uint32 levels, const RowPtr & rowptr, bool& hasNull) { + jam(); Ptr treeNodePtr; m_treenode_pool.getPtr(treeNodePtr, rowptr.m_src_node_ptrI); Uint32 corrVal = rowptr.m_src_correlation; @@ -6527,6 +6546,7 @@ Dbspj::appendDataToSection(Uint32 & ptrI Local_pattern_store::ConstDataBufferIterator& it, Uint32 len, bool& hasNull) { + jam(); if (unlikely(len==0)) { jam(); @@ -6732,6 +6752,7 @@ Uint32 Dbspj::expand(Uint32 & ptrI, DABuffer& pattern, Uint32 len, DABuffer& param, Uint32 paramCnt, bool& hasNull) { + jam(); /** * TODO handle error */ @@ -6816,6 +6837,7 @@ Dbspj::expand(Local_pattern_store& dst, DABuffer& pattern, Uint32 len, DABuffer& param, Uint32 paramCnt) { + jam(); /** * TODO handle error */ === modified file 'storage/ndb/src/ndbapi/NdbQueryBuilder.cpp' --- a/storage/ndb/src/ndbapi/NdbQueryBuilder.cpp 2011-09-29 11:35:02 +0000 +++ b/storage/ndb/src/ndbapi/NdbQueryBuilder.cpp 2011-10-20 12:45:36 +0000 @@ -1661,7 +1661,8 @@ NdbQueryIndexScanOperationDefImpl::NdbQu int& error) : NdbQueryScanOperationDefImpl(table,options,ident,ix,id,error), m_interface(*this), - m_index(index) + m_index(index), + m_paramInPruneKey(false) { memset(&m_bound, 0, sizeof m_bound); if (bound!=NULL) { @@ -2316,7 +2317,7 @@ NdbQueryLookupOperationDefImpl::appendKe Uint32 -NdbQueryIndexScanOperationDefImpl::appendPrunePattern(Uint32Buffer& serializedDef) const +NdbQueryIndexScanOperationDefImpl::appendPrunePattern(Uint32Buffer& serializedDef) { Uint32 appendedPattern = 0; @@ -2408,6 +2409,7 @@ NdbQueryIndexScanOperationDefImpl::appen } case NdbQueryOperandImpl::Param: appendedPattern |= QN_ScanIndexNode::SI_PRUNE_PARAMS; + m_paramInPruneKey = true; serializedDef.append(QueryPattern::param(paramCnt++)); break; default: === modified file 'storage/ndb/src/ndbapi/NdbQueryBuilderImpl.hpp' --- a/storage/ndb/src/ndbapi/NdbQueryBuilderImpl.hpp 2011-09-29 11:35:02 +0000 +++ b/storage/ndb/src/ndbapi/NdbQueryBuilderImpl.hpp 2011-10-20 12:45:36 +0000 @@ -382,6 +382,15 @@ public: virtual const IndexBound* getBounds() const { return NULL; } + /** + * True if this is a prunable scan and there are NdbQueryParamOperands in the + * distribution key. + */ + virtual bool hasParamInPruneKey() const + { + return false; + } + // Return 'true' is query type is a multi-row scan virtual bool isScanOperation() const = 0; @@ -523,7 +532,7 @@ protected: virtual Uint32 appendBoundPattern(Uint32Buffer& serializedDef) const { return 0; } - virtual Uint32 appendPrunePattern(Uint32Buffer& serializedDef) const + virtual Uint32 appendPrunePattern(Uint32Buffer& serializedDef) { return 0; } }; // class NdbQueryScanOperationDefImpl @@ -553,11 +562,16 @@ public: virtual const IndexBound* getBounds() const { return &m_bound; } + bool hasParamInPruneKey() const + { + return m_paramInPruneKey; + } + protected: // Append pattern for creating complete range bounds to serialized code virtual Uint32 appendBoundPattern(Uint32Buffer& serializedDef) const; - virtual Uint32 appendPrunePattern(Uint32Buffer& serializedDef) const; + virtual Uint32 appendPrunePattern(Uint32Buffer& serializedDef); private: @@ -583,6 +597,12 @@ private: /** True if there is a set of bounds.*/ IndexBound m_bound; + + /** + * True if scan is prunable and there are NdbQueryParamOperands in the + * distribution key. + */ + bool m_paramInPruneKey; }; // class NdbQueryIndexScanOperationDefImpl === modified file 'storage/ndb/src/ndbapi/NdbQueryOperation.cpp' --- a/storage/ndb/src/ndbapi/NdbQueryOperation.cpp 2011-09-20 10:43:05 +0000 +++ b/storage/ndb/src/ndbapi/NdbQueryOperation.cpp 2011-10-20 12:45:36 +0000 @@ -4562,6 +4562,10 @@ NdbQueryOperationImpl::prepareAttrInfo(U { requestInfo |= QN_ScanIndexParameters::SIP_PARALLEL; } + if (def.hasParamInPruneKey()) + { + requestInfo |= QN_ScanIndexParameters::SIP_PRUNE_PARAMS; + } param->requestInfo = requestInfo; // Check that both values fit in param->batchSize. assert(getMaxBatchRows() < (1<