List:Commits« Previous MessageNext Message »
From:Ole John Aske Date:March 17 2011 12:25pm
Subject:bzr push into mysql-5.1-telco-7.0-spj-scan-vs-scan branch
(ole.john.aske:3447 to 3448)
View as plain text  
 3448 Ole John Aske	2011-03-17
      SPJ refactoring of handler interface extensions used for retrospecting pushed joins.
      
      Intention is to clean up code, improve readability, *and* prepare for later
      enhanced EXPLAIN of pushed joins which should also include info about the parent/child 
      relations.
      
      Renamed member variables an methods in order to clearify theirs usage:
      
       - handler::is_parent_of_pushed_join() -> handler::number_of_pushed_joins()
       - handler::member_of_pushed_join()  -> handler::root_of_pushed_join()
       - ha_ndbcluster::m_pushed_join -> ha_ndbcluster::m_pushed_join_member
      
      Introduced:
      
        int ha_ndbcluster::m_pushed_join_operation:
          Enumerates the pushed query operation which relates to this handler instance
      
        static const uint ha_ndbcluster::PUSHED_ROOT= 0:
          Enumerates the pushed operation being the root in the pushed query.
          Mainly for improved readability of the code.
      
        handler::parent_of_pushed_join():
          Returns the pushed parent of this handler instance. NULL if operation
          is unpushed, or if this is the root of the pushed query.
      
        

    modified:
      sql/ha_ndbcluster.cc
      sql/ha_ndbcluster.h
      sql/handler.h
      sql/sql_select.cc
      storage/ndb/include/ndbapi/NdbQueryBuilder.hpp
      storage/ndb/src/ndbapi/NdbQueryBuilder.cpp
 3447 Ole John Aske	2011-03-17 [merge]
      Merge from telco mainline -> SPJ-scan-scan

    removed:
      mysql-test/suite/rpl_ndb/t/rpl_ndb_conflict_d_d.inc
      mysql-test/suite/rpl_ndb/t/rpl_ndb_conflict_d_u.inc
      mysql-test/suite/rpl_ndb/t/rpl_ndb_conflict_i_i.inc
      mysql-test/suite/rpl_ndb/t/rpl_ndb_conflict_init.inc
      mysql-test/suite/rpl_ndb/t/rpl_ndb_conflict_u_d.inc
      mysql-test/suite/rpl_ndb/t/rpl_ndb_conflict_u_u.inc
      storage/ndb/test/sql/
      storage/ndb/test/sql/BANK.sql
      storage/ndb/test/sql/T1.sql
      storage/ndb/test/sql/test_create_drop.pl
      storage/ndb/test/sql/test_range_bounds.pl
      storage/ndb/tools/clean-links.sh
      storage/ndb/tools/make-errors.pl
      storage/ndb/tools/make-links.sh
    added:
      mysql-test/suite/binlog/r/binlog_incident_ignore.result
      mysql-test/suite/binlog/t/binlog_incident_ignore-master.opt
      mysql-test/suite/binlog/t/binlog_incident_ignore.test
      mysql-test/suite/rpl/r/rpl_skip_incident.result
      mysql-test/suite/rpl/t/rpl_skip_incident-master.opt
      mysql-test/suite/rpl/t/rpl_skip_incident-slave.opt
      mysql-test/suite/rpl/t/rpl_skip_incident.test
      mysql-test/suite/rpl_ndb/r/rpl_ndb_ignore_db.result
      mysql-test/suite/rpl_ndb/r/rpl_ndb_skip_gap_event.result
      mysql-test/suite/rpl_ndb/t/rpl_ndb_ignore_db-master.opt
      mysql-test/suite/rpl_ndb/t/rpl_ndb_ignore_db.test
      mysql-test/suite/rpl_ndb/t/rpl_ndb_skip_gap_event-slave.opt
      mysql-test/suite/rpl_ndb/t/rpl_ndb_skip_gap_event.test
    renamed:
      mysql-test/include/ndb_conflict_info.inc => mysql-test/suite/rpl_ndb/t/ndb_conflict_info.inc
      mysql-test/include/ndb_conflict_info_init.inc => mysql-test/suite/rpl_ndb/t/ndb_conflict_info_init.inc
    modified:
      mysql-test/suite/ndb/r/ndb_basic.result
      mysql-test/suite/ndb_binlog/r/ndb_binlog_ignore_db.result
      mysql-test/suite/ndb_binlog/t/ndb_binlog_ignore_db-master.opt
      mysql-test/suite/ndb_binlog/t/ndb_binlog_ignore_db.test
      mysql-test/suite/rpl_ndb/ndb_master-slave.inc
      mysql-test/suite/rpl_ndb/r/rpl_ndb_gap_event.result
      mysql-test/suite/rpl_ndb/t/rpl_ndb_conflict_1.inc
      mysql-test/suite/rpl_ndb/t/rpl_ndb_gap_event.test
      sql/ha_ndbcluster.cc
      sql/ha_ndbcluster.h
      sql/log.cc
      sql/log_event.cc
      sql/log_event.h
      sql/rpl_injector.h
      storage/ndb/docs/doxygen/Doxyfile.mgmapi
      storage/ndb/docs/doxygen/Doxyfile.ndbapi
      storage/ndb/include/ndb_config.h.in
      storage/ndb/ndb_configure.cmake
      storage/ndb/src/common/portlib/NdbCondition.c
      storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
      storage/ndb/src/kernel/blocks/pgman.cpp
      storage/ndb/src/kernel/blocks/tsman.cpp
=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc	2011-03-17 08:17:18 +0000
+++ b/sql/ha_ndbcluster.cc	2011-03-17 12:25:32 +0000
@@ -780,12 +780,13 @@ ha_ndbcluster::make_pushed_join(ndb_push
   
   DBUG_PRINT("info", ("Created pushed join with %d child operations", 
                       push_cnt-1));
-  m_pushed_join= new ndb_pushed_join(context.plan(), 
+  m_pushed_join_member= new ndb_pushed_join(
+                                     context.plan(), 
                                      context.join_scope(), 
                                      fld_refs, 
                                      referred_fields, 
                                      query_def);
-  if (unlikely (m_pushed_join == NULL))
+  if (unlikely (m_pushed_join_member == NULL))
   {
     builder->destroy();
     DBUG_RETURN(HA_ERR_OUT_OF_MEM);
@@ -793,10 +794,11 @@ ha_ndbcluster::make_pushed_join(ndb_push
 
   for (uint i = 0; i < push_cnt; i++)
   {
-    const TABLE* const tab= m_pushed_join->get_table(i);
+    const TABLE* const tab= m_pushed_join_member->get_table(i);
     DBUG_ASSERT(tab->file->ht == ht);
-    ha_ndbcluster* handler= static_cast<ha_ndbcluster*>(tab->file);
-    handler->m_pushed_join_member= this;
+    ha_ndbcluster* child= static_cast<ha_ndbcluster*>(tab->file);
+    child->m_pushed_join_member= m_pushed_join_member;
+    child->m_pushed_join_operation= i;
   }
 
   builder->destroy();
@@ -899,13 +901,13 @@ bool 
 ha_ndbcluster::check_if_pushable(const NdbQueryOperationTypeWrapper& type, 
                                  uint idx, bool needSorted) const
 {
-  if (m_pushed_join == NULL)
+  if (m_pushed_join_operation != PUSHED_ROOT)
   {
     return FALSE;
   }
 
   const NdbQueryOperationDef* const root_operation= 
-    m_pushed_join->get_query_def().getQueryOperation(0U);
+    m_pushed_join_member->get_query_def().getQueryOperation(PUSHED_ROOT);
 
   const NdbQueryOperationTypeWrapper& query_def_type=  
     root_operation->getType();
@@ -980,9 +982,9 @@ ha_ndbcluster::check_if_pushable(const N
   // 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->get_field_referrences_count(); i++)
+  for (uint i= 0; i < m_pushed_join_member->get_field_referrences_count(); i++)
   {
-    Field* field= m_pushed_join->get_field_ref(i);
+    Field* field= m_pushed_join_member->get_field_ref(i);
     if (field->is_real_null())
     {
       DBUG_PRINT("info", 
@@ -1013,34 +1015,36 @@ int
 ha_ndbcluster::create_pushed_join(NdbQueryParamValue* paramValues, uint paramOffs)
 {
   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->get_operation_count(),
-              m_pushed_join->get_table(0)->alias,
+              m_pushed_join_member->get_operation_count(),
+              m_pushed_join_member->get_table(0)->alias,
               NdbQueryOperationDef::getTypeName(
-                m_pushed_join->get_query_def().getQueryOperation(0U)->getType()))
+                m_pushed_join_member->get_query_def().getQueryOperation(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->get_field_referrences_count(); i++)
+  for (uint i= 0; i < m_pushed_join_member->get_field_referrences_count(); i++)
   {
-    Field* field= m_pushed_join->get_field_ref(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);
   }
 
-  NdbQuery* const query= m_thd_ndb->trans->createQuery(&m_pushed_join->get_query_def(), paramValues);
+  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());
 
   // Bind to instantiated NdbQueryOperations.
-  for (uint i= 0; i < m_pushed_join->get_operation_count(); i++)
+  for (uint i= 0; i < m_pushed_join_member->get_operation_count(); i++)
   {
-    const TABLE* const tab= m_pushed_join->get_table(i);
+    const TABLE* const tab= m_pushed_join_member->get_table(i);
     ha_ndbcluster* handler= static_cast<ha_ndbcluster*>(tab->file);
 
+    DBUG_ASSERT(handler->m_pushed_join_operation==i);
     NdbQueryOperation* const op= query->getQueryOperation(i);
     handler->m_pushed_operation= op;
 
@@ -1066,23 +1070,50 @@ ha_ndbcluster::create_pushed_join(NdbQue
 
 
 /**
- * Check if this table access operation is part if a pushed join operation
+ * Check if this table access operation is part of a pushed join operation
  * which is actively executing.
  */
 bool 
 ha_ndbcluster::check_is_pushed() const
 {
-  return (m_pushed_join_member && m_pushed_join_member->m_active_query);
-}
+  if (m_pushed_join_member == NULL)
+    return false;
 
+  handler *root= m_pushed_join_member->get_table(PUSHED_ROOT)->file;
+  return (static_cast<ha_ndbcluster*>(root)->m_active_query);
+}
 
 uint 
-ha_ndbcluster::is_parent_of_pushed_join() const
+ha_ndbcluster::number_of_pushed_joins() const
 {
-  if (!m_pushed_join)
+  if (m_pushed_join_member == NULL)
     return 0;
   else
-    return m_pushed_join->get_operation_count();
+    return m_pushed_join_member->get_operation_count();
+}
+
+const TABLE*
+ha_ndbcluster::root_of_pushed_join() const
+{
+  if (m_pushed_join_member == NULL)
+    return NULL;
+  else
+    return m_pushed_join_member->get_table(PUSHED_ROOT);
+}
+
+const TABLE*
+ha_ndbcluster::parent_of_pushed_join() const
+{
+  if (m_pushed_join_operation > PUSHED_ROOT)
+  {
+    DBUG_ASSERT(m_pushed_join_member!=NULL);
+    uint parent_ix= m_pushed_join_member
+                    ->get_query_def().getQueryOperation(m_pushed_join_operation)
+                    ->getParentOperation(0)
+                    ->getQueryOperationIx();
+    return m_pushed_join_member->get_table(parent_ix);
+  }
+  return NULL;
 }
 
 bool
@@ -1121,8 +1152,8 @@ ha_ndbcluster::test_push_flag(enum ha_pu
      * column values (paramValues), the pushed join has dependencies
      * in addition to the root operation itself.
      */
-    if (m_pushed_join &&
-        m_pushed_join->get_field_referrences_count() > 0)   // Childs has field refs
+    if (m_pushed_join_operation==PUSHED_ROOT &&
+        m_pushed_join_member->get_field_referrences_count() > 0)  // Childs has field refs
     {
       DBUG_RETURN(true);
     }
@@ -1130,13 +1161,13 @@ ha_ndbcluster::test_push_flag(enum ha_pu
 
   case HA_PUSH_NO_ORDERED_INDEX:
   {
-    if (!m_pushed_join)
+    if (m_pushed_join_operation != PUSHED_ROOT)
     {
       DBUG_RETURN(true);
     }
-    const NdbQueryDef& query_def = m_pushed_join->get_query_def();
+    const NdbQueryDef& query_def = m_pushed_join_member->get_query_def();
     const NdbQueryOperationTypeWrapper& root_type=
-      query_def.getQueryOperation(0U)->getType();
+      query_def.getQueryOperation(PUSHED_ROOT)->getType();
 
     /**
      * Primary key/ unique key lookup is always 'ordered' wrt. itself.
@@ -3701,7 +3732,7 @@ int ha_ndbcluster::pk_read(const uchar *
   }
   else
   {
-    if (m_pushed_join != NULL)
+    if (m_pushed_join_operation == PUSHED_ROOT)
     {
       m_thd_ndb->m_pushed_queries_dropped++;
     }
@@ -4113,7 +4144,7 @@ int ha_ndbcluster::unique_index_read(con
   }
   else
   {
-    if (m_pushed_join != NULL)
+    if (m_pushed_join_operation == PUSHED_ROOT)
     {
       m_thd_ndb->m_pushed_queries_dropped++;
     }
@@ -4341,9 +4372,8 @@ int ha_ndbcluster::index_next_pushed(uch
     DBUG_RETURN(index_next(buf));
   }
 
-  DBUG_ASSERT(m_pushed_join_member && m_active_query==NULL);  // Child of a pushed join
-  DBUG_ASSERT(m_pushed_join_member->m_pushed_join);
-  DBUG_ASSERT(m_pushed_join_member->m_active_query);
+  DBUG_ASSERT(m_pushed_join_operation>PUSHED_ROOT);  // Child of a pushed join
+  DBUG_ASSERT(m_active_query==NULL);
 
   int res = fetch_next_pushed();
   if (res == NdbQuery::NextResult_gotRow)
@@ -4676,7 +4706,7 @@ int ha_ndbcluster::ordered_index_scan(co
       DBUG_RETURN(error);
 
     NdbQuery* const query= m_active_query;
-    if (sorted && query->getQueryOperation(0U)
+    if (sorted && query->getQueryOperation(PUSHED_ROOT)
                        ->setOrdering(descending ? NdbQueryOptions::ScanOrdering_descending
                                                 : NdbQueryOptions::ScanOrdering_ascending))
     {
@@ -4698,7 +4728,7 @@ int ha_ndbcluster::ordered_index_scan(co
   }
   else // if (check_if_pushable(NdbQueryOperationDef::OrderedIndexScan))
   {
-    if (m_pushed_join != NULL)
+    if (m_pushed_join_operation == PUSHED_ROOT)
     {
       m_thd_ndb->m_pushed_queries_dropped++;
     }
@@ -4805,7 +4835,7 @@ int ha_ndbcluster::full_table_scan(const
 
   if (m_use_partition_pruning && m_user_defined_partitioning)
   {
-    DBUG_ASSERT(!m_pushed_join);
+    DBUG_ASSERT(m_pushed_join_operation != PUSHED_ROOT);
     part_spec.start_part= 0;
     part_spec.end_part= m_part_info->get_tot_partitions() - 1;
     prune_partition_set(table, &part_spec);
@@ -4873,7 +4903,7 @@ int ha_ndbcluster::full_table_scan(const
   }
   else // if (check_if_pushable(NdbQueryOperationDef::TableScan))
   {
-    if (m_pushed_join != NULL)
+    if (m_pushed_join_operation == PUSHED_ROOT)
     {
       m_thd_ndb->m_pushed_queries_dropped++;
     }
@@ -6826,7 +6856,7 @@ int ha_ndbcluster::read_range_first_to_b
 
   if (m_use_partition_pruning)
   {
-    DBUG_ASSERT(!m_pushed_join);
+    DBUG_ASSERT(!m_pushed_join_operation != PUSHED_ROOT);
     get_partition_set(table, buf, active_index, start_key, &part_spec);
     DBUG_PRINT("info", ("part_spec.start_part: %u  part_spec.end_part: %u",
                         part_spec.start_part, part_spec.end_part));
@@ -7454,12 +7484,12 @@ int ha_ndbcluster::reset()
     m_cond->cond_clear();
   }
   DBUG_ASSERT(m_active_query == NULL);
-  if (m_pushed_join)
+  if (m_pushed_join_operation==PUSHED_ROOT)  // Root of pushed query
   {
-    delete m_pushed_join;
-    m_pushed_join= NULL;
+    delete m_pushed_join_member;
   }
   m_pushed_join_member= NULL;
+  m_pushed_join_operation= -1;
   m_disable_pushed_join= FALSE;
 
   /*
@@ -10712,8 +10742,6 @@ ha_ndbcluster::ha_ndbcluster(handlerton 
   handler(hton, table_arg),
   m_thd_ndb(NULL),
   m_active_cursor(NULL),
-  m_active_query(NULL),
-  m_pushed_operation(NULL),
   m_table(NULL),
   m_ndb_record(0),
   m_ndb_hidden_key_record(0),
@@ -10745,9 +10773,11 @@ ha_ndbcluster::ha_ndbcluster(handlerton 
   m_blobs_buffer_size(0),
   m_dupkey((uint) -1),
   m_autoincrement_prefetch(DEFAULT_AUTO_PREFETCH),
-  m_pushed_join(NULL),
   m_pushed_join_member(NULL),
+  m_pushed_join_operation(-1),
   m_disable_pushed_join(FALSE),
+  m_active_query(NULL),
+  m_pushed_operation(NULL),
   m_cond(NULL),
   m_multi_cursor(NULL)
 {
@@ -10802,11 +10832,11 @@ ha_ndbcluster::~ha_ndbcluster() 
   }
   DBUG_PRINT("info", ("Deleting pushed joins"));
   DBUG_ASSERT(m_active_query == NULL);
-  if (m_pushed_join)
+  if (m_pushed_join_operation==PUSHED_ROOT)
   {
-    delete m_pushed_join;
-    m_pushed_join= NULL;
+    delete m_pushed_join_member;
   }
+  m_pushed_join_member= NULL;
   DBUG_VOID_RETURN;
 }
 
@@ -13791,8 +13821,9 @@ ha_ndbcluster::read_multi_range_first(KE
       (cur_index_type ==  UNIQUE_INDEX &&
        has_null_in_unique_index(active_index) &&
        null_value_index_search(ranges, ranges+range_count, buffer))
-      || (m_pushed_join && !m_disable_pushed_join &&
-         !m_pushed_join->get_query_def().isScanQuery())
+      || (m_pushed_join_operation==PUSHED_ROOT &&
+         !m_disable_pushed_join &&
+         !m_pushed_join_member->get_query_def().isScanQuery())
       || m_delete_cannot_batch || m_update_cannot_batch)
   {
     DBUG_PRINT("info", ("read_multi_range not possible, falling back to default handler implementation"));
@@ -13891,7 +13922,8 @@ ha_ndbcluster::read_multi_range_first(KE
     }
     r->range_flag&= ~(uint)SKIP_RANGE;
 
-    if ((m_pushed_join && m_pushed_join->get_query_def().isScanQuery()) ||    // Pushed joins currently restricted to ordered range scan in mrr
+    if ((m_pushed_join_operation==PUSHED_ROOT &&
+         m_pushed_join_member->get_query_def().isScanQuery()) || // Pushed joins restricted to ordered range scan in mrr
         read_multi_needs_scan(cur_index_type, key_info, r))
     {
       if (!trans)
@@ -13942,14 +13974,14 @@ ha_ndbcluster::read_multi_range_first(KE
 
           NdbQuery* const query= m_active_query;
           if (sorted &&
-              query->getQueryOperation(0U)->setOrdering(NdbQueryOptions::ScanOrdering_ascending))
+              query->getQueryOperation(PUSHED_ROOT)->setOrdering(NdbQueryOptions::ScanOrdering_ascending))
             ERR_RETURN(query->getNdbError());
         }
       } // check_if_pushable()
 
       else if (!m_multi_cursor)
       {
-        if (m_pushed_join != NULL)
+        if (m_pushed_join_operation == PUSHED_ROOT)
         {
           m_thd_ndb->m_pushed_queries_dropped++;
         }
@@ -14050,9 +14082,9 @@ ha_ndbcluster::read_multi_range_first(KE
       r->range_flag&= ~(uint)UNIQUE_RANGE;
       num_scan_ranges++;
     }
-    else // if ((m_pushed_join && m_pushed_join->get_query_def().isScanQuery()) ||...
+    else // if ((...PUSHED_ROOT && m_pushed_join->get_query_def().isScanQuery()) ||...
     {
-      if (m_pushed_join != NULL)
+      if (m_pushed_join_operation == PUSHED_ROOT)
       {
         m_thd_ndb->m_pushed_queries_dropped++;
       }
@@ -14102,9 +14134,9 @@ ha_ndbcluster::read_multi_range_first(KE
       // 'Pushable codepath' is incomplete and expected not
       // to be produced as make_join_pushed() handle 
       // AT_MULTI_UNIQUE_KEY as non-pushable
-      if (m_pushed_join &&
+      if (m_pushed_join_operation==PUSHED_ROOT &&
           !m_disable_pushed_join &&
-          !m_pushed_join->get_query_def().isScanQuery())
+          !m_pushed_join_member->get_query_def().isScanQuery())
       {
         DBUG_ASSERT(false);  // Incomplete code, should not be executed
         DBUG_ASSERT(lm == NdbOperation::LM_CommittedRead);
@@ -14116,7 +14148,7 @@ ha_ndbcluster::read_multi_range_first(KE
       }
       else
       {
-        if (m_pushed_join)
+        if (m_pushed_join_operation == PUSHED_ROOT)
         {
           DBUG_PRINT("info", ("Cannot push join due to incomplete implementation."));
           m_thd_ndb->m_pushed_queries_dropped++;
@@ -14137,7 +14169,7 @@ ha_ndbcluster::read_multi_range_first(KE
   buffer->end_of_used_area= row_buf;
 
   if (m_active_query != NULL &&         
-      m_pushed_join->get_query_def().isScanQuery())
+      m_pushed_join_member->get_query_def().isScanQuery())
   {
     m_thd_ndb->m_scan_count++;
     if (sorted)

=== modified file 'sql/ha_ndbcluster.h'
--- a/sql/ha_ndbcluster.h	2011-03-17 08:17:18 +0000
+++ b/sql/ha_ndbcluster.h	2011-03-17 12:25:32 +0000
@@ -597,10 +597,9 @@ static void set_tabname(const char *path
 
   bool test_push_flag(enum ha_push_flag flag) const;
 
-  uint is_parent_of_pushed_join() const;
-  const handler* member_of_pushed_join() const
-  { return m_pushed_join_member;
-  }
+  uint number_of_pushed_joins() const;
+  const TABLE* root_of_pushed_join() const;
+  const TABLE* parent_of_pushed_join() const;
 
   int index_read_pushed(uchar *buf, const uchar *key,
                         key_part_map keypart_map);
@@ -853,8 +852,6 @@ private:
 
   Thd_ndb *m_thd_ndb;
   NdbScanOperation *m_active_cursor;
-  NdbQuery* m_active_query;
-  NdbQueryOperation* m_pushed_operation;
 
   const NdbDictionary::Table *m_table;
   /*
@@ -940,9 +937,14 @@ private:
   ha_rows m_autoincrement_prefetch;
 
   // Joins pushed to NDB.
-  const class ndb_pushed_join *m_pushed_join; // Pushed join def. if I am parent
-  const ha_ndbcluster *m_pushed_join_member;  // Parent handler instance
-  bool m_disable_pushed_join;            // Execution allowed?
+  const class ndb_pushed_join
+       *m_pushed_join_member;            // Pushed join def. I am member of
+  int m_pushed_join_operation;           // Op. id. in above pushed join
+  static const uint PUSHED_ROOT= 0;      // Op. id. if I'm root
+
+  bool m_disable_pushed_join;            // Pushed execution allowed?
+  NdbQuery* m_active_query;              // Pushed query instance executing
+  NdbQueryOperation* m_pushed_operation; // Pushed operation instance
 
   ha_ndbcluster_cond *m_cond;
   bool m_disable_multi_read;

=== modified file 'sql/handler.h'
--- a/sql/handler.h	2011-01-04 14:50:54 +0000
+++ b/sql/handler.h	2011-03-17 12:25:32 +0000
@@ -1890,17 +1890,24 @@ public:
  virtual void cond_pop() { return; };
 
   /**
-    Reports #tables included in pushed join starting from 
-    this handler instance.
+    Reports #tables included in pushed join which this
+    handler instance is part of. ==0 -> Not pushed
   */
-  virtual uint is_parent_of_pushed_join() const
+  virtual uint number_of_pushed_joins() const
   { return 0; }
 
   /**
-    Is this handler instance part of a pushed join sequence
-    having the returned handler instance as parent?
+    If this handler instance is part of a pushed join sequence
+    returned TABLE instance being root of the pushed query?
   */
-  virtual const handler* member_of_pushed_join() const
+  virtual const TABLE* root_of_pushed_join() const
+  { return NULL; }
+
+  /**
+    If this handler instance is a child in a pushed join sequence
+    returned TABLE instance being my parent?
+  */
+  virtual const TABLE* parent_of_pushed_join() const
   { return NULL; }
 
   virtual bool test_push_flag(enum ha_push_flag flag) const

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2011-02-23 13:09:10 +0000
+++ b/sql/sql_select.cc	2011-03-17 12:25:32 +0000
@@ -1670,12 +1670,14 @@ make_pushed_join(THD *thd, JOIN *join)
   {
     JOIN_TAB *tab=join->join_tab+i;
 
-    if (tab->table->file->member_of_pushed_join())
+    uint pushed_joins= tab->table->file->number_of_pushed_joins();
+    if (pushed_joins > 0)
     {
-      uint pushed_joins= tab->table->file->is_parent_of_pushed_join();
-      active_pushed_joins += pushed_joins;
-
-      if (pushed_joins == 0)
+      if (tab->table->file->root_of_pushed_join() == tab->table)
+      {
+        active_pushed_joins += pushed_joins;
+      }
+      else  
       {
         // Is child of a pushed join operation:
         // Replace 'read_key' access with its linked counterpart 
@@ -1694,7 +1696,7 @@ make_pushed_join(THD *thd, JOIN *join)
    * or write to a temp. table later being filesorted.
    */
   if (join->const_tables < join->tables &&
-      join->join_tab[join->const_tables].table->file->is_parent_of_pushed_join())
+      join->join_tab[join->const_tables].table->file->number_of_pushed_joins() > 0)
   {
     const handler *ha=join->join_tab[join->const_tables].table->file;
 
@@ -17198,8 +17200,8 @@ static void select_describe(JOIN *join, 
       }
       else
       {
-        const handler* pushed_join= table->file->member_of_pushed_join();
-        if (pushed_join)
+        const TABLE* pushed_root= table->file->root_of_pushed_join();
+        if (pushed_root)
         {
           char buf[64];
           int len;
@@ -17207,16 +17209,17 @@ static void select_describe(JOIN *join, 
 
           for (JOIN_TAB* prev= join->join_tab; prev <= tab; prev++)
           {
-            if (prev->table->file->is_parent_of_pushed_join() > 0)
+            const TABLE* prev_root= prev->table->file->root_of_pushed_join();
+            if (prev_root == prev->table)
             {
               pushed_id++;
-              if (prev->table->file->member_of_pushed_join() == pushed_join)
+              if (prev_root == pushed_root)
                 break;
             }
           }
-          uint pushed_count= tab->table->file->is_parent_of_pushed_join();
-          if (pushed_count > 0)
+          if (pushed_root == table)
           {
+            uint pushed_count= tab->table->file->number_of_pushed_joins();
 	    len= my_snprintf(buf, sizeof(buf)-1,
                              "; Parent of %d pushed join@%d",
                              pushed_count, pushed_id);

=== modified file 'storage/ndb/include/ndbapi/NdbQueryBuilder.hpp'
--- a/storage/ndb/include/ndbapi/NdbQueryBuilder.hpp	2011-02-11 13:12:09 +0000
+++ b/storage/ndb/include/ndbapi/NdbQueryBuilder.hpp	2011-03-17 12:25:32 +0000
@@ -223,6 +223,11 @@ public:
 
   static const char* getTypeName(Type type);
 
+  /**
+   * Get the ordinal position of this operation within the QueryDef.
+   */
+  Uint32 getQueryOperationIx() const;
+
   Uint32 getNoOfParentOperations() const;
   const NdbQueryOperationDef* getParentOperation(Uint32 i) const;
 

=== modified file 'storage/ndb/src/ndbapi/NdbQueryBuilder.cpp'
--- a/storage/ndb/src/ndbapi/NdbQueryBuilder.cpp	2011-02-11 13:12:09 +0000
+++ b/storage/ndb/src/ndbapi/NdbQueryBuilder.cpp	2011-03-17 12:25:32 +0000
@@ -616,6 +616,11 @@ NdbQueryIndexScanOperationDefImpl& getIm
 }
 
 
+Uint32
+NdbQueryOperationDef::getQueryOperationIx() const
+{
+  return ::getImpl(*this).getQueryOperationIx();
+}
 
 Uint32
 NdbQueryOperationDef::getNoOfParentOperations() const

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:3447 to 3448) Ole John Aske17 Mar