summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/selectivity.result40
-rw-r--r--mysql-test/r/selectivity_innodb.result41
-rw-r--r--mysql-test/t/selectivity.test35
-rw-r--r--sql/opt_range.cc19
-rw-r--r--sql/sql_select.cc57
5 files changed, 171 insertions, 21 deletions
diff --git a/mysql-test/r/selectivity.result b/mysql-test/r/selectivity.result
index b1328fddb3a..28a38c11b01 100644
--- a/mysql-test/r/selectivity.result
+++ b/mysql-test/r/selectivity.result
@@ -675,4 +675,44 @@ DROP VIEW v1;
DROP TABLE t1,t2;
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
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;
diff --git a/mysql-test/r/selectivity_innodb.result b/mysql-test/r/selectivity_innodb.result
index 8a620de68e8..02f58dbfebe 100644
--- a/mysql-test/r/selectivity_innodb.result
+++ b/mysql-test/r/selectivity_innodb.result
@@ -681,6 +681,47 @@ DROP VIEW v1;
DROP TABLE t1,t2;
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
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 optimizer_switch=@save_optimizer_switch_for_selectivity_test;
SET SESSION STORAGE_ENGINE=DEFAULT;
diff --git a/mysql-test/t/selectivity.test b/mysql-test/t/selectivity.test
index 88bc0683f33..15cb886dc8b 100644
--- a/mysql-test/t/selectivity.test
+++ b/mysql-test/t/selectivity.test
@@ -267,5 +267,40 @@ DROP TABLE t1,t2;
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
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;
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index fee401d7aac..44c5f619f37 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -3325,7 +3325,8 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item *cond)
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;
MEM_ROOT alloc;
@@ -3362,9 +3363,25 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item *cond)
double rows;
if (*key)
{
+#if 0
rows= records_in_column_ranges(&param, idx, *key);
if (rows != HA_POS_ERROR)
(*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
}
}
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index f943b9b20d6..c5671544972 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -3794,6 +3794,8 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
all select distinct fields participate in one index.
*/
add_group_and_distinct_keys(join, s);
+
+ table->cond_selectivity= 1.0;
/*
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,
Don't do range analysis for materialized subqueries (4).
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 && // (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,
!(s->table->pos_in_table_list->derived && // (5)
s->table->pos_in_table_list->is_materialized_derived())) // (5)
{
- ha_rows records;
- SQL_SELECT *select;
- select= make_select(s->table, found_const_table_map,
- found_const_table_map,
- *s->on_expr_ref ? *s->on_expr_ref : conds,
- 1, &error);
- if (!select)
- goto error;
- records= get_quick_record_count(join->thd, select, s->table,
- &s->const_keys, join->row_limit);
- s->quick=select->quick;
- s->needed_reg=select->needed_reg;
- select->quick=0;
- if (records == 0 && s->table->reginfo.impossible_range)
+ bool impossible_range= FALSE;
+ ha_rows records= HA_POS_ERROR;
+ SQL_SELECT *select= 0;
+ if (!s->const_keys.is_clear_all())
+ {
+ select= make_select(s->table, found_const_table_map,
+ found_const_table_map,
+ *s->on_expr_ref ? *s->on_expr_ref : conds,
+ 1, &error);
+ if (!select)
+ goto error;
+ records= get_quick_record_count(join->thd, select, s->table,
+ &s->const_keys, join->row_limit);
+ 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
@@ -3848,13 +3868,10 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
s->found_records=records;
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))