summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc76
-rw-r--r--sql/field.h15
-rw-r--r--sql/item.cc2
-rw-r--r--sql/item_cmpfunc.cc2
-rw-r--r--sql/sql_select.cc4
-rw-r--r--sql/sql_statistics.cc3
6 files changed, 45 insertions, 57 deletions
diff --git a/sql/field.cc b/sql/field.cc
index 5e4d29045a3..51938bab9b3 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -11369,7 +11369,7 @@ void Field::print_key_value_binary(String *out, const uchar* key, uint32 length)
If the column is the first component of a key, then statistics
for the column are available from the range optimizer.
Sets the bit in Field::stats_table
- a) NDV is available
+ a) Number of distinct values(NDV) is available
b) Statistics are available for the non-const argument of a
range predicate
*/
@@ -11381,15 +11381,12 @@ void Field::statistics_available_via_keys()
while ((key= it++) != key_map::Iterator::BITMAP_END)
{
KEY *keyinfo= table->key_info + key;
- if (keyinfo->usable_key_parts == 1 &&
- field_index + 1 == keyinfo->key_part->fieldnr)
+ DBUG_ASSERT(field_index + 1 == keyinfo->key_part->fieldnr);
+ stats_available|= (1 << STATISTICS_FOR_RANGE_PREDICATES_AVAILABLE);
+ if (keyinfo->actual_rec_per_key(0))
{
- stats_available|= (1 << STATISTICS_FOR_RANGE_PREDICATES_AVAILABLE);
- if (keyinfo->actual_rec_per_key(0))
- {
- stats_available|= (1 << STATISTICS_FOR_NDV_AVAILABLE);
- return;
- }
+ stats_available|= (1 << STATISTICS_FOR_NDV_AVAILABLE);
+ return;
}
}
}
@@ -11402,11 +11399,12 @@ void Field::statistics_available_via_keys()
void Field::statistics_available_via_stat_tables()
{
- if (!(read_stats && !read_stats->no_stat_values_provided()))
- return;
- stats_available|= (1 << STATISTICS_FOR_RANGE_PREDICATES_AVAILABLE);
- if (!read_stats->is_null(COLUMN_STAT_AVG_FREQUENCY))
- stats_available|= (1 << STATISTICS_FOR_NDV_AVAILABLE);
+ if (read_stats && !read_stats->no_stat_values_provided())
+ {
+ stats_available|= (1 << STATISTICS_FOR_RANGE_PREDICATES_AVAILABLE);
+ if (!read_stats->is_null(COLUMN_STAT_AVG_FREQUENCY))
+ stats_available|= (1 << STATISTICS_FOR_NDV_AVAILABLE);
+ }
}
@@ -11414,14 +11412,19 @@ void Field::statistics_available_via_stat_tables()
@brief
Check if statistics for a column are available via indexes or stat tables
+ @details
+ This function checks if there are statistics for a column via indexes
+ or stat tables. Also if the member Field::stats_available
+ has not been updated then update it
+
@retval
TRUE : statistics available for the column
FALSE : OTHERWISE
*/
-bool Field::is_statistics_available()
+bool Field::is_range_statistics_available()
{
- if (!(stats_available & (1 << STATISTICS_CACHED)))
+ if (!stats_available)
{
statistics_available_via_keys();
statistics_available_via_stat_tables();
@@ -11433,7 +11436,8 @@ bool Field::is_statistics_available()
/*
@brief
- Check if ndv for a column are available via indexes or stat tables
+ Check if number of distinct values (NDV) for a column are available
+ via indexes or stat tables
@retval
TRUE : ndv available for the column
@@ -11442,12 +11446,11 @@ bool Field::is_statistics_available()
bool Field::is_ndv_available()
{
- if (!(stats_available & (1 << STATISTICS_CACHED)))
+ if (!stats_available)
{
- bool res= is_ndv_available_via_keys() ||
- is_ndv_available_via_stat_tables();
stats_available|= (1 << STATISTICS_CACHED);
- return res;
+ return is_ndv_available_via_keys() ||
+ is_ndv_available_via_stat_tables();
}
return (stats_available & (1 << STATISTICS_FOR_NDV_AVAILABLE));
}
@@ -11469,7 +11472,7 @@ bool Field::is_ndv_available_via_keys()
while ((key= it++) != key_map::Iterator::BITMAP_END)
{
KEY *keyinfo= table->key_info + key;
- if (is_first_component_of_key(keyinfo) && keyinfo->actual_rec_per_key(0))
+ if (keyinfo->actual_rec_per_key(0))
{
stats_available|= (1 << STATISTICS_FOR_NDV_AVAILABLE);
return true;
@@ -11490,30 +11493,13 @@ bool Field::is_ndv_available_via_keys()
bool Field::is_ndv_available_via_stat_tables()
{
- if (!(read_stats && !read_stats->no_stat_values_provided() &&
+ if ((read_stats && !read_stats->no_stat_values_provided() &&
!read_stats->is_null(COLUMN_STAT_AVG_FREQUENCY)))
- return false;
- stats_available|= (1 << STATISTICS_FOR_NDV_AVAILABLE);
- return true;
-}
-
-
-/*
- @brief
- Checks if a field is the first component of a given key
-
- @param
- key given key
-
- @retval
- TRUE : field is the first component of the given key
- FALSE : otherwise
-*/
-
-bool Field::is_first_component_of_key(KEY *key)
-{
- DBUG_ASSERT(key->usable_key_parts >= 1);
- return field_index + 1 == key->key_part->fieldnr;
+ {
+ stats_available|= (1 << STATISTICS_FOR_NDV_AVAILABLE);
+ return true;
+ }
+ return false;
}
diff --git a/sql/field.h b/sql/field.h
index e4a1e2b12c4..18633f8f1fe 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -832,6 +832,13 @@ public:
uint32 flags;
uint16 field_index; // field number in fields array
uchar null_bit; // Bit used to test null bit
+
+ /*
+ Caches the value of whether statistics are available for a field
+ This is reset for each query in THD::init()
+ */
+ uint8 stats_available;
+
/**
If true, this field was created in create_tmp_field_from_item from a NULL
value. This means that the type of the field is just a guess, and the type
@@ -876,11 +883,6 @@ public:
STATISTICS_FOR_NDV_AVAILABLE
};
- /*
- Caches the value of whether statistics are available for a field or not.
- */
- uint stats_available;
-
/*
This is additional data provided for any computed(virtual) field,
default function or check constraint.
@@ -1919,10 +1921,9 @@ public:
/* Mark field in read map. Updates also virtual fields */
void register_field_in_read_map();
- bool is_first_component_of_key(KEY *key);
void statistics_available_via_keys();
void statistics_available_via_stat_tables();
- bool is_statistics_available();
+ bool is_range_statistics_available();
bool is_ndv_available();
bool is_ndv_available_via_stat_tables();
bool is_ndv_available_via_keys();
diff --git a/sql/item.cc b/sql/item.cc
index c72f488c81d..71b73ae314f 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -9367,7 +9367,7 @@ bool Item_field::predicate_selectivity_checker(void *arg)
{
same_field_arg->item= this;
same_field_arg->is_stats_available=
- field->is_statistics_available() ||
+ field->is_range_statistics_available() ||
(item_equal && item_equal->is_statistics_available());
return false;
}
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 711f1b939a9..4fe1d78af45 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -7244,7 +7244,7 @@ bool Item_equal::is_statistics_available()
while (it++)
{
Field *field= it.get_curr_field();
- if (field->is_statistics_available())
+ if (field->is_range_statistics_available())
return true;
}
return false;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 3553ee78c5b..c04eda05c57 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -29478,6 +29478,10 @@ void unpack_to_base_table_fields(TABLE *table)
bool is_range_predicate(Item *item, Item *value)
{
+ /*
+ calling real_item() here so that if the item is a REF_ITEM
+ then we would get the item field it is referring to
+ */
Item *field= item->real_item();
if (field->type() == Item::FIELD_ITEM && !field->const_item() &&
(!value || !value->is_expensive()))
diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc
index 71d472feaba..5a93df13cf8 100644
--- a/sql/sql_statistics.cc
+++ b/sql/sql_statistics.cc
@@ -3158,10 +3158,7 @@ static void dump_stats_from_share_to_table(TABLE *table)
Field **field_ptr= table_share->field;
Field **table_field_ptr= table->field;
for ( ; *field_ptr; field_ptr++, table_field_ptr++)
- {
(*table_field_ptr)->read_stats= (*field_ptr)->read_stats;
- (*table_field_ptr)->stats_available= (*field_ptr)->stats_available;
- }
table->stats_is_read= true;
}