From: Frazer Clement Date: August 24 2010 9:56am Subject: Re: bzr commit into mysql-5.1-telco-7.0-spj-scan-vs-scan branch (jan.wedvik:3240) List-Archive: http://lists.mysql.com/commits/116609 Message-Id: <4C739753.2070606@oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Excellent! Jan Wedvik wrote: > #At file:///net/atum17/export/home2/tmp/jw159207/mysql/repo/push-scan-scan/ based on revid:jan.wedvik@stripped > > 3240 Jan Wedvik 2010-08-24 > This commit implements a mechanism for printing a visualization of query tree > graphs (in the API) to ndbout. This is by default turned off, but can be > activated by setting doPrintQueryTree to true. > > modified: > storage/ndb/src/ndbapi/NdbQueryBuilder.cpp > storage/ndb/src/ndbapi/NdbQueryBuilderImpl.hpp > === modified file 'storage/ndb/src/ndbapi/NdbQueryBuilder.cpp' > --- a/storage/ndb/src/ndbapi/NdbQueryBuilder.cpp 2010-08-17 07:32:36 +0000 > +++ b/storage/ndb/src/ndbapi/NdbQueryBuilder.cpp 2010-08-24 09:40:27 +0000 > @@ -49,6 +49,9 @@ > * > */ > > +// For debugging purposes. Enable to print query tree graph to ndbout. > +static const bool doPrintQueryTree = false; > + > /* Various error codes that are not specific to NdbQuery. */ > STATIC_CONST(Err_MemoryAlloc = 4000); > > @@ -979,6 +982,12 @@ NdbQueryBuilderImpl::prepare() > return NULL; > } > > + if (doPrintQueryTree) > + { > + ndbout << "Query tree:" << endl; > + def->getQueryOperation(0U).printTree(0, Bitmask()); > + } > + > return def; > } > > @@ -1743,6 +1752,10 @@ Uint32 NdbQueryOperationDefImpl::markSca > { > if (operation->m_hasScanDescendant) > { > + /* Remove this line if you want to allow bushy scans. Result sets will > + * probably be wrong, but 'explain' output etc. may be useful for > + * debugging. > + */ > return QRY_MULTIPLE_SCAN_BRANCHES; > } > operation->m_hasScanDescendant = true; > @@ -1857,6 +1870,84 @@ NdbQueryOperationDefImpl::appendChildPro > return requestInfo; > } // NdbQueryOperationDefImpl::appendChildProjection > > +/** Used by NdbQueryOperationDefImpl::printTree() to print the arrows > + * that connect the tree nodes. > + */ > +static void printMargin(Uint32 depth, > + Bitmask hasMoreSiblingsMask, > + bool header) > +{ > + if (depth > 0) > + { > + // Print vertical lines to the siblings of the ancestore nodes. > + for (Uint32 i = 0; i + { > + if (hasMoreSiblingsMask.get(i+1)) > + { > + ndbout << "| "; > + } > + else > + { > + ndbout << " "; > + } > + } > + if (header) > + { > + ndbout << "+->"; > + } > + else if (hasMoreSiblingsMask.get(depth)) > + { > + ndbout << "| "; > + } > + else > + { > + ndbout << " "; > + } > + } > +} > + > +void > +NdbQueryOperationDefImpl::printTree(Uint32 depth, > + Bitmask > + hasMoreSiblingsMask) const > +{ > + // Print vertical line leading down to this node. > + Bitmask firstLineMask = hasMoreSiblingsMask; > + firstLineMask.set(depth); > + printMargin(depth, firstLineMask, false); > + ndbout << endl; > + // Print +-> leading to this node. > + printMargin(depth, hasMoreSiblingsMask, true); > + ndbout << NdbQueryOperationDef::getTypeName(getType()) << endl; > + printMargin(depth, hasMoreSiblingsMask, false); > + // Print attributes. > + ndbout << " opNo: " << getQueryOperationIx() << endl; > + printMargin(depth, hasMoreSiblingsMask, false); > + ndbout << " table: " << getTable().getName() << endl; > + if (getIndex() != NULL) > + { > + printMargin(depth, hasMoreSiblingsMask, false); > + ndbout << " index: " << getIndex()->getName() << endl; > + } > + /* For each child but the last one, use a mask with an extra bit set to > + * indicate that there are more siblings. > + */ > + hasMoreSiblingsMask.set(depth+1); > + for (int childNo = 0; > + childNo < static_cast(getNoOfChildOperations()) - 1; > + childNo++) > + { > + getChildOperation(childNo).printTree(depth+1, hasMoreSiblingsMask); > + } > + if (getNoOfChildOperations() > 0) > + { > + // The last child has no more siblings. > + hasMoreSiblingsMask.clear(depth+1); > + getChildOperation(getNoOfChildOperations() - 1) > + .printTree(depth+1, hasMoreSiblingsMask); > + } > +} // NdbQueryOperationDefImpl::printTree() > + > > Uint32 > NdbQueryLookupOperationDefImpl::appendKeyPattern(Uint32Buffer& serializedDef) const > > === modified file 'storage/ndb/src/ndbapi/NdbQueryBuilderImpl.hpp' > --- a/storage/ndb/src/ndbapi/NdbQueryBuilderImpl.hpp 2010-08-17 07:32:36 +0000 > +++ b/storage/ndb/src/ndbapi/NdbQueryBuilderImpl.hpp 2010-08-24 09:40:27 +0000 > @@ -48,6 +48,7 @@ > > #ifdef __cplusplus > #include > +#include > #include "NdbQueryBuilder.hpp" > #include "NdbIndexScanOperation.hpp" > #include "ndb_limits.h" > @@ -402,6 +403,14 @@ public: > // Get type of query operation > virtual NdbQueryOperationDef::Type getType() const = 0; > > + /** Print query tree graph to trace file (using recursion). > + * @param depth Number of ancestor nodes that this node has. > + * @param hasMoreSiblingsMask The n'th bit should be set if the n'th ancestor > + * (counted from the root) has more sibling nodes. > + */ > + void printTree(Uint32 depth, > + Bitmask hasMoreSiblingsMask) const; > + > protected: > // QueryTree building: > // Append list of parent nodes to serialized code > > > > ------------------------------------------------------------------------ > > -- Frazer Clement, Senior Software Engineer, MySQL Cluster / Oracle - www.mysql.com Office: Edinburgh, UK Are you MySQL certified? www.mysql.com/certification