File: binlog_transaction_write_set_savepoint_level.test

package info (click to toggle)
mysql-8.0 8.0.43-3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,273,924 kB
  • sloc: cpp: 4,684,605; ansic: 412,450; pascal: 108,398; java: 83,641; perl: 30,221; cs: 27,067; sql: 26,594; sh: 24,181; python: 21,816; yacc: 17,169; php: 11,522; xml: 7,388; javascript: 7,076; makefile: 2,194; lex: 1,075; awk: 670; asm: 520; objc: 183; ruby: 97; lisp: 86
file content (143 lines) | stat: -rw-r--r-- 4,247 bytes parent folder | download
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
###############################################################################
# This test validates that a new level is created when a stored function or
# a trigger is called. The savepoint on previous level become unavailable
# and thus do not cause conflict with savepoints on new level. When function
# or trigger terminates, any savepoints it created are released and the previous
# level is restored.
#
# Test:
#   0. Create four tables (t1, t2, t3, t4) to insert data
#   1. Create a trigger t1_tr1, will create a SAVEPOINT S1 and insert values on t2
#   2. Create a function f1, will insert on t2, create a SAVEPOINT S1, insert on
#   t1 and execute ROLLBACK TO S1
#   3. Create a transaction, define a SAVEPOINT S1 insert values on T1 and execute
#   a rollback to S1
#   4. Call twice the function f1
#   5. Create trigger t3_tr1 with exit handler which will rollback to savepoint
#   created inside the trigger.
#   6. Print contents of tables
#   7. Execute asserts to confirm table data
#   8. Clean up
#
###############################################################################

--source include/have_debug.inc
--source include/have_binlog_format_row.inc

SET @save_session_debug= @@SESSION.debug;

# transaction_write_set_savepoint_level guarantees that when a SAVEPOINT is
# created the level is empty
SET @@SESSION.debug = "+d,transaction_write_set_savepoint_level";

CREATE TABLE t1 (c1 INT NOT NULL PRIMARY KEY);
CREATE TABLE t2 (c1 INT NOT NULL PRIMARY KEY);
CREATE TABLE t3 (c1 INT NOT NULL PRIMARY KEY);
CREATE TABLE t4 (c1 INT NOT NULL PRIMARY KEY);

DELIMITER |;

#
# When executing a trigger is created a new empty savepoint level
#
CREATE TRIGGER t1_tr1 BEFORE INSERT ON t1 FOR EACH ROW
BEGIN
  SAVEPOINT S1;
  INSERT INTO t2 VALUES (NEW.c1);
END|

#
# When executing a function is created a new empty savepoint level
#
CREATE FUNCTION f1(x INT) RETURNS INT
BEGIN
  INSERT INTO t2 VALUES (x);
  SAVEPOINT S1;
  INSERT INTO t1 VALUES (100);
  ROLLBACK TO S1;

  RETURN (1);
END|

DELIMITER ;|

BEGIN;

# S1 is the only savepoint on this level
SAVEPOINT S1;
INSERT INTO t1 VALUES (1);
# This will trigger t1_tr1 that will create a new empty savepoint level and
# there it will add a SAVEPOINT
ROLLBACK TO S1;

# The call to f1 will create a new empty savepoint level and there will add a
# SAVEPOINT
SELECT f1(102);

# Validate that when executing a rollback, it will be executed in the context
# of the function, the write set have size 2
SET @@SESSION.debug = "+d,transaction_write_set_size_2";

# This call to f1 will create a new empty savepoint level and there will add
# a SAVEPOINT
SELECT f1(101);

COMMIT;

SET @@SESSION.debug= @save_session_debug;

# Create trigger t3_tr1 with exit handler which will rollback to a savepoint
# created within the trigger.

DELIMITER |;
CREATE TRIGGER t3_tr1 AFTER INSERT ON t3 FOR EACH ROW
BEGIN
        DECLARE EXIT HANDLER FOR SQLEXCEPTION
                BEGIN
                        ROLLBACK TO SAVEPOINT inside_trigger;
                        INSERT INTO t4 VALUES (NEW.c1*20);
                END;

        SAVEPOINT inside_trigger;

        INSERT INTO t4 VALUES (NEW.c1);

        RELEASE SAVEPOINT inside_trigger;

END|
DELIMITER ;|

# Invoke t3_tr1 such that it will not invoke exit handler.
INSERT INTO t3 values (1);

# Invoke t3_tr1 such that it will invoke exit handler.
INSERT INTO t4 values (2);
INSERT INTO t3 values (2);

--query_vertical SELECT * FROM t1
--query_vertical SELECT * FROM t2
--query_vertical SELECT * FROM t3
--query_vertical SELECT * FROM t4

--let $assert_text= 'There are no values in table t1'
--let $assert_cond= [SELECT COUNT(*) AS count FROM t1, count, 1] = 0
--source include/assert.inc

--let $assert_text= 'There are 2 values in table t2'
--let $assert_cond= [SELECT COUNT(*) AS count FROM t2, count, 1] = 2
--source include/assert.inc

--let $assert_text= 'There are 2 values in table t3'
--let $assert_cond= [SELECT COUNT(*) AS count FROM t3, count, 1] = 2
--source include/assert.inc

--let $assert_text= 'There are 3 values in table t4'
--let $assert_cond= [SELECT COUNT(*) AS count FROM t4, count, 1] = 3
--source include/assert.inc

# Cleanup
DROP FUNCTION f1;
DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;
DROP TABLE t4;