summaryrefslogtreecommitdiff
path: root/sql/sql_select.cc
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2019-02-19 02:44:27 -0800
committerIgor Babaev <igor@askmonty.org>2019-02-19 02:45:24 -0800
commit8283d7d2c029cb520214ae7d33af8851acc80892 (patch)
tree9e805ca20f1913fa005a59db48aeeb7f02ad31fe /sql/sql_select.cc
parent7fe1ca7ed6ac5d28a51a08749c8cdc64495d6911 (diff)
downloadmariadb-git-8283d7d2c029cb520214ae7d33af8851acc80892.tar.gz
MDEV-7486: Condition pushdown from HAVING into WHERE
Optimized the code that removed multiple equalities pushed from HAVING into WHERE. Now this removal is postponed until all multiple equalities are eliminated in substitute_for_best_equal_field().
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r--sql/sql_select.cc23
1 files changed, 10 insertions, 13 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 3c108094b9e..ef712f76031 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -2285,7 +2285,8 @@ int JOIN::optimize_stage2()
DBUG_PRINT("error",("Error from substitute_for_best_equal"));
DBUG_RETURN(1);
}
- having->update_used_tables();
+ if (having)
+ having->update_used_tables();
DBUG_EXECUTE("having",
print_where(having,
"after substitute_best_equal",
@@ -5205,11 +5206,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
{
if (*s->on_expr_ref && s->cond_equal &&
s->cond_equal->upper_levels == orig_cond_equal)
- {
s->cond_equal->upper_levels= join->cond_equal;
- if (s->cond_equal->upper_levels)
- s->cond_equal->upper_levels->references++;
- }
}
}
}
@@ -14761,8 +14758,6 @@ COND *Item_func_eq::build_equal_items(THD *thd,
set_if_bigger(thd->lex->current_select->max_equal_elems,
item_equal->n_field_items());
item_equal->upper_levels= inherited;
- if (inherited)
- inherited->increase_references();
if (cond_equal_ref)
*cond_equal_ref= new (thd->mem_root) COND_EQUAL(item_equal,
thd->mem_root);
@@ -14797,8 +14792,6 @@ COND *Item_func_eq::build_equal_items(THD *thd,
and_cond->update_used_tables();
if (cond_equal_ref)
*cond_equal_ref= &and_cond->m_cond_equal;
- if (inherited)
- inherited->increase_references();
return and_cond;
}
}
@@ -14924,8 +14917,6 @@ static COND *build_equal_items(JOIN *join, COND *cond,
if (*cond_equal_ref)
{
(*cond_equal_ref)->upper_levels= inherited;
- if (inherited)
- inherited->increase_references();
inherited= *cond_equal_ref;
}
}
@@ -15161,7 +15152,7 @@ Item *eliminate_item_equal(THD *thd, COND *cond, COND_EQUAL *upper_levels,
((Item_func *) cond)->functype() == Item_func::EQ_FUNC) ||
(cond->type() == Item::COND_ITEM &&
((Item_func *) cond)->functype() == Item_func::COND_AND_FUNC));
-
+
/*
Pick the "head" item: the constant one or the first in the join order
(if the first in the join order happends to be inside an SJM nest, that's
@@ -15428,8 +15419,12 @@ static COND* substitute_for_best_equal_field(THD *thd, JOIN_TAB *context_tab,
COND *eq_cond= 0;
List_iterator_fast<Item_equal> it(cond_equal->current_level);
bool false_eq_cond= FALSE;
+ bool all_deleted= true;
while ((item_equal= it++))
{
+ if (item_equal->get_extraction_flag() == DELETION_FL)
+ continue;
+ all_deleted= false;
eq_cond= eliminate_item_equal(thd, eq_cond, cond_equal->upper_levels,
item_equal);
if (!eq_cond)
@@ -15468,7 +15463,7 @@ static COND* substitute_for_best_equal_field(THD *thd, JOIN_TAB *context_tab,
}
}
}
- if (!eq_cond)
+ if (!eq_cond && !all_deleted)
{
/*
We are out of memory doing the transformation.
@@ -15487,6 +15482,8 @@ static COND* substitute_for_best_equal_field(THD *thd, JOIN_TAB *context_tab,
cond_equal= item_equal->upper_levels;
if (cond_equal && cond_equal->current_level.head() == item_equal)
cond_equal= cond_equal->upper_levels;
+ if (item_equal->get_extraction_flag() == DELETION_FL)
+ return 0;
cond= eliminate_item_equal(thd, 0, cond_equal, item_equal);
return cond ? cond : org_cond;
}