diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/events.cc | 4 | ||||
-rw-r--r-- | sql/field.h | 4 | ||||
-rw-r--r-- | sql/field_conv.cc | 26 | ||||
-rw-r--r-- | sql/item.cc | 29 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 2 | ||||
-rw-r--r-- | sql/item_strfunc.h | 3 | ||||
-rw-r--r-- | sql/item_subselect.cc | 15 | ||||
-rw-r--r-- | sql/item_subselect.h | 1 | ||||
-rw-r--r-- | sql/item_sum.cc | 2 | ||||
-rw-r--r-- | sql/log.cc | 28 | ||||
-rw-r--r-- | sql/log_event.cc | 5 | ||||
-rw-r--r-- | sql/log_event.h | 22 | ||||
-rw-r--r-- | sql/mysqld.cc | 6 | ||||
-rw-r--r-- | sql/mysqld.h | 1 | ||||
-rw-r--r-- | sql/protocol.cc | 4 | ||||
-rw-r--r-- | sql/sp_head.cc | 1 | ||||
-rw-r--r-- | sql/sql_class.cc | 4 | ||||
-rw-r--r-- | sql/sql_class.h | 1 | ||||
-rw-r--r-- | sql/sql_insert.cc | 2 | ||||
-rw-r--r-- | sql/sql_lex.h | 1 | ||||
-rw-r--r-- | sql/sql_load.cc | 8 | ||||
-rw-r--r-- | sql/sql_parse.cc | 2 | ||||
-rw-r--r-- | sql/sql_select.cc | 25 | ||||
-rw-r--r-- | sql/sql_show.cc | 3 | ||||
-rw-r--r-- | sql/sys_vars.cc | 7 |
25 files changed, 154 insertions, 52 deletions
diff --git a/sql/events.cc b/sql/events.cc index 96b86e6798f..a548bda53e2 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -276,7 +276,9 @@ create_query_string(THD *thd, String *buf) /* Append definer */ append_definer(thd, buf, &(thd->lex->definer->user), &(thd->lex->definer->host)); /* Append the left part of thd->query after "DEFINER" part */ - if (buf->append(thd->lex->stmt_definition_begin)) + if (buf->append(thd->lex->stmt_definition_begin, + thd->lex->stmt_definition_end - + thd->lex->stmt_definition_begin)) return 1; return 0; diff --git a/sql/field.h b/sql/field.h index d1fcc40ff5d..66b13d02b89 100644 --- a/sql/field.h +++ b/sql/field.h @@ -685,6 +685,10 @@ public: int store_decimal(const my_decimal *); int store(const char *to,uint length,CHARSET_INFO *cs)=0; uint size_of() const { return sizeof(*this); } + uint repertoire(void) const + { + return my_charset_repertoire(field_charset); + } CHARSET_INFO *charset(void) const { return field_charset; } void set_charset(CHARSET_INFO *charset_arg) { field_charset= charset_arg; } enum Derivation derivation(void) const { return field_derivation; } diff --git a/sql/field_conv.cc b/sql/field_conv.cc index e3be33c0f3c..299865e6114 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -123,13 +123,18 @@ set_field_to_null(Field *field) return 0; } field->reset(); - if (field->table->in_use->count_cuted_fields == CHECK_FIELD_WARN) - { + switch (field->table->in_use->count_cuted_fields) { + case CHECK_FIELD_WARN: field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); + /* fall through */ + case CHECK_FIELD_IGNORE: return 0; + case CHECK_FIELD_ERROR_FOR_NULL: + if (!field->table->in_use->no_errors) + my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name); + return -1; } - if (!field->table->in_use->no_errors) - my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name); + DBUG_ASSERT(0); // impossible return -1; } @@ -179,13 +184,18 @@ set_field_to_null_with_conversions(Field *field, bool no_conversions) field->table->auto_increment_field_not_null= FALSE; return 0; // field is set in fill_record() } - if (field->table->in_use->count_cuted_fields == CHECK_FIELD_WARN) - { + switch (field->table->in_use->count_cuted_fields) { + case CHECK_FIELD_WARN: field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_BAD_NULL_ERROR, 1); + /* fall through */ + case CHECK_FIELD_IGNORE: return 0; + case CHECK_FIELD_ERROR_FOR_NULL: + if (!field->table->in_use->no_errors) + my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name); + return -1; } - if (!field->table->in_use->no_errors) - my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name); + DBUG_ASSERT(0); // impossible return -1; } diff --git a/sql/item.cc b/sql/item.cc index 209d5aa0197..9c712e30bca 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1796,7 +1796,16 @@ bool agg_item_set_converter(DTCollation &coll, const char *fname, if (!(conv= (*arg)->safe_charset_converter(coll.collation)) && ((*arg)->collation.repertoire == MY_REPERTOIRE_ASCII)) - conv= new Item_func_conv_charset(*arg, coll.collation, 1); + { + /* + We should disable const subselect item evaluation because + subselect transformation does not happen in view_prepare_mode + and thus val_...() methods can not be called for const items. + */ + bool resolve_const= ((*arg)->type() == Item::SUBSELECT_ITEM && + thd->lex->view_prepare_mode) ? FALSE : TRUE; + conv= new Item_func_conv_charset(*arg, coll.collation, resolve_const); + } if (!conv) { @@ -3765,7 +3774,7 @@ void Item_copy_decimal::copy() { my_decimal *nr= item->val_decimal(&cached_value); if (nr && nr != &cached_value) - memcpy (&cached_value, nr, sizeof (my_decimal)); + my_decimal2decimal (nr, &cached_value); null_value= item->null_value; } @@ -5310,14 +5319,22 @@ int Item_field::save_in_field(Field *to, bool no_conversions) if (result_field->is_null()) { null_value=1; - res= set_field_to_null_with_conversions(to, no_conversions); + return set_field_to_null_with_conversions(to, no_conversions); } - else + to->set_notnull(); + + /* + If we're setting the same field as the one we're reading from there's + nothing to do. This can happen in 'SET x = x' type of scenarios. + */ + if (to == result_field) { - to->set_notnull(); - res= field_conv(to,result_field); null_value=0; + return 0; } + + res= field_conv(to,result_field); + null_value=0; return res; } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 9ae15322265..3cf1b349946 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -372,7 +372,7 @@ String *Item_func_concat::val_str(String *str) } else if (str->alloced_length() >= res->length()+res2->length()) { - if (str == res2) + if (str->ptr() == res2->ptr()) str->replace(0,0,*res); else { diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index e3008a5daab..a72d6ba1340 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -723,8 +723,9 @@ public: String *val_str(String *); void fix_length_and_dec() { + ulonglong max_result_length= (ulonglong) args[0]->max_length * 2 + 2; + max_length= (uint32) min(max_result_length, MAX_BLOB_WIDTH); collation.set(args[0]->collation); - max_length= args[0]->max_length * 2 + 2; } }; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index c341dd97460..10ef992594e 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -130,6 +130,21 @@ void Item_subselect::cleanup() DBUG_VOID_RETURN; } + +/* + We cannot use generic Item::safe_charset_converter() because + Subselect transformation does not happen in view_prepare_mode + and thus we can not evaluate val_...() for const items. +*/ + +Item *Item_subselect::safe_charset_converter(CHARSET_INFO *tocs) +{ + Item_func_conv_charset *conv= + new Item_func_conv_charset(this, tocs, thd->lex->view_prepare_mode ? 0 : 1); + return conv->safe ? conv : NULL; +} + + void Item_singlerow_subselect::cleanup() { DBUG_ENTER("Item_singlerow_subselect::cleanup"); diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 04daab19adc..34b09ca6fdc 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -138,6 +138,7 @@ public: virtual void reset_value_registration() {} enum_parsing_place place() { return parsing_place; } bool walk(Item_processor processor, bool walk_subquery, uchar *arg); + Item *safe_charset_converter(CHARSET_INFO *tocs); /** Get the SELECT_LEX structure associated with this Item. diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 4746a6057c6..917acb0e908 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -3411,7 +3411,7 @@ void Item_func_group_concat::print(String *str, enum_query_type query_type) { if (i) str->append(','); - (*order[i]->item)->print(str, query_type); + pargs[i + arg_count_field]->print(str, query_type); if (order[i]->asc) str->append(STRING_WITH_LEN(" ASC")); else diff --git a/sql/log.cc b/sql/log.cc index 551072d2d47..a64ab013225 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1889,12 +1889,14 @@ static int binlog_savepoint_set(handlerton *hton, THD *thd, void *sv) binlog_trans_log_savepos(thd, (my_off_t*) sv); /* Write it to the binary log */ + String log_query; + if (log_query.append(STRING_WITH_LEN("SAVEPOINT ")) || + log_query.append(thd->lex->ident.str, thd->lex->ident.length)) + DBUG_RETURN(1); int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED); - int const error= - thd->binlog_query(THD::STMT_QUERY_TYPE, - thd->query(), thd->query_length(), TRUE, FALSE, FALSE, - errcode); - DBUG_RETURN(error); + Query_log_event qinfo(thd, log_query.c_ptr_safe(), log_query.length(), + TRUE, FALSE, TRUE, errcode); + DBUG_RETURN(mysql_bin_log.write(&qinfo)); } static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv) @@ -1909,12 +1911,14 @@ static int binlog_savepoint_rollback(handlerton *hton, THD *thd, void *sv) if (unlikely(thd->transaction.all.modified_non_trans_table || (thd->variables.option_bits & OPTION_KEEP_LOG))) { + String log_query; + if (log_query.append(STRING_WITH_LEN("ROLLBACK TO ")) || + log_query.append(thd->lex->ident.str, thd->lex->ident.length)) + DBUG_RETURN(1); int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED); - int error= - thd->binlog_query(THD::STMT_QUERY_TYPE, - thd->query(), thd->query_length(), TRUE, FALSE, FALSE, - errcode); - DBUG_RETURN(error); + Query_log_event qinfo(thd, log_query.c_ptr_safe(), log_query.length(), + TRUE, FALSE, TRUE, errcode); + DBUG_RETURN(mysql_bin_log.write(&qinfo)); } binlog_trans_log_truncate(thd, *(my_off_t*)sv); DBUG_RETURN(0); @@ -4608,7 +4612,9 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info) */ const char *local_db= event_info->get_db(); if ((thd && !(thd->variables.option_bits & OPTION_BIN_LOG)) || - !binlog_filter->db_ok(local_db)) + (thd->lex->sql_command != SQLCOM_ROLLBACK_TO_SAVEPOINT && + thd->lex->sql_command != SQLCOM_SAVEPOINT && + !binlog_filter->db_ok(local_db))) DBUG_RETURN(0); #endif /* HAVE_REPLICATION */ diff --git a/sql/log_event.cc b/sql/log_event.cc index a1f8a791c49..b2b2f28a63d 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -3184,10 +3184,7 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli, ::do_apply_event(), then the companion SET also have so we don't need to reset_one_shot_variables(). */ - if (!strncmp(query_arg, "BEGIN", q_len_arg) || - !strncmp(query_arg, "COMMIT", q_len_arg) || - !strncmp(query_arg, "ROLLBACK", q_len_arg) || - rpl_filter->db_ok(thd->db)) + if (is_trans_keyword() || rpl_filter->db_ok(thd->db)) { thd->set_time((time_t)when); thd->set_query_and_id((char*)query_arg, q_len_arg, next_query_id()); diff --git a/sql/log_event.h b/sql/log_event.h index 36397c427e5..206b4acdc45 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -1746,6 +1746,28 @@ public: /* !!! Public in this patch to allow old usage */ const char *query_arg, uint32 q_len_arg); #endif /* HAVE_REPLICATION */ + /* + If true, the event always be applied by slave SQL thread or be printed by + mysqlbinlog + */ + bool is_trans_keyword() + { + /* + Before the patch for bug#50407, The 'SAVEPOINT and ROLLBACK TO' + queries input by user was written into log events directly. + So the keywords can be written in both upper case and lower case + together, strncasecmp is used to check both cases. they also could be + binlogged with comments in the front of these keywords. for examples: + / * bla bla * / SAVEPOINT a; + / * bla bla * / ROLLBACK TO a; + but we don't handle these cases and after the patch, both quiries are + binlogged in upper case with no comments. + */ + return !strncmp(query, "BEGIN", q_len) || + !strncmp(query, "COMMIT", q_len) || + !strncasecmp(query, "SAVEPOINT", 9) || + !strncasecmp(query, "ROLLBACK", 8); + } }; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 2bc47849915..9c213c3d590 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -400,6 +400,7 @@ ulonglong log_output_options; my_bool opt_log_queries_not_using_indexes= 0; bool opt_error_log= IF_WIN(1,0); bool opt_disable_networking=0, opt_skip_show_db=0; +bool opt_skip_name_resolve=0; my_bool opt_character_set_client_handshake= 1; bool server_id_supplied = 0; bool opt_endinfo, using_udf_functions; @@ -6209,9 +6210,6 @@ Can't be set to 1 if --log-slave-updates is used.", #endif {"skip-host-cache", OPT_SKIP_HOST_CACHE, "Don't cache host names.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"skip-name-resolve", OPT_SKIP_RESOLVE, - "Don't resolve hostnames. All hostnames are IP's or 'localhost'.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"skip-new", OPT_SKIP_NEW, "Don't use new, possibly wrong routines.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"skip-slave-start", 0, @@ -6961,6 +6959,7 @@ static int mysql_init_variables(void) opt_log= opt_slow_log= 0; opt_bin_log= 0; opt_disable_networking= opt_skip_show_db=0; + opt_skip_name_resolve= 0; opt_ignore_builtin_innodb= 0; opt_logname= opt_update_logname= opt_binlog_index_name= opt_slow_logname= 0; opt_tc_log_file= (char *)"tc.log"; // no hostname in tc_log file name ! @@ -7328,6 +7327,7 @@ mysqld_get_one_option(int optid, opt_specialflag|= SPECIAL_NO_HOST_CACHE; break; case (int) OPT_SKIP_RESOLVE: + opt_skip_name_resolve= 1; opt_specialflag|=SPECIAL_NO_RESOLVE; break; case (int) OPT_WANT_CORE: diff --git a/sql/mysqld.h b/sql/mysqld.h index 2547100d8ff..8770e273445 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -97,6 +97,7 @@ extern ulonglong log_output_options; extern ulong log_backup_output_options; extern my_bool opt_log_queries_not_using_indexes; extern bool opt_disable_networking, opt_skip_show_db; +extern bool opt_skip_name_resolve; extern bool opt_ignore_builtin_innodb; extern my_bool opt_character_set_client_handshake; extern bool volatile abort_loop; diff --git a/sql/protocol.cc b/sql/protocol.cc index e036f255960..1903ab0c864 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -1014,8 +1014,8 @@ bool Protocol_text::store(const char *from, size_t length, { CHARSET_INFO *tocs= this->thd->variables.character_set_results; #ifndef DBUG_OFF - DBUG_PRINT("info", ("Protocol_text::store field %u (%u): %*.s", - field_pos, field_count, (int) length, from)); + DBUG_PRINT("info", ("Protocol_text::store field %u (%u): %s", field_pos, + field_count, (length == 0? "" : from))); DBUG_ASSERT(field_pos < field_count); DBUG_ASSERT(field_types == 0 || field_types[field_pos] == MYSQL_TYPE_DECIMAL || diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 62d53888149..b5ab5517ea5 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -3039,6 +3039,7 @@ int sp_instr_set_trigger_field::execute(THD *thd, uint *nextp) { DBUG_ENTER("sp_instr_set_trigger_field::execute"); + thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL; DBUG_RETURN(m_lex_keeper.reset_lex_and_exec_core(thd, nextp, TRUE, this)); } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 256f2fa730a..f1df2285262 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -3192,6 +3192,7 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup, #endif backup->option_bits= variables.option_bits; + backup->count_cuted_fields= count_cuted_fields; backup->in_sub_stmt= in_sub_stmt; backup->enable_slow_log= enable_slow_log; backup->limit_found_rows= limit_found_rows; @@ -3229,6 +3230,7 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup, void THD::restore_sub_statement_state(Sub_statement_state *backup) { + DBUG_ENTER("THD::restore_sub_statement_state"); #ifndef EMBEDDED_LIBRARY /* BUG#33029, if we are replicating from a buggy master, restore auto_inc_intervals_forced so that the top statement can use the @@ -3255,6 +3257,7 @@ void THD::restore_sub_statement_state(Sub_statement_state *backup) /* ha_release_savepoint() never returns error. */ (void)ha_release_savepoint(this, sv); } + count_cuted_fields= backup->count_cuted_fields; transaction.savepoints= backup->savepoints; variables.option_bits= backup->option_bits; in_sub_stmt= backup->in_sub_stmt; @@ -3284,6 +3287,7 @@ void THD::restore_sub_statement_state(Sub_statement_state *backup) */ examined_row_count+= backup->examined_row_count; cuted_fields+= backup->cuted_fields; + DBUG_VOID_RETURN; } diff --git a/sql/sql_class.h b/sql/sql_class.h index 950db01d1cd..0c9ad749132 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1094,6 +1094,7 @@ public: bool enable_slow_log; bool last_insert_id_used; SAVEPOINT *savepoints; + enum enum_check_fields count_cuted_fields; }; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 103be4c851f..2d2564a515c 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -3257,7 +3257,7 @@ bool select_insert::send_data(List<Item> &values) thd->count_cuted_fields= CHECK_FIELD_WARN; // Calculate cuted fields store_values(values); - thd->count_cuted_fields= CHECK_FIELD_IGNORE; + thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL; if (thd->is_error()) { table->auto_increment_field_not_null= FALSE; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index cb8a96ad2ed..7a381dabdea 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -2026,6 +2026,7 @@ struct LEX: public Query_tables_list - CREATE TRIGGER (points to "TRIGGER"); - CREATE PROCEDURE (points to "PROCEDURE"); - CREATE FUNCTION (points to "FUNCTION" or "AGGREGATE"); + - CREATE EVENT (points to "EVENT") This pointer is required to add possibly omitted DEFINER-clause to the DDL-statement before dumping it to the binlog. diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 87a347b9f98..89bb8a9634c 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -742,12 +742,10 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex, strcpy(end, p); end += pl; - thd->set_query_inner(load_data_query, end - load_data_query); - Execute_load_query_log_event - e(thd, thd->query(), thd->query_length(), - (uint) ((char*) fname_start - (char*) thd->query() - 1), - (uint) ((char*) fname_end - (char*) thd->query()), + e(thd, load_data_query, end-load_data_query, + (uint) ((char*) fname_start - load_data_query - 1), + (uint) ((char*) fname_end - load_data_query), (duplicates == DUP_REPLACE) ? LOAD_DUP_REPLACE : (ignore ? LOAD_DUP_IGNORE : LOAD_DUP_ERROR), transactional_table, FALSE, FALSE, errcode); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 8dc5f4a8c56..81c26623617 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3232,7 +3232,7 @@ end_with_restore_list: TODO: this is workaround. right way will be move invalidating in the unlock procedure. */ - if (first_table->lock_type == TL_WRITE_CONCURRENT_INSERT && + if (!res && first_table->lock_type == TL_WRITE_CONCURRENT_INSERT && thd->lock) { /* INSERT ... SELECT should invalidate only the very first table */ diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 7d379ab34de..ceaf2cb2cf3 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1126,7 +1126,7 @@ JOIN::optimize() } } - if (conds &&!outer_join && const_table_map != found_const_table_map && + if (conds && const_table_map != found_const_table_map && (select_options & SELECT_DESCRIBE) && select_lex->master_unit() == &thd->lex->unit) // upper level SELECT { @@ -1145,13 +1145,13 @@ JOIN::optimize() elements may be lost during further having condition transformation in JOIN::exec. */ - if (having && !having->with_sum_func) + if (having && const_table_map) { - COND *const_cond= make_cond_for_table(having, const_table_map, 0); - DBUG_EXECUTE("where", print_where(const_cond, "const_having_cond", - QT_ORDINARY);); - if (const_cond && !const_cond->val_int()) + having->update_used_tables(); + having= remove_eq_conds(thd, having, &having_value); + if (having_value == Item::COND_FALSE) { + having= new Item_int((longlong) 0,1); zero_result_cause= "Impossible HAVING noticed after reading const tables"; error= 0; DBUG_RETURN(0); @@ -5162,6 +5162,11 @@ greedy_search(JOIN *join, if (best_extension_by_limited_search(join, remaining_tables, idx, record_count, read_time, search_depth, prune_level)) DBUG_RETURN(TRUE); + /* + 'best_read < DBL_MAX' means that optimizer managed to find + some plan and updated 'best_positions' array accordingly. + */ + DBUG_ASSERT(join->best_read < DBL_MAX); if (size_remain <= search_depth) { @@ -8942,8 +8947,14 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top) we still make the inner tables dependent on the outer tables. It would be enough to set dependency only on one outer table for them. Yet this is really a rare case. + Note: + RAND_TABLE_BIT mask should not be counted as it + prevents update of inner table dependences. + For example it might happen if RAND() function + is used in JOIN ON clause. */ - if (!(prev_table->on_expr->used_tables() & ~prev_used_tables)) + if (!((prev_table->on_expr->used_tables() & ~RAND_TABLE_BIT) & + ~prev_used_tables)) prev_table->dep_tables|= used_tables; } } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 1b77e20cc02..891bd8f8c40 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1911,6 +1911,8 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond) mysql_mutex_unlock(&mysys_var->mutex); /* INFO */ + /* Lock THD mutex that protects its data when looking at it. */ + mysql_mutex_lock(&tmp->LOCK_thd_data); if (tmp->query()) { table->field[7]->store(tmp->query(), @@ -1918,6 +1920,7 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond) tmp->query_length()), cs); table->field[7]->set_notnull(); } + mysql_mutex_unlock(&tmp->LOCK_thd_data); if (schema_table_store_record(thd, table)) { diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 3cb1e90b124..49d272af8d3 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -1596,6 +1596,13 @@ static Sys_var_mybool Sys_skip_networking( READ_ONLY GLOBAL_VAR(opt_disable_networking), CMD_LINE(OPT_ARG), DEFAULT(FALSE)); +static Sys_var_mybool Sys_skip_name_resolve( + "skip_name_resolve", + "Don't resolve hostnames. All hostnames are IP's or 'localhost'.", + READ_ONLY GLOBAL_VAR(opt_skip_name_resolve), + CMD_LINE(OPT_ARG, OPT_SKIP_RESOLVE), + DEFAULT(FALSE)); + static Sys_var_mybool Sys_skip_show_database( "skip_show_database", "Don't allow 'SHOW DATABASE' commands", READ_ONLY GLOBAL_VAR(opt_skip_show_db), CMD_LINE(OPT_ARG), |