4
4
# The functions are typically useful to check assertions related to
5
5
# GTIDs. The following functions are defined:
7
# GTID_IS_EQUAL(g1, g2)
8
# True if g1 and g2 are the same set
9
# GTID_IS_DISJOINT(g1, g2)
10
# True if g1 and g2 are disjoint
11
# GTID_IS_DISJOINT_UNION(g1, g2, sum)
12
# True if sum is the disjoint union of g1 and g2
14
# Return the union of g1 and g2
15
# GTID_INTERSECTION(g1, g2)
16
# Return the union of g1 and g2
17
# GTID_SYMMETRIC_DIFFERENCE(g1, g2)
18
# Return the symmetric difference of g1 and g2
19
# GTID_SUBTRACT_UUID(gtid, uuid)
7
# GTID_IS_EQUAL(gtid_set_1, gtid_set_2)
8
# True if gtid_set_1 and gtid_set_2 are the same set
9
# GTID_IS_DISJOINT(gtid_set_1, gtid_set_2)
10
# True if gtid_set_1 and gtid_set_2 are disjoint
11
# GTID_IS_DISJOINT_UNION(gtid_set_1, gtid_set_2, sum)
12
# True if sum is the disjoint union of gtid_set_1 and gtid_set_2
13
# GTID_NORMALIZE(gtid_set)
14
# Return the gtid set in a normalized form: all uuids in alphabetic
15
# order, all intervals compressed and in order, no whitespace, all
17
# GTID_UNION(gtid_set_1, gtid_set_2)
18
# Return the union of gtid_set_1 and gtid_set_2
19
# GTID_INTERSECTION(gtid_set_1, gtid_set_2)
20
# Return the intersection of gtid_set_1 and gtid_set_2
21
# GTID_SYMMETRIC_DIFFERENCE(gtid_set_1, gtid_set_2)
22
# Return the symmetric difference of gtid_set_1 and gtid_set_2
23
# GTID_SUBTRACT_UUID(gtid_set, uuid)
20
24
# Remove the UUID from the GTID set
21
# GTID_INTERSECTION_WITH_UUID(gtid, uuid)
25
# GTID_INTERSECTION_WITH_UUID(gtid_set, uuid)
22
26
# Return only the gtids with the given uuid from the GTID set
27
# GTID_COUNT(gtid_set)
28
# Return the number of gtids in the gtid_set.
29
# GTID_NEXT_GENERATED(gtid_set, uuid)
30
# Return the next GNO that will be generated for the given uuid.
31
# GTID_NEXT_GENERATED_SET(gtid_set, uuid, count)
32
# Return the GTID set consisting of the next 'count' GTIDs that will
33
# be generated for the given uuid.
23
34
# GTID_COMPARE(old, diff, new)
24
35
# The same as GTID_IS_DISJOINT_UNION, except it has the following
25
36
# additional feature: if diff begins by '~', then it returns true
75
97
--let $uuidf= ffffffff-ffff-ffff-ffff-ffffffffffff
77
99
# Return nonzero if the two gtid_sets are equal.
78
CREATE FUNCTION GTID_IS_EQUAL(g1 TEXT(10000), g2 TEXT(10000))
100
CREATE FUNCTION GTID_IS_EQUAL(gtid_set_1 TEXT(10000), gtid_set_2 TEXT(10000))
81
RETURN GTID_SUBSET(g1, g2) AND GTID_SUBSET(g2, g1);
102
RETURN GTID_SUBSET(gtid_set_1, gtid_set_2) AND GTID_SUBSET(gtid_set_2, gtid_set_1)|
84
104
# Return nonzero if the two gtid_sets are disjoint.
85
CREATE FUNCTION GTID_IS_DISJOINT(g1 TEXT(10000), g2 TEXT(10000))
88
RETURN GTID_SUBSET(g1, GTID_SUBTRACT(g1, g2));
91
# Return true if g1 union g2 = sum, and g1 and g2 are disjoint.
92
CREATE FUNCTION GTID_IS_DISJOINT_UNION(g1 TEXT(10000), g2 TEXT(10000), sum TEXT(10000))
95
RETURN GTID_IS_EQUAL(GTID_SUBTRACT(sum, g1), g2) AND
96
GTID_IS_EQUAL(GTID_SUBTRACT(sum, g2), g1);
99
# Return the union of g1 and g2.
100
CREATE FUNCTION GTID_UNION(g1 TEXT(10000), g2 TEXT(10000))
103
RETURN GTID_SUBTRACT(CONCAT(g1, ',', g2), '');
106
# Return the intersection of g1 and g2.
107
CREATE FUNCTION GTID_INTERSECT(g1 TEXT(10000), g2 TEXT(10000))
110
RETURN GTID_SUBTRACT(g1, GTID_SUBTRACT(g1, g2));
113
# Return the symmetric difference between g1 and g2.
114
CREATE FUNCTION GTID_SYMMETRIC_DIFFERENCE(g1 TEXT(10000), g2 TEXT(10000))
117
RETURN SUBTRACT(CONCAT(g1, ',', g2), GTID_INTERSECTION(g1, g2));
105
CREATE FUNCTION GTID_IS_DISJOINT(gtid_set_1 TEXT(10000), gtid_set_2 TEXT(10000))
107
RETURN GTID_SUBSET(gtid_set_1, GTID_SUBTRACT(gtid_set_1, gtid_set_2))|
109
# Return true if gtid_set_1 union gtid_set_2 = sum, and gtid_set_1 and gtid_set_2 are disjoint.
110
CREATE FUNCTION GTID_IS_DISJOINT_UNION(gtid_set_1 TEXT(10000), gtid_set_2 TEXT(10000), sum TEXT(10000))
112
RETURN GTID_IS_EQUAL(GTID_SUBTRACT(sum, gtid_set_1), gtid_set_2) AND
113
GTID_IS_EQUAL(GTID_SUBTRACT(sum, gtid_set_2), gtid_set_1)|
115
# Return a normalized form of the GTID (all uppercase, no whitespace,
116
# no duplicates, uuids in alphabetic order, intervals in numeric
118
CREATE FUNCTION GTID_NORMALIZE(g TEXT(10000))
120
RETURN GTID_SUBTRACT(g, '')|
122
# Return the union of gtid_set_1 and gtid_set_2.
123
CREATE FUNCTION GTID_UNION(gtid_set_1 TEXT(10000), gtid_set_2 TEXT(10000))
125
RETURN GTID_NORMALIZE(CONCAT(gtid_set_1, ',', gtid_set_2))|
127
# Return the intersection of gtid_set_1 and gtid_set_2.
128
CREATE FUNCTION GTID_INTERSECTION(gtid_set_1 TEXT(10000), gtid_set_2 TEXT(10000))
130
RETURN GTID_SUBTRACT(gtid_set_1, GTID_SUBTRACT(gtid_set_1, gtid_set_2))|
132
# Return the symmetric difference between gtid_set_1 and gtid_set_2.
133
CREATE FUNCTION GTID_SYMMETRIC_DIFFERENCE(gtid_set_1 TEXT(10000), gtid_set_2 TEXT(10000))
135
RETURN GTID_SUBTRACT(CONCAT(gtid_set_1, ',', gtid_set_2), GTID_INTERSECTION(gtid_set_1, gtid_set_2))|
120
137
# Return the gtid with uuid removed.
121
CREATE FUNCTION GTID_SUBTRACT_UUID(gtid TEXT(10000), uuid TEXT(10000))
138
CREATE FUNCTION GTID_SUBTRACT_UUID(gtid_set TEXT(10000), uuid TEXT(100))
122
139
RETURNS TEXT(10000)
124
RETURN GTID_SUBTRACT(gtid, CONCAT(UUID, ':1-', 1 << 62));
140
RETURN GTID_SUBTRACT(gtid_set, CONCAT(UUID, ':1-', 1 << 63 - 1))|
127
142
# Return the intersection of gtid and uuid.
128
CREATE FUNCTION GTID_INTERSECT_UUID(gtid TEXT(10000), uuid TEXT(10000))
131
RETURN GTID_SUBTRACT(gtid, GTID_SUBTRACT_UUID(gtid, uuid));
143
CREATE FUNCTION GTID_INTERSECTION_WITH_UUID(gtid_set TEXT(10000), uuid TEXT(100))
145
RETURN GTID_SUBTRACT(gtid_set, GTID_SUBTRACT_UUID(gtid_set, uuid))|
147
# If the first argument is nonzero, return it, else return the second argument
148
CREATE FUNCTION IFZERO(a INT, b INT)
150
RETURN IF(a = 0, b, a)|
152
# Like the builtin LOCATE, but returns length+1 rather than 0 if nothing found.
153
CREATE FUNCTION LOCATE2(needle TEXT(10000), haystack TEXT(10000), offset INT)
155
RETURN IFZERO(LOCATE(needle, haystack, offset), LENGTH(haystack) + 1)|
157
# Return the number of GTIDs in the given GTID set.
158
CREATE FUNCTION GTID_COUNT(gtid_set TEXT(10000))
161
DECLARE result BIGINT DEFAULT 0;
162
DECLARE colon_pos INT;
163
DECLARE next_dash_pos INT;
164
DECLARE next_colon_pos INT;
165
DECLARE next_comma_pos INT;
166
SET gtid_set = GTID_NORMALIZE(gtid_set);
167
SET colon_pos = LOCATE2(':', gtid_set, 1);
168
WHILE colon_pos != LENGTH(gtid_set) + 1 DO
169
SET next_dash_pos = LOCATE2('-', gtid_set, colon_pos + 1);
170
SET next_colon_pos = LOCATE2(':', gtid_set, colon_pos + 1);
171
SET next_comma_pos = LOCATE2(',', gtid_set, colon_pos + 1);
172
IF next_dash_pos < next_colon_pos AND next_dash_pos < next_comma_pos THEN
173
SET result = result +
174
SUBSTR(gtid_set, next_dash_pos + 1,
175
LEAST(next_colon_pos, next_comma_pos) - (next_dash_pos + 1)) -
176
SUBSTR(gtid_set, colon_pos + 1, next_dash_pos - (colon_pos + 1)) + 1;
178
SET result = result + 1;
180
SET colon_pos = next_colon_pos;
185
# Return the next GNO (numeric component) to be generated for the given UUID
186
CREATE FUNCTION GTID_NEXT_GENERATED(gtid_set TEXT(10000), uuid TEXT(100))
189
DECLARE gtid_uuid TEXT(10000) DEFAULT GTID_INTERSECTION_WITH_UUID(gtid_set, uuid);
190
DECLARE colon_pos INT DEFAULT LOCATE2(':', gtid_uuid, 1);
191
DECLARE next_dash_pos INT DEFAULT LOCATE2('-', gtid_uuid, colon_pos + 1);
192
DECLARE next_comma_pos INT DEFAULT LOCATE2(',', gtid_uuid, colon_pos + 1);
193
DECLARE next_colon_pos INT DEFAULT LOCATE2(':', gtid_uuid, colon_pos + 1);
194
IF gtid_uuid = '' THEN
196
ELSEIF SUBSTR(gtid_uuid, colon_pos + 1,
197
LEAST(next_dash_pos, next_comma_pos, next_colon_pos) -
198
(colon_pos + 1)) != '1' THEN
200
ELSEIF next_dash_pos < LEAST(next_comma_pos, next_colon_pos) THEN
201
RETURN SUBSTR(gtid_uuid, next_dash_pos + 1,
202
LEAST(next_comma_pos, next_colon_pos) -
203
(next_dash_pos + 1)) + 1;
209
# Return a GTID set consisting of the the next 'count' GTIDs that will
210
# be generated for the given UUID.
211
# This is inefficient if count is big, consider optimizing it if needed.
212
CREATE FUNCTION GTID_NEXT_GENERATED_SET(gtid_set TEXT(10000), uuid TEXT(100), count INT)
215
DECLARE result TEXT(10000) DEFAULT '';
217
DECLARE new_gtid VARCHAR(100);
219
SET new_gtid = CONCAT(uuid, ':', GTID_NEXT_GENERATED(gtid_set, uuid));
220
SET result = GTID_UNION(result, new_gtid);
221
SET gtid_set = GTID_UNION(gtid_set, new_gtid);
222
SET count = count - 1;
134
227
# Return true if gtid_set 'new' is obtained by adding 'diff' to 'old',