Commit 915a8ae4 authored by Igor Babaev's avatar Igor Babaev

Fixed bug mdev-4349.

Range analysis of the condition for a non-indexed column may
return an impossible range. This must be taken into account.
parent 70badba5
...@@ -675,4 +675,44 @@ DROP VIEW v1; ...@@ -675,4 +675,44 @@ DROP VIEW v1;
DROP TABLE t1,t2; DROP TABLE t1,t2;
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
set use_stat_tables=@tmp_use_stat_tables; set use_stat_tables=@tmp_use_stat_tables;
#
# Bug mdev-4349: impossible range for non-indexed column
#
set optimizer_use_condition_selectivity=3;
create table t1 (a int);
insert into t1 values
(3), (7), (2), (5), (7), (1), (2), (2);
set optimizer_use_condition_selectivity=1;
explain extended
select * from t1 where a < 1 and a > 7;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 8 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` < 1) and (`test`.`t1`.`a` > 7))
select * from t1 where a < 1 and a > 7;
a
set optimizer_use_condition_selectivity=3;
explain extended
select * from t1 where a < 1 and a > 7;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where 0
select * from t1 where a < 1 and a > 7;
a
drop table t1;
create table t1 (a int);
insert into t1 values (1);
create table t2 (b int);
insert into t2 values (2),(3);
explain extended
select * from t1 where a in ( select b from t2 ) AND ( a > 3 );
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings:
Note 1003 select 1 AS `a` from (`test`.`t2`) where 0
select * from t1 where a in ( select b from t2 ) AND ( a > 3 );
a
drop table t1,t2;
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
set use_stat_tables=@save_use_stat_tables; set use_stat_tables=@save_use_stat_tables;
...@@ -681,6 +681,47 @@ DROP VIEW v1; ...@@ -681,6 +681,47 @@ DROP VIEW v1;
DROP TABLE t1,t2; DROP TABLE t1,t2;
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
set use_stat_tables=@tmp_use_stat_tables; set use_stat_tables=@tmp_use_stat_tables;
#
# Bug mdev-4349: impossible range for non-indexed column
#
set optimizer_use_condition_selectivity=3;
create table t1 (a int);
insert into t1 values
(3), (7), (2), (5), (7), (1), (2), (2);
set optimizer_use_condition_selectivity=1;
explain extended
select * from t1 where a < 1 and a > 7;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 8 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` < 1) and (`test`.`t1`.`a` > 7))
select * from t1 where a < 1 and a > 7;
a
set optimizer_use_condition_selectivity=3;
explain extended
select * from t1 where a < 1 and a > 7;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where 0
select * from t1 where a < 1 and a > 7;
a
drop table t1;
create table t1 (a int);
insert into t1 values (1);
create table t2 (b int);
insert into t2 values (2),(3);
explain extended
select * from t1 where a in ( select b from t2 ) AND ( a > 3 );
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 1 0.00 Using where
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 0 Using where; FirstMatch(t1); Using join buffer (flat, BNL join)
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t2`.`b` = `test`.`t1`.`a`) and (`test`.`t1`.`a` > 3))
select * from t1 where a in ( select b from t2 ) AND ( a > 3 );
a
drop table t1,t2;
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
set use_stat_tables=@save_use_stat_tables; set use_stat_tables=@save_use_stat_tables;
set optimizer_switch=@save_optimizer_switch_for_selectivity_test; set optimizer_switch=@save_optimizer_switch_for_selectivity_test;
SET SESSION STORAGE_ENGINE=DEFAULT; SET SESSION STORAGE_ENGINE=DEFAULT;
...@@ -267,5 +267,40 @@ DROP TABLE t1,t2; ...@@ -267,5 +267,40 @@ DROP TABLE t1,t2;
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
set use_stat_tables=@tmp_use_stat_tables; set use_stat_tables=@tmp_use_stat_tables;
--echo #
--echo # Bug mdev-4349: impossible range for non-indexed column
--echo #
set optimizer_use_condition_selectivity=3;
create table t1 (a int);
insert into t1 values
(3), (7), (2), (5), (7), (1), (2), (2);
set optimizer_use_condition_selectivity=1;
explain extended
select * from t1 where a < 1 and a > 7;
select * from t1 where a < 1 and a > 7;
set optimizer_use_condition_selectivity=3;
explain extended
select * from t1 where a < 1 and a > 7;
select * from t1 where a < 1 and a > 7;
drop table t1;
create table t1 (a int);
insert into t1 values (1);
create table t2 (b int);
insert into t2 values (2),(3);
explain extended
select * from t1 where a in ( select b from t2 ) AND ( a > 3 );
select * from t1 where a in ( select b from t2 ) AND ( a > 3 );
drop table t1,t2;
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
set use_stat_tables=@save_use_stat_tables; set use_stat_tables=@save_use_stat_tables;
...@@ -3325,7 +3325,8 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item *cond) ...@@ -3325,7 +3325,8 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item *cond)
table->cond_selectivity= 1.0; table->cond_selectivity= 1.0;
if (!bitmap_is_clear_all(used_fields)) if (thd->variables.optimizer_use_condition_selectivity > 2 &&
!bitmap_is_clear_all(used_fields))
{ {
PARAM param; PARAM param;
MEM_ROOT alloc; MEM_ROOT alloc;
...@@ -3362,9 +3363,25 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item *cond) ...@@ -3362,9 +3363,25 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item *cond)
double rows; double rows;
if (*key) if (*key)
{ {
#if 0
rows= records_in_column_ranges(&param, idx, *key); rows= records_in_column_ranges(&param, idx, *key);
if (rows != HA_POS_ERROR) if (rows != HA_POS_ERROR)
(*key)->field->cond_selectivity= rows/table_records; (*key)->field->cond_selectivity= rows/table_records;
#else
table->reginfo.impossible_range= 0;
if ((*key)->type == SEL_ARG::IMPOSSIBLE)
{
rows= 0;
table->reginfo.impossible_range= 1;
goto free_alloc;
}
else
{
rows= records_in_column_ranges(&param, idx, *key);
if (rows != HA_POS_ERROR)
(*key)->field->cond_selectivity= rows/table_records;
}
#endif
} }
} }
......
...@@ -3794,6 +3794,8 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list, ...@@ -3794,6 +3794,8 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
all select distinct fields participate in one index. all select distinct fields participate in one index.
*/ */
add_group_and_distinct_keys(join, s); add_group_and_distinct_keys(join, s);
table->cond_selectivity= 1.0;
/* /*
Perform range analysis if there are keys it could use (1). Perform range analysis if there are keys it could use (1).
...@@ -3802,7 +3804,8 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list, ...@@ -3802,7 +3804,8 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
Don't do range analysis for materialized subqueries (4). Don't do range analysis for materialized subqueries (4).
Don't do range analysis for materialized derived tables (5) Don't do range analysis for materialized derived tables (5)
*/ */
if (!s->const_keys.is_clear_all() && // (1) if ((!s->const_keys.is_clear_all() ||
!bitmap_is_clear_all(&s->table->cond_set)) && // (1)
(!s->table->pos_in_table_list->embedding || // (2) (!s->table->pos_in_table_list->embedding || // (2)
(s->table->pos_in_table_list->embedding && // (3) (s->table->pos_in_table_list->embedding && // (3)
s->table->pos_in_table_list->embedding->sj_on_expr)) && // (3) s->table->pos_in_table_list->embedding->sj_on_expr)) && // (3)
...@@ -3810,20 +3813,37 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list, ...@@ -3810,20 +3813,37 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
!(s->table->pos_in_table_list->derived && // (5) !(s->table->pos_in_table_list->derived && // (5)
s->table->pos_in_table_list->is_materialized_derived())) // (5) s->table->pos_in_table_list->is_materialized_derived())) // (5)
{ {
ha_rows records; bool impossible_range= FALSE;
SQL_SELECT *select; ha_rows records= HA_POS_ERROR;
select= make_select(s->table, found_const_table_map, SQL_SELECT *select= 0;
found_const_table_map, if (!s->const_keys.is_clear_all())
*s->on_expr_ref ? *s->on_expr_ref : conds, {
1, &error); select= make_select(s->table, found_const_table_map,
if (!select) found_const_table_map,
goto error; *s->on_expr_ref ? *s->on_expr_ref : conds,
records= get_quick_record_count(join->thd, select, s->table, 1, &error);
&s->const_keys, join->row_limit); if (!select)
s->quick=select->quick; goto error;
s->needed_reg=select->needed_reg; records= get_quick_record_count(join->thd, select, s->table,
select->quick=0; &s->const_keys, join->row_limit);
if (records == 0 && s->table->reginfo.impossible_range) s->quick=select->quick;
s->needed_reg=select->needed_reg;
select->quick=0;
impossible_range= records == 0 && s->table->reginfo.impossible_range;
}
if (!impossible_range)
{
if (join->thd->variables.optimizer_use_condition_selectivity > 1)
calculate_cond_selectivity_for_table(join->thd, s->table,
*s->on_expr_ref ?
*s->on_expr_ref : conds);
if (s->table->reginfo.impossible_range)
{
impossible_range= TRUE;
records= 0;
}
}
if (impossible_range)
{ {
/* /*
Impossible WHERE or ON expression Impossible WHERE or ON expression
...@@ -3848,13 +3868,10 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list, ...@@ -3848,13 +3868,10 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
s->found_records=records; s->found_records=records;
s->read_time= s->quick ? s->quick->read_time : 0.0; s->read_time= s->quick ? s->quick->read_time : 0.0;
} }
delete select; if (select)
delete select;
} }
if (join->thd->variables.optimizer_use_condition_selectivity > 1)
calculate_cond_selectivity_for_table(join->thd, s->table,
*s->on_expr_ref ?
*s->on_expr_ref : conds);
} }
if (pull_out_semijoin_tables(join)) if (pull_out_semijoin_tables(join))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment