diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/field.cc | 11 | ||||
-rw-r--r-- | sql/item.cc | 2 | ||||
-rw-r--r-- | sql/log.cc | 5 | ||||
-rw-r--r-- | sql/log.h | 6 | ||||
-rw-r--r-- | sql/log_event.cc | 44 | ||||
-rw-r--r-- | sql/log_event.h | 17 | ||||
-rw-r--r-- | sql/mysqld.cc | 1 | ||||
-rw-r--r-- | sql/mysqld.h | 1 | ||||
-rw-r--r-- | sql/opt_range.cc | 7 | ||||
-rw-r--r-- | sql/protocol.cc | 4 | ||||
-rw-r--r-- | sql/rpl_utility.h | 2 | ||||
-rw-r--r-- | sql/slave.cc | 12 | ||||
-rw-r--r-- | sql/sql_acl.cc | 1 | ||||
-rw-r--r-- | sql/sql_class.cc | 138 | ||||
-rw-r--r-- | sql/sql_delete.cc | 8 | ||||
-rw-r--r-- | sql/sql_plugin.cc | 2 | ||||
-rw-r--r-- | sql/sql_plugin.h | 4 | ||||
-rw-r--r-- | sql/sql_profile.cc | 6 | ||||
-rw-r--r-- | sql/sql_repl.cc | 2 | ||||
-rw-r--r-- | sql/sql_select.cc | 6 | ||||
-rw-r--r-- | sql/sql_show.cc | 7 | ||||
-rw-r--r-- | sql/sql_table.cc | 49 | ||||
-rw-r--r-- | sql/sql_update.cc | 9 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 18 | ||||
-rw-r--r-- | sql/sys_vars.cc | 9 |
25 files changed, 319 insertions, 52 deletions
diff --git a/sql/field.cc b/sql/field.cc index 4fcf5b33dc1..bb668a118c4 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -9929,6 +9929,17 @@ Create_field::Create_field(Field *old_field,Field *orig_field) geom_type= ((Field_geom*)old_field)->geom_type; break; #endif + case MYSQL_TYPE_YEAR: + if (length != 4) + { + char buff[sizeof("YEAR()") + MY_INT64_NUM_DECIMAL_DIGITS + 1]; + my_snprintf(buff, sizeof(buff), "YEAR(%lu)", length); + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_NOTE, + ER_WARN_DEPRECATED_SYNTAX, + ER(ER_WARN_DEPRECATED_SYNTAX), + buff, "YEAR(4)"); + } + break; default: break; } diff --git a/sql/item.cc b/sql/item.cc index 22b5adc4597..53776782205 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -6429,7 +6429,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference) if (from_field != not_found_field) { Item_field* fld; - if (!(fld= new Item_field(from_field))) + if (!(fld= new Item_field(thd, last_checked_context, from_field))) goto error; thd->change_item_tree(reference, fld); mark_as_dependent(thd, last_checked_context->select_lex, diff --git a/sql/log.cc b/sql/log.cc index 24cee143c71..fc11dcc77ce 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2762,7 +2762,10 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time, { end= strxmov(buff, "# administrator command: ", NullS); buff_len= (ulong) (end - buff); - my_b_write(&log_file, (uchar*) buff, buff_len); + DBUG_EXECUTE_IF("simulate_slow_log_write_error", + {DBUG_SET("+d,simulate_file_write_error");}); + if(my_b_write(&log_file, (uchar*) buff, buff_len)) + tmp_errno= errno; } if (my_b_write(&log_file, (uchar*) sql_text, sql_text_len) || my_b_write(&log_file, (uchar*) ";\n",2) || diff --git a/sql/log.h b/sql/log.h index 6f86d6ca5f8..1fc13afe7d1 100644 --- a/sql/log.h +++ b/sql/log.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -353,8 +353,8 @@ class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG int new_file_impl(bool need_lock); public: - MYSQL_LOG::generate_name; - MYSQL_LOG::is_open; + using MYSQL_LOG::generate_name; + using MYSQL_LOG::is_open; /* This is relay log */ bool is_relay_log; diff --git a/sql/log_event.cc b/sql/log_event.cc index 47d1bef0eea..73c2342b6fa 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1139,7 +1139,7 @@ failed my_b_read")); Log_event *res= 0; #ifndef max_allowed_packet THD *thd=current_thd; - uint max_allowed_packet= thd ? thd->variables.max_allowed_packet : ~(ulong)0; + uint max_allowed_packet= thd ? slave_max_allowed_packet:~(ulong)0; #endif if (data_len > max_allowed_packet) @@ -5767,6 +5767,9 @@ User_var_log_event:: User_var_log_event(const char* buf, const Format_description_log_event* description_event) :Log_event(buf, description_event) +#ifndef MYSQL_CLIENT + , deferred(false) +#endif { /* The Post-Header is empty. The Variable Data part begins immediately. */ const char *start= buf; @@ -6002,7 +6005,10 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli) CHARSET_INFO *charset; if (rli->deferred_events_collecting) + { + set_deferred(); return rli->deferred_events->add(this); + } if (!(charset= get_charset(charset_number, MYF(MY_WME)))) return 1; @@ -6054,7 +6060,8 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli) return 0; } } - Item_func_set_user_var e(user_var_name, it); + + Item_func_set_user_var *e= new Item_func_set_user_var(user_var_name, it); /* Item_func_set_user_var can't substitute something else on its place => 0 can be passed as last argument (reference on item) @@ -6063,7 +6070,7 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli) crash the server, so if fix fields fails, we just return with an error. */ - if (e.fix_fields(thd, 0)) + if (e->fix_fields(thd, 0)) return 1; /* @@ -6071,9 +6078,10 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli) a single record and with a single column. Thus, like a column value, it could always have IMPLICIT derivation. */ - e.update_hash(val, val_len, type, charset, DERIVATION_IMPLICIT, - (flags & User_var_log_event::UNSIGNED_F)); - free_root(thd->mem_root,0); + e->update_hash(val, val_len, type, charset, DERIVATION_IMPLICIT, + (flags & User_var_log_event::UNSIGNED_F)); + if (!is_deferred()) + free_root(thd->mem_root, 0); return 0; } @@ -6470,11 +6478,18 @@ void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info { Load_log_event::print(file, print_event_info, !check_fname_outside_temp_buf()); - /* - That one is for "file_id: etc" below: in mysqlbinlog we want the #, in - SHOW BINLOG EVENTS we don't. - */ - my_b_printf(&cache, "#"); + /** + reduce the size of io cache so that the write function is called + for every call to my_b_printf(). + */ + DBUG_EXECUTE_IF ("simulate_create_event_write_error", + {(&cache)->write_pos= (&cache)->write_end; + DBUG_SET("+d,simulate_file_write_error");}); + /* + That one is for "file_id: etc" below: in mysqlbinlog we want the #, in + SHOW BINLOG EVENTS we don't. + */ + my_b_printf(&cache, "#"); } my_b_printf(&cache, " file_id: %d block_len: %d\n", file_id, block_len); @@ -7161,6 +7176,13 @@ void Execute_load_query_log_event::print(FILE* file, Write_on_release_cache cache(&print_event_info->head_cache, file); print_query_header(&cache, print_event_info); + /** + reduce the size of io cache so that the write function is called + for every call to my_b_printf(). + */ + DBUG_EXECUTE_IF ("simulate_execute_event_write_error", + {(&cache)->write_pos= (&cache)->write_end; + DBUG_SET("+d,simulate_file_write_error");}); if (local_fname) { diff --git a/sql/log_event.h b/sql/log_event.h index 5ad90bda00f..000c7420ca8 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -280,6 +280,13 @@ struct sql_ex_info MAX_SIZE_LOG_EVENT_STATUS + /* status */ \ NAME_LEN + 1) +/* + The new option is added to handle large packets that are sent from the master + to the slave. It is used to increase the thd(max_allowed) for both the + DUMP thread on the master and the SQL/IO thread on the slave. +*/ +#define MAX_MAX_ALLOWED_PACKET 1024*1024*1024 + /* Event header offsets; these point to places inside the fixed header. @@ -2557,12 +2564,13 @@ public: bool is_null; uchar flags; #ifdef MYSQL_SERVER + bool deferred; User_var_log_event(THD* thd_arg, char *name_arg, uint name_len_arg, char *val_arg, ulong val_len_arg, Item_result type_arg, uint charset_number_arg, uchar flags_arg) :Log_event(), name(name_arg), name_len(name_len_arg), val(val_arg), val_len(val_len_arg), type(type_arg), charset_number(charset_number_arg), - flags(flags_arg) + flags(flags_arg), deferred(false) { is_null= !val; } void pack_info(Protocol* protocol); #else @@ -2575,6 +2583,13 @@ public: Log_event_type get_type_code() { return USER_VAR_EVENT;} #ifdef MYSQL_SERVER bool write(IO_CACHE* file); + /* + Getter and setter for deferred User-event. + Returns true if the event is not applied directly + and which case the applier adjusts execution path. + */ + bool is_deferred() { return deferred; } + void set_deferred() { deferred= val; } #endif bool is_valid() const { return 1; } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index df9fbaa8652..90fd1f1e126 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -469,6 +469,7 @@ ulonglong slave_type_conversions_options; ulong thread_cache_size=0; ulong binlog_cache_size=0; ulonglong max_binlog_cache_size=0; +ulong slave_max_allowed_packet= 0; ulong binlog_stmt_cache_size=0; ulonglong max_binlog_stmt_cache_size=0; ulong query_cache_size=0; diff --git a/sql/mysqld.h b/sql/mysqld.h index 2604e889ebd..632bcfe975f 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -179,6 +179,7 @@ extern ulong open_files_limit; extern ulong binlog_cache_size, binlog_stmt_cache_size; extern ulonglong max_binlog_cache_size, max_binlog_stmt_cache_size; extern ulong max_binlog_size, max_relay_log_size; +extern ulong slave_max_allowed_packet; extern ulong opt_binlog_rows_event_max_size; extern ulong rpl_recovery_rank, thread_cache_size; extern ulong stored_program_cache_size; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 8a6607cf343..03f444c22b5 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -9463,9 +9463,10 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time) have_min= TRUE; else if (min_max_item->sum_func() == Item_sum::MAX_FUNC) have_max= TRUE; - else if (min_max_item->sum_func() == Item_sum::COUNT_DISTINCT_FUNC || - min_max_item->sum_func() == Item_sum::SUM_DISTINCT_FUNC || - min_max_item->sum_func() == Item_sum::AVG_DISTINCT_FUNC) + else if (is_agg_distinct && + (min_max_item->sum_func() == Item_sum::COUNT_DISTINCT_FUNC || + min_max_item->sum_func() == Item_sum::SUM_DISTINCT_FUNC || + min_max_item->sum_func() == Item_sum::AVG_DISTINCT_FUNC)) continue; else DBUG_RETURN(NULL); diff --git a/sql/protocol.cc b/sql/protocol.cc index 53ab032517e..5c1533ad10d 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -722,6 +722,8 @@ bool Protocol::send_result_set_metadata(List<Item> *list, uint flags) /* Store fixed length fields */ pos= (char*) local_packet->ptr()+local_packet->length(); *pos++= 12; // Length of packed fields + /* inject a NULL to test the client */ + DBUG_EXECUTE_IF("poison_rs_fields", pos[-1]= 0xfb;); if (item->charset_for_protocol() == &my_charset_bin || thd_charset == NULL) { /* No conversion */ diff --git a/sql/rpl_utility.h b/sql/rpl_utility.h index 55b0431b938..c07f1a32490 100644 --- a/sql/rpl_utility.h +++ b/sql/rpl_utility.h @@ -271,7 +271,7 @@ private: public: Deferred_log_events(Relay_log_info *rli); ~Deferred_log_events(); - /* queue for exection at Query-log-event time prior the Query */; + /* queue for exection at Query-log-event time prior the Query */ int add(Log_event *ev); bool is_empty(); bool execute(Relay_log_info *rli); diff --git a/sql/slave.cc b/sql/slave.cc index 94425317a77..f456beaa9d4 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2077,8 +2077,7 @@ static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type) slave threads, since a replication event can become this much larger than the corresponding packet (query) sent from client to master. */ - thd->variables.max_allowed_packet= global_system_variables.max_allowed_packet - + MAX_LOG_EVENT_HEADER; /* note, incr over the global not session var */ + thd->variables.max_allowed_packet= slave_max_allowed_packet; thd->slave_thread = 1; thd->enable_slow_log= opt_log_slow_slave_statements; set_slave_thread_options(thd); @@ -2834,6 +2833,7 @@ pthread_handler_t handle_slave_io(void *arg) thread, since a replication event can become this much larger than the corresponding packet (query) sent from client to master. */ + thd->net.max_packet_size= slave_max_allowed_packet; mysql->net.max_packet_size= thd->net.max_packet_size+= MAX_LOG_EVENT_HEADER; } else @@ -2966,12 +2966,12 @@ reading event")) switch (mysql_error_number) { case CR_NET_PACKET_TOO_LARGE: sql_print_error("\ -Log entry on master is longer than max_allowed_packet (%ld) on \ +Log entry on master is longer than slave_max_allowed_packet (%lu) on \ slave. If the entry is correct, restart the server with a higher value of \ -max_allowed_packet", - thd->variables.max_allowed_packet); +slave_max_allowed_packet", + slave_max_allowed_packet); mi->report(ERROR_LEVEL, ER_NET_PACKET_TOO_LARGE, - "%s", ER(ER_NET_PACKET_TOO_LARGE)); + "%s", "Got a packet bigger than 'slave_max_allowed_packet' bytes"); goto err; case ER_MASTER_FATAL_ERROR_READING_BINLOG: mi->report(ERROR_LEVEL, ER_MASTER_FATAL_ERROR_READING_BINLOG, diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index d3715fd2312..242967fff6a 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -8032,6 +8032,7 @@ static bool send_server_handshake_packet(MPVIO_EXT *mpvio, int2store(end + 3, mpvio->server_status[0]); int2store(end + 5, mpvio->client_capabilities >> 16); end[7]= data_len; + DBUG_EXECUTE_IF("poison_srv_handshake_scramble_len", end[7]= -100;); bzero(end + 8, 10); end+= 18; /* write scramble tail */ diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 7e93157c69e..8931d67dd25 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -4806,6 +4806,134 @@ show_query_type(THD::enum_binlog_query_type qtype) } #endif +/* + Constants required for the limit unsafe warnings suppression +*/ +//seconds after which the limit unsafe warnings suppression will be activated +#define LIMIT_UNSAFE_WARNING_ACTIVATION_TIMEOUT 50 +//number of limit unsafe warnings after which the suppression will be activated +#define LIMIT_UNSAFE_WARNING_ACTIVATION_THRESHOLD_COUNT 50 + +static ulonglong limit_unsafe_suppression_start_time= 0; +static bool unsafe_warning_suppression_is_activated= false; +static int limit_unsafe_warning_count= 0; + +/** + Auxiliary function to reset the limit unsafety warning suppression. +*/ +static void reset_binlog_unsafe_suppression() +{ + DBUG_ENTER("reset_binlog_unsafe_suppression"); + unsafe_warning_suppression_is_activated= false; + limit_unsafe_warning_count= 0; + limit_unsafe_suppression_start_time= my_getsystime()/10000000; + DBUG_VOID_RETURN; +} + +/** + Auxiliary function to print warning in the error log. +*/ +static void print_unsafe_warning_to_log(int unsafe_type, char* buf, + char* query) +{ + DBUG_ENTER("print_unsafe_warning_in_log"); + sprintf(buf, ER(ER_BINLOG_UNSAFE_STATEMENT), + ER(LEX::binlog_stmt_unsafe_errcode[unsafe_type])); + sql_print_warning(ER(ER_MESSAGE_AND_STATEMENT), buf, query); + DBUG_VOID_RETURN; +} + +/** + Auxiliary function to check if the warning for limit unsafety should be + thrown or suppressed. Details of the implementation can be found in the + comments inline. + SYNOPSIS: + @params + buf - buffer to hold the warning message text + unsafe_type - The type of unsafety. + query - The actual query statement. + + TODO: Remove this function and implement a general service for all warnings + that would prevent flooding the error log. +*/ +static void do_unsafe_limit_checkout(char* buf, int unsafe_type, char* query) +{ + ulonglong now= 0; + DBUG_ENTER("do_unsafe_limit_checkout"); + DBUG_ASSERT(unsafe_type == LEX::BINLOG_STMT_UNSAFE_LIMIT); + limit_unsafe_warning_count++; + /* + INITIALIZING: + If this is the first time this function is called with log warning + enabled, the monitoring the unsafe warnings should start. + */ + if (limit_unsafe_suppression_start_time == 0) + { + limit_unsafe_suppression_start_time= my_getsystime()/10000000; + print_unsafe_warning_to_log(unsafe_type, buf, query); + } + else + { + if (!unsafe_warning_suppression_is_activated) + print_unsafe_warning_to_log(unsafe_type, buf, query); + + if (limit_unsafe_warning_count >= + LIMIT_UNSAFE_WARNING_ACTIVATION_THRESHOLD_COUNT) + { + now= my_getsystime()/10000000; + if (!unsafe_warning_suppression_is_activated) + { + /* + ACTIVATION: + We got LIMIT_UNSAFE_WARNING_ACTIVATION_THRESHOLD_COUNT warnings in + less than LIMIT_UNSAFE_WARNING_ACTIVATION_TIMEOUT we activate the + suppression. + */ + if ((now-limit_unsafe_suppression_start_time) <= + LIMIT_UNSAFE_WARNING_ACTIVATION_TIMEOUT) + { + unsafe_warning_suppression_is_activated= true; + DBUG_PRINT("info",("A warning flood has been detected and the limit \ +unsafety warning suppression has been activated.")); + } + else + { + /* + there is no flooding till now, therefore we restart the monitoring + */ + limit_unsafe_suppression_start_time= my_getsystime()/10000000; + limit_unsafe_warning_count= 0; + } + } + else + { + /* + Print the suppression note and the unsafe warning. + */ + sql_print_information("The following warning was suppressed %d times \ +during the last %d seconds in the error log", + limit_unsafe_warning_count, + (int) + (now-limit_unsafe_suppression_start_time)); + print_unsafe_warning_to_log(unsafe_type, buf, query); + /* + DEACTIVATION: We got LIMIT_UNSAFE_WARNING_ACTIVATION_THRESHOLD_COUNT + warnings in more than LIMIT_UNSAFE_WARNING_ACTIVATION_TIMEOUT, the + suppression should be deactivated. + */ + if ((now - limit_unsafe_suppression_start_time) > + LIMIT_UNSAFE_WARNING_ACTIVATION_TIMEOUT) + { + reset_binlog_unsafe_suppression(); + DBUG_PRINT("info",("The limit unsafety warning supression has been \ +deactivated")); + } + } + limit_unsafe_warning_count= 0; + } + } + DBUG_VOID_RETURN; +} /** Auxiliary method used by @c binlog_query() to raise warnings. @@ -4815,6 +4943,7 @@ show_query_type(THD::enum_binlog_query_type qtype) */ void THD::issue_unsafe_warnings() { + char buf[MYSQL_ERRMSG_SIZE * 2]; DBUG_ENTER("issue_unsafe_warnings"); /* Ensure that binlog_unsafe_warning_flags is big enough to hold all @@ -4840,17 +4969,16 @@ void THD::issue_unsafe_warnings() ER(LEX::binlog_stmt_unsafe_errcode[unsafe_type])); if (global_system_variables.log_warnings) { - char buf[MYSQL_ERRMSG_SIZE * 2]; - sprintf(buf, ER(ER_BINLOG_UNSAFE_STATEMENT), - ER(LEX::binlog_stmt_unsafe_errcode[unsafe_type])); - sql_print_warning(ER(ER_MESSAGE_AND_STATEMENT), buf, query()); + if (unsafe_type == LEX::BINLOG_STMT_UNSAFE_LIMIT) + do_unsafe_limit_checkout( buf, unsafe_type, query()); + else //cases other than LIMIT unsafety + print_unsafe_warning_to_log(unsafe_type, buf, query()); } } } DBUG_VOID_RETURN; } - /** Log the current query. diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 4fd1815ad7f..1bbc9af0835 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -341,8 +341,14 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, break; } } - else + /* + Don't try unlocking the row if skip_record reported an error since in + this case the transaction might have been rolled back already. + */ + else if (!thd->is_error()) table->file->unlock_row(); // Row failed selection, release lock on it + else + break; } killed_status= thd->killed; if (killed_status != THD::NOT_KILLED || thd->is_error()) diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index a5c5cec5f66..47827e0e567 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -714,7 +714,7 @@ bool plugin_is_ready(const LEX_STRING *name, int type) } -SHOW_COMP_OPTION plugin_status(const char *name, int len, size_t type) +SHOW_COMP_OPTION plugin_status(const char *name, size_t len, int type) { LEX_STRING plugin_name= { (char *) name, len }; return plugin_status(&plugin_name, type); diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h index c3e6cc6fb28..da59e6ee58a 100644 --- a/sql/sql_plugin.h +++ b/sql/sql_plugin.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -154,7 +154,7 @@ extern bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name); extern bool plugin_register_builtin(struct st_mysql_plugin *plugin); extern void plugin_thdvar_init(THD *thd); extern void plugin_thdvar_cleanup(THD *thd); -extern SHOW_COMP_OPTION plugin_status(const char *name, int len, size_t type); +extern SHOW_COMP_OPTION plugin_status(const char *name, size_t len, int type); extern bool check_valid_path(const char *path, size_t length); typedef my_bool (plugin_foreach_func)(THD *thd, diff --git a/sql/sql_profile.cc b/sql/sql_profile.cc index cd06408045e..70bec36b03d 100644 --- a/sql/sql_profile.cc +++ b/sql/sql_profile.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -83,8 +83,8 @@ ST_FIELD_INFO query_profile_statistics_info[]= int make_profile_table_for_show(THD *thd, ST_SCHEMA_TABLE *schema_table) { - int profile_options = thd->lex->profile_options; - int fields_include_condition_truth_values[]= { + uint profile_options = thd->lex->profile_options; + uint fields_include_condition_truth_values[]= { FALSE, /* Query_id */ FALSE, /* Seq */ TRUE, /* Status */ diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 5968c17f871..16b6a7594eb 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -588,7 +588,7 @@ impossible position"; this larger than the corresponding packet (query) sent from client to master. */ - thd->variables.max_allowed_packet+= MAX_LOG_EVENT_HEADER; + thd->variables.max_allowed_packet= MAX_MAX_ALLOWED_PACKET; /* We can set log_lock now, it does not move (it's a member of diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 211b10617fa..42e9fbfa650 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -557,6 +557,8 @@ JOIN::prepare(Item ***rref_pointer_array, if (having) { + Query_arena backup, *arena; + arena= thd->activate_stmt_arena_if_needed(&backup); nesting_map save_allow_sum_func= thd->lex->allow_sum_func; thd->where="having clause"; thd->lex->allow_sum_func|= 1 << select_lex_arg->nest_level; @@ -565,6 +567,10 @@ JOIN::prepare(Item ***rref_pointer_array, (having->fix_fields(thd, &having) || having->check_cols(1))); select_lex->having_fix_field= 0; + select_lex->having= having; + if (arena) + thd->restore_active_arena(arena, &backup); + if (having_fix_rc || thd->is_error()) DBUG_RETURN(-1); /* purecov: inspected */ thd->lex->allow_sum_func= save_allow_sum_func; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 189532b2479..e9873d2325f 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2784,9 +2784,12 @@ int make_db_list(THD *thd, List<LEX_STRING> *files, /* If we have db lookup vaule we just add it to list and - exit from the function + exit from the function. + We don't do this for database names longer than the maximum + path length. */ - if (lookup_field_vals->db_value.str) + if (lookup_field_vals->db_value.str && + lookup_field_vals->db_value.length < FN_REFLEN) { if (is_infoschema_db(lookup_field_vals->db_value.str, lookup_field_vals->db_value.length)) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 60ae2ed800b..7d70fa8afd2 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -6313,11 +6313,23 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, the primary key is not added and dropped in the same statement. Otherwise we have to recreate the table. need_copy_table is no-zero at this place. + + Also, in-place is not possible if we add a primary key + and drop another key in the same statement. If the drop fails, + we will not be able to revert adding of primary key. */ if ( pk_changed < 2 ) { - if ((alter_flags & needed_inplace_with_read_flags) == - needed_inplace_with_read_flags) + if ((needed_inplace_with_read_flags & HA_INPLACE_ADD_PK_INDEX_NO_WRITE) && + index_drop_count > 0) + { + /* + Do copy, not in-place ALTER. + Avoid setting ALTER_TABLE_METADATA_ONLY. + */ + } + else if ((alter_flags & needed_inplace_with_read_flags) == + needed_inplace_with_read_flags) { /* All required in-place flags to allow concurrent reads are present. */ need_copy_table= ALTER_TABLE_METADATA_ONLY; @@ -6579,17 +6591,38 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, Tell the handler to prepare for drop indexes. This re-numbers the indexes to get rid of gaps. */ - if ((error= table->file->prepare_drop_index(table, key_numbers, - index_drop_count))) + error= table->file->prepare_drop_index(table, key_numbers, + index_drop_count); + if (!error) { - table->file->print_error(error, MYF(0)); - goto err_new_table_cleanup; + /* Tell the handler to finally drop the indexes. */ + error= table->file->final_drop_index(table); } - /* Tell the handler to finally drop the indexes. */ - if ((error= table->file->final_drop_index(table))) + if (error) { table->file->print_error(error, MYF(0)); + if (index_add_count) // Drop any new indexes added. + { + /* + Temporarily set table-key_info to include information about the + indexes added above that we now need to drop. + */ + KEY *save_key_info= table->key_info; + table->key_info= key_info_buffer; + if ((error= table->file->prepare_drop_index(table, index_add_buffer, + index_add_count))) + table->file->print_error(error, MYF(0)); + else if ((error= table->file->final_drop_index(table))) + table->file->print_error(error, MYF(0)); + table->key_info= save_key_info; + } + + /* + Mark this TABLE instance as stale to avoid + out-of-sync index information. + */ + table->m_needs_reopen= true; goto err_new_table_cleanup; } } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 754170e4c55..c4a95edcfc2 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -450,6 +450,15 @@ int mysql_update(THD *thd, { // Check if we are modifying a key that we are used to search with: used_key_is_modified= is_key_used(table, used_index, table->write_set); } + else if (select && select->quick) + { + /* + select->quick != NULL and used_index == MAX_KEY happens for index + merge and should be handled in a different way. + */ + used_key_is_modified= (!select->quick->unique_key_range() && + select->quick->is_keys_used(table->write_set)); + } #ifdef WITH_PARTITION_STORAGE_ENGINE if (used_key_is_modified || order || diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index bf7ca6b02ed..45024faa03f 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -5465,7 +5465,23 @@ type: $$= MYSQL_TYPE_VARCHAR; } | YEAR_SYM opt_field_length field_options - { $$=MYSQL_TYPE_YEAR; } + { + if (Lex->length) + { + errno= 0; + ulong length= strtoul(Lex->length, NULL, 10); + if (errno == 0 && length <= MAX_FIELD_BLOBLENGTH && length != 4) + { + char buff[sizeof("YEAR()") + MY_INT64_NUM_DECIMAL_DIGITS + 1]; + my_snprintf(buff, sizeof(buff), "YEAR(%lu)", length); + push_warning_printf(YYTHD, MYSQL_ERROR::WARN_LEVEL_NOTE, + ER_WARN_DEPRECATED_SYNTAX, + ER(ER_WARN_DEPRECATED_SYNTAX), + buff, "YEAR(4)"); + } + } + $$=MYSQL_TYPE_YEAR; + } | DATE_SYM { $$=MYSQL_TYPE_DATE; } | TIME_SYM diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index f15664bca10..e0523989f9d 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -45,6 +45,7 @@ #include "derror.h" // read_texts #include "sql_base.h" // close_cached_tables +#include "log_event.h" #ifdef WITH_PERFSCHEMA_STORAGE_ENGINE #include "../storage/perfschema/pfs_server.h" #endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */ @@ -1131,6 +1132,14 @@ static Sys_var_ulong Sys_max_allowed_packet( BLOCK_SIZE(1024), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_max_allowed_packet)); +static Sys_var_ulong Sys_slave_max_allowed_packet( + "slave_max_allowed_packet", + "The maximum packet length to sent successfully from the master to slave.", + GLOBAL_VAR(slave_max_allowed_packet), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(1024, MAX_MAX_ALLOWED_PACKET), + DEFAULT(MAX_MAX_ALLOWED_PACKET), + BLOCK_SIZE(1024)); + static Sys_var_ulonglong Sys_max_binlog_cache_size( "max_binlog_cache_size", "Sets the total size of the transactional cache", |