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, &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[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