summaryrefslogtreecommitdiff
path: root/mysql-test/suite/rpl/t/rpl_user_variables.test
blob: dd6ddf39580df32c8d2aac431ceb5b1b7f9dc09e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
###################################
#
# Test of replicating user variables
#
###################################

-- source include/master-slave.inc

disable_query_log;
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
enable_query_log;

# Disable PS as the log positions differs
--disable_ps_protocol


# Clean up old slave's binlogs.
# The slave is started with --log-slave-updates
# and this test does SHOW BINLOG EVENTS on the slave's
# binlog. But previous tests can influence the current test's
# binlog (e.g. a temporary table in the previous test has not
# been explicitly deleted, or it has but the slave hasn't had
# enough time to catch it before STOP SLAVE, 
# and at the beginning of the current
# test the slave immediately writes DROP TEMPORARY TABLE this_old_table).
# We wait for the slave to have written all he wants to the binlog
# (otherwise RESET MASTER may come too early).
sync_slave_with_master;
reset master;
connection master;

create table t1(n char(30));
set @i1:=12345678901234, @i2:=-12345678901234, @i3:=0, @i4:=-1;
set @s1:='This is a test', @r1:=12.5, @r2:=-12.5;
set @n1:=null;
set @s2:='', @s3:='abc\'def', @s4:= 'abc\\def', @s5:= 'abc''def';
insert into t1 values (@i1), (@i2), (@i3), (@i4);
insert into t1 values (@r1), (@r2);
insert into t1 values (@s1), (@s2), (@s3), (@s4), (@s5);
insert into t1 values (@n1);
insert into t1 values (@n2); # not explicitely set before
insert into t1 values (@a:=0), (@a:=@a+1), (@a:=@a+1);
insert into t1 values (@a+(@b:=@a+1));
set @q:='abc';
insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2'));
set @a:=5;
insert into t1 values (@a),(@a);
# To flush the pending event, we add the following statement. RBR can
# concatenate the result of several statements, which SBR cannot.
select * from t1 where n = '<nonexistant>';
connection master1; # see if variable is reset in binlog when thread changes
insert into t1 values (@a),(@a),(@a*5);
SELECT * FROM t1 ORDER BY n;
sync_slave_with_master;
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;
drop table t1, t2;

#
# Bug #12826: Possible to get inconsistent slave using SQL syntax Prepared Statements
#
connection master;
create table t1(a int, b int);
prepare s1 from 'insert into t1 values (@x:=@x+1, ?)';
set @x=1; execute s1 using @x;
select * from t1;
sync_slave_with_master;
connection slave;
select * from t1;
connection master;
drop table t1;

#
# Bug#33851: Passing UNSIGNED param to EXECUTE returns ERROR 1210
#

connection master;
create table t1(a int);
insert into t1 values (1),(2);
prepare s1 from 'insert into t1 select a from t1 limit ?';
set @x='1.1';
--disable_warnings
execute s1 using @x;
--enable_warnings
select * from t1;
sync_slave_with_master;
connection slave;
select * from t1;
connection master;
drop table t1;

--echo End of 5.0 tests.

# 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 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;

--source include/rpl_end.inc