diff options
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r-- | sql/sql_select.cc | 64 |
1 files changed, 50 insertions, 14 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 738e1912994..5a8c8b7dea4 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -111,6 +111,7 @@ static bool best_extension_by_limited_search(JOIN *join, uint prune_level, uint use_cond_selectivity); static uint determine_search_depth(JOIN* join); +static void pick_table_access_method(JOIN_TAB *tab); C_MODE_START static int join_tab_cmp(const void *dummy, const void* ptr1, const void* ptr2); static int join_tab_cmp_straight(const void *dummy, const void* ptr1, const void* ptr2); @@ -10081,6 +10082,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, j->ref.disable_cache= FALSE; j->ref.null_ref_part= NO_REF_PART; j->ref.const_ref_part_map= 0; + j->ref.not_null_keyparts= 0; keyuse=org_keyuse; store_key **ref_key= j->ref.key_copy; @@ -10173,23 +10175,12 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, } } /* not ftkey */ *ref_key=0; // end_marker + j->ref.not_null_keyparts= not_null_keyparts; if (j->type == JT_FT) DBUG_RETURN(0); - ulong key_flags= j->table->actual_key_flags(keyinfo); if (j->type == JT_CONST) j->table->const_table= 1; - else if (!((keyparts == keyinfo->user_defined_key_parts && - ( - (key_flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME || - /* Unique key and all keyparts are NULL rejecting */ - ((key_flags & HA_NOSAME) && keyparts == not_null_keyparts) - )) || - /* true only for extended keys */ - (keyparts > keyinfo->user_defined_key_parts && - MY_TEST(key_flags & HA_EXT_NOSAME) && - keyparts == keyinfo->ext_key_parts) - ) || - null_ref_key) + else if (!j->is_eq_ref_access()|| null_ref_key) { /* Must read with repeat */ j->type= null_ref_key ? JT_REF_OR_NULL : JT_REF; @@ -11582,11 +11573,25 @@ void set_join_cache_denial(JOIN_TAB *join_tab) don't do join buffering for the first table in sjm nest. */ join_tab[-1].next_select= sub_select; - if (join_tab->type == JT_REF && join_tab->is_ref_for_hash_join()) + if ((join_tab->type == JT_REF || join_tab->type == JT_HASH) && + join_tab->is_ref_for_hash_join()) { join_tab->type= JT_ALL; join_tab->ref.key_parts= 0; } + + if (join_tab->type == JT_HASH && !join_tab->is_ref_for_hash_join()) + { + join_tab->type= join_tab->is_eq_ref_access() ? JT_EQ_REF : JT_REF; + pick_table_access_method(join_tab); + } + + if (join_tab->type == JT_HASH_NEXT) + { + join_tab->type = JT_NEXT; + join_tab->ref.key_parts= 0; + } + join_tab->join->return_tab= join_tab; } } @@ -27967,6 +27972,37 @@ void JOIN_TAB::partial_cleanup() } +/* +TODO varun: add comments +*/ +bool JOIN_TAB::is_eq_ref_access() +{ + + KEY *keyinfo; + if (!is_hash_join_key_no(ref.key)) + keyinfo= table->key_info + ref.key; + else + keyinfo= hj_key; + + uint keyparts= ref.key_parts; + ulong key_flags= table->actual_key_flags(keyinfo); + if ( (keyparts == keyinfo->user_defined_key_parts && + ( + (key_flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME || + /* Unique key and all keyparts are NULL rejecting */ + ((key_flags & HA_NOSAME) && keyparts == ref.not_null_keyparts) + ) + ) || + /* true only for extended keys */ + (keyparts > keyinfo->user_defined_key_parts && + MY_TEST(key_flags & HA_EXT_NOSAME) && + keyparts == keyinfo->ext_key_parts) + ) + return true; + return false; +} + + /** @} (end of group Query_Optimizer) */ |