diff options
author | Igor Babaev <igor@askmonty.org> | 2013-03-30 15:37:21 -0700 |
---|---|---|
committer | Igor Babaev <igor@askmonty.org> | 2013-03-30 15:37:21 -0700 |
commit | 905549863454647b6070e23b7cf5fc1394f92750 (patch) | |
tree | 7c44a0d40f9f073932c8b7b9dd5b3afe1a2220bd /sql/sql_statistics.cc | |
parent | e59e529635f5a033aff905e95a901b17fe0f9833 (diff) | |
download | mariadb-git-905549863454647b6070e23b7cf5fc1394f92750.tar.gz |
Fixed several bugs for mwl #253.
One of them is quite serious: the function table_cond_selectivity used
the TABLE_REF structure for ref/eq_ref access methods as if they had been
filled. In fact these structure are filled after the best execution plan
has been chosen.
The other bugs happened due to:
- an erroneous attempt at get statistics on the result of materialization
of a view
- incorrect handling of ranges with no left/right limits when calculating
selectivity of range conditions on non-indexed columns
- lack of cleanup for some newly introduced fields
Diffstat (limited to 'sql/sql_statistics.cc')
-rw-r--r-- | sql/sql_statistics.cc | 44 |
1 files changed, 35 insertions, 9 deletions
diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 8c0b2730b02..0f26ca7520a 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -3303,6 +3303,18 @@ double get_column_avg_frequency(Field * field) { double res; TABLE *table= field->table; + + /* + Statistics is shared by table instances and is accessed through + the table share. If table->s->field is not set for 'table', then + no column statistics is available for the table . + */ + if (!table->s->field) + { + res= table->stat_records(); + return res; + } + Column_statistics *col_stats= table->s->field[field->field_index]->read_stats; if (!col_stats) @@ -3323,8 +3335,8 @@ double get_column_range_cardinality(Field *field, if (!col_stats) res= table->stat_records(); - else if (min_endp->length == max_endp->length && - !memcmp(min_endp->key, max_endp->key, min_endp->length)) + else if (min_endp && max_endp && min_endp->length == max_endp->length && + !memcmp(min_endp->key, max_endp->key, min_endp->length)) { double avg_frequency= col_stats->get_avg_frequency(); res= avg_frequency; @@ -3346,13 +3358,27 @@ double get_column_range_cardinality(Field *field, { if (col_stats->min_value && col_stats->max_value) { - double sel; - store_key_image_to_rec(field, (uchar *) min_endp->key, min_endp->length); - double min_mp_pos= field->middle_point_pos(col_stats->min_value, - col_stats->max_value); - store_key_image_to_rec(field, (uchar *) max_endp->key, max_endp->length); - double max_mp_pos= field->middle_point_pos(col_stats->min_value, - col_stats->max_value); + double sel, min_mp_pos, max_mp_pos; + + if (min_endp) + { + store_key_image_to_rec(field, (uchar *) min_endp->key, + min_endp->length); + min_mp_pos= field->middle_point_pos(col_stats->min_value, + col_stats->max_value); + } + else + min_mp_pos= 0.0; + if (max_endp) + { + store_key_image_to_rec(field, (uchar *) max_endp->key, + max_endp->length); + max_mp_pos= field->middle_point_pos(col_stats->min_value, + col_stats->max_value); + } + else + max_mp_pos= 1.0; + Histogram *hist= &col_stats->histogram; if (hist->get_size() == 0) sel= (max_mp_pos - min_mp_pos); |