Commit 322bc6e8 authored by Alexander Barkov's avatar Alexander Barkov

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.
parent 5e7f100b
...@@ -1309,6 +1309,19 @@ bool Field::can_optimize_group_min_max(const Item_bool_func *cond, ...@@ -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. Numeric fields base class constructor.
*/ */
...@@ -6955,6 +6968,16 @@ bool Field_longstr::can_optimize_group_min_max(const Item_bool_func *cond, ...@@ -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 This overrides the default behavior of the parent constructor
Warn_filter(thd) to suppress notes about trailing spaces in case of CHAR(N), 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, ...@@ -8461,6 +8484,14 @@ Field::geometry_type Field_geom::geometry_type_merge(geometry_type a,
return Field::GEOM_GEOMETRY; 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*/ #endif /*HAVE_SPATIAL*/
/**************************************************************************** /****************************************************************************
......
...@@ -1199,16 +1199,6 @@ class Field: public Value_source ...@@ -1199,16 +1199,6 @@ class Field: public Value_source
{ return binary() ? &my_charset_bin : charset(); } { return binary() ? &my_charset_bin : charset(); }
virtual CHARSET_INFO *sort_charset(void) const { return charset(); } virtual CHARSET_INFO *sort_charset(void) const { return charset(); }
virtual bool has_charset(void) const { return FALSE; } 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 void set_charset(CHARSET_INFO *charset_arg) { }
virtual enum Derivation derivation(void) const virtual enum Derivation derivation(void) const
{ return DERIVATION_IMPLICIT; } { return DERIVATION_IMPLICIT; }
...@@ -1359,6 +1349,15 @@ class Field: public Value_source ...@@ -1359,6 +1349,15 @@ class Field: public Value_source
} }
virtual bool can_optimize_group_min_max(const Item_bool_func *cond, virtual bool can_optimize_group_min_max(const Item_bool_func *cond,
const Item *const_item) const; 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, bool can_optimize_outer_join_table_elimination(const Item_bool_func *cond,
const Item *item) const const Item *item) const
{ {
...@@ -1583,13 +1582,15 @@ class Field_longstr :public Field_str ...@@ -1583,13 +1582,15 @@ class Field_longstr :public Field_str
int store_decimal(const my_decimal *d); int store_decimal(const my_decimal *d);
uint32 max_data_length() const; uint32 max_data_length() const;
bool match_collation_to_optimize_range() const { return true; }
bool can_optimize_keypart_ref(const Item_bool_func *cond, bool can_optimize_keypart_ref(const Item_bool_func *cond,
const Item *item) const; const Item *item) const;
bool can_optimize_hash_join(const Item_bool_func *cond, bool can_optimize_hash_join(const Item_bool_func *cond,
const Item *item) const; const Item *item) const;
bool can_optimize_group_min_max(const Item_bool_func *cond, bool can_optimize_group_min_max(const Item_bool_func *cond,
const Item *const_item) const; 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) */ /* base class for float and double and decimal (old one) */
...@@ -2082,6 +2083,12 @@ class Field_temporal: public Field { ...@@ -2082,6 +2083,12 @@ class Field_temporal: public Field {
const Item *item) const; const Item *item) const;
bool can_optimize_group_min_max(const Item_bool_func *cond, bool can_optimize_group_min_max(const Item_bool_func *cond,
const Item *const_item) const; 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 @@ class Field_geom :public Field_blob { ...@@ -3101,7 +3108,9 @@ class Field_geom :public Field_blob {
{ geom_type= geom_type_arg; srid= 0; } { geom_type= geom_type_arg; srid= 0; }
enum ha_base_keytype key_type() const { return HA_KEYTYPE_VARBINARY2; } enum ha_base_keytype key_type() const { return HA_KEYTYPE_VARBINARY2; }
enum_field_types type() const { return MYSQL_TYPE_GEOMETRY; } 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; void sql_type(String &str) const;
int store(const char *to, uint length, CHARSET_INFO *charset); int store(const char *to, uint length, CHARSET_INFO *charset);
int store(double nr); int store(double nr);
......
...@@ -7849,28 +7849,6 @@ Item_bool_func::get_mm_leaf(RANGE_OPT_PARAM *param, ...@@ -7849,28 +7849,6 @@ Item_bool_func::get_mm_leaf(RANGE_OPT_PARAM *param,
if (key_part->image_type != Field::itRAW) if (key_part->image_type != Field::itRAW)
DBUG_RETURN(0); // e.g. SPATIAL index 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 && if (param->using_real_indexes &&
!field->optimize_range(param->real_keynr[key_part->key], !field->optimize_range(param->real_keynr[key_part->key],
key_part->part) && key_part->part) &&
...@@ -7878,12 +7856,10 @@ Item_bool_func::get_mm_leaf(RANGE_OPT_PARAM *param, ...@@ -7878,12 +7856,10 @@ Item_bool_func::get_mm_leaf(RANGE_OPT_PARAM *param,
type != EQUAL_FUNC) type != EQUAL_FUNC)
goto end; // Can't optimize this goto end; // Can't optimize this
/* if (!field->can_optimize_range(this, value,
We can't always use indexes when comparing a string index to a number type == EQUAL_FUNC || type == EQ_FUNC))
cmp_type() is checked to allow compare of dates to numbers
*/
if (field->cmp_type() == STRING_RESULT && value->cmp_type() != STRING_RESULT)
goto end; goto end;
err= value->save_in_field_no_warnings(field, 1); err= value->save_in_field_no_warnings(field, 1);
if (err == 2 && field->cmp_type() == STRING_RESULT) if (err == 2 && field->cmp_type() == STRING_RESULT)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment