MDEV-6442: Assertion `join->best_read < double(...)' failed with optimizer_use_condition_selectivity >=3
- Fix the crash by making get_column_range_cardinality() to handle the special case where Column_stats objects is an all-zeros object (the question of what is the point of having Field::read_stats point to such object remains a mystery) - Added a few comments. Learning the code still.
This commit is contained in:
parent
689ffe3559
commit
fd4c9af398
@ -1358,6 +1358,8 @@ set optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivit
|
|||||||
DROP TABLE t1,t2;
|
DROP TABLE t1,t2;
|
||||||
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 @tmp_ust= @@use_stat_tables;
|
||||||
|
set @tmp_oucs= @@optimizer_use_condition_selectivity;
|
||||||
#
|
#
|
||||||
# MDEV-6808: MariaDB 10.0.13 crash with optimizer_use_condition_selectivity > 1
|
# MDEV-6808: MariaDB 10.0.13 crash with optimizer_use_condition_selectivity > 1
|
||||||
#
|
#
|
||||||
@ -1393,4 +1395,22 @@ t2.subject_type in ('user')
|
|||||||
repost_id subject_type subject_id object_type object_id is_private event_id
|
repost_id subject_type subject_id object_type object_id is_private event_id
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
set optimizer_use_condition_selectivity=@tmp_mdev6808;
|
set optimizer_use_condition_selectivity=@tmp_mdev6808;
|
||||||
|
#
|
||||||
|
# MDEV-6442: Assertion `join->best_read < double(...)' failed with optimizer_use_condition_selectivity >=3, ...
|
||||||
|
#
|
||||||
|
SET use_stat_tables = PREFERABLY;
|
||||||
|
SET optimizer_use_condition_selectivity = 3;
|
||||||
|
CREATE TABLE t1 ( a VARCHAR(3), b VARCHAR(8), KEY (a,b) ) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t1 VALUES ('USA','Chinese'),('USA','English');
|
||||||
|
CREATE TABLE t2 (i INT) ENGINE=InnoDB;
|
||||||
|
SELECT * FROM t1, t2 WHERE ( 't', 'o' ) IN (
|
||||||
|
SELECT t1_2.b, t1_1.a FROM t1 AS t1_1 STRAIGHT_JOIN t1 AS t1_2 ON ( t1_2.a = t1_1.b )
|
||||||
|
);
|
||||||
|
a b i
|
||||||
|
DROP TABLE t1,t2;
|
||||||
|
#
|
||||||
|
# End of 10.0 tests
|
||||||
|
#
|
||||||
|
set use_stat_tables= @tmp_ust;
|
||||||
|
set optimizer_use_condition_selectivity= @tmp_oucs;
|
||||||
SET SESSION STORAGE_ENGINE=DEFAULT;
|
SET SESSION STORAGE_ENGINE=DEFAULT;
|
||||||
|
@ -8,6 +8,9 @@ set optimizer_switch='extended_keys=on';
|
|||||||
--source selectivity.test
|
--source selectivity.test
|
||||||
|
|
||||||
set optimizer_switch=@save_optimizer_switch_for_selectivity_test;
|
set optimizer_switch=@save_optimizer_switch_for_selectivity_test;
|
||||||
|
set @tmp_ust= @@use_stat_tables;
|
||||||
|
set @tmp_oucs= @@optimizer_use_condition_selectivity;
|
||||||
|
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # MDEV-6808: MariaDB 10.0.13 crash with optimizer_use_condition_selectivity > 1
|
--echo # MDEV-6808: MariaDB 10.0.13 crash with optimizer_use_condition_selectivity > 1
|
||||||
@ -46,4 +49,26 @@ WHERE
|
|||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
set optimizer_use_condition_selectivity=@tmp_mdev6808;
|
set optimizer_use_condition_selectivity=@tmp_mdev6808;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-6442: Assertion `join->best_read < double(...)' failed with optimizer_use_condition_selectivity >=3, ...
|
||||||
|
--echo #
|
||||||
|
SET use_stat_tables = PREFERABLY;
|
||||||
|
SET optimizer_use_condition_selectivity = 3;
|
||||||
|
|
||||||
|
CREATE TABLE t1 ( a VARCHAR(3), b VARCHAR(8), KEY (a,b) ) ENGINE=InnoDB;
|
||||||
|
INSERT INTO t1 VALUES ('USA','Chinese'),('USA','English');
|
||||||
|
|
||||||
|
CREATE TABLE t2 (i INT) ENGINE=InnoDB;
|
||||||
|
|
||||||
|
SELECT * FROM t1, t2 WHERE ( 't', 'o' ) IN (
|
||||||
|
SELECT t1_2.b, t1_1.a FROM t1 AS t1_1 STRAIGHT_JOIN t1 AS t1_2 ON ( t1_2.a = t1_1.b )
|
||||||
|
);
|
||||||
|
DROP TABLE t1,t2;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # End of 10.0 tests
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
set use_stat_tables= @tmp_ust;
|
||||||
|
set optimizer_use_condition_selectivity= @tmp_oucs;
|
||||||
SET SESSION STORAGE_ENGINE=DEFAULT;
|
SET SESSION STORAGE_ENGINE=DEFAULT;
|
||||||
|
@ -3502,7 +3502,7 @@ double get_column_range_cardinality(Field *field,
|
|||||||
!(range_flag & NEAR_MIN);
|
!(range_flag & NEAR_MIN);
|
||||||
|
|
||||||
if (col_non_nulls < 1)
|
if (col_non_nulls < 1)
|
||||||
res= 0;
|
res= 0; /* this is likely wrong, see MDEV-6843 */
|
||||||
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))
|
||||||
{
|
{
|
||||||
@ -3515,6 +3515,15 @@ double get_column_range_cardinality(Field *field,
|
|||||||
{
|
{
|
||||||
double avg_frequency= col_stats->get_avg_frequency();
|
double avg_frequency= col_stats->get_avg_frequency();
|
||||||
res= avg_frequency;
|
res= avg_frequency;
|
||||||
|
/*
|
||||||
|
psergey-todo: what does check for min_value, max_value mean?
|
||||||
|
min/max_value are set to NULL in alloc_statistics_for_table() and
|
||||||
|
alloc_statistics_for_table_share(). Both functions will immediately
|
||||||
|
call create_min_max_statistical_fields_for_table and
|
||||||
|
create_min_max_statistical_fields_for_table_share() respectively,
|
||||||
|
which will set min/max_value to be valid pointers, unless OOM
|
||||||
|
occurs.
|
||||||
|
*/
|
||||||
if (avg_frequency > 1.0 + 0.000001 &&
|
if (avg_frequency > 1.0 + 0.000001 &&
|
||||||
col_stats->min_value && col_stats->max_value)
|
col_stats->min_value && col_stats->max_value)
|
||||||
{
|
{
|
||||||
@ -3530,6 +3539,11 @@ double get_column_range_cardinality(Field *field,
|
|||||||
avg_frequency / col_non_nulls);
|
avg_frequency / col_non_nulls);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (avg_frequency == 0.0)
|
||||||
|
{
|
||||||
|
/* This actually means there is no statistics data */
|
||||||
|
res= tab_records;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -280,7 +280,14 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Statistical data on a column */
|
/*
|
||||||
|
Statistical data on a column
|
||||||
|
|
||||||
|
Note: objects of this class may be "empty", where they have almost all fields
|
||||||
|
as zeros, for example, get_avg_frequency() will return 0.
|
||||||
|
|
||||||
|
objects are allocated in alloc_statistics_for_table[_share].
|
||||||
|
*/
|
||||||
|
|
||||||
class Column_statistics
|
class Column_statistics
|
||||||
{
|
{
|
||||||
@ -297,6 +304,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
uint32 column_stat_nulls;
|
uint32 column_stat_nulls;
|
||||||
|
|
||||||
|
/* For the below two, see comments in get_column_range_cardinality() */
|
||||||
/* Minimum value for the column */
|
/* Minimum value for the column */
|
||||||
Field *min_value;
|
Field *min_value;
|
||||||
/* Maximum value for the column */
|
/* Maximum value for the column */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user