Merge mysql.com:/nfsdisk1/lars/MERGE/mysql-5.0-merge
into mysql.com:/nfsdisk1/lars/MERGE/mysql-5.1-merge sql/sql_load.cc: Auto merged mysql-test/r/rpl_user_variables.result: Manual merge mysql-test/t/rpl_user_variables.test: Manual merge sql/item_func.cc: Manual merge sql/log.cc: Manual merge sql/sp_head.cc: Manual merge sql/sql_class.cc: Manual merge sql/sql_class.h: Manual merge
This commit is contained in:
commit
7443227bca
@ -241,6 +241,116 @@ SELECT f1(), f2();
|
|||||||
f1() f2()
|
f1() f2()
|
||||||
123 0
|
123 0
|
||||||
On master: Check to see that data was inserted correctly
|
On master: Check to see that data was inserted correctly
|
||||||
|
CREATE FUNCTION test.square() RETURNS INTEGER DETERMINISTIC RETURN (@var * @var);
|
||||||
|
SET @var = 1;
|
||||||
|
INSERT INTO t1 VALUES (square());
|
||||||
|
SET @var = 2;
|
||||||
|
INSERT INTO t1 VALUES (square());
|
||||||
|
SET @var = 3;
|
||||||
|
INSERT INTO t1 VALUES (square());
|
||||||
|
SET @var = 4;
|
||||||
|
INSERT INTO t1 VALUES (square());
|
||||||
|
SET @var = 5;
|
||||||
|
INSERT INTO t1 VALUES (square());
|
||||||
|
On master: Retrieve the values from the table
|
||||||
|
SELECT * FROM t1;
|
||||||
|
i
|
||||||
|
1
|
||||||
|
4
|
||||||
|
9
|
||||||
|
16
|
||||||
|
25
|
||||||
|
On slave: Retrieve the values from the table and verify they are the same as on master
|
||||||
|
SELECT * FROM t1;
|
||||||
|
i
|
||||||
|
1
|
||||||
|
4
|
||||||
|
9
|
||||||
|
16
|
||||||
|
25
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP FUNCTION test.square;
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
DROP FUNCTION IF EXISTS f1;
|
||||||
|
DROP FUNCTION IF EXISTS f2;
|
||||||
|
CREATE TABLE t1(a int);
|
||||||
|
CREATE FUNCTION f1() returns int deterministic
|
||||||
|
BEGIN
|
||||||
|
return @a;
|
||||||
|
END |
|
||||||
|
CREATE FUNCTION f2() returns int deterministic
|
||||||
|
BEGIN
|
||||||
|
IF (@b > 0) then
|
||||||
|
SET @c = (@a + @b);
|
||||||
|
else
|
||||||
|
SET @c = (@a - 1);
|
||||||
|
END if;
|
||||||
|
return @c;
|
||||||
|
END |
|
||||||
|
SET @a=500;
|
||||||
|
INSERT INTO t1 values(f1());
|
||||||
|
SET @b = 125;
|
||||||
|
SET @c = 1;
|
||||||
|
INSERT INTO t1 values(f2());
|
||||||
|
On master: Retrieve the values from the table
|
||||||
|
SELECT * from t1;
|
||||||
|
a
|
||||||
|
500
|
||||||
|
625
|
||||||
|
On slave: Check the tables for correct data and it matches master
|
||||||
|
SELECT * from t1;
|
||||||
|
a
|
||||||
|
500
|
||||||
|
625
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP FUNCTION f1;
|
||||||
|
DROP FUNCTION f2;
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
DROP TABLE IF EXISTS t2;
|
||||||
|
CREATE TABLE t1 (i int);
|
||||||
|
CREATE TABLE t2 (k int);
|
||||||
|
CREATE trigger t1_bi before INSERT on t1 for each row
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO t2 values (@a);
|
||||||
|
SET @a:=42;
|
||||||
|
INSERT INTO t2 values (@a);
|
||||||
|
END |
|
||||||
|
SET @a:=100;
|
||||||
|
INSERT INTO t1 values (5);
|
||||||
|
On master: Check to see that data was inserted correctly in both tables
|
||||||
|
SELECT * from t1;
|
||||||
|
i
|
||||||
|
5
|
||||||
|
SELECT * from t2;
|
||||||
|
k
|
||||||
|
100
|
||||||
|
42
|
||||||
|
On slave: Check the tables for correct data and it matches master
|
||||||
|
SELECT * from t1;
|
||||||
|
i
|
||||||
|
5
|
||||||
|
SELECT * from t2;
|
||||||
|
k
|
||||||
|
100
|
||||||
|
42
|
||||||
|
End of 5.0 tests.
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP TABLE t2;
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
DROP FUNCTION IF EXISTS f1;
|
||||||
|
DROP FUNCTION IF EXISTS f2;
|
||||||
|
CREATE TABLE t1 (i INT);
|
||||||
|
CREATE FUNCTION f1() RETURNS INT RETURN @a;
|
||||||
|
CREATE FUNCTION f2() RETURNS INT
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO t1 VALUES (10 + @a);
|
||||||
|
RETURN 0;
|
||||||
|
END|
|
||||||
|
SET @a:=123;
|
||||||
|
SELECT f1(), f2();
|
||||||
|
f1() f2()
|
||||||
|
123 0
|
||||||
|
On master: Check to see that data was inserted correctly
|
||||||
INSERT INTO t1 VALUES(f1());
|
INSERT INTO t1 VALUES(f1());
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
i
|
i
|
||||||
|
@ -291,8 +291,6 @@ SELECT * from t2;
|
|||||||
|
|
||||||
connection master;
|
connection master;
|
||||||
|
|
||||||
--echo End of 5.0 tests.
|
|
||||||
|
|
||||||
# Cleanup
|
# Cleanup
|
||||||
|
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
@ -349,6 +347,307 @@ DROP FUNCTION f1;
|
|||||||
DROP FUNCTION f2;
|
DROP FUNCTION f2;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
save_master_pos;
|
||||||
|
connection slave;
|
||||||
|
sync_with_master;
|
||||||
|
|
||||||
|
# BUG#20141
|
||||||
|
# The following tests ensure that if user-defined variables are used in SF/Triggers
|
||||||
|
# that they are replicated correctly. These tests should be run in both SBR and RBR
|
||||||
|
# modes.
|
||||||
|
|
||||||
|
# This test uses a procedure that inserts data values based on the value of a
|
||||||
|
# user-defined variable. It also has a trigger that inserts data based on the
|
||||||
|
# same variable. Successful test runs show that the @var is replicated
|
||||||
|
# properly and that the procedure and trigger insert the correct data on the
|
||||||
|
# slave.
|
||||||
|
#
|
||||||
|
# The test of stored procedure was included for completeness. Replication of stored
|
||||||
|
# procedures was not directly affected by BUG#20141.
|
||||||
|
#
|
||||||
|
# This test was constructed for BUG#20141
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
DROP TABLE IF EXISTS t20;
|
||||||
|
DROP TABLE IF EXISTS t21;
|
||||||
|
DROP PROCEDURE IF EXISTS test.insert;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
CREATE TABLE t20 (a VARCHAR(20));
|
||||||
|
CREATE TABLE t21 (a VARCHAR(20));
|
||||||
|
DELIMITER |;
|
||||||
|
|
||||||
|
# Create a procedure that uses the @var for flow control
|
||||||
|
|
||||||
|
CREATE PROCEDURE test.insert()
|
||||||
|
BEGIN
|
||||||
|
IF (@VAR)
|
||||||
|
THEN
|
||||||
|
INSERT INTO test.t20 VALUES ('SP_TRUE');
|
||||||
|
ELSE
|
||||||
|
INSERT INTO test.t20 VALUES ('SP_FALSE');
|
||||||
|
END IF;
|
||||||
|
END|
|
||||||
|
|
||||||
|
# Create a trigger that uses the @var for flow control
|
||||||
|
|
||||||
|
CREATE TRIGGER test.insert_bi BEFORE INSERT
|
||||||
|
ON test.t20 FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
IF (@VAR)
|
||||||
|
THEN
|
||||||
|
INSERT INTO test.t21 VALUES ('TRIG_TRUE');
|
||||||
|
ELSE
|
||||||
|
INSERT INTO test.t21 VALUES ('TRIG_FALSE');
|
||||||
|
END IF;
|
||||||
|
END|
|
||||||
|
DELIMITER ;|
|
||||||
|
|
||||||
|
sync_slave_with_master;
|
||||||
|
connection master;
|
||||||
|
|
||||||
|
# Set @var and call the procedure, repeat with different values
|
||||||
|
|
||||||
|
SET @VAR=0;
|
||||||
|
CALL test.insert();
|
||||||
|
SET @VAR=1;
|
||||||
|
CALL test.insert();
|
||||||
|
|
||||||
|
--echo On master: Check the tables for correct data
|
||||||
|
|
||||||
|
SELECT * FROM t20;
|
||||||
|
SELECT * FROM t21;
|
||||||
|
|
||||||
|
sync_slave_with_master;
|
||||||
|
|
||||||
|
--echo On slave: Check the tables for correct data and it matches master
|
||||||
|
|
||||||
|
SELECT * FROM t20;
|
||||||
|
SELECT * FROM t21;
|
||||||
|
connection master;
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
|
||||||
|
DROP TABLE t20;
|
||||||
|
DROP TABLE t21;
|
||||||
|
DROP PROCEDURE test.insert;
|
||||||
|
|
||||||
|
# This test uses a stored function that uses user-defined variables to return data
|
||||||
|
# This test was constructed for BUG#20141
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
DROP FUNCTION IF EXISTS test.square;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
CREATE TABLE t1 (i INT);
|
||||||
|
|
||||||
|
# Create function that returns a value from @var. In this case, the square function
|
||||||
|
|
||||||
|
CREATE FUNCTION test.square() RETURNS INTEGER DETERMINISTIC RETURN (@var * @var);
|
||||||
|
|
||||||
|
sync_slave_with_master;
|
||||||
|
connection master;
|
||||||
|
|
||||||
|
# Set the @var to different values and insert them into a table
|
||||||
|
|
||||||
|
SET @var = 1;
|
||||||
|
INSERT INTO t1 VALUES (square());
|
||||||
|
SET @var = 2;
|
||||||
|
INSERT INTO t1 VALUES (square());
|
||||||
|
SET @var = 3;
|
||||||
|
INSERT INTO t1 VALUES (square());
|
||||||
|
SET @var = 4;
|
||||||
|
INSERT INTO t1 VALUES (square());
|
||||||
|
SET @var = 5;
|
||||||
|
INSERT INTO t1 VALUES (square());
|
||||||
|
|
||||||
|
--echo On master: Retrieve the values from the table
|
||||||
|
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
sync_slave_with_master;
|
||||||
|
|
||||||
|
--echo On slave: Retrieve the values from the table and verify they are the same as on master
|
||||||
|
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
connection master;
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP FUNCTION test.square;
|
||||||
|
|
||||||
|
# This test uses stored functions that uses user-defined variables to return data
|
||||||
|
# based on the use of @vars inside a function body.
|
||||||
|
# This test was constructed for BUG#14914
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
DROP FUNCTION IF EXISTS f1;
|
||||||
|
DROP FUNCTION IF EXISTS f2;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
CREATE TABLE t1(a int);
|
||||||
|
DELIMITER |;
|
||||||
|
|
||||||
|
# Create a function that simply returns the value of an @var.
|
||||||
|
# Create a function that uses an @var for flow control, creates and uses another
|
||||||
|
# @var and sets its value to a value based on another @var.
|
||||||
|
|
||||||
|
CREATE FUNCTION f1() returns int deterministic
|
||||||
|
BEGIN
|
||||||
|
return @a;
|
||||||
|
END |
|
||||||
|
|
||||||
|
CREATE FUNCTION f2() returns int deterministic
|
||||||
|
BEGIN
|
||||||
|
IF (@b > 0) then
|
||||||
|
SET @c = (@a + @b);
|
||||||
|
else
|
||||||
|
SET @c = (@a - 1);
|
||||||
|
END if;
|
||||||
|
return @c;
|
||||||
|
END |
|
||||||
|
DELIMITER ;|
|
||||||
|
|
||||||
|
sync_slave_with_master;
|
||||||
|
connection master;
|
||||||
|
|
||||||
|
# Set an @var to a value and insert data into a table using the first function.
|
||||||
|
# Set two more @vars to some values and insert data into a table using the second function.
|
||||||
|
|
||||||
|
SET @a=500;
|
||||||
|
INSERT INTO t1 values(f1());
|
||||||
|
SET @b = 125;
|
||||||
|
SET @c = 1;
|
||||||
|
INSERT INTO t1 values(f2());
|
||||||
|
|
||||||
|
sync_slave_with_master;
|
||||||
|
|
||||||
|
--echo On master: Retrieve the values from the table
|
||||||
|
|
||||||
|
SELECT * from t1;
|
||||||
|
|
||||||
|
--echo On slave: Check the tables for correct data and it matches master
|
||||||
|
|
||||||
|
SELECT * from t1;
|
||||||
|
|
||||||
|
connection master;
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP FUNCTION f1;
|
||||||
|
DROP FUNCTION f2;
|
||||||
|
|
||||||
|
# This test uses a function that changes a user-defined variable in its body. This test
|
||||||
|
# will ensure the @vars are replicated when needed and not interrupt the normal execution
|
||||||
|
# of the function on the slave. This also applies to triggers.
|
||||||
|
#
|
||||||
|
# This test was constructed for BUG#25167
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
DROP TABLE IF EXISTS t2;
|
||||||
|
--enable_warnings
|
||||||
|
CREATE TABLE t1 (i int);
|
||||||
|
CREATE TABLE t2 (k int);
|
||||||
|
DELIMITER |;
|
||||||
|
|
||||||
|
# Create a trigger that inserts data into another table, changes the @var then inserts
|
||||||
|
# another row with the modified value.
|
||||||
|
|
||||||
|
CREATE trigger t1_bi before INSERT on t1 for each row
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO t2 values (@a);
|
||||||
|
SET @a:=42;
|
||||||
|
INSERT INTO t2 values (@a);
|
||||||
|
END |
|
||||||
|
DELIMITER ;|
|
||||||
|
|
||||||
|
sync_slave_with_master;
|
||||||
|
connection master;
|
||||||
|
|
||||||
|
# Set the @var to a value then insert data into first table.
|
||||||
|
|
||||||
|
SET @a:=100;
|
||||||
|
INSERT INTO t1 values (5);
|
||||||
|
|
||||||
|
--echo On master: Check to see that data was inserted correctly in both tables
|
||||||
|
|
||||||
|
SELECT * from t1;
|
||||||
|
SELECT * from t2;
|
||||||
|
|
||||||
|
sync_slave_with_master;
|
||||||
|
|
||||||
|
--echo On slave: Check the tables for correct data and it matches master
|
||||||
|
|
||||||
|
SELECT * from t1;
|
||||||
|
SELECT * from t2;
|
||||||
|
|
||||||
|
connection master;
|
||||||
|
|
||||||
|
--echo End of 5.0 tests.
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
DROP TABLE t2;
|
||||||
|
|
||||||
|
# This test uses a stored function that uses user-defined variables to return data
|
||||||
|
# The test ensures the value of the user-defined variable is replicated correctly
|
||||||
|
# and in the correct order of assignment.
|
||||||
|
# This test was constructed for BUG#20141
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
DROP TABLE IF EXISTS t1;
|
||||||
|
DROP FUNCTION IF EXISTS f1;
|
||||||
|
DROP FUNCTION IF EXISTS f2;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
CREATE TABLE t1 (i INT);
|
||||||
|
|
||||||
|
# Create two functions. One simply returns the user-defined variable. The other
|
||||||
|
# returns a value based on the user-defined variable.
|
||||||
|
|
||||||
|
CREATE FUNCTION f1() RETURNS INT RETURN @a;
|
||||||
|
DELIMITER |;
|
||||||
|
CREATE FUNCTION f2() RETURNS INT
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO t1 VALUES (10 + @a);
|
||||||
|
RETURN 0;
|
||||||
|
END|
|
||||||
|
DELIMITER ;|
|
||||||
|
|
||||||
|
sync_slave_with_master;
|
||||||
|
connection master;
|
||||||
|
|
||||||
|
# Set the variable and execute the functions.
|
||||||
|
|
||||||
|
SET @a:=123;
|
||||||
|
SELECT f1(), f2();
|
||||||
|
|
||||||
|
--echo On master: Check to see that data was inserted correctly
|
||||||
|
|
||||||
|
INSERT INTO t1 VALUES(f1());
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
sync_slave_with_master;
|
||||||
|
|
||||||
|
--echo On slave: Check the table for correct data and it matches master
|
||||||
|
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
connection master;
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
|
||||||
|
DROP FUNCTION f1;
|
||||||
|
DROP FUNCTION f2;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
sync_slave_with_master;
|
sync_slave_with_master;
|
||||||
stop slave;
|
stop slave;
|
||||||
|
|
||||||
|
@ -4222,9 +4222,9 @@ int get_var_with_binlog(THD *thd, enum_sql_command sql_command,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Any reference to user-defined variable which is done from stored
|
Any reference to user-defined variable which is done from stored
|
||||||
function or trigger affects their execution and execution of calling
|
function or trigger affects their execution and the execution of the
|
||||||
statement. Hence we want to log all accesses to such variables and
|
calling statement. We must log all such variables even if they are
|
||||||
not only those that happen from table-updating statement.
|
not involved in table-updating statements.
|
||||||
*/
|
*/
|
||||||
if (!(opt_bin_log &&
|
if (!(opt_bin_log &&
|
||||||
(is_update_query(sql_command) || thd->in_sub_stmt)))
|
(is_update_query(sql_command) || thd->in_sub_stmt)))
|
||||||
|
@ -2157,7 +2157,7 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
|
|||||||
!current_stmt_binlog_row_based)
|
!current_stmt_binlog_row_based)
|
||||||
{
|
{
|
||||||
options&= ~OPTION_BIN_LOG;
|
options&= ~OPTION_BIN_LOG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((backup->options & OPTION_BIN_LOG) && is_update_query(lex->sql_command)&&
|
if ((backup->options & OPTION_BIN_LOG) && is_update_query(lex->sql_command)&&
|
||||||
!current_stmt_binlog_row_based)
|
!current_stmt_binlog_row_based)
|
||||||
@ -2209,7 +2209,7 @@ void THD::restore_sub_statement_state(Sub_statement_state *backup)
|
|||||||
if ((options & OPTION_BIN_LOG) && is_update_query(lex->sql_command) &&
|
if ((options & OPTION_BIN_LOG) && is_update_query(lex->sql_command) &&
|
||||||
!current_stmt_binlog_row_based)
|
!current_stmt_binlog_row_based)
|
||||||
mysql_bin_log.stop_union_events(this);
|
mysql_bin_log.stop_union_events(this);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The following is added to the old values as we are interested in the
|
The following is added to the old values as we are interested in the
|
||||||
total complexity of the query
|
total complexity of the query
|
||||||
|
@ -458,7 +458,6 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
|||||||
}
|
}
|
||||||
sprintf(name, ER(ER_LOAD_INFO), (ulong) info.records, (ulong) info.deleted,
|
sprintf(name, ER(ER_LOAD_INFO), (ulong) info.records, (ulong) info.deleted,
|
||||||
(ulong) (info.records - info.copied), (ulong) thd->cuted_fields);
|
(ulong) (info.records - info.copied), (ulong) thd->cuted_fields);
|
||||||
send_ok(thd,info.copied+info.deleted,0L,name);
|
|
||||||
|
|
||||||
if (!transactional_table)
|
if (!transactional_table)
|
||||||
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
|
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
|
||||||
@ -494,6 +493,8 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
|||||||
if (transactional_table)
|
if (transactional_table)
|
||||||
error=ha_autocommit_or_rollback(thd,error);
|
error=ha_autocommit_or_rollback(thd,error);
|
||||||
|
|
||||||
|
/* ok to client sent only after binlog write and engine commit */
|
||||||
|
send_ok(thd, info.copied + info.deleted, 0L, name);
|
||||||
err:
|
err:
|
||||||
table->file->ha_release_auto_increment();
|
table->file->ha_release_auto_increment();
|
||||||
if (thd->lock)
|
if (thd->lock)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user