3502 Ole John Aske 2011-06-15
SPJ: Refactoring of AQP interface in order to avoid heap alloc of an
'Item_equal_iterator' object.
This has been changed to instead let the 'Item_equal_iterator' be a direct
member of the AQP::Equal_set_iterator and constructed as part of this object.
modified:
sql/abstract_query_plan.cc
sql/abstract_query_plan.h
sql/ha_ndbcluster_push.cc
3501 Jan Wedvik 2011-06-07
This commit adds a regression test case for http://lists.mysql.com/commits/138760 (mysql-5.1-telco-7.0 revno 4441,
bushy scan with pruning).
modified:
mysql-test/suite/ndb/r/ndb_join_pushdown.result
mysql-test/suite/ndb/t/ndb_join_pushdown.test
=== modified file 'sql/abstract_query_plan.cc'
--- a/sql/abstract_query_plan.cc 2011-05-02 13:44:39 +0000
+++ b/sql/abstract_query_plan.cc 2011-06-15 07:26:12 +0000
@@ -271,6 +271,22 @@ namespace AQP
return m_join_plan->get_join_tab(m_tab_no);
}
+ /** Get the Item_equal's set relevant for the specified 'Item_field' */
+ Item_equal*
+ Table_access::get_item_equal(const Item_field* field_item) const
+ {
+ DBUG_ASSERT(field_item->type() == Item::FIELD_ITEM);
+
+ COND_EQUAL* const cond_equal = get_join_tab()->join->cond_equal;
+ if (cond_equal!=NULL)
+ {
+ return (field_item->item_equal != NULL)
+ ? field_item->item_equal
+ : const_cast<Item_field*>(field_item)->find_item_equal(cond_equal);
+ }
+ return NULL;
+ }
+
/**
Write an entry in the trace file about the contents of this object.
*/
@@ -543,67 +559,5 @@ namespace AQP
return get_join_tab()->next_select == sub_select_cache;
}
- /**
- @param plan Iterate over fields within this plan.
- @param field_item Iterate over Item_fields equal to this.
- */
- Equal_set_iterator::Equal_set_iterator(const Join_plan* plan,
- const Item_field* field_item)
- :m_next(NULL),
- m_iterator(NULL)
- {
- DBUG_ASSERT(field_item->type() == Item::FIELD_ITEM);
-
- COND_EQUAL* const cond_equal=
- plan->get_join_tab(0)->join->cond_equal;
-
- if (cond_equal!=NULL)
- {
- Item_equal* item_equal= NULL;
- if (field_item->item_equal == NULL)
- item_equal=
- const_cast<Item_field*>(field_item)->find_item_equal(cond_equal);
- else
- item_equal= field_item->item_equal;
-
- if (item_equal != NULL)
- {
- m_iterator= new Item_equal_iterator(*item_equal);
- m_next= (*m_iterator)++;
- }
- }
- }
-
-
- Equal_set_iterator::~Equal_set_iterator()
- {
- delete m_iterator;
- }
-
-
- /**
- Get the next Item_field and advance the iterator.
- @return A pointer to the next Item_field, or NULL if the end has been
- reached.
- */
- const Item_field*
- Equal_set_iterator::next()
- {
- const Item_field* result= m_next;
- if (m_next != NULL)
- {
- if (m_iterator == NULL)
- m_next= NULL;
- else
- {
- if (m_iterator->is_last())
- m_next= NULL;
- else
- m_next= (*m_iterator)++;
- }
- }
- return result;
- }
-
};
// namespace AQP
=== modified file 'sql/abstract_query_plan.h'
--- a/sql/abstract_query_plan.h 2011-01-18 08:17:07 +0000
+++ b/sql/abstract_query_plan.h 2011-06-15 07:26:12 +0000
@@ -112,25 +112,17 @@ namespace AQP
class Equal_set_iterator
{
public:
+ explicit Equal_set_iterator(Item_equal& item_equal)
+ : m_iterator(item_equal) {}
- explicit Equal_set_iterator(const Join_plan* plan,
- const Item_field* field_item);
-
- ~Equal_set_iterator();
-
- const Item_field* next();
+ const Item_field* next()
+ { return m_iterator++; }
private:
-
- /**
- The next Item_field, or NULL if end has been reached.
- */
- const Item_field* m_next;
-
/**
This class is implemented in terms of this mysqld internal class.
*/
- Item_equal_iterator* m_iterator;
+ Item_equal_iterator m_iterator;
// No copying.
Equal_set_iterator(const Equal_set_iterator&);
@@ -211,6 +203,8 @@ namespace AQP
st_table* get_table() const;
+ Item_equal* get_item_equal(const Item_field* field_item) const;
+
void dbug_print() const;
bool is_fixed_ordered_index() const;
=== modified file 'sql/ha_ndbcluster_push.cc'
--- a/sql/ha_ndbcluster_push.cc 2011-05-04 13:29:32 +0000
+++ b/sql/ha_ndbcluster_push.cc 2011-06-15 07:26:12 +0000
@@ -739,29 +739,31 @@ bool ndb_pushed_builder_ctx::is_field_it
// 2) Use the equality set to possibly find more parent candidates
// usable by substituting existing 'key_item_field'
//
- AQP::Equal_set_iterator equal_iter(&m_plan, key_item_field);
- const Item_field* substitute_field= equal_iter.next();
- while (substitute_field != NULL)
+ Item_equal* item_equal= table->get_item_equal(key_item_field);
+ if (item_equal)
{
- if (substitute_field != key_item_field)
+ AQP::Equal_set_iterator equal_iter(*item_equal);
+ const Item_field* substitute_field;
+ while ((substitute_field= equal_iter.next()) != NULL)
{
- const uint substitute_table_no= get_table_no(substitute_field);
- if (m_join_scope.contain(substitute_table_no))
+ if (substitute_field != key_item_field)
{
- DBUG_PRINT("info",
- (" join_items[%d] %s.%s can be replaced with %s.%s",
- (int)(key_item - table->get_key_field(0)),
- get_referred_table_access_name(key_item_field),
- get_referred_field_name(key_item_field),
- get_referred_table_access_name(substitute_field),
- get_referred_field_name(substitute_field)));
+ const uint substitute_table_no= get_table_no(substitute_field);
+ if (m_join_scope.contain(substitute_table_no))
+ {
+ DBUG_PRINT("info",
+ (" join_items[%d] %s.%s can be replaced with %s.%s",
+ (int)(key_item - table->get_key_field(0)),
+ get_referred_table_access_name(key_item_field),
+ get_referred_field_name(key_item_field),
+ get_referred_table_access_name(substitute_field),
+ get_referred_field_name(substitute_field)));
- field_parents.add(substitute_table_no);
+ field_parents.add(substitute_table_no);
+ }
}
- }
- substitute_field= equal_iter.next();
- } // while(substitute_field != NULL)
-
+ } // while(substitute_field != NULL)
+ }
if (!field_parents.is_clear_all())
{
DBUG_RETURN(true);
@@ -963,12 +965,14 @@ ndb_pushed_builder_ctx::collect_key_refs
{
const Item_field* join_item= static_cast<const Item_field*>(key_item);
uint referred_table_no= get_table_no(join_item);
+ Item_equal* item_equal;
- if (referred_table_no != parent_no)
+ if (referred_table_no != parent_no &&
+ (item_equal= table->get_item_equal(join_item)) != NULL)
{
- AQP::Equal_set_iterator iter(&m_plan, join_item);
- const Item_field* substitute_field= iter.next();
- while (substitute_field != NULL)
+ AQP::Equal_set_iterator iter(*item_equal);
+ const Item_field* substitute_field;
+ while ((substitute_field= iter.next()) != NULL)
{
///////////////////////////////////////////////////////////
// Prefer to replace join_item with ref. to selected parent.
@@ -1014,7 +1018,6 @@ ndb_pushed_builder_ctx::collect_key_refs
key_refs[key_part_no]= join_item= substitute_field;
}
}
- substitute_field= iter.next();
} // while (substitute...
DBUG_ASSERT (referred_table_no == parent_no ||
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:3501 to 3502) | Ole John Aske | 15 Jun |