1 | /* |
2 | Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. |
3 | |
4 | The 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 |
6 | MySQL Connectors. There are special exceptions to the terms and |
7 | conditions of the GPLv2 as it is applied to this software, see the |
8 | FLOSS License Exception |
9 | <http://www.mysql.com/about/legal/licensing/foss-exception.html>. |
10 | |
11 | This program is free software; you can redistribute it and/or modify |
12 | it under the terms of the GNU General Public License as published |
13 | by the Free Software Foundation; version 2 of the License. |
14 | |
15 | This program is distributed in the hope that it will be useful, but |
16 | WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
17 | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
18 | for more details. |
19 | |
20 | You should have received a copy of the GNU General Public License along |
21 | with this program; if not, write to the Free Software Foundation, Inc., |
22 | 51 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 | |
28 | static 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 | |
182 | static 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 | |
268 | static 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); |
319 | diag("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 | |
392 | static 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 | |
513 | static 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 | |
565 | static 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 | |
647 | static 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 | |
774 | static 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 | |
797 | static 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 | |
819 | static 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 | |
841 | static 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 | |
864 | static 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 | |
887 | static 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 | |
911 | static 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 | |
927 | static 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 | |
975 | struct 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 | |
993 | int 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 | |