diff options
Diffstat (limited to 'sql/set_var.cc')
-rw-r--r-- | sql/set_var.cc | 57 |
1 files changed, 54 insertions, 3 deletions
diff --git a/sql/set_var.cc b/sql/set_var.cc index 12f3a61aa4e..7ff3401b102 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -141,6 +141,7 @@ static int check_log_update(THD *thd, set_var *var); static bool set_log_update(THD *thd, set_var *var); static int check_pseudo_thread_id(THD *thd, set_var *var); static bool set_log_bin(THD *thd, set_var *var); +void fix_binlog_format_after_update(THD *thd, enum_var_type type); static void fix_low_priority_updates(THD *thd, enum_var_type type); static int check_tx_isolation(THD *thd, set_var *var); static void fix_tx_isolation(THD *thd, enum_var_type type); @@ -185,6 +186,8 @@ sys_var_bool_ptr sys_automatic_sp_privileges("automatic_sp_privileges", sys_var_long_ptr sys_binlog_cache_size("binlog_cache_size", &binlog_cache_size); +sys_var_thd_binlog_format sys_binlog_format("binlog_format", + &SV::binlog_format); sys_var_thd_ulong sys_bulk_insert_buff_size("bulk_insert_buffer_size", &SV::bulk_insert_buff_size); sys_var_character_set_server sys_character_set_server("character_set_server"); @@ -653,11 +656,11 @@ static int show_slave_skip_errors(THD *thd, SHOW_VAR *var, char *buff) var->value= buff; if (!use_slave_mask || bitmap_is_clear_all(&slave_error_mask)) { - var->value= "OFF"; + var->value= const_cast<char *>("OFF"); } else if (bitmap_is_set_all(&slave_error_mask)) { - var->value= "ALL"; + var->value= const_cast<char *>("ALL"); } else { @@ -706,7 +709,7 @@ SHOW_VAR init_vars[]= { {"bdb_shared_data", (char*) &berkeley_shared_data, SHOW_BOOL}, {"bdb_tmpdir", (char*) &berkeley_tmpdir, SHOW_CHAR_PTR}, {sys_binlog_cache_size.name,(char*) &sys_binlog_cache_size, SHOW_SYS}, - {"binlog_format", (char*) &opt_binlog_format, SHOW_CHAR_PTR}, + {sys_binlog_format.name, (char*) &sys_binlog_format, SHOW_SYS}, {sys_bulk_insert_buff_size.name,(char*) &sys_bulk_insert_buff_size,SHOW_SYS}, {sys_character_set_client.name,(char*) &sys_character_set_client, SHOW_SYS}, {sys_character_set_connection.name,(char*) &sys_character_set_connection,SHOW_SYS}, @@ -1243,6 +1246,54 @@ extern void fix_delay_key_write(THD *thd, enum_var_type type) } } + +bool sys_var_thd_binlog_format::is_readonly() const +{ + /* + Under certain circumstances, the variable is read-only (unchangeable): + */ + THD *thd= current_thd; + /* + If RBR and open temporary tables, their CREATE TABLE may not be in the + binlog, so we can't toggle to SBR in this connection. + The test below will also prevent SET GLOBAL, well it was not easy to test + if global or not here. + And this test will also prevent switching from RBR to RBR (a no-op which + should not happen too often). + */ + if ((thd->variables.binlog_format == BINLOG_FORMAT_ROW) && + thd->temporary_tables) + { + my_error(ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR, MYF(0)); + return 1; + } + /* + if in a stored function, it's too late to change mode + */ + if (thd->spcont && thd->prelocked_mode) + { + DBUG_ASSERT(thd->variables.binlog_format != BINLOG_FORMAT_ROW); + my_error(ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT, MYF(0)); + return 1; + } +#ifdef HAVE_NDB_BINLOG + /* + Cluster does not support changing the binlog format on the fly yet. + */ + if (opt_bin_log && (have_ndbcluster == SHOW_OPTION_YES)) + { + my_error(ER_NDB_CANT_SWITCH_BINLOG_FORMAT, MYF(0)); + return 1; + } +#endif + return sys_var_thd_enum::is_readonly(); +} + +void fix_binlog_format_after_update(THD *thd, enum_var_type type) +{ + thd->reset_current_stmt_binlog_row_based(); +} + static void fix_max_binlog_size(THD *thd, enum_var_type type) { DBUG_ENTER("fix_max_binlog_size"); |