summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2016-09-14 01:06:45 -0700
committerIgor Babaev <igor@askmonty.org>2016-09-14 01:06:45 -0700
commitc22d307afa1a6accbfe9857256cad01c1eacd677 (patch)
tree2a78540435691e50fc50fa1d625f30fea3197e28 /sql
parent61d46e0423c61ff2fd1eedd707924193006cdedd (diff)
downloadmariadb-git-c22d307afa1a6accbfe9857256cad01c1eacd677.tar.gz
Fixed bug mdev-10785.
The condition pushed into WHERE/HAVING of a materialized view/derived table may differ for different executions of the same prepared statement. That's why the should be ANDed with the existing WHERE/HAVING conditions only after all permanent transformations of these conditions has been performed.
Diffstat (limited to 'sql')
-rw-r--r--sql/sql_derived.cc38
-rw-r--r--sql/sql_lex.cc1
-rw-r--r--sql/sql_lex.h2
-rw-r--r--sql/sql_select.cc18
4 files changed, 27 insertions, 32 deletions
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index a7435117e69..677a4c4d91a 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -1145,7 +1145,7 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived)
return false;
/* Do not push conditions into constant derived */
- if (derived->fill_me)
+ if (unit->executed)
return false;
/* Do not push conditions into recursive with tables */
@@ -1191,18 +1191,8 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived)
(uchar*) sl);
if (extracted_cond_copy)
{
- /*
- Create the conjunction of the existing where condition of sl
- and the pushed condition, take it as the new where condition of sl
- and fix this new condition
- */
- extracted_cond_copy->walk(&Item::cleanup_processor, 0, 0);
- thd->change_item_tree(&sl->join->conds,
- and_conds(thd, sl->join->conds,
- extracted_cond_copy));
-
- if (sl->join->conds->fix_fields(thd, &sl->join->conds))
- goto err;
+ extracted_cond_copy->walk(&Item::cleanup_processor, 0, 0);
+ sl->cond_pushed_into_where= extracted_cond_copy;
}
continue;
@@ -1236,19 +1226,9 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived)
*/
extracted_cond_copy= remove_pushed_top_conjuncts(thd, extracted_cond_copy);
- /*
- Create the conjunction of the existing where condition of sl
- and the pushed condition, take it as the new where condition of sl
- and fix this new condition
- */
cond_over_grouping_fields->walk(&Item::cleanup_processor, 0, 0);
- thd->change_item_tree(&sl->join->conds,
- and_conds(thd, sl->join->conds,
- cond_over_grouping_fields));
-
- if (sl->join->conds->fix_fields(thd, &sl->join->conds))
- goto err;
-
+ sl->cond_pushed_into_where= cond_over_grouping_fields;
+
if (!extracted_cond_copy)
continue;
}
@@ -1268,13 +1248,7 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived)
and fix this new condition
*/
extracted_cond_copy->walk(&Item::cleanup_processor, 0, 0);
- thd->change_item_tree(&sl->join->having,
- and_conds(thd, sl->join->having,
- extracted_cond_copy));
- sl->having_fix_field= 1;
- if (sl->join->having->fix_fields(thd, &sl->join->having))
- return true;
- sl->having_fix_field= 0;
+ sl->cond_pushed_into_having= extracted_cond_copy;
}
thd->lex->current_select= save_curr_select;
return false;
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 5c2b004a471..592de98ca0f 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -2093,6 +2093,7 @@ void st_select_lex::init_query()
item_list.empty();
join= 0;
having= prep_having= where= prep_where= 0;
+ cond_pushed_into_where= cond_pushed_into_having= 0;
olap= UNSPECIFIED_OLAP_TYPE;
having_fix_field= 0;
context.select_lex= this;
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 881116192fd..e499cc794a1 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -765,6 +765,8 @@ public:
Item *where, *having; /* WHERE & HAVING clauses */
Item *prep_where; /* saved WHERE clause for prepared statement processing */
Item *prep_having;/* saved HAVING clause for prepared statement processing */
+ Item *cond_pushed_into_where; /* condition pushed into the select's WHERE */
+ Item *cond_pushed_into_having; /* condition pushed into the select's HAVING */
/* Saved values of the WHERE and HAVING clauses*/
Item::cond_result cond_value, having_value;
/* point on lex in which it was created, used in view subquery detection */
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 49bc6199d4b..aa08420931f 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1248,6 +1248,24 @@ JOIN::optimize_inner()
if (setup_jtbm_semi_joins(this, join_list, &conds))
DBUG_RETURN(1);
+
+ if (select_lex->cond_pushed_into_where)
+ {
+ conds= and_conds(thd, conds, select_lex->cond_pushed_into_where);
+ if (conds && conds->fix_fields(thd, &conds))
+ DBUG_RETURN(1);
+ }
+ if (select_lex->cond_pushed_into_having)
+ {
+ having= and_conds(thd, having, select_lex->cond_pushed_into_having);
+ if (having)
+ {
+ select_lex->having_fix_field= 1;
+ if (having->fix_fields(thd, &having))
+ DBUG_RETURN(1);
+ select_lex->having_fix_field= 0;
+ }
+ }
conds= optimize_cond(this, conds, join_list, FALSE,
&cond_value, &cond_equal, OPT_LINK_EQUAL_FIELDS);