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
22static my_bool bulk_enabled= 0;
23
24char *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
37static 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
46static 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
140static 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
190static 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
241static 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
303static 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, &param_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);
351 rc= mysql_query(mysql, "DROP TABLE IF EXISTS bulk_null");
352 check_mysql_rc(rc, mysql);
353 return OK;
354}
355
356static int bulk5(MYSQL *mysql)
357{
358 MYSQL_STMT *stmt= mysql_stmt_init(mysql);
359 MYSQL_BIND bind[3];
360 MYSQL_RES *res;
361 unsigned long rows;
362 unsigned int array_size= 5;
363 int rc;
364 int intval[]= {12,13,14,15,16};
365 int id[]= {1,2,3,4,5};
366
367 if (!bulk_enabled)
368 return SKIP;
369
370 rc= mysql_query(mysql, "DROP TABLE IF EXISTS bulk5");
371 check_mysql_rc(rc, mysql);
372
373 rc= mysql_query(mysql, "CREATE TABLE bulk5 (a int, b int)");
374 check_mysql_rc(rc, mysql);
375
376 rc= mysql_query(mysql, "INSERT INTO bulk5 VALUES (1,1), (2,2), (3,3), (4,4), (5,5)");
377 check_mysql_rc(rc, mysql);
378
379
380 memset(bind, 0, sizeof(MYSQL_BIND) * 3);
381
382 rc= mysql_stmt_prepare(stmt, SL("UPDATE bulk5 SET a=? WHERE a=?"));
383 check_stmt_rc(rc, stmt);
384
385 bind[0].buffer_type= MYSQL_TYPE_LONG;
386 bind[0].buffer= &intval;
387 bind[1].buffer_type= MYSQL_TYPE_LONG;
388 bind[1].buffer= &id;
389
390 rc= mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
391 check_stmt_rc(rc, stmt);
392
393 rc= mysql_stmt_bind_param(stmt, bind);
394 check_stmt_rc(rc, stmt);
395
396 rc= mysql_stmt_execute(stmt);
397 check_stmt_rc(rc, stmt);
398
399 mysql_stmt_close(stmt);
400
401 rc= mysql_query(mysql, "SELECT * FROM bulk5 WHERE a=b+11");
402 check_mysql_rc(rc, mysql);
403
404 res= mysql_store_result(mysql);
405 rows= (unsigned long)mysql_num_rows(res);
406 diag("rows: %lu", rows);
407 mysql_free_result(res);
408
409 FAIL_IF(rows != 5, "expected 5 rows");
410
411 rc= mysql_query(mysql, "DROP TABLE IF EXISTS bulk5");
412 check_mysql_rc(rc, mysql);
413
414 return OK;
415}
416
417static int bulk6(MYSQL *mysql)
418{
419 MYSQL_STMT *stmt= mysql_stmt_init(mysql);
420 MYSQL_BIND bind[3];
421 MYSQL_RES *res;
422 unsigned long rows;
423 unsigned int array_size= 5;
424 int rc;
425 int intval[]= {12,13,14,15,16};
426 int id[]= {1,2,3,4,5};
427 char indicator[5];
428
429 if (!bulk_enabled)
430 return SKIP;
431 memset(indicator, STMT_INDICATOR_IGNORE, 5);
432
433 rc= mysql_query(mysql, "DROP TABLE IF EXISTS bulk6");
434 check_mysql_rc(rc, mysql);
435
436 rc= mysql_query(mysql, "CREATE TABLE bulk6 (a int, b int default 4)");
437 check_mysql_rc(rc, mysql);
438
439 rc= mysql_query(mysql, "INSERT INTO bulk6 VALUES (1,1), (2,2), (3,3), (4,4), (5,5)");
440 check_mysql_rc(rc, mysql);
441
442
443 memset(bind, 0, sizeof(MYSQL_BIND) * 3);
444
445 /* 1st case: UPDATE */
446 rc= mysql_stmt_prepare(stmt, SL("UPDATE bulk6 SET a=?, b=? WHERE a=?"));
447 check_stmt_rc(rc, stmt);
448
449 bind[0].buffer_type= MYSQL_TYPE_LONG;
450 bind[0].buffer= &intval;
451 bind[1].buffer_type= MYSQL_TYPE_LONG;
452 bind[1].buffer= &intval;
453 bind[1].u.indicator= indicator;
454 bind[2].buffer_type= MYSQL_TYPE_LONG;
455 bind[2].buffer= &id;
456
457 rc= mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
458 check_stmt_rc(rc, stmt);
459
460 rc= mysql_stmt_bind_param(stmt, bind);
461 check_stmt_rc(rc, stmt);
462
463 rc= mysql_stmt_execute(stmt);
464 check_stmt_rc(rc, stmt);
465
466 mysql_stmt_close(stmt);
467
468 rc= mysql_query(mysql, "SELECT * FROM bulk6 WHERE a=b+11");
469 check_mysql_rc(rc, mysql);
470
471 res= mysql_store_result(mysql);
472 rows= (unsigned long)mysql_num_rows(res);
473 mysql_free_result(res);
474
475 FAIL_IF(rows != 5, "expected 5 rows");
476
477 /* 2nd case: INSERT - ignore indicator should be same as default */
478 rc= mysql_query(mysql, "DELETE FROM bulk6");
479 check_mysql_rc(rc, mysql);
480
481 stmt= mysql_stmt_init(mysql);
482 rc= mysql_stmt_prepare(stmt, SL("INSERT INTO bulk6 VALUES (?,?)"));
483 check_stmt_rc(rc, stmt);
484
485 rc= mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
486 check_stmt_rc(rc, stmt);
487
488 /* this should insert 5 default values (=4) */
489 memset(indicator, STMT_INDICATOR_DEFAULT, 5);
490 rc= mysql_stmt_bind_param(stmt, bind);
491 check_stmt_rc(rc, stmt);
492 rc= mysql_stmt_execute(stmt);
493 check_stmt_rc(rc, stmt);
494
495 /* this should insert 5 default values (=4) */
496 memset(indicator, STMT_INDICATOR_IGNORE, 5);
497 rc= mysql_stmt_execute(stmt);
498 check_stmt_rc(rc, stmt);
499
500 mysql_stmt_close(stmt);
501
502 rc= mysql_query(mysql, "SELECT * FROM bulk6 WHERE b=4");
503 check_mysql_rc(rc, mysql);
504
505 res= mysql_store_result(mysql);
506 rows= (unsigned long)mysql_num_rows(res);
507 mysql_free_result(res);
508
509 FAIL_IF(rows != 10, "expected 10 rows");
510 rc= mysql_query(mysql, "DROP TABLE IF EXISTS bulk6");
511 check_mysql_rc(rc, mysql);
512
513 return OK;
514}
515
516static int test_conc243(MYSQL *mysql)
517{
518 MYSQL_STMT *stmt;
519 MYSQL_BIND bind[3];
520 MYSQL_RES *result;
521 MYSQL_ROW row;
522
523 struct st_data {
524 unsigned long id;
525 char id_ind;
526 char forename[30];
527 char forename_ind;
528 char surname[30];
529 char surname_ind;
530 };
531
532 struct st_data data[]= {
533 {0, STMT_INDICATOR_NULL, "Monty", STMT_INDICATOR_NTS, "Widenius", STMT_INDICATOR_NTS},
534 {0, STMT_INDICATOR_NULL, "David", STMT_INDICATOR_NTS, "Axmark", STMT_INDICATOR_NTS},
535 {0, STMT_INDICATOR_NULL, "default", STMT_INDICATOR_DEFAULT, "N.N.", STMT_INDICATOR_NTS},
536 };
537
538 unsigned int array_size= 1;
539 size_t row_size= sizeof(struct st_data);
540 int rc;
541
542 if (!bulk_enabled)
543 return SKIP;
544 rc= mysql_query(mysql, "DROP TABLE IF EXISTS bulk_example2");
545 check_mysql_rc(rc, mysql);
546
547 rc= mysql_query(mysql, "CREATE TABLE bulk_example2 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,"\
548 "forename CHAR(30) NOT NULL DEFAULT 'unknown', surname CHAR(30))");
549 check_mysql_rc(rc, mysql);
550
551 stmt= mysql_stmt_init(mysql);
552 rc= mysql_stmt_prepare(stmt, SL("INSERT INTO bulk_example2 VALUES (?,?,?)"));
553 check_stmt_rc(rc, stmt);
554
555 memset(bind, 0, sizeof(MYSQL_BIND) * 3);
556
557 /* We autogenerate id's, so all indicators are STMT_INDICATOR_NULL */
558 bind[0].u.indicator= &data[0].id_ind;
559 bind[0].buffer_type= MYSQL_TYPE_LONG;
560
561 bind[1].buffer= &data[0].forename;
562 bind[1].buffer_type= MYSQL_TYPE_STRING;
563 bind[1].u.indicator= &data[0].forename_ind;
564
565 bind[2].buffer_type= MYSQL_TYPE_STRING;
566 bind[2].buffer= &data[0].surname;
567 bind[2].u.indicator= &data[0].surname_ind;
568
569 /* set array size */
570 mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
571
572 /* set row size */
573 mysql_stmt_attr_set(stmt, STMT_ATTR_ROW_SIZE, &row_size);
574
575 /* bind parameter */
576 mysql_stmt_bind_param(stmt, bind);
577
578 /* execute */
579 rc= mysql_stmt_execute(stmt);
580 check_stmt_rc(rc, stmt);
581
582 mysql_stmt_close(stmt);
583
584 rc= mysql_query(mysql, "SELECT forename, surname FROM bulk_example2");
585 check_mysql_rc(rc, mysql);
586
587 result= mysql_store_result(mysql);
588 FAIL_IF(!result || !mysql_num_rows(result), "Invalid resultset");
589 row = mysql_fetch_row(result);
590 if (strcmp(row[0], "Monty") || strcmp(row[1], "Widenius"))
591 {
592 mysql_free_result(result);
593 diag("Wrong values");
594 return FAIL;
595 }
596 mysql_free_result(result);
597 rc= mysql_query(mysql, "DROP TABLE bulk_example2");
598 check_mysql_rc(rc, mysql);
599 return OK;
600}
601static int bulk7(MYSQL *mysql)
602{
603 MYSQL_STMT *stmt= mysql_stmt_init(mysql);
604 int rc;
605 int array_size= 5;
606
607 rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
608 check_mysql_rc(rc, mysql);
609 rc= mysql_query(mysql, "CREATE TABLE t1 (a int)");
610 check_mysql_rc(rc, mysql);
611 rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)");
612 check_mysql_rc(rc, mysql);
613
614 rc= mysql_stmt_prepare(stmt, SL("UPDATE t1 SET a=a+1"));
615 check_stmt_rc(rc, stmt);
616
617 rc= mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
618 check_stmt_rc(rc, stmt);
619 rc= mysql_stmt_execute(stmt);
620
621 FAIL_IF(!rc, "Error expected: Bulk operation without parameters is not supported");
622 diag("%s", mysql_stmt_error(stmt));
623
624 mysql_stmt_close(stmt);
625 rc= mysql_query(mysql, "DROP TABLE t1");
626 check_mysql_rc(rc, mysql);
627
628 return OK;
629}
630
631static int test_char_conv1(MYSQL *mysql)
632{
633 MYSQL_STMT *stmt;
634 int rc;
635 MYSQL_BIND bind_in, bind_out;
636 char buffer[100];
637 char outbuffer[100];
638
639 if (!bulk_enabled)
640 return SKIP;
641 stmt= mysql_stmt_init(mysql);
642 strcpy (buffer, "\xC3\x82\xC3\x83\xC3\x84\x00");
643
644 rc= mysql_query(mysql, "SET NAMES UTF8");
645 check_mysql_rc(rc, mysql);
646 rc= mysql_query(mysql, "DROP TABLE IF EXISTS char_conv");
647 check_mysql_rc(rc, mysql);
648 rc= mysql_query(mysql, "CREATE TABLE char_conv (a varchar(20)) CHARSET=latin1");
649 check_mysql_rc(rc, mysql);
650
651 rc= mysql_stmt_prepare(stmt, SL("INSERT INTO char_conv VALUES (?)"));
652 check_stmt_rc(rc, stmt);
653
654 memset(&bind_in, 0, sizeof(MYSQL_BIND));
655 bind_in.buffer_type= MYSQL_TYPE_STRING;
656 bind_in.buffer_length= -1;
657 bind_in.buffer= &buffer;
658
659 rc= mysql_stmt_bind_param(stmt, &bind_in);
660 check_stmt_rc(rc, stmt);
661
662 rc= mysql_stmt_execute(stmt);
663 check_stmt_rc(rc, stmt);
664
665 mysql_stmt_close(stmt);
666
667 stmt= mysql_stmt_init(mysql);
668
669 rc= mysql_stmt_prepare(stmt, SL("SELECT a from char_conv"));
670 check_stmt_rc(rc, stmt);
671
672 memset(&bind_out, 0, sizeof(MYSQL_BIND));
673 bind_out.buffer_type= MYSQL_TYPE_STRING;
674 bind_out.buffer_length= 100;
675 bind_out.buffer= outbuffer;
676
677 rc= mysql_stmt_bind_result(stmt, &bind_out);
678 check_stmt_rc(rc, stmt);
679
680 rc= mysql_stmt_execute(stmt);
681 check_stmt_rc(rc, stmt);
682
683 rc= mysql_stmt_fetch(stmt);
684 FAIL_IF(rc == MYSQL_NO_DATA, "Error");
685
686 mysql_stmt_close(stmt);
687
688
689 if (strcmp(buffer, outbuffer))
690 {
691 diag("Error: Expected '%s' instead of '%s'", buffer, outbuffer);
692 return FAIL;
693 }
694
695 rc= mysql_query(mysql, "DROP TABLE char_conv");
696 check_mysql_rc(rc, mysql);
697
698 return OK;
699}
700
701
702static int test_char_conv2(MYSQL *mysql)
703{
704 MYSQL_STMT *stmt;
705 int rc;
706 int array_size= 1;
707 MYSQL_BIND bind_in, bind_out;
708 char *buffer[1];
709 char outbuffer[100];
710
711 if (!bulk_enabled)
712 return SKIP;
713
714 stmt= mysql_stmt_init(mysql);
715 buffer[0]= calloc(1, 7);
716 strcpy (buffer[0], "\xC3\x82\xC3\x83\xC3\x84\x00");
717
718 rc= mysql_query(mysql, "SET NAMES UTF8");
719 check_mysql_rc(rc, mysql);
720 rc= mysql_query(mysql, "DROP TABLE IF EXISTS char_conv");
721 check_mysql_rc(rc, mysql);
722 rc= mysql_query(mysql, "CREATE TABLE char_conv (a varchar(20)) CHARSET=latin1");
723 check_mysql_rc(rc, mysql);
724
725 rc= mysql_stmt_prepare(stmt, SL("INSERT INTO char_conv VALUES (?)"));
726 check_stmt_rc(rc, stmt);
727
728 rc= mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
729 check_stmt_rc(rc, stmt);
730
731 memset(&bind_in, 0, sizeof(MYSQL_BIND));
732 bind_in.buffer_type= MYSQL_TYPE_STRING;
733 bind_in.buffer_length= -1;
734 bind_in.buffer= &buffer;
735
736 rc= mysql_stmt_bind_param(stmt, &bind_in);
737 check_stmt_rc(rc, stmt);
738
739 rc= mysql_stmt_execute(stmt);
740 check_stmt_rc(rc, stmt);
741
742 mysql_stmt_close(stmt);
743
744 stmt= mysql_stmt_init(mysql);
745
746 rc= mysql_stmt_prepare(stmt, SL("SELECT a from char_conv"));
747 check_stmt_rc(rc, stmt);
748
749 memset(&bind_out, 0, sizeof(MYSQL_BIND));
750 bind_out.buffer_type= MYSQL_TYPE_STRING;
751 bind_out.buffer_length= 100;
752 bind_out.buffer= outbuffer;
753
754 rc= mysql_stmt_bind_result(stmt, &bind_out);
755 check_stmt_rc(rc, stmt);
756
757 rc= mysql_stmt_execute(stmt);
758 check_stmt_rc(rc, stmt);
759
760 rc= mysql_stmt_fetch(stmt);
761 FAIL_IF(rc == MYSQL_NO_DATA, "Error");
762
763 mysql_stmt_close(stmt);
764
765
766 if (strcmp(buffer[0], outbuffer))
767 {
768 diag("Error: Expected '%s' instead of '%s'", buffer[0], outbuffer);
769 return FAIL;
770 }
771 free(buffer[0]);
772
773 rc= mysql_query(mysql, "DROP TABLE char_conv");
774 check_mysql_rc(rc, mysql);
775
776 return OK;
777}
778
779
780static int bulk_skip_row(MYSQL *mysql)
781{
782 MYSQL_STMT *stmt;
783 MYSQL_BIND bind[3];
784 MYSQL_RES *result;
785 MYSQL_ROW row;
786
787 struct st_data {
788 unsigned long id;
789 char id_ind;
790 char forename[30];
791 char forename_ind;
792 char surname[30];
793 char surname_ind;
794 };
795
796 struct st_data data[]={
797 { 0, STMT_INDICATOR_NULL, "Monty", STMT_INDICATOR_NTS, "Widenius", STMT_INDICATOR_IGNORE_ROW },
798 { 0, STMT_INDICATOR_IGNORE_ROW, "David", STMT_INDICATOR_NTS, "Axmark", STMT_INDICATOR_NTS },
799 { 0, STMT_INDICATOR_NULL, "default", STMT_INDICATOR_DEFAULT, "N.N.", STMT_INDICATOR_NTS },
800 };
801
802 unsigned int array_size= 3;
803 size_t row_size= sizeof(struct st_data);
804 int rc;
805
806 if (!bulk_enabled)
807 return SKIP;
808 rc= mysql_query(mysql, "DROP TABLE IF EXISTS bulk_example2");
809 check_mysql_rc(rc, mysql);
810
811 rc= mysql_query(mysql, "CREATE TABLE bulk_example2 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,"\
812 "forename CHAR(30) NOT NULL DEFAULT 'unknown', surname CHAR(30))");
813 check_mysql_rc(rc, mysql);
814
815 stmt= mysql_stmt_init(mysql);
816 rc= mysql_stmt_prepare(stmt, SL("INSERT INTO bulk_example2 VALUES (?,?,?)"));
817 check_stmt_rc(rc, stmt);
818
819 memset(bind, 0, sizeof(MYSQL_BIND) * 3);
820
821 /* We autogenerate id's, so all indicators are STMT_INDICATOR_NULL */
822 bind[0].u.indicator= &data[0].id_ind;
823 bind[0].buffer_type= MYSQL_TYPE_LONG;
824
825 bind[1].buffer= &data[0].forename;
826 bind[1].buffer_type= MYSQL_TYPE_STRING;
827 bind[1].u.indicator= &data[0].forename_ind;
828
829 bind[2].buffer_type= MYSQL_TYPE_STRING;
830 bind[2].buffer= &data[0].surname;
831 bind[2].u.indicator= &data[0].surname_ind;
832
833 /* set array size */
834 mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
835
836 /* set row size */
837 mysql_stmt_attr_set(stmt, STMT_ATTR_ROW_SIZE, &row_size);
838
839 /* bind parameter */
840 mysql_stmt_bind_param(stmt, bind);
841
842 /* execute */
843 rc= mysql_stmt_execute(stmt);
844 check_stmt_rc(rc, stmt);
845
846 mysql_stmt_close(stmt);
847
848 rc= mysql_query(mysql, "SELECT forename, surname FROM bulk_example2");
849 check_mysql_rc(rc, mysql);
850
851 result= mysql_store_result(mysql);
852 FAIL_IF(!result || mysql_num_rows(result) != 1, "Invalid resultset");
853
854 row = mysql_fetch_row(result);
855 if (strcmp(row[0], "unknown") || strcmp(row[1], "N.N."))
856 {
857 mysql_free_result(result);
858 diag("Wrong values");
859 return FAIL;
860 }
861 mysql_free_result(result);
862 rc= mysql_query(mysql, "DROP TABLE bulk_example2");
863 check_mysql_rc(rc, mysql);
864 return OK;
865}
866
867static int bulk_null_null(MYSQL *mysql)
868{
869 struct st_bulk4 {
870 char char_value[20];
871 char indicator1;
872 int int_value;
873 char indicator2;
874 double double_value;
875 char indicator3;
876 char time_value[20];
877 char indicator4;
878 char decimal_value[4];
879 char indicator5;
880 };
881
882 struct st_bulk4 val[]= {{"3", STMT_INDICATOR_NTS,
883 3, STMT_INDICATOR_NONE,
884 3.0, STMT_INDICATOR_NONE,
885 "00:00:00", STMT_INDICATOR_NTS,
886 "3.0", STMT_INDICATOR_NTS},
887 {"3", STMT_INDICATOR_NULL,
888 3, STMT_INDICATOR_NULL,
889 3.0, STMT_INDICATOR_NULL,
890 "00:00:00", STMT_INDICATOR_NULL,
891 "3.0", STMT_INDICATOR_NULL},
892 {"3", STMT_INDICATOR_NTS,
893 3, STMT_INDICATOR_NONE,
894 3.0, STMT_INDICATOR_NONE,
895 "00:00:00", STMT_INDICATOR_NTS,
896 "3.0", STMT_INDICATOR_NTS}};
897 int rc;
898 MYSQL_BIND bind[5];
899 MYSQL_RES *res;
900 MYSQL_STMT *stmt= mysql_stmt_init(mysql);
901 size_t row_size= sizeof(struct st_bulk4);
902 int array_size= 3;
903 unsigned long server_version= mysql_get_server_version(mysql);
904 unsigned long lengths[3]= {-1, -1, -1};
905
906 if (!bulk_enabled)
907 return SKIP;
908
909 if (server_version > 100300 &&
910 server_version < 100305)
911 return SKIP;
912
913 rc= mysql_query(mysql, "DROP TABLE IF EXISTS bulk_null");
914 check_mysql_rc(rc,mysql);
915 rc= mysql_query(mysql, "CREATE TABLE bulk_null "
916 "(s varchar(20), "
917 " i int, "
918 " d double, "
919 " t time, "
920 " c decimal(3,1))");
921 check_mysql_rc(rc,mysql);
922
923 rc= mysql_stmt_prepare(stmt, "INSERT INTO bulk_null VALUES (?,?,?,?,?)", -1);
924 check_stmt_rc(rc, stmt);
925
926 memset(bind, 0, sizeof(MYSQL_BIND)*2);
927
928 rc= mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, &array_size);
929 check_stmt_rc(rc, stmt);
930 rc= mysql_stmt_attr_set(stmt, STMT_ATTR_ROW_SIZE, &row_size);
931 check_stmt_rc(rc, stmt);
932
933 bind[0].buffer_type= MYSQL_TYPE_STRING;
934 bind[0].u.indicator= &val[0].indicator1;
935 bind[0].buffer= &val[0].char_value;
936 bind[0].length= lengths;
937 bind[1].buffer_type= MYSQL_TYPE_LONG;
938 bind[1].buffer= &val[0].int_value;
939 bind[1].u.indicator= &val[0].indicator2;
940 bind[2].buffer_type= MYSQL_TYPE_DOUBLE;
941 bind[2].buffer= &val[0].double_value;
942 bind[2].u.indicator= &val[0].indicator3;
943 bind[3].buffer_type= MYSQL_TYPE_STRING;
944 bind[3].u.indicator= &val[0].indicator4;
945 bind[3].buffer= &val[0].time_value;
946 bind[3].length= lengths;
947 bind[4].buffer_type= MYSQL_TYPE_NEWDECIMAL;
948 bind[4].u.indicator= &val[0].indicator5;
949 bind[4].buffer= &val[0].decimal_value;
950 bind[4].length= lengths;
951
952 rc= mysql_stmt_bind_param(stmt, bind);
953 check_stmt_rc(rc, stmt);
954 rc= mysql_stmt_execute(stmt);
955 check_stmt_rc(rc, stmt);
956
957 mysql_stmt_close(stmt);
958
959 rc= mysql_query(mysql, "SELECT * FROM bulk_null WHERE s='3'");
960 check_mysql_rc(rc, mysql);
961 res= mysql_store_result(mysql);
962 rc= (int)mysql_num_rows(res);
963 mysql_free_result(res);
964 FAIL_IF(rc != 2, "expected 2 rows");
965
966 rc= mysql_query(mysql, "SELECT * FROM bulk_null WHERE i=3");
967 check_mysql_rc(rc, mysql);
968 res= mysql_store_result(mysql);
969 rc= (int)mysql_num_rows(res);
970 mysql_free_result(res);
971 FAIL_IF(rc != 2, "expected 2 rows");
972
973 rc= mysql_query(mysql, "SELECT * FROM bulk_null WHERE d=3.0");
974 check_mysql_rc(rc, mysql);
975 res= mysql_store_result(mysql);
976 rc= (int)mysql_num_rows(res);
977 mysql_free_result(res);
978 FAIL_IF(rc != 2, "expected 2 rows");
979
980 rc= mysql_query(mysql, "SELECT * FROM bulk_null WHERE t='00:00:00'");
981 check_mysql_rc(rc, mysql);
982 res= mysql_store_result(mysql);
983 rc= (int)mysql_num_rows(res);
984 mysql_free_result(res);
985 FAIL_IF(rc != 2, "expected 2 rows");
986
987 rc= mysql_query(mysql, "SELECT * FROM bulk_null WHERE c=3.0");
988 check_mysql_rc(rc, mysql);
989 res= mysql_store_result(mysql);
990 rc= (int)mysql_num_rows(res);
991 mysql_free_result(res);
992 FAIL_IF(rc != 2, "expected 2 rows");
993
994 rc= mysql_query(mysql, "DROP TABLE bulk_null");
995 check_mysql_rc(rc, mysql);
996 return OK;
997}
998
999struct my_tests_st my_tests[] = {
1000 {"check_bulk", check_bulk, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
1001 {"bulk_null_null", bulk_null_null, TEST_CONNECTION_NEW, 0, NULL, NULL},
1002 {"test_char_conv1", test_char_conv1, TEST_CONNECTION_NEW, 0, NULL, NULL},
1003 {"test_char_conv2", test_char_conv2, TEST_CONNECTION_NEW, 0, NULL, NULL},
1004 {"test_conc243", test_conc243, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
1005 {"update_no_param", bulk7, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
1006 {"bulk5", bulk5, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
1007 {"bulk6", bulk6, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
1008 {"bulk1", bulk1, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
1009 {"bulk2", bulk2, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
1010 {"bulk3", bulk3, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
1011 {"bulk4", bulk4, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
1012 {"bulk_null", bulk_null, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
1013 {"bulk_skip_row", bulk_skip_row, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},
1014 {NULL, NULL, 0, 0, NULL, NULL}
1015};
1016
1017int main(int argc, char **argv)
1018{
1019 if (argc > 1)
1020 get_options(argc, argv);
1021
1022 get_envvars();
1023
1024 run_tests(my_tests);
1025
1026 return(exit_status());
1027}
1028