1/*
2Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
3
4The MySQL Connector/C is licensed under the terms of the GPLv2
5<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
6MySQL Connectors. There are special exceptions to the terms and
7conditions of the GPLv2 as it is applied to this software, see the
8FLOSS License Exception
9<http://www.mysql.com/about/legal/licensing/foss-exception.html>.
10
11This program is free software; you can redistribute it and/or modify
12it under the terms of the GNU General Public License as published
13by the Free Software Foundation; version 2 of the License.
14
15This program is distributed in the hope that it will be useful, but
16WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18for more details.
19
20You should have received a copy of the GNU General Public License along
21with this program; if not, write to the Free Software Foundation, Inc.,
2251 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23*/
24#include "my_test.h"
25
26/* Generalized fetch conversion routine for all basic types */
27
28static int bind_fetch(MYSQL *mysql, int row_count)
29{
30 MYSQL_STMT *stmt;
31 int rc, i, count= row_count;
32 int32 data[10];
33 int8 i8_data;
34 int16 i16_data;
35 int i32_data;
36 longlong i64_data;
37 float f_data;
38 double d_data;
39 char s_data[10];
40 ulong length[10];
41 MYSQL_BIND my_bind[7];
42 my_bool is_null[7];
43 char query[MAX_TEST_QUERY_LENGTH];
44
45 stmt= mysql_stmt_init(mysql);
46 FAIL_IF(!stmt, mysql_error(mysql));
47
48 strcpy(query, "INSERT INTO test_bind_fetch VALUES (?, ?, ?, ?, ?, ?, ?)");
49 rc= mysql_stmt_prepare(stmt, SL(query));
50 check_stmt_rc(rc,stmt);
51
52 FAIL_UNLESS(mysql_stmt_param_count(stmt) == 7, "ParamCount != 7");
53
54 memset(my_bind, '\0', sizeof(my_bind));
55
56 for (i= 0; i < (int) array_elements(my_bind); i++)
57 {
58 my_bind[i].buffer_type= MYSQL_TYPE_LONG;
59 my_bind[i].buffer= (void *) &data[i];
60 }
61 rc= mysql_stmt_bind_param(stmt, my_bind);
62 check_stmt_rc(rc,stmt);
63
64 while (count--)
65 {
66 rc= 10+count;
67 for (i= 0; i < (int) array_elements(my_bind); i++)
68 {
69 data[i]= rc+i;
70 rc+= 12;
71 }
72 rc= mysql_stmt_execute(stmt);
73 check_stmt_rc(rc,stmt);
74 }
75
76 rc= mysql_commit(mysql);
77 check_stmt_rc(rc,stmt);
78
79 mysql_stmt_close(stmt);
80
81 rc= my_stmt_result(mysql, "SELECT * FROM test_bind_fetch");
82 FAIL_UNLESS(row_count == rc, "Wrong number of rows");
83
84 stmt= mysql_stmt_init(mysql);
85 FAIL_IF(!stmt, mysql_error(mysql));
86
87 strcpy(query, "SELECT * FROM test_bind_fetch");
88 rc= mysql_stmt_prepare(stmt, SL(query));
89 check_stmt_rc(rc,stmt);
90
91 for (i= 0; i < (int) array_elements(my_bind); i++)
92 {
93 my_bind[i].buffer= (void *) &data[i];
94 my_bind[i].length= &length[i];
95 my_bind[i].is_null= &is_null[i];
96 }
97
98 my_bind[0].buffer_type= MYSQL_TYPE_TINY;
99 my_bind[0].buffer= (void *)&i8_data;
100
101 my_bind[1].buffer_type= MYSQL_TYPE_SHORT;
102 my_bind[1].buffer= (void *)&i16_data;
103
104 my_bind[2].buffer_type= MYSQL_TYPE_LONG;
105 my_bind[2].buffer= (void *)&i32_data;
106
107 my_bind[3].buffer_type= MYSQL_TYPE_LONGLONG;
108 my_bind[3].buffer= (void *)&i64_data;
109
110 my_bind[4].buffer_type= MYSQL_TYPE_FLOAT;
111 my_bind[4].buffer= (void *)&f_data;
112
113 my_bind[5].buffer_type= MYSQL_TYPE_DOUBLE;
114 my_bind[5].buffer= (void *)&d_data;
115
116 my_bind[6].buffer_type= MYSQL_TYPE_STRING;
117 my_bind[6].buffer= (void *)&s_data;
118 my_bind[6].buffer_length= sizeof(s_data);
119
120 rc= mysql_stmt_bind_result(stmt, my_bind);
121 check_stmt_rc(rc,stmt);
122
123 rc= mysql_stmt_execute(stmt);
124 check_stmt_rc(rc,stmt);
125
126 rc= mysql_stmt_store_result(stmt);
127 check_stmt_rc(rc,stmt);
128
129 while (row_count--)
130 {
131 rc= mysql_stmt_fetch(stmt);
132 check_stmt_rc(rc,stmt);
133
134 rc= 10+row_count;
135
136 /* TINY */
137 FAIL_UNLESS((int) i8_data == rc, "Invalid value for i8_data");
138 FAIL_UNLESS(length[0] == 1, "Invalid length");
139 rc+= 13;
140
141 /* SHORT */
142 FAIL_UNLESS((int) i16_data == rc, "Invalid value for i16_data");
143 FAIL_UNLESS(length[1] == 2, "Invalid length");
144 rc+= 13;
145
146 /* LONG */
147 FAIL_UNLESS((int) i32_data == rc, "Invalid value for i32_data");
148 FAIL_UNLESS(length[2] == 4, "Invalid length");
149 rc+= 13;
150
151 /* LONGLONG */
152 FAIL_UNLESS((int) i64_data == rc, "Invalid value for i64_data");
153 FAIL_UNLESS(length[3] == 8, "Invalid length");
154 rc+= 13;
155
156 /* FLOAT */
157 FAIL_UNLESS((int)f_data == rc, "Invalid value for f_data");
158 FAIL_UNLESS(length[4] == 4, "Invalid length");
159 rc+= 13;
160
161 /* DOUBLE */
162 FAIL_UNLESS((int)d_data == rc, "Invalid value for d_data");
163 FAIL_UNLESS(length[5] == 8, "Invalid length");
164 rc+= 13;
165
166 /* CHAR */
167 {
168 char buff[20];
169 long len= sprintf(buff, "%d", rc);
170 FAIL_UNLESS(strcmp(s_data, buff) == 0, "Invalid value for s_data");
171 FAIL_UNLESS(length[6] == (ulong) len, "Invalid length");
172 }
173 }
174 rc= mysql_stmt_fetch(stmt);
175 FAIL_UNLESS(rc == MYSQL_NO_DATA, "Expected MYSQL_NO_DATA");
176
177 mysql_stmt_close(stmt);
178 return OK;
179}
180
181
182static int test_fetch_seek(MYSQL *mysql)
183{
184 MYSQL_STMT *stmt;
185 MYSQL_BIND my_bind[3];
186 MYSQL_ROW_OFFSET row;
187 int rc;
188 int32 c1;
189 char c2[11], c3[20];
190 const char *query = "SELECT * FROM t1";
191
192 rc= mysql_query(mysql, "drop table if exists t1");
193 check_mysql_rc(rc, mysql);
194 rc= mysql_query(mysql, "create table t1(c1 int primary key auto_increment, c2 char(10), c3 timestamp)");
195 check_mysql_rc(rc, mysql);
196 rc= mysql_query(mysql, "insert into t1(c2) values('venu'), ('mysql'), ('open'), ('source')");
197 check_mysql_rc(rc, mysql);
198
199 stmt= mysql_stmt_init(mysql);
200 FAIL_IF(!stmt, mysql_error(mysql));
201
202 rc= mysql_stmt_prepare(stmt, SL(query));
203 check_stmt_rc(rc,stmt);
204
205 memset(my_bind, '\0', sizeof(my_bind));
206 my_bind[0].buffer_type= MYSQL_TYPE_LONG;
207 my_bind[0].buffer= (void *)&c1;
208
209 my_bind[1].buffer_type= MYSQL_TYPE_STRING;
210 my_bind[1].buffer= (void *)c2;
211 my_bind[1].buffer_length= sizeof(c2);
212
213 my_bind[2]= my_bind[1];
214 my_bind[2].buffer= (void *)c3;
215 my_bind[2].buffer_length= sizeof(c3);
216
217 rc= mysql_stmt_execute(stmt);
218 check_stmt_rc(rc,stmt);
219
220 rc= mysql_stmt_bind_result(stmt, my_bind);
221 check_stmt_rc(rc,stmt);
222
223 rc= mysql_stmt_store_result(stmt);
224 check_stmt_rc(rc,stmt);
225
226
227 rc= mysql_stmt_fetch(stmt);
228 check_stmt_rc(rc,stmt);
229
230 row= mysql_stmt_row_tell(stmt);
231
232 row= mysql_stmt_row_seek(stmt, row);
233
234 rc= mysql_stmt_fetch(stmt);
235 check_stmt_rc(rc,stmt);
236
237 row= mysql_stmt_row_seek(stmt, row);
238
239 rc= mysql_stmt_fetch(stmt);
240 check_stmt_rc(rc,stmt);
241
242 mysql_stmt_data_seek(stmt, 0);
243
244 rc= mysql_stmt_fetch(stmt);
245 check_stmt_rc(rc,stmt);
246
247 rc= mysql_stmt_fetch(stmt);
248 check_stmt_rc(rc,stmt);
249
250 rc= mysql_stmt_fetch(stmt);
251 check_stmt_rc(rc,stmt);
252
253 rc= mysql_stmt_fetch(stmt);
254 check_stmt_rc(rc,stmt);
255
256 rc= mysql_stmt_fetch(stmt);
257 FAIL_IF(rc != MYSQL_NO_DATA, "Expected MYSQL_NO_DATA");
258
259 mysql_stmt_close(stmt);
260 rc= mysql_query(mysql, "drop table t1");
261 check_mysql_rc(rc, mysql);
262
263 return OK;
264}
265
266/* Test mysql_stmt_fetch_column() with offset */
267
268static int test_fetch_offset(MYSQL *mysql)
269{
270 MYSQL_STMT *stmt;
271 MYSQL_BIND my_bind[2];
272 char data[11], chunk[5];
273 ulong length[2];
274 int rc;
275 my_bool is_null[2];
276 const char *query = "SELECT * FROM t1";
277
278
279 rc= mysql_query(mysql, "drop table if exists t1");
280 check_mysql_rc(rc, mysql);
281 rc= mysql_query(mysql, "create table t1(a char(10), b mediumblob)");
282 check_mysql_rc(rc, mysql);
283 rc= mysql_query(mysql, "insert into t1 values('abcdefghij', 'klmnopqrstzy'), (null, null)");
284 check_mysql_rc(rc, mysql);
285
286 stmt= mysql_stmt_init(mysql);
287 FAIL_IF(!stmt, mysql_error(mysql));
288
289 rc= mysql_stmt_prepare(stmt, SL(query));
290 check_stmt_rc(rc,stmt);
291
292 memset(my_bind, '\0', sizeof(my_bind));
293 my_bind[0].buffer_type= MYSQL_TYPE_STRING;
294 my_bind[0].buffer= (void *)data;
295 my_bind[0].buffer_length= 11;
296 my_bind[0].is_null= &is_null[0];
297 my_bind[0].length= &length[0];
298
299 my_bind[1].buffer_type= MYSQL_TYPE_MEDIUM_BLOB;
300 my_bind[1].buffer= NULL;
301 my_bind[1].buffer_length= 0;
302 my_bind[1].is_null= &is_null[1];
303 my_bind[1].length= &length[1];
304
305 rc= mysql_stmt_execute(stmt);
306 check_stmt_rc(rc,stmt);
307
308 rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
309 FAIL_IF(!rc, "Error expected");
310
311 rc= mysql_stmt_execute(stmt);
312 check_stmt_rc(rc,stmt);
313
314 rc= mysql_stmt_bind_result(stmt, my_bind);
315 check_stmt_rc(rc,stmt);
316
317 rc= mysql_stmt_store_result(stmt);
318 check_stmt_rc(rc,stmt);
319diag("truncation: %d", mysql->options.report_data_truncation);
320 rc= mysql_stmt_fetch(stmt);
321 FAIL_UNLESS(rc == MYSQL_DATA_TRUNCATED, "rc != MYSQL_DATA_TRUNCATED");
322
323 data[0]= '\0';
324 rc= mysql_stmt_fetch_column(stmt, &my_bind[0], 0, 0);
325 check_stmt_rc(rc,stmt);
326
327
328 FAIL_IF(!(strncmp(data, "abcdefghij", 11) == 0 && length[0] == 10), "Wrong value");
329 FAIL_IF(my_bind[0].error_value, "No truncation, but error is set");
330
331 rc= mysql_stmt_fetch_column(stmt, &my_bind[0], 0, 5);
332 check_stmt_rc(rc,stmt);
333 FAIL_IF(!(strncmp(data, "fghij", 6) == 0 && length[0] == 10), "Wrong value");
334 FAIL_IF(my_bind[0].error_value, "No truncation, but error is set");
335
336 rc= mysql_stmt_fetch_column(stmt, &my_bind[0], 0, 9);
337 check_stmt_rc(rc,stmt);
338 FAIL_IF(!(strncmp(data, "j", 2) == 0 && length[0] == 10), "Wrong value");
339 FAIL_IF(my_bind[0].error_value, "No truncation, but error is set");
340
341 /* Now blob field */
342 my_bind[1].buffer= chunk;
343 my_bind[1].buffer_length= sizeof(chunk);
344
345 rc= mysql_stmt_fetch_column(stmt, &my_bind[1], 1, 0);
346 check_stmt_rc(rc,stmt);
347
348 FAIL_IF(!(strncmp(chunk, "klmno", 5) == 0 && length[1] == 12), "Wrong value");
349 FAIL_IF(my_bind[1].error_value == '\0', "Truncation, but error is not set");
350
351 rc= mysql_stmt_fetch_column(stmt, &my_bind[1], 1, 5);
352 check_stmt_rc(rc,stmt);
353 FAIL_IF(!(strncmp(chunk, "pqrst", 5) == 0 && length[1] == 12), "Wrong value");
354 FAIL_IF(my_bind[1].error_value == '\0', "Truncation, but error is not set");
355
356 rc= mysql_stmt_fetch_column(stmt, &my_bind[1], 1, 10);
357 check_stmt_rc(rc,stmt);
358 FAIL_IF(!(strncmp(chunk, "zy", 2) == 0 && length[1] == 12), "Wrong value");
359 FAIL_IF(my_bind[1].error_value, "No truncation, but error is set");
360
361 rc= mysql_stmt_fetch(stmt);
362 check_stmt_rc(rc,stmt);
363
364 memset(is_null, 0, sizeof(is_null));
365
366 rc= mysql_stmt_fetch_column(stmt, &my_bind[0], 0, 0);
367 check_stmt_rc(rc,stmt);
368
369 FAIL_IF(is_null[0] != 1, "Null flag not set");
370
371 rc= mysql_stmt_fetch_column(stmt, &my_bind[1], 1, 0);
372 check_stmt_rc(rc,stmt);
373
374 FAIL_IF(is_null[1] != 1, "Null flag not set");
375
376 rc= mysql_stmt_fetch(stmt);
377 FAIL_IF(rc != MYSQL_NO_DATA, "Expected MYSQL_NO_DATA");
378
379 rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
380 FAIL_IF(!rc, "Error expected");
381
382 mysql_stmt_close(stmt);
383
384 rc= mysql_query(mysql, "drop table t1");
385 check_mysql_rc(rc, mysql);
386
387 return OK;
388}
389
390/* Test mysql_stmt_fetch_column() */
391
392static int test_fetch_column(MYSQL *mysql)
393{
394 MYSQL_STMT *stmt;
395 MYSQL_BIND my_bind[2];
396 char c2[20], bc2[20];
397 ulong l1, l2, bl1, bl2;
398 int rc, c1, bc1;
399 const char *query= "SELECT * FROM t1 ORDER BY c2 DESC";
400
401 rc= mysql_query(mysql, "drop table if exists t1");
402 check_mysql_rc(rc, mysql);
403 rc= mysql_query(mysql, "create table t1(c1 int primary key auto_increment, c2 char(10))");
404 check_mysql_rc(rc, mysql);
405 rc= mysql_query(mysql, "insert into t1(c2) values('venu'), ('mysql')");
406 check_mysql_rc(rc, mysql);
407
408 stmt= mysql_stmt_init(mysql);
409 FAIL_IF(!stmt, mysql_error(mysql));
410
411 rc= mysql_stmt_prepare(stmt, SL(query));
412 check_stmt_rc(rc,stmt);
413
414 memset(my_bind, '\0', sizeof(my_bind));
415 my_bind[0].buffer_type= MYSQL_TYPE_LONG;
416 my_bind[0].buffer= (void *)&bc1;
417 my_bind[0].buffer_length= 0;
418 my_bind[0].is_null= 0;
419 my_bind[0].length= &bl1;
420 my_bind[1].buffer_type= MYSQL_TYPE_STRING;
421 my_bind[1].buffer= (void *)bc2;
422 my_bind[1].buffer_length= 7;
423 my_bind[1].is_null= 0;
424 my_bind[1].length= &bl2;
425
426 rc= mysql_stmt_execute(stmt);
427 check_stmt_rc(rc,stmt);
428
429 rc= mysql_stmt_bind_result(stmt, my_bind);
430 check_stmt_rc(rc,stmt);
431
432 rc= mysql_stmt_store_result(stmt);
433 check_stmt_rc(rc,stmt);
434
435 rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0); /* No-op at this point */
436 FAIL_IF(!rc, "Error expected");
437
438 rc= mysql_stmt_fetch(stmt);
439 check_stmt_rc(rc,stmt);
440
441 c2[0]= '\0'; l2= 0;
442 my_bind[0].buffer_type= MYSQL_TYPE_STRING;
443 my_bind[0].buffer= (void *)c2;
444 my_bind[0].buffer_length= 7;
445 my_bind[0].is_null= 0;
446 my_bind[0].length= &l2;
447
448 rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
449 check_stmt_rc(rc,stmt);
450 FAIL_IF(!(strncmp(c2, "venu", 4) == 0 && l2 == 4), "Expected c2='venu'");
451
452 c2[0]= '\0'; l2= 0;
453 rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
454 check_stmt_rc(rc,stmt);
455 FAIL_IF(!(strcmp(c2, "venu") == 0 && l2 == 4), "Expected c2='venu'");
456
457 c1= 0;
458 my_bind[0].buffer_type= MYSQL_TYPE_LONG;
459 my_bind[0].buffer= (void *)&c1;
460 my_bind[0].buffer_length= 0;
461 my_bind[0].is_null= 0;
462 my_bind[0].length= &l1;
463
464 rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
465 check_stmt_rc(rc,stmt);
466 FAIL_IF(!(c1 == 1 && l1 == 4), "Expected c1=1");
467
468 rc= mysql_stmt_fetch(stmt);
469 check_stmt_rc(rc,stmt);
470
471 c2[0]= '\0'; l2= 0;
472 my_bind[0].buffer_type= MYSQL_TYPE_STRING;
473 my_bind[0].buffer= (void *)c2;
474 my_bind[0].buffer_length= 7;
475 my_bind[0].is_null= 0;
476 my_bind[0].length= &l2;
477
478 rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
479 check_stmt_rc(rc,stmt);
480 FAIL_IF(!(strncmp(c2, "mysq", 4) == 0 && l2 == 5), "Expected c2='mysql'");
481
482 c2[0]= '\0'; l2= 0;
483 rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
484 check_stmt_rc(rc,stmt);
485 FAIL_IF(!(strcmp(c2, "mysql") == 0 && l2 == 5), "Expected c2='mysql'");
486
487 c1= 0;
488 my_bind[0].buffer_type= MYSQL_TYPE_LONG;
489 my_bind[0].buffer= (void *)&c1;
490 my_bind[0].buffer_length= 0;
491 my_bind[0].is_null= 0;
492 my_bind[0].length= &l1;
493
494 rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
495 check_stmt_rc(rc,stmt);
496 FAIL_IF(!(c1 == 2 && l1 == 4), "Expected c2=2");
497
498 rc= mysql_stmt_fetch(stmt);
499 FAIL_IF(rc!=MYSQL_NO_DATA, "Expected MYSQL_NO_DATA");
500
501 rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
502 FAIL_IF(!rc, "Error expected");
503
504 mysql_stmt_close(stmt);
505 rc= mysql_query(mysql, "drop table t1");
506 check_mysql_rc(rc, mysql);
507
508 return OK;
509}
510
511/* Test fetch without prior bound buffers */
512
513static int test_fetch_nobuffs(MYSQL *mysql)
514{
515 MYSQL_STMT *stmt;
516 MYSQL_BIND my_bind[4];
517 char str[4][50];
518 int rc;
519 const char *query = "SELECT DATABASE(), CURRENT_USER(), \
520 CURRENT_DATE(), CURRENT_TIME()";
521
522 stmt = mysql_stmt_init(mysql);
523 FAIL_IF(!stmt, mysql_error(mysql));
524 rc= mysql_stmt_prepare(stmt, SL(query));
525 check_stmt_rc(rc, stmt);
526
527 rc= mysql_stmt_execute(stmt);
528 check_stmt_rc(rc, stmt);
529
530 rc= 0;
531 while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
532 rc++;
533
534 FAIL_IF(rc != 1, "Expected 1 row");
535
536 memset(my_bind, '\0', sizeof(my_bind));
537 my_bind[0].buffer_type= MYSQL_TYPE_STRING;
538 my_bind[0].buffer= (void *)str[0];
539 my_bind[0].buffer_length= sizeof(str[0]);
540 my_bind[1]= my_bind[2]= my_bind[3]= my_bind[0];
541 my_bind[1].buffer= (void *)str[1];
542 my_bind[2].buffer= (void *)str[2];
543 my_bind[3].buffer= (void *)str[3];
544
545 rc= mysql_stmt_bind_result(stmt, my_bind);
546 check_stmt_rc(rc, stmt);
547
548 rc= mysql_stmt_execute(stmt);
549 check_stmt_rc(rc, stmt);
550
551 rc= 0;
552 while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
553 {
554 rc++;
555 }
556 FAIL_IF(rc != 1, "Expected 1 row");
557
558 mysql_stmt_close(stmt);
559
560 return OK;
561}
562
563/* Test fetch null */
564
565static int test_fetch_null(MYSQL *mysql)
566{
567 MYSQL_STMT *stmt;
568 int rc;
569 int i;
570 int nData= 0;
571 MYSQL_BIND my_bind[11];
572 ulong length[11];
573 my_bool is_null[11];
574 char query[MAX_TEST_QUERY_LENGTH];
575
576
577 rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_fetch_null");
578 check_mysql_rc(rc, mysql);
579
580 rc= mysql_query(mysql, "CREATE TABLE test_fetch_null("
581 " col1 tinyint, col2 smallint, "
582 " col3 int, col4 bigint, "
583 " col5 float, col6 double, "
584 " col7 date, col8 time, "
585 " col9 varbinary(10), "
586 " col10 varchar(50), "
587 " col11 char(20))");
588 check_mysql_rc(rc, mysql);
589
590 rc= mysql_query(mysql, "INSERT INTO test_fetch_null (col11) "
591 "VALUES (1000), (88), (389789)");
592 check_mysql_rc(rc, mysql);
593
594 rc= mysql_commit(mysql);
595 FAIL_IF(rc, mysql_error(mysql));
596
597 /* fetch */
598 memset(my_bind, '\0', sizeof(my_bind));
599 for (i= 0; i < (int) array_elements(my_bind); i++)
600 {
601 my_bind[i].buffer_type= MYSQL_TYPE_LONG;
602 my_bind[i].is_null= &is_null[i];
603 my_bind[i].length= &length[i];
604 }
605 my_bind[i-1].buffer= (void *)&nData; /* Last column is not null */
606
607 strcpy((char *)query , "SELECT * FROM test_fetch_null");
608
609 rc= my_stmt_result(mysql, query);
610 FAIL_UNLESS(rc == 3, "Exoected 3 rows");
611
612 stmt = mysql_stmt_init(mysql);
613 FAIL_IF(!stmt, mysql_error(mysql));
614
615 rc= mysql_stmt_prepare(stmt, SL(query));
616 check_stmt_rc(rc, stmt);
617
618 rc= mysql_stmt_bind_result(stmt, my_bind);
619 check_stmt_rc(rc, stmt);
620
621 rc= mysql_stmt_execute(stmt);
622 check_stmt_rc(rc, stmt);
623
624 rc= 0;
625 while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
626 {
627 rc++;
628 for (i= 0; i < 10; i++)
629 {
630 FAIL_IF(!is_null[i], "Expected is_null");
631 }
632 FAIL_UNLESS(nData == 1000 || nData == 88 || nData == 389789, "Wrong value for nData");
633 FAIL_UNLESS(is_null[i] == 0, "Exoected !is_null");
634 FAIL_UNLESS(length[i] == 4, "Expected length=4");
635 }
636 FAIL_UNLESS(rc == 3, "Expected 3 rows");
637 mysql_stmt_close(stmt);
638
639 rc= mysql_query(mysql, "DROP TABLE test_fetch_null");
640 check_mysql_rc(rc, mysql);
641
642 return OK;
643}
644
645/* Test fetching of date, time and ts */
646
647static int test_fetch_date(MYSQL *mysql)
648{
649 MYSQL_STMT *stmt;
650 uint i;
651 int rc;
652 long year;
653 char date[25], my_time[25], ts[25], ts_4[25], ts_6[20], dt[20];
654 ulong d_length, t_length, ts_length, ts4_length, ts6_length,
655 dt_length, y_length;
656 MYSQL_BIND my_bind[8];
657 my_bool is_null[8];
658 ulong length[8];
659 const char *query= "SELECT * FROM test_bind_result";
660
661 rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_result");
662 check_mysql_rc(rc, mysql);
663
664 rc= mysql_query(mysql, "CREATE TABLE test_bind_result(c1 date, c2 time, \
665 c3 timestamp, \
666 c4 year, \
667 c5 datetime, \
668 c6 timestamp, \
669 c7 timestamp)");
670 check_mysql_rc(rc, mysql);
671
672 rc= mysql_query(mysql, "SET SQL_MODE=''");
673 check_mysql_rc(rc, mysql);
674 rc= mysql_query(mysql, "INSERT INTO test_bind_result VALUES('2002-01-02', \
675 '12:49:00', \
676 '2002-01-02 17:46:59', \
677 2010, \
678 '2010-07-10', \
679 '2020', '1999-12-29')");
680 check_mysql_rc(rc, mysql);
681
682 rc= mysql_commit(mysql);
683 FAIL_IF(rc, mysql_error(mysql));
684
685 memset(my_bind, '\0', sizeof(my_bind));
686 for (i= 0; i < array_elements(my_bind); i++)
687 {
688 my_bind[i].is_null= &is_null[i];
689 my_bind[i].length= &length[i];
690 }
691
692 my_bind[0].buffer_type= MYSQL_TYPE_STRING;
693 my_bind[1]= my_bind[2]= my_bind[0];
694
695 my_bind[0].buffer= (void *)&date;
696 my_bind[0].buffer_length= sizeof(date);
697 my_bind[0].length= &d_length;
698
699 my_bind[1].buffer= (void *)&my_time;
700 my_bind[1].buffer_length= sizeof(my_time);
701 my_bind[1].length= &t_length;
702
703 my_bind[2].buffer= (void *)&ts;
704 my_bind[2].buffer_length= sizeof(ts);
705 my_bind[2].length= &ts_length;
706
707 my_bind[3].buffer_type= MYSQL_TYPE_LONG;
708 my_bind[3].buffer= (void *)&year;
709 my_bind[3].length= &y_length;
710
711 my_bind[4].buffer_type= MYSQL_TYPE_STRING;
712 my_bind[4].buffer= (void *)&dt;
713 my_bind[4].buffer_length= sizeof(dt);
714 my_bind[4].length= &dt_length;
715
716 my_bind[5].buffer_type= MYSQL_TYPE_STRING;
717 my_bind[5].buffer= (void *)&ts_4;
718 my_bind[5].buffer_length= sizeof(ts_4);
719 my_bind[5].length= &ts4_length;
720
721 my_bind[6].buffer_type= MYSQL_TYPE_STRING;
722 my_bind[6].buffer= (void *)&ts_6;
723 my_bind[6].buffer_length= sizeof(ts_6);
724 my_bind[6].length= &ts6_length;
725
726 rc= my_stmt_result(mysql, "SELECT * FROM test_bind_result");
727 FAIL_UNLESS(rc == 1, "Expected 1 row");
728
729 stmt= mysql_stmt_init(mysql);
730 FAIL_IF(!stmt, mysql_error(mysql));
731 rc= mysql_stmt_prepare(stmt, SL(query));
732 check_stmt_rc(rc, stmt);
733
734 rc= mysql_stmt_bind_result(stmt, my_bind);
735 check_stmt_rc(rc, stmt);
736
737 rc= mysql_stmt_execute(stmt);
738 check_stmt_rc(rc, stmt);
739
740 ts_4[0]= '\0';
741 rc= mysql_stmt_fetch(stmt);
742 check_stmt_rc(rc, stmt);
743
744 FAIL_UNLESS(strcmp(date, "2002-01-02") == 0, "date != '2002-01-02'");
745 FAIL_UNLESS(d_length == 10, "d_length != 10");
746
747 FAIL_UNLESS(strcmp(my_time, "12:49:00") == 0, "mytime != '12:49:00'");
748 FAIL_UNLESS(t_length == 8, "t_length != 8");
749
750 FAIL_UNLESS(strcmp(ts, "2002-01-02 17:46:59") == 0, "ts != '2002-01-02 17:46:59'");
751 FAIL_UNLESS(ts_length == 19, "ts_length != 19");
752
753 FAIL_UNLESS(strcmp(dt, "2010-07-10 00:00:00") == 0, "dt != 2010-07-10 00:00:00");
754 FAIL_UNLESS(dt_length == 19, "dt_length != 19");
755
756 FAIL_UNLESS(strcmp(ts_4, "0000-00-00 00:00:00") == 0, "ts4 != '0000-00-00 00:00:00'");
757 FAIL_UNLESS(ts4_length == strlen("0000-00-00 00:00:00"), "ts4_length != 19");
758
759 FAIL_UNLESS(strcmp(ts_6, "1999-12-29 00:00:00") == 0, "ts_6 != '1999-12-29 00:00:00'");
760 FAIL_UNLESS(ts6_length == 19, "ts6_length != 19");
761
762 rc= mysql_stmt_fetch(stmt);
763 FAIL_UNLESS(rc == MYSQL_NO_DATA, "rc != MYSQL_NO_DATA");
764
765 mysql_stmt_close(stmt);
766 rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_result");
767 check_mysql_rc(rc, mysql);
768
769 return OK;
770}
771
772/* Test fetching of str to all types */
773
774static int test_fetch_str(MYSQL *mysql)
775{
776 int rc;
777
778 rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
779 check_mysql_rc(rc, mysql);
780
781 rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 char(10), \
782 c2 char(10), \
783 c3 char(20), \
784 c4 char(20), \
785 c5 char(30), \
786 c6 char(40), \
787 c7 char(20))");
788 check_mysql_rc(rc, mysql);
789
790 rc= bind_fetch(mysql, 3);
791 mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
792 return rc;
793}
794
795/* Test fetching of long to all types */
796
797static int test_fetch_long(MYSQL *mysql)
798{
799 int rc;
800
801 rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
802 check_mysql_rc(rc, mysql);
803 rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 int unsigned, \
804 c2 int unsigned, \
805 c3 int, \
806 c4 int, \
807 c5 int, \
808 c6 int unsigned, \
809 c7 int)");
810 check_mysql_rc(rc, mysql);
811 rc= bind_fetch(mysql, 4);
812 mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
813 return rc;
814}
815
816
817/* Test fetching of short to all types */
818
819static int test_fetch_short(MYSQL *mysql)
820{
821 int rc;
822
823 rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
824 check_mysql_rc(rc, mysql);
825 rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 smallint unsigned, \
826 c2 smallint, \
827 c3 smallint unsigned, \
828 c4 smallint, \
829 c5 smallint, \
830 c6 smallint, \
831 c7 smallint unsigned)");
832 check_mysql_rc(rc, mysql);
833 rc= bind_fetch(mysql, 5);
834 mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
835 return rc;
836}
837
838
839/* Test fetching of tiny to all types */
840
841static int test_fetch_tiny(MYSQL *mysql)
842{
843 int rc;
844
845 rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
846 check_mysql_rc(rc, mysql);
847
848 rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 tinyint unsigned, \
849 c2 tinyint, \
850 c3 tinyint unsigned, \
851 c4 tinyint, \
852 c5 tinyint, \
853 c6 tinyint, \
854 c7 tinyint unsigned)");
855 check_mysql_rc(rc, mysql);
856 rc= bind_fetch(mysql, 3);
857 mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
858 return rc;
859}
860
861
862/* Test fetching of longlong to all types */
863
864static int test_fetch_bigint(MYSQL *mysql)
865{
866 int rc;
867
868 rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
869 check_mysql_rc(rc, mysql);
870
871 rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 bigint, \
872 c2 bigint, \
873 c3 bigint unsigned, \
874 c4 bigint unsigned, \
875 c5 bigint unsigned, \
876 c6 bigint unsigned, \
877 c7 bigint unsigned)");
878 check_mysql_rc(rc, mysql);
879 rc= bind_fetch(mysql, 2);
880 mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
881 return rc;
882}
883
884
885/* Test fetching of float to all types */
886
887static int test_fetch_float(MYSQL *mysql)
888{
889 int rc;
890
891 rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
892 check_mysql_rc(rc, mysql);
893
894 rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 float(3), \
895 c2 float, \
896 c3 float unsigned, \
897 c4 float, \
898 c5 float, \
899 c6 float, \
900 c7 float(10) unsigned)");
901 check_mysql_rc(rc, mysql);
902
903 rc= bind_fetch(mysql, 2);
904 mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
905 return rc;
906}
907
908
909/* Test fetching of double to all types */
910
911static int test_fetch_double(MYSQL *mysql)
912{
913 int rc;
914
915 rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
916 check_mysql_rc(rc, mysql);
917 rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 double(5, 2), "
918 "c2 double unsigned, c3 double unsigned, "
919 "c4 double unsigned, c5 double unsigned, "
920 "c6 double unsigned, c7 double unsigned)");
921 check_mysql_rc(rc, mysql);
922 rc= bind_fetch(mysql, 3);
923 mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
924 return rc;
925}
926
927static int test_conc281(MYSQL *mysql)
928{
929 int rc;
930 MYSQL_STMT *stmt= mysql_stmt_init(mysql);
931 MYSQL_BIND bind[2];
932 unsigned long length= 0;
933 char buffer[2048];
934
935 rc= mysql_query(mysql, "DROP TABLE IF EXISTS conc282");
936 check_mysql_rc(rc, mysql);
937
938 rc= mysql_query(mysql, "CREATE TABLE conc282 (a blob, b varchar(1000), c int)");
939 check_mysql_rc(rc, mysql);
940
941 rc= mysql_query(mysql, "INSERT INTO conc282 VALUES (REPEAT('A',2000), REPEAT('B', 999),3)");
942 check_mysql_rc(rc, mysql);
943
944 rc= mysql_stmt_prepare(stmt, "SELECT a, b FROM conc282", -1);
945 check_stmt_rc(rc, stmt);
946
947 rc= mysql_stmt_execute(stmt);
948 check_stmt_rc(rc, stmt);
949
950 rc= mysql_stmt_fetch(stmt);
951 check_stmt_rc(rc, stmt);
952
953 memset(bind, 0, sizeof(MYSQL_BIND) * 2);
954
955 bind[0].buffer_type= MYSQL_TYPE_BLOB;
956 bind[0].buffer= buffer;
957 bind[0].buffer_length= 2048;
958 bind[0].length= &length;
959
960 rc= mysql_stmt_fetch_column(stmt, &bind[0], 0, 0);
961 check_stmt_rc(rc, stmt);
962
963 FAIL_IF(length != 2000, "Expected length= 2000");
964 FAIL_IF(buffer[0] != 'A' || buffer[1999] != 'A', "Wrong result");
965
966 mysql_stmt_close(stmt);
967
968 rc= mysql_query(mysql, "DROP TABLE conc282");
969 check_mysql_rc(rc, mysql);
970
971 return OK;
972
973}
974
975struct my_tests_st my_tests[] = {
976 {"test_conc281", test_conc281, 1, 0, NULL, NULL},
977 {"test_fetch_seek", test_fetch_seek, 1, 0, NULL , NULL},
978 {"test_fetch_offset", test_fetch_offset, 1, 0, NULL , NULL},
979 {"test_fetch_column", test_fetch_column, 1, 0, NULL , NULL},
980 {"test_fetch_nobuffs", test_fetch_nobuffs, 1, 0, NULL , NULL},
981 {"test_fetch_null", test_fetch_null, 1, 0, NULL , NULL},
982 {"test_fetch_date", test_fetch_date, 1, 0, NULL , NULL},
983 {"test_fetch_str", test_fetch_str, 1, 0, NULL , NULL},
984 {"test_fetch_long", test_fetch_long, 1, 0, NULL , NULL},
985 {"test_fetch_short", test_fetch_short, 1, 0, NULL , NULL},
986 {"test_fetch_tiny", test_fetch_tiny, 1, 0, NULL , NULL},
987 {"test_fetch_bigint", test_fetch_bigint, 1, 0, NULL , NULL},
988 {"test_fetch_float", test_fetch_float, 1, 0, NULL , NULL},
989 {"test_fetch_double", test_fetch_double, 1, 0, NULL , NULL},
990 {NULL, NULL, 0, 0, NULL, NULL}
991};
992
993int main(int argc, char **argv)
994{
995 if (argc > 1)
996 get_options(argc, argv);
997
998 get_envvars();
999
1000 run_tests(my_tests);
1001
1002 return(exit_status());
1003}
1004