summaryrefslogtreecommitdiff
path: root/sql/sql_select.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r--sql/sql_select.cc47
1 files changed, 6 insertions, 41 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 610687ce8f1..28febc60fbb 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -4124,6 +4124,7 @@ error:
/// Used when finding key fields
typedef struct key_field_t {
Field *field;
+ Item_func *cond;
Item *val; ///< May be empty if diff constant
uint level;
uint optimize;
@@ -4466,46 +4467,6 @@ add_key_field(JOIN *join,
}
if (!eq_func) // eq_func is NEVER true when num_values > 1
return;
-
- if ((*value)->cmp_type() == TIME_RESULT &&
- field->cmp_type() != TIME_RESULT)
- return;
-
- /*
- Note, for ITEM/ENUM columns:
- - field->cmp_type() returns INT_RESULT
- - field->result_type() returns STRING_RESULT
- - field->type() returns MYSQL_TYPE_STRING
-
- Using field->real_type() to detect ENUM/SET,
- as they need a special handling:
- - Conditions between a ENUM/SET filter and a TIME expression
- cannot be optimized. They were filtered out in the previous if block.
- - It's Ok to use ref access for an ENUM/SET field compared to an
- INT/REAL/DECIMAL expression.
- - It's Ok to use ref for an ENUM/SET field compared to a STRING
- expression if the collation of the field and the collation of
- the condition match.
- */
- if ((field->real_type() == MYSQL_TYPE_ENUM ||
- field->real_type() == MYSQL_TYPE_SET) &&
- (*value)->cmp_type () == STRING_RESULT &&
- field->charset() != cond->compare_collation())
- return;
-
- /*
- We can't use indexes when comparing a string index to a
- number or two strings if the effective collation
- of the operation differ from the field collation.
- */
-
- if (field->cmp_type() == STRING_RESULT)
- {
- if ((*value)->cmp_type() != STRING_RESULT)
- return;
- if (field->charset() != cond->compare_collation())
- return;
- }
}
}
/*
@@ -4517,6 +4478,7 @@ add_key_field(JOIN *join,
(*key_fields)->field= field;
(*key_fields)->eq_func= eq_func;
(*key_fields)->val= *value;
+ (*key_fields)->cond= cond;
(*key_fields)->level= and_level;
(*key_fields)->optimize= optimize;
/*
@@ -4958,7 +4920,8 @@ add_key_part(DYNAMIC_ARRAY *keyuse_array, KEY_FIELD *key_field)
uint key_parts= form->actual_n_key_parts(keyinfo);
for (uint part=0 ; part < key_parts ; part++)
{
- if (field->eq(form->key_info[key].key_part[part].field))
+ if (field->eq(form->key_info[key].key_part[part].field) &&
+ field->can_optimize_keypart_ref(key_field->cond, key_field->val))
{
if (add_keyuse(keyuse_array, key_field, key, part))
return TRUE;
@@ -4969,6 +4932,8 @@ add_key_part(DYNAMIC_ARRAY *keyuse_array, KEY_FIELD *key_field)
(key_field->optimize & KEY_OPTIMIZE_EQ) &&
key_field->val->used_tables())
{
+ if (!field->can_optimize_hash_join(key_field->cond, key_field->val))
+ return false;
/*
If a key use is extracted from an equi-join predicate then it is
added not only as a key use for every index whose component can