summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc11
-rw-r--r--sql/item.cc2
-rw-r--r--sql/log.cc5
-rw-r--r--sql/log.h6
-rw-r--r--sql/log_event.cc44
-rw-r--r--sql/log_event.h17
-rw-r--r--sql/mysqld.cc1
-rw-r--r--sql/mysqld.h1
-rw-r--r--sql/opt_range.cc7
-rw-r--r--sql/protocol.cc4
-rw-r--r--sql/rpl_utility.h2
-rw-r--r--sql/slave.cc12
-rw-r--r--sql/sql_acl.cc1
-rw-r--r--sql/sql_class.cc138
-rw-r--r--sql/sql_delete.cc8
-rw-r--r--sql/sql_plugin.cc2
-rw-r--r--sql/sql_plugin.h4
-rw-r--r--sql/sql_profile.cc6
-rw-r--r--sql/sql_repl.cc2
-rw-r--r--sql/sql_select.cc6
-rw-r--r--sql/sql_show.cc7
-rw-r--r--sql/sql_table.cc49
-rw-r--r--sql/sql_update.cc9
-rw-r--r--sql/sql_yacc.yy18
-rw-r--r--sql/sys_vars.cc9
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",