From: magnus.blaudd
Date: September 30 2011 10:30am
Subject: bzr push into mysql-trunk-cluster branch (magnus.blaudd:3390 to 3392)
List-Archive: http://lists.mysql.com/commits/141230
Message-Id: <201109301030.p8UAUhuW024961@acsmt356.oracle.com>
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
3392 magnus.blaudd@stripped 2011-09-30
ndb - remove abstract_query_plan.h/cc, should be added to trunk as part of it's own WL#
removed:
sql/abstract_query_plan.cc
sql/abstract_query_plan.h
3391 magnus.blaudd@stripped 2011-09-30 [merge]
Merge
modified:
sql/abstract_query_plan.cc
sql/ha_ndbcluster.cc
sql/ha_ndbcluster.h
sql/ha_ndbcluster_cond.cc
sql/ha_ndbcluster_cond.h
sql/ha_ndbcluster_connection.cc
sql/ha_ndbcluster_push.cc
sql/ha_ndbcluster_push.h
storage/ndb/CMakeLists.txt
3390 magnus.blaudd@stripped 2011-09-28 [merge]
Merge
=== removed file 'sql/abstract_query_plan.cc'
--- a/sql/abstract_query_plan.cc 2011-09-28 19:25:31 +0000
+++ b/sql/abstract_query_plan.cc 1970-01-01 00:00:00 +0000
@@ -1,573 +0,0 @@
-/*
- Copyright 2010 Sun Microsystems, Inc.
- All rights reserved. Use is subject to license terms.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#ifdef USE_PRAGMA_IMPLEMENTATION
-#pragma implementation // gcc: Class implementation
-#endif
-
-#ifndef MYSQL_SERVER
-#define MYSQL_SERVER
-#endif
-
-#include "sql_priv.h"
-#include "sql_select.h"
-#include "abstract_query_plan.h"
-
-
-#ifdef NDB_WITHOUT_JOIN_PUSHDOWN
-static bool
-test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
- bool no_changes, const key_map *map)
-{
- // Stub used when compiling AQP as part of ndbcluster, never called
- assert(false);
- return false;
-}
-#endif
-
-namespace AQP
-{
-
- /**
- @param join_tab Array of access methods constituting the nested loop join.
- @param access_count Length of array.
- */
- Join_plan::Join_plan(const JOIN* join)
- : m_join_tabs(join->join_tab),
- m_access_count(join->tables),
- m_table_accesses(NULL)
- {
- /*
- This combination is assumed not to appear. If it does, code must
- be written to handle it.
- */
- DBUG_ASSERT((m_join_tabs[0].use_quick != 2)
- || (m_join_tabs[0].type == JT_ALL)
- || (m_join_tabs[0].select == NULL)
- || (m_join_tabs[0].select->quick == NULL));
-
- m_table_accesses= new Table_access[m_access_count];
- for(uint i= 0; i < m_access_count; i++)
- {
- m_table_accesses[i].m_join_plan= this;
- m_table_accesses[i].m_tab_no= i;
- }
- }
-
- Join_plan::~Join_plan()
- {
- delete[] m_table_accesses;
- m_table_accesses= NULL;
- }
-
- /** Get the JOIN_TAB of the n'th table access operation.*/
- const JOIN_TAB* Join_plan::get_join_tab(uint join_tab_no) const
- {
- DBUG_ASSERT(join_tab_no < m_access_count);
- return m_join_tabs + join_tab_no;
- }
-
- void
- Join_plan::find_skippabable_group_or_order() const
- {
- const
- JOIN* const join= m_join_tabs->join;
-
- if (join->const_tables < join->tables)
- {
- JOIN_TAB* join_head= join->join_tab+join->const_tables;
-
- m_group_by_filesort_is_skippable= join->group_optimized_away;
- m_order_by_filesort_is_skippable= join->skip_sort_order;
-
- /* A single row don't have to be sorted */
- if (join_head->type == JT_CONST ||
- join_head->type == JT_SYSTEM ||
- join_head->type == JT_EQ_REF)
- {
- m_group_by_filesort_is_skippable= true;
- m_order_by_filesort_is_skippable= true;
- }
- else if (join->select_options & SELECT_BIG_RESULT)
- {
- /* Excluded from ordered index optimization */
- }
- else if (join->group_list && !m_group_by_filesort_is_skippable)
- {
- if (!join->tmp_table_param.quick_group || join->procedure)
- {
- /* Unsure how to handle - Is disabled in ::compute_type_and_index() */
- }
- if (join->simple_group)
- {
- /**
- test_if_skip_sort_order(...group_list...) already done by JOIN::optimize().
- As we still have a 'simple_group', GROUP BY has been optimized through an
- access path providing an ordered sequence as required by GROUP BY:
-
- Verify this assumption in ASSERT below:
- */
- DBUG_ASSERT(test_if_skip_sort_order(join_head, join->group_list,
- join->unit->select_limit_cnt, true,
- &join_head->table->keys_in_use_for_group_by));
- m_group_by_filesort_is_skippable= true;
- }
- }
- else if (join->order && !m_order_by_filesort_is_skippable)
- {
- if (join->simple_order)
- {
- m_order_by_filesort_is_skippable=
- test_if_skip_sort_order(join_head,
- join->order,
- join->unit->select_limit_cnt, false,
- &join_head->table->keys_in_use_for_order_by);
- }
- }
- }
- }
-
- bool
- Join_plan::group_by_filesort_is_skippable() const
- {
- return (m_group_by_filesort_is_skippable == true);
- }
-
- bool
- Join_plan::order_by_filesort_is_skippable() const
- {
- return (m_order_by_filesort_is_skippable == true);
- }
-
- /**
- Determine join type between this table access and some other table
- access that preceeds it in the join plan..
- */
- enum_join_type
- Table_access::get_join_type(const Table_access* predecessor) const
- {
- DBUG_ENTER("get_join_type");
- DBUG_ASSERT(get_access_no() > predecessor->get_access_no());
-
- if (get_join_tab()->table->pos_in_table_list->outer_join != 0)
- {
- /*
- This cover unnested outer joins such as
- 'select * from t1 left join t2 on t1.attr=t1.pk'.
- */
- DBUG_PRINT("info", ("JT_OUTER_JOIN between %s and %s",
- predecessor->get_join_tab()->table->alias,
- get_join_tab()->table->alias));
- DBUG_RETURN(JT_OUTER_JOIN);
- }
-
- const TABLE_LIST* const child_embedding=
- get_join_tab()->table->pos_in_table_list->embedding;
-
- if (child_embedding == NULL)
- {
- // 'this' is not on the inner side of any left join.
- DBUG_PRINT("info", ("JT_INNER_JOIN between %s and %s",
- predecessor->get_join_tab()->table->alias,
- get_join_tab()->table->alias));
- DBUG_RETURN(JT_INNER_JOIN);
- }
-
- DBUG_ASSERT(child_embedding->outer_join != 0);
-
- const TABLE_LIST *predecessor_embedding=
- predecessor->get_join_tab()->table->pos_in_table_list->embedding;
-
- /*
- This covers the nested join case, i.e:
-
LEFT JOIN ().
-
- TABLE_LIST objects form a tree where TABLE_LIST::emebedding points to
- the parent object. Now if child_embedding is non null and not an
- ancestor of predecessor_embedding in the embedding tree, then 'this'
- must be on the inner side of some left join where 'predecessor' is on
- the outer side.
- */
- while (true)
- {
- if (predecessor_embedding == child_embedding)
- {
- DBUG_PRINT("info", ("JT_INNER_JOIN between %s and %s",
- predecessor->get_join_tab()->table->alias,
- get_join_tab()->table->alias));
- DBUG_RETURN(JT_INNER_JOIN);
- }
- else if (predecessor_embedding == NULL)
- {
- /*
- We reached the root of the tree without finding child_embedding,
- so it must be in another branch and hence on the inner side of some
- left join where 'predecessor' is on the outer side.
- */
- DBUG_PRINT("info", ("JT_OUTER_JOIN between %s and %s",
- predecessor->get_join_tab()->table->alias,
- get_join_tab()->table->alias));
- DBUG_RETURN(JT_OUTER_JOIN);
- }
- // Iterate through ancestors of predecessor_embedding.
- predecessor_embedding = predecessor_embedding->embedding;
- }
- }
-
- /**
- Get the number of key values for this operation. It is an error
- to call this method on an operation that is not an index lookup
- operation.
- */
- uint Table_access::get_no_of_key_fields() const
- {
- DBUG_ASSERT(m_access_type == AT_PRIMARY_KEY ||
- m_access_type == AT_UNIQUE_KEY ||
- m_access_type == AT_MULTI_PRIMARY_KEY ||
- m_access_type == AT_MULTI_UNIQUE_KEY ||
- m_access_type == AT_ORDERED_INDEX_SCAN); // Used as 'range scan'
- return get_join_tab()->ref.key_parts;
- }
-
- /**
- Get the field_no'th key values for this operation. It is an error
- to call this method on an operation that is not an index lookup
- operation.
- */
- const Item* Table_access::get_key_field(uint field_no) const
- {
- DBUG_ASSERT(field_no < get_no_of_key_fields());
- return get_join_tab()->ref.items[field_no];
- }
-
- /**
- Get the field_no'th KEY_PART_INFO for this operation. It is an error
- to call this method on an operation that is not an index lookup
- operation.
- */
- const KEY_PART_INFO* Table_access::get_key_part_info(uint field_no) const
- {
- DBUG_ASSERT(field_no < get_no_of_key_fields());
- const KEY* key= &get_join_tab()->table->key_info[get_join_tab()->ref.key];
- return &key->key_part[field_no];
- }
-
- /**
- Get the table that this operation accesses.
- */
- TABLE* Table_access::get_table() const
- {
- return get_join_tab()->table;
- }
-
- /** Get the JOIN_TAB object that corresponds to this operation.*/
- const JOIN_TAB* Table_access::get_join_tab() const
- {
- 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(field_item)->find_item_equal(cond_equal);
- }
- return NULL;
- }
-
- /**
- Write an entry in the trace file about the contents of this object.
- */
- void Table_access::dbug_print() const
- {
- DBUG_PRINT("info", ("type:%d", get_join_tab()->type));
- DBUG_PRINT("info", ("ref.key:%d", get_join_tab()->ref.key));
- DBUG_PRINT("info", ("ref.key_parts:%d", get_join_tab()->ref.key_parts));
- DBUG_PRINT("info", ("ref.key_length:%d", get_join_tab()->ref.key_length));
-
- DBUG_PRINT("info", ("order:%p", get_join_tab()->join->order));
- DBUG_PRINT("info", ("skip_sort_order:%d",
- get_join_tab()->join->skip_sort_order));
- DBUG_PRINT("info", ("no_order:%d", get_join_tab()->join->no_order));
- DBUG_PRINT("info", ("simple_order:%d", get_join_tab()->join->simple_order));
-
- DBUG_PRINT("info", ("group:%d", get_join_tab()->join->group));
- DBUG_PRINT("info", ("group_list:%p", get_join_tab()->join->group_list));
- DBUG_PRINT("info", ("simple_group:%d", get_join_tab()->join->simple_group));
- DBUG_PRINT("info", ("group_optimized_away:%d",
- get_join_tab()->join->group_optimized_away));
-
- DBUG_PRINT("info", ("full_join:%d", get_join_tab()->join->full_join));
- DBUG_PRINT("info", ("need_tmp:%d", get_join_tab()->join->need_tmp));
- DBUG_PRINT("info", ("select_distinct:%d",
- get_join_tab()->join->select_distinct));
-
- DBUG_PRINT("info", ("use_quick:%d", get_join_tab()->use_quick));
- DBUG_PRINT("info", ("index:%d", get_join_tab()->index));
- DBUG_PRINT("info", ("quick:%p", get_join_tab()->quick));
- DBUG_PRINT("info", ("select:%p", get_join_tab()->select));
- if (get_join_tab()->select && get_join_tab()->select->quick)
- {
- DBUG_PRINT("info", ("select->quick->get_type():%d",
- get_join_tab()->select->quick->get_type()));
- }
- }
-
-
- /**
- Compute the access type and index (if apliccable) of this operation .
- */
- void Table_access::compute_type_and_index() const
- {
- DBUG_ENTER("Table_access::compute_type_and_index");
- const JOIN_TAB* const join_tab= get_join_tab();
- JOIN* const join= join_tab->join;
-
- /**
- * There are some JOIN arguments we don't fully understand or has
- * not yet invested time into exploring pushability of:
- */
- if (join->procedure)
- {
- m_access_type= AT_OTHER;
- m_other_access_reason =
- "'PROCEDURE'-clause post processing cannot be pushed.";
- DBUG_VOID_RETURN;
- }
-
- if (join->group_list && !join->tmp_table_param.quick_group)
- {
- m_access_type= AT_OTHER;
- m_other_access_reason =
- "GROUP BY cannot be done using index on grouped columns.";
- DBUG_VOID_RETURN;
- }
-
- /* Tables below 'const_tables' has been const'ified, or entirely
- * optimized away due to 'impossible WHERE/ON'
- */
- if (join_tab < join->join_tab+join->const_tables)
- {
- DBUG_PRINT("info", ("Operation %d is const-optimized.", m_tab_no));
- m_access_type= AT_FIXED;
- DBUG_VOID_RETURN;
- }
-
- /* First non-const table may provide 'simple' ordering for entire join */
- if (join_tab == join->join_tab+join->const_tables)
- {
- m_join_plan->find_skippabable_group_or_order();
- }
-
- /*
- Identify the type of access operation and the index to use (if any).
- */
- switch (join_tab->type)
- {
- case JT_EQ_REF:
- case JT_CONST:
- m_index_no= join_tab->ref.key;
-
- if (m_index_no == static_cast(join_tab->table->s->primary_key))
- {
- DBUG_PRINT("info", ("Operation %d is a primary key lookup.", m_tab_no));
- m_access_type= AT_PRIMARY_KEY;
- }
- else
- {
- DBUG_PRINT("info", ("Operation %d is a unique index lookup.",
- m_tab_no));
- m_access_type= AT_UNIQUE_KEY;
- }
- break;
-
- case JT_REF:
- {
- DBUG_ASSERT(join_tab->ref.key >= 0);
- DBUG_ASSERT(join_tab->ref.key < MAX_KEY);
- m_index_no= join_tab->ref.key;
-
- /*
- All parts of a key are specified for an unique index -> access is a key lookup.
- */
- const KEY *key_info= join_tab->table->s->key_info;
- if (key_info[m_index_no].key_parts == join_tab->ref.key_parts &&
- key_info[m_index_no].flags & HA_NOSAME)
- {
- m_access_type=
- (m_index_no == static_cast(join_tab->table->s->primary_key))
- ? AT_PRIMARY_KEY
- : AT_UNIQUE_KEY;
- DBUG_PRINT("info", ("Operation %d is an unique key referrence.", m_tab_no));
- }
- else
- {
- DBUG_ASSERT(join_tab->ref.key_parts > 0);
- DBUG_ASSERT(join_tab->ref.key_parts <= key_info[m_index_no].key_parts);
- m_access_type= AT_ORDERED_INDEX_SCAN;
- DBUG_PRINT("info", ("Operation %d is an ordered index scan.", m_tab_no));
- }
- break;
- }
- case JT_NEXT:
- DBUG_ASSERT(join_tab->index < MAX_KEY);
- m_index_no= join_tab->index;
- m_access_type= AT_ORDERED_INDEX_SCAN;
- DBUG_PRINT("info", ("Operation %d is an ordered index scan.", m_tab_no));
- break;
-
- case JT_ALL:
- if (join_tab->use_quick == 2)
- {
- /*
- use_quick == 2 means that the decision on which access method to use
- will be taken late (as rows from the preceeding operation arrive).
- This operation is therefor not pushable.
- */
- DBUG_PRINT("info",
- ("Operation %d has 'use_quick == 2' -> not pushable",
- m_tab_no));
- m_access_type= AT_UNDECIDED;
- m_index_no= -1;
- }
- else
- {
- if (join_tab->select != NULL &&
- join_tab->select->quick != NULL)
- {
- QUICK_SELECT_I *quick= join_tab->select->quick;
-
- /** QUICK_SELECT results in execution of MRR (Multi Range Read).
- * Depending on each range, it may require execution of
- * either a PK-lookup or a range scan. To cover both of
- * these we may need to prepare both a pushed lookup join
- * and a pushed range scan. Currently we handle it as
- * a range scan and convert e PK lookup to a (closed-) range
- * whenever required.
- **/
-
- const KEY *key_info= join_tab->table->s->key_info;
- DBUG_EXECUTE("info", quick->dbug_dump(0, TRUE););
-
- // Temporary assert as we are still investigation the relation between
- // 'quick->index == MAX_KEY' and the different quick_types
- DBUG_ASSERT ((quick->index == MAX_KEY) ==
- ((quick->get_type() == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE) ||
- (quick->get_type() == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT) ||
- (quick->get_type() == QUICK_SELECT_I::QS_TYPE_ROR_UNION)));
-
- // JT_INDEX_MERGE: We have a set of qualifying PKs as root of pushed joins
- if (quick->index == MAX_KEY)
- {
- m_index_no= join_tab->table->s->primary_key;
- m_access_type= AT_MULTI_PRIMARY_KEY; // Multiple PKs are produced by merge
- }
-
- // Else JT_RANGE: May be both exact PK and/or index scans when sorted index available
- else if (quick->index == join_tab->table->s->primary_key)
- {
- m_index_no= quick->index;
- if (key_info[m_index_no].algorithm == HA_KEY_ALG_HASH)
- m_access_type= AT_MULTI_PRIMARY_KEY; // MRR w/ multiple PK's
- else
- m_access_type= AT_MULTI_MIXED; // MRR w/ both range and PKs
- }
- else
- {
- m_index_no= quick->index;
- if (key_info[m_index_no].algorithm == HA_KEY_ALG_HASH)
- m_access_type= AT_MULTI_UNIQUE_KEY; // MRR with multiple unique keys
- else
- m_access_type= AT_MULTI_MIXED; // MRR w/ both range and unique keys
- }
- }
- else
- {
- DBUG_PRINT("info", ("Operation %d is a table scan.", m_tab_no));
- m_access_type= AT_TABLE_SCAN;
- }
- }
- break;
-
- default:
- /*
- Other join_types either cannot be pushed or the code analyze them is
- not yet in place.
- */
- DBUG_PRINT("info",
- ("Operation %d has join_type %d. -> Not pushable.",
- m_tab_no, join_tab->type));
- m_access_type= AT_OTHER;
- m_index_no= -1;
- m_other_access_reason = "This table access method can not be pushed.";
- break;
- }
- DBUG_VOID_RETURN;
- }
- // Table_access::compute_type_and_index()
-
-
- Table_access::Table_access()
- :m_join_plan(NULL),
- m_tab_no(0),
- m_access_type(AT_VOID),
- m_other_access_reason(NULL),
- m_index_no(-1)
- {}
-
- /**
- @return True iff ordered index access is *required* from this operation.
- */
- bool Table_access::is_fixed_ordered_index() const
- {
- const JOIN_TAB* const join_tab= get_join_tab();
-
- /* For the QUICK_SELECT_I classes we can disable ordered index usage by
- * setting 'QUICK_SELECT_I::sorted = false'.
- * However, QUICK_SELECT_I::QS_TYPE_RANGE_DESC is special as its
- * internal implementation requires its 'multi-ranges' to be retrieved
- * in (descending) sorted order from the underlying table.
- */
- if (join_tab->select != NULL &&
- join_tab->select->quick != NULL)
- {
- QUICK_SELECT_I *quick= join_tab->select->quick;
- return (quick->get_type() == QUICK_SELECT_I::QS_TYPE_RANGE_DESC);
- }
- return false;
- }
-
- /**
- Check if the results from this operation will joined with results
- from the next operation using a join buffer (instead of plain nested loop).
- @return True if using a join buffer.
- */
- bool Table_access::uses_join_cache() const
- {
- return get_join_tab()->next_select == sub_select_cache;
- }
-
-};
-// namespace AQP
=== removed file 'sql/abstract_query_plan.h'
--- a/sql/abstract_query_plan.h 2011-09-28 19:25:31 +0000
+++ b/sql/abstract_query_plan.h 1970-01-01 00:00:00 +0000
@@ -1,315 +0,0 @@
-/*
- Copyright 2010 Sun Microsystems, Inc.
- All rights reserved. Use is subject to license terms.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#ifndef ABSTRACT_QUERY_PLAN_H_INCLUDED
-#define ABSTRACT_QUERY_PLAN_H_INCLUDED
-
-struct TABLE;
-struct st_join_table;
-typedef st_join_table JOIN_TAB;
-class JOIN;
-class Item;
-class Item_field;
-class Item_equal_iterator;
-
-/**
- Abstract query plan (AQP) is an interface for examining certain aspects of
- query plans without accessing mysqld internal classes (JOIN_TAB, SQL_SELECT
- etc.) directly.
-
- AQP maps join execution plans, as represented by mysqld internals, to a set
- of facade classes. Non-join operations such as sorting and aggregation is
- currently *not* modelled in the AQP.
-
- The AQP models an n-way join as a sequence of the n table access operations
- that the MySQL server would execute as part of its nested loop join
- execution. (Each such table access operation is a scan of a table or index,
- or an index lookup.) For each lookup operation, it is possible to examine
- the expression that represents each field in the key.
-
- A storage enging will typically use the AQP for finding sections of a join
- execution plan that may be executed in the engine rather than in mysqld. By
- using the AQP rather than the mysqld internals directly, the coupling between
- the engine and mysqld is reduced.
-*/
-namespace AQP
-{
- class Table_access;
-
- /**
- This class represents a query plan for an n-way join, in the form a
- sequence of n table access operations that will execute as a nested loop
- join.
- */
- class Join_plan
- {
- friend class Equal_set_iterator;
- friend class Table_access;
- public:
-
- explicit Join_plan(const JOIN* join);
-
- ~Join_plan();
-
- const Table_access* get_table_access(uint access_no) const;
-
- uint get_access_count() const;
-
- /**
- Can filesort(), normally required by execution of GROUP BY
- or ORDER BY, be skipped due to the columns already being
- accessible in required sorted order.
- */
- bool group_by_filesort_is_skippable() const;
- bool order_by_filesort_is_skippable() const;
-
- private:
- /**
- Array of the JOIN_TABs that are the internal representation of table
- access operations.
- */
- const JOIN_TAB* const m_join_tabs;
-
- /** Number of table access operations. */
- const uint m_access_count;
- Table_access* m_table_accesses;
-
- mutable bool m_group_by_filesort_is_skippable;
- mutable bool m_order_by_filesort_is_skippable;
-
- void find_skippabable_group_or_order() const;
-
- const JOIN_TAB* get_join_tab(uint join_tab_no) const;
-
- // No copying.
- Join_plan(const Join_plan&);
- Join_plan& operator=(const Join_plan&);
- };
- // class Join_plan
-
-
- /**
- This class is an iterator for iterating over sets of fields (columns) that
- should have the same value. For example, if the query is
- SELECT * FROM T1, T2, T3 WHERE T1.b = T2.a AND T2.a = T3.a
- then there would be such a set of {T1.b, T2.a, T3.a}.
- */
- class Equal_set_iterator
- {
- public:
- explicit Equal_set_iterator(Item_equal& item_equal)
- : m_iterator(item_equal) {}
-
- const Item_field* next()
- { return m_iterator++; }
-
- private:
- /**
- This class is implemented in terms of this mysqld internal class.
- */
- Item_equal_iterator m_iterator;
-
- // No copying.
- Equal_set_iterator(const Equal_set_iterator&);
- Equal_set_iterator& operator=(const Equal_set_iterator&);
- };
- // class Equal_set_iterator
-
- /** The type of a table access operation. */
- enum enum_access_type
- {
- /** For default initialization.*/
- AT_VOID,
- /** Value has already been fetched / determined by optimizer.*/
- AT_FIXED,
- /** Do a lookup of a single primary key.*/
- AT_PRIMARY_KEY,
- /** Do a lookup of a single unique index key.*/
- AT_UNIQUE_KEY,
- /** Scan an ordered index with a single upper and lower bound pair.*/
- AT_ORDERED_INDEX_SCAN,
- /** Do a multi range read for a set of primary keys.*/
- AT_MULTI_PRIMARY_KEY,
- /** Do a multi range read for a set of unique index keys.*/
- AT_MULTI_UNIQUE_KEY,
- /**
- Do a multi range read for a mix of ranges (for which there is an
- ordered index), and either primary keys or unique index keys.
- */
- AT_MULTI_MIXED,
- /** Scan a table. (No index is assumed to be used.) */
- AT_TABLE_SCAN,
- /** Access method will not be chosen before the execution phase.*/
- AT_UNDECIDED,
- /**
- The access method has properties that prevents it from being pushed to a
- storage engine.
- */
- AT_OTHER
- };
-
- /** The type of join operation require */
- enum enum_join_type
- {
- JT_OUTER_JOIN,
- JT_INNER_JOIN,
- JT_SEMI_JOIN
- };
-
- /**
- This class represents an access operation on a table, such as a table
- scan, or a scan or lookup via an index. A Table_access object is always
- owned by a Join_plan object, such that the life time of the Table_access
- object ends when the life time of the owning Join_plan object ends.
- */
- class Table_access
- {
- friend class Join_plan;
- friend inline bool equal(const Table_access*, const Table_access*);
- public:
-
- const Join_plan* get_join_plan() const;
-
- enum_access_type get_access_type() const;
-
- const char* get_other_access_reason() const;
-
- enum_join_type get_join_type(const Table_access* parent) const;
-
- uint get_no_of_key_fields() const;
-
- const Item* get_key_field(uint field_no) const;
-
- const KEY_PART_INFO* get_key_part_info(uint field_no) const;
-
- uint get_access_no() const;
-
- int get_index_no() const;
-
- 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;
-
- bool uses_join_cache() const;
-
- private:
-
- /** Backref. to the Join_plan which this Table_access is part of */
- const Join_plan* m_join_plan;
-
- /** This operation corresponds to m_root_tab[m_tab_no].*/
- uint m_tab_no;
-
- /** The type of this operation.*/
- mutable enum_access_type m_access_type;
-
- /**
- The reason for getting m_access_type==AT_OTHER. Used for explain extended.
- */
- mutable const char* m_other_access_reason;
-
- /** The index to use for this operation (if applicable )*/
- mutable int m_index_no;
-
- explicit Table_access();
-
- const JOIN_TAB* get_join_tab() const;
-
- void compute_type_and_index() const;
-
- /** No copying*/
- Table_access(const Table_access&);
- Table_access& operator=(const Table_access&);
- };
- // class Table_access
-
- /**
- Get the n'th table access operation.
- @param access_no The index of the table access operation to fetch.
- @return The access_no'th table access operation.
- */
- inline const Table_access* Join_plan::get_table_access(uint access_no) const
- {
- DBUG_ASSERT(access_no < m_access_count);
- return m_table_accesses + access_no;
- }
-
- /**
- @return The number of table access operations in the nested loop join.
- */
- inline uint Join_plan::get_access_count() const
- {
- return m_access_count;
- }
-
- /** Get the Join_plan that this Table_access belongs to.*/
- inline const Join_plan* Table_access::get_join_plan() const
- {
- return m_join_plan;
- }
-
- /** Get the type of this operation.*/
- inline enum_access_type Table_access::get_access_type() const
- {
- if (m_access_type == AT_VOID)
- compute_type_and_index();
- return m_access_type;
- }
-
- /**
- Get a description of the reason for getting access_type==AT_OTHER. To be
- used for informational messages.
- @return A string that should be assumed to have the same life time as the
- Table_access object.
- */
- inline const char* Table_access::get_other_access_reason() const
- {
- if (m_access_type == AT_VOID)
- compute_type_and_index();
- return m_other_access_reason;
- }
-
- /**
- @return The number of the index to use for this access operation (
- or -1 for non-index operations).
- */
- inline int Table_access::get_index_no() const
- {
- if (m_access_type == AT_VOID)
- compute_type_and_index();
-
- return m_index_no;
- }
-
- /**
- Get the number of this Table_access within the enclosing Join_plan.
- (This number will be in the range 0 to Join_plan::get_access_count() - 1.)
- */
- inline uint Table_access::get_access_no() const
- {
- return m_tab_no;
- }
-
-};
-// namespace AQP
-
-#endif
=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc 2011-09-28 19:11:28 +0000
+++ b/sql/ha_ndbcluster.cc 2011-09-30 10:24:10 +0000
@@ -21,10 +21,6 @@
MySQL and NDB Cluster
*/
-#ifdef USE_PRAGMA_IMPLEMENTATION
-#pragma implementation // gcc: Class implementation
-#endif
-
#include "ha_ndbcluster_glue.h"
#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
@@ -45,7 +41,9 @@
#include "ndb_table_guard.h"
#include "ndb_global_schema_lock.h"
#include "ndb_global_schema_lock_guard.h"
+#ifndef NDB_WITHOUT_JOIN_PUSHDOWN
#include "abstract_query_plan.h"
+#endif
#include "ndb_dist_priv_util.h"
#include "ha_ndb_index_stat.h"
@@ -3139,7 +3137,7 @@ ha_ndbcluster::primary_key_is_clustered(
get_index_type_from_table(table->s->primary_key);
return (idx_type == PRIMARY_KEY_ORDERED_INDEX ||
idx_type == UNIQUE_ORDERED_INDEX ||
- idx_type == ORDERED_INDEX);
+ idx_type == ORDERED_INDEX);
}
bool ha_ndbcluster::check_index_fields_in_write_set(uint keyno)
@@ -3180,6 +3178,7 @@ int ha_ndbcluster::pk_read(const uchar *
NdbOperation::LockMode lm= get_ndb_lock_mode(m_lock.type);
+#ifndef NDB_WITHOUT_JOIN_PUSHDOWN
if (check_if_pushable(NdbQueryOperationDef::PrimaryKeyAccess, table->s->primary_key))
{
// Is parent of pushed join
@@ -3213,6 +3212,7 @@ int ha_ndbcluster::pk_read(const uchar *
}
}
else
+#endif
{
if (m_pushed_join_operation == PUSHED_ROOT)
{
@@ -3594,6 +3594,7 @@ int ha_ndbcluster::unique_index_read(con
NdbOperation::LockMode lm= get_ndb_lock_mode(m_lock.type);
+#ifndef NDB_WITHOUT_JOIN_PUSHDOWN
if (check_if_pushable(NdbQueryOperationDef::UniqueIndexAccess, active_index))
{
DBUG_ASSERT(lm == NdbOperation::LM_CommittedRead);
@@ -3624,6 +3625,7 @@ int ha_ndbcluster::unique_index_read(con
}
}
else
+#endif
{
if (m_pushed_join_operation == PUSHED_ROOT)
{
@@ -3984,6 +3986,7 @@ ha_ndbcluster::pk_unique_index_read_key(
extern void sql_print_information(const char *format, ...);
+#ifndef NDB_WITHOUT_JOIN_PUSHDOWN
static
bool
is_shrinked_varchar(const Field *field)
@@ -4063,8 +4066,9 @@ ha_ndbcluster::pk_unique_index_read_key_
const int ret= create_pushed_join(paramValues, key_def->key_parts);
DBUG_RETURN(ret);
-} // ha_ndbcluster::pk_unique_index_read_key_pushed
+}
+#endif
/** Count number of columns in key part. */
static uint
@@ -4226,6 +4230,7 @@ int ha_ndbcluster::ordered_index_scan(co
pbound = &bound;
}
+#ifndef NDB_WITHOUT_JOIN_PUSHDOWN
if (check_if_pushable(NdbQueryOperationDef::OrderedIndexScan, active_index,
sorted))
{
@@ -4254,7 +4259,8 @@ int ha_ndbcluster::ordered_index_scan(co
DBUG_ASSERT(!uses_blob_value(table->read_set)); // Can't have BLOB in pushed joins (yet)
}
- else // if (check_if_pushable(NdbQueryOperationDef::OrderedIndexScan))
+ else
+#endif
{
if (m_pushed_join_operation == PUSHED_ROOT)
{
@@ -4419,6 +4425,7 @@ int ha_ndbcluster::full_table_scan(const
if (table_share->primary_key == MAX_KEY)
get_hidden_fields_scan(&options, gets);
+#ifndef NDB_WITHOUT_JOIN_PUSHDOWN
if (check_if_pushable(NdbQueryOperationDef::TableScan))
{
const int error= create_pushed_join();
@@ -4428,7 +4435,8 @@ int ha_ndbcluster::full_table_scan(const
m_thd_ndb->m_scan_count++;
DBUG_ASSERT(!uses_blob_value(table->read_set)); // Can't have BLOB in pushed joins (yet)
}
- else // if (check_if_pushable(NdbQueryOperationDef::TableScan))
+ else
+#endif
{
if (m_pushed_join_operation == PUSHED_ROOT)
{
@@ -7215,6 +7223,7 @@ int ha_ndbcluster::reset()
{
m_cond->cond_clear();
}
+#ifndef NDB_WITHOUT_JOIN_PUSHDOWN
DBUG_ASSERT(m_active_query == NULL);
if (m_pushed_join_operation==PUSHED_ROOT) // Root of pushed query
{
@@ -7223,6 +7232,7 @@ int ha_ndbcluster::reset()
m_pushed_join_member= NULL;
m_pushed_join_operation= -1;
m_disable_pushed_join= FALSE;
+#endif
#if 0
// Magnus, disble this "hack" until it's possible to test if
@@ -10610,8 +10620,6 @@ ha_ndbcluster::~ha_ndbcluster()
release_blobs_buffer();
// Check for open cursor/transaction
- DBUG_ASSERT(m_active_cursor == NULL);
- DBUG_ASSERT(m_active_query == NULL);
DBUG_ASSERT(m_thd_ndb == NULL);
// Discard any generated condition
@@ -10622,12 +10630,15 @@ ha_ndbcluster::~ha_ndbcluster()
m_cond= NULL;
}
DBUG_PRINT("info", ("Deleting pushed joins"));
+#ifndef NDB_WITHOUT_JOIN_PUSHDOWN
DBUG_ASSERT(m_active_query == NULL);
+ DBUG_ASSERT(m_active_cursor == NULL);
if (m_pushed_join_operation==PUSHED_ROOT)
{
delete m_pushed_join_member; // Also delete QueryDef
}
m_pushed_join_member= NULL;
+#endif
DBUG_VOID_RETURN;
}
@@ -13783,6 +13794,7 @@ ha_ndbcluster::read_multi_range_first(KE
break;
}
+#ifndef NDB_WITHOUT_JOIN_PUSHDOWN
/* Create the scan operation for the first scan range. */
if (check_if_pushable(NdbQueryOperationDef::OrderedIndexScan,
active_index,
@@ -13799,9 +13811,10 @@ ha_ndbcluster::read_multi_range_first(KE
query->getQueryOperation((uint)PUSHED_ROOT)->setOrdering(NdbQueryOptions::ScanOrdering_ascending))
ERR_RETURN(query->getNdbError());
}
- } // check_if_pushable()
-
- else if (!m_multi_cursor)
+ }
+ else
+#endif
+ if (!m_multi_cursor)
{
if (m_pushed_join_operation == PUSHED_ROOT)
{
@@ -14353,7 +14366,7 @@ int ndbcluster_make_pushed_join(handlert
}
}
DBUG_RETURN(0);
-} // ndbcluster_make_pushed_join
+}
#endif
@@ -14382,7 +14395,7 @@ ha_ndbcluster::assign_pushed_join(const
pushed_join->get_operation_count()-1));
DBUG_RETURN(0);
-} // ha_ndbcluster::assign_pushed_join()
+}
/**
@@ -14425,7 +14438,7 @@ ha_ndbcluster::maybe_pushable_join(const
}
return true;
-} // ha_ndbcluster::is_pushable()
+}
/**
* Check if this table access operation (and a number of succeding operation)
@@ -14441,6 +14454,7 @@ ha_ndbcluster::maybe_pushable_join(const
* with sorted results.
* @return True if the operation may be pushed.
*/
+#ifndef NDB_WITHOUT_JOIN_PUSHDOWN
bool
ha_ndbcluster::check_if_pushable(int type, //NdbQueryOperationDef::Type,
uint idx,
@@ -14499,7 +14513,8 @@ ha_ndbcluster::create_pushed_join(const
m_thd_ndb->m_pushed_queries_executed++;
DBUG_RETURN(0);
-} // ha_ndbcluster::create_pushed_join
+}
+#endif
/**
=== modified file 'sql/ha_ndbcluster.h'
--- a/sql/ha_ndbcluster.h 2011-09-28 19:11:28 +0000
+++ b/sql/ha_ndbcluster.h 2011-09-30 10:24:10 +0000
@@ -21,10 +21,6 @@
*/
-#ifdef USE_PRAGMA_INTERFACE
-#pragma interface /* gcc class implementation */
-#endif
-
/* Blob tables and events are internal to NDB and must never be accessed */
#define IS_NDB_BLOB_PREFIX(A) is_prefix(A, "NDB$BLOB")
=== modified file 'sql/ha_ndbcluster_cond.cc'
--- a/sql/ha_ndbcluster_cond.cc 2011-09-07 10:08:09 +0000
+++ b/sql/ha_ndbcluster_cond.cc 2011-09-30 10:24:10 +0000
@@ -20,10 +20,6 @@
This file defines the NDB Cluster handler engine_condition_pushdown
*/
-#ifdef USE_PRAGMA_IMPLEMENTATION
-#pragma implementation // gcc: Class implementation
-#endif
-
#include "ha_ndbcluster_glue.h"
#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
=== modified file 'sql/ha_ndbcluster_cond.h'
--- a/sql/ha_ndbcluster_cond.h 2011-07-08 09:34:07 +0000
+++ b/sql/ha_ndbcluster_cond.h 2011-09-30 10:24:10 +0000
@@ -21,10 +21,6 @@
the NDB Cluster handler
*/
-#ifdef USE_PRAGMA_INTERFACE
-#pragma interface /* gcc class implementation */
-#endif
-
typedef enum ndb_item_type {
NDB_VALUE = 0, // Qualified more with Item::Type
NDB_FIELD = 1, // Qualified from table definition
=== modified file 'sql/ha_ndbcluster_connection.cc'
--- a/sql/ha_ndbcluster_connection.cc 2011-07-05 12:46:07 +0000
+++ b/sql/ha_ndbcluster_connection.cc 2011-09-30 10:24:10 +0000
@@ -16,10 +16,6 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifdef USE_PRAGMA_IMPLEMENTATION
-#pragma implementation // gcc: Class implementation
-#endif
-
#include "ha_ndbcluster_glue.h"
#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
=== modified file 'sql/ha_ndbcluster_push.cc'
--- a/sql/ha_ndbcluster_push.cc 2011-09-07 10:08:09 +0000
+++ b/sql/ha_ndbcluster_push.cc 2011-09-30 10:24:10 +0000
@@ -22,14 +22,9 @@
to the ndb data node (for execution by the SPJ block).
*/
-#ifdef USE_PRAGMA_IMPLEMENTATION
-#pragma implementation // gcc: Class implementation
-#endif
#include "ha_ndbcluster_glue.h"
-#include "rpl_mi.h"
-
#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
#include "ha_ndbcluster.h"
@@ -45,12 +40,6 @@
#include
-
-#ifdef ndb_dynamite
-#undef assert
-#define assert(x) do { if(x) break; ::printf("%s %d: assert failed: %s\n", __FILE__, __LINE__, #x); ::fflush(stdout); ::signal(SIGABRT,SIG_DFL); ::abort(); ::kill(::getpid(),6); ::kill(::getpid(),9); } while (0)
-#endif
-
#define EXPLAIN_NO_PUSH(msgfmt, ...) \
do \
{ \
=== modified file 'sql/ha_ndbcluster_push.h'
--- a/sql/ha_ndbcluster_push.h 2011-07-04 08:38:03 +0000
+++ b/sql/ha_ndbcluster_push.h 2011-09-30 10:24:10 +0000
@@ -15,10 +15,6 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#ifdef USE_PRAGMA_INTERFACE
-#pragma interface /* gcc class implementation */
-#endif
-
#include "sql_bitmap.h"
class NdbTransaction;
=== modified file 'storage/ndb/CMakeLists.txt'
--- a/storage/ndb/CMakeLists.txt 2011-09-28 19:36:09 +0000
+++ b/storage/ndb/CMakeLists.txt 2011-09-30 10:26:18 +0000
@@ -67,7 +67,6 @@ NDB_CHECK_MYSQL_CLUSTER(${VERSION})
SET(NDBCLUSTER_SOURCES
../../sql/ha_ndbcluster.cc
../../sql/ha_ndbcluster_cond.cc
- ../../sql/ha_ndbcluster_push.cc
../../sql/ha_ndbcluster_connection.cc
../../sql/ha_ndbcluster_binlog.cc
../../sql/ha_ndb_index_stat.cc
@@ -93,10 +92,6 @@ IF(NOT MYSQL_CLUSTER_VERSION)
# Pushdown of join queries not supported in non
# MySQL Cluster version yet, compile ndbcluster without it
ADD_DEFINITIONS(-DNDB_WITHOUT_JOIN_PUSHDOWN)
- # Since the MySQL Server has no AQP support, compile
- # that into ndbcluster instead
- SET(NDBCLUSTER_SOURCES ${NDBCLUSTER_SOURCES}
- ../../sql/abstract_query_plan.cc)
ENDIF()
# NDB is DEFAULT plugin in MySQL Cluster
No bundle (reason: useless for push emails).