1 /*
2 Copyright 2011 Kristian Nielsen and Monty Program Ab.
3
4 This file is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this. If not, see <http://www.gnu.org/licenses/>.
16 */
17 #include "my_test.h"
18 #include "ma_common.h"
19
20 #define TEST_ARRAY_SIZE 1024
21
22 static my_bool bulk_enabled= 0;
23
rand_str(size_t length)24 char *rand_str(size_t length) {
25 const char charset[] = "0123456789"
26 "abcdefghijklmnopqrstuvwxyz"
27 "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
28 char *dest= (char *)malloc(length+1);
29 char *p= dest;
30 while (length-- > 0) {
31 *dest++ = charset[rand() % sizeof(charset)];
32 }
33 *dest = '\0';
34 return p;
35 }
36
check_bulk(MYSQL * mysql)37 static int check_bulk(MYSQL *mysql)
38 {
39 bulk_enabled= (!(mysql->server_capabilities & CLIENT_MYSQL) &&
40 (mysql->extension->mariadb_server_capabilities &
41 (MARIADB_CLIENT_STMT_BULK_OPERATIONS >> 32)));
42 diag("bulk %ssupported", bulk_enabled ? "" : "not ");
43 return OK;
44 }
45
bulk1(MYSQL * mysql)46 static int bulk1(MYSQL *mysql)
47 {
48 MYSQL_STMT *stmt= mysql_stmt_init(mysql);
49 const char *stmt_str= "INSERT INTO bulk1 VALUES (?,?)";
50 unsigned int array_size= TEST_ARRAY_SIZE;
51 int rc;
52 unsigned int i;
53 char **buffer;
54 unsigned long *lengths;
55 unsigned int *vals;
56 MYSQL_BIND bind[2];
57 MYSQL_RES *res;
58 MYSQL_ROW row;
59 unsigned int intval;
60
61 if (!bulk_enabled)
62 return SKIP;
63
64 rc= mysql_select_db(mysql, "testc");
65
66 rc= mysql_query(mysql, "DROP TABLE IF EXISTS bulk1");
67 check_mysql_rc(rc, mysql);
68
69 rc= mysql_query(mysql, "CREATE TABLE bulk1 (a int , b VARCHAR(255))");
70 check_mysql_rc(rc, mysql);
71
72 rc= mysql_stmt_prepare(stmt, SL(stmt_str));
73 check_stmt_rc(rc, stmt);
74
75 /* allocate memory */
76 buffer= calloc(TEST_ARRAY_SIZE, sizeof(char *));
77 lengths= (unsigned long *)calloc(sizeof(long), TEST_ARRAY_SIZE);
78 vals= (unsigned int *)calloc(sizeof(int), TEST_ARRAY_SIZE);
79
80 for (i=0; i < TEST_ARRAY_SIZE; i++)
81 {
82 buffer[i]= rand_str(254);
83 lengths[i]= -1;
84 vals[i]= i;
85 }
86
87 memset(bind, 0, sizeof(MYSQL_BIND) * 2);
88 bind[0].buffer_type= MYSQL_TYPE_LONG;
89 bind[0].buffer= vals;
90 bind[1].buffer_type= MYSQL_TYPE_STRING;
91 bind[1].buffer= (void *)buffer;
92 bind[1].length= (unsigned long *)lengths;
93
94 rc= mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
95 check_stmt_rc(rc, stmt);
96
97 rc= mysql_stmt_bind_param(stmt, bind);
98 check_stmt_rc(rc, stmt);
99
100 for (i=0; i < 100; i++)
101 {
102 rc= mysql_stmt_execute(stmt);
103 check_stmt_rc(rc, stmt);
104 FAIL_IF(mysql_stmt_affected_rows(stmt) != TEST_ARRAY_SIZE, "affected_rows != TEST_ARRAY_SIZE");
105 }
106
107 for (i=0; i < array_size; i++)
108 free(buffer[i]);
109
110 free(buffer);
111 free(lengths);
112 free(vals);
113
114 rc= mysql_stmt_close(stmt);
115 check_mysql_rc(rc, mysql);
116
117 rc= mysql_query(mysql, "SELECT COUNT(*) FROM bulk1");
118 check_mysql_rc(rc, mysql);
119
120 res= mysql_store_result(mysql);
121 row= mysql_fetch_row(res);
122 intval= atoi(row[0]);
123 mysql_free_result(res);
124 FAIL_IF(intval != array_size * 100, "Expected 102400 rows");
125
126 rc= mysql_query(mysql, "SELECT MAX(a) FROM bulk1");
127 check_mysql_rc(rc, mysql);
128
129 res= mysql_store_result(mysql);
130 row= mysql_fetch_row(res);
131 intval= atoi(row[0]);
132 mysql_free_result(res);
133 FAIL_IF(intval != array_size - 1, "Expected max value 1024");
134
135 rc= mysql_query(mysql, "DROP TABLE IF EXISTS bulk1");
136 check_mysql_rc(rc, mysql);
137 return OK;
138 }
139
bulk2(MYSQL * mysql)140 static int bulk2(MYSQL *mysql)
141 {
142 MYSQL_STMT *stmt= mysql_stmt_init(mysql);
143 int rc;
144 MYSQL_BIND bind[2];
145 unsigned int i;
146 unsigned int array_size=1024;
147 char indicator[1024];
148 long lval[1024];
149
150 if (!bulk_enabled)
151 return SKIP;
152 rc= mysql_query(mysql, "DROP TABLE IF EXISTS bulk2");
153 check_mysql_rc(rc, mysql);
154
155 rc= mysql_query(mysql, "CREATE TABLE bulk2 (a int default 4, b int default 2)");
156 check_mysql_rc(rc, mysql);
157
158 rc= mysql_stmt_prepare(stmt, SL("INSERT INTO bulk2 VALUES (?,1)"));
159 check_stmt_rc(rc, stmt);
160
161 memset(bind, 0, 2 * sizeof(MYSQL_BIND));
162
163 for (i=0; i < array_size; i++)
164 {
165 indicator[i]= STMT_INDICATOR_DEFAULT;
166 lval[i]= i;
167 }
168
169 bind[0].buffer_type= MYSQL_TYPE_LONG;
170 bind[0].u.indicator= indicator;
171 bind[1].buffer_type= MYSQL_TYPE_LONG;
172 bind[1].buffer= &lval;
173
174 rc= mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
175 check_stmt_rc(rc, stmt);
176
177 rc= mysql_stmt_bind_param(stmt, bind);
178 check_stmt_rc(rc, stmt);
179
180 rc= mysql_stmt_execute(stmt);
181 check_stmt_rc(rc, stmt);
182
183 mysql_stmt_close(stmt);
184 rc= mysql_query(mysql, "DROP TABLE IF EXISTS bulk2");
185 check_mysql_rc(rc, mysql);
186
187 return OK;
188 }
189
bulk3(MYSQL * mysql)190 static int bulk3(MYSQL *mysql)
191 {
192 struct st_bulk3 {
193 char char_value[20];
194 unsigned long length;
195 int int_value;
196 };
197
198 struct st_bulk3 val[3]= {{"Row 1", 5, 1},
199 {"Row 02", 6, 2},
200 {"Row 003", 7, 3}};
201 int rc;
202 MYSQL_BIND bind[2];
203 MYSQL_STMT *stmt= mysql_stmt_init(mysql);
204 size_t row_size= sizeof(struct st_bulk3);
205 int array_size= 3;
206
207 if (!bulk_enabled)
208 return SKIP;
209 rc= mysql_query(mysql, "DROP TABLE IF EXISTS bulk3");
210 check_mysql_rc(rc,mysql);
211 rc= mysql_query(mysql, "CREATE TABLE bulk3 (name varchar(20), row int)");
212 check_mysql_rc(rc,mysql);
213
214 rc= mysql_stmt_prepare(stmt, SL("INSERT INTO bulk3 VALUES (?,?)"));
215 check_stmt_rc(rc, stmt);
216
217 memset(bind, 0, sizeof(MYSQL_BIND)*2);
218
219 rc= mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
220 check_stmt_rc(rc, stmt);
221 rc= mysql_stmt_attr_set(stmt, STMT_ATTR_ROW_SIZE, &row_size);
222 check_stmt_rc(rc, stmt);
223
224 bind[0].buffer_type= MYSQL_TYPE_STRING;
225 bind[0].buffer= &val[0].char_value;
226 bind[0].length= &val[0].length;
227 bind[1].buffer_type= MYSQL_TYPE_LONG;
228 bind[1].buffer= &val[0].int_value;
229
230 rc= mysql_stmt_bind_param(stmt, bind);
231 check_stmt_rc(rc, stmt);
232 rc= mysql_stmt_execute(stmt);
233 check_stmt_rc(rc, stmt);
234
235 mysql_stmt_close(stmt);
236 rc= mysql_query(mysql, "DROP TABLE IF EXISTS bulk3");
237 check_mysql_rc(rc, mysql);
238 return OK;
239 }
240
bulk4(MYSQL * mysql)241 static int bulk4(MYSQL *mysql)
242 {
243 struct st_bulk4 {
244 char char_value[20];
245 char indicator1;
246 int int_value;
247 char indicator2;
248 };
249
250 struct st_bulk4 val[]= {{"Row 1", STMT_INDICATOR_NTS, 0, STMT_INDICATOR_DEFAULT},
251 {"Row 2", STMT_INDICATOR_NTS, 0, STMT_INDICATOR_DEFAULT},
252 {"Row 3", STMT_INDICATOR_NTS, 0, STMT_INDICATOR_DEFAULT}};
253 int rc;
254 MYSQL_BIND bind[2];
255 MYSQL_RES *res;
256 MYSQL_STMT *stmt= mysql_stmt_init(mysql);
257 size_t row_size= sizeof(struct st_bulk4);
258 int array_size= 3;
259 unsigned long lengths[3]= {-1, -1, -1};
260
261 if (!bulk_enabled)
262 return SKIP;
263 rc= mysql_query(mysql, "DROP TABLE IF EXISTS bulk4");
264 check_mysql_rc(rc,mysql);
265 rc= mysql_query(mysql, "CREATE TABLE bulk4 (name varchar(20), row int not null default 3)");
266 check_mysql_rc(rc,mysql);
267
268 rc= mysql_stmt_prepare(stmt, SL("INSERT INTO bulk4 VALUES (?,?)"));
269 check_stmt_rc(rc, stmt);
270
271 memset(bind, 0, sizeof(MYSQL_BIND)*2);
272
273 rc= mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
274 check_stmt_rc(rc, stmt);
275 rc= mysql_stmt_attr_set(stmt, STMT_ATTR_ROW_SIZE, &row_size);
276 check_stmt_rc(rc, stmt);
277
278 bind[0].buffer_type= MYSQL_TYPE_STRING;
279 bind[0].u.indicator= &val[0].indicator1;
280 bind[0].buffer= &val[0].char_value;
281 bind[0].length= lengths;
282 bind[1].buffer_type= MYSQL_TYPE_LONG;
283 bind[1].u.indicator= &val[0].indicator2;
284
285 rc= mysql_stmt_bind_param(stmt, bind);
286 check_stmt_rc(rc, stmt);
287 rc= mysql_stmt_execute(stmt);
288 check_stmt_rc(rc, stmt);
289
290 mysql_stmt_close(stmt);
291
292 rc= mysql_query(mysql, "SELECT * FROM bulk4 WHERE row=3");
293 check_mysql_rc(rc, mysql);
294 res= mysql_store_result(mysql);
295 rc= (int)mysql_num_rows(res);
296 mysql_free_result(res);
297 FAIL_IF(rc != 3, "expected 3 rows");
298 rc= mysql_query(mysql, "DROP TABLE IF EXISTS bulk4");
299 check_mysql_rc(rc, mysql);
300 return OK;
301 }
302
bulk_null(MYSQL * mysql)303 static int bulk_null(MYSQL *mysql)
304 {
305 MYSQL_STMT *stmt= mysql_stmt_init(mysql);
306 int rc;
307 MYSQL_BIND bind[2];
308 unsigned int param_count= 2;
309 unsigned int array_size= 2;
310 unsigned long lengths[2]= {-1, -1};
311 char **buf= calloc(1, 2 * sizeof(char *));
312
313 if (!bulk_enabled)
314 {
315 free(buf);
316 return SKIP;
317 }
318
319 buf[0]= strdup("foo");
320 buf[1]= strdup("foobar");
321
322 rc= mariadb_stmt_execute_direct(stmt, "DROP TABLE IF EXISTS bulk_null", -1);
323 check_stmt_rc(rc, stmt);
324
325 rc= mariadb_stmt_execute_direct(stmt, "CREATE TABLE bulk_null (a int not null auto_increment primary key, b varchar(20))", -1);
326 check_stmt_rc(rc, stmt);
327
328 memset(bind, 0, 2 * sizeof(MYSQL_BIND));
329 bind[0].buffer_type= MYSQL_TYPE_NULL;
330 bind[1].buffer_type= MYSQL_TYPE_STRING;
331 bind[1].buffer= buf;
332 bind[1].length= lengths;
333
334 mysql_stmt_close(stmt);
335 stmt= mysql_stmt_init(mysql);
336
337 rc= mysql_stmt_attr_set(stmt, STMT_ATTR_PREBIND_PARAMS, ¶m_count);
338 check_stmt_rc(rc, stmt);
339
340 rc= mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
341 check_stmt_rc(rc, stmt);
342
343 rc= mysql_stmt_bind_param(stmt, bind);
344 check_stmt_rc(rc, stmt);
345
346 rc= mariadb_stmt_execute_direct(stmt, "INSERT INTO bulk_null VALUES (?, ?)", -1);
347 check_stmt_rc(rc, stmt);
348
349 mysql_stmt_close(stmt);
350 free(buf[0]);
351 free(buf[1]);
352 free(buf);
353 rc= mysql_query(mysql, "DROP TABLE IF EXISTS bulk_null");
354 check_mysql_rc(rc, mysql);
355 return OK;
356 }
357
bulk5(MYSQL * mysql)358 static int bulk5(MYSQL *mysql)
359 {
360 MYSQL_STMT *stmt= mysql_stmt_init(mysql);
361 MYSQL_BIND bind[3];
362 MYSQL_RES *res;
363 unsigned long rows;
364 unsigned int array_size= 5;
365 int rc;
366 int intval[]= {12,13,14,15,16};
367 int id[]= {1,2,3,4,5};
368
369 if (!bulk_enabled)
370 return SKIP;
371
372 rc= mysql_query(mysql, "DROP TABLE IF EXISTS bulk5");
373 check_mysql_rc(rc, mysql);
374
375 rc= mysql_query(mysql, "CREATE TABLE bulk5 (a int, b int)");
376 check_mysql_rc(rc, mysql);
377
378 rc= mysql_query(mysql, "INSERT INTO bulk5 VALUES (1,1), (2,2), (3,3), (4,4), (5,5)");
379 check_mysql_rc(rc, mysql);
380
381
382 memset(bind, 0, sizeof(MYSQL_BIND) * 3);
383
384 rc= mysql_stmt_prepare(stmt, SL("UPDATE bulk5 SET a=? WHERE a=?"));
385 check_stmt_rc(rc, stmt);
386
387 bind[0].buffer_type= MYSQL_TYPE_LONG;
388 bind[0].buffer= &intval;
389 bind[1].buffer_type= MYSQL_TYPE_LONG;
390 bind[1].buffer= &id;
391
392 rc= mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
393 check_stmt_rc(rc, stmt);
394
395 rc= mysql_stmt_bind_param(stmt, bind);
396 check_stmt_rc(rc, stmt);
397
398 rc= mysql_stmt_execute(stmt);
399 check_stmt_rc(rc, stmt);
400
401 mysql_stmt_close(stmt);
402
403 rc= mysql_query(mysql, "SELECT * FROM bulk5 WHERE a=b+11");
404 check_mysql_rc(rc, mysql);
405
406 res= mysql_store_result(mysql);
407 rows= (unsigned long)mysql_num_rows(res);
408 diag("rows: %lu", rows);
409 mysql_free_result(res);
410
411 FAIL_IF(rows != 5, "expected 5 rows");
412
413 rc= mysql_query(mysql, "DROP TABLE IF EXISTS bulk5");
414 check_mysql_rc(rc, mysql);
415
416 return OK;
417 }
418
bulk6(MYSQL * mysql)419 static int bulk6(MYSQL *mysql)
420 {
421 MYSQL_STMT *stmt= mysql_stmt_init(mysql);
422 MYSQL_BIND bind[3];
423 MYSQL_RES *res;
424 unsigned long rows;
425 unsigned int array_size= 5;
426 int rc;
427 int intval[]= {12,13,14,15,16};
428 int id[]= {1,2,3,4,5};
429 char indicator[5];
430
431 if (!bulk_enabled)
432 return SKIP;
433 memset(indicator, STMT_INDICATOR_IGNORE, 5);
434
435 rc= mysql_query(mysql, "DROP TABLE IF EXISTS bulk6");
436 check_mysql_rc(rc, mysql);
437
438 rc= mysql_query(mysql, "CREATE TABLE bulk6 (a int, b int default 4)");
439 check_mysql_rc(rc, mysql);
440
441 rc= mysql_query(mysql, "INSERT INTO bulk6 VALUES (1,1), (2,2), (3,3), (4,4), (5,5)");
442 check_mysql_rc(rc, mysql);
443
444
445 memset(bind, 0, sizeof(MYSQL_BIND) * 3);
446
447 /* 1st case: UPDATE */
448 rc= mysql_stmt_prepare(stmt, SL("UPDATE bulk6 SET a=?, b=? WHERE a=?"));
449 check_stmt_rc(rc, stmt);
450
451 bind[0].buffer_type= MYSQL_TYPE_LONG;
452 bind[0].buffer= &intval;
453 bind[1].buffer_type= MYSQL_TYPE_LONG;
454 bind[1].buffer= &intval;
455 bind[1].u.indicator= indicator;
456 bind[2].buffer_type= MYSQL_TYPE_LONG;
457 bind[2].buffer= &id;
458
459 rc= mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
460 check_stmt_rc(rc, stmt);
461
462 rc= mysql_stmt_bind_param(stmt, bind);
463 check_stmt_rc(rc, stmt);
464
465 rc= mysql_stmt_execute(stmt);
466 check_stmt_rc(rc, stmt);
467
468 mysql_stmt_close(stmt);
469
470 rc= mysql_query(mysql, "SELECT * FROM bulk6 WHERE a=b+11");
471 check_mysql_rc(rc, mysql);
472
473 res= mysql_store_result(mysql);
474 rows= (unsigned long)mysql_num_rows(res);
475 mysql_free_result(res);
476
477 FAIL_IF(rows != 5, "expected 5 rows");
478
479 /* 2nd case: INSERT - ignore indicator should be same as default */
480 rc= mysql_query(mysql, "DELETE FROM bulk6");
481 check_mysql_rc(rc, mysql);
482
483 stmt= mysql_stmt_init(mysql);
484 rc= mysql_stmt_prepare(stmt, SL("INSERT INTO bulk6 VALUES (?,?)"));
485 check_stmt_rc(rc, stmt);
486
487 rc= mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
488 check_stmt_rc(rc, stmt);
489
490 /* this should insert 5 default values (=4) */
491 memset(indicator, STMT_INDICATOR_DEFAULT, 5);
492 rc= mysql_stmt_bind_param(stmt, bind);
493 check_stmt_rc(rc, stmt);
494 rc= mysql_stmt_execute(stmt);
495 check_stmt_rc(rc, stmt);
496
497 /* this should insert 5 default values (=4) */
498 memset(indicator, STMT_INDICATOR_IGNORE, 5);
499 rc= mysql_stmt_execute(stmt);
500 check_stmt_rc(rc, stmt);
501
502 mysql_stmt_close(stmt);
503
504 rc= mysql_query(mysql, "SELECT * FROM bulk6 WHERE b=4");
505 check_mysql_rc(rc, mysql);
506
507 res= mysql_store_result(mysql);
508 rows= (unsigned long)mysql_num_rows(res);
509 mysql_free_result(res);
510
511 FAIL_IF(rows != 10, "expected 10 rows");
512 rc= mysql_query(mysql, "DROP TABLE IF EXISTS bulk6");
513 check_mysql_rc(rc, mysql);
514
515 return OK;
516 }
517
test_conc243(MYSQL * mysql)518 static int test_conc243(MYSQL *mysql)
519 {
520 MYSQL_STMT *stmt;
521 MYSQL_BIND bind[3];
522 MYSQL_RES *result;
523 MYSQL_ROW row;
524
525 struct st_data {
526 unsigned long id;
527 char id_ind;
528 char forename[30];
529 char forename_ind;
530 char surname[30];
531 char surname_ind;
532 };
533
534 struct st_data data[]= {
535 {0, STMT_INDICATOR_NULL, "Monty", STMT_INDICATOR_NTS, "Widenius", STMT_INDICATOR_NTS},
536 {0, STMT_INDICATOR_NULL, "David", STMT_INDICATOR_NTS, "Axmark", STMT_INDICATOR_NTS},
537 {0, STMT_INDICATOR_NULL, "default", STMT_INDICATOR_DEFAULT, "N.N.", STMT_INDICATOR_NTS},
538 };
539
540 unsigned int array_size= 1;
541 size_t row_size= sizeof(struct st_data);
542 int rc;
543
544 if (!bulk_enabled)
545 return SKIP;
546 rc= mysql_query(mysql, "DROP TABLE IF EXISTS bulk_example2");
547 check_mysql_rc(rc, mysql);
548
549 rc= mysql_query(mysql, "CREATE TABLE bulk_example2 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,"\
550 "forename CHAR(30) NOT NULL DEFAULT 'unknown', surname CHAR(30))");
551 check_mysql_rc(rc, mysql);
552
553 stmt= mysql_stmt_init(mysql);
554 rc= mysql_stmt_prepare(stmt, SL("INSERT INTO bulk_example2 VALUES (?,?,?)"));
555 check_stmt_rc(rc, stmt);
556
557 memset(bind, 0, sizeof(MYSQL_BIND) * 3);
558
559 /* We autogenerate id's, so all indicators are STMT_INDICATOR_NULL */
560 bind[0].u.indicator= &data[0].id_ind;
561 bind[0].buffer_type= MYSQL_TYPE_LONG;
562
563 bind[1].buffer= &data[0].forename;
564 bind[1].buffer_type= MYSQL_TYPE_STRING;
565 bind[1].u.indicator= &data[0].forename_ind;
566
567 bind[2].buffer_type= MYSQL_TYPE_STRING;
568 bind[2].buffer= &data[0].surname;
569 bind[2].u.indicator= &data[0].surname_ind;
570
571 /* set array size */
572 mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
573
574 /* set row size */
575 mysql_stmt_attr_set(stmt, STMT_ATTR_ROW_SIZE, &row_size);
576
577 /* bind parameter */
578 mysql_stmt_bind_param(stmt, bind);
579
580 /* execute */
581 rc= mysql_stmt_execute(stmt);
582 check_stmt_rc(rc, stmt);
583
584 mysql_stmt_close(stmt);
585
586 rc= mysql_query(mysql, "SELECT forename, surname FROM bulk_example2");
587 check_mysql_rc(rc, mysql);
588
589 result= mysql_store_result(mysql);
590 FAIL_IF(!result || !mysql_num_rows(result), "Invalid resultset");
591 row = mysql_fetch_row(result);
592 if (strcmp(row[0], "Monty") || strcmp(row[1], "Widenius"))
593 {
594 mysql_free_result(result);
595 diag("Wrong values");
596 return FAIL;
597 }
598 mysql_free_result(result);
599 rc= mysql_query(mysql, "DROP TABLE bulk_example2");
600 check_mysql_rc(rc, mysql);
601 return OK;
602 }
bulk7(MYSQL * mysql)603 static int bulk7(MYSQL *mysql)
604 {
605 MYSQL_STMT *stmt= mysql_stmt_init(mysql);
606 int rc;
607 int array_size= 5;
608
609 rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
610 check_mysql_rc(rc, mysql);
611 rc= mysql_query(mysql, "CREATE TABLE t1 (a int)");
612 check_mysql_rc(rc, mysql);
613 rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)");
614 check_mysql_rc(rc, mysql);
615
616 rc= mysql_stmt_prepare(stmt, SL("UPDATE t1 SET a=a+1"));
617 check_stmt_rc(rc, stmt);
618
619 rc= mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
620 check_stmt_rc(rc, stmt);
621 rc= mysql_stmt_execute(stmt);
622
623 FAIL_IF(!rc, "Error expected: Bulk operation without parameters is not supported");
624 diag("%s", mysql_stmt_error(stmt));
625
626 mysql_stmt_close(stmt);
627 rc= mysql_query(mysql, "DROP TABLE t1");
628 check_mysql_rc(rc, mysql);
629
630 return OK;
631 }
632
test_char_conv1(MYSQL * mysql)633 static int test_char_conv1(MYSQL *mysql)
634 {
635 MYSQL_STMT *stmt;
636 int rc;
637 MYSQL_BIND bind_in, bind_out;
638 char buffer[100];
639 char outbuffer[100];
640
641 if (!bulk_enabled)
642 return SKIP;
643 stmt= mysql_stmt_init(mysql);
644 strcpy (buffer, "\xC3\x82\xC3\x83\xC3\x84\x00");
645
646 rc= mysql_query(mysql, "SET NAMES UTF8");
647 check_mysql_rc(rc, mysql);
648 rc= mysql_query(mysql, "DROP TABLE IF EXISTS char_conv");
649 check_mysql_rc(rc, mysql);
650 rc= mysql_query(mysql, "CREATE TABLE char_conv (a varchar(20)) CHARSET=latin1");
651 check_mysql_rc(rc, mysql);
652
653 rc= mysql_stmt_prepare(stmt, SL("INSERT INTO char_conv VALUES (?)"));
654 check_stmt_rc(rc, stmt);
655
656 memset(&bind_in, 0, sizeof(MYSQL_BIND));
657 bind_in.buffer_type= MYSQL_TYPE_STRING;
658 bind_in.buffer_length= -1;
659 bind_in.buffer= &buffer;
660
661 rc= mysql_stmt_bind_param(stmt, &bind_in);
662 check_stmt_rc(rc, stmt);
663
664 rc= mysql_stmt_execute(stmt);
665 check_stmt_rc(rc, stmt);
666
667 mysql_stmt_close(stmt);
668
669 stmt= mysql_stmt_init(mysql);
670
671 rc= mysql_stmt_prepare(stmt, SL("SELECT a from char_conv"));
672 check_stmt_rc(rc, stmt);
673
674 memset(&bind_out, 0, sizeof(MYSQL_BIND));
675 bind_out.buffer_type= MYSQL_TYPE_STRING;
676 bind_out.buffer_length= 100;
677 bind_out.buffer= outbuffer;
678
679 rc= mysql_stmt_bind_result(stmt, &bind_out);
680 check_stmt_rc(rc, stmt);
681
682 rc= mysql_stmt_execute(stmt);
683 check_stmt_rc(rc, stmt);
684
685 rc= mysql_stmt_fetch(stmt);
686 FAIL_IF(rc == MYSQL_NO_DATA, "Error");
687
688 mysql_stmt_close(stmt);
689
690
691 if (strcmp(buffer, outbuffer))
692 {
693 diag("Error: Expected '%s' instead of '%s'", buffer, outbuffer);
694 return FAIL;
695 }
696
697 rc= mysql_query(mysql, "DROP TABLE char_conv");
698 check_mysql_rc(rc, mysql);
699
700 return OK;
701 }
702
703
test_char_conv2(MYSQL * mysql)704 static int test_char_conv2(MYSQL *mysql)
705 {
706 MYSQL_STMT *stmt;
707 int rc;
708 int array_size= 1;
709 MYSQL_BIND bind_in, bind_out;
710 char *buffer[1];
711 char outbuffer[100];
712
713 if (!bulk_enabled)
714 return SKIP;
715
716 stmt= mysql_stmt_init(mysql);
717 buffer[0]= calloc(1, 7);
718 strcpy (buffer[0], "\xC3\x82\xC3\x83\xC3\x84\x00");
719
720 rc= mysql_query(mysql, "SET NAMES UTF8");
721 check_mysql_rc(rc, mysql);
722 rc= mysql_query(mysql, "DROP TABLE IF EXISTS char_conv");
723 check_mysql_rc(rc, mysql);
724 rc= mysql_query(mysql, "CREATE TABLE char_conv (a varchar(20)) CHARSET=latin1");
725 check_mysql_rc(rc, mysql);
726
727 rc= mysql_stmt_prepare(stmt, SL("INSERT INTO char_conv VALUES (?)"));
728 check_stmt_rc(rc, stmt);
729
730 rc= mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
731 check_stmt_rc(rc, stmt);
732
733 memset(&bind_in, 0, sizeof(MYSQL_BIND));
734 bind_in.buffer_type= MYSQL_TYPE_STRING;
735 bind_in.buffer_length= -1;
736 bind_in.buffer= &buffer;
737
738 rc= mysql_stmt_bind_param(stmt, &bind_in);
739 check_stmt_rc(rc, stmt);
740
741 rc= mysql_stmt_execute(stmt);
742 check_stmt_rc(rc, stmt);
743
744 mysql_stmt_close(stmt);
745
746 stmt= mysql_stmt_init(mysql);
747
748 rc= mysql_stmt_prepare(stmt, SL("SELECT a from char_conv"));
749 check_stmt_rc(rc, stmt);
750
751 memset(&bind_out, 0, sizeof(MYSQL_BIND));
752 bind_out.buffer_type= MYSQL_TYPE_STRING;
753 bind_out.buffer_length= 100;
754 bind_out.buffer= outbuffer;
755
756 rc= mysql_stmt_bind_result(stmt, &bind_out);
757 check_stmt_rc(rc, stmt);
758
759 rc= mysql_stmt_execute(stmt);
760 check_stmt_rc(rc, stmt);
761
762 rc= mysql_stmt_fetch(stmt);
763 FAIL_IF(rc == MYSQL_NO_DATA, "Error");
764
765 mysql_stmt_close(stmt);
766
767
768 if (strcmp(buffer[0], outbuffer))
769 {
770 diag("Error: Expected '%s' instead of '%s'", buffer[0], outbuffer);
771 return FAIL;
772 }
773 free(buffer[0]);
774
775 rc= mysql_query(mysql, "DROP TABLE char_conv");
776 check_mysql_rc(rc, mysql);
777
778 return OK;
779 }
780
781
bulk_skip_row(MYSQL * mysql)782 static int bulk_skip_row(MYSQL *mysql)
783 {
784 MYSQL_STMT *stmt;
785 MYSQL_BIND bind[3];
786 MYSQL_RES *result;
787 MYSQL_ROW row;
788
789 struct st_data {
790 unsigned long id;
791 char id_ind;
792 char forename[30];
793 char forename_ind;
794 char surname[30];
795 char surname_ind;
796 };
797
798 struct st_data data[]={
799 { 0, STMT_INDICATOR_NULL, "Monty", STMT_INDICATOR_NTS, "Widenius", STMT_INDICATOR_IGNORE_ROW },
800 { 0, STMT_INDICATOR_IGNORE_ROW, "David", STMT_INDICATOR_NTS, "Axmark", STMT_INDICATOR_NTS },
801 { 0, STMT_INDICATOR_NULL, "default", STMT_INDICATOR_DEFAULT, "N.N.", STMT_INDICATOR_NTS },
802 };
803
804 unsigned int array_size= 3;
805 size_t row_size= sizeof(struct st_data);
806 int rc;
807
808 if (!bulk_enabled)
809 return SKIP;
810 rc= mysql_query(mysql, "DROP TABLE IF EXISTS bulk_example2");
811 check_mysql_rc(rc, mysql);
812
813 rc= mysql_query(mysql, "CREATE TABLE bulk_example2 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,"\
814 "forename CHAR(30) NOT NULL DEFAULT 'unknown', surname CHAR(30))");
815 check_mysql_rc(rc, mysql);
816
817 stmt= mysql_stmt_init(mysql);
818 rc= mysql_stmt_prepare(stmt, SL("INSERT INTO bulk_example2 VALUES (?,?,?)"));
819 check_stmt_rc(rc, stmt);
820
821 memset(bind, 0, sizeof(MYSQL_BIND) * 3);
822
823 /* We autogenerate id's, so all indicators are STMT_INDICATOR_NULL */
824 bind[0].u.indicator= &data[0].id_ind;
825 bind[0].buffer_type= MYSQL_TYPE_LONG;
826
827 bind[1].buffer= &data[0].forename;
828 bind[1].buffer_type= MYSQL_TYPE_STRING;
829 bind[1].u.indicator= &data[0].forename_ind;
830
831 bind[2].buffer_type= MYSQL_TYPE_STRING;
832 bind[2].buffer= &data[0].surname;
833 bind[2].u.indicator= &data[0].surname_ind;
834
835 /* set array size */
836 mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
837
838 /* set row size */
839 mysql_stmt_attr_set(stmt, STMT_ATTR_ROW_SIZE, &row_size);
840
841 /* bind parameter */
842 mysql_stmt_bind_param(stmt, bind);
843
844 /* execute */
845 rc= mysql_stmt_execute(stmt);
846 check_stmt_rc(rc, stmt);
847
848 mysql_stmt_close(stmt);
849
850 rc= mysql_query(mysql, "SELECT forename, surname FROM bulk_example2");
851 check_mysql_rc(rc, mysql);
852
853 result= mysql_store_result(mysql);
854 FAIL_IF(!result || mysql_num_rows(result) != 1, "Invalid resultset");
855
856 row = mysql_fetch_row(result);
857 if (strcmp(row[0], "unknown") || strcmp(row[1], "N.N."))
858 {
859 mysql_free_result(result);
860 diag("Wrong values");
861 return FAIL;
862 }
863 mysql_free_result(result);
864 rc= mysql_query(mysql, "DROP TABLE bulk_example2");
865 check_mysql_rc(rc, mysql);
866 return OK;
867 }
868
bulk_null_null(MYSQL * mysql)869 static int bulk_null_null(MYSQL *mysql)
870 {
871 struct st_bulk4 {
872 char char_value[20];
873 char indicator1;
874 int int_value;
875 char indicator2;
876 double double_value;
877 char indicator3;
878 char time_value[20];
879 char indicator4;
880 char decimal_value[4];
881 char indicator5;
882 };
883
884 struct st_bulk4 val[]= {{"3", STMT_INDICATOR_NTS,
885 3, STMT_INDICATOR_NONE,
886 3.0, STMT_INDICATOR_NONE,
887 "00:00:00", STMT_INDICATOR_NTS,
888 "3.0", STMT_INDICATOR_NTS},
889 {"3", STMT_INDICATOR_NULL,
890 3, STMT_INDICATOR_NULL,
891 3.0, STMT_INDICATOR_NULL,
892 "00:00:00", STMT_INDICATOR_NULL,
893 "3.0", STMT_INDICATOR_NULL},
894 {"3", STMT_INDICATOR_NTS,
895 3, STMT_INDICATOR_NONE,
896 3.0, STMT_INDICATOR_NONE,
897 "00:00:00", STMT_INDICATOR_NTS,
898 "3.0", STMT_INDICATOR_NTS}};
899 int rc;
900 MYSQL_BIND bind[5];
901 MYSQL_RES *res;
902 MYSQL_STMT *stmt= mysql_stmt_init(mysql);
903 size_t row_size= sizeof(struct st_bulk4);
904 int array_size= 3;
905 unsigned long server_version= mysql_get_server_version(mysql);
906 unsigned long lengths[3]= {-1, -1, -1};
907
908 if (!bulk_enabled)
909 return SKIP;
910
911 if (server_version > 100300 &&
912 server_version < 100305)
913 return SKIP;
914
915 rc= mysql_query(mysql, "DROP TABLE IF EXISTS bulk_null");
916 check_mysql_rc(rc,mysql);
917 rc= mysql_query(mysql, "CREATE TABLE bulk_null "
918 "(s varchar(20), "
919 " i int, "
920 " d double, "
921 " t time, "
922 " c decimal(3,1))");
923 check_mysql_rc(rc,mysql);
924
925 rc= mysql_stmt_prepare(stmt, "INSERT INTO bulk_null VALUES (?,?,?,?,?)", -1);
926 check_stmt_rc(rc, stmt);
927
928 memset(bind, 0, sizeof(MYSQL_BIND)*5);
929
930 rc= mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
931 check_stmt_rc(rc, stmt);
932 rc= mysql_stmt_attr_set(stmt, STMT_ATTR_ROW_SIZE, &row_size);
933 check_stmt_rc(rc, stmt);
934
935 bind[0].buffer_type= MYSQL_TYPE_STRING;
936 bind[0].u.indicator= &val[0].indicator1;
937 bind[0].buffer= &val[0].char_value;
938 bind[0].length= lengths;
939 bind[1].buffer_type= MYSQL_TYPE_LONG;
940 bind[1].buffer= &val[0].int_value;
941 bind[1].u.indicator= &val[0].indicator2;
942 bind[2].buffer_type= MYSQL_TYPE_DOUBLE;
943 bind[2].buffer= &val[0].double_value;
944 bind[2].u.indicator= &val[0].indicator3;
945 bind[3].buffer_type= MYSQL_TYPE_STRING;
946 bind[3].u.indicator= &val[0].indicator4;
947 bind[3].buffer= &val[0].time_value;
948 bind[3].length= lengths;
949 bind[4].buffer_type= MYSQL_TYPE_NEWDECIMAL;
950 bind[4].u.indicator= &val[0].indicator5;
951 bind[4].buffer= &val[0].decimal_value;
952 bind[4].length= lengths;
953
954 rc= mysql_stmt_bind_param(stmt, bind);
955 check_stmt_rc(rc, stmt);
956 rc= mysql_stmt_execute(stmt);
957 check_stmt_rc(rc, stmt);
958
959 mysql_stmt_close(stmt);
960
961 rc= mysql_query(mysql, "SELECT * FROM bulk_null WHERE s='3'");
962 check_mysql_rc(rc, mysql);
963 res= mysql_store_result(mysql);
964 rc= (int)mysql_num_rows(res);
965 mysql_free_result(res);
966 FAIL_IF(rc != 2, "expected 2 rows");
967
968 rc= mysql_query(mysql, "SELECT * FROM bulk_null WHERE i=3");
969 check_mysql_rc(rc, mysql);
970 res= mysql_store_result(mysql);
971 rc= (int)mysql_num_rows(res);
972 mysql_free_result(res);
973 FAIL_IF(rc != 2, "expected 2 rows");
974
975 rc= mysql_query(mysql, "SELECT * FROM bulk_null WHERE d=3.0");
976 check_mysql_rc(rc, mysql);
977 res= mysql_store_result(mysql);
978 rc= (int)mysql_num_rows(res);
979 mysql_free_result(res);
980 FAIL_IF(rc != 2, "expected 2 rows");
981
982 rc= mysql_query(mysql, "SELECT * FROM bulk_null WHERE t='00:00:00'");
983 check_mysql_rc(rc, mysql);
984 res= mysql_store_result(mysql);
985 rc= (int)mysql_num_rows(res);
986 mysql_free_result(res);
987 FAIL_IF(rc != 2, "expected 2 rows");
988
989 rc= mysql_query(mysql, "SELECT * FROM bulk_null WHERE c=3.0");
990 check_mysql_rc(rc, mysql);
991 res= mysql_store_result(mysql);
992 rc= (int)mysql_num_rows(res);
993 mysql_free_result(res);
994 FAIL_IF(rc != 2, "expected 2 rows");
995
996 rc= mysql_query(mysql, "DROP TABLE bulk_null");
997 check_mysql_rc(rc, mysql);
998 return OK;
999 }
1000
test_mdev16593(MYSQL * mysql)1001 static int test_mdev16593(MYSQL *mysql)
1002 {
1003 int i;
1004 int rc;
1005 MYSQL_BIND bind[2];
1006 unsigned int array_size= 2;
1007 int val_a[2]= {1,2};
1008 char indicators[2]= {STMT_INDICATOR_NULL, STMT_INDICATOR_NULL};
1009 const char *testcase[]= {"MYSQL_TYPE_LONG", "MYSQL_TYPE_NULL", "STMT_INDICATOR_NULL"};
1010
1011 diag("waiting for server fix");
1012 return SKIP;
1013
1014 memset(&bind, 0, 2 * sizeof(MYSQL_BIND));
1015 for (i=0; i < 3; i++)
1016 {
1017 MYSQL_RES *res;
1018 MYSQL_ROW row;
1019 MYSQL_STMT *stmt= mysql_stmt_init(mysql);
1020 rc= mysql_query(mysql, "CREATE OR REPLACE TABLE t1 (a int not null auto_increment primary key, b int)");
1021 check_mysql_rc(rc, mysql);
1022 switch (i) {
1023 case 0:
1024 bind[0].buffer_type= MYSQL_TYPE_LONG;
1025 break;
1026 case 1:
1027 bind[0].buffer_type= MYSQL_TYPE_NULL;
1028 break;
1029 case 2:
1030 bind[0].buffer_type= MYSQL_TYPE_LONG;
1031 bind[0].u.indicator= indicators;
1032 break;
1033 }
1034 bind[0].buffer= val_a;
1035 bind[1].buffer_type= MYSQL_TYPE_LONG;
1036 bind[1].buffer= val_a;
1037
1038 rc= mysql_stmt_prepare(stmt, SL("insert into t1 values(?,?)"));
1039 check_stmt_rc(rc, stmt);
1040
1041 rc= mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
1042 check_stmt_rc(rc, stmt);
1043
1044 rc= mysql_stmt_bind_param(stmt, bind);
1045 check_stmt_rc(rc, stmt);
1046
1047 rc= mysql_stmt_execute(stmt);
1048 check_stmt_rc(rc, stmt);
1049
1050 rc= mysql_query(mysql, "COMMIT");
1051 check_mysql_rc(rc, mysql);
1052
1053 diag("Insert id with buffer_type %s: %lld",
1054 testcase[i],
1055 mysql_stmt_insert_id(stmt));
1056
1057 rc= mysql_query(mysql, "SELECT max(a) FROM t1");
1058 check_mysql_rc(rc, mysql);
1059
1060 res= mysql_store_result(mysql);
1061 row= mysql_fetch_row(res);
1062 diag("Max value for t1.a=%s", row[0]);
1063 mysql_free_result(res);
1064
1065 mysql_stmt_close(stmt);
1066 }
1067 return OK;
1068 }
1069
1070 struct my_tests_st my_tests[] = {
1071 {"check_bulk", check_bulk, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
1072 {"test_mdev16593", test_mdev16593, TEST_CONNECTION_NEW, 0, NULL, NULL},
1073 {"bulk_null_null", bulk_null_null, TEST_CONNECTION_NEW, 0, NULL, NULL},
1074 {"test_char_conv1", test_char_conv1, TEST_CONNECTION_NEW, 0, NULL, NULL},
1075 {"test_char_conv2", test_char_conv2, TEST_CONNECTION_NEW, 0, NULL, NULL},
1076 {"test_conc243", test_conc243, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
1077 {"update_no_param", bulk7, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
1078 {"bulk5", bulk5, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
1079 {"bulk6", bulk6, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
1080 {"bulk1", bulk1, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
1081 {"bulk2", bulk2, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
1082 {"bulk3", bulk3, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
1083 {"bulk4", bulk4, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
1084 {"bulk_null", bulk_null, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
1085 {"bulk_skip_row", bulk_skip_row, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
1086 {NULL, NULL, 0, 0, NULL, NULL}
1087 };
1088
main(int argc,char ** argv)1089 int main(int argc, char **argv)
1090 {
1091 if (argc > 1)
1092 get_options(argc, argv);
1093
1094 get_envvars();
1095
1096 run_tests(my_tests);
1097
1098 return(exit_status());
1099 }
1100