diff options
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r-- | sql/sql_select.cc | 47 |
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 |