summaryrefslogtreecommitdiff
path: root/sql/opt_range.cc
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2019-09-12 23:00:49 -0700
committerIgor Babaev <igor@askmonty.org>2019-09-12 23:01:11 -0700
commitdeb9121fdf2152752346c767321e6e01aa5d6c69 (patch)
tree403ebd9fd662ed8407dceba77fed6738f32d8a3a /sql/opt_range.cc
parentd6f0e60a67a5e81dc6fd90a117db2aa5fb658664 (diff)
downloadmariadb-git-deb9121fdf2152752346c767321e6e01aa5d6c69.tar.gz
MDEV-20576 A new assertion added to check validity of calculated
selectivity values fails After having set the assertion that checks validity of selectivity values returned by the function table_cond_selectivity() a test case from order_by.tesst failed. The failure occurred because range optimizer could return as an estimate of the cardinality of the ranges built for an index a number exceeding the total number of records in the table. The second bug is more subtle. It may happen when there are several indexes with same prefix defined on the first joined table t accessed by a constant ref access. In this case the range optimizer estimates the number of accessed records of t for each usable index and these estimates can be different. Only the first of these estimates is taken into account when the selectivity of the ref access is calculated. However the optimizer later can choose a different index that provides a different estimate. The function table_condition_selectivity() could use this estimate to discount the selectivity of the ref access. This could lead to an selectivity value returned by this function that was greater that 1.
Diffstat (limited to 'sql/opt_range.cc')
-rw-r--r--sql/opt_range.cc10
1 files changed, 10 insertions, 0 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index e8421ad052a..45dad8882a1 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -10179,6 +10179,16 @@ ha_rows check_quick_select(PARAM *param, uint idx, bool index_only,
bufsize, mrr_flags, cost);
if (rows != HA_POS_ERROR)
{
+ ha_rows table_records= param->table->stat_records();
+ if (rows > table_records)
+ {
+ /*
+ For any index the total number of records within all ranges
+ cannot be be bigger than the number of records in the table
+ */
+ rows= table_records;
+ set_if_bigger(rows, 1);
+ }
param->quick_rows[keynr]= rows;
param->possible_keys.set_bit(keynr);
if (update_tbl_stats)