diff --git a/sql/histograms/histogram.cc b/sql/histograms/histogram.cc index 289cb2b860b..c470feec5c5 100644 --- a/sql/histograms/histogram.cc +++ b/sql/histograms/histogram.cc @@ -2191,6 +2191,20 @@ double Histogram::get_equal_to_selectivity_dispatcher(const T &value) const { /* purecov: end deadcode */ } +// template helper functions for Histogram::get_selectivity_dispatcher() + +inline const CHARSET_INFO *charset_of(Item *item) { + return item->collation.collation; +} + +inline enum_field_types data_type_of(Item *item) { + return item->data_type(); +} + +inline bool is_null(Item *item) { + return item->is_null(); +} + static bool get_temporal(Item *item, Value_map_type preferred_type, MYSQL_TIME *time_value) { if (item->is_temporal_with_date_and_time()) { @@ -2236,7 +2250,8 @@ double Histogram::apply_operator(const enum_operator op, const T &value) const { } } -bool Histogram::get_selectivity_dispatcher(Item *item, const enum_operator op, +template +bool Histogram::get_selectivity_dispatcher(T *item, const enum_operator op, const TYPELIB *typelib, double *selectivity) const { switch (this->get_data_type()) { @@ -2248,12 +2263,12 @@ bool Histogram::get_selectivity_dispatcher(Item *item, const enum_operator op, } case Value_map_type::STRING: { // Is the character set the same? If not, we cannot use the histogram - if (item->collation.collation->number != get_character_set()->number) + if (charset_of(item)->number != get_character_set()->number) return true; - StringBuffer str_buf(item->collation.collation); + StringBuffer str_buf(charset_of(item)); const String *str = item->val_str(&str_buf); - if (item->is_null()) return true; + if (is_null(item)) return true; *selectivity = apply_operator(op, str->substr(0, HISTOGRAM_MAX_COMPARE_LENGTH)); @@ -2261,7 +2276,7 @@ bool Histogram::get_selectivity_dispatcher(Item *item, const enum_operator op, } case Value_map_type::INT: { const longlong value = item->val_int(); - if (item->is_null()) return true; + if (is_null(item)) return true; *selectivity = apply_operator(op, value); return false; @@ -2270,10 +2285,10 @@ bool Histogram::get_selectivity_dispatcher(Item *item, const enum_operator op, assert(typelib != nullptr); longlong value; - if (item->data_type() == MYSQL_TYPE_VARCHAR) { - StringBuffer str_buf(item->collation.collation); + if (data_type_of(item) == MYSQL_TYPE_VARCHAR) { + StringBuffer str_buf(charset_of(item)); const String *str = item->val_str(&str_buf); - if (item->is_null()) return true; + if (is_null(item)) return true; // Remove any trailing whitespace size_t length = str->charset()->cset->lengthsp( @@ -2281,7 +2296,7 @@ bool Histogram::get_selectivity_dispatcher(Item *item, const enum_operator op, value = find_type2(typelib, str->ptr(), length, str->charset()); } else { value = item->val_int(); - if (item->is_null()) return true; + if (is_null(item)) return true; } if (op == enum_operator::EQUALS_TO) { @@ -2295,10 +2310,10 @@ bool Histogram::get_selectivity_dispatcher(Item *item, const enum_operator op, assert(typelib != nullptr); longlong value; - if (item->data_type() == MYSQL_TYPE_VARCHAR) { - StringBuffer str_buf(item->collation.collation); + if (data_type_of(item) == MYSQL_TYPE_VARCHAR) { + StringBuffer str_buf(charset_of(item)); const String *str = item->val_str(&str_buf); - if (item->is_null()) return true; + if (is_null(item)) return true; bool got_warning; const char *not_used; @@ -2310,7 +2325,7 @@ bool Histogram::get_selectivity_dispatcher(Item *item, const enum_operator op, value = static_cast(tmp_value); } else { value = item->val_int(); - if (item->is_null()) return true; + if (is_null(item)) return true; } if (op == enum_operator::EQUALS_TO) { @@ -2322,14 +2337,14 @@ bool Histogram::get_selectivity_dispatcher(Item *item, const enum_operator op, } case Value_map_type::UINT: { const ulonglong value = static_cast(item->val_int()); - if (item->is_null()) return true; + if (is_null(item)) return true; *selectivity = apply_operator(op, value); return false; } case Value_map_type::DOUBLE: { const double value = item->val_real(); - if (item->is_null()) return true; + if (is_null(item)) return true; *selectivity = apply_operator(op, value); return false; @@ -2337,7 +2352,7 @@ bool Histogram::get_selectivity_dispatcher(Item *item, const enum_operator op, case Value_map_type::DECIMAL: { my_decimal buffer; const my_decimal *value = item->val_decimal(&buffer); - if (item->is_null()) return true; + if (is_null(item)) return true; *selectivity = apply_operator(op, *value); return false; @@ -2361,6 +2376,10 @@ bool Histogram::get_selectivity_dispatcher(Item *item, const enum_operator op, /* purecov: end deadcode */ } +template +bool Histogram::get_selectivity_dispatcher(Item *, const enum_operator, + const TYPELIB *, double *) const; + bool Histogram::get_selectivity(Item **items, size_t item_count, enum_operator op, double *selectivity) const { if (get_raw_selectivity(items, item_count, op, selectivity)) return true; diff --git a/sql/histograms/histogram.h b/sql/histograms/histogram.h index 46dcc67b516..9b616088ee2 100644 --- a/sql/histograms/histogram.h +++ b/sql/histograms/histogram.h @@ -481,7 +481,8 @@ class Histogram { @return true on error (i.e the provided item was NULL), false on success. */ - bool get_selectivity_dispatcher(Item *item, const enum_operator op, + template + bool get_selectivity_dispatcher(T *item, const enum_operator op, const TYPELIB *typelib, double *selectivity) const;