diff options
author | Alexander Barkov <bar@mariadb.org> | 2015-10-02 12:14:50 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2015-10-02 12:14:50 +0400 |
commit | 322bc6e8c900b28c7d06f91f9b91b4f719825fc7 (patch) | |
tree | 575bc810451eaee0f5fc43f2a4da0aacd3388e78 | |
parent | 5e7f100bf55e65f4a4f38dbe6d79a0db70b4acf8 (diff) | |
download | mariadb-git-322bc6e8c900b28c7d06f91f9b91b4f719825fc7.tar.gz |
Adding "virtual bool Field::can_optimize_range(...)" and moving the code
from Item_bool_func::get_mm_leaf() into Field_xxx::can_optimize_range().
This reduces the total amount of virtual calls. Also, it's a prerequisite
change for the pluggable data types.
-rw-r--r-- | sql/field.cc | 31 | ||||
-rw-r--r-- | sql/field.h | 33 | ||||
-rw-r--r-- | sql/opt_range.cc | 30 |
3 files changed, 55 insertions, 39 deletions
diff --git a/sql/field.cc b/sql/field.cc index 5b33d809ef0..8115223a0ce 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1309,6 +1309,19 @@ bool Field::can_optimize_group_min_max(const Item_bool_func *cond, } +/* + This covers all numeric types, ENUM, SET, BIT +*/ +bool Field::can_optimize_range(const Item_bool_func *cond, + const Item *item, + bool is_eq_func) const +{ + DBUG_ASSERT(cmp_type() != TIME_RESULT); // Handled in Field_temporal + DBUG_ASSERT(cmp_type() != STRING_RESULT); // Handled in Field_longstr + return item->cmp_type() != TIME_RESULT; +} + + /** Numeric fields base class constructor. */ @@ -6955,6 +6968,16 @@ bool Field_longstr::can_optimize_group_min_max(const Item_bool_func *cond, } +bool Field_longstr::can_optimize_range(const Item_bool_func *cond, + const Item *item, + bool is_eq_func) const +{ + return is_eq_func ? + cmp_to_string_with_stricter_collation(cond, item) : + cmp_to_string_with_same_collation(cond, item); +} + + /** This overrides the default behavior of the parent constructor Warn_filter(thd) to suppress notes about trailing spaces in case of CHAR(N), @@ -8461,6 +8484,14 @@ Field::geometry_type Field_geom::geometry_type_merge(geometry_type a, return Field::GEOM_GEOMETRY; } + +bool Field_geom::can_optimize_range(const Item_bool_func *cond, + const Item *item, + bool is_eq_func) const +{ + return item->cmp_type() == STRING_RESULT; +} + #endif /*HAVE_SPATIAL*/ /**************************************************************************** diff --git a/sql/field.h b/sql/field.h index 05703a20864..6cd435f2bec 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1199,16 +1199,6 @@ public: { return binary() ? &my_charset_bin : charset(); } virtual CHARSET_INFO *sort_charset(void) const { return charset(); } virtual bool has_charset(void) const { return FALSE; } - /* - match_collation_to_optimize_range() is to distinguish in - range optimizer (see opt_range.cc) between real string types: - CHAR, VARCHAR, TEXT - and the other string-alike types with result_type() == STRING_RESULT: - DATE, TIME, DATETIME, TIMESTAMP - We need it to decide whether to test if collation of the operation - matches collation of the field (needed only for real string types). - */ - virtual bool match_collation_to_optimize_range() const { return false; } virtual void set_charset(CHARSET_INFO *charset_arg) { } virtual enum Derivation derivation(void) const { return DERIVATION_IMPLICIT; } @@ -1359,6 +1349,15 @@ public: } virtual bool can_optimize_group_min_max(const Item_bool_func *cond, const Item *const_item) const; + /** + Test if Field can use range optimizer for a standard comparison operation: + <=, <, =, <=>, >, >= + Note, this method does not cover spatial operations. + */ + virtual bool can_optimize_range(const Item_bool_func *cond, + const Item *item, + bool is_eq_func) const; + bool can_optimize_outer_join_table_elimination(const Item_bool_func *cond, const Item *item) const { @@ -1583,13 +1582,15 @@ public: int store_decimal(const my_decimal *d); uint32 max_data_length() const; - bool match_collation_to_optimize_range() const { return true; } bool can_optimize_keypart_ref(const Item_bool_func *cond, const Item *item) const; bool can_optimize_hash_join(const Item_bool_func *cond, const Item *item) const; bool can_optimize_group_min_max(const Item_bool_func *cond, const Item *const_item) const; + bool can_optimize_range(const Item_bool_func *cond, + const Item *item, + bool is_eq_func) const; }; /* base class for float and double and decimal (old one) */ @@ -2082,6 +2083,12 @@ public: const Item *item) const; bool can_optimize_group_min_max(const Item_bool_func *cond, const Item *const_item) const; + bool can_optimize_range(const Item_bool_func *cond, + const Item *item, + bool is_eq_func) const + { + return true; + } }; @@ -3101,7 +3108,9 @@ public: { geom_type= geom_type_arg; srid= 0; } enum ha_base_keytype key_type() const { return HA_KEYTYPE_VARBINARY2; } enum_field_types type() const { return MYSQL_TYPE_GEOMETRY; } - bool match_collation_to_optimize_range() const { return false; } + bool can_optimize_range(const Item_bool_func *cond, + const Item *item, + bool is_eq_func) const; void sql_type(String &str) const; int store(const char *to, uint length, CHARSET_INFO *charset); int store(double nr); diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 534353248eb..bb92f278b01 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -7849,28 +7849,6 @@ Item_bool_func::get_mm_leaf(RANGE_OPT_PARAM *param, if (key_part->image_type != Field::itRAW) DBUG_RETURN(0); // e.g. SPATIAL index - /* - 1. Usually we can't use an index if the column collation - differ from the operation collation. - - 2. However, we can reuse a case insensitive index for - the binary searches: - - WHERE latin1_swedish_ci_column = 'a' COLLATE lati1_bin; - - WHERE latin1_swedish_ci_colimn = BINARY 'a ' - - */ - if (field->result_type() == STRING_RESULT && - field->match_collation_to_optimize_range() && - value->result_type() == STRING_RESULT && - field->charset() != compare_collation() && - !((type == EQUAL_FUNC || type == EQ_FUNC) && - compare_collation()->state & MY_CS_BINSORT)) - goto end; - if (value->cmp_type() == TIME_RESULT && field->cmp_type() != TIME_RESULT) - goto end; - if (param->using_real_indexes && !field->optimize_range(param->real_keynr[key_part->key], key_part->part) && @@ -7878,12 +7856,10 @@ Item_bool_func::get_mm_leaf(RANGE_OPT_PARAM *param, type != EQUAL_FUNC) goto end; // Can't optimize this - /* - We can't always use indexes when comparing a string index to a number - cmp_type() is checked to allow compare of dates to numbers - */ - if (field->cmp_type() == STRING_RESULT && value->cmp_type() != STRING_RESULT) + if (!field->can_optimize_range(this, value, + type == EQUAL_FUNC || type == EQ_FUNC)) goto end; + err= value->save_in_field_no_warnings(field, 1); if (err == 2 && field->cmp_type() == STRING_RESULT) { |