mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
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.
This commit is contained in:
31
sql/field.cc
31
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.
|
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
|
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,
|
|||||||
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*/
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
33
sql/field.h
33
sql/field.h
@@ -1199,16 +1199,6 @@ public:
|
|||||||
{ 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 @@ public:
|
|||||||
}
|
}
|
||||||
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 @@ public:
|
|||||||
|
|
||||||
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 @@ public:
|
|||||||
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 @@ public:
|
|||||||
{ 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,
|
|||||||
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,
|
|||||||
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)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user