Commit 9cd6325b authored by unknown's avatar unknown

Merge gbichot@bk-internal.mysql.com:/home/bk/mysql-5.1-new

into  mysql.com:/home/mysql_src/mysql-5.1-new


sql/mysqld.cc:
  Auto merged
sql/sp_head.cc:
  Auto merged
sql/share/errmsg.txt:
  Auto merged
sql/sql_show.cc:
  Auto merged
sql/sql_table.cc:
  Auto merged
parents 8f4cec20 7cac0ddf
set session binlog_format=row;
ERROR HY000: The NDB cluster engine does not support changing the binlog format on the fly yet
set session binlog_format=statement;
ERROR HY000: The NDB cluster engine does not support changing the binlog format on the fly yet
set global binlog_format=row;
ERROR HY000: The NDB cluster engine does not support changing the binlog format on the fly yet
set global binlog_format=statement;
ERROR HY000: The NDB cluster engine does not support changing the binlog format on the fly yet
set session binlog_format=default;
ERROR HY000: The NDB cluster engine does not support changing the binlog format on the fly yet
set global binlog_format=default;
ERROR HY000: The NDB cluster engine does not support changing the binlog format on the fly yet
......@@ -24,4 +24,4 @@ a
ABE
ANG
LIL
DROP TABLE t1,t2;
DROP DATABASE mysqltest1;
stop slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
drop database if exists mysqltest1;
create database mysqltest1;
use mysqltest1;
show global variables like "binlog_format%";
Variable_name Value
binlog_format ROW
show session variables like "binlog_format%";
Variable_name Value
binlog_format ROW
select @@global.binlog_format, @@session.binlog_format;
@@global.binlog_format @@session.binlog_format
ROW ROW
CREATE TABLE t1 (a varchar(100));
prepare stmt1 from 'insert into t1 select concat(UUID(),?)';
set @string="emergency";
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;
prepare stmt1 from 'insert into t1 select ?';
insert into t1 values(concat(UUID(),"work"));
execute stmt1 using @string;
deallocate prepare stmt1;
insert into t1 values(concat("for",UUID()));
insert into t1 select "yesterday";
create temporary table tmp(a char(3));
insert into tmp values("see");
set binlog_format=statement;
ERROR HY000: Cannot switch out of the row-based binary log format when the session has open temporary tables
insert into t1 select * from tmp;
drop temporary table tmp;
set binlog_format=statement;
show global variables like "binlog_format%";
Variable_name Value
binlog_format ROW
show session variables like "binlog_format%";
Variable_name Value
binlog_format STATEMENT
select @@global.binlog_format, @@session.binlog_format;
@@global.binlog_format @@session.binlog_format
ROW STATEMENT
set global binlog_format=statement;
show global variables like "binlog_format%";
Variable_name Value
binlog_format STATEMENT
show session variables like "binlog_format%";
Variable_name Value
binlog_format STATEMENT
select @@global.binlog_format, @@session.binlog_format;
@@global.binlog_format @@session.binlog_format
STATEMENT STATEMENT
prepare stmt1 from 'insert into t1 select ?';
set @string="emergency";
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;
prepare stmt1 from 'insert into t1 select ?';
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;
insert into t1 values("for");
insert into t1 select "yesterday";
set binlog_format=default;
select @@global.binlog_format, @@session.binlog_format;
@@global.binlog_format @@session.binlog_format
STATEMENT STATEMENT
set global binlog_format=default;
ERROR 42000: Variable 'binlog_format' doesn't have a default value
select @@global.binlog_format, @@session.binlog_format;
@@global.binlog_format @@session.binlog_format
STATEMENT STATEMENT
prepare stmt1 from 'insert into t1 select ?';
set @string="emergency";
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;
prepare stmt1 from 'insert into t1 select ?';
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;
insert into t1 values("for");
insert into t1 select "yesterday";
set binlog_format=mixed;
select @@global.binlog_format, @@session.binlog_format;
@@global.binlog_format @@session.binlog_format
STATEMENT MIXED
set global binlog_format=mixed;
select @@global.binlog_format, @@session.binlog_format;
@@global.binlog_format @@session.binlog_format
MIXED MIXED
prepare stmt1 from 'insert into t1 select concat(UUID(),?)';
set @string="emergency";
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;
prepare stmt1 from 'insert into t1 select ?';
insert into t1 values(concat(UUID(),"work"));
execute stmt1 using @string;
deallocate prepare stmt1;
insert into t1 values(concat("for",UUID()));
insert into t1 select "yesterday";
prepare stmt1 from 'insert into t1 select ?';
insert into t1 values(concat(UUID(),"work"));
execute stmt1 using @string;
deallocate prepare stmt1;
insert into t1 values(concat("for",UUID()));
insert into t1 select "yesterday";
create procedure foo()
begin
insert into t1 values("work");
insert into t1 values(concat("for",UUID()));
insert into t1 select "yesterday";
end|
create procedure foo2()
begin
insert into t1 values(concat("emergency",UUID()));
insert into t1 values("work");
insert into t1 values(concat("for",UUID()));
set session binlog_format=row; # accepted for stored procs
insert into t1 values("more work");
set session binlog_format=mixed;
end|
create function foo3() returns bigint unsigned
begin
set session binlog_format=row; # rejected for stored funcs
insert into t1 values("alarm");
return 100;
end|
call foo();
call foo2();
select foo3();
ERROR HY000: Cannot change the binary logging format inside a stored function or trigger
select * from t1 where a="alarm";
a
show binlog events from 102;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 102 Query 1 205 drop database if exists mysqltest1
master-bin.000001 205 Query 1 300 create database mysqltest1
master-bin.000001 300 Query 1 401 use `mysqltest1`; CREATE TABLE t1 (a varchar(100))
master-bin.000001 401 Table_map 1 446 mysqltest1.t1
master-bin.000001 446 Write_rows 1 481
master-bin.000001 481 Table_map 1 526 mysqltest1.t1
master-bin.000001 526 Write_rows 1 602
master-bin.000001 602 Table_map 1 647 mysqltest1.t1
master-bin.000001 647 Write_rows 1 718
master-bin.000001 718 Table_map 1 763 mysqltest1.t1
master-bin.000001 763 Write_rows 1 803
master-bin.000001 803 Table_map 1 848 mysqltest1.t1
master-bin.000001 848 Write_rows 1 918
master-bin.000001 918 Table_map 1 963 mysqltest1.t1
master-bin.000001 963 Write_rows 1 1003
master-bin.000001 1003 Table_map 1 1048 mysqltest1.t1
master-bin.000001 1048 Write_rows 1 1082
master-bin.000001 1082 Query 1 1180 use `mysqltest1`; insert into t1 values("work")
master-bin.000001 1180 User var 1 1228 @`string`=_latin1 0x656D657267656E6379 COLLATE latin1_swedish_ci
master-bin.000001 1228 Query 1 1328 use `mysqltest1`; insert into t1 select @'string'
master-bin.000001 1328 Query 1 1426 use `mysqltest1`; insert into t1 values("work")
master-bin.000001 1426 User var 1 1474 @`string`=_latin1 0x656D657267656E6379 COLLATE latin1_swedish_ci
master-bin.000001 1474 Query 1 1574 use `mysqltest1`; insert into t1 select @'string'
master-bin.000001 1574 Query 1 1671 use `mysqltest1`; insert into t1 values("for")
master-bin.000001 1671 Query 1 1773 use `mysqltest1`; insert into t1 select "yesterday"
master-bin.000001 1773 Query 1 1871 use `mysqltest1`; insert into t1 values("work")
master-bin.000001 1871 User var 1 1919 @`string`=_latin1 0x656D657267656E6379 COLLATE latin1_swedish_ci
master-bin.000001 1919 Query 1 2019 use `mysqltest1`; insert into t1 select @'string'
master-bin.000001 2019 Query 1 2117 use `mysqltest1`; insert into t1 values("work")
master-bin.000001 2117 User var 1 2165 @`string`=_latin1 0x656D657267656E6379 COLLATE latin1_swedish_ci
master-bin.000001 2165 Query 1 2265 use `mysqltest1`; insert into t1 select @'string'
master-bin.000001 2265 Query 1 2362 use `mysqltest1`; insert into t1 values("for")
master-bin.000001 2362 Query 1 2464 use `mysqltest1`; insert into t1 select "yesterday"
master-bin.000001 2464 Query 1 2562 use `mysqltest1`; insert into t1 values("work")
master-bin.000001 2562 Table_map 1 2607 mysqltest1.t1
master-bin.000001 2607 Write_rows 1 2683
master-bin.000001 2683 Table_map 1 2728 mysqltest1.t1
master-bin.000001 2728 Write_rows 1 2799
master-bin.000001 2799 User var 1 2847 @`string`=_latin1 0x656D657267656E6379 COLLATE latin1_swedish_ci
master-bin.000001 2847 Query 1 2947 use `mysqltest1`; insert into t1 select @'string'
master-bin.000001 2947 Table_map 1 2992 mysqltest1.t1
master-bin.000001 2992 Write_rows 1 3062
master-bin.000001 3062 Query 1 3164 use `mysqltest1`; insert into t1 select "yesterday"
master-bin.000001 3164 Table_map 1 3209 mysqltest1.t1
master-bin.000001 3209 Write_rows 1 3280
master-bin.000001 3280 User var 1 3328 @`string`=_latin1 0x656D657267656E6379 COLLATE latin1_swedish_ci
master-bin.000001 3328 Query 1 3428 use `mysqltest1`; insert into t1 select @'string'
master-bin.000001 3428 Table_map 1 3473 mysqltest1.t1
master-bin.000001 3473 Write_rows 1 3543
master-bin.000001 3543 Query 1 3645 use `mysqltest1`; insert into t1 select "yesterday"
master-bin.000001 3645 Query 1 3857 use `mysqltest1`; create procedure foo()
begin
insert into t1 values("work");
insert into t1 values(concat("for",UUID()));
insert into t1 select "yesterday";
end
master-bin.000001 3857 Query 1 4214 use `mysqltest1`; create procedure foo2()
begin
insert into t1 values(concat("emergency",UUID()));
insert into t1 values("work");
insert into t1 values(concat("for",UUID()));
set session binlog_format=row; # accepted for stored procs
insert into t1 values("more work");
set session binlog_format=mixed;
end
master-bin.000001 4214 Query 1 4442 use `mysqltest1`; create function foo3() returns bigint unsigned
begin
set session binlog_format=row; # rejected for stored funcs
insert into t1 values("alarm");
return 100;
end
master-bin.000001 4442 Query 1 4548 use `mysqltest1`; insert into t1 values("work")
master-bin.000001 4548 Table_map 1 4593 mysqltest1.t1
master-bin.000001 4593 Write_rows 1 4663
master-bin.000001 4663 Query 1 4773 use `mysqltest1`; insert into t1 select "yesterday"
master-bin.000001 4773 Table_map 1 4818 mysqltest1.t1
master-bin.000001 4818 Write_rows 1 4894
master-bin.000001 4894 Query 1 5000 use `mysqltest1`; insert into t1 values("work")
master-bin.000001 5000 Table_map 1 5045 mysqltest1.t1
master-bin.000001 5045 Write_rows 1 5115
master-bin.000001 5115 Table_map 1 5160 mysqltest1.t1
master-bin.000001 5160 Write_rows 1 5200
drop database mysqltest1;
-- source include/have_ndb.inc
--error ER_NDB_CANT_SWITCH_BINLOG_FORMAT
set session binlog_format=row;
--error ER_NDB_CANT_SWITCH_BINLOG_FORMAT
set session binlog_format=statement;
--error ER_NDB_CANT_SWITCH_BINLOG_FORMAT
set global binlog_format=row;
--error ER_NDB_CANT_SWITCH_BINLOG_FORMAT
set global binlog_format=statement;
--error ER_NDB_CANT_SWITCH_BINLOG_FORMAT
set session binlog_format=default;
--error ER_NDB_CANT_SWITCH_BINLOG_FORMAT
set global binlog_format=default;
......@@ -29,5 +29,5 @@ select * from t1 order by a;
select * from t2 order by a;
connection master;
DROP TABLE t1,t2;
DROP DATABASE mysqltest1;
sync_slave_with_master;
-- source include/have_binlog_format_row.inc
-- source include/master-slave.inc
connection master;
--disable_warnings
drop database if exists mysqltest1;
create database mysqltest1;
--enable_warnings
use mysqltest1;
show global variables like "binlog_format%";
show session variables like "binlog_format%";
select @@global.binlog_format, @@session.binlog_format;
CREATE TABLE t1 (a varchar(100));
prepare stmt1 from 'insert into t1 select concat(UUID(),?)';
set @string="emergency";
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;
prepare stmt1 from 'insert into t1 select ?';
insert into t1 values(concat(UUID(),"work"));
execute stmt1 using @string;
deallocate prepare stmt1;
insert into t1 values(concat("for",UUID()));
insert into t1 select "yesterday";
# verify that temp tables prevent a switch to SBR
create temporary table tmp(a char(3));
insert into tmp values("see");
--error ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR
set binlog_format=statement;
insert into t1 select * from tmp;
drop temporary table tmp;
# Now we go to SBR
set binlog_format=statement;
show global variables like "binlog_format%";
show session variables like "binlog_format%";
select @@global.binlog_format, @@session.binlog_format;
set global binlog_format=statement;
show global variables like "binlog_format%";
show session variables like "binlog_format%";
select @@global.binlog_format, @@session.binlog_format;
prepare stmt1 from 'insert into t1 select ?';
set @string="emergency";
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;
prepare stmt1 from 'insert into t1 select ?';
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;
insert into t1 values("for");
insert into t1 select "yesterday";
# test SET DEFAULT (=statement at this point of test)
set binlog_format=default;
select @@global.binlog_format, @@session.binlog_format;
# due to cluster it's hard to set back to default
--error ER_NO_DEFAULT
set global binlog_format=default;
select @@global.binlog_format, @@session.binlog_format;
prepare stmt1 from 'insert into t1 select ?';
set @string="emergency";
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;
prepare stmt1 from 'insert into t1 select ?';
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;
insert into t1 values("for");
insert into t1 select "yesterday";
# and now the mixed mode
set binlog_format=mixed;
select @@global.binlog_format, @@session.binlog_format;
set global binlog_format=mixed;
select @@global.binlog_format, @@session.binlog_format;
prepare stmt1 from 'insert into t1 select concat(UUID(),?)';
set @string="emergency";
insert into t1 values("work");
execute stmt1 using @string;
deallocate prepare stmt1;
prepare stmt1 from 'insert into t1 select ?';
insert into t1 values(concat(UUID(),"work"));
execute stmt1 using @string;
deallocate prepare stmt1;
insert into t1 values(concat("for",UUID()));
insert into t1 select "yesterday";
prepare stmt1 from 'insert into t1 select ?';
insert into t1 values(concat(UUID(),"work"));
execute stmt1 using @string;
deallocate prepare stmt1;
insert into t1 values(concat("for",UUID()));
insert into t1 select "yesterday";
# inside a stored procedure (inside a function or trigger won't
# work)
delimiter |;
create procedure foo()
begin
insert into t1 values("work");
insert into t1 values(concat("for",UUID()));
insert into t1 select "yesterday";
end|
create procedure foo2()
begin
insert into t1 values(concat("emergency",UUID()));
insert into t1 values("work");
insert into t1 values(concat("for",UUID()));
set session binlog_format=row; # accepted for stored procs
insert into t1 values("more work");
set session binlog_format=mixed;
end|
create function foo3() returns bigint unsigned
begin
set session binlog_format=row; # rejected for stored funcs
insert into t1 values("alarm");
return 100;
end|
delimiter ;|
call foo();
call foo2();
# test that can't SET in a stored function if not in row-based mode
--error ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT
select foo3();
select * from t1 where a="alarm";
# and now compare:
show binlog events from 102;
sync_slave_with_master;
# as we're using UUID we don't SELECT but use "diff" like in rpl_row_UUID
--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info mysqltest1 > ./var/tmp/rpl_row_UDF_master.sql
--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info mysqltest1 > ./var/tmp/rpl_row_UDF_slave.sql
connection master;
drop database mysqltest1;
sync_slave_with_master;
# Let's compare. Note: If they match test will pass, if they do not match
# the test will show that the diff statement failed and not reject file
# will be created. You will need to go to the mysql-test dir and diff
# the files your self to see what is not matching
#--exec diff ./var/tmp/rpl_row_UDF_master.sql ./var/tmp/rpl_row_UDF_slave.sql;
......@@ -177,9 +177,10 @@ handlerton archive_hton = {
NULL, /* Partition flags */
NULL, /* Alter table flags */
NULL, /* Alter interface */
NULL, /* fill_files_table */
HTON_NO_FLAGS,
NULL, /* binlog_func */
NULL /* binlog_log_query */
NULL, /* binlog_func */
NULL /* binlog_log_query */
};
static handler *archive_create_handler(TABLE_SHARE *table)
......
......@@ -153,7 +153,9 @@ handlerton berkeley_hton = {
NULL, /* Alter table flags */
NULL, /* Alter Tablespace */
NULL, /* Fill Files Table */
HTON_CLOSE_CURSORS_AT_COMMIT | HTON_FLUSH_AFTER_RENAME
HTON_CLOSE_CURSORS_AT_COMMIT | HTON_FLUSH_AFTER_RENAME,
NULL, /* binlog_func */
NULL /* binlog_log_query */
};
handler *berkeley_create_handler(TABLE_SHARE *table)
......
......@@ -61,7 +61,9 @@ handlerton blackhole_hton= {
NULL, /* Alter table flags */
NULL, /* Alter Tablespace */
NULL, /* Fill FILES table */
HTON_CAN_RECREATE
HTON_CAN_RECREATE,
NULL, /* binlog_func */
NULL /* binlog_log_query */
};
......
......@@ -398,7 +398,9 @@ handlerton federated_hton= {
NULL, /* Alter table flags */
NULL, /* Alter Tablespace */
NULL, /* Fill FILES table */
HTON_ALTER_NOT_SUPPORTED
HTON_ALTER_NOT_SUPPORTED,
NULL, /* binlog_func */
NULL /* binlog_log_query */
};
......
......@@ -58,7 +58,9 @@ handlerton heap_hton= {
NULL, /* Alter table flags */
NULL, /* Alter Tablespace */
NULL, /* Fill Files Table */
HTON_CAN_RECREATE
HTON_CAN_RECREATE,
NULL, /* binlog_func */
NULL /* binlog_log_query */
};
static handler *heap_create_handler(TABLE_SHARE *table)
......
......@@ -237,8 +237,11 @@ handlerton innobase_hton = {
innobase_show_status, /* Show status */
NULL, /* Partition flags */
NULL, /* Alter table flags */
NULL, /* alter_tablespace */
NULL, /* Fill FILES table */
HTON_NO_FLAGS
HTON_NO_FLAGS,
NULL, /* binlog_func */
NULL /* binlog_log_query */
};
......
......@@ -90,7 +90,9 @@ handlerton myisam_hton= {
NULL, /* Alter table flags */
NULL, /* Alter Tablespace */
NULL, /* Fill Files Table */
HTON_CAN_RECREATE
HTON_CAN_RECREATE,
NULL, /* binlog_func */
NULL /* binlog_log_query */
};
......
......@@ -68,7 +68,9 @@ handlerton myisammrg_hton= {
NULL, /* Alter table flags */
NULL, /* Alter Tablespace */
NULL, /* Fill Files Table */
HTON_CAN_RECREATE
HTON_CAN_RECREATE,
NULL, /* binlog_func */
NULL /* binlog_log_query */
};
static handler *myisammrg_create_handler(TABLE_SHARE *table)
......
......@@ -2774,7 +2774,7 @@ pthread_handler_t ndb_binlog_thread_func(void *arg)
ndb_binlog_thread_running= 1;
if (opt_bin_log)
{
if (binlog_row_based)
if (global_system_variables.binlog_format == BINLOG_FORMAT_ROW)
{
ndb_binlog_running= TRUE;
}
......
......@@ -102,7 +102,9 @@ handlerton partition_hton = {
alter_table_flags, /* Partition flags */
NULL, /* Alter Tablespace */
NULL, /* Fill FILES table */
HTON_NOT_USER_SELECTABLE | HTON_HIDDEN
HTON_NOT_USER_SELECTABLE | HTON_HIDDEN,
NULL, /* binlog_func */
NULL /* binlog_log_query */
};
/*
......@@ -2609,7 +2611,7 @@ void ha_partition::unlock_row()
ADDITIONAL INFO:
Most handlers set timestamp when calling write row if any such fields
exists. Since we are calling an underlying handler we assume the´
exists. Since we are calling an underlying handler we assume the´
underlying handler will assume this responsibility.
Underlying handlers will also call update_auto_increment to calculate
......
......@@ -64,7 +64,11 @@ const handlerton default_hton =
NULL, NULL, NULL,
create_default,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
HTON_NO_FLAGS
NULL, /* alter_tablespace */
NULL, /* fill_files_table */
HTON_NO_FLAGS, /* flags */
NULL, /* binlog_func */
NULL /* binlog_log_query */
};
static SHOW_COMP_OPTION have_yes= SHOW_OPTION_YES;
......@@ -3147,7 +3151,7 @@ namespace {
bool check_table_binlog_row_based(THD *thd, TABLE *table)
{
return
binlog_row_based &&
thd->current_stmt_binlog_row_based &&
thd && (thd->options & OPTION_BIN_LOG) &&
(table->s->tmp_table == NO_TMP_TABLE) &&
binlog_filter->db_ok(table->s->db.str);
......
......@@ -543,10 +543,9 @@ typedef struct
struct st_table_list *tables,
class Item *cond);
uint32 flags; /* global handler flags */
/*
Handlerton functions are not set in the different storage
engines static initialization. They are initialized at handler init.
Thus, leave them last in the struct.
/*
Those handlerton functions below are properly initialized at handler
init.
*/
int (*binlog_func)(THD *thd, enum_binlog_func fn, void *arg);
void (*binlog_log_query)(THD *thd, enum_binlog_command binlog_command,
......
......@@ -2657,6 +2657,7 @@ udf_handler::fix_fields(THD *thd, Item_result_field *func,
u_d->name.str, ER(ER_UNKNOWN_ERROR));
DBUG_RETURN(TRUE);
}
thd->set_current_stmt_binlog_row_based_if_mixed();
DBUG_RETURN(FALSE);
}
......
......@@ -3002,6 +3002,7 @@ String *Item_func_uuid::val_str(String *str)
char *s;
THD *thd= current_thd;
thd->set_current_stmt_binlog_row_based_if_mixed();
pthread_mutex_lock(&LOCK_uuid_generator);
if (! uuid_time) /* first UUID() call. initializing data */
{
......
......@@ -102,7 +102,9 @@ handlerton binlog_hton = {
NULL, /* Alter table flags */
NULL, /* Alter Tablespace */
NULL, /* Fill FILES table */
HTON_NOT_USER_SELECTABLE | HTON_HIDDEN
HTON_NOT_USER_SELECTABLE | HTON_HIDDEN,
NULL, /* binlog_func */
NULL /* binlog_log_query */
};
......@@ -2630,7 +2632,7 @@ THD::binlog_set_pending_rows_event(Rows_log_event* ev)
int MYSQL_LOG::flush_and_set_pending_rows_event(THD *thd, Rows_log_event* event)
{
DBUG_ENTER("MYSQL_LOG::flush_and_set_pending_rows_event(event)");
DBUG_ASSERT(binlog_row_based && mysql_bin_log.is_open());
DBUG_ASSERT(thd->current_stmt_binlog_row_based && mysql_bin_log.is_open());
DBUG_PRINT("enter", ("event=%p", event));
int error= 0;
......@@ -2847,7 +2849,7 @@ bool MYSQL_LOG::write(Log_event *event_info)
*/
if (thd)
{
if (!binlog_row_based)
if (!thd->current_stmt_binlog_row_based)
{
if (thd->last_insert_id_used)
{
......@@ -3517,7 +3519,7 @@ bool MYSQL_LOG::write_table_map(THD *thd, IO_CACHE *file, TABLE* table,
table, table->s->table_name, table->s->table_map_id));
/* Pre-conditions */
DBUG_ASSERT(binlog_row_based && is_open());
DBUG_ASSERT(thd->current_stmt_binlog_row_based && is_open());
DBUG_ASSERT(table->s->table_map_id != ULONG_MAX);
#ifndef DBUG_OFF
......
......@@ -507,4 +507,24 @@ class LOGGER
void init_general_log(uint general_log_printer);
};
enum enum_binlog_format {
BINLOG_FORMAT_STMT= 0, // statement-based
#ifdef HAVE_ROW_BASED_REPLICATION
BINLOG_FORMAT_ROW= 1, // row_based
/*
statement-based except for cases where only row-based can work (UUID()
etc):
*/
BINLOG_FORMAT_MIXED= 2,
#endif
/*
This value is last, after the end of binlog_format_typelib: it has no
corresponding cell in this typelib. We use this value to be able to know if
the user has explicitely specified a binlog format at startup or not.
*/
BINLOG_FORMAT_UNSPEC= 3
};
extern TYPELIB binlog_format_typelib;
#endif /* LOG_H */
......@@ -5853,6 +5853,10 @@ int Table_map_log_event::exec_event(st_relay_log_info *rli)
if (rpl_filter->db_ok(table_list.db) &&
(!rpl_filter->is_on() || rpl_filter->tables_ok("", &table_list)))
{
/*
TODO: Mats will soon change this test below so that a SBR slave always
accepts RBR events from the master (and binlogs them RBR).
*/
/*
Check if the slave is set to use SBR. If so, the slave should
stop immediately since it is not possible to daisy-chain from
......@@ -5860,7 +5864,7 @@ int Table_map_log_event::exec_event(st_relay_log_info *rli)
RBR.
*/
if (mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG) &&
!binlog_row_based)
!thd->current_stmt_binlog_row_based)
{
slave_print_msg(ERROR_LEVEL, rli, ER_BINLOG_ROW_RBR_TO_SBR,
"It is not possible to use statement-based binlogging "
......
......@@ -28,14 +28,6 @@
#include <my_bitmap.h>
#if !defined(MYSQL_CLIENT)
#ifdef HAVE_ROW_BASED_REPLICATION
extern my_bool binlog_row_based;
#else
extern const my_bool binlog_row_based;
#endif
#endif
#define LOG_READ_EOF -1
#define LOG_READ_BOGUS -2
#define LOG_READ_IO -3
......
......@@ -1288,12 +1288,8 @@ extern ulong what_to_log,flush_time;
extern ulong query_buff_size, thread_stack;
extern ulong binlog_cache_size, max_binlog_cache_size, open_files_limit;
extern ulong max_binlog_size, max_relay_log_size;
extern const char *opt_binlog_format;
#ifdef HAVE_ROW_BASED_REPLICATION
extern my_bool binlog_row_based;
extern ulong opt_binlog_rows_event_max_size;
#else
extern const my_bool binlog_row_based;
#endif
extern ulong rpl_recovery_rank, thread_cache_size;
extern ulong back_log;
......
......@@ -465,31 +465,14 @@ my_bool opt_noacl;
my_bool sp_automatic_privileges= 1;
#ifdef HAVE_ROW_BASED_REPLICATION
/*
This variable below serves as an optimization for (opt_binlog_format ==
BF_ROW) as we need to do this test for every row. Stmt-based is default.
*/
my_bool binlog_row_based= FALSE;
ulong opt_binlog_rows_event_max_size;
const char *binlog_format_names[]= {"STATEMENT", "ROW", NullS};
/*
Note that BF_UNSPECIFIED is last, after the end of binlog_format_names: it
has no corresponding cell in this array. We use this value to be able to
know if the user has explicitely specified a binlog format (then we require
also --log-bin) or not (then we fall back to statement-based).
*/
enum binlog_format { BF_STMT= 0, BF_ROW= 1, BF_UNSPECIFIED= 2 };
const char *binlog_format_names[]= {"STATEMENT", "ROW", "MIXED", NullS};
#else
const my_bool binlog_row_based= FALSE;
const char *binlog_format_names[]= {"STATEMENT", NullS};
enum binlog_format { BF_STMT= 0, BF_UNSPECIFIED= 2 };
#endif
TYPELIB binlog_format_typelib=
{ array_elements(binlog_format_names)-1,"",
binlog_format_names, NULL };
const char *opt_binlog_format= 0;
enum binlog_format opt_binlog_format_id= BF_UNSPECIFIED;
#ifdef HAVE_INITGROUPS
static bool calling_initgroups= FALSE; /* Used in SIGSEGV handler. */
......@@ -3187,42 +3170,25 @@ with --log-bin instead.");
unireg_abort(1);
}
if (!opt_bin_log && (opt_binlog_format_id != BF_UNSPECIFIED))
if (!opt_bin_log && (global_system_variables.binlog_format != BINLOG_FORMAT_UNSPEC))
{
sql_print_warning("You need to use --log-bin to make "
"--binlog-format work.");
unireg_abort(1);
}
if (opt_binlog_format_id == BF_UNSPECIFIED)
if (global_system_variables.binlog_format == BINLOG_FORMAT_UNSPEC)
{
#ifdef HAVE_NDB_BINLOG
if (opt_bin_log && have_ndbcluster == SHOW_OPTION_YES)
opt_binlog_format_id= BF_ROW;
global_system_variables.binlog_format= BINLOG_FORMAT_ROW;
else
#endif
opt_binlog_format_id= BF_STMT;
}
#ifdef HAVE_ROW_BASED_REPLICATION
if (opt_binlog_format_id == BF_ROW)
{
binlog_row_based= TRUE;
/*
Row-based binlogging turns on InnoDB unsafe locking, because the locks
are not needed when using row-based binlogging. In fact
innodb-locks-unsafe-for-binlog is unsafe only for stmt-based, it's
safe for row-based.
*/
#ifdef HAVE_INNOBASE_DB
innobase_locks_unsafe_for_binlog= TRUE;
#endif
/* Trust stored function creators because they can do no harm */
trust_function_creators= 1;
global_system_variables.binlog_format= BINLOG_FORMAT_STMT;
}
#endif
/* Check that we have not let the format to unspecified at this point */
DBUG_ASSERT((uint)opt_binlog_format_id <=
DBUG_ASSERT((uint)global_system_variables.binlog_format <=
array_elements(binlog_format_names)-1);
opt_binlog_format= binlog_format_names[opt_binlog_format_id];
#ifdef HAVE_REPLICATION
if (opt_log_slave_updates && replicate_same_server_id)
......@@ -4929,23 +4895,23 @@ Disable with --skip-bdb (will save memory).",
{"bind-address", OPT_BIND_ADDRESS, "IP address to bind to.",
(gptr*) &my_bind_addr_str, (gptr*) &my_bind_addr_str, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"binlog-format", OPT_BINLOG_FORMAT,
{"binlog_format", OPT_BINLOG_FORMAT,
#ifdef HAVE_ROW_BASED_REPLICATION
"Tell the master the form of binary logging to use: either 'row' for "
"row-based binary logging (which automatically turns on "
"innodb_locks_unsafe_for_binlog as it is safe in this case), or "
"'statement' for statement-based logging. "
"row-based binary logging, or 'statement' for statement-based binary "
"logging, or 'mixed'. 'mixed' is statement-based binary logging except "
"for those statements where only row-based is correct: those which "
"involve user-defined functions (i.e. UDFs) or the UUID() function; for "
"those, row-based binary logging is automatically used. "
#ifdef HAVE_NDB_BINLOG
"If ndbcluster is enabled, the default will be set to 'row'."
"If ndbcluster is enabled, the default is 'row'."
#endif
,
#else
"Tell the master the form of binary logging to use: this release build "
"Tell the master the form of binary logging to use: this build "
"supports only statement-based binary logging, so only 'statement' is "
"a legal value; MySQL-Max release builds support row-based binary logging "
"in addition.",
"a legal value."
#endif
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
, 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
{"binlog-do-db", OPT_BINLOG_DO_DB,
"Tells the master it should log updates for the specified database, and exclude all others not explicitly mentioned.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
......@@ -5148,9 +5114,7 @@ Disable with --skip-innodb-doublewrite.", (gptr*) &innobase_use_doublewrite,
(gptr*) &innobase_unix_file_flush_method, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
0, 0, 0},
{"innodb_locks_unsafe_for_binlog", OPT_INNODB_LOCKS_UNSAFE_FOR_BINLOG,
"Force InnoDB not to use next-key locking, to use only row-level locking."
" This is unsafe if you are using statement-based binary logging, and safe"
" if you are using row-based binary logging.",
"Force InnoDB to not use next-key locking, to use only row-level locking.",
(gptr*) &innobase_locks_unsafe_for_binlog,
(gptr*) &innobase_locks_unsafe_for_binlog, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"innodb_log_arch_dir", OPT_INNODB_LOG_ARCH_DIR,
......@@ -5231,8 +5195,9 @@ Disable with --skip-innodb-doublewrite.", (gptr*) &innobase_use_doublewrite,
"a stored function (or trigger) is allowed only to users having the SUPER privilege "
"and only if this stored function (trigger) may not break binary logging."
#ifdef HAVE_ROW_BASED_REPLICATION
" If using --binlog-format=row, the security issues do not exist and the "
"binary logging cannot break so this option is automatically set to 1."
"Note that if ALL connections to this server ALWAYS use row-based binary "
"logging, the security issues do not exist and the binary logging cannot "
"break, so you can safely set this to 1."
#endif
,(gptr*) &trust_function_creators, (gptr*) &trust_function_creators, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
......@@ -7070,6 +7035,7 @@ static void mysql_init_variables(void)
max_system_variables.max_join_size= (ulonglong) HA_POS_ERROR;
global_system_variables.old_passwords= 0;
global_system_variables.old_alter_table= 0;
global_system_variables.binlog_format= BINLOG_FORMAT_UNSPEC;
/*
Default behavior for 4.1 and 5.0 is to treat NULL values as unequal
when collecting index statistics for MyISAM tables.
......@@ -7314,18 +7280,19 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
#ifdef HAVE_ROW_BASED_REPLICATION
fprintf(stderr,
"Unknown binary log format: '%s' "
"(should be '%s' or '%s')\n",
"(should be one of '%s', '%s', '%s')\n",
argument,
binlog_format_names[BF_STMT],
binlog_format_names[BF_ROW]);
binlog_format_names[BINLOG_FORMAT_STMT],
binlog_format_names[BINLOG_FORMAT_ROW],
binlog_format_names[BINLOG_FORMAT_MIXED]);
#else
fprintf(stderr,
"Unknown binary log format: '%s' (only legal value is '%s')\n",
argument, binlog_format_names[BF_STMT]);
argument, binlog_format_names[BINLOG_FORMAT_STMT]);
#endif
exit(1);
}
opt_binlog_format_id= (enum binlog_format)(id-1);
global_system_variables.binlog_format= id-1;
break;
}
case (int)OPT_BINLOG_DO_DB:
......
......@@ -278,7 +278,7 @@ bool partition_info::has_unique_name(partition_element *element)
List_iterator<partition_element> parts_it(partitions);
partition_element *el;
while (el= (parts_it++))
while ((el= (parts_it++)))
{
if (!(my_strcasecmp(system_charset_info, el->partition_name,
name_to_check)) && el != element)
......@@ -288,7 +288,7 @@ bool partition_info::has_unique_name(partition_element *element)
{
partition_element *sub_el;
List_iterator<partition_element> subparts_it(el->subpartitions);
while (sub_el= (subparts_it++))
while ((sub_el= (subparts_it++)))
{
if (!(my_strcasecmp(system_charset_info, sub_el->partition_name,
name_to_check)) && sub_el != element)
......@@ -323,7 +323,7 @@ char *partition_info::has_unique_names()
List_iterator<partition_element> parts_it(partitions);
partition_element *el;
while (el= (parts_it++))
while ((el= (parts_it++)))
{
if (! has_unique_name(el))
DBUG_RETURN(el->partition_name);
......@@ -332,7 +332,7 @@ char *partition_info::has_unique_names()
{
List_iterator<partition_element> subparts_it(el->subpartitions);
partition_element *subel;
while (subel= (subparts_it++))
while ((subel= (subparts_it++)))
{
if (! has_unique_name(subel))
DBUG_RETURN(subel->partition_name);
......
......@@ -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");
......
......@@ -826,6 +826,18 @@ class sys_var_event_executor :public sys_var_bool_ptr
bool update(THD *thd, set_var *var);
};
extern void fix_binlog_format_after_update(THD *thd, enum_var_type type);
class sys_var_thd_binlog_format :public sys_var_thd_enum
{
public:
sys_var_thd_binlog_format(const char *name_arg, ulong SV::*offset_arg)
:sys_var_thd_enum(name_arg, offset_arg,
&binlog_format_typelib,
fix_binlog_format_after_update)
{};
bool is_readonly() const;
};
/****************************************************************************
Classes for parsing of the SET command
......
......@@ -5812,6 +5812,12 @@ ER_CANT_CHANGE_TX_ISOLATION 25001
eng "Transaction isolation level can't be changed while a transaction is in progress"
ER_WARN_DEPRECATED_STATEMENT
eng "The '%s' statement is deprecated and will be removed in MySQL %s. Please use client programs (e.g. %s) instead."
ER_SP_NO_AGGREGATE 42000
eng "AGGREGATE is not supported for stored functions"
ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR
eng "Cannot switch out of the row-based binary log format when the session has open temporary tables"
ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT
eng "Cannot change the binary logging format inside a stored function or trigger"
ER_NDB_CANT_SWITCH_BINLOG_FORMAT
eng "The NDB cluster engine does not support changing the binlog format on the fly yet"
......@@ -1301,7 +1301,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
each substatement be binlogged its way.
*/
need_binlog_call= mysql_bin_log.is_open() &&
(thd->options & OPTION_BIN_LOG) && !binlog_row_based;
(thd->options & OPTION_BIN_LOG) && !thd->current_stmt_binlog_row_based;
if (need_binlog_call)
{
reset_dynamic(&thd->user_var_events);
......
......@@ -1189,7 +1189,7 @@ void close_temporary_tables(THD *thd)
close_temporary(table, 1, 1);
}
if (query && found_user_tables && mysql_bin_log.is_open() &&
!binlog_row_based) // CREATE TEMP TABLE not binlogged if row-based
!thd->current_stmt_binlog_row_based) // CREATE TEMP TABLE not binlogged if row-based
{
/* The -1 is to remove last ',' */
thd->clear_error();
......
......@@ -329,6 +329,7 @@ void THD::init(void)
bzero((char*) warn_count, sizeof(warn_count));
total_warn_count= 0;
update_charset();
reset_current_stmt_binlog_row_based();
bzero((char *) &status_var, sizeof(status_var));
}
......@@ -2026,12 +2027,12 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
INSERT INTO t1 VALUES (1), (foo()), (2);
*/
if (binlog_row_based)
if (current_stmt_binlog_row_based)
binlog_flush_pending_rows_event(false);
#endif /* HAVE_ROW_BASED_REPLICATION */
if ((!lex->requires_prelocking() || is_update_query(lex->sql_command)) &&
!binlog_row_based)
!current_stmt_binlog_row_based)
options&= ~OPTION_BIN_LOG;
/* Disable result sets */
client_capabilities &= ~CLIENT_MULTI_RESULTS;
......@@ -2394,7 +2395,7 @@ int THD::binlog_write_row(TABLE* table, bool is_trans,
MY_BITMAP const* cols, my_size_t colcnt,
byte const *record)
{
DBUG_ASSERT(binlog_row_based && mysql_bin_log.is_open());
DBUG_ASSERT(current_stmt_binlog_row_based && mysql_bin_log.is_open());
/*
Pack records into format for transfer. We are allocating more
......@@ -2441,7 +2442,7 @@ int THD::binlog_update_row(TABLE* table, bool is_trans,
const byte *before_record,
const byte *after_record)
{
DBUG_ASSERT(binlog_row_based && mysql_bin_log.is_open());
DBUG_ASSERT(current_stmt_binlog_row_based && mysql_bin_log.is_open());
bool error= 0;
my_size_t const before_maxlen = max_row_length(table, before_record);
......@@ -2489,7 +2490,7 @@ int THD::binlog_delete_row(TABLE* table, bool is_trans,
MY_BITMAP const* cols, my_size_t colcnt,
byte const *record)
{
DBUG_ASSERT(binlog_row_based && mysql_bin_log.is_open());
DBUG_ASSERT(current_stmt_binlog_row_based && mysql_bin_log.is_open());
/*
Pack records into format for transfer. We are allocating more
......@@ -2520,7 +2521,7 @@ int THD::binlog_delete_row(TABLE* table, bool is_trans,
int THD::binlog_flush_pending_rows_event(bool stmt_end)
{
DBUG_ENTER("THD::binlog_flush_pending_rows_event");
if (!binlog_row_based || !mysql_bin_log.is_open())
if (!current_stmt_binlog_row_based || !mysql_bin_log.is_open())
DBUG_RETURN(0);
/*
......@@ -2561,8 +2562,8 @@ void THD::binlog_delete_pending_rows_event()
/*
Member function that will log query, either row-based or
statement-based depending on the value of the 'binlog_row_based'
variable and the value of the 'qtype' flag.
statement-based depending on the value of the 'current_stmt_binlog_row_based'
the value of the 'qtype' flag.
This function should be called after the all calls to ha_*_row()
functions have been issued, but before tables are unlocked and
......@@ -2586,11 +2587,11 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype,
moving back and forth between using RBR for replication of
system tables and not using it.
Make sure to change in check_table_binlog_row_based() according
Make sure to change in check_table_current_stmt_binlog_row_based according
to how you treat this.
*/
case THD::ROW_QUERY_TYPE:
if (binlog_row_based)
if (current_stmt_binlog_row_based)
DBUG_RETURN(binlog_flush_pending_rows_event(true));
/* Otherwise, we fall through */
case THD::STMT_QUERY_TYPE:
......
......@@ -248,13 +248,15 @@ struct system_variables
#endif /* HAVE_REPLICATION */
my_bool innodb_table_locks;
my_bool innodb_support_xa;
ulong ndb_autoincrement_prefetch_sz;
my_bool ndb_force_send;
my_bool ndb_use_exact_count;
my_bool ndb_use_transactions;
my_bool ndb_index_stat_enable;
ulong ndb_autoincrement_prefetch_sz;
ulong ndb_index_stat_cache_entries;
ulong ndb_index_stat_update_freq;
ulong binlog_format; // binlog format for this thd (see enum_binlog_format)
my_bool old_alter_table;
my_bool old_passwords;
......@@ -1123,6 +1125,8 @@ class THD :public Statement,
char scramble[SCRAMBLE_LENGTH+1];
bool slave_thread, one_shot_set;
/* tells if current statement should binlog row-based(1) or stmt-based(0) */
bool current_stmt_binlog_row_based;
bool locked, some_tables_deleted;
bool last_cuted_field;
bool no_errors, password, is_fatal_error;
......@@ -1377,6 +1381,15 @@ class THD :public Statement,
void restore_sub_statement_state(Sub_statement_state *backup);
void set_n_backup_active_arena(Query_arena *set, Query_arena *backup);
void restore_active_arena(Query_arena *set, Query_arena *backup);
inline void set_current_stmt_binlog_row_based_if_mixed()
{
if (variables.binlog_format == BINLOG_FORMAT_MIXED)
current_stmt_binlog_row_based= 1;
}
inline void reset_current_stmt_binlog_row_based()
{
current_stmt_binlog_row_based= test(variables.binlog_format == BINLOG_FORMAT_ROW);
}
};
......
......@@ -962,7 +962,7 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
{
/*
TRUNCATE must always be statement-based binlogged (not row-based) so
we don't test binlog_row_based.
we don't test current_stmt_binlog_row_based.
*/
thd->clear_error();
thd->binlog_query(THD::STMT_QUERY_TYPE,
......
......@@ -2411,7 +2411,7 @@ void select_insert::send_error(uint errcode,const char *err)
thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query, thd->query_length,
table->file->has_transactions(), FALSE);
}
if (!binlog_row_based && !table->s->tmp_table)
if (!thd->current_stmt_binlog_row_based && !table->s->tmp_table)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
}
if (info.copied || info.deleted || info.updated)
......@@ -2556,7 +2556,7 @@ select_create::binlog_show_create_table()
on rollback, we clear the OPTION_STATUS_NO_TRANS_UPDATE bit of
thd->options.
*/
DBUG_ASSERT(binlog_row_based && !create_table_written);
DBUG_ASSERT(thd->current_stmt_binlog_row_based && !create_table_written);
thd->options&= ~OPTION_STATUS_NO_TRANS_UPDATE;
char buf[2048];
......@@ -2582,7 +2582,7 @@ void select_create::store_values(List<Item> &values)
Before writing the first row, we write the CREATE TABLE statement
to the binlog.
*/
if (binlog_row_based && !create_table_written)
if (thd->current_stmt_binlog_row_based && !create_table_written)
{
binlog_show_create_table();
create_table_written= TRUE;
......@@ -2611,7 +2611,7 @@ bool select_create::send_eof()
If no rows where written to the binary log, we write the CREATE
TABLE statement to the binlog.
*/
if (binlog_row_based && !create_table_written)
if (thd->current_stmt_binlog_row_based && !create_table_written)
{
binlog_show_create_table();
create_table_written= TRUE;
......
......@@ -426,7 +426,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
version for the binary log to mark that table maps are invalid
after this point.
*/
if (binlog_row_based)
if (thd->current_stmt_binlog_row_based)
thd->binlog_flush_pending_rows_event(true);
else
#endif
......@@ -491,7 +491,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
version for the binary log to mark that table maps are invalid
after this point.
*/
if (binlog_row_based)
if (thd->current_stmt_binlog_row_based)
thd->binlog_flush_pending_rows_event(true);
else
#endif
......@@ -948,7 +948,8 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, CHARSET_INFO *cs,
if (get_it_from_net)
cache.read_function = _my_b_net_read;
if (!binlog_row_based && mysql_bin_log.is_open())
if (((LOAD_FILE_INFO*)cache.arg)->thd->current_stmt_binlog_row_based &&
mysql_bin_log.is_open())
cache.pre_read = cache.pre_close =
(IO_CACHE_CALLBACK) log_loaded_block;
#endif
......
......@@ -4990,6 +4990,7 @@ mysql_execute_command(THD *thd)
*/
if (thd->one_shot_set && lex->sql_command != SQLCOM_SET_OPTION)
reset_one_shot_variables(thd);
thd->reset_current_stmt_binlog_row_based();
/*
The return value for ROW_COUNT() is "implementation dependent" if the
......
......@@ -697,7 +697,7 @@ bool check_partition_info(partition_info *part_info,handlerton **eng_type,
my_error(ER_TOO_MANY_PARTITIONS_ERROR, MYF(0));
goto end;
}
if (same_name= part_info->has_unique_names())
if ((same_name= part_info->has_unique_names()))
{
my_error(ER_SAME_NAME_PARTITION, MYF(0), same_name);
goto end;
......
......@@ -1654,7 +1654,7 @@ static int show_var_cmp(const void *var1, const void *var2)
*/
static void shrink_var_array(DYNAMIC_ARRAY *array)
{
int a,b;
uint a,b;
SHOW_VAR *all= dynamic_element(array, 0, SHOW_VAR *);
for (a= b= 0; b < array->elements; b++)
......
......@@ -565,7 +565,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
String built_query;
DBUG_ENTER("mysql_rm_table_part2");
if (binlog_row_based && !dont_log_query)
if (thd->current_stmt_binlog_row_based && !dont_log_query)
{
built_query.set_charset(system_charset_info);
if (if_exists)
......@@ -612,7 +612,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
being built. The string always end in a comma and the comma
will be chopped off before being written to the binary log.
*/
if (binlog_row_based && !dont_log_query)
if (thd->current_stmt_binlog_row_based && !dont_log_query)
{
++non_temp_tables_count;
/*
......@@ -722,7 +722,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
query_cache_invalidate3(thd, tables, 0);
if (!dont_log_query)
{
if (!binlog_row_based ||
if (!thd->current_stmt_binlog_row_based ||
non_temp_tables_count > 0 && !tmp_table_deleted)
{
/*
......@@ -734,7 +734,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
*/
write_bin_log(thd, !error, thd->query, thd->query_length);
}
else if (binlog_row_based &&
else if (thd->current_stmt_binlog_row_based &&
non_temp_tables_count > 0 &&
tmp_table_deleted)
{
......@@ -2250,8 +2250,8 @@ bool mysql_create_table_internal(THD *thd,
Otherwise, the statement shall be binlogged.
*/
if (!internal_tmp_table &&
(!binlog_row_based ||
(binlog_row_based &&
(!thd->current_stmt_binlog_row_based ||
(thd->current_stmt_binlog_row_based &&
!(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
write_bin_log(thd, TRUE, thd->query, thd->query_length);
error= FALSE;
......@@ -3477,7 +3477,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table,
/*
We have to write the query before we unlock the tables.
*/
if (binlog_row_based)
if (thd->current_stmt_binlog_row_based)
{
/*
Since temporary tables are not replicated under row-based
......@@ -4863,7 +4863,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
goto err;
}
/* We don't replicate alter table statement on temporary tables */
if (!binlog_row_based)
if (!thd->current_stmt_binlog_row_based)
write_bin_log(thd, TRUE, thd->query, thd->query_length);
goto end_temporary;
}
......@@ -5033,7 +5033,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
thd->query, thd->query_length,
db, table_name);
DBUG_ASSERT(!(mysql_bin_log.is_open() && binlog_row_based &&
DBUG_ASSERT(!(mysql_bin_log.is_open() && thd->current_stmt_binlog_row_based &&
(create_info->options & HA_LEX_CREATE_TMP_TABLE)));
write_bin_log(thd, TRUE, thd->query, thd->query_length);
/*
......
......@@ -14724,9 +14724,9 @@ static void test_bug12744()
mysql_close(mysql);
if (rc= mysql_stmt_execute(prep_stmt))
if ((rc= mysql_stmt_execute(prep_stmt)))
{
if (rc= mysql_stmt_reset(prep_stmt))
if ((rc= mysql_stmt_reset(prep_stmt)))
printf("OK!\n");
else
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment