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<NDB_SPJ_MAX_TREE_NODES>());
> + }
> +
> 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<NDB_SPJ_MAX_TREE_NODES> hasMoreSiblingsMask,
> + bool header)
> +{
> + if (depth > 0)
> + {
> + // Print vertical lines to the siblings of the ancestore nodes.
> + for (Uint32 i = 0; i<depth-1; 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<NDB_SPJ_MAX_TREE_NODES>
> + hasMoreSiblingsMask) const
> +{
> + // Print vertical line leading down to this node.
> + Bitmask<NDB_SPJ_MAX_TREE_NODES> 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<int>(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 <Vector.hpp>
> +#include <Bitmask.hpp>
> #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<NDB_SPJ_MAX_TREE_NODES> 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