List:Commits« Previous MessageNext Message »
From:Ole John Aske Date:February 11 2011 1:16pm
Subject:bzr push into mysql-5.1-telco-7.0-spj-scan-vs-scan branch
(ole.john.aske:3429 to 3431)
View as plain text  
 3431 Ole John Aske	2011-02-11
      SPJ-scan-scan: ::setInterpretedCode() as part of the NdbQueryDef instead of 
      setting it as part of each instantiated NdbQuery.

    modified:
      sql/ha_ndbcluster.cc
 3430 Ole John Aske	2011-02-11
      Extend SPJ API with NdbQueryOptions::setInterpretedCode() which allows a 
      filter condition to be defined as part of a NdbQueryDef.
      
      This filter will then be reused for all  NdbQuery's instantiated from this 
      NdbQueryDef - Usage of this feature will save the overhead of a seperate 
      ::generate_scan_filter() for each instantiation of this NdbQueryDef.

    modified:
      storage/ndb/include/ndbapi/NdbInterpretedCode.hpp
      storage/ndb/include/ndbapi/NdbQueryBuilder.hpp
      storage/ndb/include/ndbapi/NdbQueryOperation.hpp
      storage/ndb/src/ndbapi/NdbQueryBuilder.cpp
      storage/ndb/src/ndbapi/NdbQueryBuilderImpl.hpp
      storage/ndb/src/ndbapi/NdbQueryOperation.cpp
 3429 Ole John Aske	2011-02-10
      spj-scan-scan: Fixed some more incorrect 'size' spec when using Bitmask<size>.

    modified:
      storage/ndb/src/ndbapi/NdbQueryBuilder.cpp
      storage/ndb/src/ndbapi/NdbQueryBuilderImpl.hpp
=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc	2011-02-09 14:59:39 +0000
+++ b/sql/ha_ndbcluster.cc	2011-02-11 13:16:37 +0000
@@ -486,6 +486,16 @@ ha_ndbcluster::make_pushed_join(ndb_push
      */
     if (push_cnt == 0)
     {
+      NdbQueryOptions options;
+      if (m_cond)
+      {
+        NdbInterpretedCode code(m_table);
+        if (m_cond->generate_scan_filter(&code, NULL) != 0)
+          ERR_RETURN(code.getNdbError());
+
+        options.setInterpretedCode(code);
+      }
+
       if (ndbcluster_is_lookup_operation(access_type))
       {
         const KEY* const key= 
@@ -511,7 +521,7 @@ ha_ndbcluster::make_pushed_join(ndb_push
           DBUG_PRINT("info", ("Root operation is 'primary-key-lookup'"));
           DBUG_ASSERT(join_root->get_index_no() == 
                       static_cast<int>(table->s->primary_key));
-          query_op= builder->readTuple(m_table, root_key);
+          query_op= builder->readTuple(m_table, root_key, &options);
         }
         else
         {
@@ -519,7 +529,7 @@ ha_ndbcluster::make_pushed_join(ndb_push
           const NdbDictionary::Index* const index 
             = m_index[join_root->get_index_no()].unique_index;
           DBUG_ASSERT(index);
-          query_op= builder->readTuple(index, m_table, root_key);
+          query_op= builder->readTuple(index, m_table, root_key, &options);
         }
       }
       /**
@@ -542,12 +552,12 @@ ha_ndbcluster::make_pushed_join(ndb_push
 
         // Bounds will be generated and supplied during execute
         query_op= 
-          builder->scanIndex(m_index[join_root->get_index_no()].index, m_table);
+          builder->scanIndex(m_index[join_root->get_index_no()].index, m_table, 0, &options);
       }
       else if (access_type == AQP::AT_TABLE_SCAN) 
       {
         DBUG_PRINT("info", ("Root operation is 'table scan'"));
-        query_op= builder->scanTable(m_table);
+        query_op= builder->scanTable(m_table, &options);
       }
       else
       {
@@ -700,6 +710,14 @@ ha_ndbcluster::make_pushed_join(ndb_push
       DBUG_ASSERT(parent_op != NULL);
       options.setParent(parent_op);
     }
+    if (handler->m_cond)
+    {
+      NdbInterpretedCode code(table);
+      if (handler->m_cond->generate_scan_filter(&code, NULL) != 0)
+        ERR_RETURN(code.getNdbError());
+
+      options.setInterpretedCode(code);
+    }
 
     if (join_tab->get_access_type() == AQP::AT_ORDERED_INDEX_SCAN)
     {
@@ -721,7 +739,6 @@ ha_ndbcluster::make_pushed_join(ndb_push
       query_op= builder->readTuple(index, table, linked_key, &options);
     }
 
-//  DBUG_ASSERT(query_op);
     if (unlikely(!query_op))
     {
       const NdbError error = builder->getNdbError();
@@ -1019,7 +1036,6 @@ ha_ndbcluster::create_pushed_join(NdbQue
     ERR_RETURN(m_thd_ndb->trans->getNdbError());
 
   // Bind to instantiated NdbQueryOperations.
-  // Append filters for for pushed conditions where available
   for (uint i= 0; i < m_pushed_join->get_operation_count(); i++)
   {
     const TABLE* const tab= m_pushed_join->get_table(i);
@@ -1028,16 +1044,6 @@ ha_ndbcluster::create_pushed_join(NdbQue
     NdbQueryOperation* const op= query->getQueryOperation(i);
     handler->m_pushed_operation= op;
 
-    if (handler->m_cond)
-    {
-      NdbInterpretedCode code(handler->m_table);
-      if (handler->m_cond->generate_scan_filter(&code, NULL) != 0)
-        ERR_RETURN(code.getNdbError());
-
-      if (op->setInterpretedCode(code) != 0)
-        ERR_RETURN(query->getNdbError());
-    }
-
     // Bind to result buffers
     const NdbRecord* const resultRec= handler->m_ndb_record;
     int res= op->setResultRowRef(

=== modified file 'storage/ndb/include/ndbapi/NdbInterpretedCode.hpp'
--- a/storage/ndb/include/ndbapi/NdbInterpretedCode.hpp	2011-02-08 15:13:13 +0000
+++ b/storage/ndb/include/ndbapi/NdbInterpretedCode.hpp	2011-02-11 13:12:09 +0000
@@ -544,6 +544,7 @@ private:
   friend class NdbOperation;
   friend class NdbScanOperation;
   friend class NdbQueryOperationImpl;
+  friend class NdbQueryOptionsImpl;
 
   static const Uint32 MaxReg= 8;
   static const Uint32 MaxLabels= 65535;

=== modified file 'storage/ndb/include/ndbapi/NdbQueryBuilder.hpp'
--- a/storage/ndb/include/ndbapi/NdbQueryBuilder.hpp	2010-11-23 10:05:44 +0000
+++ b/storage/ndb/include/ndbapi/NdbQueryBuilder.hpp	2011-02-11 13:12:09 +0000
@@ -172,6 +172,26 @@ public:
    */
   int setParent(const class NdbQueryOperationDef* parent);
 
+  /**
+   * Set the NdbInterpretedCode needed for defining a conditional filter 
+   * (aka: predicate) for this operation. Might be used both on scan 
+   * and lookup operations.
+   *
+   * Typically, one would create NdbScanFilter and NdbInterpretedCode objects
+   * on the stack, e.g.:
+   *   NdbInterpretedCode code(table);
+   *   NdbScanFilter filter(code);
+   *   filter.begin();
+   *   filter.ge(0, 5U); // Check if column 1 is greater of equal to 5.
+   *   filter.end();
+   *   queryOp->setInterpretedCode(code);
+   *
+   * @param code The interpreted code. This object is copied internally, 
+   * meaning that 'code' may be destroyed as soon as this method returns.
+   * @return 0 if ok, -1 in case of error (call getNdbError() for details.)
+   */
+  int setInterpretedCode(const class NdbInterpretedCode& code);
+
   const NdbQueryOptionsImpl& getImpl() const;
 
 private:

=== modified file 'storage/ndb/include/ndbapi/NdbQueryOperation.hpp'
--- a/storage/ndb/include/ndbapi/NdbQueryOperation.hpp	2010-11-23 10:05:44 +0000
+++ b/storage/ndb/include/ndbapi/NdbQueryOperation.hpp	2011-02-11 13:12:09 +0000
@@ -336,8 +336,9 @@ public:
   int setBatchSize(Uint32 batchSize);
 
   /**
-   * Set the NdbInterpretedCode needed for defining a scan filter for 
-   * this operation. 
+   * Set the NdbInterpretedCode needed for defining a conditional filter 
+   * (aka: predicate) for this operation. Might be used both on scan 
+   * and lookup operations.
    *
    * Typically, one would create NdbScanFilter and NdbInterpretedCode objects
    * on the stack, e.g.:
@@ -346,9 +347,8 @@ public:
    *   filter.begin();
    *   filter.ge(0, 5U); // Check if column 1 is greater of equal to 5.
    *   filter.end();
-   *   scanOp->setInterpretedCode(code);
+   *   queryOp->setInterpretedCode(code);
    *
-   * It is an error to call this method on a lookup operation.
    * @param code The interpreted code. This object is copied internally, 
    * meaning that 'code' may be destroyed as soon as this method returns.
    * @return 0 if ok, -1 in case of error (call getNdbError() for details.)

=== modified file 'storage/ndb/src/ndbapi/NdbQueryBuilder.cpp'
--- a/storage/ndb/src/ndbapi/NdbQueryBuilder.cpp	2011-02-10 11:54:23 +0000
+++ b/storage/ndb/src/ndbapi/NdbQueryBuilder.cpp	2011-02-11 13:12:09 +0000
@@ -29,6 +29,7 @@
 #include "AttributeHeader.hpp"
 #include "NdbIndexScanOperation.hpp"
 #include "NdbOut.hpp"
+#include "NdbInterpretedCode.hpp"
 
 /**
  * Implementation of all QueryBuilder objects are hidden from
@@ -54,6 +55,7 @@ static const bool doPrintQueryTree = fal
 
 /* Various error codes that are not specific to NdbQuery. */
 static const int Err_MemoryAlloc = 4000;
+static const int Err_FinaliseNotCalled = 4519;
 
 static void
 setErrorCode(NdbQueryBuilderImpl* qb, int aErrorCode)
@@ -474,6 +476,77 @@ NdbQueryOptions::setParent(const NdbQuer
   return 0;
 }
 
+int
+NdbQueryOptions::setInterpretedCode(const NdbInterpretedCode& code)
+{
+  if (m_pimpl==&defaultOptions)
+  {
+    m_pimpl = new NdbQueryOptionsImpl;
+    if (unlikely(m_pimpl==0))
+    {
+      return Err_MemoryAlloc;
+    }
+  }
+  return m_pimpl->copyInterpretedCode(code);
+}
+
+
+NdbQueryOptionsImpl::~NdbQueryOptionsImpl()
+{
+  delete m_interpretedCode;
+}
+
+NdbQueryOptionsImpl::NdbQueryOptionsImpl(const NdbQueryOptionsImpl& src)
+ : m_matchType(src.m_matchType),
+   m_scanOrder(src.m_scanOrder),
+   m_parent(src.m_parent),
+   m_interpretedCode(NULL)
+{
+  if (src.m_interpretedCode)
+  {
+    copyInterpretedCode(*src.m_interpretedCode);
+  }
+}
+
+/* 
+ * Make a deep copy, such that 'src' can be destroyed when this method 
+ * returns.
+ */
+int
+NdbQueryOptionsImpl::copyInterpretedCode(const NdbInterpretedCode& src)
+{
+  /* Check the program's finalised */
+  if (unlikely(!(src.m_flags & NdbInterpretedCode::Finalised)))
+  {
+    return Err_FinaliseNotCalled;  // NdbInterpretedCode::finalise() not called.
+  }
+  if (src.m_instructions_length == 0)
+  {
+    return 0;
+  }
+
+  NdbInterpretedCode* interpretedCode = new NdbInterpretedCode();
+  if (unlikely(interpretedCode==NULL))
+  {
+    return Err_MemoryAlloc;
+  }
+
+  const int error = interpretedCode->copy(src);
+  if (unlikely(error))
+  {
+    delete interpretedCode;
+    return error;
+  }
+
+  /* Replace existing NdbInterpretedCode */
+  if (m_interpretedCode)
+    delete m_interpretedCode;
+
+  m_interpretedCode = interpretedCode;
+  return 0;
+}
+
+
 /****************************************************************************
  * Glue layer between NdbQueryOperationDef interface and its Impl'ementation.
  ****************************************************************************/
@@ -1837,15 +1910,16 @@ NdbQueryOperationDefImpl::NdbQueryOperat
     error = Err_MemoryAlloc;
     return;
   }
-  if (m_options.m_parent!=NULL)
+  if (m_options.m_parent != NULL)
   {
-     m_parent = m_options.m_parent;
-     const int res = m_parent->addChild(this);
-     if (unlikely(res != 0))
-     {
-       error = res;
-     }
-  }
+    m_parent = m_options.m_parent;
+    const int res = m_parent->addChild(this);
+    if (unlikely(res != 0))
+    {
+      error = res;
+      return;
+    }
+  }  // else, ::linkWithParent() will assign 'm_parent'
 }
 
 

=== modified file 'storage/ndb/src/ndbapi/NdbQueryBuilderImpl.hpp'
--- a/storage/ndb/src/ndbapi/NdbQueryBuilderImpl.hpp	2011-02-10 11:54:23 +0000
+++ b/storage/ndb/src/ndbapi/NdbQueryBuilderImpl.hpp	2011-02-11 13:12:09 +0000
@@ -270,13 +270,25 @@ public:
   explicit NdbQueryOptionsImpl()
   : m_matchType(NdbQueryOptions::MatchAll),
     m_scanOrder(NdbQueryOptions::ScanOrdering_void),
-    m_parent(NULL)
+    m_parent(NULL),
+    m_interpretedCode(NULL)
   {};
+  NdbQueryOptionsImpl(const NdbQueryOptionsImpl&);
+  ~NdbQueryOptionsImpl();
 
 private:
   NdbQueryOptions::MatchType     m_matchType;
   NdbQueryOptions::ScanOrdering  m_scanOrder;
   NdbQueryOperationDefImpl*      m_parent;
+  const NdbInterpretedCode*      m_interpretedCode;
+
+  /**
+   * Assign NdbInterpretedCode by taking a deep copy of 'src'
+   * @return possible error code.
+   */
+  int copyInterpretedCode(const NdbInterpretedCode& src);
+
+  NdbQueryOptionsImpl&operator=(const NdbQueryOptionsImpl&);  // Not impl.
 };
 
 
@@ -330,6 +342,9 @@ public:
   enum NdbQueryOptions::ScanOrdering getOrdering() const
   { return m_options.m_scanOrder; }
 
+  const NdbInterpretedCode* getInterpretedCode() const
+  { return m_options.m_interpretedCode; }
+
   Uint32 assignQueryOperationId(Uint32& nodeId)
   { if (getType()==NdbQueryOperationDef::UniqueIndexAccess) nodeId++;
     m_id = nodeId++;

=== modified file 'storage/ndb/src/ndbapi/NdbQueryOperation.cpp'
--- a/storage/ndb/src/ndbapi/NdbQueryOperation.cpp	2011-02-10 11:10:54 +0000
+++ b/storage/ndb/src/ndbapi/NdbQueryOperation.cpp	2011-02-11 13:12:09 +0000
@@ -22,6 +22,7 @@
 #include <NdbQueryBuilder.hpp>
 #include "NdbQueryBuilderImpl.hpp"
 #include "NdbQueryOperationImpl.hpp"
+#include "NdbInterpretedCode.hpp"
 
 #include <signaldata/TcKeyReq.hpp>
 #include <signaldata/TcKeyRef.hpp>
@@ -4803,29 +4804,35 @@ NdbQueryOperationImpl::getResultStream(U
 bool
 NdbQueryOperationImpl::hasInterpretedCode() const
 {
-  return m_interpretedCode && m_interpretedCode->m_instructions_length > 0;
+  return (m_interpretedCode && m_interpretedCode->m_instructions_length > 0) ||
+         (getQueryOperationDef().getInterpretedCode() != NULL);
 } // NdbQueryOperationImpl::hasInterpretedCode
 
 int
 NdbQueryOperationImpl::prepareInterpretedCode(Uint32Buffer& attrInfo) const
 {
+  const NdbInterpretedCode* interpretedCode =
+    (m_interpretedCode && m_interpretedCode->m_instructions_length > 0)
+     ? m_interpretedCode
+     : getQueryOperationDef().getInterpretedCode();
+
   // There should be no subroutines in a filter.
-  assert(m_interpretedCode->m_first_sub_instruction_pos==0);
-  assert(m_interpretedCode->m_instructions_length > 0);
-  assert(m_interpretedCode->m_instructions_length <= 0xffff);
+  assert(interpretedCode->m_first_sub_instruction_pos==0);
+  assert(interpretedCode->m_instructions_length > 0);
+  assert(interpretedCode->m_instructions_length <= 0xffff);
 
   // Allocate space for program and length field.
   Uint32* const buffer = 
-    attrInfo.alloc(1+m_interpretedCode->m_instructions_length);
+    attrInfo.alloc(1+interpretedCode->m_instructions_length);
   if(unlikely(buffer==NULL))
   {
     return Err_MemoryAlloc;
   }
 
-  buffer[0] = m_interpretedCode->m_instructions_length;
+  buffer[0] = interpretedCode->m_instructions_length;
   memcpy(buffer+1, 
-         m_interpretedCode->m_buffer, 
-         m_interpretedCode->m_instructions_length * sizeof(Uint32));
+         interpretedCode->m_buffer, 
+         interpretedCode->m_instructions_length * sizeof(Uint32));
   return 0;
 } // NdbQueryOperationImpl::prepareInterpretedCode
 

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-5.1-telco-7.0-spj-scan-vs-scan branch(ole.john.aske:3429 to 3431) Ole John Aske11 Feb