File: rbwr.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 (379 lines) | stat: -rw-r--r-- 12,793 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
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
#
# Test for read before write removal(rbwr) optimization in MySQL Cluster
#
# Parameter based testcase using a table containing the different queries
# and their expected number of roundtrips(regarding rbwr). This allows the
# same queries  to be run with different settings while making sure that
# the query result is always the same. Of course some settings causes the
# rbwr optimzation to not apply and the expected number of roundtrips etc.
# shouldn't be checked.
#
-- source include/have_ndb.inc

--disable_query_log
--disable_result_log

### Setup parameter tables and utility procedures
create table rbwr_tests (
  test_id int primary key auto_increment,
  table_name varchar(255),
  query varchar(255),
  execute_count int,
  affected_rows int
) engine = MEMORY;

### Setup test tables
# Same table as ndb_update_no_read
create table t1 (
  a int not null primary key,
  b int not null,
  c int,
  unique index_b (b) using hash
) engine = ndb;
create temporary table data_t1 (
  a int not null primary key,
  b int not null,
  c int
);
insert into data_t1 values
  (1,10,1),(2,9,1),(3,8,1),(4,7,1),(5,6,1),
  (6,5,2),(7,4,2),(8,3,2),(9,2,2),(10,1,2);

# Composite PK
create table t2 (
  pk_a int not null,
  pk_b int not null,
  pk_c int not null,
  PRIMARY KEY (pk_a,pk_b,pk_c),
  d int
) engine = ndb;
create temporary table data_t2 (
  a int not null,
  b int not null,
  c int not null,
  d int
);
insert into data_t2 values
  (1,10,1,37),(2,9,1,38),(3,8,1,39),(4,7,1,40),(5,6,1,41),
  (6,5,2,42),(7,4,2,43),(8,3,2,44),(9,2,2,45),(10,1,2,46);

#
create table t3 (
  pk_a varchar(256) not null,
  b int not null,
  c int not null,
  PRIMARY KEY (pk_a),
  unique index_cb (c,b) using hash,
  d int
) engine = ndb;
create temporary table data_t3 (
  a varchar(256) not null,
  b int not null,
  c int not null,
  d int
);
insert into data_t3 values
  ('11111',10,1,44),('22222',9,2,45),('33333',8,3,46),('44444',7,4,47),('55555',6,5,48),
  ('66666',5,6,44),('77777',4,7,45),('88888',3,8,46),('99999',2,9,47),('00000',1,10,48);

# Composite PK, more rows, random number of rows
create table t4 (
  pk_a varchar(256) not null,
  pk_b int not null,
  pk_c datetime not null,
  PRIMARY KEY (pk_a, pk_b, pk_c),
  d int,
  e varchar(255),
  f int,
  unique index_f (f) using hash,
  g bigint,
  h bigint,
  i bigint,
  j bigint,
  unique index_ghij (g,h,i,j) using hash
) engine = ndb;
create temporary table data_t4 (
  a varchar(256) not null,
  b int not null,
  c datetime not null,
  d int,
  e varchar(255),
  f int,
  g bigint,
  h int,
  i bigint,
  j char(11)
);
let $i = `select round(rand() * 10)`;
while ($i)
{
  eval insert into data_t4 values (
    REPEAT('$i', 4),
    $i,
    DATE_ADD("2012-10-15 11:11:11", INTERVAL $i SECOND),
    100000-$i,
    REPEAT(CHAR(64+25*RAND()), 1+254*RAND()),
    $i,
    1000+$i,
    10000+$i,
    100000+$i,
    1000000+$i
  );

  dec $i;
}

#Table with BLOB
create table t5 (
  a int not null primary key,
  b int not null,
  c int,
  d text,
  unique index_b (b) using hash
) engine = ndb;
create temporary table data_t5 (
  a int not null primary key,
  b int not null,
  c int,
  d text
);
insert into data_t5 values
  (1,10,1,'aaa'),(2,9,1,'bbb'),(3,8,1,'ccc'),(4,7,1,''),(5,6,1,NULL),
  (6,5,2,'foo'),(7,4,2,'xxx'),(8,3,2,'yyy'),(9,2,2,'zzz'),(10,1,3,'xyz');

#enable_result_log;
#select * from data_t4;
#exit;


### Add test cases and their expected execute_count results

# Same testcases as ndb_update_no_read
INSERT INTO rbwr_tests (table_name, query, execute_count) VALUES
  ("t1", "update t1 set c = 97, b = 98 where a = 1", 2),
  ("t1", "delete from t1 where a = 1", 1),
  ("t1", "update t1 set c = 97 where b = 2", 1),
  ("t1", "update t1 set c = 97, b = 98 where b = 2", 2),
  ("t1", "delete from t1 where b = 9", 1),
  ("t1", "update t1 set c = 97 where a = 10 or a >= 10", 3),
  ("t1", "update t1 set c = 97 where a in (8,10)", 1),
  ("t1", "update t1 set c = 97 where a in (7,8) or a >= 10", 4),
  ("t1", "update t1 set a = 99, b = 98 where a = 3", 4),
  ("t1", "update t1 set a = 99, b = 98 where b = 7", 4),
  ("t1", "update t1 set c = 97, b = 98 where a = 5 and b = 6", 2),
  ("t1", "delete from t1 where b = 8 and c = 2", 2);

# Using full primary key, one roundtrip
INSERT INTO rbwr_tests (table_name, query, execute_count) VALUES
  ("t1", "delete from t1 where a = 1", 1),
  ("t1", "update t1 set c = 37 where a = 1", 1),
  ("t2", "delete from t2 where pk_a = 1 and pk_b = 2 and pk_c = 3", 1),
  ("t2", "update t2 set d = 37 where pk_a = 1 and pk_b = 2 and pk_c = 3", 1),
  ("t3", "delete from t3 where pk_a = \"11111\"", 1),
  ("t3", "update t3 set d = 37 where pk_a = \"11111\"", 1),
  ("t4", "delete from t4 where pk_a = \"16161616\" and pk_b = 16
            and pk_c = \"2012-10-15 11:11:27\"", 1),
  ("t4", "update t4 set d = 37 where pk_a = \"16161616\" and pk_b = 16
            and pk_c = \"2012-10-15 11:11:27\"", 1);

# Using full primary key with constant parameter in value list, one roundtrip
set @param37 = 37;
INSERT INTO rbwr_tests (table_name, query, execute_count) VALUES
  ("t1", "update t1 set c = @param37 where a = 1", 1),
  ("t2", "update t2 set d = @param37 where pk_a = 1 and pk_b = 2 and
            pk_c = 3", 1),
  ("t3", "update t3 set d = @param37 where pk_a = \"11111\"", 1),
  ("t4", "update t4 set d = @param37 where pk_a = \"16161616\" and pk_b = 16
            and pk_c = \"2012-10-15 11:11:27\"", 1);

# Using full primary key with constant parameters in value list and where
# clause, one roundtrip
set @param1 = 1;
set @param2 = 2;
set @param3 = 3;
set @param11111 = "11111";
set @param16161616 = "16161616";
INSERT INTO rbwr_tests (table_name, query, execute_count) VALUES
  ("t1", "delete from t1 where a = @param1", 1),
  ("t1", "update t1 set c = @param37 where a = @param1", 1),
  ("t2", "delete from t2 where pk_a = @param1 and pk_b = @param2 and
            pk_c = 3", 1),
  ("t2", "update t2 set d = @param37 where pk_a = @param1 and pk_b = @param2 and
            pk_c = 3", 1),
  ("t3", "delete from t3 where pk_a = @param11111", 1),
  ("t3", "update t3 set d = @param37 where pk_a = @param11111", 1),
  ("t4", "delete from t4 where pk_a = @param16161616 and pk_b = 16
            and pk_c = \"2012-10-15 11:11:27\"", 1),
  ("t4", "update t4 set d = @param37 where pk_a = @param16161616 and pk_b = 16
            and pk_c = \"2012-10-15 11:11:27\"", 1);

# Using full unique key, one roundtrip
INSERT INTO rbwr_tests (table_name, query, execute_count) VALUES
  ("t1", "delete from t1 where b = 1", 1),
  ("t1", "update t1 set c = 37 where b = 1", 1),
   # no unique key in t2
  ("t3", "delete from t3 where c = 2 and b = 9", 1),
  ("t3", "update t3 set d = 37 where c = 2 and b = 9", 1),
  # The 4 cases below should supposedly also use only 1 roundtrip
  ("t4", "delete from t4 where f = 37", 2),
  ("t4", "update t4 set d = 37 where f = 37", 2),
  ("t4", "delete from t4
            where g = 1009 and h = 10009 and i = 100009 and j = \"1000009\"", 2),
  ("t4", "update t4 set d = 37
            where g = 1009 and h = 10009 and i = 100009 and j = \"1000009\"", 2);

# Update (part of) primary key (may require read+delete+insert+commit)
INSERT INTO rbwr_tests (table_name, query, execute_count) VALUES
  # All columns in PK updated
  ("t1", "update t1 set a = 97 where a = 1", 4), #PK
  ("t1", "update t1 set a = 98 where b = 1", 4), #Unique key

  # Update PK as keyop
  ("t2", "update t2 set pk_a = 37 where pk_a = 1 and pk_b = 2 and pk_c = 3", 2), #No match
  ("t2", "update t2 set pk_a = 38 where pk_a = 9 and pk_b = 2 and pk_c = 2", 4),
  ("t2", "update t2 set pk_b = 39 where pk_a = 9 and pk_b = 2 and pk_c = 2", 4),

  # Update PK as index-rangeop
  ("t2", "update t2 set pk_a = 47 where pk_a = 1 and pk_b = 2", 2), #No match
  ("t2", "update t2 set pk_a = 48 where pk_a = 9 and pk_b = 2", 6),

  # Update PK on table having BLOB
  ("t5", "update t5 set a = 57 where a = 1", 4), #PK
  ("t5", "update t5 set a = 58 where b = 1", 4), #Unique key

  # Update PK on table having BLOB, non existing rows 
  ("t5", "update t5 set a = 57 where a = 99", 2), #PK
  ("t5", "update t5 set a = 58 where b = 99", 2)  #Unique key
;

# Update or delete of table with BLOB (Column 'd')
set @b1 = 'b1';
set @b1 = concat(@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1);
set @b1 = concat(@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1);
set @b1 = concat(@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1,@b1);

INSERT INTO rbwr_tests (table_name, query, execute_count) VALUES
  ("t5", "update t5 set d = @b1  where a = 1", 3), #PK
  ("t5", "update t5 set d = NULL where a = 1", 3), #PK

  ("t5", "update t5 set d = @b1  where b = 1", 3), #UQ index
  ("t5", "update t5 set d = NULL where b = 1", 3), #UQ index

  ("t5", "update t5 set d = @b1  where c = 3", 3), #Scan 1 row
  ("t5", "update t5 set d = NULL where c = 3", 3), #Scan, update 1 row
  #("t5", "update t5 set d = @b1  where c > 1", 7), #Scan, update 5 rows
  #("t5", "update t5 set d = @b1", 12),             #Scan, update 10 rows

  # Update BLOB in non existing rows
  ("t5", "update t5 set d = @b1  where a = 99", 2), #PK
  ("t5", "update t5 set d = NULL where a = 99", 2), #PK

  ("t5", "update t5 set d = @b1  where b = 99", 2), #UQ index
  ("t5", "update t5 set d = NULL where b = 99", 2), #UQ index

  ("t5", "update t5 set d = @b1  where c = 99", 2), #Scan
  ("t5", "update t5 set d = NULL where c = 99", 2), #Scan

  # Update BLOB also req. to read the BLOB column
  ("t5", "update t5 set d = concat(d,@b1) where a = 1", 3), #PK
  ("t5", "update t5 set d = concat(d,@b1) where b = 1", 3), #UQ index
  ("t5", "update t5 set d = concat(d,@b1) where c = 3", 3), #Scan 1 row
  #("t5", "update t5 set d = concat(d,@b1) where c > 1", 7), #Scan 5 rows
  #("t5", "update t5 set d = concat(d,@b1)", 11),            #Scan 10 rows

  # Delete rows with BLOB
  ("t5", "delete from t5 where a = 1", 2), #PK
  ("t5", "delete from t5 where b = 1", 2), #UQ index
  ("t5", "delete from t5 where c = 3", 3), #Scan, single match
  #("t5", "delete from t5 where c > 1", 4), #Scan, match 5  rows
  #("t5", "delete from t5 where c > 0", 4), #Scan, match 10 rows
  ("t5", "delete from t5 where c > 9", 2)  #Scan, no match
  #("t5", "delete from t5", 4)
;


### Run testcases while there are tests left in the param table
while (`select count(*) from rbwr_tests`)
{
  # Find one testcase
  select @test_id := test_id,
    @test_table := table_name,
    @test_query := query,
    @test_execute_count := execute_count,
    @test_affected_rows := affected_rows
      from rbwr_tests order by test_id limit 1;
  let $test_query = `select @test_query`;
  let $test_table = `select @test_table`;
  let $test_execute_count = `select @test_execute_count`;

  --source rbwr.inc

  # Delete testcase
  delete from rbwr_tests where test_id = @test_id;
}

## Table with triggers
CREATE TABLE main(id int NOT NULL AUTO_INCREMENT PRIMARY KEY, val int)engine=ndb;
CREATE TABLE log(id int NOT NULL AUTO_INCREMENT PRIMARY KEY, bug_text varchar(500) NOT NULL)engine=ndb;

# Check execute count to verify that read removal is not done for
# a delete on a table which has a delete trigger
CREATE TRIGGER log_deletes AFTER DELETE ON main FOR EACH ROW
INSERT INTO log (bug_text) VALUES ("one row deleted");

let $before= `select VARIABLE_VALUE from performance_schema.session_status
                where variable_name like 'NDB_EXECUTE_COUNT'`;
DELETE FROM main WHERE id = 1;
let $after= `select VARIABLE_VALUE from performance_schema.session_status
               where variable_name like 'NDB_EXECUTE_COUNT'`;
if (!`select $after-$before >= 4`)
{
  enable_result_log;
  echo before: $before;
  echo after: $after;
  die Read removal used even when table has delete triggers;
}

# Check execute count to verify that read removal is not done for
# an update on a table which has an update trigger
CREATE TRIGGER log_updates AFTER UPDATE ON main FOR EACH ROW
INSERT INTO log (bug_text) VALUES ("one row updated");

let $before= `select VARIABLE_VALUE from performance_schema.session_status
                where variable_name like 'NDB_EXECUTE_COUNT'`;
UPDATE main SET val = 111 WHERE id = 1;
let $after= `select VARIABLE_VALUE from performance_schema.session_status
               where variable_name like 'NDB_EXECUTE_COUNT'`;
if (!`select $after-$before >= 3`)
{
  enable_result_log;
  echo before: $before;
  echo after: $after;
  die Read removal used even when table has update triggers;
}

### Cleanup
# Drop test tables
drop table t1, data_t1;
drop table t2, data_t2;
drop table t3, data_t3;
drop table t4, data_t4;
drop table t5, data_t5;

drop trigger log_deletes;
drop trigger log_updates;
drop table main;
drop table log;

# Drop parameter tables
drop table rbwr_tests;

--enable_query_log
--enable_result_log

if ($ndb_rbwr_fail)
{
  die Test failure detected!;
}