Skip to content

Commit 322bc6e

Browse files
author
Alexander Barkov
committed
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.
1 parent 5e7f100 commit 322bc6e

File tree

3 files changed

+55
-39
lines changed

3 files changed

+55
-39
lines changed

sql/field.cc

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,6 +1309,19 @@ bool Field::can_optimize_group_min_max(const Item_bool_func *cond,
13091309
}
13101310

13111311

1312+
/*
1313+
This covers all numeric types, ENUM, SET, BIT
1314+
*/
1315+
bool Field::can_optimize_range(const Item_bool_func *cond,
1316+
const Item *item,
1317+
bool is_eq_func) const
1318+
{
1319+
DBUG_ASSERT(cmp_type() != TIME_RESULT); // Handled in Field_temporal
1320+
DBUG_ASSERT(cmp_type() != STRING_RESULT); // Handled in Field_longstr
1321+
return item->cmp_type() != TIME_RESULT;
1322+
}
1323+
1324+
13121325
/**
13131326
Numeric fields base class constructor.
13141327
*/
@@ -6955,6 +6968,16 @@ bool Field_longstr::can_optimize_group_min_max(const Item_bool_func *cond,
69556968
}
69566969

69576970

6971+
bool Field_longstr::can_optimize_range(const Item_bool_func *cond,
6972+
const Item *item,
6973+
bool is_eq_func) const
6974+
{
6975+
return is_eq_func ?
6976+
cmp_to_string_with_stricter_collation(cond, item) :
6977+
cmp_to_string_with_same_collation(cond, item);
6978+
}
6979+
6980+
69586981
/**
69596982
This overrides the default behavior of the parent constructor
69606983
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,
84618484
return Field::GEOM_GEOMETRY;
84628485
}
84638486

8487+
8488+
bool Field_geom::can_optimize_range(const Item_bool_func *cond,
8489+
const Item *item,
8490+
bool is_eq_func) const
8491+
{
8492+
return item->cmp_type() == STRING_RESULT;
8493+
}
8494+
84648495
#endif /*HAVE_SPATIAL*/
84658496

84668497
/****************************************************************************

sql/field.h

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,16 +1199,6 @@ class Field: public Value_source
11991199
{ return binary() ? &my_charset_bin : charset(); }
12001200
virtual CHARSET_INFO *sort_charset(void) const { return charset(); }
12011201
virtual bool has_charset(void) const { return FALSE; }
1202-
/*
1203-
match_collation_to_optimize_range() is to distinguish in
1204-
range optimizer (see opt_range.cc) between real string types:
1205-
CHAR, VARCHAR, TEXT
1206-
and the other string-alike types with result_type() == STRING_RESULT:
1207-
DATE, TIME, DATETIME, TIMESTAMP
1208-
We need it to decide whether to test if collation of the operation
1209-
matches collation of the field (needed only for real string types).
1210-
*/
1211-
virtual bool match_collation_to_optimize_range() const { return false; }
12121202
virtual void set_charset(CHARSET_INFO *charset_arg) { }
12131203
virtual enum Derivation derivation(void) const
12141204
{ return DERIVATION_IMPLICIT; }
@@ -1359,6 +1349,15 @@ class Field: public Value_source
13591349
}
13601350
virtual bool can_optimize_group_min_max(const Item_bool_func *cond,
13611351
const Item *const_item) const;
1352+
/**
1353+
Test if Field can use range optimizer for a standard comparison operation:
1354+
<=, <, =, <=>, >, >=
1355+
Note, this method does not cover spatial operations.
1356+
*/
1357+
virtual bool can_optimize_range(const Item_bool_func *cond,
1358+
const Item *item,
1359+
bool is_eq_func) const;
1360+
13621361
bool can_optimize_outer_join_table_elimination(const Item_bool_func *cond,
13631362
const Item *item) const
13641363
{
@@ -1583,13 +1582,15 @@ class Field_longstr :public Field_str
15831582

15841583
int store_decimal(const my_decimal *d);
15851584
uint32 max_data_length() const;
1586-
bool match_collation_to_optimize_range() const { return true; }
15871585
bool can_optimize_keypart_ref(const Item_bool_func *cond,
15881586
const Item *item) const;
15891587
bool can_optimize_hash_join(const Item_bool_func *cond,
15901588
const Item *item) const;
15911589
bool can_optimize_group_min_max(const Item_bool_func *cond,
15921590
const Item *const_item) const;
1591+
bool can_optimize_range(const Item_bool_func *cond,
1592+
const Item *item,
1593+
bool is_eq_func) const;
15931594
};
15941595

15951596
/* base class for float and double and decimal (old one) */
@@ -2082,6 +2083,12 @@ class Field_temporal: public Field {
20822083
const Item *item) const;
20832084
bool can_optimize_group_min_max(const Item_bool_func *cond,
20842085
const Item *const_item) const;
2086+
bool can_optimize_range(const Item_bool_func *cond,
2087+
const Item *item,
2088+
bool is_eq_func) const
2089+
{
2090+
return true;
2091+
}
20852092
};
20862093

20872094

@@ -3101,7 +3108,9 @@ class Field_geom :public Field_blob {
31013108
{ geom_type= geom_type_arg; srid= 0; }
31023109
enum ha_base_keytype key_type() const { return HA_KEYTYPE_VARBINARY2; }
31033110
enum_field_types type() const { return MYSQL_TYPE_GEOMETRY; }
3104-
bool match_collation_to_optimize_range() const { return false; }
3111+
bool can_optimize_range(const Item_bool_func *cond,
3112+
const Item *item,
3113+
bool is_eq_func) const;
31053114
void sql_type(String &str) const;
31063115
int store(const char *to, uint length, CHARSET_INFO *charset);
31073116
int store(double nr);

sql/opt_range.cc

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7849,41 +7849,17 @@ Item_bool_func::get_mm_leaf(RANGE_OPT_PARAM *param,
78497849
if (key_part->image_type != Field::itRAW)
78507850
DBUG_RETURN(0); // e.g. SPATIAL index
78517851

7852-
/*
7853-
1. Usually we can't use an index if the column collation
7854-
differ from the operation collation.
7855-
7856-
2. However, we can reuse a case insensitive index for
7857-
the binary searches:
7858-
7859-
WHERE latin1_swedish_ci_column = 'a' COLLATE lati1_bin;
7860-
7861-
WHERE latin1_swedish_ci_colimn = BINARY 'a '
7862-
7863-
*/
7864-
if (field->result_type() == STRING_RESULT &&
7865-
field->match_collation_to_optimize_range() &&
7866-
value->result_type() == STRING_RESULT &&
7867-
field->charset() != compare_collation() &&
7868-
!((type == EQUAL_FUNC || type == EQ_FUNC) &&
7869-
compare_collation()->state & MY_CS_BINSORT))
7870-
goto end;
7871-
if (value->cmp_type() == TIME_RESULT && field->cmp_type() != TIME_RESULT)
7872-
goto end;
7873-
78747852
if (param->using_real_indexes &&
78757853
!field->optimize_range(param->real_keynr[key_part->key],
78767854
key_part->part) &&
78777855
type != EQ_FUNC &&
78787856
type != EQUAL_FUNC)
78797857
goto end; // Can't optimize this
78807858

7881-
/*
7882-
We can't always use indexes when comparing a string index to a number
7883-
cmp_type() is checked to allow compare of dates to numbers
7884-
*/
7885-
if (field->cmp_type() == STRING_RESULT && value->cmp_type() != STRING_RESULT)
7859+
if (!field->can_optimize_range(this, value,
7860+
type == EQUAL_FUNC || type == EQ_FUNC))
78867861
goto end;
7862+
78877863
err= value->save_in_field_no_warnings(field, 1);
78887864
if (err == 2 && field->cmp_type() == STRING_RESULT)
78897865
{

0 commit comments

Comments
 (0)