summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorAlfranio Correia <alfranio.correia@sun.com>2010-06-01 14:49:31 +0100
committerAlfranio Correia <alfranio.correia@sun.com>2010-06-01 14:49:31 +0100
commitc54aabc93bfef93d8da7c4d4852a1d124ce549f7 (patch)
treefd3e39e11c99318f0d9755c7c1abf6fa06afd139 /sql
parentff6cf4bb462cf2d6fc0b761c40639f268eb0b5f5 (diff)
parent835759603561e0a12443c760dfcae37961c1948d (diff)
downloadmariadb-git-c54aabc93bfef93d8da7c4d4852a1d124ce549f7.tar.gz
auto-merge mysql-trunk-bugfixing (local) --> mysql-trunk-bugfixing.merge
Diffstat (limited to 'sql')
-rw-r--r--sql/share/errmsg-utf8.txt8
-rw-r--r--sql/sql_base.cc4
-rw-r--r--sql/sql_class.cc14
-rw-r--r--sql/sql_class.h3
-rw-r--r--sql/sys_vars.cc68
5 files changed, 82 insertions, 15 deletions
diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index 598f563ac87..f6ed6330749 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -6336,3 +6336,11 @@ ER_BINLOG_UNSAFE_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE
ER_BINLOG_UNSAFE_MIXED_STATEMENT
eng "Statements that read from both transactional (or a temporary table of any engine type) and non-transactional tables and write to any of them are unsafe."
+
+ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_SQL_LOG_BIN
+ eng "Cannot modify @@session.sql_log_bin inside a transaction"
+
+ER_STORED_FUNCTION_PREVENTS_SWITCH_SQL_LOG_BIN
+ eng "Cannot change the sql_log_bin inside a stored function or trigger"
+
+
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 1e537112d01..325f054db02 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -4007,9 +4007,9 @@ thr_lock_type read_lock_type_for_table(THD *thd,
prelocked mode we can't rely on OPTION_BIN_LOG flag in THD::options
bitmap to determine that binary logging is turned on as this bit can
be cleared before executing sub-statement. So instead we have to look
- at THD::sql_log_bin_toplevel member.
+ at THD::variables::sql_log_bin member.
*/
- bool log_on= mysql_bin_log.is_open() && thd->sql_log_bin_toplevel;
+ bool log_on= mysql_bin_log.is_open() && thd->variables.sql_log_bin;
ulong binlog_format= thd->variables.binlog_format;
if ((log_on == FALSE) || (binlog_format == BINLOG_FORMAT_ROW) ||
(table_list->table->s->table_category == TABLE_CATEGORY_LOG) ||
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 814ef27e574..dfe17fe5779 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -491,7 +491,6 @@ THD::THD()
rli_fake(0),
lock_id(&main_lock_id),
user_time(0), in_sub_stmt(0),
- sql_log_bin_toplevel(false),
binlog_unsafe_warning_flags(0), binlog_table_maps(0),
table_map_for_update(0),
arg_of_last_insert_id_function(FALSE),
@@ -960,7 +959,11 @@ void THD::init(void)
update_charset();
reset_current_stmt_binlog_format_row();
bzero((char *) &status_var, sizeof(status_var));
- sql_log_bin_toplevel= variables.option_bits & OPTION_BIN_LOG;
+
+ if (variables.sql_log_bin)
+ variables.option_bits|= OPTION_BIN_LOG;
+ else
+ variables.option_bits&= ~OPTION_BIN_LOG;
#if defined(ENABLED_DEBUG_SYNC)
/* Initialize the Debug Sync Facility. See debug_sync.cc. */
@@ -4608,8 +4611,13 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, char const *query_arg,
because the warnings should be printed only if the statement is
actually logged. When executing decide_logging_format(), we cannot
know for sure if the statement will be logged.
+
+ Besides, we should not try to print these warnings if it is not
+ possible to write statements to the binary log as it happens when
+ the execution is inside a function, or generaly speaking, when
+ the variables.option_bits & OPTION_BIN_LOG is false.
*/
- if (sql_log_bin_toplevel)
+ if (variables.option_bits & OPTION_BIN_LOG)
issue_unsafe_warnings();
switch (qtype) {
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 22143eb1498..15aef33bcb3 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -428,6 +428,7 @@ typedef struct system_variables
uint binlog_format; ///< binlog format for this thd (see enum_binlog_format)
my_bool binlog_direct_non_trans_update;
+ my_bool sql_log_bin;
uint completion_type;
uint query_cache_type;
uint tx_isolation;
@@ -1672,8 +1673,6 @@ public:
/* <> 0 if we are inside of trigger or stored function. */
uint in_sub_stmt;
- /* TRUE when the current top has SQL_LOG_BIN ON */
- bool sql_log_bin_toplevel;
/* container for handler's private per-connection data */
Ha_data ha_data[MAX_HA];
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 5c1a44ba844..48a5cf06147 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -2243,17 +2243,69 @@ static Sys_var_bit Sys_log_off(
SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_LOG_OFF,
DEFAULT(FALSE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_has_super));
-static bool fix_sql_log_bin(sys_var *self, THD *thd, enum_var_type type)
+/**
+ This function sets the session variable thd->variables.sql_log_bin
+ to reflect changes to @@session.sql_log_bin.
+
+ @param[IN] self A pointer to the sys_var, i.e. Sys_log_binlog.
+ @param[IN] type The type either session or global.
+
+ @return @c FALSE.
+*/
+static bool fix_sql_log_bin_after_update(sys_var *self, THD *thd,
+ enum_var_type type)
{
- if (type != OPT_GLOBAL && !thd->in_sub_stmt)
- thd->sql_log_bin_toplevel= thd->variables.option_bits & OPTION_BIN_LOG;
- return false;
+ if (type == OPT_SESSION)
+ {
+ if (thd->variables.sql_log_bin)
+ thd->variables.option_bits |= OPTION_BIN_LOG;
+ else
+ thd->variables.option_bits &= ~OPTION_BIN_LOG;
+ }
+ return FALSE;
}
-static Sys_var_bit Sys_log_binlog(
+
+/**
+ This function checks if the sql_log_bin can be changed,
+ what is possible if:
+ - the user is a super user;
+ - the set is not called from within a function/trigger;
+ - there is no on-going transaction.
+
+ @param[IN] self A pointer to the sys_var, i.e. Sys_log_binlog.
+ @param[IN] var A pointer to the set_var created by the parser.
+
+ @return @c FALSE if the change is allowed, otherwise @c TRUE.
+*/
+static bool check_sql_log_bin(sys_var *self, THD *thd, set_var *var)
+{
+ if (check_has_super(self, thd, var))
+ return TRUE;
+
+ if (var->type == OPT_GLOBAL)
+ return FALSE;
+
+ /* If in a stored function/trigger, it's too late to change sql_log_bin. */
+ if (thd->in_sub_stmt)
+ {
+ my_error(ER_STORED_FUNCTION_PREVENTS_SWITCH_SQL_LOG_BIN, MYF(0));
+ return TRUE;
+ }
+ /* Make the session variable 'sql_log_bin' read-only inside a transaction. */
+ if (thd->in_active_multi_stmt_transaction())
+ {
+ my_error(ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_SQL_LOG_BIN, MYF(0));
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static Sys_var_mybool Sys_log_binlog(
"sql_log_bin", "sql_log_bin",
- SESSION_VAR(option_bits), NO_CMD_LINE, OPTION_BIN_LOG,
- DEFAULT(TRUE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_has_super),
- ON_UPDATE(fix_sql_log_bin));
+ SESSION_VAR(sql_log_bin), NO_CMD_LINE,
+ DEFAULT(TRUE), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_sql_log_bin),
+ ON_UPDATE(fix_sql_log_bin_after_update));
static Sys_var_bit Sys_sql_warnings(
"sql_warnings", "sql_warnings",