diff options
author | Vicențiu Ciorbaru <vicentiu@mariadb.org> | 2017-06-20 12:31:17 +0300 |
---|---|---|
committer | Vicențiu Ciorbaru <vicentiu@mariadb.org> | 2017-06-20 12:31:17 +0300 |
commit | 8baf9b0c469e2845d15cc1181bc6b101cdfba087 (patch) | |
tree | f5808173b56692f71874213639401af1e18cb146 /sql | |
parent | 5e4f4ec8211b61e71ec29069161d0f41f4c05376 (diff) | |
parent | ded614d7dbc930e373d1a69a0d2a7e4bf0a2c6d3 (diff) | |
download | mariadb-git-8baf9b0c469e2845d15cc1181bc6b101cdfba087.tar.gz |
Merge remote-tracking branch '5.5' into 10.0
Diffstat (limited to 'sql')
-rw-r--r-- | sql/opt_subselect.cc | 4 | ||||
-rw-r--r-- | sql/sql_partition.cc | 40 | ||||
-rw-r--r-- | sql/sql_plugin.cc | 20 | ||||
-rw-r--r-- | sql/sql_priv.h | 2 | ||||
-rw-r--r-- | sql/sql_select.cc | 75 | ||||
-rw-r--r-- | sql/sql_select.h | 8 |
6 files changed, 111 insertions, 38 deletions
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 03204a627ed..cc63efa7d8c 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -3433,6 +3433,7 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join) table_map remaining_tables= 0; table_map handled_tabs= 0; join->sjm_lookup_tables= 0; + join->sjm_scan_tables= 0; for (tablenr= table_count - 1 ; tablenr != join->const_tables - 1; tablenr--) { POSITION *pos= join->best_positions + tablenr; @@ -3491,6 +3492,9 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join) for (i= tablenr; i != (first + sjm->tables - 1); i--) rem_tables |= join->best_positions[i].table->table->map; + for (i= first; i < first+ sjm->tables; i++) + join->sjm_scan_tables |= join->best_positions[i].table->table->map; + POSITION dummy; join->cur_sj_inner_tables= 0; for (i= first + sjm->tables; i <= tablenr; i++) diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index be7824aae9e..5446db41a72 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -1870,6 +1870,22 @@ static int add_subpartition_by(File fptr) return err + add_partition_by(fptr); } +static int add_name_string(File fptr, const char *name) +{ + int err; + String name_string("", 0, system_charset_info); + THD *thd= current_thd; + ulonglong save_sql_mode= thd->variables.sql_mode; + thd->variables.sql_mode&= ~MODE_ANSI_QUOTES; + ulonglong save_options= thd->variables.option_bits; + thd->variables.option_bits&= ~OPTION_QUOTE_SHOW_CREATE; + append_identifier(thd, &name_string, name, strlen(name)); + thd->variables.sql_mode= save_sql_mode; + thd->variables.option_bits= save_options; + err= add_string_object(fptr, &name_string); + return err; +} + static int add_part_field_list(File fptr, List<char> field_list) { uint i, num_fields; @@ -1881,15 +1897,7 @@ static int add_part_field_list(File fptr, List<char> field_list) err+= add_begin_parenthesis(fptr); while (i < num_fields) { - const char *field_str= part_it++; - String field_string("", 0, system_charset_info); - THD *thd= current_thd; - ulonglong save_options= thd->variables.option_bits; - thd->variables.option_bits&= ~OPTION_QUOTE_SHOW_CREATE; - append_identifier(thd, &field_string, field_str, - strlen(field_str)); - thd->variables.option_bits= save_options; - err+= add_string_object(fptr, &field_string); + err+= add_name_string(fptr, part_it++); if (i != (num_fields-1)) err+= add_comma(fptr); i++; @@ -1898,20 +1906,6 @@ static int add_part_field_list(File fptr, List<char> field_list) return err; } -static int add_name_string(File fptr, const char *name) -{ - int err; - String name_string("", 0, system_charset_info); - THD *thd= current_thd; - ulonglong save_options= thd->variables.option_bits; - thd->variables.option_bits&= ~OPTION_QUOTE_SHOW_CREATE; - append_identifier(thd, &name_string, name, - strlen(name)); - thd->variables.option_bits= save_options; - err= add_string_object(fptr, &name_string); - return err; -} - static int add_int(File fptr, longlong number) { char buff[32]; diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 63c3933db93..e34409b3532 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -306,6 +306,12 @@ static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref plugin); static void intern_plugin_unlock(LEX *lex, plugin_ref plugin); static void reap_plugins(void); +bool plugin_is_forced(struct st_plugin_int *p) +{ + return p->load_option == PLUGIN_FORCE || + p->load_option == PLUGIN_FORCE_PLUS_PERMANENT; +} + static void report_error(int where_to, uint error, ...) { va_list args; @@ -1360,7 +1366,7 @@ static int plugin_initialize(MEM_ROOT *tmp_root, struct st_plugin_int *plugin, if (options_only || state == PLUGIN_IS_DISABLED) { - ret= 0; + ret= !options_only && plugin_is_forced(plugin); goto err; } @@ -1671,8 +1677,7 @@ int plugin_init(int *argc, char **argv, int flags) while ((plugin_ptr= *(--reap))) { mysql_mutex_unlock(&LOCK_plugin); - if (plugin_ptr->load_option == PLUGIN_FORCE || - plugin_ptr->load_option == PLUGIN_FORCE_PLUS_PERMANENT) + if (plugin_is_forced(plugin_ptr)) reaped_mandatory_plugin= TRUE; plugin_deinitialize(plugin_ptr, true); mysql_mutex_lock(&LOCK_plugin); @@ -3536,8 +3541,7 @@ static int construct_options(MEM_ROOT *mem_root, struct st_plugin_int *tmp, plugin_dash.length + 1); strxmov(plugin_name_with_prefix_ptr, plugin_dash.str, plugin_name_ptr, NullS); - if (tmp->load_option != PLUGIN_FORCE && - tmp->load_option != PLUGIN_FORCE_PLUS_PERMANENT) + if (!plugin_is_forced(tmp)) { /* support --skip-plugin-foo syntax */ options[0].name= plugin_name_ptr; @@ -3855,8 +3859,7 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp, We adjust the default value to account for the hardcoded exceptions we have set for the federated and ndbcluster storage engines. */ - if (tmp->load_option != PLUGIN_FORCE && - tmp->load_option != PLUGIN_FORCE_PLUS_PERMANENT) + if (!plugin_is_forced(tmp)) opts[0].def_value= opts[1].def_value= plugin_load_option; error= handle_options(argc, &argv, opts, NULL); @@ -3872,8 +3875,7 @@ static int test_plugin_options(MEM_ROOT *tmp_root, struct st_plugin_int *tmp, Set plugin loading policy from option value. First element in the option list is always the <plugin name> option value. */ - if (tmp->load_option != PLUGIN_FORCE && - tmp->load_option != PLUGIN_FORCE_PLUS_PERMANENT) + if (!plugin_is_forced(tmp)) plugin_load_option= (enum_plugin_load_option) *(ulong*) opts[0].value; } diff --git a/sql/sql_priv.h b/sql/sql_priv.h index 09a22ba0444..2c9a22d4bd9 100644 --- a/sql/sql_priv.h +++ b/sql/sql_priv.h @@ -121,7 +121,7 @@ #define OPTION_AUTOCOMMIT (1ULL << 8) // THD, user #define OPTION_BIG_SELECTS (1ULL << 9) // THD, user #define OPTION_LOG_OFF (1ULL << 10) // THD, user -#define OPTION_QUOTE_SHOW_CREATE (1ULL << 11) // THD, user, unused +#define OPTION_QUOTE_SHOW_CREATE (1ULL << 11) // THD, user #define TMP_TABLE_ALL_COLUMNS (1ULL << 12) // SELECT, intern #define OPTION_WARNINGS (1ULL << 13) // THD, user #define OPTION_AUTO_IS_NULL (1ULL << 14) // THD, user, binlog diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 6a281a4583e..7be9bfb7838 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1305,6 +1305,7 @@ TODO: make view to decide if it is possible to write to WHERE directly or make S DBUG_PRINT("info",("Select tables optimized away")); zero_result_cause= "Select tables optimized away"; tables_list= 0; // All tables resolved + select_lex->min_max_opt_list.empty(); const_tables= top_join_tab_count= table_count; /* Extract all table-independent conditions and replace the WHERE @@ -2942,8 +2943,11 @@ void JOIN::exec_inner() if (sort_table_cond) { if (!curr_table->select) + { if (!(curr_table->select= new SQL_SELECT)) DBUG_VOID_RETURN; + curr_table->select->head= curr_table->table; + } if (!curr_table->select->cond) curr_table->select->cond= sort_table_cond; else @@ -8076,6 +8080,63 @@ bool JOIN_TAB::hash_join_is_possible() } +/** + @brief + Check whether a KEYUSE can be really used for access this join table + + @param join Join structure with the best join order + for which the check is performed + @param keyuse Evaluated KEYUSE structure + + @details + This function is supposed to be used after the best execution plan have been + already chosen and the JOIN_TAB array for the best join order been already set. + For a given KEYUSE to access this JOIN_TAB in the best execution plan the + function checks whether it really can be used. The function first performs + the check with access_from_tables_is_allowed(). If it succeeds it checks + whether the keyuse->val does not use some fields of a materialized semijoin + nest that cannot be used to build keys to access outer tables. + Such KEYUSEs exists for the query like this: + select * from ot + where ot.c in (select it1.c from it1, it2 where it1.c=f(it2.c)) + Here we have two KEYUSEs to access table ot: with val=it1.c and val=f(it2.c). + However if the subquery was materialized the second KEYUSE cannot be employed + to access ot. + + @retval true the given keyuse can be used for ref access of this JOIN_TAB + @retval false otherwise +*/ + +bool JOIN_TAB::keyuse_is_valid_for_access_in_chosen_plan(JOIN *join, + KEYUSE *keyuse) +{ + if (!access_from_tables_is_allowed(keyuse->used_tables, + join->sjm_lookup_tables)) + return false; + if (join->sjm_scan_tables & table->map) + return true; + table_map keyuse_sjm_scan_tables= keyuse->used_tables & + join->sjm_scan_tables; + if (!keyuse_sjm_scan_tables) + return true; + uint sjm_tab_nr= 0; + while (!(keyuse_sjm_scan_tables & table_map(1) << sjm_tab_nr)) + sjm_tab_nr++; + JOIN_TAB *sjm_tab= join->map2table[sjm_tab_nr]; + TABLE_LIST *emb_sj_nest= sjm_tab->emb_sj_nest; + if (!(emb_sj_nest->sj_mat_info && emb_sj_nest->sj_mat_info->is_used && + emb_sj_nest->sj_mat_info->is_sj_scan)) + return true; + st_select_lex *sjm_sel= emb_sj_nest->sj_subq_pred->unit->first_select(); + for (uint i= 0; i < sjm_sel->item_list.elements; i++) + { + if (sjm_sel->ref_pointer_array[i] == keyuse->val) + return true; + } + return false; +} + + static uint cache_record_length(JOIN *join,uint idx) { @@ -8623,6 +8684,7 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab, do { if (!(~used_tables & keyuse->used_tables) && + join_tab->keyuse_is_valid_for_access_in_chosen_plan(join, keyuse) && are_tables_local(join_tab, keyuse->used_tables)) { if (first_keyuse) @@ -8637,6 +8699,8 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab, { if (curr->keypart == keyuse->keypart && !(~used_tables & curr->used_tables) && + join_tab->keyuse_is_valid_for_access_in_chosen_plan(join, + keyuse) && are_tables_local(join_tab, curr->used_tables)) break; } @@ -8671,6 +8735,7 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab, do { if (!(~used_tables & keyuse->used_tables) && + join_tab->keyuse_is_valid_for_access_in_chosen_plan(join, keyuse) && are_tables_local(join_tab, keyuse->used_tables)) { bool add_key_part= TRUE; @@ -8680,7 +8745,9 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab, { if (curr->keypart == keyuse->keypart && !(~used_tables & curr->used_tables) && - are_tables_local(join_tab, curr->used_tables)) + join_tab->keyuse_is_valid_for_access_in_chosen_plan(join, + curr) && + are_tables_local(join_tab, curr->used_tables)) { keyuse->keypart= NO_KEYPART; add_key_part= FALSE; @@ -8782,8 +8849,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, do { if (!(~used_tables & keyuse->used_tables) && - j->access_from_tables_is_allowed(keyuse->used_tables, - join->sjm_lookup_tables)) + j->keyuse_is_valid_for_access_in_chosen_plan(join, keyuse)) { if (are_tables_local(j, keyuse->val->used_tables())) { @@ -8853,8 +8919,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, for (i=0 ; i < keyparts ; keyuse++,i++) { while (((~used_tables) & keyuse->used_tables) || - !j->access_from_tables_is_allowed(keyuse->used_tables, - join->sjm_lookup_tables) || + !j->keyuse_is_valid_for_access_in_chosen_plan(join, keyuse) || keyuse->keypart == NO_KEYPART || (keyuse->keypart != (is_hash_join_key_no(key) ? diff --git a/sql/sql_select.h b/sql/sql_select.h index d51bca785a5..4f1b7bd7e05 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -534,6 +534,8 @@ typedef struct st_join_table { !(used_sjm_lookup_tables & ~emb_sj_nest->sj_inner_tables)); } + bool keyuse_is_valid_for_access_in_chosen_plan(JOIN *join, KEYUSE *keyuse); + void remove_redundant_bnl_scan_conds(); } JOIN_TAB; @@ -1000,6 +1002,11 @@ public: to materialize and access by lookups */ table_map sjm_lookup_tables; + /** + Bitmap of semijoin tables that the chosen plan decided + to materialize to scan the results of materialization + */ + table_map sjm_scan_tables; /* Constant tables for which we have found a row (as opposed to those for which we didn't). @@ -1341,6 +1348,7 @@ public: pre_sort_join_tab= NULL; emb_sjm_nest= NULL; sjm_lookup_tables= 0; + sjm_scan_tables= 0; exec_saved_explain= false; /* |