diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/events.cc | 27 | ||||
-rw-r--r-- | sql/events.h | 8 | ||||
-rw-r--r-- | sql/field.cc | 18 | ||||
-rw-r--r-- | sql/rpl_utility.cc | 16 | ||||
-rw-r--r-- | sql/sql_parse.cc | 23 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 3 | ||||
-rw-r--r-- | sql/sys_vars.cc | 24 | ||||
-rw-r--r-- | sql/udf_example.c | 2 |
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'. ** */ |