Commit e3bf08d4 authored by Igor Babaev's avatar Igor Babaev

Fixed bug mdev-4363.

When calculating the selectivity of a range in the function
get_column_range_cardinality a check whether NULL values are
included into into the range must be done.
parent 10f0530b
...@@ -882,7 +882,7 @@ Table Op Msg_type Msg_text ...@@ -882,7 +882,7 @@ Table Op Msg_type Msg_text
test.t1 analyze status OK test.t1 analyze status OK
test.t2 analyze status OK test.t2 analyze status OK
FLUSH TABLES; FLUSH TABLES;
SET optimizer_use_condition_selectivity=3; set optimizer_use_condition_selectivity=3;
EXPLAIN EXTENDED EXPLAIN EXTENDED
SELECT * FROM t1, t2 WHERE EXISTS ( SELECT 1 FROM t1, t2 ) AND a != b OR a <= 4; SELECT * FROM t1, t2 WHERE EXISTS ( SELECT 1 FROM t1, t2 ) AND a != b OR a <= 4;
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
...@@ -895,4 +895,44 @@ Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` ...@@ -895,4 +895,44 @@ Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1`
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
DROP TABLE t1,t2; DROP TABLE t1,t2;
set use_stat_tables=@save_use_stat_tables; set use_stat_tables=@save_use_stat_tables;
#
# Bug mdev-4363: selectivity of the condition a IS NULL OR IS NOT NULL
# with optimizer_use_condition_selectivity=3
#
set use_stat_tables = PREFERABLY;
CREATE TABLE t1 (a int);
INSERT INTO t1 VALUES
(1),(7),(4),(7),(NULL),(2),(NULL),(4),(NULL),(NULL),(1),(3),(8),(8);
ANALYZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
FLUSH TABLE t1;
set optimizer_use_condition_selectivity=3;
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE a IS NULL;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 14 28.57 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where isnull(`test`.`t1`.`a`)
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE a IS NOT NULL;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 14 71.43 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` is not null)
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE a IS NULL OR a IS NOT NULL;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 14 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (isnull(`test`.`t1`.`a`) or (`test`.`t1`.`a` is not null))
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE a IS NULL OR a < 5;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 14 69.39 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (isnull(`test`.`t1`.`a`) or (`test`.`t1`.`a` < 5))
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
DROP TABLE t1;
set use_stat_tables=@save_use_stat_tables;
set use_stat_tables=@save_use_stat_tables; set use_stat_tables=@save_use_stat_tables;
...@@ -890,7 +890,7 @@ Table Op Msg_type Msg_text ...@@ -890,7 +890,7 @@ Table Op Msg_type Msg_text
test.t1 analyze status OK test.t1 analyze status OK
test.t2 analyze status OK test.t2 analyze status OK
FLUSH TABLES; FLUSH TABLES;
SET optimizer_use_condition_selectivity=3; set optimizer_use_condition_selectivity=3;
EXPLAIN EXTENDED EXPLAIN EXTENDED
SELECT * FROM t1, t2 WHERE EXISTS ( SELECT 1 FROM t1, t2 ) AND a != b OR a <= 4; SELECT * FROM t1, t2 WHERE EXISTS ( SELECT 1 FROM t1, t2 ) AND a != b OR a <= 4;
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
...@@ -903,6 +903,46 @@ Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` ...@@ -903,6 +903,46 @@ Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1`
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity; set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
DROP TABLE t1,t2; DROP TABLE t1,t2;
set use_stat_tables=@save_use_stat_tables; set use_stat_tables=@save_use_stat_tables;
#
# Bug mdev-4363: selectivity of the condition a IS NULL OR IS NOT NULL
# with optimizer_use_condition_selectivity=3
#
set use_stat_tables = PREFERABLY;
CREATE TABLE t1 (a int);
INSERT INTO t1 VALUES
(1),(7),(4),(7),(NULL),(2),(NULL),(4),(NULL),(NULL),(1),(3),(8),(8);
ANALYZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
FLUSH TABLE t1;
set optimizer_use_condition_selectivity=3;
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE a IS NULL;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 14 28.57 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where isnull(`test`.`t1`.`a`)
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE a IS NOT NULL;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 14 71.43 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` is not null)
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE a IS NULL OR a IS NOT NULL;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 14 100.00 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (isnull(`test`.`t1`.`a`) or (`test`.`t1`.`a` is not null))
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE a IS NULL OR a < 5;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 14 69.39 Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where (isnull(`test`.`t1`.`a`) or (`test`.`t1`.`a` < 5))
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
DROP TABLE t1;
set use_stat_tables=@save_use_stat_tables;
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;
...@@ -483,7 +483,7 @@ INSERT INTO t2 VALUES (4),(5),(2),(5),(1),(1),(2); ...@@ -483,7 +483,7 @@ INSERT INTO t2 VALUES (4),(5),(2),(5),(1),(1),(2);
ANALYZE TABLE t1, t2; ANALYZE TABLE t1, t2;
FLUSH TABLES; FLUSH TABLES;
SET optimizer_use_condition_selectivity=3; set optimizer_use_condition_selectivity=3;
EXPLAIN EXTENDED EXPLAIN EXTENDED
SELECT * FROM t1, t2 WHERE EXISTS ( SELECT 1 FROM t1, t2 ) AND a != b OR a <= 4; SELECT * FROM t1, t2 WHERE EXISTS ( SELECT 1 FROM t1, t2 ) AND a != b OR a <= 4;
...@@ -495,4 +495,36 @@ DROP TABLE t1,t2; ...@@ -495,4 +495,36 @@ DROP TABLE t1,t2;
set use_stat_tables=@save_use_stat_tables; set use_stat_tables=@save_use_stat_tables;
--echo #
--echo # Bug mdev-4363: selectivity of the condition a IS NULL OR IS NOT NULL
--echo # with optimizer_use_condition_selectivity=3
--echo #
set use_stat_tables = PREFERABLY;
CREATE TABLE t1 (a int);
INSERT INTO t1 VALUES
(1),(7),(4),(7),(NULL),(2),(NULL),(4),(NULL),(NULL),(1),(3),(8),(8);
ANALYZE TABLE t1;
FLUSH TABLE t1;
set optimizer_use_condition_selectivity=3;
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE a IS NULL;
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE a IS NOT NULL;
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE a IS NULL OR a IS NOT NULL;
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE a IS NULL OR a < 5;
set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
DROP TABLE t1;
set use_stat_tables=@save_use_stat_tables;
set use_stat_tables=@save_use_stat_tables; set use_stat_tables=@save_use_stat_tables;
...@@ -3303,7 +3303,8 @@ double records_in_column_ranges(PARAM *param, uint idx, ...@@ -3303,7 +3303,8 @@ double records_in_column_ranges(PARAM *param, uint idx,
key_range *min_endp, *max_endp; key_range *min_endp, *max_endp;
min_endp= range.start_key.length? &range.start_key : NULL; min_endp= range.start_key.length? &range.start_key : NULL;
max_endp= range.end_key.length? &range.end_key : NULL; max_endp= range.end_key.length? &range.end_key : NULL;
rows= get_column_range_cardinality(field, min_endp, max_endp); rows= get_column_range_cardinality(field, min_endp, max_endp,
range.range_flag);
if (HA_POS_ERROR == rows) if (HA_POS_ERROR == rows)
{ {
total_rows= HA_POS_ERROR; total_rows= HA_POS_ERROR;
......
...@@ -3339,7 +3339,8 @@ double get_column_avg_frequency(Field * field) ...@@ -3339,7 +3339,8 @@ double get_column_avg_frequency(Field * field)
double get_column_range_cardinality(Field *field, double get_column_range_cardinality(Field *field,
key_range *min_endp, key_range *min_endp,
key_range *max_endp) key_range *max_endp,
uint range_flag)
{ {
double res; double res;
TABLE *table= field->table; TABLE *table= field->table;
...@@ -3353,12 +3354,15 @@ double get_column_range_cardinality(Field *field, ...@@ -3353,12 +3354,15 @@ double get_column_range_cardinality(Field *field,
double col_non_nulls= tab_records - col_nulls; double col_non_nulls= tab_records - col_nulls;
bool nulls_incl= field->null_ptr && min_endp && min_endp->key[0] &&
!(range_flag & NEAR_MIN);
if (col_non_nulls < 1) if (col_non_nulls < 1)
res= 0; res= 0;
else if (min_endp && max_endp && min_endp->length == max_endp->length && else if (min_endp && max_endp && min_endp->length == max_endp->length &&
!memcmp(min_endp->key, max_endp->key, min_endp->length)) !memcmp(min_endp->key, max_endp->key, min_endp->length))
{ {
if (field->null_ptr && min_endp->key[0]) if (nulls_incl)
{ {
/* This is null single point range */ /* This is null single point range */
res= col_nulls; res= col_nulls;
...@@ -3416,6 +3420,8 @@ double get_column_range_cardinality(Field *field, ...@@ -3416,6 +3420,8 @@ double get_column_range_cardinality(Field *field,
} }
else else
res= col_non_nulls; res= col_non_nulls;
if (nulls_incl)
res+= col_nulls;
} }
return res; return res;
} }
...@@ -105,7 +105,8 @@ double get_column_avg_frequency(Field * field); ...@@ -105,7 +105,8 @@ double get_column_avg_frequency(Field * field);
double get_column_range_cardinality(Field *field, double get_column_range_cardinality(Field *field,
key_range *min_endp, key_range *min_endp,
key_range *max_endp); key_range *max_endp,
uint range_flag);
class Histogram class Histogram
{ {
......
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