Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
995f2ae1
Commit
995f2ae1
authored
Feb 26, 2007
by
cbell/Chuck@mysql_cab_desk
Browse files
Options
Browse Files
Download
Plain Diff
Merge cbell@bk-internal.mysql.com:/home/bk/mysql-5.1-new-rpl
into mysql_cab_desk.:C:/source/C++/mysql-5.1-new-rpl
parents
75be2a8b
d7e4de99
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
508 additions
and
5 deletions
+508
-5
mysql-test/r/rpl_user_variables.result
mysql-test/r/rpl_user_variables.result
+174
-0
mysql-test/t/rpl_user_variables.test
mysql-test/t/rpl_user_variables.test
+297
-0
sql/item_func.cc
sql/item_func.cc
+8
-1
sql/log.cc
sql/log.cc
+2
-2
sql/log.h
sql/log.h
+1
-1
sql/sp_head.cc
sql/sp_head.cc
+17
-1
sql/sql_class.cc
sql/sql_class.cc
+9
-0
No files found.
mysql-test/r/rpl_user_variables.result
View file @
995f2ae1
...
...
@@ -80,4 +80,178 @@ abc\def
This is a test
insert into t1 select * FROM (select @var1 union select @var2) AS t2;
drop table t1;
End of 4.1 tests.
DROP TABLE IF EXISTS t20;
DROP TABLE IF EXISTS t21;
DROP PROCEDURE IF EXISTS test.insert;
CREATE TABLE t20 (a VARCHAR(20));
CREATE TABLE t21 (a VARCHAR(20));
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 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|
SET @VAR=0;
CALL test.insert();
SET @VAR=1;
CALL test.insert();
On master: Check the tables for correct data
SELECT * FROM t20;
a
SP_FALSE
SP_TRUE
SELECT * FROM t21;
a
TRIG_FALSE
TRIG_TRUE
On slave: Check the tables for correct data and it matches master
SELECT * FROM t20;
a
SP_FALSE
SP_TRUE
SELECT * FROM t21;
a
TRIG_FALSE
TRIG_TRUE
DROP TABLE t20;
DROP TABLE t21;
DROP PROCEDURE test.insert;
DROP TABLE IF EXISTS t1;
DROP FUNCTION IF EXISTS test.square;
CREATE TABLE t1 (i INT);
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());
SELECT * FROM t1;
i
133
123
On slave: Check the table for correct data and it matches master
SELECT * FROM t1;
i
133
123
DROP FUNCTION f1;
DROP FUNCTION f2;
DROP TABLE t1;
stop slave;
mysql-test/t/rpl_user_variables.test
View file @
995f2ae1
...
...
@@ -53,5 +53,302 @@ SELECT * FROM t1 ORDER BY n;
connection
master
;
insert
into
t1
select
*
FROM
(
select
@
var1
union
select
@
var2
)
AS
t2
;
drop
table
t1
;
--
echo
End
of
4.1
tests
.
# 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
);
# 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
());
--
echo
On
master
:
Retrieve
the
values
from
the
table
sync_slave_with_master
;
connection
master
;
SELECT
*
from
t1
;
connection
slave
;
--
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 procedures and 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
;
stop
slave
;
sql/item_func.cc
View file @
995f2ae1
...
...
@@ -4220,7 +4220,14 @@ int get_var_with_binlog(THD *thd, enum_sql_command sql_command,
user_var_entry
*
var_entry
;
var_entry
=
get_variable
(
&
thd
->
user_vars
,
name
,
0
);
if
(
!
(
opt_bin_log
&&
is_update_query
(
sql_command
)))
/*
Any reference to user-defined variable which is done from stored
function or trigger affects their execution and execution of calling
statement. Hence we want to log all accesses to such variables and
not only those that happen from table-updating statement.
*/
if
(
!
(
opt_bin_log
&&
(
is_update_query
(
sql_command
)
||
thd
->
in_sub_stmt
)))
{
*
out_entry
=
var_entry
;
return
0
;
...
...
sql/log.cc
View file @
995f2ae1
...
...
@@ -3345,13 +3345,13 @@ bool MYSQL_BIN_LOG::flush_and_sync()
return
err
;
}
void
MYSQL_BIN_LOG
::
start_union_events
(
THD
*
thd
)
void
MYSQL_BIN_LOG
::
start_union_events
(
THD
*
thd
,
query_id_t
query_id_param
)
{
DBUG_ASSERT
(
!
thd
->
binlog_evt_union
.
do_union
);
thd
->
binlog_evt_union
.
do_union
=
TRUE
;
thd
->
binlog_evt_union
.
unioned_events
=
FALSE
;
thd
->
binlog_evt_union
.
unioned_events_trans
=
FALSE
;
thd
->
binlog_evt_union
.
first_query_id
=
thd
->
query_id
;
thd
->
binlog_evt_union
.
first_query_id
=
query_id_param
;
}
void
MYSQL_BIN_LOG
::
stop_union_events
(
THD
*
thd
)
...
...
sql/log.h
View file @
995f2ae1
...
...
@@ -341,7 +341,7 @@ public:
int
write_cache
(
IO_CACHE
*
cache
,
bool
lock_log
,
bool
flush_and_sync
);
void
start_union_events
(
THD
*
thd
);
void
start_union_events
(
THD
*
thd
,
query_id_t
query_id_param
);
void
stop_union_events
(
THD
*
thd
);
bool
is_query_in_union
(
THD
*
thd
,
query_id_t
query_id_param
);
...
...
sql/sp_head.cc
View file @
995f2ae1
...
...
@@ -1482,8 +1482,24 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
if
(
need_binlog_call
)
{
query_id_t
q
;
reset_dynamic
(
&
thd
->
user_var_events
);
mysql_bin_log
.
start_union_events
(
thd
);
/*
In case of artificially constructed events for function calls
we have separate union for each such event and hence can't use
query_id of real calling statement as the start of all these
unions (this will break logic of replication of user-defined
variables). So we use artifical value which is guaranteed to
be greater than all query_id's of all statements belonging
to previous events/unions.
Possible alternative to this is logging of all function invocations
as one select and not resetting THD::user_var_events before
each invocation.
*/
VOID
(
pthread_mutex_lock
(
&
LOCK_thread_count
));
q
=
::
query_id
;
VOID
(
pthread_mutex_unlock
(
&
LOCK_thread_count
));
mysql_bin_log
.
start_union_events
(
thd
,
q
+
1
);
binlog_save_options
=
thd
->
options
;
thd
->
options
&=
~
OPTION_BIN_LOG
;
}
...
...
sql/sql_class.cc
View file @
995f2ae1
...
...
@@ -2158,6 +2158,11 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
{
options
&=
~
OPTION_BIN_LOG
;
}
if
((
backup
->
options
&
OPTION_BIN_LOG
)
&&
is_update_query
(
lex
->
sql_command
)
&&
!
current_stmt_binlog_row_based
)
mysql_bin_log
.
start_union_events
(
this
,
this
->
query_id
);
/* Disable result sets */
client_capabilities
&=
~
CLIENT_MULTI_RESULTS
;
in_sub_stmt
|=
new_state
;
...
...
@@ -2201,6 +2206,10 @@ void THD::restore_sub_statement_state(Sub_statement_state *backup)
sent_row_count
=
backup
->
sent_row_count
;
client_capabilities
=
backup
->
client_capabilities
;
if
((
options
&
OPTION_BIN_LOG
)
&&
is_update_query
(
lex
->
sql_command
)
&&
!
current_stmt_binlog_row_based
)
mysql_bin_log
.
stop_union_events
(
this
);
/*
The following is added to the old values as we are interested in the
total complexity of the query
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment