List:Commits« Previous MessageNext Message »
From:Ole John Aske Date:July 1 2011 10:54am
Subject:bzr push into mysql-5.1-telco-7.0-spj-scan-vs-scan branch
(ole.john.aske:3525 to 3526)
View as plain text  
 3526 Ole John Aske	2011-07-01
      Refactoring intended to move more of the 'PUSHED_JOIN' specific code 
      from ha_ndbcluster.* into ha_ndbcluster_push.*
      
      Two new methods has been created as member of ndb_pushed_join:
      
      - ::match_definition() check that the NdbQueryDef encapsulated
        as part of this ndb_pushed_join object match the execution request
        as specified by the arguments. (Access type, index usage, ordered)
      
      - ::make_query_instance() instantiate another executable NdbQuery from
        the definition contained in this ndb_psuhed_join object.
      
      These new methods now contain a lot of the code previously found in
      ha_ndbcluster::check_if_pushable() and ::create_pushed_join().

    modified:
      sql/ha_ndbcluster.cc
      sql/ha_ndbcluster.h
      sql/ha_ndbcluster_push.cc
      sql/ha_ndbcluster_push.h
 3525 jonas oreland	2011-07-01
      ndb - remove pointless includes (causing build-failure on windows in 55-cluster)

    modified:
      sql/abstract_query_plan.cc
=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc	2011-06-30 09:00:45 +0000
+++ b/sql/ha_ndbcluster.cc	2011-07-01 10:54:02 +0000
@@ -886,30 +886,7 @@ SHOW_VAR ndb_status_index_stat_variables
 };
 
 #ifndef NO_PUSHED_JOIN
-
-/**
- * C++98 does not allow forward declarations of enum types. By using this 
- * class instead of using NdbQueryOperationDef::Type directly, 
- * ha_ndbcluster.h avoids including NdbQueryBuilder.h.
- */
-class NdbQueryOperationTypeWrapper
-{
-public:
-  /** Implcit conversion from NdbQueryOperationDef::Type.*/
-  NdbQueryOperationTypeWrapper(NdbQueryOperationDef::Type type)
-    :m_type(type)
-  {}
-
-  /** Implcit conversion to NdbQueryOperationDef::Type.*/
-  operator NdbQueryOperationDef::Type() const
-  { return m_type; }
-
-private:
-  const NdbQueryOperationDef::Type m_type;
-};
-
 static int ndbcluster_make_pushed_join(handlerton *, THD*,AQP::Join_plan*);
-
 #endif
 
 /*
@@ -4005,7 +3982,8 @@ ha_ndbcluster::pk_unique_index_read_key_
 
   uint i;
   Uint32 offset= 0;
-  NdbQueryParamValue paramValues[ndb_pushed_join::MAX_KEY_PART + ndb_pushed_join::MAX_REFERRED_FIELDS];
+  NdbQueryParamValue paramValues[ndb_pushed_join::MAX_KEY_PART];
+  DBUG_ASSERT(key_def->key_parts <= ndb_pushed_join::MAX_KEY_PART);
 
   uint map[ndb_pushed_join::MAX_KEY_PART];
   ndbcluster_build_key_map(m_table, m_index[idx], &table->key_info[idx], map);
@@ -4029,11 +4007,8 @@ ha_ndbcluster::pk_unique_index_read_key_
     offset+= key_part->store_length;
   }
 
-  const int error= create_pushed_join(paramValues, key_def->key_parts);
-  if (unlikely(error))
-    DBUG_RETURN(error);
-
-  DBUG_RETURN(0);
+  const int ret= create_pushed_join(paramValues, key_def->key_parts);
+  DBUG_RETURN(ret);
 } // ha_ndbcluster::pk_unique_index_read_key_pushed
 
 
@@ -4168,8 +4143,7 @@ int ha_ndbcluster::ordered_index_scan(co
   if (check_if_pushable(NdbQueryOperationDef::OrderedIndexScan, active_index,
                         sorted))
   {
-    NdbQueryParamValue paramValues[ndb_pushed_join::MAX_REFERRED_FIELDS];
-    const int error= create_pushed_join(paramValues);
+    const int error= create_pushed_join();
     if (unlikely(error))
       DBUG_RETURN(error);
 
@@ -4361,8 +4335,7 @@ int ha_ndbcluster::full_table_scan(const
 
   if (check_if_pushable(NdbQueryOperationDef::TableScan))
   {
-    NdbQueryParamValue paramValues[ndb_pushed_join::MAX_REFERRED_FIELDS];
-    const int error= create_pushed_join(paramValues);
+    const int error= create_pushed_join();
     if (unlikely(error))
       DBUG_RETURN(error);
 
@@ -13738,8 +13711,7 @@ ha_ndbcluster::read_multi_range_first(KE
       {
         if (!m_active_query)
         {
-          NdbQueryParamValue paramValues[ndb_pushed_join::MAX_REFERRED_FIELDS];
-          const int error= create_pushed_join(paramValues);
+          const int error= create_pushed_join();
           if (unlikely(error))
             DBUG_RETURN(error);
 
@@ -14384,141 +14356,37 @@ ha_ndbcluster::maybe_pushable_join(const
  *
  * @param type This is the operation type that the server want to execute.
  * @param idx  Index used whenever relevant for operation type
- * @param rootSorted True if the root operation is an ordered index scan 
+ * @param needSorted True if the root operation is an ordered index scan 
  * with sorted results.
  * @return True if the operation may be pushed.
  */
 bool 
-ha_ndbcluster::check_if_pushable(const NdbQueryOperationTypeWrapper& type, 
-                                 uint idx, bool needSorted) const
+ha_ndbcluster::check_if_pushable(int type,  //NdbQueryOperationDef::Type, 
+                                 uint idx,  
+                                 bool needSorted) const
 {
-  if (m_pushed_join_operation != PUSHED_ROOT)
-  {
-    return FALSE;
-  }
-
-  const NdbQueryDef& queryDef= m_pushed_join_member->get_query_def();
-  const NdbQueryOperationDef* const root_operation= 
-    queryDef.getQueryOperation((uint)PUSHED_ROOT);
-
-  const NdbQueryOperationTypeWrapper& query_def_type=  
-    root_operation->getType();
-
   if (m_disable_pushed_join)
   {
     DBUG_PRINT("info", ("Push disabled (HA_EXTRA_KEYREAD)"));
-    return FALSE;
-  }
-
-  if (query_def_type != type)
-  {
-    DBUG_PRINT("info", 
-               ("Cannot execute push join. Root operation prepared as %s "
-                "not executable as %s w/ index %d",
-                NdbQueryOperationDef::getTypeName(query_def_type),
-                NdbQueryOperationDef::getTypeName(type), idx));
-    return FALSE;
-  }
-
-  const NdbDictionary::Index* const expected_index= root_operation->getIndex();
-
-  // Check that we still use the same index as when the query was prepared.
-  switch (type)
-  {
-  case NdbQueryOperationDef::PrimaryKeyAccess:
-    DBUG_ASSERT(idx==table->s->primary_key);
-    break;
-
-  case NdbQueryOperationDef::UniqueIndexAccess:
-    DBUG_ASSERT(idx<MAX_KEY);
-    //          DBUG_ASSERT(m_index[idx].unique_index == expected_index);
-    if (m_index[idx].unique_index != expected_index)
-    {
-      DBUG_PRINT("info", ("Actual index %s differs from expected index %s."
-                          "Therefore, join cannot be pushed.", 
-                          m_index[idx].unique_index->getName(),
-                          expected_index->getName()));
-      return FALSE;
-    }
-    break;
-
-  case NdbQueryOperationDef::TableScan:
-    DBUG_ASSERT (idx==0);
-    if (needSorted)
-    {
-      DBUG_PRINT("info", 
-                 ("TableScan access not not be provied as sorted result. " 
-                  "Therefore, join cannot be pushed."));
-      return FALSE;
-    }
-    break;
-
-  case NdbQueryOperationDef::OrderedIndexScan:
-    DBUG_ASSERT(idx<MAX_KEY);
-    //          DBUG_ASSERT(m_index[idx].index == expected_index);
-    if (m_index[idx].index != expected_index)
-    {
-      DBUG_PRINT("info", ("Actual index %s differs from expected index %s. "
-                          "Therefore, join cannot be pushed.", 
-                          m_index[idx].index->getName(),
-                          expected_index->getName()));
-      return FALSE;
-    }
-    if (needSorted && queryDef.getQueryType() == NdbQueryDef::MultiScanQuery)
-    {
-      DBUG_PRINT("info", 
-                 ("OrderedIndexScan with scan siblings " 
-                  "can not execute as pushed join."));
-      return FALSE;
-    }
-    break;
-
-  default:
-    DBUG_ASSERT(false);
-    break;
-  }
-
-  // There may be referrences to Field values from tables outside the scope of
-  // our pushed join which are supplied as paramValues().
-  // If any of these are NULL values, join can't be pushed
-  for (uint i= 0; i < m_pushed_join_member->get_field_referrences_count(); i++)
-  {
-    Field* field= m_pushed_join_member->get_field_ref(i);
-    if (field->is_real_null())
-    {
-      DBUG_PRINT("info", 
-                 ("paramValue is NULL, can not execute as pushed join"));
-      return FALSE;
-    }
+    return false;
   }
-
-  return TRUE;
+  return   m_pushed_join_operation == PUSHED_ROOT
+        && m_pushed_join_member    != NULL
+        && m_pushed_join_member->match_definition(
+                        type,
+                        (idx<MAX_KEY) ? &m_index[idx] : NULL,
+                        needSorted);
 }
 
 int
-ha_ndbcluster::create_pushed_join(NdbQueryParamValue* paramValues, uint paramOffs)
+ha_ndbcluster::create_pushed_join(const NdbQueryParamValue* keyFieldParams, uint paramCnt)
 {
   DBUG_ENTER("create_pushed_join");
-  DBUG_ASSERT(m_pushed_join_operation == PUSHED_ROOT);
-  DBUG_PRINT("info", 
-             ("executing chain of %d pushed joins."
-              " First table is %s, accessed as %s.", 
-              m_pushed_join_member->get_operation_count(),
-              m_pushed_join_member->get_table(0)->alias,
-              NdbQueryOperationDef::getTypeName(
-                m_pushed_join_member->get_query_def().getQueryOperation((uint)PUSHED_ROOT)->getType()))
-             );
-
-  // There may be referrences to Field values from tables outside the scope of
-  // our pushed join: These are expected to be supplied as paramValues()
-  for (uint i= 0; i < m_pushed_join_member->get_field_referrences_count(); i++)
-  {
-    Field* field= m_pushed_join_member->get_field_ref(i);
-    DBUG_ASSERT(!field->is_real_null());  // Checked by ::check_if_pushable()
-    paramValues[paramOffs+i]= NdbQueryParamValue(field->ptr, false);
-  }
+  DBUG_ASSERT(m_pushed_join_member && m_pushed_join_operation == PUSHED_ROOT);
+
+  NdbQuery* const query= 
+    m_pushed_join_member->make_query_instance(m_thd_ndb->trans, keyFieldParams, paramCnt);
 
-  NdbQuery* const query= m_thd_ndb->trans->createQuery(&m_pushed_join_member->get_query_def(), paramValues);
   if (unlikely(query==NULL))
     ERR_RETURN(m_thd_ndb->trans->getNdbError());
 
@@ -14650,7 +14518,7 @@ ha_ndbcluster::test_push_flag(enum ha_pu
       DBUG_RETURN(true);
     }
     const NdbQueryDef& query_def = m_pushed_join_member->get_query_def();
-    const NdbQueryOperationTypeWrapper& root_type=
+    const NdbQueryOperationDef::Type root_type=
       query_def.getQueryOperation((uint)PUSHED_ROOT)->getType();
 
     /**
@@ -14670,7 +14538,7 @@ ha_ndbcluster::test_push_flag(enum ha_pu
     {
       for (uint i= 1; i < query_def.getNoOfOperations(); i++)
       {
-        const NdbQueryOperationTypeWrapper& child_type=
+        const NdbQueryOperationDef::Type child_type=
           query_def.getQueryOperation(i)->getType();
         if (child_type == NdbQueryOperationDef::TableScan ||
             child_type == NdbQueryOperationDef::OrderedIndexScan)

=== modified file 'sql/ha_ndbcluster.h'
--- a/sql/ha_ndbcluster.h	2011-06-30 08:49:22 +0000
+++ b/sql/ha_ndbcluster.h	2011-07-01 10:54:02 +0000
@@ -799,11 +799,12 @@ private:
   bool has_null_in_unique_index(uint idx_no) const;
   bool check_index_fields_not_null(KEY *key_info);
 
-  bool check_if_pushable(const NdbQueryOperationTypeWrapper& type,
-                         uint idx= 0,
-			 bool rootSorted= false) const;
+  bool check_if_pushable(int type, //NdbQueryOperationDef::Type,
+                         uint idx= MAX_KEY,
+                         bool rootSorted= false) const;
   bool check_is_pushed() const;
-  int create_pushed_join(NdbQueryParamValue* paramValues, uint paramOffs= 0);
+  int create_pushed_join(const NdbQueryParamValue* keyFieldParams=NULL,
+                         uint paramCnt= 0);
 
   int set_up_partition_info(partition_info *part_info,
                             NdbDictionary::Table&) const;

=== modified file 'sql/ha_ndbcluster_push.cc'
--- a/sql/ha_ndbcluster_push.cc	2011-06-30 09:17:30 +0000
+++ b/sql/ha_ndbcluster_push.cc	2011-07-01 10:54:02 +0000
@@ -41,6 +41,7 @@
 #include <ndbapi/NdbApi.hpp>
 #include <ndbapi/NdbInterpretedCode.hpp>
 #include "../storage/ndb/src/ndbapi/NdbQueryBuilder.hpp"
+#include "../storage/ndb/src/ndbapi/NdbQueryOperation.hpp"
 
 #include <ndb_version.h>
 
@@ -161,6 +162,153 @@ ndb_pushed_join::~ndb_pushed_join()
     m_query_def->destroy();
 }
 
+bool ndb_pushed_join::match_definition(
+                      int type, //NdbQueryOperationDef::Type, 
+                      const NDB_INDEX_DATA* idx,
+                      bool needSorted) const
+{
+  const NdbQueryOperationDef* const root_operation= 
+    m_query_def->getQueryOperation((uint)0);
+  const NdbQueryOperationDef::Type def_type=  
+    root_operation->getType();
+
+  if (def_type != type)
+  {
+    DBUG_PRINT("info", 
+               ("Cannot execute push join. Root operation prepared as %s "
+                "not executable as %s",
+                NdbQueryOperationDef::getTypeName(def_type),
+                NdbQueryOperationDef::getTypeName((NdbQueryOperationDef::Type)type)));
+    return FALSE;
+  }
+  const NdbDictionary::Index* const expected_index= root_operation->getIndex();
+
+  // Check that we still use the same index as when the query was prepared.
+  switch (def_type)
+  {
+  case NdbQueryOperationDef::PrimaryKeyAccess:
+    DBUG_ASSERT(idx!=NULL);
+    DBUG_ASSERT(idx->unique_index == expected_index);
+    break;
+
+  case NdbQueryOperationDef::UniqueIndexAccess:
+    DBUG_ASSERT(idx!=NULL);
+    // DBUG_ASSERT(idx->unique_index == expected_index);
+    if (idx->unique_index != expected_index)
+    {
+      DBUG_PRINT("info", ("Actual index %s differs from expected index %s."
+                          "Therefore, join cannot be pushed.", 
+                          idx->unique_index->getName(),
+                          expected_index->getName()));
+      return FALSE;
+    }
+    break;
+
+  case NdbQueryOperationDef::TableScan:
+    DBUG_ASSERT (idx==NULL && expected_index==NULL);
+    if (needSorted)
+    {
+      DBUG_PRINT("info", 
+                 ("TableScan access can not be provied as sorted result. " 
+                  "Therefore, join cannot be pushed."));
+      return FALSE;
+    }
+    break;
+
+  case NdbQueryOperationDef::OrderedIndexScan:
+    DBUG_ASSERT(idx!=NULL);
+    // DBUG_ASSERT(idx->index == expected_index);
+    if (idx->index != expected_index)
+    {
+      DBUG_PRINT("info", ("Actual index %s differs from expected index %s. "
+                          "Therefore, join cannot be pushed.", 
+                          idx->index->getName(),
+                          expected_index->getName()));
+      return FALSE;
+    }
+    if (needSorted && m_query_def->getQueryType() == NdbQueryDef::MultiScanQuery)
+    {
+      DBUG_PRINT("info", 
+                 ("OrderedIndexScan with scan siblings " 
+                  "can not execute as pushed join."));
+      return FALSE;
+    }
+    break;
+
+  default:
+    DBUG_ASSERT(false);
+    break;
+  }
+
+  /**
+   * There may be referrences to Field values from tables outside the scope of
+   * our pushed join which are supplied as paramValues().
+   * If any of these are NULL values, join can't be pushed.
+   */
+  for (uint i= 0; i < get_field_referrences_count(); i++)
+  {
+    Field* field= m_referred_fields[i];
+    if (field->is_real_null())
+    {
+      DBUG_PRINT("info", 
+                 ("paramValue is NULL, can not execute as pushed join"));
+      return FALSE;
+    }
+  }
+
+  return TRUE;
+}
+
+NdbQuery* ndb_pushed_join::make_query_instance(
+                       NdbTransaction* trans,
+                       const NdbQueryParamValue* keyFieldParams,
+                       uint paramCnt) const
+{
+  DBUG_ENTER("make_query_instance");
+  DBUG_PRINT("info", 
+             ("executing chain of %d pushed joins."
+              " First table is %s, accessed as %s.", 
+              get_operation_count(),
+              get_table(0)->alias,
+              NdbQueryOperationDef::getTypeName(
+                m_query_def->getQueryOperation((uint)0)->getType())
+             ));
+
+  const NdbQueryParamValue* paramValues = keyFieldParams;
+
+  /**
+   * There may be referrences to Field values from tables outside the scope of
+   * our pushed join: These are expected to be supplied as paramValues()
+   * after the keyFieldParams[]. 
+   */
+  uint outer_fields= get_field_referrences_count();
+  if (unlikely(outer_fields > 0))
+  {
+    uint size= sizeof(NdbQueryParamValue) * (paramCnt+outer_fields);
+    NdbQueryParamValue* extendedParams = reinterpret_cast<NdbQueryParamValue*>(alloca(size));
+    // Copy specified keyFieldParams[] first
+    for (uint i= 0; i < paramCnt; i++)
+    {
+      extendedParams[i]= keyFieldParams[i];
+    }
+
+    // There may be referrences to Field values from tables outside the scope of
+    // our pushed join: These are expected to be supplied as paramValues()
+    for (uint i= 0; i < outer_fields; i++)
+    {
+      Field* field= m_referred_fields[i];
+      DBUG_ASSERT(!field->is_real_null());  // Checked by ::check_if_pushable()
+      extendedParams[paramCnt+i]= NdbQueryParamValue(field->ptr, false);
+    }
+    paramValues= extendedParams;
+  }
+
+  NdbQuery* query= trans->createQuery(&get_query_def(), paramValues);
+  DBUG_RETURN(query);
+}
+
+/////////////////////////////////////////
+
 ndb_pushed_builder_ctx::ndb_pushed_builder_ctx(const AQP::Join_plan& plan)
 :
   m_plan(plan),

=== modified file 'sql/ha_ndbcluster_push.h'
--- a/sql/ha_ndbcluster_push.h	2011-06-20 14:40:46 +0000
+++ b/sql/ha_ndbcluster_push.h	2011-07-01 10:54:02 +0000
@@ -21,6 +21,7 @@
 
 #include "sql_bitmap.h"
 
+class NdbTransaction;
 class NdbQueryBuilder;
 class NdbQueryOperand;
 class NdbQueryOperationDef;
@@ -96,6 +97,20 @@ public:
   
   ~ndb_pushed_join(); 
 
+  /**
+   * Check that this prepared pushed query matches the type
+   * of operation specified by the arguments.
+   */
+  bool match_definition(int type, //NdbQueryOperationDef::Type, 
+                        const NDB_INDEX_DATA* idx,
+                        bool needSorted) const;
+
+  /** Create an executable instance of this defined query. */
+  NdbQuery* make_query_instance(
+                        NdbTransaction* trans,
+                        const NdbQueryParamValue* keyFieldParams,
+                        uint paramCnt) const;
+
   /** Get the number of pushed table access operations.*/
   uint get_operation_count() const
   { return m_operation_count; }
@@ -108,14 +123,6 @@ public:
   uint get_field_referrences_count() const
   { return m_field_count; }
 
-  /** Get the no'th referred field of table access operations that executes
-   * prior to the pushed join.*/
-  Field* get_field_ref(uint no) const
-  { 
-    DBUG_ASSERT(no < m_field_count);
-    return m_referred_fields[no]; 
-  }
-
   const NdbQueryDef& get_query_def() const
   { return *m_query_def; }
 

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:3525 to 3526) Ole John Aske4 Jul