summaryrefslogtreecommitdiff
path: root/sql/sql_statistics.cc
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2013-03-30 15:37:21 -0700
committerIgor Babaev <igor@askmonty.org>2013-03-30 15:37:21 -0700
commit905549863454647b6070e23b7cf5fc1394f92750 (patch)
tree7c44a0d40f9f073932c8b7b9dd5b3afe1a2220bd /sql/sql_statistics.cc
parente59e529635f5a033aff905e95a901b17fe0f9833 (diff)
downloadmariadb-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.cc44
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);