summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/events.cc27
-rw-r--r--sql/events.h8
-rw-r--r--sql/field.cc18
-rw-r--r--sql/rpl_utility.cc16
-rw-r--r--sql/sql_parse.cc23
-rw-r--r--sql/sql_prepare.cc3
-rw-r--r--sql/sys_vars.cc24
-rw-r--r--sql/udf_example.c2
8 files changed, 82 insertions, 39 deletions
diff --git a/sql/events.cc b/sql/events.cc
index d8bf549321e..a2375b1274b 100644
--- a/sql/events.cc
+++ b/sql/events.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004-2006 MySQL AB, 2008-2009 Sun Microsystems, Inc
+/* Copyright (c) 2004, 2010, 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
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#include "mysql_priv.h"
#include "events.h"
@@ -367,15 +367,14 @@ Events::create_event(THD *thd, Event_parse_data *parse_data,
{
sql_print_error("Event Error: An error occurred while creating query string, "
"before writing it into binary log.");
- /* Restore the state of binlog format */
- DBUG_ASSERT(!thd->is_current_stmt_binlog_format_row());
- if (save_binlog_row_based)
- thd->set_current_stmt_binlog_format_row();
- DBUG_RETURN(TRUE);
+ ret= TRUE;
+ }
+ else
+ {
+ /* If the definer is not set or set to CURRENT_USER, the value of CURRENT_USER
+ will be written into the binary log as the definer for the SQL thread. */
+ ret= write_bin_log(thd, TRUE, log_query.c_ptr(), log_query.length());
}
- /* If the definer is not set or set to CURRENT_USER, the value of CURRENT_USER
- will be written into the binary log as the definer for the SQL thread. */
- ret= write_bin_log(thd, TRUE, log_query.c_ptr(), log_query.length());
}
}
mysql_mutex_unlock(&LOCK_event_metadata);
@@ -1017,7 +1016,11 @@ Events::dump_internal_status()
puts("LLA = Last Locked At LUA = Last Unlocked At");
puts("WOC = Waiting On Condition DL = Data Locked");
- mysql_mutex_lock(&LOCK_event_metadata);
+ /*
+ opt_event_scheduler should only be accessed while
+ holding LOCK_global_system_variables.
+ */
+ mysql_mutex_lock(&LOCK_global_system_variables);
if (opt_event_scheduler == EVENTS_DISABLED)
puts("The Event Scheduler is disabled");
else
@@ -1026,7 +1029,7 @@ Events::dump_internal_status()
event_queue->dump_internal_status();
}
- mysql_mutex_unlock(&LOCK_event_metadata);
+ mysql_mutex_unlock(&LOCK_global_system_variables);
DBUG_VOID_RETURN;
}
diff --git a/sql/events.h b/sql/events.h
index 881ade37cbf..380b0d97f0a 100644
--- a/sql/events.h
+++ b/sql/events.h
@@ -1,6 +1,6 @@
#ifndef _EVENT_H_
#define _EVENT_H_
-/* Copyright (C) 2004-2006 MySQL AB, 2008-2009 Sun Microsystems, Inc
+/* Copyright (c) 2004, 2010, 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
@@ -13,7 +13,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/**
@defgroup Event_Scheduler Event Scheduler
@@ -83,6 +83,7 @@ public:
See sys_var.cc
*/
enum enum_opt_event_scheduler { EVENTS_OFF, EVENTS_ON, EVENTS_DISABLED };
+ /* Protected using LOCK_global_system_variables only. */
static uint opt_event_scheduler;
static mysql_mutex_t LOCK_event_metadata;
static bool check_if_system_tables_error();
@@ -107,9 +108,6 @@ public:
destroy_mutexes();
static bool
- switch_event_scheduler_state(enum enum_opt_event_scheduler new_state);
-
- static bool
create_event(THD *thd, Event_parse_data *parse_data, bool if_exists);
static bool
diff --git a/sql/field.cc b/sql/field.cc
index 51235d9f0e8..8efa765a4bc 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -6613,8 +6613,20 @@ uchar *Field_string::pack(uchar *to, const uchar *from,
local_char_length= my_charpos(field_charset, from, from+length,
local_char_length);
set_if_smaller(length, local_char_length);
- while (length && from[length-1] == field_charset->pad_char)
- length--;
+
+ /*
+ TODO: change charset interface to add a new function that does
+ the following or add a flag to lengthsp to do it itself
+ (this is for not packing padding adding bytes in BINARY
+ fields).
+ */
+ if (field_charset->mbmaxlen == 1)
+ {
+ while (length && from[length-1] == field_charset->pad_char)
+ length --;
+ }
+ else
+ length= field_charset->cset->lengthsp(field_charset, (const char*) from, length);
// Length always stored little-endian
*to++= (uchar) length;
@@ -6680,7 +6692,7 @@ Field_string::unpack(uchar *to,
memcpy(to, from, length);
// Pad the string with the pad character of the fields charset
- bfill(to + length, field_length - length, field_charset->pad_char);
+ field_charset->cset->fill(field_charset, (char*) to + length, field_length - length, field_charset->pad_char);
return from+length;
}
diff --git a/sql/rpl_utility.cc b/sql/rpl_utility.cc
index feb35527b62..8171d028326 100644
--- a/sql/rpl_utility.cc
+++ b/sql/rpl_utility.cc
@@ -340,7 +340,7 @@ uint32 table_def::calc_field_size(uint col, uchar *master_data) const
/**
*/
-void show_sql_type(enum_field_types type, uint16 metadata, String *str)
+void show_sql_type(enum_field_types type, uint16 metadata, String *str, CHARSET_INFO *field_cs)
{
DBUG_ENTER("show_sql_type");
DBUG_PRINT("enter", ("type: %d, metadata: 0x%x", type, metadata));
@@ -489,7 +489,7 @@ void show_sql_type(enum_field_types type, uint16 metadata, String *str)
uint bytes= (((metadata >> 4) & 0x300) ^ 0x300) + (metadata & 0x00ff);
uint32 length=
cs->cset->snprintf(cs, (char*) str->ptr(), str->alloced_length(),
- "char(%d)", bytes / cs->mbmaxlen);
+ "char(%d)", bytes / field_cs->mbmaxlen);
str->length(length);
}
break;
@@ -579,7 +579,7 @@ can_convert_field_to(Field *field,
DBUG_ENTER("can_convert_field_to");
#ifndef DBUG_OFF
char field_type_buf[MAX_FIELD_WIDTH];
- String field_type(field_type_buf, sizeof(field_type_buf), field->charset());
+ String field_type(field_type_buf, sizeof(field_type_buf), &my_charset_latin1);
field->sql_type(field_type);
DBUG_PRINT("enter", ("field_type: %s, target_type: %d, source_type: %d, source_metadata: 0x%x",
field_type.c_ptr_safe(), field->real_type(), source_type, metadata));
@@ -822,9 +822,9 @@ table_def::compatible_with(THD *thd, Relay_log_info *rli,
const char *tbl_name= table->s->table_name.str;
char source_buf[MAX_FIELD_WIDTH];
char target_buf[MAX_FIELD_WIDTH];
- String source_type(source_buf, sizeof(source_buf), field->charset());
- String target_type(target_buf, sizeof(target_buf), field->charset());
- show_sql_type(type(col), field_metadata(col), &source_type);
+ String source_type(source_buf, sizeof(source_buf), &my_charset_latin1);
+ String target_type(target_buf, sizeof(target_buf), &my_charset_latin1);
+ show_sql_type(type(col), field_metadata(col), &source_type, field->charset());
field->sql_type(target_type);
rli->report(ERROR_LEVEL, ER_SLAVE_CONVERSION_FAILED,
ER(ER_SLAVE_CONVERSION_FAILED),
@@ -842,8 +842,8 @@ table_def::compatible_with(THD *thd, Relay_log_info *rli,
{
char source_buf[MAX_FIELD_WIDTH];
char target_buf[MAX_FIELD_WIDTH];
- String source_type(source_buf, sizeof(source_buf), table->field[col]->charset());
- String target_type(target_buf, sizeof(target_buf), table->field[col]->charset());
+ String source_type(source_buf, sizeof(source_buf), &my_charset_latin1);
+ String target_type(target_buf, sizeof(target_buf), &my_charset_latin1);
tmp_table->field[col]->sql_type(source_type);
table->field[col]->sql_type(target_type);
DBUG_PRINT("debug", ("Field %s - conversion required."
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 6403ad99282..23e0d8c0d70 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1631,6 +1631,14 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
- you can't flush WITH READ LOCK a non-existent table
- you can't flush WITH READ LOCK under LOCK TABLES
- currently incompatible with the GRL (@todo: fix)
+
+ Effect on views and temporary tables.
+ ------------------------------------
+ You can only apply this command to existing base tables.
+ If a view with such name exists, ER_WRONG_OBJECT is returned.
+ If a temporary table with such name exists, it's ignored:
+ if there is a base table, it's used, otherwise ER_NO_SUCH_TABLE
+ is returned.
*/
static bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables)
@@ -1665,6 +1673,21 @@ static bool flush_tables_with_read_lock(THD *thd, TABLE_LIST *all_tables)
if (lock_table_names(thd, all_tables))
goto error;
+ for (table_list= all_tables; table_list;
+ table_list= table_list->next_global)
+ {
+ /* Remove the table from cache. */
+ mysql_mutex_lock(&LOCK_open);
+ tdc_remove_table(thd, TDC_RT_REMOVE_ALL,
+ table_list->db,
+ table_list->table_name);
+ mysql_mutex_unlock(&LOCK_open);
+
+ /* Skip views and temporary tables. */
+ table_list->required_type= FRMTYPE_TABLE; /* Don't try to flush views. */
+ table_list->open_type= OT_BASE_ONLY; /* Ignore temporary tables. */
+ }
+
if (open_and_lock_tables(thd, all_tables, FALSE,
MYSQL_OPEN_HAS_MDL_LOCK,
&lock_tables_prelocking_strategy) ||
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 31e3baca764..94a35db3a2d 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -3769,7 +3769,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
if (state == Query_arena::PREPARED)
state= Query_arena::EXECUTED;
- if (this->lex->sql_command == SQLCOM_CALL)
+ if (error == 0 && this->lex->sql_command == SQLCOM_CALL)
{
if (is_sql_prepare())
thd->protocol_text.send_out_parameters(&this->lex->param_list);
@@ -3777,7 +3777,6 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
thd->protocol->send_out_parameters(&this->lex->param_list);
}
-
/*
Log COM_EXECUTE to the general log. Note, that in case of SQL
prepared statements this causes two records to be output:
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 2e239a9161c..e14286210b4 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002-2006 MySQL AB, 2009-2010 Sun Microsystems, Inc.
+/* Copyright (c) 2002, 2010, 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
@@ -11,7 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/*
How to add new variables:
@@ -647,32 +647,40 @@ static bool event_scheduler_check(sys_var *self, THD *thd, set_var *var)
}
static bool event_scheduler_update(sys_var *self, THD *thd, enum_var_type type)
{
+ uint opt_event_scheduler_value= Events::opt_event_scheduler;
mysql_mutex_unlock(&LOCK_global_system_variables);
/*
Events::start() is heavyweight. In particular it creates a new THD,
which takes LOCK_global_system_variables internally.
Thus we have to release it here.
We need to re-take it before returning, though.
- And we need to take it *without* holding Events::LOCK_event_metadata.
+
+ Note that since we release LOCK_global_system_variables before calling
+ start/stop, there is a possibility that the server variable
+ can become out of sync with the real event scheduler state.
+
+ This can happen with two concurrent statments if the first gets
+ interrupted after start/stop but before retaking
+ LOCK_global_system_variables. However, this problem should be quite
+ rare and it's difficult to avoid it without opening up possibilities
+ for deadlocks. See bug#51160.
*/
- bool ret= Events::opt_event_scheduler == Events::EVENTS_ON
+ bool ret= opt_event_scheduler_value == Events::EVENTS_ON
? Events::start()
: Events::stop();
- mysql_mutex_unlock(&Events::LOCK_event_metadata);
mysql_mutex_lock(&LOCK_global_system_variables);
- mysql_mutex_lock(&Events::LOCK_event_metadata);
if (ret)
my_error(ER_EVENT_SET_VAR_ERROR, MYF(0));
return ret;
}
-static PolyLock_mutex PLock_event_metadata(&Events::LOCK_event_metadata);
+
static Sys_var_enum Sys_event_scheduler(
"event_scheduler", "Enable the event scheduler. Possible values are "
"ON, OFF, and DISABLED (keep the event scheduler completely "
"deactivated, it cannot be activated run-time)",
GLOBAL_VAR(Events::opt_event_scheduler), CMD_LINE(OPT_ARG),
event_scheduler_names, DEFAULT(Events::EVENTS_OFF),
- &PLock_event_metadata, NOT_IN_BINLOG,
+ NO_MUTEX_GUARD, NOT_IN_BINLOG,
ON_CHECK(event_scheduler_check), ON_UPDATE(event_scheduler_update));
#endif
diff --git a/sql/udf_example.c b/sql/udf_example.c
index 73256bb5529..fa1b44178ac 100644
--- a/sql/udf_example.c
+++ b/sql/udf_example.c
@@ -107,7 +107,7 @@
** option.
**
** If you can't get AGGREGATES to work, check that you have the column
-** 'type' in the mysql.func table. If not, run 'mysql_fix_privilege_tables'.
+** 'type' in the mysql.func table. If not, run 'mysql_upgrade'.
**
*/