#At file:///export/home/jl208045/mysql/mysql-trunk-59415/ based on revid:dmitry.lenev@stripped
3653 Jorgen Loland 2011-02-15
BUG#11766327: Range analysis should not be done many times
for the same index
(formerly 59415)
Pre-bugfix change:
* Make JOIN_TAB::select_cond private, add getter
* Make use of extend_select_cond() where possible to
simplify code
@ sql/sql_select.cc
Make JOIN_TAB::select_cond private, make use of extend_select_cond() where possible
@ sql/sql_select.h
Make JOIN_TAB::select_cond private, make use of extend_select_cond() where possible
@ sql/sql_show.cc
Make JOIN_TAB::select_cond private
modified:
sql/sql_select.cc
sql/sql_select.h
sql/sql_show.cc
=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc 2011-02-10 09:30:20 +0000
+++ b/sql/sql_select.cc 2011-02-15 15:02:30 +0000
@@ -3219,7 +3219,7 @@ JOIN::exec()
curr_table->select->cond->fix_fields(thd, 0);
}
curr_table->set_select_cond(curr_table->select->cond, __LINE__);
- curr_table->select_cond->top_level_item();
+ curr_table->get_select_cond()->top_level_item();
DBUG_EXECUTE("where",print_where(curr_table->select->cond,
"select and having",
QT_ORDINARY););
@@ -3274,7 +3274,7 @@ JOIN::exec()
table->keyuse is set in the case there was an original WHERE clause
on the table that was optimized away.
*/
- if (curr_table->select_cond ||
+ if (curr_table->get_select_cond() ||
(curr_table->keyuse && !curr_table->first_inner))
{
/* We have to sort all rows */
@@ -9301,9 +9301,7 @@ static void add_not_null_conds(JOIN *joi
DBUG_EXECUTE("where",print_where(notnull,
referred_tab->table->alias,
QT_ORDINARY););
- Item *new_cond= referred_tab->select_cond;
- add_cond_and_fix(&new_cond, notnull);
- referred_tab->set_select_cond(new_cond, __LINE__);
+ referred_tab->extend_select_cond(notnull);
}
}
}
@@ -9440,24 +9438,6 @@ make_outerjoin_info(JOIN *join)
DBUG_VOID_RETURN;
}
-static bool extend_select_cond(JOIN_TAB *cond_tab, Item *tmp_cond)
-{
- DBUG_ENTER("extend_select_cond");
-
- Item *new_cond= !cond_tab->select_cond ? tmp_cond :
- new Item_cond_and(cond_tab->select_cond, tmp_cond);
- cond_tab->set_select_cond(new_cond, __LINE__);
- if (!cond_tab->select_cond)
- DBUG_RETURN(1);
- cond_tab->select_cond->update_used_tables();
- cond_tab->select_cond->quick_fix_field();
- if (cond_tab->select)
- cond_tab->select->cond= cond_tab->select_cond;
-
- DBUG_RETURN(0);
-}
-
-
/**
Local helper function for make_join_select().
@@ -9489,7 +9469,7 @@ static bool pushdown_on_conditions(JOIN*
DBUG_RETURN(1);
tmp_cond->quick_fix_field();
- if (extend_select_cond(cond_tab, tmp_cond))
+ if (cond_tab->extend_cond(tmp_cond))
DBUG_RETURN(1);
}
}
@@ -9536,7 +9516,7 @@ static bool pushdown_on_conditions(JOIN*
tmp_cond->quick_fix_field();
/* Add the predicate to other pushed down predicates */
- if (extend_select_cond(cond_tab, tmp_cond))
+ if (cond_tab->extend_cond(tmp_cond))
DBUG_RETURN(1);
}
first_inner_tab= first_inner_tab->first_upper;
@@ -9597,7 +9577,7 @@ static bool make_join_select(JOIN *join,
(table_map) 0, 1);
/* Add conditions added by add_not_null_conds(). */
for (uint i= 0 ; i < join->const_tables ; i++)
- add_cond_and_fix(&const_cond, join->join_tab[i].select_cond);
+ add_cond_and_fix(&const_cond, join->join_tab[i].get_select_cond());
DBUG_EXECUTE("where",print_where(const_cond,"constants", QT_ORDINARY););
for (JOIN_TAB *tab= join->join_tab+join->const_tables;
@@ -9615,12 +9595,9 @@ static bool make_join_select(JOIN *join,
if (!tmp)
DBUG_RETURN(1);
tmp->quick_fix_field();
- Item *new_cond= !cond_tab->select_cond ? tmp :
- new Item_cond_and(cond_tab->select_cond, tmp);
- cond_tab->set_select_cond(new_cond, __LINE__);
- if (!cond_tab->select_cond)
- DBUG_RETURN(1);
- cond_tab->select_cond->quick_fix_field();
+
+ if (cond_tab->extend_select_cond(tmp))
+ DBUG_RETURN(1);
}
}
if (const_cond && !const_cond->val_int())
@@ -9695,8 +9672,8 @@ static bool make_join_select(JOIN *join,
if (cond)
tmp= make_cond_for_table(cond,used_tables,current_map, 0);
/* Add conditions added by add_not_null_conds(). */
- if (tab->select_cond)
- add_cond_and_fix(&tmp, tab->select_cond);
+ if (tab->get_select_cond())
+ add_cond_and_fix(&tmp, tab->get_select_cond());
if (cond && !tmp && tab->quick)
{ // Outer join
@@ -10242,22 +10219,22 @@ static void push_index_cond(JOIN_TAB *ta
when doing the update part and result in either not finding
the record to update or updating the wrong record.
*/
- if (tab->select_cond &&
+ if (tab->get_select_cond() &&
tab->table->file->index_flags(keyno, 0, 1) &
HA_DO_INDEX_COND_PUSHDOWN &&
tab->join->thd->optimizer_switch_flag(OPTIMIZER_SWITCH_INDEX_CONDITION_PUSHDOWN) &&
tab->join->thd->lex->sql_command != SQLCOM_UPDATE_MULTI &&
tab->join->thd->lex->sql_command != SQLCOM_DELETE_MULTI)
{
- DBUG_EXECUTE("where", print_where(tab->select_cond, "full cond",
+ DBUG_EXECUTE("where", print_where(tab->get_select_cond(), "full cond",
QT_ORDINARY););
- Item *idx_cond= make_cond_for_index(tab->select_cond, tab->table, keyno,
- other_tbls_ok);
+ Item *idx_cond= make_cond_for_index(tab->get_select_cond(), tab->table,
+ keyno, other_tbls_ok);
DBUG_EXECUTE("where", print_where(idx_cond, "idx cond", QT_ORDINARY););
if (idx_cond)
{
Item *idx_remainder_cond= 0;
- tab->pre_idx_push_select_cond= tab->select_cond;
+ tab->pre_idx_push_select_cond= tab->get_select_cond();
/*
For BKA cache we store condition to special BKA cache field
@@ -10295,7 +10272,7 @@ static void push_index_cond(JOIN_TAB *ta
if (idx_remainder_cond != idx_cond)
tab->ref.disable_cache= TRUE;
- Item *row_cond= make_cond_remainder(tab->select_cond, TRUE);
+ Item *row_cond= make_cond_remainder(tab->get_select_cond(), TRUE);
DBUG_EXECUTE("where", print_where(row_cond, "remainder cond",
QT_ORDINARY););
@@ -10307,8 +10284,8 @@ static void push_index_cond(JOIN_TAB *ta
{
Item *new_cond= new Item_cond_and(row_cond, idx_remainder_cond);
tab->set_select_cond(new_cond, __LINE__);
- tab->select_cond->quick_fix_field();
- ((Item_cond_and*)tab->select_cond)->used_tables_cache=
+ tab->get_select_cond()->quick_fix_field();
+ ((Item_cond_and*)tab->get_select_cond())->used_tables_cache=
row_cond->used_tables() | idx_remainder_cond->used_tables();
}
}
@@ -10318,7 +10295,7 @@ static void push_index_cond(JOIN_TAB *ta
{
DBUG_EXECUTE("where", print_where(tab->select->cond, "select_cond",
QT_ORDINARY););
- tab->select->cond= tab->select_cond;
+ tab->select->cond= tab->get_select_cond();
}
}
}
@@ -10819,19 +10796,19 @@ static bool is_cond_sj_in_equality(Item
}
-void remove_sj_conds(Item **tree)
+void remove_sj_conds(Item *cond)
{
- if (*tree)
+ if (cond)
{
- if (is_cond_sj_in_equality(*tree))
+ if (is_cond_sj_in_equality(cond))
{
- *tree= NULL;
+ cond= NULL;
return;
}
- else if ((*tree)->type() == Item::COND_ITEM)
+ else if (cond->type() == Item::COND_ITEM)
{
Item *item;
- List_iterator<Item> li(*(((Item_cond*)*tree)->argument_list()));
+ List_iterator<Item> li(*(((Item_cond*)cond)->argument_list()));
while ((item= li++))
{
if (is_cond_sj_in_equality(item))
@@ -11000,9 +10977,9 @@ bool setup_sj_materialization(JOIN_TAB *
*/
for (i= 0; i < sjm->table_count; i++)
{
- remove_sj_conds(&tab[i].select_cond);
+ remove_sj_conds(tab[i].get_select_cond());
if (tab[i].select)
- remove_sj_conds(&tab[i].select->cond);
+ remove_sj_conds(tab[i].select->cond);
}
if (!(sjm->in_equality= create_subquery_equalities(thd, emb_sj_nest)))
DBUG_RETURN(TRUE); /* purecov: inspected */
@@ -11388,6 +11365,57 @@ uint JOIN_TAB::get_sj_strategy() const
return s;
}
+/**
+ Extend JOIN_TAB->select_cond and JOIN_TAB->select->cond by AND'ing
+ add_cond to them
+
+ @param add_cond The condition to AND with the existing conditions
+
+ @return
+ true if there was an error, in which case the conditions remain
+ unchanged
+ false otherwise
+*/
+bool JOIN_TAB::extend_cond(Item *tmp_cond)
+{
+ if (extend_select_cond(tmp_cond))
+ return true;
+ if (select)
+ select->cond= select_cond;
+ return false;
+}
+
+/**
+ Extend JOIN_TAB->select_cond by AND'ing add_cond to it
+
+ @param add_cond The condition to AND with the existing select_cond
+ for this JOIN_TAB
+ @return
+ true if there was an error, in which case JOIN_TAB::select_cond remains
+ unchanged
+ false otherwise
+*/
+bool JOIN_TAB::extend_select_cond(Item *add_cond)
+{
+ DBUG_ENTER("JOIN_TAB::extend_select_cond");
+
+ Item *new_cond= select_cond ?
+ new Item_cond_and(select_cond, add_cond) :
+ add_cond;
+
+ if (!new_cond)
+ DBUG_RETURN(true);
+
+ set_select_cond(new_cond, __LINE__);
+
+ select_cond->update_used_tables();
+ select_cond->quick_fix_field();
+
+ DBUG_RETURN(false);
+}
+
+
+
/**
Partially cleanup JOIN after it has executed: close index or rnd read
@@ -17183,7 +17211,7 @@ sub_select_sjm(JOIN *join, JOIN_TAB *joi
/* Do full scan of the materialized table */
JOIN_TAB *last_tab= join_tab + (sjm->table_count - 1);
- Item *save_cond= last_tab->select_cond;
+ Item *save_cond= last_tab->get_select_cond();
last_tab->set_select_cond(sjm->join_cond, __LINE__);
rc= sub_select(join, last_tab, end_of_records);
last_tab->set_select_cond(save_cond, __LINE__);
@@ -17613,7 +17641,7 @@ evaluate_join_record(JOIN *join, JOIN_TA
{
bool not_used_in_distinct=join_tab->not_used_in_distinct;
ha_rows found_records=join->found_records;
- Item *select_cond= join_tab->select_cond;
+ Item *select_cond= join_tab->get_select_cond();
bool found= TRUE;
DBUG_ENTER("evaluate_join_record");
@@ -17678,9 +17706,9 @@ evaluate_join_record(JOIN *join, JOIN_TA
the 'not_exists_optimize'.
*/
DBUG_ASSERT(!(tab->table->reginfo.not_exists_optimize &&
- !tab->select_cond));
+ !tab->get_select_cond()));
- if (tab->select_cond && !tab->select_cond->val_int())
+ if (tab->get_select_cond() && !tab->get_select_cond()->val_int())
{
/* The condition attached to table tab is false */
@@ -17857,7 +17885,7 @@ evaluate_null_complemented_join_record(J
/* The outer row is complemented by nulls for each inner tables */
restore_record(join_tab->table,s->default_values); // Make empty record
mark_as_null_row(join_tab->table); // For group by without error
- select_cond= join_tab->select_cond;
+ select_cond= join_tab->get_select_cond();
/* Check all attached conditions for inner table rows. */
if (select_cond && !select_cond->val_int())
DBUG_RETURN(NESTED_LOOP_OK);
@@ -18581,8 +18609,8 @@ end_send(JOIN *join, JOIN_TAB *join_tab
{
JOIN_TAB *jt=join->join_tab;
if ((join->tables == 1) && !join->tmp_table && !join->sort_and_group
- && !join->send_group_parts && !join->having && !jt->select_cond &&
- !(jt->select && jt->select->quick) &&
+ && !join->send_group_parts && !join->having &&
+ !jt->get_select_cond() && !(jt->select && jt->select->quick) &&
(jt->table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) &&
(jt->ref.key < 0))
{
=== modified file 'sql/sql_select.h'
--- a/sql/sql_select.h 2011-02-08 15:49:51 +0000
+++ b/sql/sql_select.h 2011-02-15 15:02:30 +0000
@@ -237,7 +237,9 @@ typedef struct st_join_table : public Sq
TABLE *table;
Key_use *keyuse; /**< pointer to first used key */
SQL_SELECT *select;
+private:
Item *select_cond;
+public:
QUICK_SELECT_I *quick;
Item **on_expr_ref; /**< pointer to the associated on expression */
COND_EQUAL *cond_equal; /**< multiple equalities for the on expression */
@@ -422,6 +424,10 @@ typedef struct st_join_table : public Sq
select_cond, to, line, this));
select_cond= to;
}
+ Item *get_select_cond()
+ {
+ return select_cond;
+ }
Item *set_cond(Item *new_cond, uint line)
{
Item *tmp_select_cond= select_cond;
@@ -431,6 +437,8 @@ typedef struct st_join_table : public Sq
return tmp_select_cond;
}
uint get_sj_strategy() const;
+ bool extend_select_cond(Item *tmp_cond);
+ bool extend_cond(Item *tmp_cond);
} JOIN_TAB;
=== modified file 'sql/sql_show.cc'
--- a/sql/sql_show.cc 2011-02-08 15:54:12 +0000
+++ b/sql/sql_show.cc 2011-02-15 15:02:30 +0000
@@ -6739,7 +6739,7 @@ bool get_schema_tables_result(JOIN *join
table_list->table->file->stats.records= 0;
if (table_list->schema_table->fill_table(thd, table_list,
- tab->select_cond))
+ tab->get_select_cond()))
{
result= 1;
join->error= 1;
Attachment: [text/bzr-bundle] bzr/jorgen.loland@oracle.com-20110215150230-c9fvagc4u5incx9f.bundle
| Thread |
|---|
| • bzr commit into mysql-trunk branch (jorgen.loland:3653) Bug#11766327 | Jorgen Loland | 15 Feb |