1 | /* Copyright (c) 2002, 2014, Oracle and/or its affiliates. |
2 | Copyright (c) 2008, 2017, MariaDB |
3 | |
4 | This program is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by |
6 | the Free Software Foundation; version 2 of the License. |
7 | |
8 | This program is distributed in the hope that it will be useful, |
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | GNU General Public License for more details. |
12 | |
13 | You should have received a copy of the GNU General Public License |
14 | along with this program; if not, write to the Free Software |
15 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ |
16 | |
17 | /*************************************************************************** |
18 | This is a test sample to test the new features in MySQL client-server |
19 | protocol |
20 | |
21 | Main author: venu ( venu@mysql.com ) |
22 | ***************************************************************************/ |
23 | |
24 | /* |
25 | XXX: PLEASE RUN THIS PROGRAM UNDER VALGRIND AND VERIFY THAT YOUR TEST |
26 | DOESN'T CONTAIN WARNINGS/ERRORS BEFORE YOU PUSH. |
27 | */ |
28 | |
29 | |
30 | /* |
31 | The fw.c file includes all the mysql_client_test framework; this file |
32 | contains only the actual tests, plus the list of test functions to call. |
33 | */ |
34 | #ifdef _MSC_VER |
35 | #pragma warning (disable : 4267) |
36 | #endif |
37 | |
38 | #include "mysql_client_fw.c" |
39 | #ifndef _WIN32 |
40 | #include <arpa/inet.h> |
41 | #endif |
42 | |
43 | static const my_bool my_true= 1; |
44 | |
45 | |
46 | /* Query processing */ |
47 | |
48 | static my_bool get_reconnect(MYSQL *mysql) |
49 | { |
50 | #ifdef EMBEDDED_LIBRARY |
51 | return mysql->reconnect; |
52 | #else |
53 | my_bool reconnect; |
54 | mysql_get_option(mysql, MYSQL_OPT_RECONNECT, &reconnect); |
55 | return reconnect; |
56 | #endif |
57 | } |
58 | |
59 | static void client_query() |
60 | { |
61 | int rc; |
62 | |
63 | myheader("client_query" ); |
64 | |
65 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1" ); |
66 | myquery(rc); |
67 | |
68 | rc= mysql_query(mysql, "CREATE TABLE t1(" |
69 | "id int primary key auto_increment, " |
70 | "name varchar(20))" ); |
71 | myquery(rc); |
72 | |
73 | rc= mysql_query(mysql, "CREATE TABLE t1(id int, name varchar(20))" ); |
74 | myquery_r(rc); |
75 | |
76 | rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('mysql')" ); |
77 | myquery(rc); |
78 | |
79 | rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('monty')" ); |
80 | myquery(rc); |
81 | |
82 | rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('venu')" ); |
83 | myquery(rc); |
84 | |
85 | rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('deleted')" ); |
86 | myquery(rc); |
87 | |
88 | rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('deleted')" ); |
89 | myquery(rc); |
90 | |
91 | rc= mysql_query(mysql, "UPDATE t1 SET name= 'updated' " |
92 | "WHERE name= 'deleted'" ); |
93 | myquery(rc); |
94 | |
95 | rc= mysql_query(mysql, "UPDATE t1 SET id= 3 WHERE name= 'updated'" ); |
96 | myquery_r(rc); |
97 | |
98 | myquery(mysql_query(mysql, "drop table t1" )); |
99 | } |
100 | |
101 | |
102 | /* Store result processing */ |
103 | |
104 | static void client_store_result() |
105 | { |
106 | MYSQL_RES *result; |
107 | int rc; |
108 | |
109 | myheader("client_store_result" ); |
110 | |
111 | rc= mysql_query(mysql, "SELECT * FROM t1" ); |
112 | myquery(rc); |
113 | |
114 | /* get the result */ |
115 | result= mysql_store_result(mysql); |
116 | mytest(result); |
117 | |
118 | (void) my_process_result_set(result); |
119 | mysql_free_result(result); |
120 | } |
121 | |
122 | |
123 | /* Fetch the results */ |
124 | |
125 | static void client_use_result() |
126 | { |
127 | MYSQL_RES *result; |
128 | int rc; |
129 | myheader("client_use_result" ); |
130 | |
131 | rc= mysql_query(mysql, "SELECT * FROM t1" ); |
132 | myquery(rc); |
133 | |
134 | /* get the result */ |
135 | result= mysql_use_result(mysql); |
136 | mytest(result); |
137 | |
138 | (void) my_process_result_set(result); |
139 | mysql_free_result(result); |
140 | } |
141 | |
142 | |
143 | /* Query processing */ |
144 | |
145 | static void test_debug_example() |
146 | { |
147 | int rc; |
148 | MYSQL_RES *result; |
149 | |
150 | myheader("test_debug_example" ); |
151 | |
152 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_debug_example" ); |
153 | myquery(rc); |
154 | |
155 | rc= mysql_query(mysql, "CREATE TABLE test_debug_example(" |
156 | "id INT PRIMARY KEY AUTO_INCREMENT, " |
157 | "name VARCHAR(20), xxx INT)" ); |
158 | myquery(rc); |
159 | |
160 | rc= mysql_query(mysql, "INSERT INTO test_debug_example (name) " |
161 | "VALUES ('mysql')" ); |
162 | myquery(rc); |
163 | |
164 | rc= mysql_query(mysql, "UPDATE test_debug_example SET name='updated' " |
165 | "WHERE name='deleted'" ); |
166 | myquery(rc); |
167 | |
168 | rc= mysql_query(mysql, "SELECT * FROM test_debug_example where name='mysql'" ); |
169 | myquery(rc); |
170 | |
171 | result= mysql_use_result(mysql); |
172 | mytest(result); |
173 | |
174 | (void) my_process_result_set(result); |
175 | mysql_free_result(result); |
176 | |
177 | rc= mysql_query(mysql, "DROP TABLE test_debug_example" ); |
178 | myquery(rc); |
179 | } |
180 | |
181 | |
182 | /* Test autocommit feature for BDB tables */ |
183 | |
184 | static void test_tran_bdb() |
185 | { |
186 | MYSQL_RES *result; |
187 | MYSQL_ROW row; |
188 | int rc; |
189 | |
190 | myheader("test_tran_bdb" ); |
191 | |
192 | /* set AUTOCOMMIT to OFF */ |
193 | rc= mysql_autocommit(mysql, FALSE); |
194 | myquery(rc); |
195 | |
196 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS my_demo_transaction" ); |
197 | myquery(rc); |
198 | |
199 | |
200 | /* create the table 'mytran_demo' of type BDB' or 'InnoDB' */ |
201 | rc= mysql_query(mysql, "CREATE TABLE my_demo_transaction( " |
202 | "col1 int , col2 varchar(30)) ENGINE= BDB" ); |
203 | myquery(rc); |
204 | |
205 | /* insert a row and commit the transaction */ |
206 | rc= mysql_query(mysql, "INSERT INTO my_demo_transaction VALUES(10, 'venu')" ); |
207 | myquery(rc); |
208 | |
209 | rc= mysql_commit(mysql); |
210 | myquery(rc); |
211 | |
212 | /* now insert the second row, and roll back the transaction */ |
213 | rc= mysql_query(mysql, "INSERT INTO my_demo_transaction VALUES(20, 'mysql')" ); |
214 | myquery(rc); |
215 | |
216 | rc= mysql_rollback(mysql); |
217 | myquery(rc); |
218 | |
219 | /* delete first row, and roll it back */ |
220 | rc= mysql_query(mysql, "DELETE FROM my_demo_transaction WHERE col1= 10" ); |
221 | myquery(rc); |
222 | |
223 | rc= mysql_rollback(mysql); |
224 | myquery(rc); |
225 | |
226 | /* test the results now, only one row should exist */ |
227 | rc= mysql_query(mysql, "SELECT * FROM my_demo_transaction" ); |
228 | myquery(rc); |
229 | |
230 | /* get the result */ |
231 | result= mysql_store_result(mysql); |
232 | mytest(result); |
233 | |
234 | (void) my_process_result_set(result); |
235 | mysql_free_result(result); |
236 | |
237 | /* test the results now, only one row should exist */ |
238 | rc= mysql_query(mysql, "SELECT * FROM my_demo_transaction" ); |
239 | myquery(rc); |
240 | |
241 | /* get the result */ |
242 | result= mysql_use_result(mysql); |
243 | mytest(result); |
244 | |
245 | row= mysql_fetch_row(result); |
246 | mytest(row); |
247 | |
248 | row= mysql_fetch_row(result); |
249 | mytest_r(row); |
250 | |
251 | mysql_free_result(result); |
252 | mysql_autocommit(mysql, TRUE); |
253 | } |
254 | |
255 | |
256 | /* Test autocommit feature for InnoDB tables */ |
257 | |
258 | static void test_tran_innodb() |
259 | { |
260 | MYSQL_RES *result; |
261 | MYSQL_ROW row; |
262 | int rc; |
263 | |
264 | myheader("test_tran_innodb" ); |
265 | |
266 | /* set AUTOCOMMIT to OFF */ |
267 | rc= mysql_autocommit(mysql, FALSE); |
268 | myquery(rc); |
269 | |
270 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS my_demo_transaction" ); |
271 | myquery(rc); |
272 | |
273 | /* create the table 'mytran_demo' of type BDB' or 'InnoDB' */ |
274 | rc= mysql_query(mysql, "CREATE TABLE my_demo_transaction(col1 int, " |
275 | "col2 varchar(30)) ENGINE= InnoDB" ); |
276 | myquery(rc); |
277 | |
278 | /* insert a row and commit the transaction */ |
279 | rc= mysql_query(mysql, "INSERT INTO my_demo_transaction VALUES(10, 'venu')" ); |
280 | myquery(rc); |
281 | |
282 | rc= mysql_commit(mysql); |
283 | myquery(rc); |
284 | |
285 | /* now insert the second row, and roll back the transaction */ |
286 | rc= mysql_query(mysql, "INSERT INTO my_demo_transaction VALUES(20, 'mysql')" ); |
287 | myquery(rc); |
288 | |
289 | rc= mysql_rollback(mysql); |
290 | myquery(rc); |
291 | |
292 | /* delete first row, and roll it back */ |
293 | rc= mysql_query(mysql, "DELETE FROM my_demo_transaction WHERE col1= 10" ); |
294 | myquery(rc); |
295 | |
296 | rc= mysql_rollback(mysql); |
297 | myquery(rc); |
298 | |
299 | /* test the results now, only one row should exist */ |
300 | rc= mysql_query(mysql, "SELECT * FROM my_demo_transaction" ); |
301 | myquery(rc); |
302 | |
303 | /* get the result */ |
304 | result= mysql_store_result(mysql); |
305 | mytest(result); |
306 | |
307 | (void) my_process_result_set(result); |
308 | mysql_free_result(result); |
309 | |
310 | /* test the results now, only one row should exist */ |
311 | rc= mysql_query(mysql, "SELECT * FROM my_demo_transaction" ); |
312 | myquery(rc); |
313 | |
314 | /* get the result */ |
315 | result= mysql_use_result(mysql); |
316 | mytest(result); |
317 | |
318 | row= mysql_fetch_row(result); |
319 | mytest(row); |
320 | |
321 | row= mysql_fetch_row(result); |
322 | mytest_r(row); |
323 | |
324 | mysql_free_result(result); |
325 | mysql_autocommit(mysql, TRUE); |
326 | } |
327 | |
328 | |
329 | /* Test for BUG#7242 */ |
330 | |
331 | static void test_prepare_insert_update() |
332 | { |
333 | MYSQL_STMT *stmt; |
334 | int rc; |
335 | int i; |
336 | const char *testcase[]= { |
337 | "CREATE TABLE t1 (a INT, b INT, c INT, UNIQUE (A), UNIQUE(B))" , |
338 | "INSERT t1 VALUES (1,2,10), (3,4,20)" , |
339 | "INSERT t1 VALUES (5,6,30), (7,4,40), (8,9,60) ON DUPLICATE KEY UPDATE c=c+100" , |
340 | "SELECT * FROM t1" , |
341 | "INSERT t1 SET a=5 ON DUPLICATE KEY UPDATE b=0" , |
342 | "SELECT * FROM t1" , |
343 | "INSERT t1 VALUES (2,1,11), (7,4,40) ON DUPLICATE KEY UPDATE c=c+VALUES(a)" , |
344 | NULL}; |
345 | const char **cur_query; |
346 | |
347 | myheader("test_prepare_insert_update" ); |
348 | |
349 | for (cur_query= testcase; *cur_query; cur_query++) |
350 | { |
351 | char query[MAX_TEST_QUERY_LENGTH]; |
352 | printf("\nRunning query: %s" , *cur_query); |
353 | strmov(query, *cur_query); |
354 | stmt= mysql_simple_prepare(mysql, query); |
355 | check_stmt(stmt); |
356 | |
357 | verify_param_count(stmt, 0); |
358 | rc= mysql_stmt_execute(stmt); |
359 | |
360 | check_execute(stmt, rc); |
361 | /* try the last query several times */ |
362 | if (!cur_query[1]) |
363 | { |
364 | for (i=0; i < 3;i++) |
365 | { |
366 | printf("\nExecuting last statement again" ); |
367 | rc= mysql_stmt_execute(stmt); |
368 | check_execute(stmt, rc); |
369 | rc= mysql_stmt_execute(stmt); |
370 | check_execute(stmt, rc); |
371 | } |
372 | } |
373 | mysql_stmt_close(stmt); |
374 | } |
375 | |
376 | rc= mysql_commit(mysql); |
377 | myquery(rc); |
378 | } |
379 | |
380 | |
381 | /* Test simple prepares of all DML statements */ |
382 | |
383 | static void test_prepare_simple() |
384 | { |
385 | MYSQL_STMT *stmt; |
386 | int rc; |
387 | char query[MAX_TEST_QUERY_LENGTH]; |
388 | |
389 | myheader("test_prepare_simple" ); |
390 | |
391 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_simple" ); |
392 | myquery(rc); |
393 | |
394 | rc= mysql_query(mysql, "CREATE TABLE test_prepare_simple(" |
395 | "id int, name varchar(50))" ); |
396 | myquery(rc); |
397 | |
398 | /* insert */ |
399 | strmov(query, "INSERT INTO test_prepare_simple VALUES(?, ?)" ); |
400 | stmt= mysql_simple_prepare(mysql, query); |
401 | check_stmt(stmt); |
402 | |
403 | verify_param_count(stmt, 2); |
404 | mysql_stmt_close(stmt); |
405 | |
406 | /* update */ |
407 | strmov(query, "UPDATE test_prepare_simple SET id=? " |
408 | "WHERE id=? AND CONVERT(name USING utf8)= ?" ); |
409 | stmt= mysql_simple_prepare(mysql, query); |
410 | check_stmt(stmt); |
411 | |
412 | verify_param_count(stmt, 3); |
413 | mysql_stmt_close(stmt); |
414 | |
415 | /* delete */ |
416 | strmov(query, "DELETE FROM test_prepare_simple WHERE id=10" ); |
417 | stmt= mysql_simple_prepare(mysql, query); |
418 | check_stmt(stmt); |
419 | |
420 | verify_param_count(stmt, 0); |
421 | |
422 | rc= mysql_stmt_execute(stmt); |
423 | check_execute(stmt, rc); |
424 | mysql_stmt_close(stmt); |
425 | |
426 | /* delete */ |
427 | strmov(query, "DELETE FROM test_prepare_simple WHERE id=?" ); |
428 | stmt= mysql_simple_prepare(mysql, query); |
429 | check_stmt(stmt); |
430 | |
431 | verify_param_count(stmt, 1); |
432 | |
433 | mysql_stmt_close(stmt); |
434 | |
435 | /* select */ |
436 | strmov(query, "SELECT * FROM test_prepare_simple WHERE id=? " |
437 | "AND CONVERT(name USING utf8)= ?" ); |
438 | stmt= mysql_simple_prepare(mysql, query); |
439 | check_stmt(stmt); |
440 | |
441 | verify_param_count(stmt, 2); |
442 | |
443 | mysql_stmt_close(stmt); |
444 | |
445 | /* show create */ |
446 | strmov(query, "SHOW CREATE TABLE test_prepare_simple" ); |
447 | stmt= mysql_simple_prepare(mysql, query); |
448 | check_stmt(stmt); |
449 | DIE_UNLESS(mysql_stmt_field_count(stmt) == 2); |
450 | mysql_stmt_close(stmt); |
451 | |
452 | /* show create database */ |
453 | strmov(query, "SHOW CREATE DATABASE test" ); |
454 | stmt= mysql_simple_prepare(mysql, query); |
455 | check_stmt(stmt); |
456 | DIE_UNLESS(mysql_stmt_field_count(stmt) == 2); |
457 | mysql_stmt_close(stmt); |
458 | |
459 | /* show grants */ |
460 | strmov(query, "SHOW GRANTS" ); |
461 | stmt= mysql_simple_prepare(mysql, query); |
462 | check_stmt(stmt); |
463 | DIE_UNLESS(mysql_stmt_field_count(stmt) == 1); |
464 | mysql_stmt_close(stmt); |
465 | |
466 | /* show slave status */ |
467 | strmov(query, "SHOW SLAVE STATUS" ); |
468 | stmt= mysql_simple_prepare(mysql, query); |
469 | check_stmt(stmt); |
470 | DIE_UNLESS(mysql_stmt_field_count(stmt) == 53); |
471 | mysql_stmt_close(stmt); |
472 | |
473 | /* show master status */ |
474 | strmov(query, "SHOW MASTER STATUS" ); |
475 | stmt= mysql_simple_prepare(mysql, query); |
476 | check_stmt(stmt); |
477 | DIE_UNLESS(mysql_stmt_field_count(stmt) == 4); |
478 | mysql_stmt_close(stmt); |
479 | |
480 | /* show create procedure */ |
481 | strmov(query, "SHOW CREATE PROCEDURE e1;" ); |
482 | stmt= mysql_simple_prepare(mysql, query); |
483 | check_stmt(stmt); |
484 | DIE_UNLESS(mysql_stmt_field_count(stmt) == 6); |
485 | mysql_stmt_close(stmt); |
486 | |
487 | /* show create function */ |
488 | strmov(query, "SHOW CREATE FUNCTION e1;" ); |
489 | stmt= mysql_simple_prepare(mysql, query); |
490 | check_stmt(stmt); |
491 | DIE_UNLESS(mysql_stmt_field_count(stmt) == 6); |
492 | mysql_stmt_close(stmt); |
493 | |
494 | /* now fetch the results ..*/ |
495 | rc= mysql_commit(mysql); |
496 | myquery(rc); |
497 | } |
498 | |
499 | /************************************************************************/ |
500 | |
501 | #define FILE_PATH_SIZE 4096 |
502 | |
503 | char mct_log_file_path[FILE_PATH_SIZE]; |
504 | FILE *mct_log_file= NULL; |
505 | |
506 | void mct_start_logging(const char *test_case_name) |
507 | { |
508 | const char *tmp_dir= getenv("MYSQL_TMP_DIR" ); |
509 | |
510 | if (!tmp_dir) |
511 | { |
512 | printf("Warning: MYSQL_TMP_DIR is not set. Logging is disabled.\n" ); |
513 | return; |
514 | } |
515 | |
516 | if (mct_log_file) |
517 | { |
518 | printf("Warning: can not start logging for test case '%s' " |
519 | "because log is already open\n" , |
520 | (const char *) test_case_name); |
521 | return; |
522 | } |
523 | |
524 | /* |
525 | Path is: <tmp_dir>/<test_case_name>.out.log |
526 | 10 is length of '/' + '.out.log' + \0 |
527 | */ |
528 | |
529 | if (strlen(tmp_dir) + strlen(test_case_name) + 10 > FILE_PATH_SIZE) |
530 | { |
531 | printf("Warning: MYSQL_TMP_DIR is too long. Logging is disabled.\n" ); |
532 | return; |
533 | } |
534 | |
535 | my_snprintf(mct_log_file_path, FILE_PATH_SIZE, |
536 | "%s/%s.out.log" , |
537 | (const char *) tmp_dir, |
538 | (const char *) test_case_name); |
539 | |
540 | mct_log_file= my_fopen(mct_log_file_path, O_WRONLY | O_BINARY, MYF(MY_WME)); |
541 | |
542 | if (!mct_log_file) |
543 | { |
544 | printf("Warning: can not open log file (%s): %s. Logging is disabled.\n" , |
545 | (const char *) mct_log_file_path, |
546 | (const char *) strerror(errno)); |
547 | return; |
548 | } |
549 | } |
550 | |
551 | void mct_log(const char *format, ...) |
552 | { |
553 | va_list args; |
554 | va_start(args, format); |
555 | vprintf(format, args); |
556 | va_end(args); |
557 | |
558 | if (mct_log_file) |
559 | { |
560 | va_list args; |
561 | va_start(args, format); |
562 | vfprintf(mct_log_file, format, args); |
563 | va_end(args); |
564 | } |
565 | } |
566 | |
567 | void mct_close_log() |
568 | { |
569 | if (!mct_log_file) |
570 | return; |
571 | |
572 | my_fclose(mct_log_file, MYF(0)); |
573 | mct_log_file= NULL; |
574 | } |
575 | |
576 | #define WL4435_NUM_PARAMS 10 |
577 | #define WL4435_STRING_SIZE 30 |
578 | |
579 | static void test_wl4435() |
580 | { |
581 | MYSQL_STMT *stmt; |
582 | int rc; |
583 | char query[MAX_TEST_QUERY_LENGTH]; |
584 | |
585 | char str_data[20][WL4435_STRING_SIZE]; |
586 | double dbl_data[20]; |
587 | char dec_data[20][WL4435_STRING_SIZE]; |
588 | int int_data[20]; |
589 | ulong str_length= WL4435_STRING_SIZE; |
590 | my_bool is_null; |
591 | MYSQL_BIND ps_params[WL4435_NUM_PARAMS]; |
592 | |
593 | int exec_counter; |
594 | |
595 | myheader("test_wl4435" ); |
596 | mct_start_logging("test_wl4435" ); |
597 | |
598 | rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1" ); |
599 | myquery(rc); |
600 | |
601 | rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p2" ); |
602 | myquery(rc); |
603 | |
604 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1" ); |
605 | myquery(rc); |
606 | |
607 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t2" ); |
608 | myquery(rc); |
609 | |
610 | rc= mysql_query(mysql, "CREATE TABLE t1(a1 INT, a2 CHAR(32), " |
611 | " a3 DOUBLE(4, 2), a4 DECIMAL(3, 1))" ); |
612 | myquery(rc); |
613 | |
614 | rc= mysql_query(mysql, "CREATE TABLE t2(b0 INT, b1 INT, b2 CHAR(32), " |
615 | " b3 DOUBLE(4, 2), b4 DECIMAL(3, 1))" ); |
616 | myquery(rc); |
617 | |
618 | rc= mysql_query(mysql, "INSERT INTO t1 VALUES" |
619 | "(1, '11', 12.34, 56.7), " |
620 | "(2, '12', 56.78, 90.1), " |
621 | "(3, '13', 23.45, 67.8)" ); |
622 | myquery(rc); |
623 | |
624 | rc= mysql_query(mysql, "INSERT INTO t2 VALUES" |
625 | "(100, 10, '110', 70.70, 10.1), " |
626 | "(200, 20, '120', 80.80, 20.2), " |
627 | "(300, 30, '130', 90.90, 30.3)" ); |
628 | myquery(rc); |
629 | |
630 | rc= mysql_query(mysql, |
631 | "CREATE PROCEDURE p1(" |
632 | " IN v0 INT, " |
633 | " OUT v_str_1 CHAR(32), " |
634 | " OUT v_dbl_1 DOUBLE(4, 2), " |
635 | " OUT v_dec_1 DECIMAL(6, 3), " |
636 | " OUT v_int_1 INT, " |
637 | " IN v1 INT, " |
638 | " INOUT v_str_2 CHAR(64), " |
639 | " INOUT v_dbl_2 DOUBLE(5, 3), " |
640 | " INOUT v_dec_2 DECIMAL(7, 4), " |
641 | " INOUT v_int_2 INT)" |
642 | "BEGIN " |
643 | " SET v0 = -1; " |
644 | " SET v1 = -1; " |
645 | " SET v_str_1 = 'test_1'; " |
646 | " SET v_dbl_1 = 12.34; " |
647 | " SET v_dec_1 = 567.891; " |
648 | " SET v_int_1 = 2345; " |
649 | " SET v_str_2 = 'test_2'; " |
650 | " SET v_dbl_2 = 67.891; " |
651 | " SET v_dec_2 = 234.6789; " |
652 | " SET v_int_2 = 6789; " |
653 | " SELECT * FROM t1; " |
654 | " SELECT * FROM t2; " |
655 | "END" ); |
656 | myquery(rc); |
657 | |
658 | rc= mysql_query(mysql, |
659 | "CREATE PROCEDURE p2(" |
660 | " IN i1 VARCHAR(255) CHARACTER SET koi8r, " |
661 | " OUT o1 VARCHAR(255) CHARACTER SET cp1251, " |
662 | " OUT o2 VARBINARY(255)) " |
663 | "BEGIN " |
664 | " SET o1 = i1; " |
665 | " SET o2 = i1; " |
666 | "END" ); |
667 | myquery(rc); |
668 | |
669 | strmov(query, "CALL p1(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" ); |
670 | stmt= mysql_simple_prepare(mysql, query); |
671 | check_stmt(stmt); |
672 | |
673 | /* Init PS-parameters. */ |
674 | |
675 | bzero((char *) ps_params, sizeof (ps_params)); |
676 | |
677 | /* - v0 -- INT */ |
678 | |
679 | ps_params[0].buffer_type= MYSQL_TYPE_LONG; |
680 | ps_params[0].buffer= (char *) &int_data[0]; |
681 | ps_params[0].length= 0; |
682 | ps_params[0].is_null= 0; |
683 | |
684 | /* - v_str_1 -- CHAR(32) */ |
685 | |
686 | ps_params[1].buffer_type= MYSQL_TYPE_STRING; |
687 | ps_params[1].buffer= (char *) str_data[0]; |
688 | ps_params[1].buffer_length= WL4435_STRING_SIZE; |
689 | ps_params[1].length= &str_length; |
690 | ps_params[1].is_null= 0; |
691 | |
692 | /* - v_dbl_1 -- DOUBLE */ |
693 | |
694 | ps_params[2].buffer_type= MYSQL_TYPE_DOUBLE; |
695 | ps_params[2].buffer= (char *) &dbl_data[0]; |
696 | ps_params[2].length= 0; |
697 | ps_params[2].is_null= 0; |
698 | |
699 | /* - v_dec_1 -- DECIMAL */ |
700 | |
701 | ps_params[3].buffer_type= MYSQL_TYPE_NEWDECIMAL; |
702 | ps_params[3].buffer= (char *) dec_data[0]; |
703 | ps_params[3].buffer_length= WL4435_STRING_SIZE; |
704 | ps_params[3].length= 0; |
705 | ps_params[3].is_null= 0; |
706 | |
707 | /* - v_int_1 -- INT */ |
708 | |
709 | ps_params[4].buffer_type= MYSQL_TYPE_LONG; |
710 | ps_params[4].buffer= (char *) &int_data[0]; |
711 | ps_params[4].length= 0; |
712 | ps_params[4].is_null= 0; |
713 | |
714 | /* - v1 -- INT */ |
715 | |
716 | ps_params[5].buffer_type= MYSQL_TYPE_LONG; |
717 | ps_params[5].buffer= (char *) &int_data[0]; |
718 | ps_params[5].length= 0; |
719 | ps_params[5].is_null= 0; |
720 | |
721 | /* - v_str_2 -- CHAR(32) */ |
722 | |
723 | ps_params[6].buffer_type= MYSQL_TYPE_STRING; |
724 | ps_params[6].buffer= (char *) str_data[0]; |
725 | ps_params[6].buffer_length= WL4435_STRING_SIZE; |
726 | ps_params[6].length= &str_length; |
727 | ps_params[6].is_null= 0; |
728 | |
729 | /* - v_dbl_2 -- DOUBLE */ |
730 | |
731 | ps_params[7].buffer_type= MYSQL_TYPE_DOUBLE; |
732 | ps_params[7].buffer= (char *) &dbl_data[0]; |
733 | ps_params[7].length= 0; |
734 | ps_params[7].is_null= 0; |
735 | |
736 | /* - v_dec_2 -- DECIMAL */ |
737 | |
738 | ps_params[8].buffer_type= MYSQL_TYPE_DECIMAL; |
739 | ps_params[8].buffer= (char *) dec_data[0]; |
740 | ps_params[8].buffer_length= WL4435_STRING_SIZE; |
741 | ps_params[8].length= 0; |
742 | ps_params[8].is_null= 0; |
743 | |
744 | /* - v_int_2 -- INT */ |
745 | |
746 | ps_params[9].buffer_type= MYSQL_TYPE_LONG; |
747 | ps_params[9].buffer= (char *) &int_data[0]; |
748 | ps_params[9].length= 0; |
749 | ps_params[9].is_null= 0; |
750 | |
751 | /* Bind parameters. */ |
752 | |
753 | rc= mysql_stmt_bind_param(stmt, ps_params); |
754 | |
755 | /* Execute! */ |
756 | |
757 | for (exec_counter= 0; exec_counter < 3; ++exec_counter) |
758 | { |
759 | int i; |
760 | int num_fields; |
761 | MYSQL_BIND *rs_bind; |
762 | |
763 | mct_log("\nexec_counter: %d\n" , (int) exec_counter); |
764 | |
765 | rc= mysql_stmt_execute(stmt); |
766 | check_execute(stmt, rc); |
767 | |
768 | while (1) |
769 | { |
770 | MYSQL_FIELD *fields; |
771 | |
772 | MYSQL_RES *rs_metadata= mysql_stmt_result_metadata(stmt); |
773 | |
774 | num_fields= mysql_stmt_field_count(stmt); |
775 | fields= mysql_fetch_fields(rs_metadata); |
776 | |
777 | rs_bind= (MYSQL_BIND *) malloc(sizeof (MYSQL_BIND) * num_fields); |
778 | bzero(rs_bind, sizeof (MYSQL_BIND) * num_fields); |
779 | |
780 | mct_log("num_fields: %d\n" , (int) num_fields); |
781 | |
782 | for (i = 0; i < num_fields; ++i) |
783 | { |
784 | mct_log(" - %d: name: '%s'/'%s'; table: '%s'/'%s'; " |
785 | "db: '%s'; catalog: '%s'; length: %d; max_length: %d; " |
786 | "type: %d; decimals: %d\n" , |
787 | (int) i, |
788 | (const char *) fields[i].name, |
789 | (const char *) fields[i].org_name, |
790 | (const char *) fields[i].table, |
791 | (const char *) fields[i].org_table, |
792 | (const char *) fields[i].db, |
793 | (const char *) fields[i].catalog, |
794 | (int) fields[i].length, |
795 | (int) fields[i].max_length, |
796 | (int) fields[i].type, |
797 | (int) fields[i].decimals); |
798 | |
799 | rs_bind[i].buffer_type= fields[i].type; |
800 | rs_bind[i].is_null= &is_null; |
801 | |
802 | switch (fields[i].type) |
803 | { |
804 | case MYSQL_TYPE_LONG: |
805 | rs_bind[i].buffer= (char *) &(int_data[i]); |
806 | rs_bind[i].buffer_length= sizeof (int_data); |
807 | break; |
808 | |
809 | case MYSQL_TYPE_STRING: |
810 | rs_bind[i].buffer= (char *) str_data[i]; |
811 | rs_bind[i].buffer_length= WL4435_STRING_SIZE; |
812 | rs_bind[i].length= &str_length; |
813 | break; |
814 | |
815 | case MYSQL_TYPE_DOUBLE: |
816 | rs_bind[i].buffer= (char *) &dbl_data[i]; |
817 | rs_bind[i].buffer_length= sizeof (dbl_data); |
818 | break; |
819 | |
820 | case MYSQL_TYPE_NEWDECIMAL: |
821 | rs_bind[i].buffer= (char *) dec_data[i]; |
822 | rs_bind[i].buffer_length= WL4435_STRING_SIZE; |
823 | rs_bind[i].length= &str_length; |
824 | break; |
825 | |
826 | default: |
827 | fprintf(stderr, "ERROR: unexpected type: %d.\n" , fields[i].type); |
828 | exit(1); |
829 | } |
830 | } |
831 | |
832 | rc= mysql_stmt_bind_result(stmt, rs_bind); |
833 | check_execute(stmt, rc); |
834 | |
835 | mct_log("Data:\n" ); |
836 | |
837 | while (1) |
838 | { |
839 | int rc= mysql_stmt_fetch(stmt); |
840 | |
841 | if (rc == 1 || rc == MYSQL_NO_DATA) |
842 | break; |
843 | |
844 | mct_log(" " ); |
845 | |
846 | for (i = 0; i < num_fields; ++i) |
847 | { |
848 | switch (rs_bind[i].buffer_type) |
849 | { |
850 | case MYSQL_TYPE_LONG: |
851 | mct_log(" int: %ld;" , |
852 | (long) *((int *) rs_bind[i].buffer)); |
853 | break; |
854 | |
855 | case MYSQL_TYPE_STRING: |
856 | mct_log(" str: '%s';" , |
857 | (char *) rs_bind[i].buffer); |
858 | break; |
859 | |
860 | case MYSQL_TYPE_DOUBLE: |
861 | mct_log(" dbl: %lf;" , |
862 | (double) *((double *) rs_bind[i].buffer)); |
863 | break; |
864 | |
865 | case MYSQL_TYPE_NEWDECIMAL: |
866 | mct_log(" dec: '%s';" , |
867 | (char *) rs_bind[i].buffer); |
868 | break; |
869 | |
870 | default: |
871 | printf(" unexpected type (%d)\n" , |
872 | rs_bind[i].buffer_type); |
873 | } |
874 | } |
875 | mct_log("\n" ); |
876 | } |
877 | |
878 | mct_log("EOF\n" ); |
879 | |
880 | rc= mysql_stmt_next_result(stmt); |
881 | mct_log("mysql_stmt_next_result(): %d; field_count: %d\n" , |
882 | (int) rc, (int) mysql->field_count); |
883 | |
884 | free(rs_bind); |
885 | mysql_free_result(rs_metadata); |
886 | |
887 | if (rc > 0) |
888 | { |
889 | printf("Error: %s (errno: %d)\n" , |
890 | mysql_stmt_error(stmt), mysql_stmt_errno(stmt)); |
891 | DIE(rc > 0); |
892 | } |
893 | |
894 | if (rc) |
895 | break; |
896 | |
897 | if (!mysql->field_count) |
898 | { |
899 | /* This is the last OK-packet. No more resultsets. */ |
900 | break; |
901 | } |
902 | } |
903 | |
904 | } |
905 | |
906 | mysql_stmt_close(stmt); |
907 | |
908 | mct_close_log(); |
909 | |
910 | rc= mysql_commit(mysql); |
911 | myquery(rc); |
912 | |
913 | /* i18n part of test case. */ |
914 | |
915 | { |
916 | const char *str_koi8r= "\xee\xd5\x2c\x20\xda\xc1\x20\xd2\xd9\xc2\xc1\xcc\xcb\xd5" ; |
917 | const char *str_cp1251= "\xcd\xf3\x2c\x20\xe7\xe0\x20\xf0\xfb\xe1\xe0\xeb\xea\xf3" ; |
918 | char o1_buffer[255]; |
919 | ulong o1_length; |
920 | char o2_buffer[255]; |
921 | ulong o2_length; |
922 | |
923 | MYSQL_BIND rs_bind[2]; |
924 | |
925 | strmov(query, "CALL p2(?, ?, ?)" ); |
926 | stmt= mysql_simple_prepare(mysql, query); |
927 | check_stmt(stmt); |
928 | |
929 | /* Init PS-parameters. */ |
930 | |
931 | bzero((char *) ps_params, sizeof (ps_params)); |
932 | |
933 | ps_params[0].buffer_type= MYSQL_TYPE_STRING; |
934 | ps_params[0].buffer= (char *) str_koi8r; |
935 | ps_params[0].buffer_length= strlen(str_koi8r); |
936 | |
937 | ps_params[1].buffer_type= MYSQL_TYPE_STRING; |
938 | ps_params[1].buffer= o1_buffer; |
939 | ps_params[1].buffer_length= 0; |
940 | |
941 | ps_params[2].buffer_type= MYSQL_TYPE_STRING; |
942 | ps_params[2].buffer= o2_buffer; |
943 | ps_params[2].buffer_length= 0; |
944 | |
945 | /* Bind parameters. */ |
946 | |
947 | rc= mysql_stmt_bind_param(stmt, ps_params); |
948 | check_execute(stmt, rc); |
949 | |
950 | /* Prevent converting to character_set_results. */ |
951 | |
952 | rc= mysql_query(mysql, "SET NAMES binary" ); |
953 | myquery(rc); |
954 | |
955 | /* Execute statement. */ |
956 | |
957 | rc= mysql_stmt_execute(stmt); |
958 | check_execute(stmt, rc); |
959 | |
960 | /* Bind result. */ |
961 | |
962 | bzero(rs_bind, sizeof (rs_bind)); |
963 | |
964 | rs_bind[0].buffer_type= MYSQL_TYPE_STRING; |
965 | rs_bind[0].buffer= o1_buffer; |
966 | rs_bind[0].buffer_length= sizeof (o1_buffer); |
967 | rs_bind[0].length= &o1_length; |
968 | |
969 | rs_bind[1].buffer_type= MYSQL_TYPE_BLOB; |
970 | rs_bind[1].buffer= o2_buffer; |
971 | rs_bind[1].buffer_length= sizeof (o2_buffer); |
972 | rs_bind[1].length= &o2_length; |
973 | |
974 | rc= mysql_stmt_bind_result(stmt, rs_bind); |
975 | check_execute(stmt, rc); |
976 | |
977 | /* Fetch result. */ |
978 | |
979 | rc= mysql_stmt_fetch(stmt); |
980 | check_execute(stmt, rc); |
981 | |
982 | /* Check result. */ |
983 | |
984 | DIE_UNLESS(o1_length == strlen(str_cp1251)); |
985 | DIE_UNLESS(o2_length == strlen(str_koi8r)); |
986 | DIE_UNLESS(!memcmp(o1_buffer, str_cp1251, o1_length)); |
987 | DIE_UNLESS(!memcmp(o2_buffer, str_koi8r, o2_length)); |
988 | |
989 | rc= mysql_stmt_fetch(stmt); |
990 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
991 | |
992 | rc= mysql_stmt_next_result(stmt); |
993 | DIE_UNLESS(rc == 0 && mysql->field_count == 0); |
994 | |
995 | mysql_stmt_close(stmt); |
996 | |
997 | rc= mysql_commit(mysql); |
998 | myquery(rc); |
999 | } |
1000 | } |
1001 | |
1002 | static void test_wl4435_2() |
1003 | { |
1004 | MYSQL_STMT *stmt; |
1005 | int i; |
1006 | int rc; |
1007 | char query[MAX_TEST_QUERY_LENGTH]; |
1008 | |
1009 | myheader("test_wl4435_2" ); |
1010 | mct_start_logging("test_wl4435_2" ); |
1011 | |
1012 | /* |
1013 | Do a few iterations so that we catch any problem with incorrect |
1014 | handling/flushing prepared statement results. |
1015 | */ |
1016 | |
1017 | for (i= 0; i < 10; ++i) |
1018 | { |
1019 | /* |
1020 | Prepare a procedure. That can be moved out of the loop, but it was |
1021 | left in the loop for the sake of having as many statements as |
1022 | possible. |
1023 | */ |
1024 | |
1025 | rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1" ); |
1026 | myquery(rc); |
1027 | |
1028 | rc= mysql_query(mysql, |
1029 | "CREATE PROCEDURE p1()" |
1030 | "BEGIN " |
1031 | " SELECT 1; " |
1032 | " SELECT 2, 3 UNION SELECT 4, 5; " |
1033 | " SELECT 6, 7, 8; " |
1034 | "END" ); |
1035 | myquery(rc); |
1036 | |
1037 | /* Invoke a procedure, that returns several result sets. */ |
1038 | |
1039 | strmov(query, "CALL p1()" ); |
1040 | stmt= mysql_simple_prepare(mysql, query); |
1041 | check_stmt(stmt); |
1042 | |
1043 | /* Execute! */ |
1044 | |
1045 | rc= mysql_stmt_execute(stmt); |
1046 | check_execute(stmt, rc); |
1047 | |
1048 | /* Flush all the results. */ |
1049 | |
1050 | mysql_stmt_close(stmt); |
1051 | |
1052 | /* Clean up. */ |
1053 | rc= mysql_commit(mysql); |
1054 | myquery(rc); |
1055 | |
1056 | rc= mysql_query(mysql, "DROP PROCEDURE p1" ); |
1057 | myquery(rc); |
1058 | } |
1059 | mct_close_log(); |
1060 | } |
1061 | |
1062 | |
1063 | #define WL4435_TEST(sql_type, sql_value, \ |
1064 | c_api_in_type, c_api_out_type, \ |
1065 | c_type, c_type_ext, \ |
1066 | printf_args, assert_condition) \ |
1067 | \ |
1068 | do { \ |
1069 | int rc; \ |
1070 | MYSQL_STMT *ps; \ |
1071 | MYSQL_BIND psp; \ |
1072 | MYSQL_RES *rs_metadata; \ |
1073 | MYSQL_FIELD *fields; \ |
1074 | c_type pspv c_type_ext; \ |
1075 | my_bool psp_null; \ |
1076 | \ |
1077 | bzero(&pspv, sizeof (pspv)); \ |
1078 | \ |
1079 | rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1"); \ |
1080 | myquery(rc); \ |
1081 | \ |
1082 | rc= mysql_query(mysql, \ |
1083 | "CREATE PROCEDURE p1(OUT v " sql_type ") SET v = " sql_value ";"); \ |
1084 | myquery(rc); \ |
1085 | \ |
1086 | ps = mysql_simple_prepare(mysql, "CALL p1(?)"); \ |
1087 | check_stmt(ps); \ |
1088 | \ |
1089 | bzero(&psp, sizeof (psp)); \ |
1090 | psp.buffer_type= c_api_in_type; \ |
1091 | psp.is_null= &psp_null; \ |
1092 | psp.buffer= (char *) &pspv; \ |
1093 | psp.buffer_length= sizeof (psp); \ |
1094 | \ |
1095 | rc= mysql_stmt_bind_param(ps, &psp); \ |
1096 | check_execute(ps, rc); \ |
1097 | \ |
1098 | rc= mysql_stmt_execute(ps); \ |
1099 | check_execute(ps, rc); \ |
1100 | \ |
1101 | DIE_UNLESS(mysql->server_status & SERVER_PS_OUT_PARAMS); \ |
1102 | DIE_UNLESS(mysql_stmt_field_count(ps) == 1); \ |
1103 | \ |
1104 | rs_metadata= mysql_stmt_result_metadata(ps); \ |
1105 | fields= mysql_fetch_fields(rs_metadata); \ |
1106 | mysql_free_result(rs_metadata); \ |
1107 | \ |
1108 | rc= mysql_stmt_bind_result(ps, &psp); \ |
1109 | check_execute(ps, rc); \ |
1110 | \ |
1111 | rc= mysql_stmt_fetch(ps); \ |
1112 | DIE_UNLESS(rc == 0); \ |
1113 | \ |
1114 | DIE_UNLESS(fields[0].type == c_api_out_type); \ |
1115 | printf printf_args; \ |
1116 | printf("; in type: %d; out type: %d\n", \ |
1117 | (int) c_api_in_type, (int) c_api_out_type); \ |
1118 | \ |
1119 | rc= mysql_stmt_fetch(ps); \ |
1120 | DIE_UNLESS(rc == MYSQL_NO_DATA); \ |
1121 | \ |
1122 | rc= mysql_stmt_next_result(ps); \ |
1123 | DIE_UNLESS(rc == 0); \ |
1124 | \ |
1125 | mysql_stmt_free_result(ps); \ |
1126 | mysql_stmt_close(ps); \ |
1127 | \ |
1128 | DIE_UNLESS(assert_condition); \ |
1129 | \ |
1130 | } while (0) |
1131 | |
1132 | static void test_wl4435_3() |
1133 | { |
1134 | char tmp[255]; |
1135 | |
1136 | puts("" ); |
1137 | |
1138 | /* |
1139 | // The following types are not supported: |
1140 | // - ENUM |
1141 | // - SET |
1142 | // |
1143 | // The following types are supported but can not be used for |
1144 | // OUT-parameters: |
1145 | // - MEDIUMINT; |
1146 | // - BIT(..); |
1147 | // |
1148 | // The problem is that those types are not supported for IN-parameters, |
1149 | // and OUT-parameters should be bound as IN-parameters before execution. |
1150 | // |
1151 | // The following types should not be used: |
1152 | // - MYSQL_TYPE_YEAR (use MYSQL_TYPE_SHORT instead); |
1153 | // - MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB |
1154 | // (use MYSQL_TYPE_BLOB instead); |
1155 | */ |
1156 | |
1157 | WL4435_TEST("TINYINT" , "127" , |
1158 | MYSQL_TYPE_TINY, MYSQL_TYPE_TINY, |
1159 | char, , |
1160 | (" - TINYINT / char / MYSQL_TYPE_TINY:\t\t\t %d" , (int) pspv), |
1161 | pspv == 127); |
1162 | |
1163 | WL4435_TEST("SMALLINT" , "32767" , |
1164 | MYSQL_TYPE_SHORT, MYSQL_TYPE_SHORT, |
1165 | short, , |
1166 | (" - SMALLINT / short / MYSQL_TYPE_SHORT:\t\t %d" , (int) pspv), |
1167 | pspv == 32767); |
1168 | |
1169 | WL4435_TEST("INT" , "2147483647" , |
1170 | MYSQL_TYPE_LONG, MYSQL_TYPE_LONG, |
1171 | int, , |
1172 | (" - INT / int / MYSQL_TYPE_LONG:\t\t\t %d" , pspv), |
1173 | pspv == 2147483647l); |
1174 | |
1175 | WL4435_TEST("BIGINT" , "9223372036854775807" , |
1176 | MYSQL_TYPE_LONGLONG, MYSQL_TYPE_LONGLONG, |
1177 | long long, , |
1178 | (" - BIGINT / long long / MYSQL_TYPE_LONGLONG:\t\t %lld" , pspv), |
1179 | pspv == 9223372036854775807ll); |
1180 | |
1181 | WL4435_TEST("TIMESTAMP" , "'2007-11-18 15:01:02'" , |
1182 | MYSQL_TYPE_TIMESTAMP, MYSQL_TYPE_TIMESTAMP, |
1183 | MYSQL_TIME, , |
1184 | (" - TIMESTAMP / MYSQL_TIME / MYSQL_TYPE_TIMESTAMP:\t " |
1185 | "%.4d-%.2d-%.2d %.2d:%.2d:%.2d" , |
1186 | (int) pspv.year, (int) pspv.month, (int) pspv.day, |
1187 | (int) pspv.hour, (int) pspv.minute, (int) pspv.second), |
1188 | pspv.year == 2007 && pspv.month == 11 && pspv.day == 18 && |
1189 | pspv.hour == 15 && pspv.minute == 1 && pspv.second == 2); |
1190 | |
1191 | WL4435_TEST("DATETIME" , "'1234-11-12 12:34:59'" , |
1192 | MYSQL_TYPE_DATETIME, MYSQL_TYPE_DATETIME, |
1193 | MYSQL_TIME, , |
1194 | (" - DATETIME / MYSQL_TIME / MYSQL_TYPE_DATETIME:\t " |
1195 | "%.4d-%.2d-%.2d %.2d:%.2d:%.2d" , |
1196 | (int) pspv.year, (int) pspv.month, (int) pspv.day, |
1197 | (int) pspv.hour, (int) pspv.minute, (int) pspv.second), |
1198 | pspv.year == 1234 && pspv.month == 11 && pspv.day == 12 && |
1199 | pspv.hour == 12 && pspv.minute == 34 && pspv.second == 59); |
1200 | |
1201 | WL4435_TEST("TIME" , "'123:45:01'" , |
1202 | MYSQL_TYPE_TIME, MYSQL_TYPE_TIME, |
1203 | MYSQL_TIME, , |
1204 | (" - TIME / MYSQL_TIME / MYSQL_TYPE_TIME:\t\t " |
1205 | "%.3d:%.2d:%.2d" , |
1206 | (int) pspv.hour, (int) pspv.minute, (int) pspv.second), |
1207 | pspv.hour == 123 && pspv.minute == 45 && pspv.second == 1); |
1208 | |
1209 | WL4435_TEST("DATE" , "'1234-11-12'" , |
1210 | MYSQL_TYPE_DATE, MYSQL_TYPE_DATE, |
1211 | MYSQL_TIME, , |
1212 | (" - DATE / MYSQL_TIME / MYSQL_TYPE_DATE:\t\t " |
1213 | "%.4d-%.2d-%.2d" , |
1214 | (int) pspv.year, (int) pspv.month, (int) pspv.day), |
1215 | pspv.year == 1234 && pspv.month == 11 && pspv.day == 12); |
1216 | |
1217 | WL4435_TEST("YEAR" , "'2010'" , |
1218 | MYSQL_TYPE_SHORT, MYSQL_TYPE_YEAR, |
1219 | short, , |
1220 | (" - YEAR / short / MYSQL_TYPE_SHORT:\t\t\t %.4d" , (int) pspv), |
1221 | pspv == 2010); |
1222 | |
1223 | WL4435_TEST("FLOAT(7, 4)" , "123.4567" , |
1224 | MYSQL_TYPE_FLOAT, MYSQL_TYPE_FLOAT, |
1225 | float, , |
1226 | (" - FLOAT / float / MYSQL_TYPE_FLOAT:\t\t\t %g" , (double) pspv), |
1227 | pspv - 123.4567 < 0.0001); |
1228 | |
1229 | WL4435_TEST("DOUBLE(8, 5)" , "123.45678" , |
1230 | MYSQL_TYPE_DOUBLE, MYSQL_TYPE_DOUBLE, |
1231 | double, , |
1232 | (" - DOUBLE / double / MYSQL_TYPE_DOUBLE:\t\t %g" , (double) pspv), |
1233 | pspv - 123.45678 < 0.00001); |
1234 | |
1235 | WL4435_TEST("DECIMAL(9, 6)" , "123.456789" , |
1236 | MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_NEWDECIMAL, |
1237 | char, [255], |
1238 | (" - DECIMAL / char[] / MYSQL_TYPE_NEWDECIMAL:\t\t '%s'" , (char *) pspv), |
1239 | !strcmp(pspv, "123.456789" )); |
1240 | |
1241 | WL4435_TEST("CHAR(32)" , "REPEAT('C', 16)" , |
1242 | MYSQL_TYPE_STRING, MYSQL_TYPE_STRING, |
1243 | char, [255], |
1244 | (" - CHAR(32) / char[] / MYSQL_TYPE_STRING:\t\t '%s'" , (char *) pspv), |
1245 | !strcmp(pspv, "CCCCCCCCCCCCCCCC" )); |
1246 | |
1247 | WL4435_TEST("VARCHAR(32)" , "REPEAT('V', 16)" , |
1248 | MYSQL_TYPE_VAR_STRING, MYSQL_TYPE_VAR_STRING, |
1249 | char, [255], |
1250 | (" - VARCHAR(32) / char[] / MYSQL_TYPE_VAR_STRING:\t '%s'" , (char *) pspv), |
1251 | !strcmp(pspv, "VVVVVVVVVVVVVVVV" )); |
1252 | |
1253 | WL4435_TEST("TINYTEXT" , "REPEAT('t', 16)" , |
1254 | MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_BLOB, |
1255 | char, [255], |
1256 | (" - TINYTEXT / char[] / MYSQL_TYPE_TINY_BLOB:\t\t '%s'" , (char *) pspv), |
1257 | !strcmp(pspv, "tttttttttttttttt" )); |
1258 | |
1259 | WL4435_TEST("TEXT" , "REPEAT('t', 16)" , |
1260 | MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB, |
1261 | char, [255], |
1262 | (" - TEXT / char[] / MYSQL_TYPE_BLOB:\t\t\t '%s'" , (char *) pspv), |
1263 | !strcmp(pspv, "tttttttttttttttt" )); |
1264 | |
1265 | WL4435_TEST("MEDIUMTEXT" , "REPEAT('t', 16)" , |
1266 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_BLOB, |
1267 | char, [255], |
1268 | (" - MEDIUMTEXT / char[] / MYSQL_TYPE_MEDIUM_BLOB:\t '%s'" , (char *) pspv), |
1269 | !strcmp(pspv, "tttttttttttttttt" )); |
1270 | |
1271 | WL4435_TEST("LONGTEXT" , "REPEAT('t', 16)" , |
1272 | MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_BLOB, |
1273 | char, [255], |
1274 | (" - LONGTEXT / char[] / MYSQL_TYPE_LONG_BLOB:\t\t '%s'" , (char *) pspv), |
1275 | !strcmp(pspv, "tttttttttttttttt" )); |
1276 | |
1277 | WL4435_TEST("BINARY(32)" , "REPEAT('\1', 16)" , |
1278 | MYSQL_TYPE_STRING, MYSQL_TYPE_STRING, |
1279 | char, [255], |
1280 | (" - BINARY(32) / char[] / MYSQL_TYPE_STRING:\t\t '%s'" , (char *) pspv), |
1281 | memset(tmp, 1, 16) && !memcmp(tmp, pspv, 16)); |
1282 | |
1283 | WL4435_TEST("VARBINARY(32)" , "REPEAT('\1', 16)" , |
1284 | MYSQL_TYPE_VAR_STRING, MYSQL_TYPE_VAR_STRING, |
1285 | char, [255], |
1286 | (" - VARBINARY(32) / char[] / MYSQL_TYPE_VAR_STRING:\t '%s'" , (char *) pspv), |
1287 | memset(tmp, 1, 16) && !memcmp(tmp, pspv, 16)); |
1288 | |
1289 | WL4435_TEST("TINYBLOB" , "REPEAT('\2', 16)" , |
1290 | MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_BLOB, |
1291 | char, [255], |
1292 | (" - TINYBLOB / char[] / MYSQL_TYPE_TINY_BLOB:\t\t '%s'" , (char *) pspv), |
1293 | memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16)); |
1294 | |
1295 | WL4435_TEST("BLOB" , "REPEAT('\2', 16)" , |
1296 | MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB, |
1297 | char, [255], |
1298 | (" - BLOB / char[] / MYSQL_TYPE_BLOB:\t\t\t '%s'" , (char *) pspv), |
1299 | memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16)); |
1300 | |
1301 | WL4435_TEST("MEDIUMBLOB" , "REPEAT('\2', 16)" , |
1302 | MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_BLOB, |
1303 | char, [255], |
1304 | (" - MEDIUMBLOB / char[] / MYSQL_TYPE_MEDIUM_BLOB:\t '%s'" , (char *) pspv), |
1305 | memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16)); |
1306 | |
1307 | WL4435_TEST("LONGBLOB" , "REPEAT('\2', 16)" , |
1308 | MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_BLOB, |
1309 | char, [255], |
1310 | (" - LONGBLOB / char[] / MYSQL_TYPE_LONG_BLOB:\t\t '%s'" , (char *) pspv), |
1311 | memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16)); |
1312 | } |
1313 | |
1314 | |
1315 | /* Test simple prepare field results */ |
1316 | |
1317 | static void test_prepare_field_result() |
1318 | { |
1319 | MYSQL_STMT *stmt; |
1320 | MYSQL_RES *result; |
1321 | int rc; |
1322 | char query[MAX_TEST_QUERY_LENGTH]; |
1323 | |
1324 | myheader("test_prepare_field_result" ); |
1325 | |
1326 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_field_result" ); |
1327 | myquery(rc); |
1328 | |
1329 | rc= mysql_query(mysql, "CREATE TABLE test_prepare_field_result(int_c int, " |
1330 | "var_c varchar(50), ts_c timestamp, " |
1331 | "char_c char(4), date_c date, extra tinyint)" ); |
1332 | myquery(rc); |
1333 | |
1334 | /* insert */ |
1335 | strmov(query, "SELECT int_c, var_c, date_c as date, ts_c, char_c FROM " |
1336 | " test_prepare_field_result as t1 WHERE int_c=?" ); |
1337 | stmt= mysql_simple_prepare(mysql, query); |
1338 | check_stmt(stmt); |
1339 | |
1340 | verify_param_count(stmt, 1); |
1341 | |
1342 | result= mysql_stmt_result_metadata(stmt); |
1343 | mytest(result); |
1344 | |
1345 | my_print_result_metadata(result); |
1346 | |
1347 | if (!opt_silent) |
1348 | fprintf(stdout, "\n\n field attributes:\n" ); |
1349 | verify_prepare_field(result, 0, "int_c" , "int_c" , MYSQL_TYPE_LONG, |
1350 | "t1" , "test_prepare_field_result" , current_db, 11, 0); |
1351 | verify_prepare_field(result, 1, "var_c" , "var_c" , MYSQL_TYPE_VAR_STRING, |
1352 | "t1" , "test_prepare_field_result" , current_db, 50, 0); |
1353 | verify_prepare_field(result, 2, "date" , "date_c" , MYSQL_TYPE_DATE, |
1354 | "t1" , "test_prepare_field_result" , current_db, 10, 0); |
1355 | verify_prepare_field(result, 3, "ts_c" , "ts_c" , MYSQL_TYPE_TIMESTAMP, |
1356 | "t1" , "test_prepare_field_result" , current_db, 19, 0); |
1357 | verify_prepare_field(result, 4, "char_c" , "char_c" , |
1358 | (mysql_get_server_version(mysql) <= 50000 ? |
1359 | MYSQL_TYPE_VAR_STRING : MYSQL_TYPE_STRING), |
1360 | "t1" , "test_prepare_field_result" , current_db, 4, 0); |
1361 | |
1362 | verify_field_count(result, 5); |
1363 | mysql_free_result(result); |
1364 | mysql_stmt_close(stmt); |
1365 | } |
1366 | |
1367 | |
1368 | /* Test simple prepare field results */ |
1369 | |
1370 | static void test_prepare_syntax() |
1371 | { |
1372 | MYSQL_STMT *stmt; |
1373 | int rc; |
1374 | char query[MAX_TEST_QUERY_LENGTH]; |
1375 | |
1376 | myheader("test_prepare_syntax" ); |
1377 | |
1378 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_syntax" ); |
1379 | myquery(rc); |
1380 | |
1381 | rc= mysql_query(mysql, "CREATE TABLE test_prepare_syntax(" |
1382 | "id int, name varchar(50), extra int)" ); |
1383 | myquery(rc); |
1384 | |
1385 | strmov(query, "INSERT INTO test_prepare_syntax VALUES(?" ); |
1386 | stmt= mysql_simple_prepare(mysql, query); |
1387 | check_stmt_r(stmt); |
1388 | |
1389 | strmov(query, "SELECT id, name FROM test_prepare_syntax WHERE id=? AND WHERE" ); |
1390 | stmt= mysql_simple_prepare(mysql, query); |
1391 | check_stmt_r(stmt); |
1392 | |
1393 | /* now fetch the results ..*/ |
1394 | rc= mysql_commit(mysql); |
1395 | myquery(rc); |
1396 | } |
1397 | |
1398 | |
1399 | /* Test a simple prepare */ |
1400 | |
1401 | static void test_prepare() |
1402 | { |
1403 | MYSQL_STMT *stmt; |
1404 | int rc, i; |
1405 | int int_data, o_int_data; |
1406 | char str_data[50], data[50]; |
1407 | char tiny_data, o_tiny_data; |
1408 | short small_data, o_small_data; |
1409 | longlong big_data, o_big_data; |
1410 | float real_data, o_real_data; |
1411 | double double_data, o_double_data; |
1412 | ulong length[7], len; |
1413 | my_bool is_null[7]; |
1414 | char llbuf[22]; |
1415 | MYSQL_BIND my_bind[7]; |
1416 | char query[MAX_TEST_QUERY_LENGTH]; |
1417 | |
1418 | myheader("test_prepare" ); |
1419 | |
1420 | rc= mysql_autocommit(mysql, TRUE); |
1421 | myquery(rc); |
1422 | |
1423 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS my_prepare" ); |
1424 | myquery(rc); |
1425 | |
1426 | rc= mysql_query(mysql, "CREATE TABLE my_prepare(col1 tinyint, " |
1427 | "col2 varchar(15), col3 int, " |
1428 | "col4 smallint, col5 bigint, " |
1429 | "col6 float, col7 double )" ); |
1430 | myquery(rc); |
1431 | |
1432 | /* insert by prepare */ |
1433 | strxmov(query, "INSERT INTO my_prepare VALUES(?, ?, ?, ?, ?, ?, ?)" , NullS); |
1434 | stmt= mysql_simple_prepare(mysql, query); |
1435 | check_stmt(stmt); |
1436 | |
1437 | verify_param_count(stmt, 7); |
1438 | |
1439 | bzero((char*) my_bind, sizeof(my_bind)); |
1440 | |
1441 | /* tinyint */ |
1442 | my_bind[0].buffer_type= MYSQL_TYPE_TINY; |
1443 | my_bind[0].buffer= (void *)&tiny_data; |
1444 | /* string */ |
1445 | my_bind[1].buffer_type= MYSQL_TYPE_STRING; |
1446 | my_bind[1].buffer= (void *)str_data; |
1447 | my_bind[1].buffer_length= 1000; /* Max string length */ |
1448 | /* integer */ |
1449 | my_bind[2].buffer_type= MYSQL_TYPE_LONG; |
1450 | my_bind[2].buffer= (void *)&int_data; |
1451 | /* short */ |
1452 | my_bind[3].buffer_type= MYSQL_TYPE_SHORT; |
1453 | my_bind[3].buffer= (void *)&small_data; |
1454 | /* bigint */ |
1455 | my_bind[4].buffer_type= MYSQL_TYPE_LONGLONG; |
1456 | my_bind[4].buffer= (void *)&big_data; |
1457 | /* float */ |
1458 | my_bind[5].buffer_type= MYSQL_TYPE_FLOAT; |
1459 | my_bind[5].buffer= (void *)&real_data; |
1460 | /* double */ |
1461 | my_bind[6].buffer_type= MYSQL_TYPE_DOUBLE; |
1462 | my_bind[6].buffer= (void *)&double_data; |
1463 | |
1464 | for (i= 0; i < (int) array_elements(my_bind); i++) |
1465 | { |
1466 | my_bind[i].length= &length[i]; |
1467 | my_bind[i].is_null= &is_null[i]; |
1468 | is_null[i]= 0; |
1469 | } |
1470 | |
1471 | rc= mysql_stmt_bind_param(stmt, my_bind); |
1472 | check_execute(stmt, rc); |
1473 | |
1474 | int_data= 320; |
1475 | small_data= 1867; |
1476 | big_data= 1000; |
1477 | real_data= 2; |
1478 | double_data= 6578.001; |
1479 | |
1480 | /* now, execute the prepared statement to insert 10 records.. */ |
1481 | for (tiny_data= 0; tiny_data < 100; tiny_data++) |
1482 | { |
1483 | length[1]= sprintf(str_data, "MySQL%d" , int_data); |
1484 | rc= mysql_stmt_execute(stmt); |
1485 | check_execute(stmt, rc); |
1486 | int_data += 25; |
1487 | small_data += 10; |
1488 | big_data += 100; |
1489 | real_data += 1; |
1490 | double_data += 10.09; |
1491 | } |
1492 | |
1493 | mysql_stmt_close(stmt); |
1494 | |
1495 | /* now fetch the results ..*/ |
1496 | rc= mysql_commit(mysql); |
1497 | myquery(rc); |
1498 | |
1499 | /* test the results now, only one row should exist */ |
1500 | rc= my_stmt_result("SELECT * FROM my_prepare" ); |
1501 | DIE_UNLESS(tiny_data == (char) rc); |
1502 | |
1503 | stmt= mysql_simple_prepare(mysql, "SELECT * FROM my_prepare" ); |
1504 | check_stmt(stmt); |
1505 | |
1506 | rc= mysql_stmt_bind_result(stmt, my_bind); |
1507 | check_execute(stmt, rc); |
1508 | |
1509 | /* get the result */ |
1510 | rc= mysql_stmt_execute(stmt); |
1511 | check_execute(stmt, rc); |
1512 | |
1513 | o_int_data= 320; |
1514 | o_small_data= 1867; |
1515 | o_big_data= 1000; |
1516 | o_real_data= 2; |
1517 | o_double_data= 6578.001; |
1518 | |
1519 | /* now, execute the prepared statement to insert 10 records.. */ |
1520 | for (o_tiny_data= 0; o_tiny_data < 100; o_tiny_data++) |
1521 | { |
1522 | len= sprintf(data, "MySQL%d" , o_int_data); |
1523 | |
1524 | rc= mysql_stmt_fetch(stmt); |
1525 | check_execute(stmt, rc); |
1526 | |
1527 | if (!opt_silent) |
1528 | { |
1529 | fprintf(stdout, "\n" ); |
1530 | fprintf(stdout, "\n\t tiny : %d (%lu)" , tiny_data, length[0]); |
1531 | fprintf(stdout, "\n\t short : %d (%lu)" , small_data, length[3]); |
1532 | fprintf(stdout, "\n\t int : %d (%lu)" , int_data, length[2]); |
1533 | fprintf(stdout, "\n\t big : %s (%lu)" , llstr(big_data, llbuf), |
1534 | length[4]); |
1535 | |
1536 | fprintf(stdout, "\n\t float : %f (%lu)" , real_data, length[5]); |
1537 | fprintf(stdout, "\n\t double : %f (%lu)" , double_data, length[6]); |
1538 | |
1539 | fprintf(stdout, "\n\t str : %s (%lu)" , str_data, length[1]); |
1540 | } |
1541 | |
1542 | DIE_UNLESS(tiny_data == o_tiny_data); |
1543 | DIE_UNLESS(is_null[0] == 0); |
1544 | DIE_UNLESS(length[0] == 1); |
1545 | |
1546 | DIE_UNLESS(int_data == o_int_data); |
1547 | DIE_UNLESS(length[2] == 4); |
1548 | |
1549 | DIE_UNLESS(small_data == o_small_data); |
1550 | DIE_UNLESS(length[3] == 2); |
1551 | |
1552 | DIE_UNLESS(big_data == o_big_data); |
1553 | DIE_UNLESS(length[4] == 8); |
1554 | |
1555 | DIE_UNLESS(real_data == o_real_data); |
1556 | DIE_UNLESS(length[5] == 4); |
1557 | |
1558 | DIE_UNLESS(cmp_double(&double_data, &o_double_data)); |
1559 | DIE_UNLESS(length[6] == 8); |
1560 | |
1561 | DIE_UNLESS(strcmp(data, str_data) == 0); |
1562 | DIE_UNLESS(length[1] == len); |
1563 | |
1564 | o_int_data += 25; |
1565 | o_small_data += 10; |
1566 | o_big_data += 100; |
1567 | o_real_data += 1; |
1568 | o_double_data += 10.09; |
1569 | } |
1570 | |
1571 | rc= mysql_stmt_fetch(stmt); |
1572 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
1573 | |
1574 | mysql_stmt_close(stmt); |
1575 | |
1576 | } |
1577 | |
1578 | |
1579 | /* Test double comparision */ |
1580 | |
1581 | static void test_double_compare() |
1582 | { |
1583 | MYSQL_STMT *stmt; |
1584 | int rc; |
1585 | char real_data[10], tiny_data; |
1586 | double double_data; |
1587 | MYSQL_RES *result; |
1588 | MYSQL_BIND my_bind[3]; |
1589 | ulong length[3]; |
1590 | char query[MAX_TEST_QUERY_LENGTH]; |
1591 | |
1592 | myheader("test_double_compare" ); |
1593 | |
1594 | rc= mysql_autocommit(mysql, TRUE); |
1595 | myquery(rc); |
1596 | |
1597 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_double_compare" ); |
1598 | myquery(rc); |
1599 | |
1600 | rc= mysql_query(mysql, "CREATE TABLE test_double_compare(col1 tinyint, " |
1601 | " col2 float, col3 double )" ); |
1602 | myquery(rc); |
1603 | |
1604 | rc= mysql_query(mysql, "INSERT INTO test_double_compare " |
1605 | "VALUES (1, 10.2, 34.5)" ); |
1606 | myquery(rc); |
1607 | |
1608 | strmov(query, "UPDATE test_double_compare SET col1=100 " |
1609 | "WHERE col1 = ? AND col2 = ? AND COL3 = ?" ); |
1610 | stmt= mysql_simple_prepare(mysql, query); |
1611 | check_stmt(stmt); |
1612 | |
1613 | verify_param_count(stmt, 3); |
1614 | |
1615 | /* Always bzero bind array because there can be internal members */ |
1616 | bzero((char*) my_bind, sizeof(my_bind)); |
1617 | |
1618 | /* tinyint */ |
1619 | my_bind[0].buffer_type= MYSQL_TYPE_TINY; |
1620 | my_bind[0].buffer= (void *)&tiny_data; |
1621 | |
1622 | /* string->float */ |
1623 | my_bind[1].buffer_type= MYSQL_TYPE_STRING; |
1624 | my_bind[1].buffer= (void *)&real_data; |
1625 | my_bind[1].buffer_length= sizeof(real_data); |
1626 | my_bind[1].length= &length[1]; |
1627 | length[1]= 10; |
1628 | |
1629 | /* double */ |
1630 | my_bind[2].buffer_type= MYSQL_TYPE_DOUBLE; |
1631 | my_bind[2].buffer= (void *)&double_data; |
1632 | |
1633 | tiny_data= 1; |
1634 | strmov(real_data, "10.2" ); |
1635 | double_data= 34.5; |
1636 | rc= mysql_stmt_bind_param(stmt, my_bind); |
1637 | check_execute(stmt, rc); |
1638 | |
1639 | rc= mysql_stmt_execute(stmt); |
1640 | check_execute(stmt, rc); |
1641 | |
1642 | verify_affected_rows(0); |
1643 | |
1644 | mysql_stmt_close(stmt); |
1645 | |
1646 | /* now fetch the results ..*/ |
1647 | rc= mysql_commit(mysql); |
1648 | myquery(rc); |
1649 | |
1650 | /* test the results now, only one row should exist */ |
1651 | rc= mysql_query(mysql, "SELECT * FROM test_double_compare" ); |
1652 | myquery(rc); |
1653 | |
1654 | /* get the result */ |
1655 | result= mysql_store_result(mysql); |
1656 | mytest(result); |
1657 | |
1658 | rc= my_process_result_set(result); |
1659 | DIE_UNLESS((int)tiny_data == rc); |
1660 | mysql_free_result(result); |
1661 | } |
1662 | |
1663 | |
1664 | /* Test simple null */ |
1665 | |
1666 | static void test_null() |
1667 | { |
1668 | MYSQL_STMT *stmt; |
1669 | int rc; |
1670 | uint nData; |
1671 | MYSQL_BIND my_bind[2]; |
1672 | my_bool is_null[2]; |
1673 | char query[MAX_TEST_QUERY_LENGTH]; |
1674 | |
1675 | myheader("test_null" ); |
1676 | |
1677 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_null" ); |
1678 | myquery(rc); |
1679 | |
1680 | rc= mysql_query(mysql, "CREATE TABLE test_null(col1 int, col2 varchar(50))" ); |
1681 | myquery(rc); |
1682 | |
1683 | /* insert by prepare, wrong column name */ |
1684 | strmov(query, "INSERT INTO test_null(col3, col2) VALUES(?, ?)" ); |
1685 | stmt= mysql_simple_prepare(mysql, query); |
1686 | check_stmt_r(stmt); |
1687 | |
1688 | strmov(query, "INSERT INTO test_null(col1, col2) VALUES(?, ?)" ); |
1689 | stmt= mysql_simple_prepare(mysql, query); |
1690 | check_stmt(stmt); |
1691 | |
1692 | verify_param_count(stmt, 2); |
1693 | |
1694 | /* Always bzero all members of bind parameter */ |
1695 | bzero((char*) my_bind, sizeof(my_bind)); |
1696 | |
1697 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
1698 | my_bind[0].is_null= &is_null[0]; |
1699 | is_null[0]= 1; |
1700 | my_bind[1]= my_bind[0]; |
1701 | |
1702 | rc= mysql_stmt_bind_param(stmt, my_bind); |
1703 | check_execute(stmt, rc); |
1704 | |
1705 | /* now, execute the prepared statement to insert 10 records.. */ |
1706 | for (nData= 0; nData<10; nData++) |
1707 | { |
1708 | rc= mysql_stmt_execute(stmt); |
1709 | check_execute(stmt, rc); |
1710 | } |
1711 | |
1712 | /* Re-bind with MYSQL_TYPE_NULL */ |
1713 | my_bind[0].buffer_type= MYSQL_TYPE_NULL; |
1714 | is_null[0]= 0; /* reset */ |
1715 | my_bind[1]= my_bind[0]; |
1716 | |
1717 | rc= mysql_stmt_bind_param(stmt, my_bind); |
1718 | check_execute(stmt, rc); |
1719 | |
1720 | for (nData= 0; nData<10; nData++) |
1721 | { |
1722 | rc= mysql_stmt_execute(stmt); |
1723 | check_execute(stmt, rc); |
1724 | } |
1725 | |
1726 | mysql_stmt_close(stmt); |
1727 | |
1728 | /* now fetch the results ..*/ |
1729 | rc= mysql_commit(mysql); |
1730 | myquery(rc); |
1731 | |
1732 | nData*= 2; |
1733 | rc= my_stmt_result("SELECT * FROM test_null" );; |
1734 | DIE_UNLESS((int) nData == rc); |
1735 | |
1736 | /* Fetch results */ |
1737 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
1738 | my_bind[0].buffer= (void *)&nData; /* this buffer won't be altered */ |
1739 | my_bind[0].length= 0; |
1740 | my_bind[1]= my_bind[0]; |
1741 | my_bind[0].is_null= &is_null[0]; |
1742 | my_bind[1].is_null= &is_null[1]; |
1743 | |
1744 | stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_null" ); |
1745 | check_stmt(stmt); |
1746 | |
1747 | rc= mysql_stmt_execute(stmt); |
1748 | check_execute(stmt, rc); |
1749 | |
1750 | rc= mysql_stmt_bind_result(stmt, my_bind); |
1751 | check_execute(stmt, rc); |
1752 | |
1753 | rc= 0; |
1754 | is_null[0]= is_null[1]= 0; |
1755 | while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA) |
1756 | { |
1757 | DIE_UNLESS(is_null[0]); |
1758 | DIE_UNLESS(is_null[1]); |
1759 | rc++; |
1760 | is_null[0]= is_null[1]= 0; |
1761 | } |
1762 | DIE_UNLESS(rc == (int) nData); |
1763 | mysql_stmt_close(stmt); |
1764 | } |
1765 | |
1766 | |
1767 | /* Test for NULL as PS parameter (BUG#3367, BUG#3371) */ |
1768 | |
1769 | static void test_ps_null_param() |
1770 | { |
1771 | MYSQL_STMT *stmt; |
1772 | int rc; |
1773 | |
1774 | MYSQL_BIND in_bind; |
1775 | my_bool in_is_null; |
1776 | long int in_long; |
1777 | |
1778 | MYSQL_BIND out_bind; |
1779 | ulong out_length; |
1780 | my_bool out_is_null; |
1781 | char out_str_data[20]; |
1782 | |
1783 | const char *queries[]= {"select ?" , "select ?+1" , |
1784 | "select col1 from test_ps_nulls where col1 <=> ?" , |
1785 | NULL |
1786 | }; |
1787 | const char **cur_query= queries; |
1788 | |
1789 | myheader("test_null_ps_param_in_result" ); |
1790 | |
1791 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_ps_nulls" ); |
1792 | myquery(rc); |
1793 | |
1794 | rc= mysql_query(mysql, "CREATE TABLE test_ps_nulls(col1 int)" ); |
1795 | myquery(rc); |
1796 | |
1797 | rc= mysql_query(mysql, "INSERT INTO test_ps_nulls values (1), (null)" ); |
1798 | myquery(rc); |
1799 | |
1800 | /* Always bzero all members of bind parameter */ |
1801 | bzero((char*) &in_bind, sizeof(in_bind)); |
1802 | bzero((char*) &out_bind, sizeof(out_bind)); |
1803 | |
1804 | in_bind.buffer_type= MYSQL_TYPE_LONG; |
1805 | in_bind.is_null= &in_is_null; |
1806 | in_bind.length= 0; |
1807 | in_bind.buffer= (void *)&in_long; |
1808 | in_is_null= 1; |
1809 | in_long= 1; |
1810 | |
1811 | out_bind.buffer_type= MYSQL_TYPE_STRING; |
1812 | out_bind.is_null= &out_is_null; |
1813 | out_bind.length= &out_length; |
1814 | out_bind.buffer= out_str_data; |
1815 | out_bind.buffer_length= array_elements(out_str_data); |
1816 | |
1817 | /* Execute several queries, all returning NULL in result. */ |
1818 | for(cur_query= queries; *cur_query; cur_query++) |
1819 | { |
1820 | char query[MAX_TEST_QUERY_LENGTH]; |
1821 | strmov(query, *cur_query); |
1822 | stmt= mysql_simple_prepare(mysql, query); |
1823 | check_stmt(stmt); |
1824 | verify_param_count(stmt, 1); |
1825 | |
1826 | rc= mysql_stmt_bind_param(stmt, &in_bind); |
1827 | check_execute(stmt, rc); |
1828 | rc= mysql_stmt_bind_result(stmt, &out_bind); |
1829 | check_execute(stmt, rc); |
1830 | rc= mysql_stmt_execute(stmt); |
1831 | check_execute(stmt, rc); |
1832 | rc= mysql_stmt_fetch(stmt); |
1833 | DIE_UNLESS(rc != MYSQL_NO_DATA); |
1834 | DIE_UNLESS(out_is_null); |
1835 | rc= mysql_stmt_fetch(stmt); |
1836 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
1837 | mysql_stmt_close(stmt); |
1838 | } |
1839 | } |
1840 | |
1841 | |
1842 | /* Test fetch null */ |
1843 | |
1844 | static void test_fetch_null() |
1845 | { |
1846 | MYSQL_STMT *stmt; |
1847 | int rc; |
1848 | int i, nData; |
1849 | MYSQL_BIND my_bind[11]; |
1850 | ulong length[11]; |
1851 | my_bool is_null[11]; |
1852 | char query[MAX_TEST_QUERY_LENGTH]; |
1853 | |
1854 | myheader("test_fetch_null" ); |
1855 | |
1856 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_fetch_null" ); |
1857 | myquery(rc); |
1858 | |
1859 | rc= mysql_query(mysql, "CREATE TABLE test_fetch_null(" |
1860 | " col1 tinyint, col2 smallint, " |
1861 | " col3 int, col4 bigint, " |
1862 | " col5 float, col6 double, " |
1863 | " col7 date, col8 time, " |
1864 | " col9 varbinary(10), " |
1865 | " col10 varchar(50), " |
1866 | " col11 char(20))" ); |
1867 | myquery(rc); |
1868 | |
1869 | rc= mysql_query(mysql, "INSERT INTO test_fetch_null (col11) " |
1870 | "VALUES (1000), (88), (389789)" ); |
1871 | myquery(rc); |
1872 | |
1873 | rc= mysql_commit(mysql); |
1874 | myquery(rc); |
1875 | |
1876 | /* fetch */ |
1877 | bzero((char*) my_bind, sizeof(my_bind)); |
1878 | for (i= 0; i < (int) array_elements(my_bind); i++) |
1879 | { |
1880 | my_bind[i].buffer_type= MYSQL_TYPE_LONG; |
1881 | my_bind[i].is_null= &is_null[i]; |
1882 | my_bind[i].length= &length[i]; |
1883 | } |
1884 | my_bind[i-1].buffer= (void *)&nData; /* Last column is not null */ |
1885 | |
1886 | strmov((char *)query , "SELECT * FROM test_fetch_null" ); |
1887 | |
1888 | rc= my_stmt_result(query); |
1889 | DIE_UNLESS(rc == 3); |
1890 | |
1891 | stmt= mysql_simple_prepare(mysql, query); |
1892 | check_stmt(stmt); |
1893 | |
1894 | rc= mysql_stmt_bind_result(stmt, my_bind); |
1895 | check_execute(stmt, rc); |
1896 | |
1897 | rc= mysql_stmt_execute(stmt); |
1898 | check_execute(stmt, rc); |
1899 | |
1900 | rc= 0; |
1901 | while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA) |
1902 | { |
1903 | rc++; |
1904 | for (i= 0; i < 10; i++) |
1905 | { |
1906 | if (!opt_silent) |
1907 | fprintf(stdout, "\n data[%d] : %s" , i, |
1908 | is_null[i] ? "NULL" : "NOT NULL" ); |
1909 | DIE_UNLESS(is_null[i]); |
1910 | } |
1911 | if (!opt_silent) |
1912 | fprintf(stdout, "\n data[%d]: %d" , i, nData); |
1913 | DIE_UNLESS(nData == 1000 || nData == 88 || nData == 389789); |
1914 | DIE_UNLESS(is_null[i] == 0); |
1915 | DIE_UNLESS(length[i] == 4); |
1916 | } |
1917 | DIE_UNLESS(rc == 3); |
1918 | mysql_stmt_close(stmt); |
1919 | } |
1920 | |
1921 | |
1922 | /* Test simple select */ |
1923 | |
1924 | static void test_select_version() |
1925 | { |
1926 | MYSQL_STMT *stmt; |
1927 | int rc; |
1928 | |
1929 | myheader("test_select_version" ); |
1930 | |
1931 | stmt= mysql_simple_prepare(mysql, "SELECT @@version" ); |
1932 | check_stmt(stmt); |
1933 | |
1934 | verify_param_count(stmt, 0); |
1935 | |
1936 | rc= mysql_stmt_execute(stmt); |
1937 | check_execute(stmt, rc); |
1938 | |
1939 | my_process_stmt_result(stmt); |
1940 | mysql_stmt_close(stmt); |
1941 | } |
1942 | |
1943 | |
1944 | /* Test simple show */ |
1945 | |
1946 | static void test_select_show_table() |
1947 | { |
1948 | MYSQL_STMT *stmt; |
1949 | int rc, i; |
1950 | |
1951 | myheader("test_select_show_table" ); |
1952 | |
1953 | stmt= mysql_simple_prepare(mysql, "SHOW TABLES FROM mysql" ); |
1954 | check_stmt(stmt); |
1955 | |
1956 | verify_param_count(stmt, 0); |
1957 | |
1958 | for (i= 1; i < 3; i++) |
1959 | { |
1960 | rc= mysql_stmt_execute(stmt); |
1961 | check_execute(stmt, rc); |
1962 | } |
1963 | |
1964 | my_process_stmt_result(stmt); |
1965 | mysql_stmt_close(stmt); |
1966 | } |
1967 | |
1968 | |
1969 | /* Test simple select to debug */ |
1970 | |
1971 | static void test_select_direct() |
1972 | { |
1973 | int rc; |
1974 | MYSQL_RES *result; |
1975 | |
1976 | myheader("test_select_direct" ); |
1977 | |
1978 | rc= mysql_autocommit(mysql, TRUE); |
1979 | myquery(rc); |
1980 | |
1981 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select" ); |
1982 | myquery(rc); |
1983 | |
1984 | rc= mysql_query(mysql, "CREATE TABLE test_select(id int, id1 tinyint, " |
1985 | " id2 float, " |
1986 | " id3 double, " |
1987 | " name varchar(50))" ); |
1988 | myquery(rc); |
1989 | |
1990 | /* insert a row and commit the transaction */ |
1991 | rc= mysql_query(mysql, "INSERT INTO test_select VALUES(10, 5, 2.3, 4.5, 'venu')" ); |
1992 | myquery(rc); |
1993 | |
1994 | rc= mysql_commit(mysql); |
1995 | myquery(rc); |
1996 | |
1997 | rc= mysql_query(mysql, "SELECT * FROM test_select" ); |
1998 | myquery(rc); |
1999 | |
2000 | /* get the result */ |
2001 | result= mysql_store_result(mysql); |
2002 | mytest(result); |
2003 | |
2004 | (void) my_process_result_set(result); |
2005 | mysql_free_result(result); |
2006 | } |
2007 | |
2008 | |
2009 | /* Test simple select with prepare */ |
2010 | |
2011 | static void test_select_prepare() |
2012 | { |
2013 | int rc; |
2014 | MYSQL_STMT *stmt; |
2015 | |
2016 | myheader("test_select_prepare" ); |
2017 | |
2018 | rc= mysql_autocommit(mysql, TRUE); |
2019 | myquery(rc); |
2020 | |
2021 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select" ); |
2022 | myquery(rc); |
2023 | |
2024 | rc= mysql_query(mysql, "CREATE TABLE test_select(id int, name varchar(50))" ); |
2025 | myquery(rc); |
2026 | |
2027 | /* insert a row and commit the transaction */ |
2028 | rc= mysql_query(mysql, "INSERT INTO test_select VALUES(10, 'venu')" ); |
2029 | myquery(rc); |
2030 | |
2031 | rc= mysql_commit(mysql); |
2032 | myquery(rc); |
2033 | |
2034 | stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_select" ); |
2035 | check_stmt(stmt); |
2036 | |
2037 | rc= mysql_stmt_execute(stmt); |
2038 | check_execute(stmt, rc); |
2039 | |
2040 | rc= my_process_stmt_result(stmt); |
2041 | DIE_UNLESS(rc == 1); |
2042 | mysql_stmt_close(stmt); |
2043 | |
2044 | rc= mysql_query(mysql, "DROP TABLE test_select" ); |
2045 | myquery(rc); |
2046 | |
2047 | rc= mysql_query(mysql, "CREATE TABLE test_select(id tinyint, id1 int, " |
2048 | " id2 float, id3 float, " |
2049 | " name varchar(50))" ); |
2050 | myquery(rc); |
2051 | |
2052 | /* insert a row and commit the transaction */ |
2053 | rc= mysql_query(mysql, "INSERT INTO test_select(id, id1, id2, name) VALUES(10, 5, 2.3, 'venu')" ); |
2054 | myquery(rc); |
2055 | |
2056 | rc= mysql_commit(mysql); |
2057 | myquery(rc); |
2058 | |
2059 | stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_select" ); |
2060 | check_stmt(stmt); |
2061 | |
2062 | rc= mysql_stmt_execute(stmt); |
2063 | check_execute(stmt, rc); |
2064 | |
2065 | rc= my_process_stmt_result(stmt); |
2066 | DIE_UNLESS(rc == 1); |
2067 | mysql_stmt_close(stmt); |
2068 | } |
2069 | |
2070 | |
2071 | /* Test simple select */ |
2072 | |
2073 | static void test_select() |
2074 | { |
2075 | MYSQL_STMT *stmt; |
2076 | int rc; |
2077 | char szData[25]; |
2078 | int nData= 1; |
2079 | MYSQL_BIND my_bind[2]; |
2080 | ulong length[2]; |
2081 | char query[MAX_TEST_QUERY_LENGTH]; |
2082 | |
2083 | myheader("test_select" ); |
2084 | |
2085 | rc= mysql_autocommit(mysql, TRUE); |
2086 | myquery(rc); |
2087 | |
2088 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select" ); |
2089 | myquery(rc); |
2090 | |
2091 | rc= mysql_query(mysql, "CREATE TABLE test_select(id int, name varchar(50))" ); |
2092 | myquery(rc); |
2093 | |
2094 | /* insert a row and commit the transaction */ |
2095 | rc= mysql_query(mysql, "INSERT INTO test_select VALUES(10, 'venu')" ); |
2096 | myquery(rc); |
2097 | |
2098 | /* now insert the second row, and roll back the transaction */ |
2099 | rc= mysql_query(mysql, "INSERT INTO test_select VALUES(20, 'mysql')" ); |
2100 | myquery(rc); |
2101 | |
2102 | rc= mysql_commit(mysql); |
2103 | myquery(rc); |
2104 | |
2105 | strmov(query, "SELECT * FROM test_select WHERE id= ? " |
2106 | "AND CONVERT(name USING utf8) =?" ); |
2107 | stmt= mysql_simple_prepare(mysql, query); |
2108 | check_stmt(stmt); |
2109 | |
2110 | verify_param_count(stmt, 2); |
2111 | |
2112 | /* Always bzero all members of bind parameter */ |
2113 | bzero((char*) my_bind, sizeof(my_bind)); |
2114 | |
2115 | /* string data */ |
2116 | nData= 10; |
2117 | strmov(szData, (char *)"venu" ); |
2118 | my_bind[1].buffer_type= MYSQL_TYPE_STRING; |
2119 | my_bind[1].buffer= (void *)szData; |
2120 | my_bind[1].buffer_length= 4; |
2121 | my_bind[1].length= &length[1]; |
2122 | length[1]= 4; |
2123 | |
2124 | my_bind[0].buffer= (void *)&nData; |
2125 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
2126 | |
2127 | rc= mysql_stmt_bind_param(stmt, my_bind); |
2128 | check_execute(stmt, rc); |
2129 | |
2130 | rc= mysql_stmt_execute(stmt); |
2131 | check_execute(stmt, rc); |
2132 | |
2133 | rc= my_process_stmt_result(stmt); |
2134 | DIE_UNLESS(rc == 1); |
2135 | |
2136 | mysql_stmt_close(stmt); |
2137 | } |
2138 | |
2139 | |
2140 | /* |
2141 | Test for BUG#3420 ("select id1, value1 from t where id= ? or value= ?" |
2142 | returns all rows in the table) |
2143 | */ |
2144 | |
2145 | static void test_ps_conj_select() |
2146 | { |
2147 | MYSQL_STMT *stmt; |
2148 | int rc; |
2149 | MYSQL_BIND my_bind[2]; |
2150 | int32 int_data; |
2151 | char str_data[32]; |
2152 | unsigned long str_length; |
2153 | char query[MAX_TEST_QUERY_LENGTH]; |
2154 | myheader("test_ps_conj_select" ); |
2155 | |
2156 | rc= mysql_query(mysql, "drop table if exists t1" ); |
2157 | myquery(rc); |
2158 | |
2159 | rc= mysql_query(mysql, "create table t1 (id1 int(11) NOT NULL default '0', " |
2160 | "value2 varchar(100), value1 varchar(100))" ); |
2161 | myquery(rc); |
2162 | |
2163 | rc= mysql_query(mysql, "insert into t1 values (1, 'hh', 'hh'), " |
2164 | "(2, 'hh', 'hh'), (1, 'ii', 'ii'), (2, 'ii', 'ii')" ); |
2165 | myquery(rc); |
2166 | |
2167 | strmov(query, "SELECT id1, value1 from t1 where id1= ? or " |
2168 | "CONVERT(value1 USING utf8)= ?" ); |
2169 | stmt= mysql_simple_prepare(mysql, query); |
2170 | check_stmt(stmt); |
2171 | |
2172 | verify_param_count(stmt, 2); |
2173 | |
2174 | /* Always bzero all members of bind parameter */ |
2175 | bzero((char*) my_bind, sizeof(my_bind)); |
2176 | |
2177 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
2178 | my_bind[0].buffer= (void *)&int_data; |
2179 | |
2180 | my_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING; |
2181 | my_bind[1].buffer= (void *)str_data; |
2182 | my_bind[1].buffer_length= array_elements(str_data); |
2183 | my_bind[1].length= &str_length; |
2184 | |
2185 | rc= mysql_stmt_bind_param(stmt, my_bind); |
2186 | check_execute(stmt, rc); |
2187 | |
2188 | int_data= 1; |
2189 | strmov(str_data, "hh" ); |
2190 | str_length= strlen(str_data); |
2191 | |
2192 | rc= mysql_stmt_execute(stmt); |
2193 | check_execute(stmt, rc); |
2194 | |
2195 | rc= my_process_stmt_result(stmt); |
2196 | DIE_UNLESS(rc == 3); |
2197 | |
2198 | mysql_stmt_close(stmt); |
2199 | } |
2200 | |
2201 | |
2202 | /* reads Qcache_hits from server and returns its value */ |
2203 | static uint query_cache_hits(MYSQL *conn) |
2204 | { |
2205 | MYSQL_RES *res; |
2206 | MYSQL_ROW row; |
2207 | int rc; |
2208 | uint result; |
2209 | |
2210 | rc= mysql_query(conn, "show status like 'qcache_hits'" ); |
2211 | myquery(rc); |
2212 | res= mysql_use_result(conn); |
2213 | DIE_UNLESS(res); |
2214 | |
2215 | row= mysql_fetch_row(res); |
2216 | DIE_UNLESS(row); |
2217 | |
2218 | result= atoi(row[1]); |
2219 | mysql_free_result(res); |
2220 | return result; |
2221 | } |
2222 | |
2223 | |
2224 | /* |
2225 | utility for the next test; expects 3 rows in the result from a SELECT, |
2226 | compares each row/field with an expected value. |
2227 | */ |
2228 | #define test_ps_query_cache_result(i1,s1,l1,i2,s2,l2,i3,s3,l3) \ |
2229 | r_metadata= mysql_stmt_result_metadata(stmt); \ |
2230 | DIE_UNLESS(r_metadata != NULL); \ |
2231 | rc= mysql_stmt_fetch(stmt); \ |
2232 | check_execute(stmt, rc); \ |
2233 | if (!opt_silent) \ |
2234 | fprintf(stdout, "\n row 1: %d, %s(%lu)", r_int_data, \ |
2235 | r_str_data, r_str_length); \ |
2236 | DIE_UNLESS((r_int_data == i1) && (r_str_length == l1) && \ |
2237 | (strcmp(r_str_data, s1) == 0)); \ |
2238 | rc= mysql_stmt_fetch(stmt); \ |
2239 | check_execute(stmt, rc); \ |
2240 | if (!opt_silent) \ |
2241 | fprintf(stdout, "\n row 2: %d, %s(%lu)", r_int_data, \ |
2242 | r_str_data, r_str_length); \ |
2243 | DIE_UNLESS((r_int_data == i2) && (r_str_length == l2) && \ |
2244 | (strcmp(r_str_data, s2) == 0)); \ |
2245 | rc= mysql_stmt_fetch(stmt); \ |
2246 | check_execute(stmt, rc); \ |
2247 | if (!opt_silent) \ |
2248 | fprintf(stdout, "\n row 3: %d, %s(%lu)", r_int_data, \ |
2249 | r_str_data, r_str_length); \ |
2250 | DIE_UNLESS((r_int_data == i3) && (r_str_length == l3) && \ |
2251 | (strcmp(r_str_data, s3) == 0)); \ |
2252 | rc= mysql_stmt_fetch(stmt); \ |
2253 | DIE_UNLESS(rc == MYSQL_NO_DATA); \ |
2254 | mysql_free_result(r_metadata); |
2255 | |
2256 | |
2257 | /* |
2258 | Check that query cache is available in server. |
2259 | */ |
2260 | static my_bool is_query_cache_available() |
2261 | { |
2262 | int rc; |
2263 | MYSQL_RES *result; |
2264 | MYSQL_ROW row; |
2265 | int res= -1; |
2266 | |
2267 | rc= mysql_query(mysql, "SHOW VARIABLES LIKE 'have_query_cache'" ); |
2268 | myquery(rc); |
2269 | |
2270 | result= mysql_store_result(mysql); |
2271 | DIE_UNLESS(result); |
2272 | |
2273 | row= mysql_fetch_row(result); |
2274 | DIE_UNLESS(row != NULL); |
2275 | if (strcmp(row[1], "YES" ) == 0) |
2276 | res= 1; |
2277 | else if (strcmp(row[1], "NO" ) == 0) |
2278 | res= 0; |
2279 | mysql_free_result(result); |
2280 | |
2281 | DIE_UNLESS(res == 0 || res == 1); |
2282 | return res; |
2283 | } |
2284 | |
2285 | /* |
2286 | Test that prepared statements make use of the query cache just as normal |
2287 | statements (BUG#735). |
2288 | */ |
2289 | static void test_ps_query_cache() |
2290 | { |
2291 | MYSQL *lmysql= mysql; |
2292 | MYSQL_STMT *stmt; |
2293 | int rc; |
2294 | MYSQL_BIND p_bind[2],r_bind[2]; /* p: param bind; r: result bind */ |
2295 | int32 p_int_data, r_int_data; |
2296 | char p_str_data[32], r_str_data[32]; |
2297 | unsigned long p_str_length, r_str_length; |
2298 | MYSQL_RES *r_metadata; |
2299 | char query[MAX_TEST_QUERY_LENGTH]; |
2300 | uint hits1, hits2; |
2301 | enum enum_test_ps_query_cache |
2302 | { |
2303 | /* |
2304 | We iterate the same prepare/executes block, but have iterations where |
2305 | we vary the query cache conditions. |
2306 | */ |
2307 | /* the query cache is enabled for the duration of prep&execs: */ |
2308 | TEST_QCACHE_ON= 0, |
2309 | /* |
2310 | same but using a new connection (to see if qcache serves results from |
2311 | the previous connection as it should): |
2312 | */ |
2313 | TEST_QCACHE_ON_WITH_OTHER_CONN, |
2314 | /* |
2315 | First border case: disables the query cache before prepare and |
2316 | re-enables it before execution (to test if we have no bug then): |
2317 | */ |
2318 | TEST_QCACHE_OFF_ON, |
2319 | /* |
2320 | Second border case: enables the query cache before prepare and |
2321 | disables it before execution: |
2322 | */ |
2323 | TEST_QCACHE_ON_OFF |
2324 | }; |
2325 | enum enum_test_ps_query_cache iteration; |
2326 | |
2327 | myheader("test_ps_query_cache" ); |
2328 | |
2329 | if (! is_query_cache_available()) |
2330 | { |
2331 | fprintf(stdout, "Skipping test_ps_query_cache: Query cache not available.\n" ); |
2332 | return; |
2333 | } |
2334 | |
2335 | rc= mysql_set_character_set(mysql, "utf8" ); |
2336 | myquery(rc); |
2337 | |
2338 | /* prepare the table */ |
2339 | |
2340 | rc= mysql_query(mysql, "drop table if exists t1" ); |
2341 | myquery(rc); |
2342 | |
2343 | rc= mysql_query(mysql, "create table t1 (id1 int(11) NOT NULL default '0', " |
2344 | "value2 varchar(100), value1 varchar(100))" ); |
2345 | myquery(rc); |
2346 | |
2347 | rc= mysql_query(mysql, "insert into t1 values (1, 'hh', 'hh'), " |
2348 | "(2, 'hh', 'hh'), (1, 'ii', 'ii'), (2, 'ii', 'ii')" ); |
2349 | myquery(rc); |
2350 | |
2351 | rc= mysql_query(lmysql, "set global query_cache_type=ON" ); |
2352 | myquery(rc); |
2353 | rc= mysql_query(lmysql, "set local query_cache_type=ON" ); |
2354 | myquery(rc); |
2355 | |
2356 | for (iteration= TEST_QCACHE_ON; iteration <= TEST_QCACHE_ON_OFF; iteration++) |
2357 | { |
2358 | |
2359 | switch (iteration) { |
2360 | case TEST_QCACHE_ON: |
2361 | case TEST_QCACHE_ON_OFF: |
2362 | rc= mysql_query(lmysql, "set global query_cache_size=1000000" ); |
2363 | myquery(rc); |
2364 | break; |
2365 | case TEST_QCACHE_OFF_ON: |
2366 | rc= mysql_query(lmysql, "set global query_cache_size=0" ); |
2367 | myquery(rc); |
2368 | break; |
2369 | case TEST_QCACHE_ON_WITH_OTHER_CONN: |
2370 | if (!opt_silent) |
2371 | fprintf(stdout, "\n Establishing a test connection ..." ); |
2372 | if (!(lmysql= mysql_client_init(NULL))) |
2373 | { |
2374 | printf("mysql_client_init() failed" ); |
2375 | DIE_UNLESS(0); |
2376 | } |
2377 | if (!(mysql_real_connect(lmysql, opt_host, opt_user, |
2378 | opt_password, current_db, opt_port, |
2379 | opt_unix_socket, 0))) |
2380 | { |
2381 | printf("connection failed" ); |
2382 | mysql_close(lmysql); |
2383 | DIE_UNLESS(0); |
2384 | } |
2385 | rc= mysql_query(lmysql, "SET SQL_MODE=''" ); |
2386 | myquery(rc); |
2387 | rc= mysql_set_character_set(lmysql, "utf8" ); |
2388 | myquery(rc); |
2389 | |
2390 | if (!opt_silent) |
2391 | fprintf(stdout, "OK" ); |
2392 | break; |
2393 | } |
2394 | |
2395 | strmov(query, "select id1, value1 from t1 where id1= ? or " |
2396 | "CONVERT(value1 USING utf8)= ?" ); |
2397 | stmt= mysql_simple_prepare(lmysql, query); |
2398 | check_stmt(stmt); |
2399 | |
2400 | verify_param_count(stmt, 2); |
2401 | |
2402 | switch (iteration) { |
2403 | case TEST_QCACHE_OFF_ON: |
2404 | rc= mysql_query(lmysql, "set global query_cache_size=1000000" ); |
2405 | myquery(rc); |
2406 | break; |
2407 | case TEST_QCACHE_ON_OFF: |
2408 | rc= mysql_query(lmysql, "set global query_cache_size=0" ); |
2409 | myquery(rc); |
2410 | default: |
2411 | break; |
2412 | } |
2413 | |
2414 | bzero((char*) p_bind, sizeof(p_bind)); |
2415 | p_bind[0].buffer_type= MYSQL_TYPE_LONG; |
2416 | p_bind[0].buffer= (void *)&p_int_data; |
2417 | p_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING; |
2418 | p_bind[1].buffer= (void *)p_str_data; |
2419 | p_bind[1].buffer_length= array_elements(p_str_data); |
2420 | p_bind[1].length= &p_str_length; |
2421 | |
2422 | rc= mysql_stmt_bind_param(stmt, p_bind); |
2423 | check_execute(stmt, rc); |
2424 | |
2425 | p_int_data= 1; |
2426 | strmov(p_str_data, "hh" ); |
2427 | p_str_length= strlen(p_str_data); |
2428 | |
2429 | bzero((char*) r_bind, sizeof(r_bind)); |
2430 | r_bind[0].buffer_type= MYSQL_TYPE_LONG; |
2431 | r_bind[0].buffer= (void *)&r_int_data; |
2432 | r_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING; |
2433 | r_bind[1].buffer= (void *)r_str_data; |
2434 | r_bind[1].buffer_length= array_elements(r_str_data); |
2435 | r_bind[1].length= &r_str_length; |
2436 | |
2437 | rc= mysql_stmt_bind_result(stmt, r_bind); |
2438 | check_execute(stmt, rc); |
2439 | |
2440 | rc= mysql_stmt_execute(stmt); |
2441 | check_execute(stmt, rc); |
2442 | |
2443 | test_ps_query_cache_result(1, "hh" , 2, 2, "hh" , 2, 1, "ii" , 2); |
2444 | |
2445 | /* now retry with the same parameter values and see qcache hits */ |
2446 | hits1= query_cache_hits(lmysql); |
2447 | rc= mysql_stmt_execute(stmt); |
2448 | check_execute(stmt, rc); |
2449 | test_ps_query_cache_result(1, "hh" , 2, 2, "hh" , 2, 1, "ii" , 2); |
2450 | hits2= query_cache_hits(lmysql); |
2451 | switch(iteration) { |
2452 | case TEST_QCACHE_ON_WITH_OTHER_CONN: |
2453 | case TEST_QCACHE_ON: /* should have hit */ |
2454 | DIE_UNLESS(hits2-hits1 == 1); |
2455 | break; |
2456 | case TEST_QCACHE_OFF_ON: |
2457 | case TEST_QCACHE_ON_OFF: /* should not have hit */ |
2458 | DIE_UNLESS(hits2-hits1 == 0); |
2459 | break; |
2460 | } |
2461 | |
2462 | /* now modify parameter values and see qcache hits */ |
2463 | strmov(p_str_data, "ii" ); |
2464 | p_str_length= strlen(p_str_data); |
2465 | rc= mysql_stmt_execute(stmt); |
2466 | check_execute(stmt, rc); |
2467 | test_ps_query_cache_result(1, "hh" , 2, 1, "ii" , 2, 2, "ii" , 2); |
2468 | hits1= query_cache_hits(lmysql); |
2469 | |
2470 | switch(iteration) { |
2471 | case TEST_QCACHE_ON: |
2472 | case TEST_QCACHE_OFF_ON: |
2473 | case TEST_QCACHE_ON_OFF: /* should not have hit */ |
2474 | DIE_UNLESS(hits2-hits1 == 0); |
2475 | break; |
2476 | case TEST_QCACHE_ON_WITH_OTHER_CONN: /* should have hit */ |
2477 | DIE_UNLESS(hits1-hits2 == 1); |
2478 | break; |
2479 | } |
2480 | |
2481 | rc= mysql_stmt_execute(stmt); |
2482 | check_execute(stmt, rc); |
2483 | |
2484 | test_ps_query_cache_result(1, "hh" , 2, 1, "ii" , 2, 2, "ii" , 2); |
2485 | hits2= query_cache_hits(lmysql); |
2486 | |
2487 | mysql_stmt_close(stmt); |
2488 | |
2489 | switch(iteration) { |
2490 | case TEST_QCACHE_ON: /* should have hit */ |
2491 | DIE_UNLESS(hits2-hits1 == 1); |
2492 | break; |
2493 | case TEST_QCACHE_OFF_ON: |
2494 | case TEST_QCACHE_ON_OFF: /* should not have hit */ |
2495 | DIE_UNLESS(hits2-hits1 == 0); |
2496 | break; |
2497 | case TEST_QCACHE_ON_WITH_OTHER_CONN: /* should have hit */ |
2498 | DIE_UNLESS(hits2-hits1 == 1); |
2499 | break; |
2500 | } |
2501 | |
2502 | } /* for(iteration=...) */ |
2503 | |
2504 | if (lmysql != mysql) |
2505 | mysql_close(lmysql); |
2506 | |
2507 | rc= mysql_query(mysql, "set global query_cache_size=default" ); |
2508 | myquery(rc); |
2509 | rc= mysql_query(mysql, "set global query_cache_type=default" ); |
2510 | myquery(rc); |
2511 | } |
2512 | |
2513 | |
2514 | /* Test BUG#1115 (incorrect string parameter value allocation) */ |
2515 | |
2516 | static void test_bug1115() |
2517 | { |
2518 | MYSQL_STMT *stmt; |
2519 | int rc; |
2520 | MYSQL_BIND my_bind[1]; |
2521 | ulong length[1]; |
2522 | char szData[11]; |
2523 | char query[MAX_TEST_QUERY_LENGTH]; |
2524 | |
2525 | myheader("test_bug1115" ); |
2526 | |
2527 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select" ); |
2528 | myquery(rc); |
2529 | |
2530 | rc= mysql_query(mysql, "CREATE TABLE test_select(\ |
2531 | session_id char(9) NOT NULL, \ |
2532 | a int(8) unsigned NOT NULL, \ |
2533 | b int(5) NOT NULL, \ |
2534 | c int(5) NOT NULL, \ |
2535 | d datetime NOT NULL)" ); |
2536 | myquery(rc); |
2537 | rc= mysql_query(mysql, "INSERT INTO test_select VALUES " |
2538 | "(\"abc\", 1, 2, 3, 2003-08-30), " |
2539 | "(\"abd\", 1, 2, 3, 2003-08-30), " |
2540 | "(\"abf\", 1, 2, 3, 2003-08-30), " |
2541 | "(\"abg\", 1, 2, 3, 2003-08-30), " |
2542 | "(\"abh\", 1, 2, 3, 2003-08-30), " |
2543 | "(\"abj\", 1, 2, 3, 2003-08-30), " |
2544 | "(\"abk\", 1, 2, 3, 2003-08-30), " |
2545 | "(\"abl\", 1, 2, 3, 2003-08-30), " |
2546 | "(\"abq\", 1, 2, 3, 2003-08-30) " ); |
2547 | myquery(rc); |
2548 | rc= mysql_query(mysql, "INSERT INTO test_select VALUES " |
2549 | "(\"abw\", 1, 2, 3, 2003-08-30), " |
2550 | "(\"abe\", 1, 2, 3, 2003-08-30), " |
2551 | "(\"abr\", 1, 2, 3, 2003-08-30), " |
2552 | "(\"abt\", 1, 2, 3, 2003-08-30), " |
2553 | "(\"aby\", 1, 2, 3, 2003-08-30), " |
2554 | "(\"abu\", 1, 2, 3, 2003-08-30), " |
2555 | "(\"abi\", 1, 2, 3, 2003-08-30), " |
2556 | "(\"abo\", 1, 2, 3, 2003-08-30), " |
2557 | "(\"abp\", 1, 2, 3, 2003-08-30), " |
2558 | "(\"abz\", 1, 2, 3, 2003-08-30), " |
2559 | "(\"abx\", 1, 2, 3, 2003-08-30)" ); |
2560 | myquery(rc); |
2561 | |
2562 | strmov(query, "SELECT * FROM test_select WHERE " |
2563 | "CONVERT(session_id USING utf8)= ?" ); |
2564 | stmt= mysql_simple_prepare(mysql, query); |
2565 | check_stmt(stmt); |
2566 | |
2567 | verify_param_count(stmt, 1); |
2568 | |
2569 | /* Always bzero all members of bind parameter */ |
2570 | bzero((char*) my_bind, sizeof(my_bind)); |
2571 | |
2572 | strmov(szData, (char *)"abc" ); |
2573 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
2574 | my_bind[0].buffer= (void *)szData; |
2575 | my_bind[0].buffer_length= 10; |
2576 | my_bind[0].length= &length[0]; |
2577 | length[0]= 3; |
2578 | |
2579 | rc= mysql_stmt_bind_param(stmt, my_bind); |
2580 | check_execute(stmt, rc); |
2581 | |
2582 | rc= mysql_stmt_execute(stmt); |
2583 | check_execute(stmt, rc); |
2584 | |
2585 | rc= my_process_stmt_result(stmt); |
2586 | DIE_UNLESS(rc == 1); |
2587 | |
2588 | strmov(szData, (char *)"venu" ); |
2589 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
2590 | my_bind[0].buffer= (void *)szData; |
2591 | my_bind[0].buffer_length= 10; |
2592 | my_bind[0].length= &length[0]; |
2593 | length[0]= 4; |
2594 | my_bind[0].is_null= 0; |
2595 | |
2596 | rc= mysql_stmt_bind_param(stmt, my_bind); |
2597 | check_execute(stmt, rc); |
2598 | |
2599 | rc= mysql_stmt_execute(stmt); |
2600 | check_execute(stmt, rc); |
2601 | |
2602 | rc= my_process_stmt_result(stmt); |
2603 | DIE_UNLESS(rc == 0); |
2604 | |
2605 | strmov(szData, (char *)"abc" ); |
2606 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
2607 | my_bind[0].buffer= (void *)szData; |
2608 | my_bind[0].buffer_length= 10; |
2609 | my_bind[0].length= &length[0]; |
2610 | length[0]= 3; |
2611 | my_bind[0].is_null= 0; |
2612 | |
2613 | rc= mysql_stmt_bind_param(stmt, my_bind); |
2614 | check_execute(stmt, rc); |
2615 | |
2616 | rc= mysql_stmt_execute(stmt); |
2617 | check_execute(stmt, rc); |
2618 | |
2619 | rc= my_process_stmt_result(stmt); |
2620 | DIE_UNLESS(rc == 1); |
2621 | |
2622 | mysql_stmt_close(stmt); |
2623 | } |
2624 | |
2625 | |
2626 | /* Test BUG#1180 (optimized away part of WHERE clause) */ |
2627 | |
2628 | static void test_bug1180() |
2629 | { |
2630 | MYSQL_STMT *stmt; |
2631 | int rc; |
2632 | MYSQL_BIND my_bind[1]; |
2633 | ulong length[1]; |
2634 | char szData[11]; |
2635 | char query[MAX_TEST_QUERY_LENGTH]; |
2636 | |
2637 | myheader("test_select_bug" ); |
2638 | |
2639 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select" ); |
2640 | myquery(rc); |
2641 | |
2642 | rc= mysql_query(mysql, "CREATE TABLE test_select(session_id char(9) NOT NULL)" ); |
2643 | myquery(rc); |
2644 | rc= mysql_query(mysql, "INSERT INTO test_select VALUES (\"abc\")" ); |
2645 | myquery(rc); |
2646 | |
2647 | strmov(query, "SELECT * FROM test_select WHERE ?= \"1111\" and " |
2648 | "session_id= \"abc\"" ); |
2649 | stmt= mysql_simple_prepare(mysql, query); |
2650 | check_stmt(stmt); |
2651 | |
2652 | verify_param_count(stmt, 1); |
2653 | |
2654 | /* Always bzero all members of bind parameter */ |
2655 | bzero((char*) my_bind, sizeof(my_bind)); |
2656 | |
2657 | strmov(szData, (char *)"abc" ); |
2658 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
2659 | my_bind[0].buffer= (void *)szData; |
2660 | my_bind[0].buffer_length= 10; |
2661 | my_bind[0].length= &length[0]; |
2662 | length[0]= 3; |
2663 | my_bind[0].is_null= 0; |
2664 | |
2665 | rc= mysql_stmt_bind_param(stmt, my_bind); |
2666 | check_execute(stmt, rc); |
2667 | |
2668 | rc= mysql_stmt_execute(stmt); |
2669 | check_execute(stmt, rc); |
2670 | |
2671 | rc= my_process_stmt_result(stmt); |
2672 | DIE_UNLESS(rc == 0); |
2673 | |
2674 | strmov(szData, (char *)"1111" ); |
2675 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
2676 | my_bind[0].buffer= (void *)szData; |
2677 | my_bind[0].buffer_length= 10; |
2678 | my_bind[0].length= &length[0]; |
2679 | length[0]= 4; |
2680 | my_bind[0].is_null= 0; |
2681 | |
2682 | rc= mysql_stmt_bind_param(stmt, my_bind); |
2683 | check_execute(stmt, rc); |
2684 | |
2685 | rc= mysql_stmt_execute(stmt); |
2686 | check_execute(stmt, rc); |
2687 | |
2688 | rc= my_process_stmt_result(stmt); |
2689 | DIE_UNLESS(rc == 1); |
2690 | |
2691 | strmov(szData, (char *)"abc" ); |
2692 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
2693 | my_bind[0].buffer= (void *)szData; |
2694 | my_bind[0].buffer_length= 10; |
2695 | my_bind[0].length= &length[0]; |
2696 | length[0]= 3; |
2697 | my_bind[0].is_null= 0; |
2698 | |
2699 | rc= mysql_stmt_bind_param(stmt, my_bind); |
2700 | check_execute(stmt, rc); |
2701 | |
2702 | rc= mysql_stmt_execute(stmt); |
2703 | check_execute(stmt, rc); |
2704 | |
2705 | rc= my_process_stmt_result(stmt); |
2706 | DIE_UNLESS(rc == 0); |
2707 | |
2708 | mysql_stmt_close(stmt); |
2709 | } |
2710 | |
2711 | |
2712 | /* |
2713 | Test BUG#1644 (Insertion of more than 3 NULL columns with parameter |
2714 | binding fails) |
2715 | */ |
2716 | |
2717 | static void test_bug1644() |
2718 | { |
2719 | MYSQL_STMT *stmt; |
2720 | MYSQL_RES *result; |
2721 | MYSQL_ROW row; |
2722 | MYSQL_BIND my_bind[4]; |
2723 | int num; |
2724 | my_bool isnull; |
2725 | int rc, i; |
2726 | char query[MAX_TEST_QUERY_LENGTH]; |
2727 | |
2728 | myheader("test_bug1644" ); |
2729 | |
2730 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS foo_dfr" ); |
2731 | myquery(rc); |
2732 | |
2733 | rc= mysql_query(mysql, |
2734 | "CREATE TABLE foo_dfr(col1 int, col2 int, col3 int, col4 int);" ); |
2735 | myquery(rc); |
2736 | |
2737 | strmov(query, "INSERT INTO foo_dfr VALUES (?, ?, ?, ? )" ); |
2738 | stmt= mysql_simple_prepare(mysql, query); |
2739 | check_stmt(stmt); |
2740 | |
2741 | verify_param_count(stmt, 4); |
2742 | |
2743 | /* Always bzero all members of bind parameter */ |
2744 | bzero((char*) my_bind, sizeof(my_bind)); |
2745 | |
2746 | num= 22; |
2747 | isnull= 0; |
2748 | for (i= 0 ; i < 4 ; i++) |
2749 | { |
2750 | my_bind[i].buffer_type= MYSQL_TYPE_LONG; |
2751 | my_bind[i].buffer= (void *)# |
2752 | my_bind[i].is_null= &isnull; |
2753 | } |
2754 | |
2755 | rc= mysql_stmt_bind_param(stmt, my_bind); |
2756 | check_execute(stmt, rc); |
2757 | |
2758 | rc= mysql_stmt_execute(stmt); |
2759 | check_execute(stmt, rc); |
2760 | |
2761 | isnull= 1; |
2762 | for (i= 0 ; i < 4 ; i++) |
2763 | my_bind[i].is_null= &isnull; |
2764 | |
2765 | rc= mysql_stmt_bind_param(stmt, my_bind); |
2766 | check_execute(stmt, rc); |
2767 | |
2768 | rc= mysql_stmt_execute(stmt); |
2769 | check_execute(stmt, rc); |
2770 | |
2771 | isnull= 0; |
2772 | num= 88; |
2773 | for (i= 0 ; i < 4 ; i++) |
2774 | my_bind[i].is_null= &isnull; |
2775 | |
2776 | rc= mysql_stmt_bind_param(stmt, my_bind); |
2777 | check_execute(stmt, rc); |
2778 | |
2779 | rc= mysql_stmt_execute(stmt); |
2780 | check_execute(stmt, rc); |
2781 | |
2782 | mysql_stmt_close(stmt); |
2783 | |
2784 | rc= mysql_query(mysql, "SELECT * FROM foo_dfr" ); |
2785 | myquery(rc); |
2786 | |
2787 | result= mysql_store_result(mysql); |
2788 | mytest(result); |
2789 | |
2790 | rc= my_process_result_set(result); |
2791 | DIE_UNLESS(rc == 3); |
2792 | |
2793 | mysql_data_seek(result, 0); |
2794 | |
2795 | row= mysql_fetch_row(result); |
2796 | mytest(row); |
2797 | for (i= 0 ; i < 4 ; i++) |
2798 | { |
2799 | DIE_UNLESS(strcmp(row[i], "22" ) == 0); |
2800 | } |
2801 | row= mysql_fetch_row(result); |
2802 | mytest(row); |
2803 | for (i= 0 ; i < 4 ; i++) |
2804 | { |
2805 | DIE_UNLESS(row[i] == 0); |
2806 | } |
2807 | row= mysql_fetch_row(result); |
2808 | mytest(row); |
2809 | for (i= 0 ; i < 4 ; i++) |
2810 | { |
2811 | DIE_UNLESS(strcmp(row[i], "88" ) == 0); |
2812 | } |
2813 | row= mysql_fetch_row(result); |
2814 | mytest_r(row); |
2815 | |
2816 | mysql_free_result(result); |
2817 | } |
2818 | |
2819 | |
2820 | /* Test simple select show */ |
2821 | |
2822 | static void test_select_show() |
2823 | { |
2824 | MYSQL_STMT *stmt; |
2825 | int rc; |
2826 | char query[MAX_TEST_QUERY_LENGTH]; |
2827 | |
2828 | myheader("test_select_show" ); |
2829 | |
2830 | mysql_autocommit(mysql, TRUE); |
2831 | |
2832 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_show" ); |
2833 | myquery(rc); |
2834 | |
2835 | rc= mysql_query(mysql, "CREATE TABLE test_show(id int(4) NOT NULL primary " |
2836 | " key, name char(2))" ); |
2837 | myquery(rc); |
2838 | |
2839 | stmt= mysql_simple_prepare(mysql, "show columns from test_show" ); |
2840 | check_stmt(stmt); |
2841 | |
2842 | verify_param_count(stmt, 0); |
2843 | |
2844 | rc= mysql_stmt_execute(stmt); |
2845 | check_execute(stmt, rc); |
2846 | |
2847 | my_process_stmt_result(stmt); |
2848 | mysql_stmt_close(stmt); |
2849 | |
2850 | stmt= mysql_simple_prepare(mysql, "show tables from mysql like ?" ); |
2851 | check_stmt_r(stmt); |
2852 | |
2853 | strxmov(query, "show tables from " , current_db, " like \'test_show\'" , NullS); |
2854 | stmt= mysql_simple_prepare(mysql, query); |
2855 | check_stmt(stmt); |
2856 | |
2857 | rc= mysql_stmt_execute(stmt); |
2858 | check_execute(stmt, rc); |
2859 | |
2860 | my_process_stmt_result(stmt); |
2861 | mysql_stmt_close(stmt); |
2862 | |
2863 | stmt= mysql_simple_prepare(mysql, "describe test_show" ); |
2864 | check_stmt(stmt); |
2865 | |
2866 | rc= mysql_stmt_execute(stmt); |
2867 | check_execute(stmt, rc); |
2868 | |
2869 | my_process_stmt_result(stmt); |
2870 | mysql_stmt_close(stmt); |
2871 | |
2872 | stmt= mysql_simple_prepare(mysql, "show keys from test_show" ); |
2873 | check_stmt(stmt); |
2874 | |
2875 | rc= mysql_stmt_execute(stmt); |
2876 | check_execute(stmt, rc); |
2877 | |
2878 | rc= my_process_stmt_result(stmt); |
2879 | DIE_UNLESS(rc == 1); |
2880 | mysql_stmt_close(stmt); |
2881 | } |
2882 | |
2883 | |
2884 | /* Test simple update */ |
2885 | |
2886 | static void test_simple_update() |
2887 | { |
2888 | MYSQL_STMT *stmt; |
2889 | int rc; |
2890 | char szData[25]; |
2891 | int nData= 1; |
2892 | MYSQL_RES *result; |
2893 | MYSQL_BIND my_bind[2]; |
2894 | ulong length[2]; |
2895 | char query[MAX_TEST_QUERY_LENGTH]; |
2896 | |
2897 | myheader("test_simple_update" ); |
2898 | |
2899 | rc= mysql_autocommit(mysql, TRUE); |
2900 | myquery(rc); |
2901 | |
2902 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_update" ); |
2903 | myquery(rc); |
2904 | |
2905 | rc= mysql_query(mysql, "CREATE TABLE test_update(col1 int, " |
2906 | " col2 varchar(50), col3 int )" ); |
2907 | myquery(rc); |
2908 | |
2909 | rc= mysql_query(mysql, "INSERT INTO test_update VALUES(1, 'MySQL', 100)" ); |
2910 | myquery(rc); |
2911 | |
2912 | verify_affected_rows(1); |
2913 | |
2914 | rc= mysql_commit(mysql); |
2915 | myquery(rc); |
2916 | |
2917 | /* insert by prepare */ |
2918 | strmov(query, "UPDATE test_update SET col2= ? WHERE col1= ?" ); |
2919 | stmt= mysql_simple_prepare(mysql, query); |
2920 | check_stmt(stmt); |
2921 | |
2922 | verify_param_count(stmt, 2); |
2923 | |
2924 | /* Always bzero all members of bind parameter */ |
2925 | bzero((char*) my_bind, sizeof(my_bind)); |
2926 | |
2927 | nData= 1; |
2928 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
2929 | my_bind[0].buffer= szData; /* string data */ |
2930 | my_bind[0].buffer_length= sizeof(szData); |
2931 | my_bind[0].length= &length[0]; |
2932 | length[0]= sprintf(szData, "updated-data" ); |
2933 | |
2934 | my_bind[1].buffer= (void *) &nData; |
2935 | my_bind[1].buffer_type= MYSQL_TYPE_LONG; |
2936 | |
2937 | rc= mysql_stmt_bind_param(stmt, my_bind); |
2938 | check_execute(stmt, rc); |
2939 | |
2940 | rc= mysql_stmt_execute(stmt); |
2941 | check_execute(stmt, rc); |
2942 | verify_affected_rows(1); |
2943 | |
2944 | mysql_stmt_close(stmt); |
2945 | |
2946 | /* now fetch the results ..*/ |
2947 | rc= mysql_commit(mysql); |
2948 | myquery(rc); |
2949 | |
2950 | /* test the results now, only one row should exist */ |
2951 | rc= mysql_query(mysql, "SELECT * FROM test_update" ); |
2952 | myquery(rc); |
2953 | |
2954 | /* get the result */ |
2955 | result= mysql_store_result(mysql); |
2956 | mytest(result); |
2957 | |
2958 | rc= my_process_result_set(result); |
2959 | DIE_UNLESS(rc == 1); |
2960 | mysql_free_result(result); |
2961 | } |
2962 | |
2963 | |
2964 | /* Test simple long data handling */ |
2965 | |
2966 | static void test_long_data() |
2967 | { |
2968 | MYSQL_STMT *stmt; |
2969 | int rc, int_data; |
2970 | char *data= NullS; |
2971 | MYSQL_RES *result; |
2972 | MYSQL_BIND my_bind[3]; |
2973 | char query[MAX_TEST_QUERY_LENGTH]; |
2974 | |
2975 | myheader("test_long_data" ); |
2976 | |
2977 | rc= mysql_autocommit(mysql, TRUE); |
2978 | myquery(rc); |
2979 | |
2980 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data" ); |
2981 | myquery(rc); |
2982 | |
2983 | rc= mysql_query(mysql, "CREATE TABLE test_long_data(col1 int, " |
2984 | " col2 long varchar, col3 long varbinary)" ); |
2985 | myquery(rc); |
2986 | |
2987 | strmov(query, "INSERT INTO test_long_data(col1, col2) VALUES(?)" ); |
2988 | stmt= mysql_simple_prepare(mysql, query); |
2989 | check_stmt_r(stmt); |
2990 | |
2991 | strmov(query, "INSERT INTO test_long_data(col1, col2, col3) VALUES(?, ?, ?)" ); |
2992 | stmt= mysql_simple_prepare(mysql, query); |
2993 | check_stmt(stmt); |
2994 | |
2995 | verify_param_count(stmt, 3); |
2996 | |
2997 | /* Always bzero all members of bind parameter */ |
2998 | bzero((char*) my_bind, sizeof(my_bind)); |
2999 | |
3000 | my_bind[0].buffer= (void *)&int_data; |
3001 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
3002 | |
3003 | my_bind[1].buffer_type= MYSQL_TYPE_STRING; |
3004 | |
3005 | my_bind[2]= my_bind[1]; |
3006 | rc= mysql_stmt_bind_param(stmt, my_bind); |
3007 | check_execute(stmt, rc); |
3008 | |
3009 | int_data= 999; |
3010 | data= (char *)"Michael" ; |
3011 | |
3012 | /* supply data in pieces */ |
3013 | rc= mysql_stmt_send_long_data(stmt, 1, data, strlen(data)); |
3014 | data= (char *)" 'Monty' Widenius" ; |
3015 | rc= mysql_stmt_send_long_data(stmt, 1, data, strlen(data)); |
3016 | check_execute(stmt, rc); |
3017 | rc= mysql_stmt_send_long_data(stmt, 2, "Venu (venu@mysql.com)" , 4); |
3018 | check_execute(stmt, rc); |
3019 | |
3020 | /* execute */ |
3021 | rc= mysql_stmt_execute(stmt); |
3022 | if (!opt_silent) |
3023 | fprintf(stdout, " mysql_stmt_execute() returned %d\n" , rc); |
3024 | check_execute(stmt, rc); |
3025 | |
3026 | rc= mysql_commit(mysql); |
3027 | myquery(rc); |
3028 | |
3029 | /* now fetch the results ..*/ |
3030 | rc= mysql_query(mysql, "SELECT * FROM test_long_data" ); |
3031 | myquery(rc); |
3032 | |
3033 | /* get the result */ |
3034 | result= mysql_store_result(mysql); |
3035 | mytest(result); |
3036 | |
3037 | rc= my_process_result_set(result); |
3038 | DIE_UNLESS(rc == 1); |
3039 | mysql_free_result(result); |
3040 | |
3041 | verify_col_data("test_long_data" , "col1" , "999" ); |
3042 | verify_col_data("test_long_data" , "col2" , "Michael 'Monty' Widenius" ); |
3043 | verify_col_data("test_long_data" , "col3" , "Venu" ); |
3044 | mysql_stmt_close(stmt); |
3045 | } |
3046 | |
3047 | |
3048 | /* Test long data (string) handling */ |
3049 | |
3050 | static void test_long_data_str() |
3051 | { |
3052 | MYSQL_STMT *stmt; |
3053 | int rc, i; |
3054 | char data[255]; |
3055 | long length; |
3056 | ulong length1; |
3057 | MYSQL_RES *result; |
3058 | MYSQL_BIND my_bind[2]; |
3059 | my_bool is_null[2]; |
3060 | char query[MAX_TEST_QUERY_LENGTH]; |
3061 | |
3062 | myheader("test_long_data_str" ); |
3063 | |
3064 | rc= mysql_autocommit(mysql, TRUE); |
3065 | myquery(rc); |
3066 | |
3067 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data_str" ); |
3068 | myquery(rc); |
3069 | |
3070 | rc= mysql_query(mysql, "CREATE TABLE test_long_data_str(id int, longstr long varchar)" ); |
3071 | myquery(rc); |
3072 | |
3073 | strmov(query, "INSERT INTO test_long_data_str VALUES(?, ?)" ); |
3074 | stmt= mysql_simple_prepare(mysql, query); |
3075 | check_stmt(stmt); |
3076 | |
3077 | verify_param_count(stmt, 2); |
3078 | |
3079 | /* Always bzero all members of bind parameter */ |
3080 | bzero((char*) my_bind, sizeof(my_bind)); |
3081 | |
3082 | my_bind[0].buffer= (void *)&length; |
3083 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
3084 | my_bind[0].is_null= &is_null[0]; |
3085 | is_null[0]= 0; |
3086 | length= 0; |
3087 | |
3088 | my_bind[1].buffer= data; /* string data */ |
3089 | my_bind[1].buffer_type= MYSQL_TYPE_STRING; |
3090 | my_bind[1].length= &length1; |
3091 | my_bind[1].is_null= &is_null[1]; |
3092 | is_null[1]= 0; |
3093 | rc= mysql_stmt_bind_param(stmt, my_bind); |
3094 | check_execute(stmt, rc); |
3095 | |
3096 | length= 40; |
3097 | strmov(data, "MySQL AB" ); |
3098 | |
3099 | /* supply data in pieces */ |
3100 | for(i= 0; i < 4; i++) |
3101 | { |
3102 | rc= mysql_stmt_send_long_data(stmt, 1, (char *)data, 5); |
3103 | check_execute(stmt, rc); |
3104 | } |
3105 | /* execute */ |
3106 | rc= mysql_stmt_execute(stmt); |
3107 | if (!opt_silent) |
3108 | fprintf(stdout, " mysql_stmt_execute() returned %d\n" , rc); |
3109 | check_execute(stmt, rc); |
3110 | |
3111 | mysql_stmt_close(stmt); |
3112 | |
3113 | rc= mysql_commit(mysql); |
3114 | myquery(rc); |
3115 | |
3116 | /* now fetch the results ..*/ |
3117 | rc= mysql_query(mysql, "SELECT LENGTH(longstr), longstr FROM test_long_data_str" ); |
3118 | myquery(rc); |
3119 | |
3120 | /* get the result */ |
3121 | result= mysql_store_result(mysql); |
3122 | mytest(result); |
3123 | |
3124 | rc= my_process_result_set(result); |
3125 | DIE_UNLESS(rc == 1); |
3126 | mysql_free_result(result); |
3127 | |
3128 | sprintf(data, "%d" , i*5); |
3129 | verify_col_data("test_long_data_str" , "LENGTH(longstr)" , data); |
3130 | data[0]= '\0'; |
3131 | while (i--) |
3132 | strxmov(data, data, "MySQL" , NullS); |
3133 | verify_col_data("test_long_data_str" , "longstr" , data); |
3134 | |
3135 | rc= mysql_query(mysql, "DROP TABLE test_long_data_str" ); |
3136 | myquery(rc); |
3137 | } |
3138 | |
3139 | |
3140 | /* Test long data (string) handling */ |
3141 | |
3142 | static void test_long_data_str1() |
3143 | { |
3144 | MYSQL_STMT *stmt; |
3145 | int rc, i; |
3146 | char data[255]; |
3147 | long length; |
3148 | ulong max_blob_length, blob_length= 0, length1; |
3149 | my_bool true_value; |
3150 | MYSQL_RES *result; |
3151 | MYSQL_BIND my_bind[2]; |
3152 | MYSQL_FIELD *field; |
3153 | char query[MAX_TEST_QUERY_LENGTH]; |
3154 | |
3155 | myheader("test_long_data_str1" ); |
3156 | |
3157 | rc= mysql_autocommit(mysql, TRUE); |
3158 | myquery(rc); |
3159 | |
3160 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data_str" ); |
3161 | myquery(rc); |
3162 | |
3163 | rc= mysql_query(mysql, "CREATE TABLE test_long_data_str(longstr long varchar, blb long varbinary)" ); |
3164 | myquery(rc); |
3165 | |
3166 | strmov(query, "INSERT INTO test_long_data_str VALUES(?, ?)" ); |
3167 | stmt= mysql_simple_prepare(mysql, query); |
3168 | check_stmt(stmt); |
3169 | |
3170 | verify_param_count(stmt, 2); |
3171 | |
3172 | /* Always bzero all members of bind parameter */ |
3173 | bzero((char*) my_bind, sizeof(my_bind)); |
3174 | |
3175 | my_bind[0].buffer= data; /* string data */ |
3176 | my_bind[0].buffer_length= sizeof(data); |
3177 | my_bind[0].length= &length1; |
3178 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
3179 | length1= 0; |
3180 | |
3181 | my_bind[1]= my_bind[0]; |
3182 | my_bind[1].buffer_type= MYSQL_TYPE_BLOB; |
3183 | |
3184 | rc= mysql_stmt_bind_param(stmt, my_bind); |
3185 | check_execute(stmt, rc); |
3186 | length= sprintf(data, "MySQL AB" ); |
3187 | |
3188 | /* supply data in pieces */ |
3189 | for (i= 0; i < 3; i++) |
3190 | { |
3191 | rc= mysql_stmt_send_long_data(stmt, 0, data, length); |
3192 | check_execute(stmt, rc); |
3193 | |
3194 | rc= mysql_stmt_send_long_data(stmt, 1, data, 2); |
3195 | check_execute(stmt, rc); |
3196 | } |
3197 | |
3198 | /* execute */ |
3199 | rc= mysql_stmt_execute(stmt); |
3200 | if (!opt_silent) |
3201 | fprintf(stdout, " mysql_stmt_execute() returned %d\n" , rc); |
3202 | check_execute(stmt, rc); |
3203 | |
3204 | mysql_stmt_close(stmt); |
3205 | |
3206 | rc= mysql_commit(mysql); |
3207 | myquery(rc); |
3208 | |
3209 | /* now fetch the results ..*/ |
3210 | rc= mysql_query(mysql, "SELECT LENGTH(longstr), longstr, LENGTH(blb), blb FROM test_long_data_str" ); |
3211 | myquery(rc); |
3212 | |
3213 | /* get the result */ |
3214 | result= mysql_store_result(mysql); |
3215 | |
3216 | mysql_field_seek(result, 1); |
3217 | field= mysql_fetch_field(result); |
3218 | max_blob_length= field->max_length; |
3219 | |
3220 | mytest(result); |
3221 | |
3222 | rc= my_process_result_set(result); |
3223 | DIE_UNLESS(rc == 1); |
3224 | mysql_free_result(result); |
3225 | |
3226 | sprintf(data, "%ld" , (long)i*length); |
3227 | verify_col_data("test_long_data_str" , "length(longstr)" , data); |
3228 | |
3229 | sprintf(data, "%d" , i*2); |
3230 | verify_col_data("test_long_data_str" , "length(blb)" , data); |
3231 | |
3232 | /* Test length of field->max_length */ |
3233 | stmt= mysql_simple_prepare(mysql, "SELECT * from test_long_data_str" ); |
3234 | check_stmt(stmt); |
3235 | verify_param_count(stmt, 0); |
3236 | |
3237 | rc= mysql_stmt_execute(stmt); |
3238 | check_execute(stmt, rc); |
3239 | |
3240 | rc= mysql_stmt_store_result(stmt); |
3241 | check_execute(stmt, rc); |
3242 | |
3243 | result= mysql_stmt_result_metadata(stmt); |
3244 | field= mysql_fetch_fields(result); |
3245 | |
3246 | /* First test what happens if STMT_ATTR_UPDATE_MAX_LENGTH is not used */ |
3247 | DIE_UNLESS(field->max_length == 0); |
3248 | mysql_free_result(result); |
3249 | |
3250 | /* Enable updating of field->max_length */ |
3251 | true_value= 1; |
3252 | mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &true_value); |
3253 | rc= mysql_stmt_execute(stmt); |
3254 | check_execute(stmt, rc); |
3255 | |
3256 | rc= mysql_stmt_store_result(stmt); |
3257 | check_execute(stmt, rc); |
3258 | |
3259 | result= mysql_stmt_result_metadata(stmt); |
3260 | field= mysql_fetch_fields(result); |
3261 | |
3262 | DIE_UNLESS(field->max_length == max_blob_length); |
3263 | |
3264 | /* Fetch results into a data buffer that is smaller than data */ |
3265 | bzero((char*) my_bind, sizeof(*my_bind)); |
3266 | my_bind[0].buffer_type= MYSQL_TYPE_BLOB; |
3267 | my_bind[0].buffer= (void *) &data; /* this buffer won't be altered */ |
3268 | my_bind[0].buffer_length= 16; |
3269 | my_bind[0].length= &blob_length; |
3270 | my_bind[0].error= &my_bind[0].error_value; |
3271 | rc= mysql_stmt_bind_result(stmt, my_bind); |
3272 | data[16]= 0; |
3273 | |
3274 | rc= mysql_stmt_fetch(stmt); |
3275 | DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED); |
3276 | DIE_UNLESS(my_bind[0].error_value); |
3277 | DIE_UNLESS(strlen(data) == 16); |
3278 | DIE_UNLESS(blob_length == max_blob_length); |
3279 | |
3280 | /* Fetch all data */ |
3281 | bzero((char*) (my_bind+1), sizeof(*my_bind)); |
3282 | my_bind[1].buffer_type= MYSQL_TYPE_BLOB; |
3283 | my_bind[1].buffer= (void *) &data; /* this buffer won't be altered */ |
3284 | my_bind[1].buffer_length= sizeof(data); |
3285 | my_bind[1].length= &blob_length; |
3286 | bzero(data, sizeof(data)); |
3287 | mysql_stmt_fetch_column(stmt, my_bind+1, 0, 0); |
3288 | DIE_UNLESS(strlen(data) == max_blob_length); |
3289 | |
3290 | mysql_free_result(result); |
3291 | mysql_stmt_close(stmt); |
3292 | |
3293 | /* Drop created table */ |
3294 | rc= mysql_query(mysql, "DROP TABLE test_long_data_str" ); |
3295 | myquery(rc); |
3296 | } |
3297 | |
3298 | |
3299 | /* Test long data (binary) handling */ |
3300 | |
3301 | static void test_long_data_bin() |
3302 | { |
3303 | MYSQL_STMT *stmt; |
3304 | int rc; |
3305 | char data[255]; |
3306 | long length; |
3307 | MYSQL_RES *result; |
3308 | MYSQL_BIND my_bind[2]; |
3309 | char query[MAX_TEST_QUERY_LENGTH]; |
3310 | |
3311 | |
3312 | myheader("test_long_data_bin" ); |
3313 | |
3314 | rc= mysql_autocommit(mysql, TRUE); |
3315 | myquery(rc); |
3316 | |
3317 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data_bin" ); |
3318 | myquery(rc); |
3319 | |
3320 | rc= mysql_query(mysql, "CREATE TABLE test_long_data_bin(id int, longbin long varbinary)" ); |
3321 | myquery(rc); |
3322 | |
3323 | strmov(query, "INSERT INTO test_long_data_bin VALUES(?, ?)" ); |
3324 | stmt= mysql_simple_prepare(mysql, query); |
3325 | check_stmt(stmt); |
3326 | |
3327 | verify_param_count(stmt, 2); |
3328 | |
3329 | /* Always bzero all members of bind parameter */ |
3330 | bzero((char*) my_bind, sizeof(my_bind)); |
3331 | |
3332 | my_bind[0].buffer= (void *)&length; |
3333 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
3334 | length= 0; |
3335 | |
3336 | my_bind[1].buffer= data; /* string data */ |
3337 | my_bind[1].buffer_type= MYSQL_TYPE_LONG_BLOB; |
3338 | rc= mysql_stmt_bind_param(stmt, my_bind); |
3339 | check_execute(stmt, rc); |
3340 | |
3341 | length= 10; |
3342 | strmov(data, "MySQL AB" ); |
3343 | |
3344 | /* supply data in pieces */ |
3345 | { |
3346 | int i; |
3347 | for (i= 0; i < 100; i++) |
3348 | { |
3349 | rc= mysql_stmt_send_long_data(stmt, 1, (char *)data, 4); |
3350 | check_execute(stmt, rc); |
3351 | } |
3352 | } |
3353 | /* execute */ |
3354 | rc= mysql_stmt_execute(stmt); |
3355 | if (!opt_silent) |
3356 | fprintf(stdout, " mysql_stmt_execute() returned %d\n" , rc); |
3357 | check_execute(stmt, rc); |
3358 | |
3359 | mysql_stmt_close(stmt); |
3360 | |
3361 | rc= mysql_commit(mysql); |
3362 | myquery(rc); |
3363 | |
3364 | /* now fetch the results ..*/ |
3365 | rc= mysql_query(mysql, "SELECT LENGTH(longbin), longbin FROM test_long_data_bin" ); |
3366 | myquery(rc); |
3367 | |
3368 | /* get the result */ |
3369 | result= mysql_store_result(mysql); |
3370 | mytest(result); |
3371 | |
3372 | rc= my_process_result_set(result); |
3373 | DIE_UNLESS(rc == 1); |
3374 | mysql_free_result(result); |
3375 | } |
3376 | |
3377 | |
3378 | /* Test simple delete */ |
3379 | |
3380 | static void test_simple_delete() |
3381 | { |
3382 | MYSQL_STMT *stmt; |
3383 | int rc; |
3384 | char szData[30]= {0}; |
3385 | int nData= 1; |
3386 | MYSQL_RES *result; |
3387 | MYSQL_BIND my_bind[2]; |
3388 | ulong length[2]; |
3389 | char query[MAX_TEST_QUERY_LENGTH]; |
3390 | |
3391 | myheader("test_simple_delete" ); |
3392 | |
3393 | rc= mysql_autocommit(mysql, TRUE); |
3394 | myquery(rc); |
3395 | |
3396 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_simple_delete" ); |
3397 | myquery(rc); |
3398 | |
3399 | rc= mysql_query(mysql, "CREATE TABLE test_simple_delete(col1 int, \ |
3400 | col2 varchar(50), col3 int )" ); |
3401 | myquery(rc); |
3402 | |
3403 | rc= mysql_query(mysql, "INSERT INTO test_simple_delete VALUES(1, 'MySQL', 100)" ); |
3404 | myquery(rc); |
3405 | |
3406 | verify_affected_rows(1); |
3407 | |
3408 | rc= mysql_commit(mysql); |
3409 | myquery(rc); |
3410 | |
3411 | /* insert by prepare */ |
3412 | strmov(query, "DELETE FROM test_simple_delete WHERE col1= ? AND " |
3413 | "CONVERT(col2 USING utf8)= ? AND col3= 100" ); |
3414 | stmt= mysql_simple_prepare(mysql, query); |
3415 | check_stmt(stmt); |
3416 | |
3417 | verify_param_count(stmt, 2); |
3418 | |
3419 | /* Always bzero all members of bind parameter */ |
3420 | bzero((char*) my_bind, sizeof(my_bind)); |
3421 | |
3422 | nData= 1; |
3423 | strmov(szData, "MySQL" ); |
3424 | my_bind[1].buffer_type= MYSQL_TYPE_STRING; |
3425 | my_bind[1].buffer= szData; /* string data */ |
3426 | my_bind[1].buffer_length= sizeof(szData); |
3427 | my_bind[1].length= &length[1]; |
3428 | length[1]= 5; |
3429 | |
3430 | my_bind[0].buffer= (void *)&nData; |
3431 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
3432 | |
3433 | rc= mysql_stmt_bind_param(stmt, my_bind); |
3434 | check_execute(stmt, rc); |
3435 | |
3436 | rc= mysql_stmt_execute(stmt); |
3437 | check_execute(stmt, rc); |
3438 | |
3439 | verify_affected_rows(1); |
3440 | |
3441 | mysql_stmt_close(stmt); |
3442 | |
3443 | /* now fetch the results ..*/ |
3444 | rc= mysql_commit(mysql); |
3445 | myquery(rc); |
3446 | |
3447 | /* test the results now, only one row should exist */ |
3448 | rc= mysql_query(mysql, "SELECT * FROM test_simple_delete" ); |
3449 | myquery(rc); |
3450 | |
3451 | /* get the result */ |
3452 | result= mysql_store_result(mysql); |
3453 | mytest(result); |
3454 | |
3455 | rc= my_process_result_set(result); |
3456 | DIE_UNLESS(rc == 0); |
3457 | mysql_free_result(result); |
3458 | } |
3459 | |
3460 | |
3461 | /* Test simple update */ |
3462 | |
3463 | static void test_update() |
3464 | { |
3465 | MYSQL_STMT *stmt; |
3466 | int rc; |
3467 | char szData[25]; |
3468 | int nData= 1; |
3469 | MYSQL_RES *result; |
3470 | MYSQL_BIND my_bind[2]; |
3471 | ulong length[2]; |
3472 | char query[MAX_TEST_QUERY_LENGTH]; |
3473 | |
3474 | myheader("test_update" ); |
3475 | |
3476 | rc= mysql_autocommit(mysql, TRUE); |
3477 | myquery(rc); |
3478 | |
3479 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_update" ); |
3480 | myquery(rc); |
3481 | |
3482 | rc= mysql_query(mysql, "CREATE TABLE test_update(" |
3483 | "col1 int primary key auto_increment, " |
3484 | "col2 varchar(50), col3 int )" ); |
3485 | myquery(rc); |
3486 | |
3487 | strmov(query, "INSERT INTO test_update(col2, col3) VALUES(?, ?)" ); |
3488 | stmt= mysql_simple_prepare(mysql, query); |
3489 | check_stmt(stmt); |
3490 | |
3491 | verify_param_count(stmt, 2); |
3492 | |
3493 | /* Always bzero all members of bind parameter */ |
3494 | bzero((char*) my_bind, sizeof(my_bind)); |
3495 | |
3496 | /* string data */ |
3497 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
3498 | my_bind[0].buffer= szData; |
3499 | my_bind[0].buffer_length= sizeof(szData); |
3500 | my_bind[0].length= &length[0]; |
3501 | length[0]= sprintf(szData, "inserted-data" ); |
3502 | |
3503 | my_bind[1].buffer= (void *)&nData; |
3504 | my_bind[1].buffer_type= MYSQL_TYPE_LONG; |
3505 | |
3506 | rc= mysql_stmt_bind_param(stmt, my_bind); |
3507 | check_execute(stmt, rc); |
3508 | |
3509 | nData= 100; |
3510 | rc= mysql_stmt_execute(stmt); |
3511 | check_execute(stmt, rc); |
3512 | |
3513 | verify_affected_rows(1); |
3514 | mysql_stmt_close(stmt); |
3515 | |
3516 | strmov(query, "UPDATE test_update SET col2= ? WHERE col3= ?" ); |
3517 | stmt= mysql_simple_prepare(mysql, query); |
3518 | check_stmt(stmt); |
3519 | |
3520 | verify_param_count(stmt, 2); |
3521 | nData= 100; |
3522 | |
3523 | /* Always bzero all members of bind parameter */ |
3524 | bzero((char*) my_bind, sizeof(my_bind)); |
3525 | |
3526 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
3527 | my_bind[0].buffer= szData; |
3528 | my_bind[0].buffer_length= sizeof(szData); |
3529 | my_bind[0].length= &length[0]; |
3530 | length[0]= sprintf(szData, "updated-data" ); |
3531 | |
3532 | my_bind[1].buffer= (void *)&nData; |
3533 | my_bind[1].buffer_type= MYSQL_TYPE_LONG; |
3534 | |
3535 | rc= mysql_stmt_bind_param(stmt, my_bind); |
3536 | check_execute(stmt, rc); |
3537 | |
3538 | rc= mysql_stmt_execute(stmt); |
3539 | check_execute(stmt, rc); |
3540 | verify_affected_rows(1); |
3541 | |
3542 | mysql_stmt_close(stmt); |
3543 | |
3544 | /* now fetch the results ..*/ |
3545 | rc= mysql_commit(mysql); |
3546 | myquery(rc); |
3547 | |
3548 | /* test the results now, only one row should exist */ |
3549 | rc= mysql_query(mysql, "SELECT * FROM test_update" ); |
3550 | myquery(rc); |
3551 | |
3552 | /* get the result */ |
3553 | result= mysql_store_result(mysql); |
3554 | mytest(result); |
3555 | |
3556 | rc= my_process_result_set(result); |
3557 | DIE_UNLESS(rc == 1); |
3558 | mysql_free_result(result); |
3559 | } |
3560 | |
3561 | |
3562 | /* Test prepare without parameters */ |
3563 | |
3564 | static void test_prepare_noparam() |
3565 | { |
3566 | MYSQL_STMT *stmt; |
3567 | int rc; |
3568 | MYSQL_RES *result; |
3569 | char query[MAX_TEST_QUERY_LENGTH]; |
3570 | |
3571 | myheader("test_prepare_noparam" ); |
3572 | |
3573 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS my_prepare" ); |
3574 | myquery(rc); |
3575 | |
3576 | |
3577 | rc= mysql_query(mysql, "CREATE TABLE my_prepare(col1 int, col2 varchar(50))" ); |
3578 | myquery(rc); |
3579 | |
3580 | /* insert by prepare */ |
3581 | strmov(query, "INSERT INTO my_prepare VALUES(10, 'venu')" ); |
3582 | stmt= mysql_simple_prepare(mysql, query); |
3583 | check_stmt(stmt); |
3584 | |
3585 | verify_param_count(stmt, 0); |
3586 | |
3587 | rc= mysql_stmt_execute(stmt); |
3588 | check_execute(stmt, rc); |
3589 | |
3590 | mysql_stmt_close(stmt); |
3591 | |
3592 | /* now fetch the results ..*/ |
3593 | rc= mysql_commit(mysql); |
3594 | myquery(rc); |
3595 | |
3596 | /* test the results now, only one row should exist */ |
3597 | rc= mysql_query(mysql, "SELECT * FROM my_prepare" ); |
3598 | myquery(rc); |
3599 | |
3600 | /* get the result */ |
3601 | result= mysql_store_result(mysql); |
3602 | mytest(result); |
3603 | |
3604 | rc= my_process_result_set(result); |
3605 | DIE_UNLESS(rc == 1); |
3606 | mysql_free_result(result); |
3607 | } |
3608 | |
3609 | |
3610 | /* Test simple bind result */ |
3611 | |
3612 | static void test_bind_result() |
3613 | { |
3614 | MYSQL_STMT *stmt; |
3615 | int rc; |
3616 | int nData; |
3617 | ulong length1; |
3618 | char szData[100]; |
3619 | MYSQL_BIND my_bind[2]; |
3620 | my_bool is_null[2]; |
3621 | |
3622 | myheader("test_bind_result" ); |
3623 | |
3624 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_result" ); |
3625 | myquery(rc); |
3626 | |
3627 | rc= mysql_query(mysql, "CREATE TABLE test_bind_result(col1 int , col2 varchar(50))" ); |
3628 | myquery(rc); |
3629 | |
3630 | rc= mysql_query(mysql, "INSERT INTO test_bind_result VALUES(10, 'venu')" ); |
3631 | myquery(rc); |
3632 | |
3633 | rc= mysql_query(mysql, "INSERT INTO test_bind_result VALUES(20, 'MySQL')" ); |
3634 | myquery(rc); |
3635 | |
3636 | rc= mysql_query(mysql, "INSERT INTO test_bind_result(col2) VALUES('monty')" ); |
3637 | myquery(rc); |
3638 | |
3639 | rc= mysql_commit(mysql); |
3640 | myquery(rc); |
3641 | |
3642 | /* fetch */ |
3643 | |
3644 | bzero((char*) my_bind, sizeof(my_bind)); |
3645 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
3646 | my_bind[0].buffer= (void *) &nData; /* integer data */ |
3647 | my_bind[0].is_null= &is_null[0]; |
3648 | |
3649 | my_bind[1].buffer_type= MYSQL_TYPE_STRING; |
3650 | my_bind[1].buffer= szData; /* string data */ |
3651 | my_bind[1].buffer_length= sizeof(szData); |
3652 | my_bind[1].length= &length1; |
3653 | my_bind[1].is_null= &is_null[1]; |
3654 | |
3655 | stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_bind_result" ); |
3656 | check_stmt(stmt); |
3657 | |
3658 | rc= mysql_stmt_bind_result(stmt, my_bind); |
3659 | check_execute(stmt, rc); |
3660 | |
3661 | rc= mysql_stmt_execute(stmt); |
3662 | check_execute(stmt, rc); |
3663 | |
3664 | rc= mysql_stmt_fetch(stmt); |
3665 | check_execute(stmt, rc); |
3666 | |
3667 | if (!opt_silent) |
3668 | fprintf(stdout, "\n row 1: %d, %s(%lu)" , nData, szData, length1); |
3669 | DIE_UNLESS(nData == 10); |
3670 | DIE_UNLESS(strcmp(szData, "venu" ) == 0); |
3671 | DIE_UNLESS(length1 == 4); |
3672 | |
3673 | rc= mysql_stmt_fetch(stmt); |
3674 | check_execute(stmt, rc); |
3675 | |
3676 | if (!opt_silent) |
3677 | fprintf(stdout, "\n row 2: %d, %s(%lu)" , nData, szData, length1); |
3678 | DIE_UNLESS(nData == 20); |
3679 | DIE_UNLESS(strcmp(szData, "MySQL" ) == 0); |
3680 | DIE_UNLESS(length1 == 5); |
3681 | |
3682 | rc= mysql_stmt_fetch(stmt); |
3683 | check_execute(stmt, rc); |
3684 | |
3685 | if (!opt_silent && is_null[0]) |
3686 | fprintf(stdout, "\n row 3: NULL, %s(%lu)" , szData, length1); |
3687 | DIE_UNLESS(is_null[0]); |
3688 | DIE_UNLESS(strcmp(szData, "monty" ) == 0); |
3689 | DIE_UNLESS(length1 == 5); |
3690 | |
3691 | rc= mysql_stmt_fetch(stmt); |
3692 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
3693 | |
3694 | mysql_stmt_close(stmt); |
3695 | } |
3696 | |
3697 | |
3698 | /* Test ext bind result */ |
3699 | |
3700 | static void test_bind_result_ext() |
3701 | { |
3702 | MYSQL_STMT *stmt; |
3703 | int rc, i; |
3704 | uchar t_data; |
3705 | short s_data; |
3706 | int i_data; |
3707 | longlong b_data; |
3708 | float f_data; |
3709 | double d_data; |
3710 | char szData[20], bData[20]; |
3711 | ulong szLength, bLength; |
3712 | MYSQL_BIND my_bind[8]; |
3713 | ulong length[8]; |
3714 | my_bool is_null[8]; |
3715 | char llbuf[22]; |
3716 | myheader("test_bind_result_ext" ); |
3717 | |
3718 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_result" ); |
3719 | myquery(rc); |
3720 | |
3721 | rc= mysql_query(mysql, "CREATE TABLE test_bind_result(c1 tinyint, " |
3722 | " c2 smallint, " |
3723 | " c3 int, c4 bigint, " |
3724 | " c5 float, c6 double, " |
3725 | " c7 varbinary(10), " |
3726 | " c8 varchar(50))" ); |
3727 | myquery(rc); |
3728 | |
3729 | rc= mysql_query(mysql, "INSERT INTO test_bind_result " |
3730 | "VALUES (19, 2999, 3999, 4999999, " |
3731 | " 2345.6, 5678.89563, 'venu', 'mysql')" ); |
3732 | myquery(rc); |
3733 | |
3734 | rc= mysql_commit(mysql); |
3735 | myquery(rc); |
3736 | |
3737 | bzero((char*) my_bind, sizeof(my_bind)); |
3738 | for (i= 0; i < (int) array_elements(my_bind); i++) |
3739 | { |
3740 | my_bind[i].length= &length[i]; |
3741 | my_bind[i].is_null= &is_null[i]; |
3742 | } |
3743 | |
3744 | my_bind[0].buffer_type= MYSQL_TYPE_TINY; |
3745 | my_bind[0].buffer= (void *)&t_data; |
3746 | |
3747 | my_bind[1].buffer_type= MYSQL_TYPE_SHORT; |
3748 | my_bind[2].buffer_type= MYSQL_TYPE_LONG; |
3749 | |
3750 | my_bind[3].buffer_type= MYSQL_TYPE_LONGLONG; |
3751 | my_bind[1].buffer= (void *)&s_data; |
3752 | |
3753 | my_bind[2].buffer= (void *)&i_data; |
3754 | my_bind[3].buffer= (void *)&b_data; |
3755 | |
3756 | my_bind[4].buffer_type= MYSQL_TYPE_FLOAT; |
3757 | my_bind[4].buffer= (void *)&f_data; |
3758 | |
3759 | my_bind[5].buffer_type= MYSQL_TYPE_DOUBLE; |
3760 | my_bind[5].buffer= (void *)&d_data; |
3761 | |
3762 | my_bind[6].buffer_type= MYSQL_TYPE_STRING; |
3763 | my_bind[6].buffer= (void *)szData; |
3764 | my_bind[6].buffer_length= sizeof(szData); |
3765 | my_bind[6].length= &szLength; |
3766 | |
3767 | my_bind[7].buffer_type= MYSQL_TYPE_TINY_BLOB; |
3768 | my_bind[7].buffer= (void *)&bData; |
3769 | my_bind[7].length= &bLength; |
3770 | my_bind[7].buffer_length= sizeof(bData); |
3771 | |
3772 | stmt= mysql_simple_prepare(mysql, "select * from test_bind_result" ); |
3773 | check_stmt(stmt); |
3774 | |
3775 | rc= mysql_stmt_bind_result(stmt, my_bind); |
3776 | check_execute(stmt, rc); |
3777 | |
3778 | rc= mysql_stmt_execute(stmt); |
3779 | check_execute(stmt, rc); |
3780 | |
3781 | rc= mysql_stmt_fetch(stmt); |
3782 | check_execute(stmt, rc); |
3783 | |
3784 | if (!opt_silent) |
3785 | { |
3786 | fprintf(stdout, "\n data (tiny) : %d" , t_data); |
3787 | fprintf(stdout, "\n data (short) : %d" , s_data); |
3788 | fprintf(stdout, "\n data (int) : %d" , i_data); |
3789 | fprintf(stdout, "\n data (big) : %s" , llstr(b_data, llbuf)); |
3790 | |
3791 | fprintf(stdout, "\n data (float) : %f" , f_data); |
3792 | fprintf(stdout, "\n data (double) : %f" , d_data); |
3793 | |
3794 | fprintf(stdout, "\n data (str) : %s(%lu)" , szData, szLength); |
3795 | |
3796 | bData[bLength]= '\0'; /* bData is binary */ |
3797 | fprintf(stdout, "\n data (bin) : %s(%lu)" , bData, bLength); |
3798 | } |
3799 | |
3800 | DIE_UNLESS(t_data == 19); |
3801 | DIE_UNLESS(s_data == 2999); |
3802 | DIE_UNLESS(i_data == 3999); |
3803 | DIE_UNLESS(b_data == 4999999); |
3804 | /*DIE_UNLESS(f_data == 2345.60);*/ |
3805 | /*DIE_UNLESS(d_data == 5678.89563);*/ |
3806 | DIE_UNLESS(strcmp(szData, "venu" ) == 0); |
3807 | DIE_UNLESS(strncmp(bData, "mysql" , 5) == 0); |
3808 | DIE_UNLESS(szLength == 4); |
3809 | DIE_UNLESS(bLength == 5); |
3810 | |
3811 | rc= mysql_stmt_fetch(stmt); |
3812 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
3813 | |
3814 | mysql_stmt_close(stmt); |
3815 | } |
3816 | |
3817 | |
3818 | /* Test ext bind result */ |
3819 | |
3820 | static void test_bind_result_ext1() |
3821 | { |
3822 | MYSQL_STMT *stmt; |
3823 | uint i; |
3824 | int rc; |
3825 | char t_data[20]; |
3826 | float s_data; |
3827 | short i_data; |
3828 | uchar b_data; |
3829 | int f_data; |
3830 | long bData; |
3831 | char d_data[20]; |
3832 | double szData; |
3833 | MYSQL_BIND my_bind[8]; |
3834 | ulong length[8]; |
3835 | my_bool is_null[8]; |
3836 | myheader("test_bind_result_ext1" ); |
3837 | |
3838 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_result" ); |
3839 | myquery(rc); |
3840 | |
3841 | rc= mysql_query(mysql, "CREATE TABLE test_bind_result(c1 tinyint, c2 smallint, \ |
3842 | c3 int, c4 bigint, \ |
3843 | c5 float, c6 double, \ |
3844 | c7 varbinary(10), \ |
3845 | c8 varchar(10))" ); |
3846 | myquery(rc); |
3847 | |
3848 | rc= mysql_query(mysql, "INSERT INTO test_bind_result VALUES(120, 2999, 3999, 54, \ |
3849 | 2.6, 58.89, \ |
3850 | '206', '6.7')" ); |
3851 | myquery(rc); |
3852 | |
3853 | rc= mysql_commit(mysql); |
3854 | myquery(rc); |
3855 | |
3856 | bzero((char*) my_bind, sizeof(my_bind)); |
3857 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
3858 | my_bind[0].buffer= (void *) t_data; |
3859 | my_bind[0].buffer_length= sizeof(t_data); |
3860 | my_bind[0].error= &my_bind[0].error_value; |
3861 | |
3862 | my_bind[1].buffer_type= MYSQL_TYPE_FLOAT; |
3863 | my_bind[1].buffer= (void *)&s_data; |
3864 | my_bind[1].buffer_length= 0; |
3865 | my_bind[1].error= &my_bind[1].error_value; |
3866 | |
3867 | my_bind[2].buffer_type= MYSQL_TYPE_SHORT; |
3868 | my_bind[2].buffer= (void *)&i_data; |
3869 | my_bind[2].buffer_length= 0; |
3870 | my_bind[2].error= &my_bind[2].error_value; |
3871 | |
3872 | my_bind[3].buffer_type= MYSQL_TYPE_TINY; |
3873 | my_bind[3].buffer= (void *)&b_data; |
3874 | my_bind[3].buffer_length= 0; |
3875 | my_bind[3].error= &my_bind[3].error_value; |
3876 | |
3877 | my_bind[4].buffer_type= MYSQL_TYPE_LONG; |
3878 | my_bind[4].buffer= (void *)&f_data; |
3879 | my_bind[4].buffer_length= 0; |
3880 | my_bind[4].error= &my_bind[4].error_value; |
3881 | |
3882 | my_bind[5].buffer_type= MYSQL_TYPE_STRING; |
3883 | my_bind[5].buffer= (void *)d_data; |
3884 | my_bind[5].buffer_length= sizeof(d_data); |
3885 | my_bind[5].error= &my_bind[5].error_value; |
3886 | |
3887 | my_bind[6].buffer_type= MYSQL_TYPE_LONG; |
3888 | my_bind[6].buffer= (void *)&bData; |
3889 | my_bind[6].buffer_length= 0; |
3890 | my_bind[6].error= &my_bind[6].error_value; |
3891 | |
3892 | my_bind[7].buffer_type= MYSQL_TYPE_DOUBLE; |
3893 | my_bind[7].buffer= (void *)&szData; |
3894 | my_bind[7].buffer_length= 0; |
3895 | my_bind[7].error= &my_bind[7].error_value; |
3896 | |
3897 | for (i= 0; i < array_elements(my_bind); i++) |
3898 | { |
3899 | my_bind[i].is_null= &is_null[i]; |
3900 | my_bind[i].length= &length[i]; |
3901 | } |
3902 | |
3903 | stmt= mysql_simple_prepare(mysql, "select * from test_bind_result" ); |
3904 | check_stmt(stmt); |
3905 | |
3906 | rc= mysql_stmt_bind_result(stmt, my_bind); |
3907 | check_execute(stmt, rc); |
3908 | |
3909 | rc= mysql_stmt_execute(stmt); |
3910 | check_execute(stmt, rc); |
3911 | |
3912 | rc= mysql_stmt_fetch(stmt); |
3913 | printf("rc=%d\n" , rc); |
3914 | DIE_UNLESS(rc == 0); |
3915 | |
3916 | if (!opt_silent) |
3917 | { |
3918 | fprintf(stdout, "\n data (tiny) : %s(%lu)" , t_data, length[0]); |
3919 | fprintf(stdout, "\n data (short) : %f(%lu)" , s_data, length[1]); |
3920 | fprintf(stdout, "\n data (int) : %d(%lu)" , i_data, length[2]); |
3921 | fprintf(stdout, "\n data (big) : %d(%lu)" , b_data, length[3]); |
3922 | |
3923 | fprintf(stdout, "\n data (float) : %d(%lu)" , f_data, length[4]); |
3924 | fprintf(stdout, "\n data (double) : %s(%lu)" , d_data, length[5]); |
3925 | |
3926 | fprintf(stdout, "\n data (bin) : %ld(%lu)" , bData, length[6]); |
3927 | fprintf(stdout, "\n data (str) : %g(%lu)" , szData, length[7]); |
3928 | } |
3929 | |
3930 | DIE_UNLESS(strcmp(t_data, "120" ) == 0); |
3931 | DIE_UNLESS(i_data == 3999); |
3932 | DIE_UNLESS(f_data == 2); |
3933 | DIE_UNLESS(strcmp(d_data, "58.89" ) == 0); |
3934 | DIE_UNLESS(b_data == 54); |
3935 | |
3936 | DIE_UNLESS(length[0] == 3); |
3937 | DIE_UNLESS(length[1] == 4); |
3938 | DIE_UNLESS(length[2] == 2); |
3939 | DIE_UNLESS(length[3] == 1); |
3940 | DIE_UNLESS(length[4] == 4); |
3941 | DIE_UNLESS(length[5] == 5); |
3942 | DIE_UNLESS(length[6] == 4); |
3943 | DIE_UNLESS(length[7] == 8); |
3944 | |
3945 | rc= mysql_stmt_fetch(stmt); |
3946 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
3947 | |
3948 | mysql_stmt_close(stmt); |
3949 | } |
3950 | |
3951 | |
3952 | /* Generalized fetch conversion routine for all basic types */ |
3953 | |
3954 | static void bind_fetch(int row_count) |
3955 | { |
3956 | MYSQL_STMT *stmt; |
3957 | int rc, i, count= row_count; |
3958 | int32 data[10]; |
3959 | int8 i8_data; |
3960 | int16 i16_data; |
3961 | int32 i32_data; |
3962 | longlong i64_data; |
3963 | float f_data; |
3964 | double d_data; |
3965 | char s_data[10]; |
3966 | ulong length[10]; |
3967 | MYSQL_BIND my_bind[7]; |
3968 | my_bool is_null[7]; |
3969 | |
3970 | stmt= mysql_simple_prepare(mysql, "INSERT INTO test_bind_fetch VALUES " |
3971 | "(?, ?, ?, ?, ?, ?, ?)" ); |
3972 | check_stmt(stmt); |
3973 | |
3974 | verify_param_count(stmt, 7); |
3975 | |
3976 | /* Always bzero all members of bind parameter */ |
3977 | bzero((char*) my_bind, sizeof(my_bind)); |
3978 | |
3979 | for (i= 0; i < (int) array_elements(my_bind); i++) |
3980 | { |
3981 | my_bind[i].buffer_type= MYSQL_TYPE_LONG; |
3982 | my_bind[i].buffer= (void *) &data[i]; |
3983 | } |
3984 | rc= mysql_stmt_bind_param(stmt, my_bind); |
3985 | check_execute(stmt, rc); |
3986 | |
3987 | while (count--) |
3988 | { |
3989 | rc= 10+count; |
3990 | for (i= 0; i < (int) array_elements(my_bind); i++) |
3991 | { |
3992 | data[i]= rc+i; |
3993 | rc+= 12; |
3994 | } |
3995 | rc= mysql_stmt_execute(stmt); |
3996 | check_execute(stmt, rc); |
3997 | } |
3998 | |
3999 | rc= mysql_commit(mysql); |
4000 | myquery(rc); |
4001 | |
4002 | mysql_stmt_close(stmt); |
4003 | |
4004 | rc= my_stmt_result("SELECT * FROM test_bind_fetch" ); |
4005 | DIE_UNLESS(row_count == rc); |
4006 | |
4007 | stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_bind_fetch" ); |
4008 | check_stmt(stmt); |
4009 | |
4010 | for (i= 0; i < (int) array_elements(my_bind); i++) |
4011 | { |
4012 | my_bind[i].buffer= (void *) &data[i]; |
4013 | my_bind[i].length= &length[i]; |
4014 | my_bind[i].is_null= &is_null[i]; |
4015 | } |
4016 | |
4017 | my_bind[0].buffer_type= MYSQL_TYPE_TINY; |
4018 | my_bind[0].buffer= (void *)&i8_data; |
4019 | |
4020 | my_bind[1].buffer_type= MYSQL_TYPE_SHORT; |
4021 | my_bind[1].buffer= (void *)&i16_data; |
4022 | |
4023 | my_bind[2].buffer_type= MYSQL_TYPE_LONG; |
4024 | my_bind[2].buffer= (void *)&i32_data; |
4025 | |
4026 | my_bind[3].buffer_type= MYSQL_TYPE_LONGLONG; |
4027 | my_bind[3].buffer= (void *)&i64_data; |
4028 | |
4029 | my_bind[4].buffer_type= MYSQL_TYPE_FLOAT; |
4030 | my_bind[4].buffer= (void *)&f_data; |
4031 | |
4032 | my_bind[5].buffer_type= MYSQL_TYPE_DOUBLE; |
4033 | my_bind[5].buffer= (void *)&d_data; |
4034 | |
4035 | my_bind[6].buffer_type= MYSQL_TYPE_STRING; |
4036 | my_bind[6].buffer= (void *)&s_data; |
4037 | my_bind[6].buffer_length= sizeof(s_data); |
4038 | |
4039 | rc= mysql_stmt_bind_result(stmt, my_bind); |
4040 | check_execute(stmt, rc); |
4041 | |
4042 | rc= mysql_stmt_execute(stmt); |
4043 | check_execute(stmt, rc); |
4044 | |
4045 | rc= mysql_stmt_store_result(stmt); |
4046 | check_execute(stmt, rc); |
4047 | |
4048 | while (row_count--) |
4049 | { |
4050 | rc= mysql_stmt_fetch(stmt); |
4051 | check_execute(stmt, rc); |
4052 | |
4053 | if (!opt_silent) |
4054 | { |
4055 | fprintf(stdout, "\n" ); |
4056 | fprintf(stdout, "\n tiny : %ld(%lu)" , (ulong) i8_data, length[0]); |
4057 | fprintf(stdout, "\n short : %ld(%lu)" , (ulong) i16_data, length[1]); |
4058 | fprintf(stdout, "\n int : %ld(%lu)" , (ulong) i32_data, length[2]); |
4059 | fprintf(stdout, "\n longlong : %ld(%lu)" , (ulong) i64_data, length[3]); |
4060 | fprintf(stdout, "\n float : %f(%lu)" , f_data, length[4]); |
4061 | fprintf(stdout, "\n double : %g(%lu)" , d_data, length[5]); |
4062 | fprintf(stdout, "\n char : %s(%lu)" , s_data, length[6]); |
4063 | } |
4064 | rc= 10+row_count; |
4065 | |
4066 | /* TINY */ |
4067 | DIE_UNLESS((int) i8_data == rc); |
4068 | DIE_UNLESS(length[0] == 1); |
4069 | rc+= 13; |
4070 | |
4071 | /* SHORT */ |
4072 | DIE_UNLESS((int) i16_data == rc); |
4073 | DIE_UNLESS(length[1] == 2); |
4074 | rc+= 13; |
4075 | |
4076 | /* LONG */ |
4077 | DIE_UNLESS((int) i32_data == rc); |
4078 | DIE_UNLESS(length[2] == 4); |
4079 | rc+= 13; |
4080 | |
4081 | /* LONGLONG */ |
4082 | DIE_UNLESS((int) i64_data == rc); |
4083 | DIE_UNLESS(length[3] == 8); |
4084 | rc+= 13; |
4085 | |
4086 | /* FLOAT */ |
4087 | DIE_UNLESS((int)f_data == rc); |
4088 | DIE_UNLESS(length[4] == 4); |
4089 | rc+= 13; |
4090 | |
4091 | /* DOUBLE */ |
4092 | DIE_UNLESS((int)d_data == rc); |
4093 | DIE_UNLESS(length[5] == 8); |
4094 | rc+= 13; |
4095 | |
4096 | /* CHAR */ |
4097 | { |
4098 | char buff[20]; |
4099 | long len= sprintf(buff, "%d" , rc); |
4100 | DIE_UNLESS(strcmp(s_data, buff) == 0); |
4101 | DIE_UNLESS(length[6] == (ulong) len); |
4102 | } |
4103 | } |
4104 | rc= mysql_stmt_fetch(stmt); |
4105 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
4106 | |
4107 | mysql_stmt_close(stmt); |
4108 | } |
4109 | |
4110 | |
4111 | /* Test fetching of date, time and ts */ |
4112 | |
4113 | static void test_fetch_date() |
4114 | { |
4115 | MYSQL_STMT *stmt; |
4116 | uint i; |
4117 | int rc, year; |
4118 | char date[25], my_time[25], ts[25], ts_4[25], ts_6[20], dt[20]; |
4119 | ulong d_length, t_length, ts_length, ts4_length, ts6_length, |
4120 | dt_length, y_length; |
4121 | MYSQL_BIND my_bind[8]; |
4122 | my_bool is_null[8]; |
4123 | ulong length[8]; |
4124 | |
4125 | myheader("test_fetch_date" ); |
4126 | |
4127 | /* Will not work if sql_mode is NO_ZERO_DATE (implicit if TRADITIONAL) */ |
4128 | rc= mysql_query(mysql, "SET SQL_MODE=''" ); |
4129 | myquery(rc); |
4130 | |
4131 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_result" ); |
4132 | myquery(rc); |
4133 | |
4134 | rc= mysql_query(mysql, "CREATE TABLE test_bind_result(c1 date, c2 time, \ |
4135 | c3 timestamp, \ |
4136 | c4 year, \ |
4137 | c5 datetime, \ |
4138 | c6 timestamp, \ |
4139 | c7 timestamp)" ); |
4140 | myquery(rc); |
4141 | |
4142 | rc= mysql_query(mysql, "SET SQL_MODE=''" ); |
4143 | rc= mysql_query(mysql, "INSERT INTO test_bind_result VALUES('2002-01-02', \ |
4144 | '12:49:00', \ |
4145 | '2002-01-02 17:46:59', \ |
4146 | 2010, \ |
4147 | '2010-07-10', \ |
4148 | '2020', '1999-12-29')" ); |
4149 | myquery(rc); |
4150 | |
4151 | rc= mysql_commit(mysql); |
4152 | myquery(rc); |
4153 | |
4154 | bzero((char*) my_bind, sizeof(my_bind)); |
4155 | for (i= 0; i < array_elements(my_bind); i++) |
4156 | { |
4157 | my_bind[i].is_null= &is_null[i]; |
4158 | my_bind[i].length= &length[i]; |
4159 | } |
4160 | |
4161 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
4162 | my_bind[1]= my_bind[2]= my_bind[0]; |
4163 | |
4164 | my_bind[0].buffer= (void *)&date; |
4165 | my_bind[0].buffer_length= sizeof(date); |
4166 | my_bind[0].length= &d_length; |
4167 | |
4168 | my_bind[1].buffer= (void *)&my_time; |
4169 | my_bind[1].buffer_length= sizeof(my_time); |
4170 | my_bind[1].length= &t_length; |
4171 | |
4172 | my_bind[2].buffer= (void *)&ts; |
4173 | my_bind[2].buffer_length= sizeof(ts); |
4174 | my_bind[2].length= &ts_length; |
4175 | |
4176 | my_bind[3].buffer_type= MYSQL_TYPE_LONG; |
4177 | my_bind[3].buffer= (void *)&year; |
4178 | my_bind[3].length= &y_length; |
4179 | |
4180 | my_bind[4].buffer_type= MYSQL_TYPE_STRING; |
4181 | my_bind[4].buffer= (void *)&dt; |
4182 | my_bind[4].buffer_length= sizeof(dt); |
4183 | my_bind[4].length= &dt_length; |
4184 | |
4185 | my_bind[5].buffer_type= MYSQL_TYPE_STRING; |
4186 | my_bind[5].buffer= (void *)&ts_4; |
4187 | my_bind[5].buffer_length= sizeof(ts_4); |
4188 | my_bind[5].length= &ts4_length; |
4189 | |
4190 | my_bind[6].buffer_type= MYSQL_TYPE_STRING; |
4191 | my_bind[6].buffer= (void *)&ts_6; |
4192 | my_bind[6].buffer_length= sizeof(ts_6); |
4193 | my_bind[6].length= &ts6_length; |
4194 | |
4195 | rc= my_stmt_result("SELECT * FROM test_bind_result" ); |
4196 | DIE_UNLESS(rc == 1); |
4197 | |
4198 | stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_bind_result" ); |
4199 | check_stmt(stmt); |
4200 | |
4201 | rc= mysql_stmt_bind_result(stmt, my_bind); |
4202 | check_execute(stmt, rc); |
4203 | |
4204 | rc= mysql_stmt_execute(stmt); |
4205 | check_execute(stmt, rc); |
4206 | |
4207 | ts_4[0]= '\0'; |
4208 | rc= mysql_stmt_fetch(stmt); |
4209 | check_execute(stmt, rc); |
4210 | |
4211 | if (!opt_silent) |
4212 | { |
4213 | fprintf(stdout, "\n date : %s(%lu)" , date, d_length); |
4214 | fprintf(stdout, "\n time : %s(%lu)" , my_time, t_length); |
4215 | fprintf(stdout, "\n ts : %s(%lu)" , ts, ts_length); |
4216 | fprintf(stdout, "\n year : %d(%lu)" , year, y_length); |
4217 | fprintf(stdout, "\n dt : %s(%lu)" , dt, dt_length); |
4218 | fprintf(stdout, "\n ts(4) : %s(%lu)" , ts_4, ts4_length); |
4219 | fprintf(stdout, "\n ts(6) : %s(%lu)" , ts_6, ts6_length); |
4220 | } |
4221 | |
4222 | DIE_UNLESS(strcmp(date, "2002-01-02" ) == 0); |
4223 | DIE_UNLESS(d_length == 10); |
4224 | |
4225 | DIE_UNLESS(strcmp(my_time, "12:49:00" ) == 0); |
4226 | DIE_UNLESS(t_length == 8); |
4227 | |
4228 | DIE_UNLESS(strcmp(ts, "2002-01-02 17:46:59" ) == 0); |
4229 | DIE_UNLESS(ts_length == 19); |
4230 | |
4231 | DIE_UNLESS(year == 2010); |
4232 | DIE_UNLESS(y_length == 4); |
4233 | |
4234 | DIE_UNLESS(strcmp(dt, "2010-07-10 00:00:00" ) == 0); |
4235 | DIE_UNLESS(dt_length == 19); |
4236 | |
4237 | DIE_UNLESS(strcmp(ts_4, "0000-00-00 00:00:00" ) == 0); |
4238 | DIE_UNLESS(ts4_length == strlen("0000-00-00 00:00:00" )); |
4239 | |
4240 | DIE_UNLESS(strcmp(ts_6, "1999-12-29 00:00:00" ) == 0); |
4241 | DIE_UNLESS(ts6_length == 19); |
4242 | |
4243 | rc= mysql_stmt_fetch(stmt); |
4244 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
4245 | |
4246 | mysql_stmt_close(stmt); |
4247 | } |
4248 | |
4249 | |
4250 | /* Test fetching of str to all types */ |
4251 | |
4252 | static void test_fetch_str() |
4253 | { |
4254 | int rc; |
4255 | |
4256 | myheader("test_fetch_str" ); |
4257 | |
4258 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch" ); |
4259 | myquery(rc); |
4260 | |
4261 | rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 char(10), \ |
4262 | c2 char(10), \ |
4263 | c3 char(20), \ |
4264 | c4 char(20), \ |
4265 | c5 char(30), \ |
4266 | c6 char(40), \ |
4267 | c7 char(20))" ); |
4268 | myquery(rc); |
4269 | |
4270 | bind_fetch(3); |
4271 | } |
4272 | |
4273 | |
4274 | /* Test fetching of long to all types */ |
4275 | |
4276 | static void test_fetch_long() |
4277 | { |
4278 | int rc; |
4279 | |
4280 | myheader("test_fetch_long" ); |
4281 | |
4282 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch" ); |
4283 | myquery(rc); |
4284 | |
4285 | rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 int unsigned, \ |
4286 | c2 int unsigned, \ |
4287 | c3 int, \ |
4288 | c4 int, \ |
4289 | c5 int, \ |
4290 | c6 int unsigned, \ |
4291 | c7 int)" ); |
4292 | myquery(rc); |
4293 | |
4294 | bind_fetch(4); |
4295 | } |
4296 | |
4297 | |
4298 | /* Test fetching of short to all types */ |
4299 | |
4300 | static void test_fetch_short() |
4301 | { |
4302 | int rc; |
4303 | |
4304 | myheader("test_fetch_short" ); |
4305 | |
4306 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch" ); |
4307 | myquery(rc); |
4308 | |
4309 | rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 smallint unsigned, \ |
4310 | c2 smallint, \ |
4311 | c3 smallint unsigned, \ |
4312 | c4 smallint, \ |
4313 | c5 smallint, \ |
4314 | c6 smallint, \ |
4315 | c7 smallint unsigned)" ); |
4316 | myquery(rc); |
4317 | |
4318 | bind_fetch(5); |
4319 | } |
4320 | |
4321 | |
4322 | /* Test fetching of tiny to all types */ |
4323 | |
4324 | static void test_fetch_tiny() |
4325 | { |
4326 | int rc; |
4327 | |
4328 | myheader("test_fetch_tiny" ); |
4329 | |
4330 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch" ); |
4331 | myquery(rc); |
4332 | |
4333 | rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 tinyint unsigned, \ |
4334 | c2 tinyint, \ |
4335 | c3 tinyint unsigned, \ |
4336 | c4 tinyint, \ |
4337 | c5 tinyint, \ |
4338 | c6 tinyint, \ |
4339 | c7 tinyint unsigned)" ); |
4340 | myquery(rc); |
4341 | |
4342 | bind_fetch(3); |
4343 | |
4344 | } |
4345 | |
4346 | |
4347 | /* Test fetching of longlong to all types */ |
4348 | |
4349 | static void test_fetch_bigint() |
4350 | { |
4351 | int rc; |
4352 | |
4353 | myheader("test_fetch_bigint" ); |
4354 | |
4355 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch" ); |
4356 | myquery(rc); |
4357 | |
4358 | rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 bigint, \ |
4359 | c2 bigint, \ |
4360 | c3 bigint unsigned, \ |
4361 | c4 bigint unsigned, \ |
4362 | c5 bigint unsigned, \ |
4363 | c6 bigint unsigned, \ |
4364 | c7 bigint unsigned)" ); |
4365 | myquery(rc); |
4366 | |
4367 | bind_fetch(2); |
4368 | |
4369 | } |
4370 | |
4371 | |
4372 | /* Test fetching of float to all types */ |
4373 | |
4374 | static void test_fetch_float() |
4375 | { |
4376 | int rc; |
4377 | |
4378 | myheader("test_fetch_float" ); |
4379 | |
4380 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch" ); |
4381 | myquery(rc); |
4382 | |
4383 | rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 float(3), \ |
4384 | c2 float, \ |
4385 | c3 float unsigned, \ |
4386 | c4 float, \ |
4387 | c5 float, \ |
4388 | c6 float, \ |
4389 | c7 float(10) unsigned)" ); |
4390 | myquery(rc); |
4391 | |
4392 | bind_fetch(2); |
4393 | |
4394 | } |
4395 | |
4396 | |
4397 | /* Test fetching of double to all types */ |
4398 | |
4399 | static void test_fetch_double() |
4400 | { |
4401 | int rc; |
4402 | |
4403 | myheader("test_fetch_double" ); |
4404 | |
4405 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch" ); |
4406 | myquery(rc); |
4407 | |
4408 | rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 double(5, 2), " |
4409 | "c2 double unsigned, c3 double unsigned, " |
4410 | "c4 double unsigned, c5 double unsigned, " |
4411 | "c6 double unsigned, c7 double unsigned)" ); |
4412 | myquery(rc); |
4413 | |
4414 | bind_fetch(3); |
4415 | |
4416 | } |
4417 | |
4418 | |
4419 | /* Test simple prepare with all possible types */ |
4420 | |
4421 | static void test_prepare_ext() |
4422 | { |
4423 | MYSQL_STMT *stmt; |
4424 | int rc; |
4425 | char *sql; |
4426 | int nData= 1; |
4427 | char tData= 1; |
4428 | short sData= 10; |
4429 | longlong bData= 20; |
4430 | MYSQL_BIND my_bind[6]; |
4431 | char query[MAX_TEST_QUERY_LENGTH]; |
4432 | myheader("test_prepare_ext" ); |
4433 | |
4434 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_ext" ); |
4435 | myquery(rc); |
4436 | |
4437 | sql= (char *)"CREATE TABLE test_prepare_ext" |
4438 | "(" |
4439 | " c1 tinyint," |
4440 | " c2 smallint," |
4441 | " c3 mediumint," |
4442 | " c4 int," |
4443 | " c5 integer," |
4444 | " c6 bigint," |
4445 | " c7 float," |
4446 | " c8 double," |
4447 | " c9 double precision," |
4448 | " c10 real," |
4449 | " c11 decimal(7, 4)," |
4450 | " c12 numeric(8, 4)," |
4451 | " c13 date," |
4452 | " c14 datetime," |
4453 | " c15 timestamp," |
4454 | " c16 time," |
4455 | " c17 year," |
4456 | " c18 bit," |
4457 | " c19 bool," |
4458 | " c20 char," |
4459 | " c21 char(10)," |
4460 | " c22 varchar(30)," |
4461 | " c23 tinyblob," |
4462 | " c24 tinytext," |
4463 | " c25 blob," |
4464 | " c26 text," |
4465 | " c27 mediumblob," |
4466 | " c28 mediumtext," |
4467 | " c29 longblob," |
4468 | " c30 longtext," |
4469 | " c31 enum('one', 'two', 'three')," |
4470 | " c32 set('monday', 'tuesday', 'wednesday'))" ; |
4471 | |
4472 | rc= mysql_query(mysql, sql); |
4473 | myquery(rc); |
4474 | |
4475 | /* insert by prepare - all integers */ |
4476 | strmov(query, (char *)"INSERT INTO test_prepare_ext(c1, c2, c3, c4, c5, c6) VALUES(?, ?, ?, ?, ?, ?)" ); |
4477 | stmt= mysql_simple_prepare(mysql, query); |
4478 | check_stmt(stmt); |
4479 | |
4480 | verify_param_count(stmt, 6); |
4481 | |
4482 | /* Always bzero all members of bind parameter */ |
4483 | bzero((char*) my_bind, sizeof(my_bind)); |
4484 | |
4485 | /*tinyint*/ |
4486 | my_bind[0].buffer_type= MYSQL_TYPE_TINY; |
4487 | my_bind[0].buffer= (void *)&tData; |
4488 | |
4489 | /*smallint*/ |
4490 | my_bind[1].buffer_type= MYSQL_TYPE_SHORT; |
4491 | my_bind[1].buffer= (void *)&sData; |
4492 | |
4493 | /*mediumint*/ |
4494 | my_bind[2].buffer_type= MYSQL_TYPE_LONG; |
4495 | my_bind[2].buffer= (void *)&nData; |
4496 | |
4497 | /*int*/ |
4498 | my_bind[3].buffer_type= MYSQL_TYPE_LONG; |
4499 | my_bind[3].buffer= (void *)&nData; |
4500 | |
4501 | /*integer*/ |
4502 | my_bind[4].buffer_type= MYSQL_TYPE_LONG; |
4503 | my_bind[4].buffer= (void *)&nData; |
4504 | |
4505 | /*bigint*/ |
4506 | my_bind[5].buffer_type= MYSQL_TYPE_LONGLONG; |
4507 | my_bind[5].buffer= (void *)&bData; |
4508 | |
4509 | rc= mysql_stmt_bind_param(stmt, my_bind); |
4510 | check_execute(stmt, rc); |
4511 | |
4512 | /* |
4513 | * integer to integer |
4514 | */ |
4515 | for (nData= 0; nData<10; nData++, tData++, sData++, bData++) |
4516 | { |
4517 | rc= mysql_stmt_execute(stmt); |
4518 | check_execute(stmt, rc); |
4519 | } |
4520 | mysql_stmt_close(stmt); |
4521 | |
4522 | /* now fetch the results ..*/ |
4523 | |
4524 | stmt= mysql_simple_prepare(mysql, "SELECT c1, c2, c3, c4, c5, c6 " |
4525 | "FROM test_prepare_ext" ); |
4526 | check_stmt(stmt); |
4527 | |
4528 | /* get the result */ |
4529 | rc= mysql_stmt_execute(stmt); |
4530 | check_execute(stmt, rc); |
4531 | |
4532 | rc= my_process_stmt_result(stmt); |
4533 | DIE_UNLESS(nData == rc); |
4534 | |
4535 | mysql_stmt_close(stmt); |
4536 | } |
4537 | |
4538 | |
4539 | /* Test real and alias names */ |
4540 | |
4541 | static void test_field_names() |
4542 | { |
4543 | int rc; |
4544 | MYSQL_RES *result; |
4545 | |
4546 | myheader("test_field_names" ); |
4547 | |
4548 | if (!opt_silent) |
4549 | fprintf(stdout, "\n %d, %d, %d" , MYSQL_TYPE_DECIMAL, MYSQL_TYPE_NEWDATE, MYSQL_TYPE_ENUM); |
4550 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_field_names1" ); |
4551 | myquery(rc); |
4552 | |
4553 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_field_names2" ); |
4554 | myquery(rc); |
4555 | |
4556 | rc= mysql_query(mysql, "CREATE TABLE test_field_names1(id int, name varchar(50))" ); |
4557 | myquery(rc); |
4558 | |
4559 | rc= mysql_query(mysql, "CREATE TABLE test_field_names2(id int, name varchar(50))" ); |
4560 | myquery(rc); |
4561 | |
4562 | /* with table name included with TRUE column name */ |
4563 | rc= mysql_query(mysql, "SELECT id as 'id-alias' FROM test_field_names1" ); |
4564 | myquery(rc); |
4565 | |
4566 | result= mysql_use_result(mysql); |
4567 | mytest(result); |
4568 | |
4569 | rc= my_process_result_set(result); |
4570 | DIE_UNLESS(rc == 0); |
4571 | mysql_free_result(result); |
4572 | |
4573 | /* with table name included with TRUE column name */ |
4574 | rc= mysql_query(mysql, "SELECT t1.id as 'id-alias', test_field_names2.name FROM test_field_names1 t1, test_field_names2" ); |
4575 | myquery(rc); |
4576 | |
4577 | result= mysql_use_result(mysql); |
4578 | mytest(result); |
4579 | |
4580 | rc= my_process_result_set(result); |
4581 | DIE_UNLESS(rc == 0); |
4582 | mysql_free_result(result); |
4583 | } |
4584 | |
4585 | |
4586 | /* Test warnings */ |
4587 | |
4588 | static void test_warnings() |
4589 | { |
4590 | int rc; |
4591 | MYSQL_RES *result; |
4592 | |
4593 | myheader("test_warnings" ); |
4594 | |
4595 | mysql_query(mysql, "DROP TABLE if exists test_non_exists" ); |
4596 | |
4597 | rc= mysql_query(mysql, "DROP TABLE if exists test_non_exists" ); |
4598 | myquery(rc); |
4599 | |
4600 | if (!opt_silent) |
4601 | fprintf(stdout, "\n total warnings: %d" , mysql_warning_count(mysql)); |
4602 | rc= mysql_query(mysql, "SHOW WARNINGS" ); |
4603 | myquery(rc); |
4604 | |
4605 | result= mysql_store_result(mysql); |
4606 | mytest(result); |
4607 | |
4608 | rc= my_process_result_set(result); |
4609 | DIE_UNLESS(rc == 1); |
4610 | mysql_free_result(result); |
4611 | } |
4612 | |
4613 | |
4614 | /* Test errors */ |
4615 | |
4616 | static void test_errors() |
4617 | { |
4618 | int rc; |
4619 | MYSQL_RES *result; |
4620 | |
4621 | myheader("test_errors" ); |
4622 | |
4623 | mysql_query(mysql, "DROP TABLE if exists test_non_exists" ); |
4624 | |
4625 | rc= mysql_query(mysql, "DROP TABLE test_non_exists" ); |
4626 | myquery_r(rc); |
4627 | |
4628 | rc= mysql_query(mysql, "SHOW ERRORS" ); |
4629 | myquery(rc); |
4630 | |
4631 | result= mysql_store_result(mysql); |
4632 | mytest(result); |
4633 | |
4634 | (void) my_process_result_set(result); |
4635 | mysql_free_result(result); |
4636 | } |
4637 | |
4638 | |
4639 | /* Test simple prepare-insert */ |
4640 | |
4641 | static void test_insert() |
4642 | { |
4643 | MYSQL_STMT *stmt; |
4644 | int rc; |
4645 | char str_data[50]; |
4646 | char tiny_data; |
4647 | MYSQL_RES *result; |
4648 | MYSQL_BIND my_bind[2]; |
4649 | ulong length; |
4650 | |
4651 | myheader("test_insert" ); |
4652 | |
4653 | rc= mysql_autocommit(mysql, TRUE); |
4654 | myquery(rc); |
4655 | |
4656 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prep_insert" ); |
4657 | myquery(rc); |
4658 | |
4659 | rc= mysql_query(mysql, "CREATE TABLE test_prep_insert(col1 tinyint, \ |
4660 | col2 varchar(50))" ); |
4661 | myquery(rc); |
4662 | |
4663 | /* insert by prepare */ |
4664 | stmt= mysql_simple_prepare(mysql, |
4665 | "INSERT INTO test_prep_insert VALUES(?, ?)" ); |
4666 | check_stmt(stmt); |
4667 | |
4668 | verify_param_count(stmt, 2); |
4669 | |
4670 | /* |
4671 | We need to bzero bind structure because mysql_stmt_bind_param checks all |
4672 | its members. |
4673 | */ |
4674 | bzero((char*) my_bind, sizeof(my_bind)); |
4675 | |
4676 | /* tinyint */ |
4677 | my_bind[0].buffer_type= MYSQL_TYPE_TINY; |
4678 | my_bind[0].buffer= (void *)&tiny_data; |
4679 | |
4680 | /* string */ |
4681 | my_bind[1].buffer_type= MYSQL_TYPE_STRING; |
4682 | my_bind[1].buffer= str_data; |
4683 | my_bind[1].buffer_length= sizeof(str_data);; |
4684 | my_bind[1].length= &length; |
4685 | |
4686 | rc= mysql_stmt_bind_param(stmt, my_bind); |
4687 | check_execute(stmt, rc); |
4688 | |
4689 | /* now, execute the prepared statement to insert 10 records.. */ |
4690 | for (tiny_data= 0; tiny_data < 3; tiny_data++) |
4691 | { |
4692 | length= sprintf(str_data, "MySQL%d" , tiny_data); |
4693 | rc= mysql_stmt_execute(stmt); |
4694 | check_execute(stmt, rc); |
4695 | } |
4696 | |
4697 | mysql_stmt_close(stmt); |
4698 | |
4699 | /* now fetch the results ..*/ |
4700 | rc= mysql_commit(mysql); |
4701 | myquery(rc); |
4702 | |
4703 | /* test the results now, only one row should exist */ |
4704 | rc= mysql_query(mysql, "SELECT * FROM test_prep_insert" ); |
4705 | myquery(rc); |
4706 | |
4707 | /* get the result */ |
4708 | result= mysql_store_result(mysql); |
4709 | mytest(result); |
4710 | |
4711 | rc= my_process_result_set(result); |
4712 | DIE_UNLESS((int) tiny_data == rc); |
4713 | mysql_free_result(result); |
4714 | |
4715 | } |
4716 | |
4717 | |
4718 | /* Test simple prepare-resultset info */ |
4719 | |
4720 | static void test_prepare_resultset() |
4721 | { |
4722 | MYSQL_STMT *stmt; |
4723 | int rc; |
4724 | MYSQL_RES *result; |
4725 | |
4726 | myheader("test_prepare_resultset" ); |
4727 | |
4728 | rc= mysql_autocommit(mysql, TRUE); |
4729 | myquery(rc); |
4730 | |
4731 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_resultset" ); |
4732 | myquery(rc); |
4733 | |
4734 | rc= mysql_query(mysql, "CREATE TABLE test_prepare_resultset(id int, \ |
4735 | name varchar(50), extra double)" ); |
4736 | myquery(rc); |
4737 | |
4738 | stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_prepare_resultset" ); |
4739 | check_stmt(stmt); |
4740 | |
4741 | verify_param_count(stmt, 0); |
4742 | |
4743 | result= mysql_stmt_result_metadata(stmt); |
4744 | mytest(result); |
4745 | my_print_result_metadata(result); |
4746 | mysql_free_result(result); |
4747 | mysql_stmt_close(stmt); |
4748 | } |
4749 | |
4750 | |
4751 | /* Test field flags (verify .NET provider) */ |
4752 | |
4753 | static void test_field_flags() |
4754 | { |
4755 | int rc; |
4756 | MYSQL_RES *result; |
4757 | MYSQL_FIELD *field; |
4758 | unsigned int i; |
4759 | |
4760 | |
4761 | myheader("test_field_flags" ); |
4762 | |
4763 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_field_flags" ); |
4764 | myquery(rc); |
4765 | |
4766 | rc= mysql_query(mysql, "CREATE TABLE test_field_flags(id int NOT NULL AUTO_INCREMENT PRIMARY KEY, \ |
4767 | id1 int NOT NULL, \ |
4768 | id2 int UNIQUE, \ |
4769 | id3 int, \ |
4770 | id4 int NOT NULL, \ |
4771 | id5 int, \ |
4772 | KEY(id3, id4))" ); |
4773 | myquery(rc); |
4774 | |
4775 | /* with table name included with TRUE column name */ |
4776 | rc= mysql_query(mysql, "SELECT * FROM test_field_flags" ); |
4777 | myquery(rc); |
4778 | |
4779 | result= mysql_use_result(mysql); |
4780 | mytest(result); |
4781 | |
4782 | mysql_field_seek(result, 0); |
4783 | if (!opt_silent) |
4784 | fputc('\n', stdout); |
4785 | |
4786 | for(i= 0; i< mysql_num_fields(result); i++) |
4787 | { |
4788 | field= mysql_fetch_field(result); |
4789 | if (!opt_silent) |
4790 | { |
4791 | fprintf(stdout, "\n field:%d" , i); |
4792 | if (field->flags & NOT_NULL_FLAG) |
4793 | fprintf(stdout, "\n NOT_NULL_FLAG" ); |
4794 | if (field->flags & PRI_KEY_FLAG) |
4795 | fprintf(stdout, "\n PRI_KEY_FLAG" ); |
4796 | if (field->flags & UNIQUE_KEY_FLAG) |
4797 | fprintf(stdout, "\n UNIQUE_KEY_FLAG" ); |
4798 | if (field->flags & MULTIPLE_KEY_FLAG) |
4799 | fprintf(stdout, "\n MULTIPLE_KEY_FLAG" ); |
4800 | if (field->flags & AUTO_INCREMENT_FLAG) |
4801 | fprintf(stdout, "\n AUTO_INCREMENT_FLAG" ); |
4802 | |
4803 | } |
4804 | } |
4805 | mysql_free_result(result); |
4806 | } |
4807 | |
4808 | |
4809 | /* Test mysql_stmt_close for open stmts */ |
4810 | |
4811 | static void test_stmt_close() |
4812 | { |
4813 | MYSQL *lmysql; |
4814 | MYSQL_STMT *stmt1, *stmt2, *stmt3, *stmt_x; |
4815 | MYSQL_BIND my_bind[1]; |
4816 | MYSQL_RES *result; |
4817 | unsigned int count; |
4818 | int rc; |
4819 | char query[MAX_TEST_QUERY_LENGTH]; |
4820 | |
4821 | myheader("test_stmt_close" ); |
4822 | |
4823 | if (!opt_silent) |
4824 | fprintf(stdout, "\n Establishing a test connection ..." ); |
4825 | if (!(lmysql= mysql_client_init(NULL))) |
4826 | { |
4827 | myerror("mysql_client_init() failed" ); |
4828 | exit(1); |
4829 | } |
4830 | if (!(mysql_real_connect(lmysql, opt_host, opt_user, |
4831 | opt_password, current_db, opt_port, |
4832 | opt_unix_socket, 0))) |
4833 | { |
4834 | myerror("connection failed" ); |
4835 | exit(1); |
4836 | } |
4837 | mysql_options(lmysql, MYSQL_OPT_RECONNECT, &my_true); |
4838 | if (!opt_silent) |
4839 | fprintf(stdout, "OK" ); |
4840 | |
4841 | |
4842 | /* set AUTOCOMMIT to ON*/ |
4843 | mysql_autocommit(lmysql, TRUE); |
4844 | |
4845 | rc= mysql_query(lmysql, "SET SQL_MODE = ''" ); |
4846 | myquery(rc); |
4847 | |
4848 | rc= mysql_query(lmysql, "DROP TABLE IF EXISTS test_stmt_close" ); |
4849 | myquery(rc); |
4850 | |
4851 | rc= mysql_query(lmysql, "CREATE TABLE test_stmt_close(id int)" ); |
4852 | myquery(rc); |
4853 | |
4854 | strmov(query, "DO \"nothing\"" ); |
4855 | stmt1= mysql_simple_prepare(lmysql, query); |
4856 | check_stmt(stmt1); |
4857 | |
4858 | verify_param_count(stmt1, 0); |
4859 | |
4860 | strmov(query, "INSERT INTO test_stmt_close(id) VALUES(?)" ); |
4861 | stmt_x= mysql_simple_prepare(mysql, query); |
4862 | check_stmt(stmt_x); |
4863 | |
4864 | verify_param_count(stmt_x, 1); |
4865 | |
4866 | strmov(query, "UPDATE test_stmt_close SET id= ? WHERE id= ?" ); |
4867 | stmt3= mysql_simple_prepare(lmysql, query); |
4868 | check_stmt(stmt3); |
4869 | |
4870 | verify_param_count(stmt3, 2); |
4871 | |
4872 | strmov(query, "SELECT * FROM test_stmt_close WHERE id= ?" ); |
4873 | stmt2= mysql_simple_prepare(lmysql, query); |
4874 | check_stmt(stmt2); |
4875 | |
4876 | verify_param_count(stmt2, 1); |
4877 | |
4878 | rc= mysql_stmt_close(stmt1); |
4879 | if (!opt_silent) |
4880 | fprintf(stdout, "\n mysql_close_stmt(1) returned: %d" , rc); |
4881 | DIE_UNLESS(rc == 0); |
4882 | |
4883 | /* |
4884 | Originally we were going to close all statements automatically in |
4885 | mysql_close(). This proved to not work well - users weren't able to |
4886 | close statements by hand once mysql_close() had been called. |
4887 | Now mysql_close() doesn't free any statements, so this test doesn't |
4888 | serve its original designation any more. |
4889 | Here we free stmt2 and stmt3 by hand to avoid memory leaks. |
4890 | */ |
4891 | mysql_stmt_close(stmt2); |
4892 | mysql_stmt_close(stmt3); |
4893 | mysql_close(lmysql); |
4894 | |
4895 | /* |
4896 | We need to bzero bind structure because mysql_stmt_bind_param checks all |
4897 | its members. |
4898 | */ |
4899 | bzero((char*) my_bind, sizeof(my_bind)); |
4900 | |
4901 | my_bind[0].buffer= (void *)&count; |
4902 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
4903 | count= 100; |
4904 | |
4905 | rc= mysql_stmt_bind_param(stmt_x, my_bind); |
4906 | check_execute(stmt_x, rc); |
4907 | |
4908 | rc= mysql_stmt_execute(stmt_x); |
4909 | check_execute(stmt_x, rc); |
4910 | |
4911 | verify_st_affected_rows(stmt_x, 1); |
4912 | |
4913 | rc= mysql_stmt_close(stmt_x); |
4914 | if (!opt_silent) |
4915 | fprintf(stdout, "\n mysql_close_stmt(x) returned: %d" , rc); |
4916 | DIE_UNLESS( rc == 0); |
4917 | |
4918 | rc= mysql_query(mysql, "SELECT id FROM test_stmt_close" ); |
4919 | myquery(rc); |
4920 | |
4921 | result= mysql_store_result(mysql); |
4922 | mytest(result); |
4923 | |
4924 | rc= my_process_result_set(result); |
4925 | DIE_UNLESS(rc == 1); |
4926 | mysql_free_result(result); |
4927 | } |
4928 | |
4929 | |
4930 | /* Test simple set variable prepare */ |
4931 | |
4932 | static void test_set_variable() |
4933 | { |
4934 | MYSQL_STMT *stmt, *stmt1; |
4935 | int rc; |
4936 | int set_count, def_count, get_count; |
4937 | ulong length; |
4938 | char var[NAME_LEN+1]; |
4939 | MYSQL_BIND set_bind[1], get_bind[2]; |
4940 | |
4941 | myheader("test_set_variable" ); |
4942 | |
4943 | mysql_autocommit(mysql, TRUE); |
4944 | |
4945 | stmt1= mysql_simple_prepare(mysql, "show variables like 'max_error_count'" ); |
4946 | check_stmt(stmt1); |
4947 | |
4948 | /* |
4949 | We need to bzero bind structure because mysql_stmt_bind_param checks all |
4950 | its members. |
4951 | */ |
4952 | bzero((char*) get_bind, sizeof(get_bind)); |
4953 | |
4954 | get_bind[0].buffer_type= MYSQL_TYPE_STRING; |
4955 | get_bind[0].buffer= (void *)var; |
4956 | get_bind[0].length= &length; |
4957 | get_bind[0].buffer_length= (int)NAME_LEN; |
4958 | length= NAME_LEN; |
4959 | |
4960 | get_bind[1].buffer_type= MYSQL_TYPE_LONG; |
4961 | get_bind[1].buffer= (void *)&get_count; |
4962 | |
4963 | rc= mysql_stmt_execute(stmt1); |
4964 | check_execute(stmt1, rc); |
4965 | |
4966 | rc= mysql_stmt_bind_result(stmt1, get_bind); |
4967 | check_execute(stmt1, rc); |
4968 | |
4969 | rc= mysql_stmt_fetch(stmt1); |
4970 | check_execute(stmt1, rc); |
4971 | |
4972 | if (!opt_silent) |
4973 | fprintf(stdout, "\n max_error_count(default): %d" , get_count); |
4974 | def_count= get_count; |
4975 | |
4976 | DIE_UNLESS(strcmp(var, "max_error_count" ) == 0); |
4977 | rc= mysql_stmt_fetch(stmt1); |
4978 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
4979 | |
4980 | stmt= mysql_simple_prepare(mysql, "set max_error_count= ?" ); |
4981 | check_stmt(stmt); |
4982 | |
4983 | bzero((char*) set_bind, sizeof(set_bind)); |
4984 | |
4985 | set_bind[0].buffer_type= MYSQL_TYPE_LONG; |
4986 | set_bind[0].buffer= (void *)&set_count; |
4987 | |
4988 | rc= mysql_stmt_bind_param(stmt, set_bind); |
4989 | check_execute(stmt, rc); |
4990 | |
4991 | set_count= 31; |
4992 | rc= mysql_stmt_execute(stmt); |
4993 | check_execute(stmt, rc); |
4994 | |
4995 | mysql_commit(mysql); |
4996 | |
4997 | rc= mysql_stmt_execute(stmt1); |
4998 | check_execute(stmt1, rc); |
4999 | |
5000 | rc= mysql_stmt_fetch(stmt1); |
5001 | check_execute(stmt1, rc); |
5002 | |
5003 | if (!opt_silent) |
5004 | fprintf(stdout, "\n max_error_count : %d" , get_count); |
5005 | DIE_UNLESS(get_count == set_count); |
5006 | |
5007 | rc= mysql_stmt_fetch(stmt1); |
5008 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
5009 | |
5010 | /* restore back to default */ |
5011 | set_count= def_count; |
5012 | rc= mysql_stmt_execute(stmt); |
5013 | check_execute(stmt, rc); |
5014 | |
5015 | rc= mysql_stmt_execute(stmt1); |
5016 | check_execute(stmt1, rc); |
5017 | |
5018 | rc= mysql_stmt_fetch(stmt1); |
5019 | check_execute(stmt1, rc); |
5020 | |
5021 | if (!opt_silent) |
5022 | fprintf(stdout, "\n max_error_count(default): %d" , get_count); |
5023 | DIE_UNLESS(get_count == set_count); |
5024 | |
5025 | rc= mysql_stmt_fetch(stmt1); |
5026 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
5027 | |
5028 | mysql_stmt_close(stmt); |
5029 | mysql_stmt_close(stmt1); |
5030 | } |
5031 | |
5032 | /* Test FUNCTION field info / DATE_FORMAT() table_name . */ |
5033 | |
5034 | static void test_func_fields() |
5035 | { |
5036 | int rc; |
5037 | MYSQL_RES *result; |
5038 | MYSQL_FIELD *field; |
5039 | |
5040 | myheader("test_func_fields" ); |
5041 | |
5042 | rc= mysql_autocommit(mysql, TRUE); |
5043 | myquery(rc); |
5044 | |
5045 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_dateformat" ); |
5046 | myquery(rc); |
5047 | |
5048 | rc= mysql_query(mysql, "CREATE TABLE test_dateformat(id int, \ |
5049 | ts timestamp)" ); |
5050 | myquery(rc); |
5051 | |
5052 | rc= mysql_query(mysql, "INSERT INTO test_dateformat(id) values(10)" ); |
5053 | myquery(rc); |
5054 | |
5055 | rc= mysql_query(mysql, "SELECT ts FROM test_dateformat" ); |
5056 | myquery(rc); |
5057 | |
5058 | result= mysql_store_result(mysql); |
5059 | mytest(result); |
5060 | |
5061 | field= mysql_fetch_field(result); |
5062 | mytest(field); |
5063 | if (!opt_silent) |
5064 | fprintf(stdout, "\n table name: `%s` (expected: `%s`)" , field->table, |
5065 | "test_dateformat" ); |
5066 | DIE_UNLESS(strcmp(field->table, "test_dateformat" ) == 0); |
5067 | |
5068 | field= mysql_fetch_field(result); |
5069 | mytest_r(field); /* no more fields */ |
5070 | |
5071 | mysql_free_result(result); |
5072 | |
5073 | /* DATE_FORMAT */ |
5074 | rc= mysql_query(mysql, "SELECT DATE_FORMAT(ts, '%Y') AS 'venu' FROM test_dateformat" ); |
5075 | myquery(rc); |
5076 | |
5077 | result= mysql_store_result(mysql); |
5078 | mytest(result); |
5079 | |
5080 | field= mysql_fetch_field(result); |
5081 | mytest(field); |
5082 | if (!opt_silent) |
5083 | fprintf(stdout, "\n table name: `%s` (expected: `%s`)" , field->table, "" ); |
5084 | DIE_UNLESS(field->table[0] == '\0'); |
5085 | |
5086 | field= mysql_fetch_field(result); |
5087 | mytest_r(field); /* no more fields */ |
5088 | |
5089 | mysql_free_result(result); |
5090 | |
5091 | /* FIELD ALIAS TEST */ |
5092 | rc= mysql_query(mysql, "SELECT DATE_FORMAT(ts, '%Y') AS 'YEAR' FROM test_dateformat" ); |
5093 | myquery(rc); |
5094 | |
5095 | result= mysql_store_result(mysql); |
5096 | mytest(result); |
5097 | |
5098 | field= mysql_fetch_field(result); |
5099 | mytest(field); |
5100 | if (!opt_silent) |
5101 | { |
5102 | printf("\n field name: `%s` (expected: `%s`)" , field->name, "YEAR" ); |
5103 | printf("\n field org name: `%s` (expected: `%s`)" , field->org_name, "" ); |
5104 | } |
5105 | DIE_UNLESS(strcmp(field->name, "YEAR" ) == 0); |
5106 | DIE_UNLESS(field->org_name[0] == '\0'); |
5107 | |
5108 | field= mysql_fetch_field(result); |
5109 | mytest_r(field); /* no more fields */ |
5110 | |
5111 | mysql_free_result(result); |
5112 | } |
5113 | |
5114 | |
5115 | /* Multiple stmts .. */ |
5116 | |
5117 | static void test_multi_stmt() |
5118 | { |
5119 | |
5120 | MYSQL_STMT *stmt, *stmt1, *stmt2; |
5121 | int rc; |
5122 | uint32 id; |
5123 | char name[50]; |
5124 | MYSQL_BIND my_bind[2]; |
5125 | ulong length[2]; |
5126 | my_bool is_null[2]; |
5127 | myheader("test_multi_stmt" ); |
5128 | |
5129 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_multi_table" ); |
5130 | myquery(rc); |
5131 | |
5132 | rc= mysql_query(mysql, "CREATE TABLE test_multi_table(id int, name char(20))" ); |
5133 | myquery(rc); |
5134 | |
5135 | rc= mysql_query(mysql, "INSERT INTO test_multi_table values(10, 'mysql')" ); |
5136 | myquery(rc); |
5137 | |
5138 | stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_multi_table " |
5139 | "WHERE id= ?" ); |
5140 | check_stmt(stmt); |
5141 | |
5142 | stmt2= mysql_simple_prepare(mysql, "UPDATE test_multi_table " |
5143 | "SET name='updated' WHERE id=10" ); |
5144 | check_stmt(stmt2); |
5145 | |
5146 | verify_param_count(stmt, 1); |
5147 | |
5148 | /* |
5149 | We need to bzero bind structure because mysql_stmt_bind_param checks all |
5150 | its members. |
5151 | */ |
5152 | bzero((char*) my_bind, sizeof(my_bind)); |
5153 | |
5154 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
5155 | my_bind[0].buffer= (void *)&id; |
5156 | my_bind[0].is_null= &is_null[0]; |
5157 | my_bind[0].length= &length[0]; |
5158 | is_null[0]= 0; |
5159 | length[0]= 0; |
5160 | |
5161 | my_bind[1].buffer_type= MYSQL_TYPE_STRING; |
5162 | my_bind[1].buffer= (void *)name; |
5163 | my_bind[1].buffer_length= sizeof(name); |
5164 | my_bind[1].length= &length[1]; |
5165 | my_bind[1].is_null= &is_null[1]; |
5166 | |
5167 | rc= mysql_stmt_bind_param(stmt, my_bind); |
5168 | check_execute(stmt, rc); |
5169 | |
5170 | rc= mysql_stmt_bind_result(stmt, my_bind); |
5171 | check_execute(stmt, rc); |
5172 | |
5173 | id= 10; |
5174 | rc= mysql_stmt_execute(stmt); |
5175 | check_execute(stmt, rc); |
5176 | |
5177 | id= 999; |
5178 | rc= mysql_stmt_fetch(stmt); |
5179 | check_execute(stmt, rc); |
5180 | |
5181 | if (!opt_silent) |
5182 | { |
5183 | fprintf(stdout, "\n int_data: %lu(%lu)" , (ulong) id, length[0]); |
5184 | fprintf(stdout, "\n str_data: %s(%lu)" , name, length[1]); |
5185 | } |
5186 | DIE_UNLESS(id == 10); |
5187 | DIE_UNLESS(strcmp(name, "mysql" ) == 0); |
5188 | |
5189 | rc= mysql_stmt_fetch(stmt); |
5190 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
5191 | |
5192 | /* alter the table schema now */ |
5193 | stmt1= mysql_simple_prepare(mysql, "DELETE FROM test_multi_table " |
5194 | "WHERE id= ? AND " |
5195 | "CONVERT(name USING utf8)=?" ); |
5196 | check_stmt(stmt1); |
5197 | |
5198 | verify_param_count(stmt1, 2); |
5199 | |
5200 | rc= mysql_stmt_bind_param(stmt1, my_bind); |
5201 | check_execute(stmt1, rc); |
5202 | |
5203 | rc= mysql_stmt_execute(stmt2); |
5204 | check_execute(stmt2, rc); |
5205 | |
5206 | verify_st_affected_rows(stmt2, 1); |
5207 | |
5208 | rc= mysql_stmt_execute(stmt); |
5209 | check_execute(stmt, rc); |
5210 | |
5211 | rc= mysql_stmt_fetch(stmt); |
5212 | check_execute(stmt, rc); |
5213 | |
5214 | if (!opt_silent) |
5215 | { |
5216 | fprintf(stdout, "\n int_data: %lu(%lu)" , (ulong) id, length[0]); |
5217 | fprintf(stdout, "\n str_data: %s(%lu)" , name, length[1]); |
5218 | } |
5219 | DIE_UNLESS(id == 10); |
5220 | DIE_UNLESS(strcmp(name, "updated" ) == 0); |
5221 | |
5222 | rc= mysql_stmt_fetch(stmt); |
5223 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
5224 | |
5225 | rc= mysql_stmt_execute(stmt1); |
5226 | check_execute(stmt1, rc); |
5227 | |
5228 | verify_st_affected_rows(stmt1, 1); |
5229 | |
5230 | mysql_stmt_close(stmt1); |
5231 | |
5232 | rc= mysql_stmt_execute(stmt); |
5233 | check_execute(stmt, rc); |
5234 | |
5235 | rc= mysql_stmt_fetch(stmt); |
5236 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
5237 | |
5238 | rc= my_stmt_result("SELECT * FROM test_multi_table" ); |
5239 | DIE_UNLESS(rc == 0); |
5240 | |
5241 | mysql_stmt_close(stmt); |
5242 | mysql_stmt_close(stmt2); |
5243 | |
5244 | } |
5245 | |
5246 | |
5247 | /* Test simple sample - manual */ |
5248 | |
5249 | static void test_manual_sample() |
5250 | { |
5251 | unsigned int param_count; |
5252 | MYSQL_STMT *stmt; |
5253 | short small_data; |
5254 | int int_data; |
5255 | int rc; |
5256 | char str_data[50]; |
5257 | ulonglong affected_rows; |
5258 | MYSQL_BIND my_bind[3]; |
5259 | my_bool is_null; |
5260 | char query[MAX_TEST_QUERY_LENGTH]; |
5261 | |
5262 | myheader("test_manual_sample" ); |
5263 | |
5264 | /* |
5265 | Sample which is incorporated directly in the manual under Prepared |
5266 | statements section (Example from mysql_stmt_execute() |
5267 | */ |
5268 | |
5269 | mysql_autocommit(mysql, 1); |
5270 | if (mysql_query(mysql, "DROP TABLE IF EXISTS test_table" )) |
5271 | { |
5272 | fprintf(stderr, "\n drop table failed" ); |
5273 | fprintf(stderr, "\n %s" , mysql_error(mysql)); |
5274 | exit(1); |
5275 | } |
5276 | if (mysql_query(mysql, "CREATE TABLE test_table(col1 int, col2 varchar(50), \ |
5277 | col3 smallint, \ |
5278 | col4 timestamp)" )) |
5279 | { |
5280 | fprintf(stderr, "\n create table failed" ); |
5281 | fprintf(stderr, "\n %s" , mysql_error(mysql)); |
5282 | exit(1); |
5283 | } |
5284 | |
5285 | /* Prepare a insert query with 3 parameters */ |
5286 | strmov(query, "INSERT INTO test_table(col1, col2, col3) values(?, ?, ?)" ); |
5287 | if (!(stmt= mysql_simple_prepare(mysql, query))) |
5288 | { |
5289 | fprintf(stderr, "\n prepare, insert failed" ); |
5290 | fprintf(stderr, "\n %s" , mysql_error(mysql)); |
5291 | exit(1); |
5292 | } |
5293 | if (!opt_silent) |
5294 | fprintf(stdout, "\n prepare, insert successful" ); |
5295 | |
5296 | /* Get the parameter count from the statement */ |
5297 | param_count= mysql_stmt_param_count(stmt); |
5298 | |
5299 | if (!opt_silent) |
5300 | fprintf(stdout, "\n total parameters in insert: %d" , param_count); |
5301 | if (param_count != 3) /* validate parameter count */ |
5302 | { |
5303 | fprintf(stderr, "\n invalid parameter count returned by MySQL" ); |
5304 | exit(1); |
5305 | } |
5306 | |
5307 | /* Bind the data for the parameters */ |
5308 | |
5309 | /* |
5310 | We need to bzero bind structure because mysql_stmt_bind_param checks all |
5311 | its members. |
5312 | */ |
5313 | bzero((char*) my_bind, sizeof(my_bind)); |
5314 | |
5315 | /* INTEGER PART */ |
5316 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
5317 | my_bind[0].buffer= (void *)&int_data; |
5318 | |
5319 | /* STRING PART */ |
5320 | my_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING; |
5321 | my_bind[1].buffer= (void *)str_data; |
5322 | my_bind[1].buffer_length= sizeof(str_data); |
5323 | |
5324 | /* SMALLINT PART */ |
5325 | my_bind[2].buffer_type= MYSQL_TYPE_SHORT; |
5326 | my_bind[2].buffer= (void *)&small_data; |
5327 | my_bind[2].is_null= &is_null; |
5328 | is_null= 0; |
5329 | |
5330 | /* Bind the buffers */ |
5331 | if (mysql_stmt_bind_param(stmt, my_bind)) |
5332 | { |
5333 | fprintf(stderr, "\n param bind failed" ); |
5334 | fprintf(stderr, "\n %s" , mysql_stmt_error(stmt)); |
5335 | exit(1); |
5336 | } |
5337 | |
5338 | /* Specify the data */ |
5339 | int_data= 10; /* integer */ |
5340 | strmov(str_data, "MySQL" ); /* string */ |
5341 | |
5342 | /* INSERT SMALLINT data as NULL */ |
5343 | is_null= 1; |
5344 | |
5345 | /* Execute the insert statement - 1*/ |
5346 | if (mysql_stmt_execute(stmt)) |
5347 | { |
5348 | fprintf(stderr, "\n execute 1 failed" ); |
5349 | fprintf(stderr, "\n %s" , mysql_stmt_error(stmt)); |
5350 | exit(1); |
5351 | } |
5352 | |
5353 | /* Get the total rows affected */ |
5354 | affected_rows= mysql_stmt_affected_rows(stmt); |
5355 | |
5356 | if (!opt_silent) |
5357 | fprintf(stdout, "\n total affected rows: %ld" , (ulong) affected_rows); |
5358 | if (affected_rows != 1) /* validate affected rows */ |
5359 | { |
5360 | fprintf(stderr, "\n invalid affected rows by MySQL" ); |
5361 | exit(1); |
5362 | } |
5363 | |
5364 | /* Re-execute the insert, by changing the values */ |
5365 | int_data= 1000; |
5366 | strmov(str_data, "The most popular open source database" ); |
5367 | small_data= 1000; /* smallint */ |
5368 | is_null= 0; /* reset */ |
5369 | |
5370 | /* Execute the insert statement - 2*/ |
5371 | if (mysql_stmt_execute(stmt)) |
5372 | { |
5373 | fprintf(stderr, "\n execute 2 failed" ); |
5374 | fprintf(stderr, "\n %s" , mysql_stmt_error(stmt)); |
5375 | exit(1); |
5376 | } |
5377 | |
5378 | /* Get the total rows affected */ |
5379 | affected_rows= mysql_stmt_affected_rows(stmt); |
5380 | |
5381 | if (!opt_silent) |
5382 | fprintf(stdout, "\n total affected rows: %ld" , (ulong) affected_rows); |
5383 | if (affected_rows != 1) /* validate affected rows */ |
5384 | { |
5385 | fprintf(stderr, "\n invalid affected rows by MySQL" ); |
5386 | exit(1); |
5387 | } |
5388 | |
5389 | /* Close the statement */ |
5390 | if (mysql_stmt_close(stmt)) |
5391 | { |
5392 | fprintf(stderr, "\n failed while closing the statement" ); |
5393 | fprintf(stderr, "\n %s" , mysql_stmt_error(stmt)); |
5394 | exit(1); |
5395 | } |
5396 | rc= my_stmt_result("SELECT * FROM test_table" ); |
5397 | DIE_UNLESS(rc == 2); |
5398 | |
5399 | /* DROP THE TABLE */ |
5400 | if (mysql_query(mysql, "DROP TABLE test_table" )) |
5401 | { |
5402 | fprintf(stderr, "\n drop table failed" ); |
5403 | fprintf(stderr, "\n %s" , mysql_error(mysql)); |
5404 | exit(1); |
5405 | } |
5406 | if (!opt_silent) |
5407 | fprintf(stdout, "Success !!!" ); |
5408 | } |
5409 | |
5410 | |
5411 | /* Test alter table scenario in the middle of prepare */ |
5412 | |
5413 | static void test_prepare_alter() |
5414 | { |
5415 | MYSQL_STMT *stmt; |
5416 | int rc, id; |
5417 | MYSQL_BIND my_bind[1]; |
5418 | my_bool is_null; |
5419 | |
5420 | myheader("test_prepare_alter" ); |
5421 | |
5422 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prep_alter" ); |
5423 | myquery(rc); |
5424 | |
5425 | rc= mysql_query(mysql, "CREATE TABLE test_prep_alter(id int, name char(20))" ); |
5426 | myquery(rc); |
5427 | |
5428 | rc= mysql_query(mysql, "INSERT INTO test_prep_alter values(10, 'venu'), (20, 'mysql')" ); |
5429 | myquery(rc); |
5430 | |
5431 | stmt= mysql_simple_prepare(mysql, "INSERT INTO test_prep_alter VALUES(?, 'monty')" ); |
5432 | check_stmt(stmt); |
5433 | |
5434 | verify_param_count(stmt, 1); |
5435 | |
5436 | /* |
5437 | We need to bzero bind structure because mysql_stmt_bind_param checks all |
5438 | its members. |
5439 | */ |
5440 | bzero((char*) my_bind, sizeof(my_bind)); |
5441 | |
5442 | is_null= 0; |
5443 | my_bind[0].buffer_type= MYSQL_TYPE_SHORT; |
5444 | my_bind[0].buffer= (void *)&id; |
5445 | my_bind[0].is_null= &is_null; |
5446 | |
5447 | rc= mysql_stmt_bind_param(stmt, my_bind); |
5448 | check_execute(stmt, rc); |
5449 | |
5450 | id= 30; |
5451 | rc= mysql_stmt_execute(stmt); |
5452 | check_execute(stmt, rc); |
5453 | |
5454 | if (thread_query("ALTER TABLE test_prep_alter change id id_new varchar(20)" )) |
5455 | exit(1); |
5456 | |
5457 | is_null= 1; |
5458 | rc= mysql_stmt_execute(stmt); |
5459 | check_execute(stmt, rc); |
5460 | |
5461 | rc= my_stmt_result("SELECT * FROM test_prep_alter" ); |
5462 | DIE_UNLESS(rc == 4); |
5463 | |
5464 | mysql_stmt_close(stmt); |
5465 | } |
5466 | |
5467 | |
5468 | /* Test the support of multi-statement executions */ |
5469 | |
5470 | static void test_multi_statements() |
5471 | { |
5472 | MYSQL *mysql_local; |
5473 | MYSQL_RES *result; |
5474 | int rc; |
5475 | |
5476 | const char *query= "\ |
5477 | DROP TABLE IF EXISTS test_multi_tab;\ |
5478 | CREATE TABLE test_multi_tab(id int, name char(20));\ |
5479 | INSERT INTO test_multi_tab(id) VALUES(10), (20);\ |
5480 | INSERT INTO test_multi_tab VALUES(20, 'insert;comma');\ |
5481 | SELECT * FROM test_multi_tab;\ |
5482 | UPDATE test_multi_tab SET name='new;name' WHERE id=20;\ |
5483 | DELETE FROM test_multi_tab WHERE name='new;name';\ |
5484 | SELECT * FROM test_multi_tab;\ |
5485 | DELETE FROM test_multi_tab WHERE id=10;\ |
5486 | SELECT * FROM test_multi_tab;\ |
5487 | DROP TABLE test_multi_tab;\ |
5488 | select 1;\ |
5489 | DROP TABLE IF EXISTS test_multi_tab" ; |
5490 | uint count, exp_value; |
5491 | uint rows[]= {0, 0, 2, 1, 3, 2, 2, 1, 1, 0, 0, 1, 0}; |
5492 | |
5493 | myheader("test_multi_statements" ); |
5494 | |
5495 | /* |
5496 | First test that we get an error for multi statements |
5497 | (Because default connection is not opened with CLIENT_MULTI_STATEMENTS) |
5498 | */ |
5499 | rc= mysql_query(mysql, query); /* syntax error */ |
5500 | myquery_r(rc); |
5501 | |
5502 | rc= mysql_next_result(mysql); |
5503 | DIE_UNLESS(rc == -1); |
5504 | rc= mysql_more_results(mysql); |
5505 | DIE_UNLESS(rc == 0); |
5506 | |
5507 | if (!(mysql_local= mysql_client_init(NULL))) |
5508 | { |
5509 | fprintf(stdout, "\n mysql_client_init() failed" ); |
5510 | exit(1); |
5511 | } |
5512 | |
5513 | /* Create connection that supports multi statements */ |
5514 | if (!(mysql_real_connect(mysql_local, opt_host, opt_user, |
5515 | opt_password, current_db, opt_port, |
5516 | opt_unix_socket, CLIENT_MULTI_STATEMENTS))) |
5517 | { |
5518 | fprintf(stdout, "\n connection failed(%s)" , mysql_error(mysql_local)); |
5519 | exit(1); |
5520 | } |
5521 | mysql_options(mysql_local, MYSQL_OPT_RECONNECT, &my_true); |
5522 | |
5523 | rc= mysql_query(mysql_local, query); |
5524 | myquery(rc); |
5525 | |
5526 | for (count= 0 ; count < array_elements(rows) ; count++) |
5527 | { |
5528 | if (!opt_silent) |
5529 | fprintf(stdout, "\n Query %d: " , count); |
5530 | if ((result= mysql_store_result(mysql_local))) |
5531 | { |
5532 | (void) my_process_result_set(result); |
5533 | mysql_free_result(result); |
5534 | } |
5535 | else if (!opt_silent) |
5536 | fprintf(stdout, "OK, %ld row(s) affected, %ld warning(s)\n" , |
5537 | (ulong) mysql_affected_rows(mysql_local), |
5538 | (ulong) mysql_warning_count(mysql_local)); |
5539 | |
5540 | exp_value= (uint) mysql_affected_rows(mysql_local); |
5541 | if (rows[count] != exp_value) |
5542 | { |
5543 | fprintf(stderr, "row %d had affected rows: %d, should be %d\n" , |
5544 | count, exp_value, rows[count]); |
5545 | exit(1); |
5546 | } |
5547 | if (count != array_elements(rows) -1) |
5548 | { |
5549 | if (!(rc= mysql_more_results(mysql_local))) |
5550 | { |
5551 | fprintf(stdout, |
5552 | "mysql_more_result returned wrong value: %d for row %d\n" , |
5553 | rc, count); |
5554 | exit(1); |
5555 | } |
5556 | if ((rc= mysql_next_result(mysql_local))) |
5557 | { |
5558 | exp_value= mysql_errno(mysql_local); |
5559 | |
5560 | exit(1); |
5561 | } |
5562 | } |
5563 | else |
5564 | { |
5565 | rc= mysql_more_results(mysql_local); |
5566 | DIE_UNLESS(rc == 0); |
5567 | rc= mysql_next_result(mysql_local); |
5568 | DIE_UNLESS(rc == -1); |
5569 | } |
5570 | } |
5571 | |
5572 | /* check that errors abort multi statements */ |
5573 | |
5574 | rc= mysql_query(mysql_local, "select 1+1+a;select 1+1" ); |
5575 | myquery_r(rc); |
5576 | rc= mysql_more_results(mysql_local); |
5577 | DIE_UNLESS(rc == 0); |
5578 | rc= mysql_next_result(mysql_local); |
5579 | DIE_UNLESS(rc == -1); |
5580 | |
5581 | rc= mysql_query(mysql_local, "select 1+1;select 1+1+a;select 1" ); |
5582 | myquery(rc); |
5583 | result= mysql_store_result(mysql_local); |
5584 | mytest(result); |
5585 | mysql_free_result(result); |
5586 | rc= mysql_more_results(mysql_local); |
5587 | DIE_UNLESS(rc == 1); |
5588 | rc= mysql_next_result(mysql_local); |
5589 | DIE_UNLESS(rc > 0); |
5590 | |
5591 | /* |
5592 | Ensure that we can now do a simple query (this checks that the server is |
5593 | not trying to send us the results for the last 'select 1' |
5594 | */ |
5595 | rc= mysql_query(mysql_local, "select 1+1+1" ); |
5596 | myquery(rc); |
5597 | result= mysql_store_result(mysql_local); |
5598 | mytest(result); |
5599 | (void) my_process_result_set(result); |
5600 | mysql_free_result(result); |
5601 | |
5602 | /* |
5603 | Check if errors in one of the queries handled properly. |
5604 | */ |
5605 | rc= mysql_query(mysql_local, "select 1; select * from not_existing_table" ); |
5606 | myquery(rc); |
5607 | result= mysql_store_result(mysql_local); |
5608 | mysql_free_result(result); |
5609 | |
5610 | rc= mysql_next_result(mysql_local); |
5611 | DIE_UNLESS(rc > 0); |
5612 | |
5613 | rc= mysql_next_result(mysql_local); |
5614 | DIE_UNLESS(rc < 0); |
5615 | |
5616 | mysql_close(mysql_local); |
5617 | } |
5618 | |
5619 | |
5620 | /* |
5621 | Check that Prepared statement cannot contain several |
5622 | SQL statements |
5623 | */ |
5624 | |
5625 | static void test_prepare_multi_statements() |
5626 | { |
5627 | MYSQL *mysql_local; |
5628 | MYSQL_STMT *stmt; |
5629 | char query[MAX_TEST_QUERY_LENGTH]; |
5630 | myheader("test_prepare_multi_statements" ); |
5631 | |
5632 | if (!(mysql_local= mysql_client_init(NULL))) |
5633 | { |
5634 | fprintf(stderr, "\n mysql_client_init() failed" ); |
5635 | exit(1); |
5636 | } |
5637 | |
5638 | if (!(mysql_real_connect(mysql_local, opt_host, opt_user, |
5639 | opt_password, current_db, opt_port, |
5640 | opt_unix_socket, CLIENT_MULTI_STATEMENTS))) |
5641 | { |
5642 | fprintf(stderr, "\n connection failed(%s)" , mysql_error(mysql_local)); |
5643 | exit(1); |
5644 | } |
5645 | mysql_options(mysql_local, MYSQL_OPT_RECONNECT, &my_true); |
5646 | strmov(query, "select 1; select 'another value'" ); |
5647 | stmt= mysql_simple_prepare(mysql_local, query); |
5648 | check_stmt_r(stmt); |
5649 | mysql_close(mysql_local); |
5650 | } |
5651 | |
5652 | |
5653 | /* Test simple bind store result */ |
5654 | |
5655 | static void test_store_result() |
5656 | { |
5657 | MYSQL_STMT *stmt; |
5658 | int rc; |
5659 | int32 nData; |
5660 | char szData[100]; |
5661 | MYSQL_BIND my_bind[2]; |
5662 | ulong length, length1; |
5663 | my_bool is_null[2]; |
5664 | |
5665 | myheader("test_store_result" ); |
5666 | |
5667 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_store_result" ); |
5668 | myquery(rc); |
5669 | |
5670 | rc= mysql_query(mysql, "CREATE TABLE test_store_result(col1 int , col2 varchar(50))" ); |
5671 | myquery(rc); |
5672 | |
5673 | rc= mysql_query(mysql, "INSERT INTO test_store_result VALUES(10, 'venu'), (20, 'mysql')" ); |
5674 | myquery(rc); |
5675 | |
5676 | rc= mysql_query(mysql, "INSERT INTO test_store_result(col2) VALUES('monty')" ); |
5677 | myquery(rc); |
5678 | |
5679 | rc= mysql_commit(mysql); |
5680 | myquery(rc); |
5681 | |
5682 | /* fetch */ |
5683 | bzero((char*) my_bind, sizeof(my_bind)); |
5684 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
5685 | my_bind[0].buffer= (void *) &nData; /* integer data */ |
5686 | my_bind[0].length= &length; |
5687 | my_bind[0].is_null= &is_null[0]; |
5688 | |
5689 | length= 0; |
5690 | my_bind[1].buffer_type= MYSQL_TYPE_STRING; |
5691 | my_bind[1].buffer= szData; /* string data */ |
5692 | my_bind[1].buffer_length= sizeof(szData); |
5693 | my_bind[1].length= &length1; |
5694 | my_bind[1].is_null= &is_null[1]; |
5695 | length1= 0; |
5696 | |
5697 | stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_store_result" ); |
5698 | check_stmt(stmt); |
5699 | |
5700 | rc= mysql_stmt_bind_result(stmt, my_bind); |
5701 | check_execute(stmt, rc); |
5702 | |
5703 | rc= mysql_stmt_execute(stmt); |
5704 | check_execute(stmt, rc); |
5705 | |
5706 | rc= mysql_stmt_store_result(stmt); |
5707 | check_execute(stmt, rc); |
5708 | |
5709 | rc= mysql_stmt_fetch(stmt); |
5710 | check_execute(stmt, rc); |
5711 | |
5712 | if (!opt_silent) |
5713 | fprintf(stdout, "\n row 1: %ld, %s(%lu)" , (long) nData, szData, length1); |
5714 | DIE_UNLESS(nData == 10); |
5715 | DIE_UNLESS(strcmp(szData, "venu" ) == 0); |
5716 | DIE_UNLESS(length1 == 4); |
5717 | |
5718 | rc= mysql_stmt_fetch(stmt); |
5719 | check_execute(stmt, rc); |
5720 | |
5721 | if (!opt_silent) |
5722 | fprintf(stdout, "\n row 2: %ld, %s(%lu)" , (long) nData, szData, length1); |
5723 | DIE_UNLESS(nData == 20); |
5724 | DIE_UNLESS(strcmp(szData, "mysql" ) == 0); |
5725 | DIE_UNLESS(length1 == 5); |
5726 | |
5727 | length= 99; |
5728 | rc= mysql_stmt_fetch(stmt); |
5729 | check_execute(stmt, rc); |
5730 | |
5731 | if (!opt_silent && is_null[0]) |
5732 | fprintf(stdout, "\n row 3: NULL, %s(%lu)" , szData, length1); |
5733 | DIE_UNLESS(is_null[0]); |
5734 | DIE_UNLESS(strcmp(szData, "monty" ) == 0); |
5735 | DIE_UNLESS(length1 == 5); |
5736 | |
5737 | rc= mysql_stmt_fetch(stmt); |
5738 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
5739 | |
5740 | rc= mysql_stmt_execute(stmt); |
5741 | check_execute(stmt, rc); |
5742 | |
5743 | rc= mysql_stmt_store_result(stmt); |
5744 | check_execute(stmt, rc); |
5745 | |
5746 | rc= mysql_stmt_fetch(stmt); |
5747 | check_execute(stmt, rc); |
5748 | |
5749 | if (!opt_silent) |
5750 | fprintf(stdout, "\n row 1: %ld, %s(%lu)" , (long) nData, szData, length1); |
5751 | DIE_UNLESS(nData == 10); |
5752 | DIE_UNLESS(strcmp(szData, "venu" ) == 0); |
5753 | DIE_UNLESS(length1 == 4); |
5754 | |
5755 | rc= mysql_stmt_fetch(stmt); |
5756 | check_execute(stmt, rc); |
5757 | |
5758 | if (!opt_silent) |
5759 | fprintf(stdout, "\n row 2: %ld, %s(%lu)" , (long) nData, szData, length1); |
5760 | DIE_UNLESS(nData == 20); |
5761 | DIE_UNLESS(strcmp(szData, "mysql" ) == 0); |
5762 | DIE_UNLESS(length1 == 5); |
5763 | |
5764 | length= 99; |
5765 | rc= mysql_stmt_fetch(stmt); |
5766 | check_execute(stmt, rc); |
5767 | |
5768 | if (!opt_silent && is_null[0]) |
5769 | fprintf(stdout, "\n row 3: NULL, %s(%lu)" , szData, length1); |
5770 | DIE_UNLESS(is_null[0]); |
5771 | DIE_UNLESS(strcmp(szData, "monty" ) == 0); |
5772 | DIE_UNLESS(length1 == 5); |
5773 | |
5774 | rc= mysql_stmt_fetch(stmt); |
5775 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
5776 | |
5777 | mysql_stmt_close(stmt); |
5778 | } |
5779 | |
5780 | |
5781 | /* Test simple bind store result */ |
5782 | |
5783 | static void test_store_result1() |
5784 | { |
5785 | MYSQL_STMT *stmt; |
5786 | int rc; |
5787 | |
5788 | myheader("test_store_result1" ); |
5789 | |
5790 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_store_result" ); |
5791 | myquery(rc); |
5792 | |
5793 | rc= mysql_query(mysql, "CREATE TABLE test_store_result(col1 int , col2 varchar(50))" ); |
5794 | myquery(rc); |
5795 | |
5796 | rc= mysql_query(mysql, "INSERT INTO test_store_result VALUES(10, 'venu'), (20, 'mysql')" ); |
5797 | myquery(rc); |
5798 | |
5799 | rc= mysql_query(mysql, "INSERT INTO test_store_result(col2) VALUES('monty')" ); |
5800 | myquery(rc); |
5801 | |
5802 | rc= mysql_commit(mysql); |
5803 | myquery(rc); |
5804 | |
5805 | stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_store_result" ); |
5806 | check_stmt(stmt); |
5807 | |
5808 | rc= mysql_stmt_execute(stmt); |
5809 | check_execute(stmt, rc); |
5810 | |
5811 | rc= mysql_stmt_store_result(stmt); |
5812 | check_execute(stmt, rc); |
5813 | |
5814 | rc= 0; |
5815 | while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA) |
5816 | rc++; |
5817 | if (!opt_silent) |
5818 | fprintf(stdout, "\n total rows: %d" , rc); |
5819 | DIE_UNLESS(rc == 3); |
5820 | |
5821 | rc= mysql_stmt_execute(stmt); |
5822 | check_execute(stmt, rc); |
5823 | |
5824 | rc= mysql_stmt_store_result(stmt); |
5825 | check_execute(stmt, rc); |
5826 | |
5827 | rc= 0; |
5828 | while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA) |
5829 | rc++; |
5830 | if (!opt_silent) |
5831 | fprintf(stdout, "\n total rows: %d" , rc); |
5832 | DIE_UNLESS(rc == 3); |
5833 | |
5834 | mysql_stmt_close(stmt); |
5835 | } |
5836 | |
5837 | |
5838 | /* Another test for bind and store result */ |
5839 | |
5840 | static void test_store_result2() |
5841 | { |
5842 | MYSQL_STMT *stmt; |
5843 | int rc; |
5844 | int nData; |
5845 | ulong length; |
5846 | MYSQL_BIND my_bind[1]; |
5847 | char query[MAX_TEST_QUERY_LENGTH]; |
5848 | |
5849 | myheader("test_store_result2" ); |
5850 | |
5851 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_store_result" ); |
5852 | myquery(rc); |
5853 | |
5854 | rc= mysql_query(mysql, "CREATE TABLE test_store_result(col1 int , col2 varchar(50))" ); |
5855 | myquery(rc); |
5856 | |
5857 | rc= mysql_query(mysql, "INSERT INTO test_store_result VALUES(10, 'venu'), (20, 'mysql')" ); |
5858 | myquery(rc); |
5859 | |
5860 | rc= mysql_query(mysql, "INSERT INTO test_store_result(col2) VALUES('monty')" ); |
5861 | myquery(rc); |
5862 | |
5863 | rc= mysql_commit(mysql); |
5864 | myquery(rc); |
5865 | |
5866 | /* |
5867 | We need to bzero bind structure because mysql_stmt_bind_param checks all |
5868 | its members. |
5869 | */ |
5870 | bzero((char*) my_bind, sizeof(my_bind)); |
5871 | |
5872 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
5873 | my_bind[0].buffer= (void *) &nData; /* integer data */ |
5874 | my_bind[0].length= &length; |
5875 | my_bind[0].is_null= 0; |
5876 | |
5877 | strmov((char *)query , "SELECT col1 FROM test_store_result where col1= ?" ); |
5878 | stmt= mysql_simple_prepare(mysql, query); |
5879 | check_stmt(stmt); |
5880 | |
5881 | rc= mysql_stmt_bind_param(stmt, my_bind); |
5882 | check_execute(stmt, rc); |
5883 | |
5884 | rc= mysql_stmt_bind_result(stmt, my_bind); |
5885 | check_execute(stmt, rc); |
5886 | |
5887 | nData= 10; length= 0; |
5888 | rc= mysql_stmt_execute(stmt); |
5889 | check_execute(stmt, rc); |
5890 | |
5891 | nData= 0; |
5892 | rc= mysql_stmt_store_result(stmt); |
5893 | check_execute(stmt, rc); |
5894 | |
5895 | rc= mysql_stmt_fetch(stmt); |
5896 | check_execute(stmt, rc); |
5897 | |
5898 | if (!opt_silent) |
5899 | fprintf(stdout, "\n row 1: %d" , nData); |
5900 | DIE_UNLESS(nData == 10); |
5901 | |
5902 | rc= mysql_stmt_fetch(stmt); |
5903 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
5904 | |
5905 | nData= 20; |
5906 | rc= mysql_stmt_execute(stmt); |
5907 | check_execute(stmt, rc); |
5908 | |
5909 | nData= 0; |
5910 | rc= mysql_stmt_store_result(stmt); |
5911 | check_execute(stmt, rc); |
5912 | |
5913 | rc= mysql_stmt_fetch(stmt); |
5914 | check_execute(stmt, rc); |
5915 | |
5916 | if (!opt_silent) |
5917 | fprintf(stdout, "\n row 1: %d" , nData); |
5918 | DIE_UNLESS(nData == 20); |
5919 | |
5920 | rc= mysql_stmt_fetch(stmt); |
5921 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
5922 | mysql_stmt_close(stmt); |
5923 | } |
5924 | |
5925 | |
5926 | /* Test simple subselect prepare */ |
5927 | |
5928 | static void test_subselect() |
5929 | { |
5930 | |
5931 | MYSQL_STMT *stmt; |
5932 | int rc, id; |
5933 | MYSQL_BIND my_bind[1]; |
5934 | DBUG_ENTER("test_subselect" ); |
5935 | |
5936 | myheader("test_subselect" ); |
5937 | |
5938 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_sub1" ); |
5939 | myquery(rc); |
5940 | |
5941 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_sub2" ); |
5942 | myquery(rc); |
5943 | |
5944 | rc= mysql_query(mysql, "CREATE TABLE test_sub1(id int)" ); |
5945 | myquery(rc); |
5946 | |
5947 | rc= mysql_query(mysql, "CREATE TABLE test_sub2(id int, id1 int)" ); |
5948 | myquery(rc); |
5949 | |
5950 | rc= mysql_query(mysql, "INSERT INTO test_sub1 values(2)" ); |
5951 | myquery(rc); |
5952 | |
5953 | rc= mysql_query(mysql, "INSERT INTO test_sub2 VALUES(1, 7), (2, 7)" ); |
5954 | myquery(rc); |
5955 | |
5956 | rc= mysql_commit(mysql); |
5957 | myquery(rc); |
5958 | |
5959 | /* fetch */ |
5960 | /* |
5961 | We need to bzero bind structure because mysql_stmt_bind_param checks all |
5962 | its members. |
5963 | */ |
5964 | bzero((char*) my_bind, sizeof(my_bind)); |
5965 | |
5966 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
5967 | my_bind[0].buffer= (void *) &id; |
5968 | my_bind[0].length= 0; |
5969 | my_bind[0].is_null= 0; |
5970 | |
5971 | stmt= mysql_simple_prepare(mysql, "INSERT INTO test_sub2(id) SELECT * FROM test_sub1 WHERE id= ?" ); |
5972 | check_stmt(stmt); |
5973 | |
5974 | rc= mysql_stmt_bind_param(stmt, my_bind); |
5975 | check_execute(stmt, rc); |
5976 | |
5977 | id= 2; |
5978 | rc= mysql_stmt_execute(stmt); |
5979 | check_execute(stmt, rc); |
5980 | |
5981 | verify_st_affected_rows(stmt, 1); |
5982 | |
5983 | id= 9; |
5984 | rc= mysql_stmt_execute(stmt); |
5985 | check_execute(stmt, rc); |
5986 | |
5987 | verify_st_affected_rows(stmt, 0); |
5988 | |
5989 | mysql_stmt_close(stmt); |
5990 | |
5991 | rc= my_stmt_result("SELECT * FROM test_sub2" ); |
5992 | DIE_UNLESS(rc == 3); |
5993 | |
5994 | rc= my_stmt_result("SELECT ROW(1, 7) IN (select id, id1 " |
5995 | "from test_sub2 WHERE id1= 8)" ); |
5996 | DIE_UNLESS(rc == 1); |
5997 | rc= my_stmt_result("SELECT ROW(1, 7) IN (select id, id1 " |
5998 | "from test_sub2 WHERE id1= 7)" ); |
5999 | DIE_UNLESS(rc == 1); |
6000 | |
6001 | stmt= mysql_simple_prepare(mysql, ("SELECT ROW(1, 7) IN (select id, id1 " |
6002 | "from test_sub2 WHERE id1= ?)" )); |
6003 | check_stmt(stmt); |
6004 | |
6005 | rc= mysql_stmt_bind_param(stmt, my_bind); |
6006 | check_execute(stmt, rc); |
6007 | |
6008 | rc= mysql_stmt_bind_result(stmt, my_bind); |
6009 | check_execute(stmt, rc); |
6010 | |
6011 | id= 7; |
6012 | rc= mysql_stmt_execute(stmt); |
6013 | check_execute(stmt, rc); |
6014 | |
6015 | rc= mysql_stmt_fetch(stmt); |
6016 | check_execute(stmt, rc); |
6017 | |
6018 | if (!opt_silent) |
6019 | fprintf(stdout, "\n row 1: %d" , id); |
6020 | DIE_UNLESS(id == 1); |
6021 | |
6022 | rc= mysql_stmt_fetch(stmt); |
6023 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
6024 | |
6025 | id= 8; |
6026 | rc= mysql_stmt_execute(stmt); |
6027 | check_execute(stmt, rc); |
6028 | |
6029 | rc= mysql_stmt_fetch(stmt); |
6030 | check_execute(stmt, rc); |
6031 | |
6032 | if (!opt_silent) |
6033 | fprintf(stdout, "\n row 1: %d" , id); |
6034 | DIE_UNLESS(id == 0); |
6035 | |
6036 | rc= mysql_stmt_fetch(stmt); |
6037 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
6038 | |
6039 | mysql_stmt_close(stmt); |
6040 | DBUG_VOID_RETURN; |
6041 | } |
6042 | |
6043 | |
6044 | /* |
6045 | Generalized conversion routine to handle DATE, TIME and DATETIME |
6046 | conversion using MYSQL_TIME structure |
6047 | */ |
6048 | |
6049 | static void test_bind_date_conv(uint row_count) |
6050 | { |
6051 | MYSQL_STMT *stmt= 0; |
6052 | uint rc, i, count= row_count; |
6053 | ulong length[4]; |
6054 | MYSQL_BIND my_bind[4]; |
6055 | my_bool is_null[4]= {0}; |
6056 | MYSQL_TIME tm[4]; |
6057 | ulong second_part; |
6058 | uint year, month, day, hour, minute, sec; |
6059 | uint now_year= 1990, now_month= 3, now_day= 13; |
6060 | |
6061 | rc= mysql_query(mysql, "SET timestamp=UNIX_TIMESTAMP('1990-03-13')" ); |
6062 | myquery(rc); |
6063 | |
6064 | stmt= mysql_simple_prepare(mysql, "INSERT INTO test_date VALUES(?, ?, ?, ?)" ); |
6065 | check_stmt(stmt); |
6066 | |
6067 | verify_param_count(stmt, 4); |
6068 | |
6069 | /* |
6070 | We need to bzero bind structure because mysql_stmt_bind_param checks all |
6071 | its members. |
6072 | */ |
6073 | bzero((char*) my_bind, sizeof(my_bind)); |
6074 | |
6075 | my_bind[0].buffer_type= MYSQL_TYPE_TIMESTAMP; |
6076 | my_bind[1].buffer_type= MYSQL_TYPE_TIME; |
6077 | my_bind[2].buffer_type= MYSQL_TYPE_DATETIME; |
6078 | my_bind[3].buffer_type= MYSQL_TYPE_DATE; |
6079 | |
6080 | for (i= 0; i < (int) array_elements(my_bind); i++) |
6081 | { |
6082 | my_bind[i].buffer= (void *) &tm[i]; |
6083 | my_bind[i].is_null= &is_null[i]; |
6084 | my_bind[i].length= &length[i]; |
6085 | my_bind[i].buffer_length= 30; |
6086 | length[i]= 20; |
6087 | } |
6088 | |
6089 | second_part= 0; |
6090 | |
6091 | year= 2000; |
6092 | month= 01; |
6093 | day= 10; |
6094 | |
6095 | hour= 11; |
6096 | minute= 16; |
6097 | sec= 20; |
6098 | |
6099 | rc= mysql_stmt_bind_param(stmt, my_bind); |
6100 | check_execute(stmt, rc); |
6101 | |
6102 | for (count= 0; count < row_count; count++) |
6103 | { |
6104 | for (i= 0; i < (int) array_elements(my_bind); i++) |
6105 | { |
6106 | tm[i].neg= 0; |
6107 | tm[i].second_part= second_part+count; |
6108 | if (my_bind[i].buffer_type != MYSQL_TYPE_TIME) |
6109 | { |
6110 | tm[i].year= year+count; |
6111 | tm[i].month= month+count; |
6112 | tm[i].day= day+count; |
6113 | } |
6114 | else |
6115 | tm[i].year= tm[i].month= tm[i].day= 0; |
6116 | if (my_bind[i].buffer_type != MYSQL_TYPE_DATE) |
6117 | { |
6118 | tm[i].hour= hour+count; |
6119 | tm[i].minute= minute+count; |
6120 | tm[i].second= sec+count; |
6121 | } |
6122 | else |
6123 | tm[i].hour= tm[i].minute= tm[i].second= 0; |
6124 | } |
6125 | rc= mysql_stmt_execute(stmt); |
6126 | check_execute(stmt, rc); |
6127 | } |
6128 | |
6129 | rc= mysql_commit(mysql); |
6130 | myquery(rc); |
6131 | |
6132 | mysql_stmt_close(stmt); |
6133 | |
6134 | rc= my_stmt_result("SELECT * FROM test_date" ); |
6135 | DIE_UNLESS(row_count == rc); |
6136 | |
6137 | stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_date" ); |
6138 | check_stmt(stmt); |
6139 | |
6140 | rc= mysql_stmt_bind_result(stmt, my_bind); |
6141 | check_execute(stmt, rc); |
6142 | |
6143 | rc= mysql_stmt_execute(stmt); |
6144 | check_execute(stmt, rc); |
6145 | |
6146 | rc= mysql_stmt_store_result(stmt); |
6147 | check_execute(stmt, rc); |
6148 | |
6149 | for (count= 0; count < row_count; count++) |
6150 | { |
6151 | rc= mysql_stmt_fetch(stmt); |
6152 | DIE_UNLESS(rc == 0 || rc == MYSQL_DATA_TRUNCATED); |
6153 | |
6154 | if (!opt_silent) |
6155 | fprintf(stdout, "\n" ); |
6156 | for (i= 0; i < array_elements(my_bind); i++) |
6157 | { |
6158 | if (!opt_silent) |
6159 | fprintf(stdout, "\ntime[%d]: %02d-%02d-%02d %02d:%02d:%02d.%02lu" , |
6160 | i, tm[i].year, tm[i].month, tm[i].day, |
6161 | tm[i].hour, tm[i].minute, tm[i].second, |
6162 | tm[i].second_part); |
6163 | DIE_UNLESS(tm[i].year == 0 || tm[i].year == year + count || |
6164 | (tm[i].year == now_year && |
6165 | my_bind[i].buffer_type == MYSQL_TYPE_TIME)); |
6166 | DIE_UNLESS(tm[i].month == 0 || tm[i].month == month + count || |
6167 | (tm[i].month == now_month && |
6168 | my_bind[i].buffer_type == MYSQL_TYPE_TIME)); |
6169 | DIE_UNLESS(tm[i].day == 0 || tm[i].day == day + count || |
6170 | (tm[i].day == now_day && |
6171 | my_bind[i].buffer_type == MYSQL_TYPE_TIME)); |
6172 | |
6173 | DIE_UNLESS(tm[i].hour == 0 || tm[i].hour == hour+count); |
6174 | DIE_UNLESS(tm[i].minute == 0 || tm[i].minute == minute+count); |
6175 | DIE_UNLESS(tm[i].second == 0 || tm[i].second == sec+count); |
6176 | DIE_UNLESS(tm[i].second_part == 0 || |
6177 | tm[i].second_part == second_part+count); |
6178 | } |
6179 | } |
6180 | rc= mysql_stmt_fetch(stmt); |
6181 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
6182 | |
6183 | mysql_stmt_close(stmt); |
6184 | } |
6185 | |
6186 | |
6187 | /* Test DATE, TIME, DATETIME and TS with MYSQL_TIME conversion */ |
6188 | |
6189 | static void test_date() |
6190 | { |
6191 | int rc; |
6192 | |
6193 | myheader("test_date" ); |
6194 | |
6195 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date" ); |
6196 | myquery(rc); |
6197 | |
6198 | rc= mysql_query(mysql, "CREATE TABLE test_date(c1 TIMESTAMP, \ |
6199 | c2 TIME, \ |
6200 | c3 DATETIME, \ |
6201 | c4 DATE)" ); |
6202 | |
6203 | myquery(rc); |
6204 | |
6205 | test_bind_date_conv(5); |
6206 | } |
6207 | |
6208 | |
6209 | /* Test all time types to DATE and DATE to all types */ |
6210 | |
6211 | static void test_date_date() |
6212 | { |
6213 | int rc; |
6214 | |
6215 | myheader("test_date_date" ); |
6216 | |
6217 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date" ); |
6218 | myquery(rc); |
6219 | |
6220 | rc= mysql_query(mysql, "CREATE TABLE test_date(c1 DATE, \ |
6221 | c2 DATE, \ |
6222 | c3 DATE, \ |
6223 | c4 DATE)" ); |
6224 | |
6225 | myquery(rc); |
6226 | |
6227 | test_bind_date_conv(3); |
6228 | } |
6229 | |
6230 | |
6231 | /* Test all time types to TIME and TIME to all types */ |
6232 | |
6233 | static void test_date_time() |
6234 | { |
6235 | int rc; |
6236 | |
6237 | myheader("test_date_time" ); |
6238 | |
6239 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date" ); |
6240 | myquery(rc); |
6241 | |
6242 | rc= mysql_query(mysql, "CREATE TABLE test_date(c1 TIME, \ |
6243 | c2 TIME, \ |
6244 | c3 TIME, \ |
6245 | c4 TIME)" ); |
6246 | |
6247 | myquery(rc); |
6248 | |
6249 | test_bind_date_conv(3); |
6250 | } |
6251 | |
6252 | |
6253 | /* Test all time types to TIMESTAMP and TIMESTAMP to all types */ |
6254 | |
6255 | static void test_date_ts() |
6256 | { |
6257 | int rc; |
6258 | |
6259 | myheader("test_date_ts" ); |
6260 | |
6261 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date" ); |
6262 | myquery(rc); |
6263 | |
6264 | rc= mysql_query(mysql, "CREATE TABLE test_date(c1 TIMESTAMP, \ |
6265 | c2 TIMESTAMP, \ |
6266 | c3 TIMESTAMP, \ |
6267 | c4 TIMESTAMP)" ); |
6268 | |
6269 | myquery(rc); |
6270 | |
6271 | test_bind_date_conv(2); |
6272 | } |
6273 | |
6274 | |
6275 | /* Test all time types to DATETIME and DATETIME to all types */ |
6276 | |
6277 | static void test_date_dt() |
6278 | { |
6279 | int rc; |
6280 | |
6281 | myheader("test_date_dt" ); |
6282 | |
6283 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date" ); |
6284 | myquery(rc); |
6285 | |
6286 | rc= mysql_query(mysql, "CREATE TABLE test_date(c1 datetime, " |
6287 | " c2 datetime, c3 datetime, c4 date)" ); |
6288 | myquery(rc); |
6289 | |
6290 | test_bind_date_conv(2); |
6291 | } |
6292 | |
6293 | |
6294 | /* Misc tests to keep pure coverage happy */ |
6295 | |
6296 | static void test_pure_coverage() |
6297 | { |
6298 | MYSQL_STMT *stmt; |
6299 | MYSQL_BIND my_bind[2]; |
6300 | int rc; |
6301 | ulong length; |
6302 | |
6303 | myheader("test_pure_coverage" ); |
6304 | |
6305 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_pure" ); |
6306 | myquery(rc); |
6307 | |
6308 | rc= mysql_query(mysql, "CREATE TABLE test_pure(c1 int, c2 varchar(20))" ); |
6309 | myquery(rc); |
6310 | |
6311 | stmt= mysql_simple_prepare(mysql, "insert into test_pure(c67788) values(10)" ); |
6312 | check_stmt_r(stmt); |
6313 | |
6314 | /* Query without params and result should allow to bind 0 arrays */ |
6315 | stmt= mysql_simple_prepare(mysql, "insert into test_pure(c2) values(10)" ); |
6316 | check_stmt(stmt); |
6317 | |
6318 | rc= mysql_stmt_bind_param(stmt, (MYSQL_BIND*)0); |
6319 | check_execute(stmt, rc); |
6320 | |
6321 | rc= mysql_stmt_execute(stmt); |
6322 | check_execute(stmt, rc); |
6323 | |
6324 | rc= mysql_stmt_bind_result(stmt, (MYSQL_BIND*)0); |
6325 | DIE_UNLESS(rc == 1); |
6326 | |
6327 | mysql_stmt_close(stmt); |
6328 | |
6329 | stmt= mysql_simple_prepare(mysql, "insert into test_pure(c2) values(?)" ); |
6330 | check_stmt(stmt); |
6331 | |
6332 | /* |
6333 | We need to bzero bind structure because mysql_stmt_bind_param checks all |
6334 | its members. |
6335 | */ |
6336 | bzero((char*) my_bind, sizeof(my_bind)); |
6337 | |
6338 | my_bind[0].length= &length; |
6339 | my_bind[0].is_null= 0; |
6340 | my_bind[0].buffer_length= 0; |
6341 | |
6342 | my_bind[0].buffer_type= MYSQL_TYPE_GEOMETRY; |
6343 | rc= mysql_stmt_bind_param(stmt, my_bind); |
6344 | check_execute_r(stmt, rc); /* unsupported buffer type */ |
6345 | |
6346 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
6347 | rc= mysql_stmt_bind_param(stmt, my_bind); |
6348 | check_execute(stmt, rc); |
6349 | |
6350 | rc= mysql_stmt_store_result(stmt); |
6351 | check_execute(stmt, rc); |
6352 | |
6353 | mysql_stmt_close(stmt); |
6354 | |
6355 | stmt= mysql_simple_prepare(mysql, "select * from test_pure" ); |
6356 | check_execute(stmt, rc); |
6357 | |
6358 | rc= mysql_stmt_execute(stmt); |
6359 | check_execute(stmt, rc); |
6360 | |
6361 | my_bind[0].buffer_type= MYSQL_TYPE_GEOMETRY; |
6362 | rc= mysql_stmt_bind_result(stmt, my_bind); |
6363 | check_execute(stmt, rc); /* MariaDB C/C converts geometry to string */ |
6364 | |
6365 | rc= mysql_stmt_store_result(stmt); |
6366 | DIE_IF(rc); |
6367 | |
6368 | rc= mysql_stmt_store_result(stmt); |
6369 | DIE_UNLESS(rc); /* Old error must be reset first */ |
6370 | |
6371 | mysql_stmt_close(stmt); |
6372 | |
6373 | mysql_query(mysql, "DROP TABLE test_pure" ); |
6374 | } |
6375 | |
6376 | |
6377 | /* Test for string buffer fetch */ |
6378 | |
6379 | static void test_buffers() |
6380 | { |
6381 | MYSQL_STMT *stmt; |
6382 | MYSQL_BIND my_bind[1]; |
6383 | int rc; |
6384 | ulong length; |
6385 | my_bool is_null; |
6386 | char buffer[20]; |
6387 | |
6388 | myheader("test_buffers" ); |
6389 | |
6390 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_buffer" ); |
6391 | myquery(rc); |
6392 | |
6393 | rc= mysql_query(mysql, "CREATE TABLE test_buffer(str varchar(20))" ); |
6394 | myquery(rc); |
6395 | |
6396 | rc= mysql_query(mysql, "insert into test_buffer values('MySQL')\ |
6397 | , ('Database'), ('Open-Source'), ('Popular')" ); |
6398 | myquery(rc); |
6399 | |
6400 | stmt= mysql_simple_prepare(mysql, "select str from test_buffer" ); |
6401 | check_stmt(stmt); |
6402 | |
6403 | rc= mysql_stmt_execute(stmt); |
6404 | check_execute(stmt, rc); |
6405 | |
6406 | bzero(buffer, sizeof(buffer)); /* Avoid overruns in printf() */ |
6407 | |
6408 | bzero((char*) my_bind, sizeof(my_bind)); |
6409 | my_bind[0].length= &length; |
6410 | my_bind[0].is_null= &is_null; |
6411 | my_bind[0].buffer_length= 1; |
6412 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
6413 | my_bind[0].buffer= (void *)buffer; |
6414 | my_bind[0].error= &my_bind[0].error_value; |
6415 | |
6416 | rc= mysql_stmt_bind_result(stmt, my_bind); |
6417 | check_execute(stmt, rc); |
6418 | |
6419 | rc= mysql_stmt_store_result(stmt); |
6420 | check_execute(stmt, rc); |
6421 | |
6422 | buffer[1]= 'X'; |
6423 | rc= mysql_stmt_fetch(stmt); |
6424 | DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED); |
6425 | DIE_UNLESS(my_bind[0].error_value); |
6426 | if (!opt_silent) |
6427 | fprintf(stdout, "\n data: %s (%lu)" , buffer, length); |
6428 | DIE_UNLESS(buffer[0] == 'M'); |
6429 | DIE_UNLESS(buffer[1] == 'X'); |
6430 | DIE_UNLESS(length == 5); |
6431 | |
6432 | my_bind[0].buffer_length= 8; |
6433 | rc= mysql_stmt_bind_result(stmt, my_bind);/* re-bind */ |
6434 | check_execute(stmt, rc); |
6435 | |
6436 | rc= mysql_stmt_fetch(stmt); |
6437 | check_execute(stmt, rc); |
6438 | if (!opt_silent) |
6439 | fprintf(stdout, "\n data: %s (%lu)" , buffer, length); |
6440 | DIE_UNLESS(strncmp(buffer, "Database" , 8) == 0); |
6441 | DIE_UNLESS(length == 8); |
6442 | |
6443 | my_bind[0].buffer_length= 12; |
6444 | rc= mysql_stmt_bind_result(stmt, my_bind);/* re-bind */ |
6445 | check_execute(stmt, rc); |
6446 | |
6447 | rc= mysql_stmt_fetch(stmt); |
6448 | check_execute(stmt, rc); |
6449 | if (!opt_silent) |
6450 | fprintf(stdout, "\n data: %s (%lu)" , buffer, length); |
6451 | DIE_UNLESS(strcmp(buffer, "Open-Source" ) == 0); |
6452 | DIE_UNLESS(length == 11); |
6453 | |
6454 | my_bind[0].buffer_length= 6; |
6455 | rc= mysql_stmt_bind_result(stmt, my_bind);/* re-bind */ |
6456 | check_execute(stmt, rc); |
6457 | |
6458 | rc= mysql_stmt_fetch(stmt); |
6459 | DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED); |
6460 | DIE_UNLESS(my_bind[0].error_value); |
6461 | if (!opt_silent) |
6462 | fprintf(stdout, "\n data: %s (%lu)" , buffer, length); |
6463 | DIE_UNLESS(strncmp(buffer, "Popula" , 6) == 0); |
6464 | DIE_UNLESS(length == 7); |
6465 | |
6466 | mysql_stmt_close(stmt); |
6467 | } |
6468 | |
6469 | |
6470 | /* Test the direct query execution in the middle of open stmts */ |
6471 | |
6472 | static void test_open_direct() |
6473 | { |
6474 | MYSQL_STMT *stmt; |
6475 | MYSQL_RES *result; |
6476 | int rc; |
6477 | |
6478 | myheader("test_open_direct" ); |
6479 | |
6480 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_open_direct" ); |
6481 | myquery(rc); |
6482 | |
6483 | rc= mysql_query(mysql, "CREATE TABLE test_open_direct(id int, name char(6))" ); |
6484 | myquery(rc); |
6485 | |
6486 | stmt= mysql_simple_prepare(mysql, "INSERT INTO test_open_direct values(10, 'mysql')" ); |
6487 | check_stmt(stmt); |
6488 | |
6489 | rc= mysql_query(mysql, "SELECT * FROM test_open_direct" ); |
6490 | myquery(rc); |
6491 | |
6492 | result= mysql_store_result(mysql); |
6493 | mytest(result); |
6494 | |
6495 | rc= my_process_result_set(result); |
6496 | DIE_UNLESS(rc == 0); |
6497 | mysql_free_result(result); |
6498 | |
6499 | rc= mysql_stmt_execute(stmt); |
6500 | check_execute(stmt, rc); |
6501 | |
6502 | verify_st_affected_rows(stmt, 1); |
6503 | |
6504 | rc= mysql_query(mysql, "SELECT * FROM test_open_direct" ); |
6505 | myquery(rc); |
6506 | |
6507 | result= mysql_store_result(mysql); |
6508 | mytest(result); |
6509 | |
6510 | rc= my_process_result_set(result); |
6511 | DIE_UNLESS(rc == 1); |
6512 | mysql_free_result(result); |
6513 | |
6514 | rc= mysql_stmt_execute(stmt); |
6515 | check_execute(stmt, rc); |
6516 | |
6517 | verify_st_affected_rows(stmt, 1); |
6518 | |
6519 | rc= mysql_query(mysql, "SELECT * FROM test_open_direct" ); |
6520 | myquery(rc); |
6521 | |
6522 | result= mysql_store_result(mysql); |
6523 | mytest(result); |
6524 | |
6525 | rc= my_process_result_set(result); |
6526 | DIE_UNLESS(rc == 2); |
6527 | mysql_free_result(result); |
6528 | |
6529 | mysql_stmt_close(stmt); |
6530 | |
6531 | /* run a direct query in the middle of a fetch */ |
6532 | stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_open_direct" ); |
6533 | check_stmt(stmt); |
6534 | |
6535 | rc= mysql_stmt_execute(stmt); |
6536 | check_execute(stmt, rc); |
6537 | |
6538 | rc= mysql_stmt_fetch(stmt); |
6539 | check_execute(stmt, rc); |
6540 | |
6541 | rc= mysql_query(mysql, "INSERT INTO test_open_direct(id) VALUES(20)" ); |
6542 | myquery_r(rc); |
6543 | |
6544 | rc= mysql_stmt_close(stmt); |
6545 | check_execute(stmt, rc); |
6546 | |
6547 | rc= mysql_query(mysql, "INSERT INTO test_open_direct(id) VALUES(20)" ); |
6548 | myquery(rc); |
6549 | |
6550 | /* run a direct query with store result */ |
6551 | stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_open_direct" ); |
6552 | check_stmt(stmt); |
6553 | |
6554 | rc= mysql_stmt_execute(stmt); |
6555 | check_execute(stmt, rc); |
6556 | |
6557 | rc= mysql_stmt_store_result(stmt); |
6558 | check_execute(stmt, rc); |
6559 | |
6560 | rc= mysql_stmt_fetch(stmt); |
6561 | check_execute(stmt, rc); |
6562 | |
6563 | rc= mysql_query(mysql, "drop table test_open_direct" ); |
6564 | myquery(rc); |
6565 | |
6566 | rc= mysql_stmt_close(stmt); |
6567 | check_execute(stmt, rc); |
6568 | } |
6569 | |
6570 | |
6571 | /* Test fetch without prior bound buffers */ |
6572 | |
6573 | static void test_fetch_nobuffs() |
6574 | { |
6575 | MYSQL_STMT *stmt; |
6576 | MYSQL_BIND my_bind[4]; |
6577 | char str[4][50]; |
6578 | int rc; |
6579 | |
6580 | myheader("test_fetch_nobuffs" ); |
6581 | |
6582 | stmt= mysql_simple_prepare(mysql, "SELECT DATABASE(), CURRENT_USER(), \ |
6583 | CURRENT_DATE(), CURRENT_TIME()" ); |
6584 | check_stmt(stmt); |
6585 | |
6586 | rc= mysql_stmt_execute(stmt); |
6587 | check_execute(stmt, rc); |
6588 | |
6589 | rc= 0; |
6590 | while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA) |
6591 | rc++; |
6592 | |
6593 | if (!opt_silent) |
6594 | fprintf(stdout, "\n total rows : %d" , rc); |
6595 | DIE_UNLESS(rc == 1); |
6596 | |
6597 | bzero((char*) my_bind, sizeof(MYSQL_BIND)); |
6598 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
6599 | my_bind[0].buffer= (void *)str[0]; |
6600 | my_bind[0].buffer_length= sizeof(str[0]); |
6601 | my_bind[1]= my_bind[2]= my_bind[3]= my_bind[0]; |
6602 | my_bind[1].buffer= (void *)str[1]; |
6603 | my_bind[2].buffer= (void *)str[2]; |
6604 | my_bind[3].buffer= (void *)str[3]; |
6605 | |
6606 | rc= mysql_stmt_bind_result(stmt, my_bind); |
6607 | check_execute(stmt, rc); |
6608 | |
6609 | rc= mysql_stmt_execute(stmt); |
6610 | check_execute(stmt, rc); |
6611 | |
6612 | rc= 0; |
6613 | while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA) |
6614 | { |
6615 | rc++; |
6616 | if (!opt_silent) |
6617 | { |
6618 | fprintf(stdout, "\n CURRENT_DATABASE(): %s" , str[0]); |
6619 | fprintf(stdout, "\n CURRENT_USER() : %s" , str[1]); |
6620 | fprintf(stdout, "\n CURRENT_DATE() : %s" , str[2]); |
6621 | fprintf(stdout, "\n CURRENT_TIME() : %s" , str[3]); |
6622 | } |
6623 | } |
6624 | if (!opt_silent) |
6625 | fprintf(stdout, "\n total rows : %d" , rc); |
6626 | DIE_UNLESS(rc == 1); |
6627 | |
6628 | mysql_stmt_close(stmt); |
6629 | } |
6630 | |
6631 | |
6632 | /* Test a misc bug */ |
6633 | |
6634 | static void test_ushort_bug() |
6635 | { |
6636 | MYSQL_STMT *stmt; |
6637 | MYSQL_BIND my_bind[4]; |
6638 | ushort short_value; |
6639 | uint32 long_value; |
6640 | ulong s_length, l_length, ll_length, t_length; |
6641 | ulonglong longlong_value; |
6642 | int rc; |
6643 | uchar tiny_value; |
6644 | char llbuf[22]; |
6645 | myheader("test_ushort_bug" ); |
6646 | |
6647 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_ushort" ); |
6648 | myquery(rc); |
6649 | |
6650 | rc= mysql_query(mysql, "CREATE TABLE test_ushort(a smallint unsigned, \ |
6651 | b smallint unsigned, \ |
6652 | c smallint unsigned, \ |
6653 | d smallint unsigned)" ); |
6654 | myquery(rc); |
6655 | |
6656 | rc= mysql_query(mysql, |
6657 | "INSERT INTO test_ushort VALUES(35999, 35999, 35999, 200)" ); |
6658 | myquery(rc); |
6659 | |
6660 | |
6661 | stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_ushort" ); |
6662 | check_stmt(stmt); |
6663 | |
6664 | rc= mysql_stmt_execute(stmt); |
6665 | check_execute(stmt, rc); |
6666 | |
6667 | bzero((char*) my_bind, sizeof(my_bind)); |
6668 | my_bind[0].buffer_type= MYSQL_TYPE_SHORT; |
6669 | my_bind[0].buffer= (void *)&short_value; |
6670 | my_bind[0].is_unsigned= TRUE; |
6671 | my_bind[0].length= &s_length; |
6672 | |
6673 | my_bind[1].buffer_type= MYSQL_TYPE_LONG; |
6674 | my_bind[1].buffer= (void *)&long_value; |
6675 | my_bind[1].length= &l_length; |
6676 | |
6677 | my_bind[2].buffer_type= MYSQL_TYPE_LONGLONG; |
6678 | my_bind[2].buffer= (void *)&longlong_value; |
6679 | my_bind[2].length= &ll_length; |
6680 | |
6681 | my_bind[3].buffer_type= MYSQL_TYPE_TINY; |
6682 | my_bind[3].buffer= (void *)&tiny_value; |
6683 | my_bind[3].is_unsigned= TRUE; |
6684 | my_bind[3].length= &t_length; |
6685 | |
6686 | rc= mysql_stmt_bind_result(stmt, my_bind); |
6687 | check_execute(stmt, rc); |
6688 | |
6689 | rc= mysql_stmt_fetch(stmt); |
6690 | check_execute(stmt, rc); |
6691 | |
6692 | if (!opt_silent) |
6693 | { |
6694 | fprintf(stdout, "\n ushort : %d (%ld)" , short_value, s_length); |
6695 | fprintf(stdout, "\n ulong : %lu (%ld)" , (ulong) long_value, l_length); |
6696 | fprintf(stdout, "\n longlong : %s (%ld)" , llstr(longlong_value, llbuf), |
6697 | ll_length); |
6698 | fprintf(stdout, "\n tinyint : %d (%ld)" , tiny_value, t_length); |
6699 | } |
6700 | |
6701 | DIE_UNLESS(short_value == 35999); |
6702 | DIE_UNLESS(s_length == 2); |
6703 | |
6704 | DIE_UNLESS(long_value == 35999); |
6705 | DIE_UNLESS(l_length == 4); |
6706 | |
6707 | DIE_UNLESS(longlong_value == 35999); |
6708 | DIE_UNLESS(ll_length == 8); |
6709 | |
6710 | DIE_UNLESS(tiny_value == 200); |
6711 | DIE_UNLESS(t_length == 1); |
6712 | |
6713 | rc= mysql_stmt_fetch(stmt); |
6714 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
6715 | |
6716 | mysql_stmt_close(stmt); |
6717 | } |
6718 | |
6719 | |
6720 | /* Test a misc smallint-signed conversion bug */ |
6721 | |
6722 | static void test_sshort_bug() |
6723 | { |
6724 | MYSQL_STMT *stmt; |
6725 | MYSQL_BIND my_bind[4]; |
6726 | short short_value; |
6727 | int32 long_value; |
6728 | ulong s_length, l_length, ll_length, t_length; |
6729 | ulonglong longlong_value; |
6730 | int rc; |
6731 | uchar tiny_value; |
6732 | char llbuf[22]; |
6733 | |
6734 | myheader("test_sshort_bug" ); |
6735 | |
6736 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_sshort" ); |
6737 | myquery(rc); |
6738 | |
6739 | rc= mysql_query(mysql, "CREATE TABLE test_sshort(a smallint signed, \ |
6740 | b smallint signed, \ |
6741 | c smallint unsigned, \ |
6742 | d smallint unsigned)" ); |
6743 | myquery(rc); |
6744 | |
6745 | rc= mysql_query(mysql, "INSERT INTO test_sshort VALUES(-5999, -5999, 35999, 200)" ); |
6746 | myquery(rc); |
6747 | |
6748 | |
6749 | stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_sshort" ); |
6750 | check_stmt(stmt); |
6751 | |
6752 | rc= mysql_stmt_execute(stmt); |
6753 | check_execute(stmt, rc); |
6754 | |
6755 | bzero((char*) my_bind, sizeof(my_bind)); |
6756 | my_bind[0].buffer_type= MYSQL_TYPE_SHORT; |
6757 | my_bind[0].buffer= (void *)&short_value; |
6758 | my_bind[0].length= &s_length; |
6759 | |
6760 | my_bind[1].buffer_type= MYSQL_TYPE_LONG; |
6761 | my_bind[1].buffer= (void *)&long_value; |
6762 | my_bind[1].length= &l_length; |
6763 | |
6764 | my_bind[2].buffer_type= MYSQL_TYPE_LONGLONG; |
6765 | my_bind[2].buffer= (void *)&longlong_value; |
6766 | my_bind[2].length= &ll_length; |
6767 | |
6768 | my_bind[3].buffer_type= MYSQL_TYPE_TINY; |
6769 | my_bind[3].buffer= (void *)&tiny_value; |
6770 | my_bind[3].is_unsigned= TRUE; |
6771 | my_bind[3].length= &t_length; |
6772 | |
6773 | rc= mysql_stmt_bind_result(stmt, my_bind); |
6774 | check_execute(stmt, rc); |
6775 | |
6776 | rc= mysql_stmt_fetch(stmt); |
6777 | check_execute(stmt, rc); |
6778 | |
6779 | if (!opt_silent) |
6780 | { |
6781 | fprintf(stdout, "\n sshort : %d (%ld)" , short_value, s_length); |
6782 | fprintf(stdout, "\n slong : %ld (%ld)" , (long) long_value, l_length); |
6783 | fprintf(stdout, "\n longlong : %s (%ld)" , llstr(longlong_value, llbuf), |
6784 | ll_length); |
6785 | fprintf(stdout, "\n tinyint : %d (%ld)" , tiny_value, t_length); |
6786 | } |
6787 | |
6788 | DIE_UNLESS(short_value == -5999); |
6789 | DIE_UNLESS(s_length == 2); |
6790 | |
6791 | DIE_UNLESS(long_value == -5999); |
6792 | DIE_UNLESS(l_length == 4); |
6793 | |
6794 | DIE_UNLESS(longlong_value == 35999); |
6795 | DIE_UNLESS(ll_length == 8); |
6796 | |
6797 | DIE_UNLESS(tiny_value == 200); |
6798 | DIE_UNLESS(t_length == 1); |
6799 | |
6800 | rc= mysql_stmt_fetch(stmt); |
6801 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
6802 | |
6803 | mysql_stmt_close(stmt); |
6804 | } |
6805 | |
6806 | |
6807 | /* Test a misc tinyint-signed conversion bug */ |
6808 | |
6809 | static void test_stiny_bug() |
6810 | { |
6811 | MYSQL_STMT *stmt; |
6812 | MYSQL_BIND my_bind[4]; |
6813 | short short_value; |
6814 | int32 long_value; |
6815 | ulong s_length, l_length, ll_length, t_length; |
6816 | ulonglong longlong_value; |
6817 | int rc; |
6818 | uchar tiny_value; |
6819 | char llbuf[22]; |
6820 | |
6821 | myheader("test_stiny_bug" ); |
6822 | |
6823 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_stiny" ); |
6824 | myquery(rc); |
6825 | |
6826 | rc= mysql_query(mysql, "CREATE TABLE test_stiny(a tinyint signed, \ |
6827 | b tinyint signed, \ |
6828 | c tinyint unsigned, \ |
6829 | d tinyint unsigned)" ); |
6830 | myquery(rc); |
6831 | |
6832 | rc= mysql_query(mysql, "INSERT INTO test_stiny VALUES(-128, -127, 255, 0)" ); |
6833 | myquery(rc); |
6834 | |
6835 | |
6836 | stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_stiny" ); |
6837 | check_stmt(stmt); |
6838 | |
6839 | rc= mysql_stmt_execute(stmt); |
6840 | check_execute(stmt, rc); |
6841 | |
6842 | bzero((char*) my_bind, sizeof(my_bind)); |
6843 | my_bind[0].buffer_type= MYSQL_TYPE_SHORT; |
6844 | my_bind[0].buffer= (void *)&short_value; |
6845 | my_bind[0].length= &s_length; |
6846 | |
6847 | my_bind[1].buffer_type= MYSQL_TYPE_LONG; |
6848 | my_bind[1].buffer= (void *)&long_value; |
6849 | my_bind[1].length= &l_length; |
6850 | |
6851 | my_bind[2].buffer_type= MYSQL_TYPE_LONGLONG; |
6852 | my_bind[2].buffer= (void *)&longlong_value; |
6853 | my_bind[2].length= &ll_length; |
6854 | |
6855 | my_bind[3].buffer_type= MYSQL_TYPE_TINY; |
6856 | my_bind[3].buffer= (void *)&tiny_value; |
6857 | my_bind[3].length= &t_length; |
6858 | |
6859 | rc= mysql_stmt_bind_result(stmt, my_bind); |
6860 | check_execute(stmt, rc); |
6861 | |
6862 | rc= mysql_stmt_fetch(stmt); |
6863 | check_execute(stmt, rc); |
6864 | |
6865 | if (!opt_silent) |
6866 | { |
6867 | fprintf(stdout, "\n sshort : %d (%ld)" , short_value, s_length); |
6868 | fprintf(stdout, "\n slong : %ld (%ld)" , (long) long_value, l_length); |
6869 | fprintf(stdout, "\n longlong : %s (%ld)" , llstr(longlong_value, llbuf), |
6870 | ll_length); |
6871 | fprintf(stdout, "\n tinyint : %d (%ld)" , tiny_value, t_length); |
6872 | } |
6873 | |
6874 | DIE_UNLESS(short_value == -128); |
6875 | DIE_UNLESS(s_length == 2); |
6876 | |
6877 | DIE_UNLESS(long_value == -127); |
6878 | DIE_UNLESS(l_length == 4); |
6879 | |
6880 | DIE_UNLESS(longlong_value == 255); |
6881 | DIE_UNLESS(ll_length == 8); |
6882 | |
6883 | DIE_UNLESS(tiny_value == 0); |
6884 | DIE_UNLESS(t_length == 1); |
6885 | |
6886 | rc= mysql_stmt_fetch(stmt); |
6887 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
6888 | |
6889 | mysql_stmt_close(stmt); |
6890 | } |
6891 | |
6892 | |
6893 | /* Test misc field information, bug: #74 */ |
6894 | |
6895 | static void test_field_misc() |
6896 | { |
6897 | MYSQL_STMT *stmt; |
6898 | MYSQL_RES *result; |
6899 | int rc; |
6900 | |
6901 | myheader("test_field_misc" ); |
6902 | |
6903 | rc= mysql_query(mysql, "SELECT @@autocommit" ); |
6904 | myquery(rc); |
6905 | |
6906 | result= mysql_store_result(mysql); |
6907 | mytest(result); |
6908 | |
6909 | rc= my_process_result_set(result); |
6910 | DIE_UNLESS(rc == 1); |
6911 | |
6912 | verify_prepare_field(result, 0, |
6913 | "@@autocommit" , "" , /* field and its org name */ |
6914 | MYSQL_TYPE_LONGLONG, /* field type */ |
6915 | "" , "" , /* table and its org name */ |
6916 | "" , 1, 0); /* db name, length(its bool flag)*/ |
6917 | |
6918 | mysql_free_result(result); |
6919 | |
6920 | stmt= mysql_simple_prepare(mysql, "SELECT @@autocommit" ); |
6921 | check_stmt(stmt); |
6922 | |
6923 | rc= mysql_stmt_execute(stmt); |
6924 | check_execute(stmt, rc); |
6925 | |
6926 | result= mysql_stmt_result_metadata(stmt); |
6927 | mytest(result); |
6928 | |
6929 | rc= my_process_stmt_result(stmt); |
6930 | DIE_UNLESS(rc == 1); |
6931 | |
6932 | verify_prepare_field(result, 0, |
6933 | "@@autocommit" , "" , /* field and its org name */ |
6934 | MYSQL_TYPE_LONGLONG, /* field type */ |
6935 | "" , "" , /* table and its org name */ |
6936 | "" , 1, 0); /* db name, length(its bool flag)*/ |
6937 | |
6938 | mysql_free_result(result); |
6939 | mysql_stmt_close(stmt); |
6940 | |
6941 | stmt= mysql_simple_prepare(mysql, "SELECT @@max_error_count" ); |
6942 | check_stmt(stmt); |
6943 | |
6944 | result= mysql_stmt_result_metadata(stmt); |
6945 | mytest(result); |
6946 | |
6947 | rc= mysql_stmt_execute(stmt); |
6948 | check_execute(stmt, rc); |
6949 | |
6950 | rc= my_process_stmt_result(stmt); |
6951 | DIE_UNLESS(rc == 1); |
6952 | |
6953 | verify_prepare_field(result, 0, |
6954 | "@@max_error_count" , "" , /* field and its org name */ |
6955 | MYSQL_TYPE_LONGLONG, /* field type */ |
6956 | "" , "" , /* table and its org name */ |
6957 | /* db name, length */ |
6958 | "" , MY_INT64_NUM_DECIMAL_DIGITS , 0); |
6959 | |
6960 | mysql_free_result(result); |
6961 | mysql_stmt_close(stmt); |
6962 | |
6963 | stmt= mysql_simple_prepare(mysql, "SELECT @@max_allowed_packet" ); |
6964 | check_stmt(stmt); |
6965 | |
6966 | result= mysql_stmt_result_metadata(stmt); |
6967 | mytest(result); |
6968 | |
6969 | rc= mysql_stmt_execute(stmt); |
6970 | check_execute(stmt, rc); |
6971 | |
6972 | DIE_UNLESS(1 == my_process_stmt_result(stmt)); |
6973 | |
6974 | verify_prepare_field(result, 0, |
6975 | "@@max_allowed_packet" , "" , /* field and its org name */ |
6976 | MYSQL_TYPE_LONGLONG, /* field type */ |
6977 | "" , "" , /* table and its org name */ |
6978 | /* db name, length */ |
6979 | "" , MY_INT64_NUM_DECIMAL_DIGITS, 0); |
6980 | |
6981 | mysql_free_result(result); |
6982 | mysql_stmt_close(stmt); |
6983 | |
6984 | stmt= mysql_simple_prepare(mysql, "SELECT @@sql_warnings" ); |
6985 | check_stmt(stmt); |
6986 | |
6987 | result= mysql_stmt_result_metadata(stmt); |
6988 | mytest(result); |
6989 | |
6990 | rc= mysql_stmt_execute(stmt); |
6991 | check_execute(stmt, rc); |
6992 | |
6993 | rc= my_process_stmt_result(stmt); |
6994 | DIE_UNLESS(rc == 1); |
6995 | |
6996 | verify_prepare_field(result, 0, |
6997 | "@@sql_warnings" , "" , /* field and its org name */ |
6998 | MYSQL_TYPE_LONGLONG, /* field type */ |
6999 | "" , "" , /* table and its org name */ |
7000 | "" , 1, 0); /* db name, length */ |
7001 | |
7002 | mysql_free_result(result); |
7003 | mysql_stmt_close(stmt); |
7004 | } |
7005 | |
7006 | |
7007 | /* |
7008 | Test SET OPTION feature with prepare stmts |
7009 | bug #85 (reported by mark@mysql.com) |
7010 | */ |
7011 | |
7012 | static void test_set_option() |
7013 | { |
7014 | MYSQL_STMT *stmt; |
7015 | MYSQL_RES *result; |
7016 | int rc; |
7017 | |
7018 | myheader("test_set_option" ); |
7019 | |
7020 | mysql_autocommit(mysql, TRUE); |
7021 | |
7022 | /* LIMIT the rows count to 2 */ |
7023 | rc= mysql_query(mysql, "SET SQL_SELECT_LIMIT= 2" ); |
7024 | myquery(rc); |
7025 | |
7026 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_limit" ); |
7027 | myquery(rc); |
7028 | |
7029 | rc= mysql_query(mysql, "CREATE TABLE test_limit(a tinyint)" ); |
7030 | myquery(rc); |
7031 | |
7032 | rc= mysql_query(mysql, "INSERT INTO test_limit VALUES(10), (20), (30), (40)" ); |
7033 | myquery(rc); |
7034 | |
7035 | if (!opt_silent) |
7036 | fprintf(stdout, "\n with SQL_SELECT_LIMIT= 2 (direct)" ); |
7037 | rc= mysql_query(mysql, "SELECT * FROM test_limit" ); |
7038 | myquery(rc); |
7039 | |
7040 | result= mysql_store_result(mysql); |
7041 | mytest(result); |
7042 | |
7043 | rc= my_process_result_set(result); |
7044 | DIE_UNLESS(rc == 2); |
7045 | |
7046 | mysql_free_result(result); |
7047 | |
7048 | if (!opt_silent) |
7049 | fprintf(stdout, "\n with SQL_SELECT_LIMIT=2 (prepare)" ); |
7050 | stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_limit" ); |
7051 | check_stmt(stmt); |
7052 | |
7053 | rc= mysql_stmt_execute(stmt); |
7054 | check_execute(stmt, rc); |
7055 | |
7056 | rc= my_process_stmt_result(stmt); |
7057 | DIE_UNLESS(rc == 2); |
7058 | |
7059 | mysql_stmt_close(stmt); |
7060 | |
7061 | /* RESET the LIMIT the rows count to 0 */ |
7062 | if (!opt_silent) |
7063 | fprintf(stdout, "\n with SQL_SELECT_LIMIT=DEFAULT (prepare)" ); |
7064 | rc= mysql_query(mysql, "SET SQL_SELECT_LIMIT=DEFAULT" ); |
7065 | myquery(rc); |
7066 | |
7067 | stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_limit" ); |
7068 | check_stmt(stmt); |
7069 | |
7070 | rc= mysql_stmt_execute(stmt); |
7071 | check_execute(stmt, rc); |
7072 | |
7073 | rc= my_process_stmt_result(stmt); |
7074 | DIE_UNLESS(rc == 4); |
7075 | |
7076 | mysql_stmt_close(stmt); |
7077 | } |
7078 | |
7079 | #ifdef EMBEDDED_LIBRARY |
7080 | static void test_embedded_start_stop() |
7081 | { |
7082 | MYSQL *mysql_emb=NULL; |
7083 | int i, j; |
7084 | int argc= original_argc; // Start with the original args |
7085 | char **argv, **my_argv; |
7086 | char test_name[]= "test_embedded_start_stop" ; |
7087 | #define EMBEDDED_RESTARTS 64 |
7088 | |
7089 | myheader("test_embedded_start_stop" ); |
7090 | |
7091 | /* Must stop the main embedded server, since we use the same config. */ |
7092 | client_disconnect(mysql); /* disconnect from server */ |
7093 | free_defaults(defaults_argv); |
7094 | mysql_server_end(); |
7095 | /* Free everything allocated by my_once_alloc */ |
7096 | my_end(0); |
7097 | |
7098 | /* |
7099 | Use a copy of the original arguments. |
7100 | The arguments will be altered when reading the configs and parsing |
7101 | options. |
7102 | */ |
7103 | my_argv= malloc((argc + 1) * sizeof(char*)); |
7104 | if (!my_argv) |
7105 | exit(1); |
7106 | |
7107 | /* Test restarting the embedded library many times. */ |
7108 | for (i= 1; i <= EMBEDDED_RESTARTS; i++) |
7109 | { |
7110 | argv= my_argv; |
7111 | argv[0]= test_name; |
7112 | for (j= 1; j < argc; j++) |
7113 | argv[j]= original_argv[j]; |
7114 | |
7115 | /* Initialize everything again. */ |
7116 | MY_INIT(argv[0]); |
7117 | |
7118 | /* Load the client defaults from the .cnf file[s]. */ |
7119 | load_defaults_or_exit("my" , client_test_load_default_groups, &argc, &argv); |
7120 | |
7121 | /* Parse the options (including the ones given from defaults files). */ |
7122 | get_options(&argc, &argv); |
7123 | |
7124 | /* mysql_library_init is the same as mysql_server_init. */ |
7125 | if (mysql_library_init(embedded_server_arg_count, |
7126 | embedded_server_args, |
7127 | (char**) embedded_server_groups)) |
7128 | { |
7129 | myerror("mysql_library_init failed" ); |
7130 | exit(1); |
7131 | } |
7132 | |
7133 | /* Create a client connection. */ |
7134 | if (!(mysql_emb= mysql_client_init(NULL))) |
7135 | { |
7136 | myerror("mysql_client_init failed" ); |
7137 | exit(1); |
7138 | } |
7139 | |
7140 | /* Connect it and see if we can use the database. */ |
7141 | if (!(mysql_real_connect(mysql_emb, opt_host, opt_user, |
7142 | opt_password, current_db, 0, |
7143 | NULL, 0))) |
7144 | { |
7145 | myerror("mysql_real_connect failed" ); |
7146 | } |
7147 | |
7148 | /* Close the client connection */ |
7149 | mysql_close(mysql_emb); |
7150 | mysql_emb = NULL; |
7151 | /* Free arguments allocated for defaults files. */ |
7152 | free_defaults(defaults_argv); |
7153 | /* mysql_library_end is a define for mysql_server_end. */ |
7154 | mysql_library_end(); |
7155 | /* Free everything allocated by my_once_alloc */ |
7156 | my_end(0); |
7157 | } |
7158 | |
7159 | argc= original_argc; |
7160 | argv= my_argv; |
7161 | argv[0]= test_name; |
7162 | for (j= 1; j < argc; j++) |
7163 | argv[j]= original_argv[j]; |
7164 | |
7165 | MY_INIT(argv[0]); |
7166 | |
7167 | load_defaults_or_exit("my" , client_test_load_default_groups, &argc, &argv); |
7168 | get_options(&argc, &argv); |
7169 | |
7170 | /* Must start the main embedded server again after the test. */ |
7171 | if (mysql_server_init(embedded_server_arg_count, |
7172 | embedded_server_args, |
7173 | (char**) embedded_server_groups)) |
7174 | DIE("Can't initialize MySQL server" ); |
7175 | |
7176 | /* connect to server with no flags, default protocol, auto reconnect true */ |
7177 | mysql= client_connect(0, MYSQL_PROTOCOL_DEFAULT, 1); |
7178 | free(my_argv); |
7179 | } |
7180 | #endif /* EMBEDDED_LIBRARY */ |
7181 | |
7182 | |
7183 | /* |
7184 | Test a misc GRANT option |
7185 | bug #89 (reported by mark@mysql.com) |
7186 | */ |
7187 | |
7188 | #ifndef EMBEDDED_LIBRARY |
7189 | static void test_prepare_grant() |
7190 | { |
7191 | int rc; |
7192 | char query[MAX_TEST_QUERY_LENGTH]; |
7193 | |
7194 | myheader("test_prepare_grant" ); |
7195 | |
7196 | mysql_autocommit(mysql, TRUE); |
7197 | |
7198 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_grant" ); |
7199 | myquery(rc); |
7200 | |
7201 | rc= mysql_query(mysql, "CREATE TABLE test_grant(a tinyint primary key auto_increment)" ); |
7202 | myquery(rc); |
7203 | |
7204 | strxmov(query, "GRANT INSERT, UPDATE, SELECT ON " , current_db, |
7205 | ".test_grant TO 'test_grant'@" , |
7206 | opt_host ? opt_host : "'localhost'" , NullS); |
7207 | |
7208 | if (mysql_query(mysql, query)) |
7209 | { |
7210 | myerror("GRANT failed" ); |
7211 | |
7212 | /* |
7213 | If server started with --skip-grant-tables, skip this test, else |
7214 | exit to indicate an error |
7215 | |
7216 | ER_UNKNOWN_COM_ERROR= 1047 |
7217 | */ |
7218 | if (mysql_errno(mysql) != 1047) |
7219 | exit(1); |
7220 | } |
7221 | else |
7222 | { |
7223 | MYSQL *org_mysql= mysql, *lmysql; |
7224 | MYSQL_STMT *stmt; |
7225 | |
7226 | if (!opt_silent) |
7227 | fprintf(stdout, "\n Establishing a test connection ..." ); |
7228 | if (!(lmysql= mysql_client_init(NULL))) |
7229 | { |
7230 | myerror("mysql_client_init() failed" ); |
7231 | exit(1); |
7232 | } |
7233 | if (!(mysql_real_connect(lmysql, opt_host, "test_grant" , |
7234 | "" , current_db, opt_port, |
7235 | opt_unix_socket, 0))) |
7236 | { |
7237 | myerror("connection failed" ); |
7238 | mysql_close(lmysql); |
7239 | exit(1); |
7240 | } |
7241 | mysql_options(lmysql, MYSQL_OPT_RECONNECT, &my_true); |
7242 | if (!opt_silent) |
7243 | fprintf(stdout, "OK" ); |
7244 | |
7245 | mysql= lmysql; |
7246 | rc= mysql_query(mysql, "INSERT INTO test_grant VALUES(NULL)" ); |
7247 | myquery(rc); |
7248 | |
7249 | rc= mysql_query(mysql, "INSERT INTO test_grant(a) VALUES(NULL)" ); |
7250 | myquery(rc); |
7251 | |
7252 | execute_prepare_query("INSERT INTO test_grant(a) VALUES(NULL)" , 1); |
7253 | execute_prepare_query("INSERT INTO test_grant VALUES(NULL)" , 1); |
7254 | execute_prepare_query("UPDATE test_grant SET a=9 WHERE a=1" , 1); |
7255 | rc= my_stmt_result("SELECT a FROM test_grant" ); |
7256 | DIE_UNLESS(rc == 4); |
7257 | |
7258 | /* Both DELETE expected to fail as user does not have DELETE privs */ |
7259 | |
7260 | rc= mysql_query(mysql, "DELETE FROM test_grant" ); |
7261 | myquery_r(rc); |
7262 | |
7263 | stmt= mysql_simple_prepare(mysql, "DELETE FROM test_grant" ); |
7264 | check_stmt_r(stmt); |
7265 | |
7266 | rc= my_stmt_result("SELECT * FROM test_grant" ); |
7267 | DIE_UNLESS(rc == 4); |
7268 | |
7269 | mysql_close(lmysql); |
7270 | mysql= org_mysql; |
7271 | |
7272 | rc= mysql_query(mysql, "delete from mysql.user where User='test_grant'" ); |
7273 | myquery(rc); |
7274 | DIE_UNLESS(1 == mysql_affected_rows(mysql)); |
7275 | |
7276 | rc= mysql_query(mysql, "delete from mysql.tables_priv where User='test_grant'" ); |
7277 | myquery(rc); |
7278 | DIE_UNLESS(1 == mysql_affected_rows(mysql)); |
7279 | |
7280 | } |
7281 | } |
7282 | #endif /* EMBEDDED_LIBRARY */ |
7283 | |
7284 | /* |
7285 | Test a crash when invalid/corrupted .frm is used in the |
7286 | SHOW TABLE STATUS |
7287 | bug #93 (reported by serg@mysql.com). |
7288 | */ |
7289 | |
7290 | static void test_frm_bug() |
7291 | { |
7292 | MYSQL_STMT *stmt; |
7293 | MYSQL_BIND my_bind[2]; |
7294 | MYSQL_RES *result; |
7295 | MYSQL_ROW row; |
7296 | FILE *test_file; |
7297 | char data_dir[FN_REFLEN]; |
7298 | char test_frm[FN_REFLEN]; |
7299 | int rc; |
7300 | |
7301 | myheader("test_frm_bug" ); |
7302 | |
7303 | mysql_autocommit(mysql, TRUE); |
7304 | |
7305 | rc= mysql_query(mysql, "drop table if exists test_frm_bug" ); |
7306 | myquery(rc); |
7307 | |
7308 | rc= mysql_query(mysql, "flush tables" ); |
7309 | myquery(rc); |
7310 | |
7311 | stmt= mysql_simple_prepare(mysql, "show variables like 'datadir'" ); |
7312 | check_stmt(stmt); |
7313 | |
7314 | rc= mysql_stmt_execute(stmt); |
7315 | check_execute(stmt, rc); |
7316 | |
7317 | bzero((char*) my_bind, sizeof(my_bind)); |
7318 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
7319 | my_bind[0].buffer= data_dir; |
7320 | my_bind[0].buffer_length= FN_REFLEN; |
7321 | my_bind[1]= my_bind[0]; |
7322 | |
7323 | rc= mysql_stmt_bind_result(stmt, my_bind); |
7324 | check_execute(stmt, rc); |
7325 | |
7326 | rc= mysql_stmt_fetch(stmt); |
7327 | check_execute(stmt, rc); |
7328 | |
7329 | if (!opt_silent) |
7330 | fprintf(stdout, "\n data directory: %s" , data_dir); |
7331 | |
7332 | rc= mysql_stmt_fetch(stmt); |
7333 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
7334 | |
7335 | strxmov(test_frm, data_dir, "/" , current_db, "/" , "test_frm_bug.frm" , NullS); |
7336 | |
7337 | if (!opt_silent) |
7338 | fprintf(stdout, "\n test_frm: %s" , test_frm); |
7339 | |
7340 | if (!(test_file= my_fopen(test_frm, (int) (O_RDWR | O_CREAT), MYF(MY_WME)))) |
7341 | { |
7342 | fprintf(stdout, "\n ERROR: my_fopen failed for '%s'" , test_frm); |
7343 | fprintf(stdout, "\n test cancelled" ); |
7344 | exit(1); |
7345 | } |
7346 | if (!opt_silent) |
7347 | fprintf(test_file, "this is a junk file for test" ); |
7348 | |
7349 | rc= mysql_query(mysql, "SHOW TABLE STATUS like 'test_frm_bug'" ); |
7350 | myquery(rc); |
7351 | |
7352 | result= mysql_store_result(mysql); |
7353 | mytest(result);/* It can't be NULL */ |
7354 | |
7355 | rc= my_process_result_set(result); |
7356 | DIE_UNLESS(rc == 1); |
7357 | |
7358 | mysql_data_seek(result, 0); |
7359 | |
7360 | row= mysql_fetch_row(result); |
7361 | mytest(row); |
7362 | |
7363 | if (!opt_silent) |
7364 | fprintf(stdout, "\n Comment: %s" , row[17]); |
7365 | DIE_UNLESS(row[17] != 0); |
7366 | |
7367 | mysql_free_result(result); |
7368 | mysql_stmt_close(stmt); |
7369 | |
7370 | my_fclose(test_file, MYF(0)); |
7371 | mysql_query(mysql, "drop table if exists test_frm_bug" ); |
7372 | } |
7373 | |
7374 | |
7375 | /* Test DECIMAL conversion */ |
7376 | |
7377 | static void test_decimal_bug() |
7378 | { |
7379 | MYSQL_STMT *stmt; |
7380 | MYSQL_BIND my_bind[1]; |
7381 | char data[30]; |
7382 | int rc; |
7383 | my_bool is_null; |
7384 | |
7385 | myheader("test_decimal_bug" ); |
7386 | |
7387 | mysql_autocommit(mysql, TRUE); |
7388 | |
7389 | rc= mysql_query(mysql, "drop table if exists test_decimal_bug" ); |
7390 | myquery(rc); |
7391 | |
7392 | rc= mysql_query(mysql, "create table test_decimal_bug(c1 decimal(10, 2))" ); |
7393 | myquery(rc); |
7394 | |
7395 | rc= mysql_query(mysql, "insert into test_decimal_bug value(8), (10.22), (5.61)" ); |
7396 | myquery(rc); |
7397 | |
7398 | stmt= mysql_simple_prepare(mysql, "select c1 from test_decimal_bug where c1= ?" ); |
7399 | check_stmt(stmt); |
7400 | |
7401 | /* |
7402 | We need to bzero bind structure because mysql_stmt_bind_param checks all |
7403 | its members. |
7404 | */ |
7405 | bzero((char*) my_bind, sizeof(my_bind)); |
7406 | |
7407 | my_bind[0].buffer_type= MYSQL_TYPE_NEWDECIMAL; |
7408 | my_bind[0].buffer= (void *)data; |
7409 | my_bind[0].buffer_length= 25; |
7410 | my_bind[0].is_null= &is_null; |
7411 | |
7412 | is_null= 0; |
7413 | rc= mysql_stmt_bind_param(stmt, my_bind); |
7414 | check_execute(stmt, rc); |
7415 | |
7416 | strmov(data, "8.0" ); |
7417 | rc= mysql_stmt_execute(stmt); |
7418 | check_execute(stmt, rc); |
7419 | |
7420 | data[0]= 0; |
7421 | rc= mysql_stmt_bind_result(stmt, my_bind); |
7422 | check_execute(stmt, rc); |
7423 | |
7424 | rc= mysql_stmt_fetch(stmt); |
7425 | check_execute(stmt, rc); |
7426 | |
7427 | if (!opt_silent) |
7428 | fprintf(stdout, "\n data: %s" , data); |
7429 | DIE_UNLESS(strcmp(data, "8.00" ) == 0); |
7430 | |
7431 | rc= mysql_stmt_fetch(stmt); |
7432 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
7433 | |
7434 | strmov(data, "5.61" ); |
7435 | rc= mysql_stmt_execute(stmt); |
7436 | check_execute(stmt, rc); |
7437 | |
7438 | data[0]= 0; |
7439 | rc= mysql_stmt_bind_result(stmt, my_bind); |
7440 | check_execute(stmt, rc); |
7441 | |
7442 | rc= mysql_stmt_fetch(stmt); |
7443 | check_execute(stmt, rc); |
7444 | |
7445 | if (!opt_silent) |
7446 | fprintf(stdout, "\n data: %s" , data); |
7447 | DIE_UNLESS(strcmp(data, "5.61" ) == 0); |
7448 | |
7449 | rc= mysql_stmt_fetch(stmt); |
7450 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
7451 | |
7452 | is_null= 1; |
7453 | rc= mysql_stmt_execute(stmt); |
7454 | check_execute(stmt, rc); |
7455 | |
7456 | rc= mysql_stmt_fetch(stmt); |
7457 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
7458 | |
7459 | strmov(data, "10.22" ); is_null= 0; |
7460 | rc= mysql_stmt_execute(stmt); |
7461 | check_execute(stmt, rc); |
7462 | |
7463 | data[0]= 0; |
7464 | rc= mysql_stmt_bind_result(stmt, my_bind); |
7465 | check_execute(stmt, rc); |
7466 | |
7467 | rc= mysql_stmt_fetch(stmt); |
7468 | check_execute(stmt, rc); |
7469 | |
7470 | if (!opt_silent) |
7471 | fprintf(stdout, "\n data: %s" , data); |
7472 | DIE_UNLESS(strcmp(data, "10.22" ) == 0); |
7473 | |
7474 | rc= mysql_stmt_fetch(stmt); |
7475 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
7476 | |
7477 | mysql_stmt_close(stmt); |
7478 | } |
7479 | |
7480 | |
7481 | /* Test EXPLAIN bug (#115, reported by mark@mysql.com & georg@php.net). */ |
7482 | |
7483 | static void test_explain_bug() |
7484 | { |
7485 | MYSQL_STMT *stmt; |
7486 | MYSQL_RES *result; |
7487 | int rc; |
7488 | |
7489 | myheader("test_explain_bug" ); |
7490 | |
7491 | mysql_autocommit(mysql, TRUE); |
7492 | |
7493 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_explain" ); |
7494 | myquery(rc); |
7495 | |
7496 | rc= mysql_query(mysql, "CREATE TABLE test_explain(id int, name char(2))" ); |
7497 | myquery(rc); |
7498 | |
7499 | stmt= mysql_simple_prepare(mysql, "explain test_explain" ); |
7500 | check_stmt(stmt); |
7501 | |
7502 | rc= mysql_stmt_execute(stmt); |
7503 | check_execute(stmt, rc); |
7504 | |
7505 | rc= my_process_stmt_result(stmt); |
7506 | DIE_UNLESS(rc == 2); |
7507 | |
7508 | result= mysql_stmt_result_metadata(stmt); |
7509 | mytest(result); |
7510 | |
7511 | if (!opt_silent) |
7512 | fprintf(stdout, "\n total fields in the result: %d" , |
7513 | mysql_num_fields(result)); |
7514 | DIE_UNLESS(6 == mysql_num_fields(result)); |
7515 | |
7516 | verify_prepare_field(result, 0, "Field" , "COLUMN_NAME" , |
7517 | mysql_get_server_version(mysql) <= 50000 ? |
7518 | MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING, |
7519 | 0, 0, "information_schema" , 64, 0); |
7520 | |
7521 | verify_prepare_field(result, 1, "Type" , "COLUMN_TYPE" , MYSQL_TYPE_BLOB, |
7522 | 0, 0, "information_schema" , 0, 0); |
7523 | |
7524 | verify_prepare_field(result, 2, "Null" , "IS_NULLABLE" , |
7525 | mysql_get_server_version(mysql) <= 50000 ? |
7526 | MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING, |
7527 | 0, 0, "information_schema" , 3, 0); |
7528 | |
7529 | verify_prepare_field(result, 3, "Key" , "COLUMN_KEY" , |
7530 | mysql_get_server_version(mysql) <= 50000 ? |
7531 | MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING, |
7532 | 0, 0, "information_schema" , 3, 0); |
7533 | |
7534 | if ( mysql_get_server_version(mysql) >= 50027 ) |
7535 | { |
7536 | /* The patch for bug#23037 changes column type of DEAULT to blob */ |
7537 | verify_prepare_field(result, 4, "Default" , "COLUMN_DEFAULT" , |
7538 | MYSQL_TYPE_BLOB, 0, 0, "information_schema" , 0, 0); |
7539 | } |
7540 | else |
7541 | { |
7542 | verify_prepare_field(result, 4, "Default" , "COLUMN_DEFAULT" , |
7543 | mysql_get_server_version(mysql) >= 50027 ? |
7544 | MYSQL_TYPE_BLOB : |
7545 | mysql_get_server_version(mysql) <= 50000 ? |
7546 | MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING, |
7547 | 0, 0, "information_schema" , |
7548 | mysql_get_server_version(mysql) >= 50027 ? 0 :64, 0); |
7549 | } |
7550 | |
7551 | verify_prepare_field(result, 5, "Extra" , "EXTRA" , |
7552 | mysql_get_server_version(mysql) <= 50000 ? |
7553 | MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING, |
7554 | 0, 0, "information_schema" , 30, 0); |
7555 | |
7556 | mysql_free_result(result); |
7557 | mysql_stmt_close(stmt); |
7558 | |
7559 | stmt= mysql_simple_prepare(mysql, "explain select id, name FROM test_explain" ); |
7560 | check_stmt(stmt); |
7561 | |
7562 | rc= mysql_stmt_execute(stmt); |
7563 | check_execute(stmt, rc); |
7564 | |
7565 | rc= my_process_stmt_result(stmt); |
7566 | DIE_UNLESS(rc == 1); |
7567 | |
7568 | result= mysql_stmt_result_metadata(stmt); |
7569 | mytest(result); |
7570 | |
7571 | if (!opt_silent) |
7572 | fprintf(stdout, "\n total fields in the result: %d" , |
7573 | mysql_num_fields(result)); |
7574 | DIE_UNLESS(10 == mysql_num_fields(result)); |
7575 | |
7576 | verify_prepare_field(result, 0, "id" , "" , MYSQL_TYPE_LONGLONG, |
7577 | "" , "" , "" , 3, 0); |
7578 | |
7579 | verify_prepare_field(result, 1, "select_type" , "" , MYSQL_TYPE_VAR_STRING, |
7580 | "" , "" , "" , 19, 0); |
7581 | |
7582 | verify_prepare_field(result, 2, "table" , "" , MYSQL_TYPE_VAR_STRING, |
7583 | "" , "" , "" , NAME_CHAR_LEN, 0); |
7584 | |
7585 | verify_prepare_field(result, 3, "type" , "" , MYSQL_TYPE_VAR_STRING, |
7586 | "" , "" , "" , 10, 0); |
7587 | |
7588 | verify_prepare_field(result, 4, "possible_keys" , "" , MYSQL_TYPE_VAR_STRING, |
7589 | "" , "" , "" , NAME_CHAR_LEN*MAX_KEY, 0); |
7590 | |
7591 | verify_prepare_field(result, 5, "key" , "" , MYSQL_TYPE_VAR_STRING, |
7592 | "" , "" , "" , NAME_CHAR_LEN, 0); |
7593 | |
7594 | if (mysql_get_server_version(mysql) <= 50000) |
7595 | { |
7596 | verify_prepare_field(result, 6, "key_len" , "" , MYSQL_TYPE_LONGLONG, "" , |
7597 | "" , "" , 3, 0); |
7598 | } |
7599 | else |
7600 | { |
7601 | verify_prepare_field(result, 6, "key_len" , "" , MYSQL_TYPE_VAR_STRING, "" , |
7602 | "" , "" , NAME_CHAR_LEN*MAX_KEY, 0); |
7603 | } |
7604 | |
7605 | /* The length of this may verify between MariaDB versions (1024 / 2048) */ |
7606 | verify_prepare_field(result, 7, "ref" , "" , MYSQL_TYPE_VAR_STRING, |
7607 | "" , "" , "" , NAME_CHAR_LEN * HA_MAX_KEY_SEG, 0); |
7608 | |
7609 | verify_prepare_field(result, 8, "rows" , "" , MYSQL_TYPE_LONGLONG, |
7610 | "" , "" , "" , 10, 0); |
7611 | |
7612 | verify_prepare_field(result, 9, "Extra" , "" , MYSQL_TYPE_VAR_STRING, |
7613 | "" , "" , "" , 255, 0); |
7614 | |
7615 | mysql_free_result(result); |
7616 | mysql_stmt_close(stmt); |
7617 | } |
7618 | |
7619 | #ifdef NOT_YET_WORKING |
7620 | |
7621 | /* |
7622 | Test math functions. |
7623 | Bug #148 (reported by salle@mysql.com). |
7624 | */ |
7625 | |
7626 | #define myerrno(n) check_errcode(n) |
7627 | |
7628 | static void check_errcode(const unsigned int err) |
7629 | { |
7630 | if (!opt_silent || mysql_errno(mysql) != err) |
7631 | { |
7632 | if (mysql->server_version) |
7633 | fprintf(stdout, "\n [MySQL-%s]" , mysql->server_version); |
7634 | else |
7635 | fprintf(stdout, "\n [MySQL]" ); |
7636 | fprintf(stdout, "[%d] %s\n" , mysql_errno(mysql), mysql_error(mysql)); |
7637 | } |
7638 | DIE_UNLESS(mysql_errno(mysql) == err); |
7639 | } |
7640 | |
7641 | |
7642 | static void test_drop_temp() |
7643 | { |
7644 | int rc; |
7645 | |
7646 | myheader("test_drop_temp" ); |
7647 | |
7648 | rc= mysql_query(mysql, "DROP DATABASE IF EXISTS test_drop_temp_db" ); |
7649 | myquery(rc); |
7650 | |
7651 | rc= mysql_query(mysql, "CREATE DATABASE test_drop_temp_db" ); |
7652 | myquery(rc); |
7653 | |
7654 | rc= mysql_query(mysql, "CREATE TABLE test_drop_temp_db.t1(c1 int, c2 char(1))" ); |
7655 | myquery(rc); |
7656 | |
7657 | rc= mysql_query(mysql, "delete from mysql.db where Db='test_drop_temp_db'" ); |
7658 | myquery(rc); |
7659 | |
7660 | rc= mysql_query(mysql, "delete from mysql.db where Db='test_drop_temp_db'" ); |
7661 | myquery(rc); |
7662 | |
7663 | strxmov(query, "GRANT SELECT, USAGE, DROP ON test_drop_temp_db.* TO test_temp@" , |
7664 | opt_host ? opt_host : "localhost" , NullS); |
7665 | |
7666 | if (mysql_query(mysql, query)) |
7667 | { |
7668 | myerror("GRANT failed" ); |
7669 | |
7670 | /* |
7671 | If server started with --skip-grant-tables, skip this test, else |
7672 | exit to indicate an error |
7673 | |
7674 | ER_UNKNOWN_COM_ERROR= 1047 |
7675 | */ |
7676 | if (mysql_errno(mysql) != 1047) |
7677 | exit(1); |
7678 | } |
7679 | else |
7680 | { |
7681 | MYSQL *org_mysql= mysql, *lmysql; |
7682 | |
7683 | if (!opt_silent) |
7684 | fprintf(stdout, "\n Establishing a test connection ..." ); |
7685 | if (!(lmysql= mysql_client_init(NULL))) |
7686 | { |
7687 | myerror("mysql_client_init() failed" ); |
7688 | exit(1); |
7689 | } |
7690 | |
7691 | rc= mysql_query(mysql, "flush privileges" ); |
7692 | myquery(rc); |
7693 | |
7694 | if (!(mysql_real_connect(lmysql, opt_host ? opt_host : "localhost" , "test_temp" , |
7695 | "" , "test_drop_temp_db" , opt_port, |
7696 | opt_unix_socket, 0))) |
7697 | { |
7698 | mysql= lmysql; |
7699 | myerror("connection failed" ); |
7700 | mysql_close(lmysql); |
7701 | exit(1); |
7702 | } |
7703 | mysql_options(lmysql, MYSQL_OPT_RECONNECT, &my_true); |
7704 | if (!opt_silent) |
7705 | fprintf(stdout, "OK" ); |
7706 | |
7707 | mysql= lmysql; |
7708 | rc= mysql_query(mysql, "INSERT INTO t1 VALUES(10, 'C')" ); |
7709 | myerrno((uint)1142); |
7710 | |
7711 | rc= mysql_query(mysql, "DROP TABLE t1" ); |
7712 | myerrno((uint)1142); |
7713 | |
7714 | mysql= org_mysql; |
7715 | rc= mysql_query(mysql, "CREATE TEMPORARY TABLE test_drop_temp_db.t1(c1 int)" ); |
7716 | myquery(rc); |
7717 | |
7718 | rc= mysql_query(mysql, "CREATE TEMPORARY TABLE test_drop_temp_db.t2 LIKE test_drop_temp_db.t1" ); |
7719 | myquery(rc); |
7720 | |
7721 | mysql= lmysql; |
7722 | |
7723 | rc= mysql_query(mysql, "DROP TABLE t1, t2" ); |
7724 | myquery_r(rc); |
7725 | |
7726 | rc= mysql_query(mysql, "DROP TEMPORARY TABLE t1" ); |
7727 | myquery_r(rc); |
7728 | |
7729 | rc= mysql_query(mysql, "DROP TEMPORARY TABLE t2" ); |
7730 | myquery_r(rc); |
7731 | |
7732 | mysql_close(lmysql); |
7733 | mysql= org_mysql; |
7734 | |
7735 | rc= mysql_query(mysql, "drop database test_drop_temp_db" ); |
7736 | myquery(rc); |
7737 | DIE_UNLESS(1 == mysql_affected_rows(mysql)); |
7738 | |
7739 | rc= mysql_query(mysql, "delete from mysql.user where User='test_temp'" ); |
7740 | myquery(rc); |
7741 | DIE_UNLESS(1 == mysql_affected_rows(mysql)); |
7742 | |
7743 | |
7744 | rc= mysql_query(mysql, "delete from mysql.tables_priv where User='test_temp'" ); |
7745 | myquery(rc); |
7746 | DIE_UNLESS(1 == mysql_affected_rows(mysql)); |
7747 | } |
7748 | } |
7749 | #endif |
7750 | |
7751 | |
7752 | /* Test warnings for cuted rows */ |
7753 | |
7754 | static void test_cuted_rows() |
7755 | { |
7756 | int rc, count; |
7757 | MYSQL_RES *result; |
7758 | |
7759 | myheader("test_cuted_rows" ); |
7760 | |
7761 | mysql_query(mysql, "DROP TABLE if exists t1" ); |
7762 | mysql_query(mysql, "DROP TABLE if exists t2" ); |
7763 | |
7764 | rc= mysql_query(mysql, "CREATE TABLE t1(c1 tinyint)" ); |
7765 | myquery(rc); |
7766 | |
7767 | rc= mysql_query(mysql, "CREATE TABLE t2(c1 int not null)" ); |
7768 | myquery(rc); |
7769 | |
7770 | rc= mysql_query(mysql, "INSERT INTO t1 values(10), (NULL), (NULL)" ); |
7771 | myquery(rc); |
7772 | |
7773 | count= mysql_warning_count(mysql); |
7774 | if (!opt_silent) |
7775 | fprintf(stdout, "\n total warnings: %d" , count); |
7776 | DIE_UNLESS(count == 0); |
7777 | |
7778 | rc= mysql_query(mysql, "INSERT INTO t2 SELECT * FROM t1" ); |
7779 | myquery(rc); |
7780 | |
7781 | count= mysql_warning_count(mysql); |
7782 | if (!opt_silent) |
7783 | fprintf(stdout, "\n total warnings: %d" , count); |
7784 | DIE_UNLESS(count == 2); |
7785 | |
7786 | rc= mysql_query(mysql, "SHOW WARNINGS" ); |
7787 | myquery(rc); |
7788 | |
7789 | result= mysql_store_result(mysql); |
7790 | mytest(result); |
7791 | |
7792 | rc= my_process_result_set(result); |
7793 | DIE_UNLESS(rc == 2); |
7794 | mysql_free_result(result); |
7795 | |
7796 | rc= mysql_query(mysql, "INSERT INTO t1 VALUES('junk'), (876789)" ); |
7797 | myquery(rc); |
7798 | |
7799 | count= mysql_warning_count(mysql); |
7800 | if (!opt_silent) |
7801 | fprintf(stdout, "\n total warnings: %d" , count); |
7802 | DIE_UNLESS(count == 2); |
7803 | |
7804 | rc= mysql_query(mysql, "SHOW WARNINGS" ); |
7805 | myquery(rc); |
7806 | |
7807 | result= mysql_store_result(mysql); |
7808 | mytest(result); |
7809 | |
7810 | rc= my_process_result_set(result); |
7811 | DIE_UNLESS(rc == 2); |
7812 | mysql_free_result(result); |
7813 | } |
7814 | |
7815 | |
7816 | /* Test update/binary logs */ |
7817 | |
7818 | static void test_logs() |
7819 | { |
7820 | MYSQL_STMT *stmt; |
7821 | MYSQL_BIND my_bind[2]; |
7822 | char data[255]; |
7823 | ulong length; |
7824 | int rc; |
7825 | short id; |
7826 | |
7827 | myheader("test_logs" ); |
7828 | |
7829 | |
7830 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_logs" ); |
7831 | myquery(rc); |
7832 | |
7833 | rc= mysql_query(mysql, "CREATE TABLE test_logs(id smallint, name varchar(20))" ); |
7834 | myquery(rc); |
7835 | |
7836 | strmov((char *)data, "INSERT INTO test_logs VALUES(?, ?)" ); |
7837 | stmt= mysql_simple_prepare(mysql, data); |
7838 | check_stmt(stmt); |
7839 | |
7840 | /* |
7841 | We need to bzero bind structure because mysql_stmt_bind_param checks all |
7842 | its members. |
7843 | */ |
7844 | bzero((char*) my_bind, sizeof(my_bind)); |
7845 | |
7846 | my_bind[0].buffer_type= MYSQL_TYPE_SHORT; |
7847 | my_bind[0].buffer= (void *)&id; |
7848 | |
7849 | my_bind[1].buffer_type= MYSQL_TYPE_STRING; |
7850 | my_bind[1].buffer= (void *)&data; |
7851 | my_bind[1].buffer_length= 255; |
7852 | my_bind[1].length= &length; |
7853 | |
7854 | id= 9876; |
7855 | length= (ulong)(strmov((char *)data, "MySQL - Open Source Database" )- data); |
7856 | |
7857 | rc= mysql_stmt_bind_param(stmt, my_bind); |
7858 | check_execute(stmt, rc); |
7859 | |
7860 | rc= mysql_stmt_execute(stmt); |
7861 | check_execute(stmt, rc); |
7862 | |
7863 | strmov((char *)data, "'" ); |
7864 | length= 1; |
7865 | |
7866 | rc= mysql_stmt_execute(stmt); |
7867 | check_execute(stmt, rc); |
7868 | |
7869 | strmov((char *)data, "\"" ); |
7870 | length= 1; |
7871 | |
7872 | rc= mysql_stmt_execute(stmt); |
7873 | check_execute(stmt, rc); |
7874 | |
7875 | length= (ulong)(strmov((char *)data, "my\'sql\'" )-data); |
7876 | rc= mysql_stmt_execute(stmt); |
7877 | check_execute(stmt, rc); |
7878 | |
7879 | length= (ulong)(strmov((char *)data, "my\"sql\"" )-data); |
7880 | rc= mysql_stmt_execute(stmt); |
7881 | check_execute(stmt, rc); |
7882 | |
7883 | mysql_stmt_close(stmt); |
7884 | |
7885 | strmov((char *)data, "INSERT INTO test_logs VALUES(20, 'mysql')" ); |
7886 | stmt= mysql_simple_prepare(mysql, data); |
7887 | check_stmt(stmt); |
7888 | |
7889 | rc= mysql_stmt_execute(stmt); |
7890 | check_execute(stmt, rc); |
7891 | |
7892 | rc= mysql_stmt_execute(stmt); |
7893 | check_execute(stmt, rc); |
7894 | |
7895 | mysql_stmt_close(stmt); |
7896 | |
7897 | strmov((char *)data, "SELECT * FROM test_logs WHERE id=?" ); |
7898 | stmt= mysql_simple_prepare(mysql, data); |
7899 | check_stmt(stmt); |
7900 | |
7901 | rc= mysql_stmt_bind_param(stmt, my_bind); |
7902 | check_execute(stmt, rc); |
7903 | |
7904 | rc= mysql_stmt_execute(stmt); |
7905 | check_execute(stmt, rc); |
7906 | |
7907 | my_bind[1].buffer_length= 255; |
7908 | rc= mysql_stmt_bind_result(stmt, my_bind); |
7909 | check_execute(stmt, rc); |
7910 | |
7911 | rc= mysql_stmt_fetch(stmt); |
7912 | check_execute(stmt, rc); |
7913 | |
7914 | if (!opt_silent) |
7915 | { |
7916 | fprintf(stdout, "id : %d\n" , id); |
7917 | fprintf(stdout, "name : %s(%ld)\n" , data, length); |
7918 | } |
7919 | |
7920 | DIE_UNLESS(id == 9876); |
7921 | DIE_UNLESS(length == 19 || length == 20); /* Due to VARCHAR(20) */ |
7922 | DIE_UNLESS(is_prefix(data, "MySQL - Open Source" ) == 1); |
7923 | |
7924 | rc= mysql_stmt_fetch(stmt); |
7925 | check_execute(stmt, rc); |
7926 | |
7927 | if (!opt_silent) |
7928 | fprintf(stdout, "\n name : %s(%ld)" , data, length); |
7929 | |
7930 | DIE_UNLESS(length == 1); |
7931 | DIE_UNLESS(strcmp(data, "'" ) == 0); |
7932 | |
7933 | rc= mysql_stmt_fetch(stmt); |
7934 | check_execute(stmt, rc); |
7935 | |
7936 | if (!opt_silent) |
7937 | fprintf(stdout, "\n name : %s(%ld)" , data, length); |
7938 | |
7939 | DIE_UNLESS(length == 1); |
7940 | DIE_UNLESS(strcmp(data, "\"" ) == 0); |
7941 | |
7942 | rc= mysql_stmt_fetch(stmt); |
7943 | check_execute(stmt, rc); |
7944 | |
7945 | if (!opt_silent) |
7946 | fprintf(stdout, "\n name : %s(%ld)" , data, length); |
7947 | |
7948 | DIE_UNLESS(length == 7); |
7949 | DIE_UNLESS(strcmp(data, "my\'sql\'" ) == 0); |
7950 | |
7951 | rc= mysql_stmt_fetch(stmt); |
7952 | check_execute(stmt, rc); |
7953 | |
7954 | if (!opt_silent) |
7955 | fprintf(stdout, "\n name : %s(%ld)" , data, length); |
7956 | |
7957 | DIE_UNLESS(length == 7); |
7958 | /*DIE_UNLESS(strcmp(data, "my\"sql\"") == 0); */ |
7959 | |
7960 | rc= mysql_stmt_fetch(stmt); |
7961 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
7962 | |
7963 | mysql_stmt_close(stmt); |
7964 | |
7965 | rc= mysql_query(mysql, "DROP TABLE test_logs" ); |
7966 | myquery(rc); |
7967 | } |
7968 | |
7969 | |
7970 | /* Test 'n' statements create and close */ |
7971 | |
7972 | static void test_nstmts() |
7973 | { |
7974 | MYSQL_STMT *stmt; |
7975 | char query[255]; |
7976 | int rc; |
7977 | static uint i, total_stmts= 2000; |
7978 | MYSQL_BIND my_bind[1]; |
7979 | |
7980 | myheader("test_nstmts" ); |
7981 | |
7982 | mysql_autocommit(mysql, TRUE); |
7983 | |
7984 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_nstmts" ); |
7985 | myquery(rc); |
7986 | |
7987 | rc= mysql_query(mysql, "CREATE TABLE test_nstmts(id int)" ); |
7988 | myquery(rc); |
7989 | |
7990 | /* |
7991 | We need to bzero bind structure because mysql_stmt_bind_param checks all |
7992 | its members. |
7993 | */ |
7994 | bzero((char*) my_bind, sizeof(my_bind)); |
7995 | |
7996 | my_bind[0].buffer= (void *)&i; |
7997 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
7998 | |
7999 | for (i= 0; i < total_stmts; i++) |
8000 | { |
8001 | if (!opt_silent) |
8002 | fprintf(stdout, "\r stmt: %d" , i); |
8003 | |
8004 | strmov(query, "insert into test_nstmts values(?)" ); |
8005 | stmt= mysql_simple_prepare(mysql, query); |
8006 | check_stmt(stmt); |
8007 | |
8008 | rc= mysql_stmt_bind_param(stmt, my_bind); |
8009 | check_execute(stmt, rc); |
8010 | |
8011 | rc= mysql_stmt_execute(stmt); |
8012 | check_execute(stmt, rc); |
8013 | |
8014 | mysql_stmt_close(stmt); |
8015 | } |
8016 | |
8017 | stmt= mysql_simple_prepare(mysql, " select count(*) from test_nstmts" ); |
8018 | check_stmt(stmt); |
8019 | |
8020 | rc= mysql_stmt_execute(stmt); |
8021 | check_execute(stmt, rc); |
8022 | |
8023 | i= 0; |
8024 | rc= mysql_stmt_bind_result(stmt, my_bind); |
8025 | check_execute(stmt, rc); |
8026 | |
8027 | rc= mysql_stmt_fetch(stmt); |
8028 | check_execute(stmt, rc); |
8029 | if (!opt_silent) |
8030 | fprintf(stdout, "\n total rows: %d" , i); |
8031 | DIE_UNLESS( i == total_stmts); |
8032 | |
8033 | rc= mysql_stmt_fetch(stmt); |
8034 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
8035 | |
8036 | mysql_stmt_close(stmt); |
8037 | |
8038 | rc= mysql_query(mysql, "DROP TABLE test_nstmts" ); |
8039 | myquery(rc); |
8040 | } |
8041 | |
8042 | |
8043 | /* Test stmt seek() functions */ |
8044 | |
8045 | static void test_fetch_seek() |
8046 | { |
8047 | MYSQL_STMT *stmt; |
8048 | MYSQL_BIND my_bind[3]; |
8049 | MYSQL_ROW_OFFSET row; |
8050 | int rc; |
8051 | int32 c1; |
8052 | char c2[11], c3[20]; |
8053 | |
8054 | myheader("test_fetch_seek" ); |
8055 | rc= mysql_query(mysql, "drop table if exists t1" ); |
8056 | |
8057 | myquery(rc); |
8058 | |
8059 | rc= mysql_query(mysql, "create table t1(c1 int primary key auto_increment, c2 char(10), c3 timestamp)" ); |
8060 | myquery(rc); |
8061 | |
8062 | rc= mysql_query(mysql, "insert into t1(c2) values('venu'), ('mysql'), ('open'), ('source')" ); |
8063 | myquery(rc); |
8064 | |
8065 | stmt= mysql_simple_prepare(mysql, "select * from t1" ); |
8066 | check_stmt(stmt); |
8067 | |
8068 | bzero((char*) my_bind, sizeof(my_bind)); |
8069 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
8070 | my_bind[0].buffer= (void *)&c1; |
8071 | |
8072 | my_bind[1].buffer_type= MYSQL_TYPE_STRING; |
8073 | my_bind[1].buffer= (void *)c2; |
8074 | my_bind[1].buffer_length= sizeof(c2); |
8075 | |
8076 | my_bind[2]= my_bind[1]; |
8077 | my_bind[2].buffer= (void *)c3; |
8078 | my_bind[2].buffer_length= sizeof(c3); |
8079 | |
8080 | rc= mysql_stmt_execute(stmt); |
8081 | check_execute(stmt, rc); |
8082 | |
8083 | rc= mysql_stmt_bind_result(stmt, my_bind); |
8084 | check_execute(stmt, rc); |
8085 | |
8086 | rc= mysql_stmt_store_result(stmt); |
8087 | check_execute(stmt, rc); |
8088 | |
8089 | rc= mysql_stmt_fetch(stmt); |
8090 | check_execute(stmt, rc); |
8091 | |
8092 | if (!opt_silent) |
8093 | fprintf(stdout, "\n row 0: %ld, %s, %s" , (long) c1, c2, c3); |
8094 | |
8095 | row= mysql_stmt_row_tell(stmt); |
8096 | |
8097 | row= mysql_stmt_row_seek(stmt, row); |
8098 | |
8099 | rc= mysql_stmt_fetch(stmt); |
8100 | check_execute(stmt, rc); |
8101 | |
8102 | if (!opt_silent) |
8103 | fprintf(stdout, "\n row 2: %ld, %s, %s" , (long) c1, c2, c3); |
8104 | |
8105 | row= mysql_stmt_row_seek(stmt, row); |
8106 | |
8107 | rc= mysql_stmt_fetch(stmt); |
8108 | check_execute(stmt, rc); |
8109 | |
8110 | if (!opt_silent) |
8111 | fprintf(stdout, "\n row 2: %ld, %s, %s" , (long) c1, c2, c3); |
8112 | |
8113 | mysql_stmt_data_seek(stmt, 0); |
8114 | |
8115 | rc= mysql_stmt_fetch(stmt); |
8116 | check_execute(stmt, rc); |
8117 | |
8118 | if (!opt_silent) |
8119 | fprintf(stdout, "\n row 0: %ld, %s, %s" , (long) c1, c2, c3); |
8120 | |
8121 | rc= mysql_stmt_fetch(stmt); |
8122 | check_execute(stmt, rc); |
8123 | |
8124 | rc= mysql_stmt_fetch(stmt); |
8125 | check_execute(stmt, rc); |
8126 | |
8127 | rc= mysql_stmt_fetch(stmt); |
8128 | check_execute(stmt, rc); |
8129 | |
8130 | rc= mysql_stmt_fetch(stmt); |
8131 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
8132 | |
8133 | mysql_stmt_close(stmt); |
8134 | myquery(mysql_query(mysql, "drop table t1" )); |
8135 | } |
8136 | |
8137 | |
8138 | /* Test mysql_stmt_fetch_column() with offset */ |
8139 | |
8140 | static void test_fetch_offset() |
8141 | { |
8142 | MYSQL_STMT *stmt; |
8143 | MYSQL_BIND my_bind[1]; |
8144 | char data[11]; |
8145 | ulong length; |
8146 | int rc; |
8147 | my_bool is_null; |
8148 | |
8149 | |
8150 | myheader("test_fetch_offset" ); |
8151 | |
8152 | rc= mysql_query(mysql, "drop table if exists t1" ); |
8153 | myquery(rc); |
8154 | |
8155 | rc= mysql_query(mysql, "create table t1(a char(10))" ); |
8156 | myquery(rc); |
8157 | |
8158 | rc= mysql_query(mysql, "insert into t1 values('abcdefghij'), (null)" ); |
8159 | myquery(rc); |
8160 | |
8161 | stmt= mysql_simple_prepare(mysql, "select * from t1" ); |
8162 | check_stmt(stmt); |
8163 | |
8164 | bzero((char*) my_bind, sizeof(my_bind)); |
8165 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
8166 | my_bind[0].buffer= (void *)data; |
8167 | my_bind[0].buffer_length= 11; |
8168 | my_bind[0].is_null= &is_null; |
8169 | my_bind[0].length= &length; |
8170 | |
8171 | rc= mysql_stmt_execute(stmt); |
8172 | check_execute(stmt, rc); |
8173 | |
8174 | rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0); |
8175 | check_execute_r(stmt, rc); |
8176 | |
8177 | rc= mysql_stmt_execute(stmt); |
8178 | check_execute(stmt, rc); |
8179 | |
8180 | rc= mysql_stmt_bind_result(stmt, my_bind); |
8181 | check_execute(stmt, rc); |
8182 | |
8183 | rc= mysql_stmt_store_result(stmt); |
8184 | check_execute(stmt, rc); |
8185 | |
8186 | rc= mysql_stmt_fetch(stmt); |
8187 | check_execute(stmt, rc); |
8188 | |
8189 | data[0]= '\0'; |
8190 | rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0); |
8191 | check_execute(stmt, rc); |
8192 | if (!opt_silent) |
8193 | fprintf(stdout, "\n col 1: %s (%ld)" , data, length); |
8194 | DIE_UNLESS(strncmp(data, "abcd" , 4) == 0 && length == 10); |
8195 | |
8196 | rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 5); |
8197 | check_execute(stmt, rc); |
8198 | if (!opt_silent) |
8199 | fprintf(stdout, "\n col 1: %s (%ld)" , data, length); |
8200 | DIE_UNLESS(strncmp(data, "fg" , 2) == 0 && length == 10); |
8201 | |
8202 | rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 9); |
8203 | check_execute(stmt, rc); |
8204 | if (!opt_silent) |
8205 | fprintf(stdout, "\n col 0: %s (%ld)" , data, length); |
8206 | DIE_UNLESS(strncmp(data, "j" , 1) == 0 && length == 10); |
8207 | |
8208 | rc= mysql_stmt_fetch(stmt); |
8209 | check_execute(stmt, rc); |
8210 | |
8211 | is_null= 0; |
8212 | |
8213 | rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0); |
8214 | check_execute(stmt, rc); |
8215 | |
8216 | DIE_UNLESS(is_null == 1); |
8217 | |
8218 | rc= mysql_stmt_fetch(stmt); |
8219 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
8220 | |
8221 | rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0); |
8222 | check_execute_r(stmt, rc); |
8223 | |
8224 | mysql_stmt_close(stmt); |
8225 | |
8226 | myquery(mysql_query(mysql, "drop table t1" )); |
8227 | } |
8228 | |
8229 | |
8230 | /* Test mysql_stmt_fetch_column() */ |
8231 | |
8232 | static void test_fetch_column() |
8233 | { |
8234 | MYSQL_STMT *stmt; |
8235 | MYSQL_BIND my_bind[2]; |
8236 | char c2[20], bc2[20]; |
8237 | ulong l1, l2, bl1, bl2; |
8238 | int rc, c1, bc1; |
8239 | |
8240 | myheader("test_fetch_column" ); |
8241 | |
8242 | rc= mysql_query(mysql, "drop table if exists t1" ); |
8243 | myquery(rc); |
8244 | |
8245 | rc= mysql_query(mysql, "create table t1(c1 int primary key auto_increment, c2 char(10))" ); |
8246 | myquery(rc); |
8247 | |
8248 | rc= mysql_query(mysql, "insert into t1(c2) values('venu'), ('mysql')" ); |
8249 | myquery(rc); |
8250 | |
8251 | stmt= mysql_simple_prepare(mysql, "select * from t1 order by c2 desc" ); |
8252 | check_stmt(stmt); |
8253 | |
8254 | bzero((char*) my_bind, sizeof(my_bind)); |
8255 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
8256 | my_bind[0].buffer= (void *)&bc1; |
8257 | my_bind[0].buffer_length= 0; |
8258 | my_bind[0].is_null= 0; |
8259 | my_bind[0].length= &bl1; |
8260 | my_bind[1].buffer_type= MYSQL_TYPE_STRING; |
8261 | my_bind[1].buffer= (void *)bc2; |
8262 | my_bind[1].buffer_length= 7; |
8263 | my_bind[1].is_null= 0; |
8264 | my_bind[1].length= &bl2; |
8265 | |
8266 | rc= mysql_stmt_execute(stmt); |
8267 | check_execute(stmt, rc); |
8268 | |
8269 | rc= mysql_stmt_bind_result(stmt, my_bind); |
8270 | check_execute(stmt, rc); |
8271 | |
8272 | rc= mysql_stmt_store_result(stmt); |
8273 | check_execute(stmt, rc); |
8274 | |
8275 | rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0); /* No-op at this point */ |
8276 | check_execute_r(stmt, rc); |
8277 | |
8278 | rc= mysql_stmt_fetch(stmt); |
8279 | check_execute(stmt, rc); |
8280 | |
8281 | if (!opt_silent) |
8282 | fprintf(stdout, "\n row 0: %d, %s" , bc1, bc2); |
8283 | |
8284 | c2[0]= '\0'; l2= 0; |
8285 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
8286 | my_bind[0].buffer= (void *)c2; |
8287 | my_bind[0].buffer_length= 7; |
8288 | my_bind[0].is_null= 0; |
8289 | my_bind[0].length= &l2; |
8290 | |
8291 | rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0); |
8292 | check_execute(stmt, rc); |
8293 | if (!opt_silent) |
8294 | fprintf(stdout, "\n col 1: %s(%ld)" , c2, l2); |
8295 | DIE_UNLESS(strncmp(c2, "venu" , 4) == 0 && l2 == 4); |
8296 | |
8297 | c2[0]= '\0'; l2= 0; |
8298 | rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0); |
8299 | check_execute(stmt, rc); |
8300 | if (!opt_silent) |
8301 | fprintf(stdout, "\n col 1: %s(%ld)" , c2, l2); |
8302 | DIE_UNLESS(strcmp(c2, "venu" ) == 0 && l2 == 4); |
8303 | |
8304 | c1= 0; |
8305 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
8306 | my_bind[0].buffer= (void *)&c1; |
8307 | my_bind[0].buffer_length= 0; |
8308 | my_bind[0].is_null= 0; |
8309 | my_bind[0].length= &l1; |
8310 | |
8311 | rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0); |
8312 | check_execute(stmt, rc); |
8313 | if (!opt_silent) |
8314 | fprintf(stdout, "\n col 0: %d(%ld)" , c1, l1); |
8315 | DIE_UNLESS(c1 == 1 && l1 == 4); |
8316 | |
8317 | rc= mysql_stmt_fetch(stmt); |
8318 | check_execute(stmt, rc); |
8319 | |
8320 | if (!opt_silent) |
8321 | fprintf(stdout, "\n row 1: %d, %s" , bc1, bc2); |
8322 | |
8323 | c2[0]= '\0'; l2= 0; |
8324 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
8325 | my_bind[0].buffer= (void *)c2; |
8326 | my_bind[0].buffer_length= 7; |
8327 | my_bind[0].is_null= 0; |
8328 | my_bind[0].length= &l2; |
8329 | |
8330 | rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0); |
8331 | check_execute(stmt, rc); |
8332 | if (!opt_silent) |
8333 | fprintf(stdout, "\n col 1: %s(%ld)" , c2, l2); |
8334 | DIE_UNLESS(strncmp(c2, "mysq" , 4) == 0 && l2 == 5); |
8335 | |
8336 | c2[0]= '\0'; l2= 0; |
8337 | rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0); |
8338 | check_execute(stmt, rc); |
8339 | if (!opt_silent) |
8340 | fprintf(stdout, "\n col 1: %si(%ld)" , c2, l2); |
8341 | DIE_UNLESS(strcmp(c2, "mysql" ) == 0 && l2 == 5); |
8342 | |
8343 | c1= 0; |
8344 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
8345 | my_bind[0].buffer= (void *)&c1; |
8346 | my_bind[0].buffer_length= 0; |
8347 | my_bind[0].is_null= 0; |
8348 | my_bind[0].length= &l1; |
8349 | |
8350 | rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0); |
8351 | check_execute(stmt, rc); |
8352 | if (!opt_silent) |
8353 | fprintf(stdout, "\n col 0: %d(%ld)" , c1, l1); |
8354 | DIE_UNLESS(c1 == 2 && l1 == 4); |
8355 | |
8356 | rc= mysql_stmt_fetch(stmt); |
8357 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
8358 | |
8359 | rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0); |
8360 | check_execute_r(stmt, rc); |
8361 | |
8362 | mysql_stmt_close(stmt); |
8363 | myquery(mysql_query(mysql, "drop table t1" )); |
8364 | } |
8365 | |
8366 | |
8367 | /* Test mysql_list_fields() */ |
8368 | |
8369 | static void test_list_fields() |
8370 | { |
8371 | MYSQL_RES *result; |
8372 | int rc; |
8373 | myheader("test_list_fields" ); |
8374 | |
8375 | rc= mysql_query(mysql, "drop table if exists t1" ); |
8376 | myquery(rc); |
8377 | |
8378 | rc= mysql_query(mysql, "create table t1(c1 int primary key auto_increment, c2 char(10) default 'mysql')" ); |
8379 | myquery(rc); |
8380 | |
8381 | result= mysql_list_fields(mysql, "t1" , NULL); |
8382 | mytest(result); |
8383 | |
8384 | rc= my_process_result_set(result); |
8385 | DIE_UNLESS(rc == 0); |
8386 | |
8387 | verify_prepare_field(result, 0, "c1" , "c1" , MYSQL_TYPE_LONG, |
8388 | "t1" , "t1" , |
8389 | current_db, 11, "0" ); |
8390 | |
8391 | verify_prepare_field(result, 1, "c2" , "c2" , MYSQL_TYPE_STRING, |
8392 | "t1" , "t1" , |
8393 | current_db, 10, "mysql" ); |
8394 | |
8395 | mysql_free_result(result); |
8396 | myquery(mysql_query(mysql, "drop table t1" )); |
8397 | } |
8398 | |
8399 | |
8400 | static void test_list_fields_default() |
8401 | { |
8402 | int rc, i; |
8403 | myheader("test_list_fields_default" ); |
8404 | |
8405 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1" ); |
8406 | myquery(rc); |
8407 | |
8408 | rc= mysql_query(mysql, |
8409 | "CREATE TABLE t1 (" |
8410 | " i1 INT NOT NULL DEFAULT 0," |
8411 | " i3 BIGINT UNSIGNED NOT NULL DEFAULT 0xFFFFFFFFFFFFFFFF," |
8412 | " s1 VARCHAR(10) CHARACTER SET latin1 NOT NULL DEFAULT 's1def'," |
8413 | " d1 DECIMAL(31,1) NOT NULL DEFAULT 111111111122222222223333333333.9," |
8414 | " t1 DATETIME(6) NOT NULL DEFAULT '2001-01-01 10:20:30.123456'," |
8415 | " e1 ENUM('a','b') NOT NULL DEFAULT 'a'" |
8416 | ")" ); |
8417 | myquery(rc); |
8418 | |
8419 | rc= mysql_query(mysql, "DROP VIEW IF EXISTS v1" ); |
8420 | myquery(rc); |
8421 | |
8422 | rc= mysql_query(mysql, "CREATE VIEW v1 AS SELECT * FROM t1" ); |
8423 | myquery(rc); |
8424 | |
8425 | /* |
8426 | Checking that mysql_list_fields() returns the same result |
8427 | for a TABLE and a VIEW on the same table. |
8428 | */ |
8429 | for (i= 0; i < 2; i++) |
8430 | { |
8431 | const char *table_name= i == 0 ? "t1" : "v1" ; |
8432 | MYSQL_RES *result= mysql_list_fields(mysql, table_name, NULL); |
8433 | mytest(result); |
8434 | |
8435 | rc= my_process_result_set(result); |
8436 | DIE_UNLESS(rc == 0); |
8437 | |
8438 | verify_prepare_field(result, 0, "i1" , "i1" , MYSQL_TYPE_LONG, |
8439 | table_name, table_name, current_db, |
8440 | 11, "0" ); |
8441 | |
8442 | verify_prepare_field(result, 1, "i3" , "i3" , MYSQL_TYPE_LONGLONG, |
8443 | table_name, table_name, current_db, |
8444 | 20, "18446744073709551615" ); |
8445 | |
8446 | verify_prepare_field(result, 2, "s1" , "s1" , MYSQL_TYPE_VAR_STRING, |
8447 | table_name, table_name, current_db, |
8448 | 10, "s1def" ); |
8449 | |
8450 | verify_prepare_field(result, 3, "d1" , "d1" , MYSQL_TYPE_NEWDECIMAL, |
8451 | table_name, table_name, current_db, |
8452 | 33, "111111111122222222223333333333.9" ); |
8453 | |
8454 | verify_prepare_field(result, 4, "t1" , "t1" , MYSQL_TYPE_DATETIME, |
8455 | table_name, table_name, current_db, |
8456 | 26, "2001-01-01 10:20:30.123456" ); |
8457 | |
8458 | verify_prepare_field(result, 5, "e1" , "e1" , MYSQL_TYPE_STRING, |
8459 | table_name, table_name, current_db, |
8460 | 1, "a" ); |
8461 | |
8462 | mysql_free_result(result); |
8463 | } |
8464 | |
8465 | myquery(mysql_query(mysql, "DROP VIEW v1" )); |
8466 | myquery(mysql_query(mysql, "DROP TABLE t1" )); |
8467 | } |
8468 | |
8469 | |
8470 | static void test_bug19671() |
8471 | { |
8472 | MYSQL_RES *result; |
8473 | int rc; |
8474 | myheader("test_bug19671" ); |
8475 | |
8476 | mysql_query(mysql, "set sql_mode=''" ); |
8477 | rc= mysql_query(mysql, "drop table if exists t1" ); |
8478 | myquery(rc); |
8479 | |
8480 | rc= mysql_query(mysql, "drop view if exists v1" ); |
8481 | myquery(rc); |
8482 | |
8483 | rc= mysql_query(mysql, "create table t1(f1 int)" ); |
8484 | myquery(rc); |
8485 | |
8486 | rc= mysql_query(mysql, "create view v1 as select va.* from t1 va" ); |
8487 | myquery(rc); |
8488 | |
8489 | result= mysql_list_fields(mysql, "v1" , NULL); |
8490 | mytest(result); |
8491 | |
8492 | rc= my_process_result_set(result); |
8493 | DIE_UNLESS(rc == 0); |
8494 | |
8495 | verify_prepare_field(result, 0, "f1" , "f1" , MYSQL_TYPE_LONG, |
8496 | "v1" , "v1" , current_db, 11, "0" ); |
8497 | |
8498 | mysql_free_result(result); |
8499 | myquery(mysql_query(mysql, "drop view v1" )); |
8500 | myquery(mysql_query(mysql, "drop table t1" )); |
8501 | } |
8502 | |
8503 | |
8504 | /* Test a memory ovverun bug */ |
8505 | |
8506 | static void test_mem_overun() |
8507 | { |
8508 | char buffer[10000], field[10]; |
8509 | MYSQL_STMT *stmt; |
8510 | MYSQL_RES *field_res; |
8511 | int rc, i, length; |
8512 | |
8513 | myheader("test_mem_overun" ); |
8514 | |
8515 | /* |
8516 | Test a memory ovverun bug when a table had 1000 fields with |
8517 | a row of data |
8518 | */ |
8519 | rc= mysql_query(mysql, "drop table if exists t_mem_overun" ); |
8520 | myquery(rc); |
8521 | |
8522 | strxmov(buffer, "create table t_mem_overun(" , NullS); |
8523 | for (i= 0; i < 1000; i++) |
8524 | { |
8525 | sprintf(field, "c%d int" , i); |
8526 | strxmov(buffer, buffer, field, ", " , NullS); |
8527 | } |
8528 | length= strlen(buffer); |
8529 | buffer[length-2]= ')'; |
8530 | buffer[--length]= '\0'; |
8531 | |
8532 | rc= mysql_real_query(mysql, buffer, length); |
8533 | myquery(rc); |
8534 | |
8535 | strxmov(buffer, "insert into t_mem_overun values(" , NullS); |
8536 | for (i= 0; i < 1000; i++) |
8537 | { |
8538 | strxmov(buffer, buffer, "1, " , NullS); |
8539 | } |
8540 | length= strlen(buffer); |
8541 | buffer[length-2]= ')'; |
8542 | buffer[--length]= '\0'; |
8543 | |
8544 | rc= mysql_real_query(mysql, buffer, length); |
8545 | myquery(rc); |
8546 | |
8547 | rc= mysql_query(mysql, "select * from t_mem_overun" ); |
8548 | myquery(rc); |
8549 | |
8550 | rc= my_process_result(mysql); |
8551 | DIE_UNLESS(rc == 1); |
8552 | |
8553 | stmt= mysql_simple_prepare(mysql, "select * from t_mem_overun" ); |
8554 | check_stmt(stmt); |
8555 | |
8556 | rc= mysql_stmt_execute(stmt); |
8557 | check_execute(stmt, rc); |
8558 | |
8559 | field_res= mysql_stmt_result_metadata(stmt); |
8560 | mytest(field_res); |
8561 | |
8562 | if (!opt_silent) |
8563 | fprintf(stdout, "\n total fields : %d" , mysql_num_fields(field_res)); |
8564 | DIE_UNLESS( 1000 == mysql_num_fields(field_res)); |
8565 | |
8566 | rc= mysql_stmt_store_result(stmt); |
8567 | check_execute(stmt, rc); |
8568 | |
8569 | rc= mysql_stmt_fetch(stmt); |
8570 | check_execute(stmt, rc); |
8571 | |
8572 | rc= mysql_stmt_fetch(stmt); |
8573 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
8574 | |
8575 | mysql_free_result(field_res); |
8576 | |
8577 | mysql_stmt_close(stmt); |
8578 | } |
8579 | |
8580 | |
8581 | /* Test mysql_stmt_free_result() */ |
8582 | |
8583 | static void test_free_result() |
8584 | { |
8585 | MYSQL_STMT *stmt; |
8586 | MYSQL_BIND my_bind[1]; |
8587 | char c2[5]; |
8588 | ulong bl1, l2; |
8589 | int rc, c1, bc1; |
8590 | |
8591 | myheader("test_free_result" ); |
8592 | |
8593 | rc= mysql_query(mysql, "drop table if exists test_free_result" ); |
8594 | myquery(rc); |
8595 | |
8596 | rc= mysql_query(mysql, "create table test_free_result(" |
8597 | "c1 int primary key auto_increment)" ); |
8598 | myquery(rc); |
8599 | |
8600 | rc= mysql_query(mysql, "insert into test_free_result values(), (), ()" ); |
8601 | myquery(rc); |
8602 | |
8603 | stmt= mysql_simple_prepare(mysql, "select * from test_free_result" ); |
8604 | check_stmt(stmt); |
8605 | |
8606 | bzero((char*) my_bind, sizeof(my_bind)); |
8607 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
8608 | my_bind[0].buffer= (void *)&bc1; |
8609 | my_bind[0].length= &bl1; |
8610 | |
8611 | rc= mysql_stmt_execute(stmt); |
8612 | check_execute(stmt, rc); |
8613 | |
8614 | rc= mysql_stmt_bind_result(stmt, my_bind); |
8615 | check_execute(stmt, rc); |
8616 | |
8617 | rc= mysql_stmt_fetch(stmt); |
8618 | check_execute(stmt, rc); |
8619 | |
8620 | c2[0]= '\0'; l2= 0; |
8621 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
8622 | my_bind[0].buffer= (void *)c2; |
8623 | my_bind[0].buffer_length= 7; |
8624 | my_bind[0].is_null= 0; |
8625 | my_bind[0].length= &l2; |
8626 | |
8627 | rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0); |
8628 | check_execute(stmt, rc); |
8629 | if (!opt_silent) |
8630 | fprintf(stdout, "\n col 0: %s(%ld)" , c2, l2); |
8631 | DIE_UNLESS(strncmp(c2, "1" , 1) == 0 && l2 == 1); |
8632 | |
8633 | rc= mysql_stmt_fetch(stmt); |
8634 | check_execute(stmt, rc); |
8635 | |
8636 | c1= 0, l2= 0; |
8637 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
8638 | my_bind[0].buffer= (void *)&c1; |
8639 | my_bind[0].buffer_length= 0; |
8640 | my_bind[0].is_null= 0; |
8641 | my_bind[0].length= &l2; |
8642 | |
8643 | rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0); |
8644 | check_execute(stmt, rc); |
8645 | if (!opt_silent) |
8646 | fprintf(stdout, "\n col 0: %d(%ld)" , c1, l2); |
8647 | DIE_UNLESS(c1 == 2 && l2 == 4); |
8648 | |
8649 | rc= mysql_query(mysql, "drop table test_free_result" ); |
8650 | myquery_r(rc); /* error should be, COMMANDS OUT OF SYNC */ |
8651 | |
8652 | rc= mysql_stmt_free_result(stmt); |
8653 | check_execute(stmt, rc); |
8654 | |
8655 | rc= mysql_query(mysql, "drop table test_free_result" ); |
8656 | myquery(rc); /* should be successful */ |
8657 | |
8658 | mysql_stmt_close(stmt); |
8659 | } |
8660 | |
8661 | |
8662 | /* Test mysql_stmt_store_result() */ |
8663 | |
8664 | static void test_free_store_result() |
8665 | { |
8666 | MYSQL_STMT *stmt; |
8667 | MYSQL_BIND my_bind[1]; |
8668 | char c2[5]; |
8669 | ulong bl1, l2; |
8670 | int rc, c1, bc1; |
8671 | |
8672 | myheader("test_free_store_result" ); |
8673 | |
8674 | rc= mysql_query(mysql, "drop table if exists test_free_result" ); |
8675 | myquery(rc); |
8676 | |
8677 | rc= mysql_query(mysql, "create table test_free_result(c1 int primary key auto_increment)" ); |
8678 | myquery(rc); |
8679 | |
8680 | rc= mysql_query(mysql, "insert into test_free_result values(), (), ()" ); |
8681 | myquery(rc); |
8682 | |
8683 | stmt= mysql_simple_prepare(mysql, "select * from test_free_result" ); |
8684 | check_stmt(stmt); |
8685 | |
8686 | bzero((char*) my_bind, sizeof(my_bind)); |
8687 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
8688 | my_bind[0].buffer= (void *)&bc1; |
8689 | my_bind[0].buffer_length= 0; |
8690 | my_bind[0].is_null= 0; |
8691 | my_bind[0].length= &bl1; |
8692 | |
8693 | rc= mysql_stmt_execute(stmt); |
8694 | check_execute(stmt, rc); |
8695 | |
8696 | rc= mysql_stmt_bind_result(stmt, my_bind); |
8697 | check_execute(stmt, rc); |
8698 | |
8699 | rc= mysql_stmt_store_result(stmt); |
8700 | check_execute(stmt, rc); |
8701 | |
8702 | rc= mysql_stmt_fetch(stmt); |
8703 | check_execute(stmt, rc); |
8704 | |
8705 | c2[0]= '\0'; l2= 0; |
8706 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
8707 | my_bind[0].buffer= (void *)c2; |
8708 | my_bind[0].buffer_length= 7; |
8709 | my_bind[0].is_null= 0; |
8710 | my_bind[0].length= &l2; |
8711 | |
8712 | rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0); |
8713 | check_execute(stmt, rc); |
8714 | if (!opt_silent) |
8715 | fprintf(stdout, "\n col 1: %s(%ld)" , c2, l2); |
8716 | DIE_UNLESS(strncmp(c2, "1" , 1) == 0 && l2 == 1); |
8717 | |
8718 | rc= mysql_stmt_fetch(stmt); |
8719 | check_execute(stmt, rc); |
8720 | |
8721 | c1= 0, l2= 0; |
8722 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
8723 | my_bind[0].buffer= (void *)&c1; |
8724 | my_bind[0].buffer_length= 0; |
8725 | my_bind[0].is_null= 0; |
8726 | my_bind[0].length= &l2; |
8727 | |
8728 | rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0); |
8729 | check_execute(stmt, rc); |
8730 | if (!opt_silent) |
8731 | fprintf(stdout, "\n col 0: %d(%ld)" , c1, l2); |
8732 | DIE_UNLESS(c1 == 2 && l2 == 4); |
8733 | |
8734 | rc= mysql_stmt_free_result(stmt); |
8735 | check_execute(stmt, rc); |
8736 | |
8737 | rc= mysql_query(mysql, "drop table test_free_result" ); |
8738 | myquery(rc); |
8739 | |
8740 | mysql_stmt_close(stmt); |
8741 | } |
8742 | |
8743 | |
8744 | /* Test SQLmode */ |
8745 | |
8746 | static void test_sqlmode() |
8747 | { |
8748 | MYSQL_STMT *stmt; |
8749 | MYSQL_BIND my_bind[2]; |
8750 | char c1[5], c2[5]; |
8751 | int rc; |
8752 | char query[MAX_TEST_QUERY_LENGTH]; |
8753 | |
8754 | myheader("test_sqlmode" ); |
8755 | |
8756 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_piping" ); |
8757 | myquery(rc); |
8758 | |
8759 | rc= mysql_query(mysql, "CREATE TABLE test_piping(name varchar(10))" ); |
8760 | myquery(rc); |
8761 | |
8762 | /* PIPES_AS_CONCAT */ |
8763 | strmov(query, "SET SQL_MODE= \"PIPES_AS_CONCAT\"" ); |
8764 | if (!opt_silent) |
8765 | fprintf(stdout, "\n With %s" , query); |
8766 | rc= mysql_query(mysql, query); |
8767 | myquery(rc); |
8768 | |
8769 | strmov(query, "INSERT INTO test_piping VALUES(?||?)" ); |
8770 | if (!opt_silent) |
8771 | fprintf(stdout, "\n query: %s" , query); |
8772 | stmt= mysql_simple_prepare(mysql, query); |
8773 | check_stmt(stmt); |
8774 | |
8775 | if (!opt_silent) |
8776 | fprintf(stdout, "\n total parameters: %ld" , mysql_stmt_param_count(stmt)); |
8777 | |
8778 | /* |
8779 | We need to bzero bind structure because mysql_stmt_bind_param checks all |
8780 | its members. |
8781 | */ |
8782 | bzero((char*) my_bind, sizeof(my_bind)); |
8783 | |
8784 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
8785 | my_bind[0].buffer= (void *)c1; |
8786 | my_bind[0].buffer_length= 2; |
8787 | |
8788 | my_bind[1].buffer_type= MYSQL_TYPE_STRING; |
8789 | my_bind[1].buffer= (void *)c2; |
8790 | my_bind[1].buffer_length= 3; |
8791 | |
8792 | rc= mysql_stmt_bind_param(stmt, my_bind); |
8793 | check_execute(stmt, rc); |
8794 | |
8795 | strmov(c1, "My" ); strmov(c2, "SQL" ); |
8796 | rc= mysql_stmt_execute(stmt); |
8797 | check_execute(stmt, rc); |
8798 | mysql_stmt_close(stmt); |
8799 | |
8800 | verify_col_data("test_piping" , "name" , "MySQL" ); |
8801 | |
8802 | rc= mysql_query(mysql, "DELETE FROM test_piping" ); |
8803 | myquery(rc); |
8804 | |
8805 | strmov(query, "SELECT connection_id ()" ); |
8806 | if (!opt_silent) |
8807 | fprintf(stdout, "\n query: %s" , query); |
8808 | stmt= mysql_simple_prepare(mysql, query); |
8809 | check_stmt(stmt); |
8810 | mysql_stmt_close(stmt); |
8811 | |
8812 | /* ANSI */ |
8813 | strmov(query, "SET SQL_MODE= \"ANSI\"" ); |
8814 | if (!opt_silent) |
8815 | fprintf(stdout, "\n With %s" , query); |
8816 | rc= mysql_query(mysql, query); |
8817 | myquery(rc); |
8818 | |
8819 | strmov(query, "INSERT INTO test_piping VALUES(?||?)" ); |
8820 | if (!opt_silent) |
8821 | fprintf(stdout, "\n query: %s" , query); |
8822 | stmt= mysql_simple_prepare(mysql, query); |
8823 | check_stmt(stmt); |
8824 | if (!opt_silent) |
8825 | fprintf(stdout, "\n total parameters: %ld" , mysql_stmt_param_count(stmt)); |
8826 | |
8827 | rc= mysql_stmt_bind_param(stmt, my_bind); |
8828 | check_execute(stmt, rc); |
8829 | |
8830 | strmov(c1, "My" ); strmov(c2, "SQL" ); |
8831 | rc= mysql_stmt_execute(stmt); |
8832 | check_execute(stmt, rc); |
8833 | |
8834 | mysql_stmt_close(stmt); |
8835 | verify_col_data("test_piping" , "name" , "MySQL" ); |
8836 | |
8837 | /* ANSI mode spaces ... */ |
8838 | strmov(query, "SELECT connection_id ()" ); |
8839 | if (!opt_silent) |
8840 | fprintf(stdout, "\n query: %s" , query); |
8841 | stmt= mysql_simple_prepare(mysql, query); |
8842 | check_stmt(stmt); |
8843 | |
8844 | rc= mysql_stmt_execute(stmt); |
8845 | check_execute(stmt, rc); |
8846 | |
8847 | rc= mysql_stmt_fetch(stmt); |
8848 | check_execute(stmt, rc); |
8849 | |
8850 | rc= mysql_stmt_fetch(stmt); |
8851 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
8852 | if (!opt_silent) |
8853 | fprintf(stdout, "\n returned 1 row\n" ); |
8854 | |
8855 | mysql_stmt_close(stmt); |
8856 | |
8857 | /* IGNORE SPACE MODE */ |
8858 | strmov(query, "SET SQL_MODE= \"IGNORE_SPACE\"" ); |
8859 | if (!opt_silent) |
8860 | fprintf(stdout, "\n With %s" , query); |
8861 | rc= mysql_query(mysql, query); |
8862 | myquery(rc); |
8863 | |
8864 | strmov(query, "SELECT connection_id ()" ); |
8865 | if (!opt_silent) |
8866 | fprintf(stdout, "\n query: %s" , query); |
8867 | stmt= mysql_simple_prepare(mysql, query); |
8868 | check_stmt(stmt); |
8869 | |
8870 | rc= mysql_stmt_execute(stmt); |
8871 | check_execute(stmt, rc); |
8872 | |
8873 | rc= mysql_stmt_fetch(stmt); |
8874 | check_execute(stmt, rc); |
8875 | |
8876 | rc= mysql_stmt_fetch(stmt); |
8877 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
8878 | if (!opt_silent) |
8879 | fprintf(stdout, "\n returned 1 row" ); |
8880 | |
8881 | mysql_stmt_close(stmt); |
8882 | } |
8883 | |
8884 | |
8885 | /* Test for timestamp handling */ |
8886 | |
8887 | static void test_ts() |
8888 | { |
8889 | MYSQL_STMT *stmt; |
8890 | MYSQL_BIND my_bind[6]; |
8891 | MYSQL_TIME ts; |
8892 | MYSQL_RES *prep_res; |
8893 | char strts[30]; |
8894 | ulong length; |
8895 | int rc, field_count; |
8896 | char name; |
8897 | char query[MAX_TEST_QUERY_LENGTH]; |
8898 | const char *queries [3]= {"SELECT a, b, c FROM test_ts WHERE %c=?" , |
8899 | "SELECT a, b, c FROM test_ts WHERE %c=CAST(? AS TIME)" , |
8900 | "SELECT a, b, c FROM test_ts WHERE %c=CAST(? AS DATE)" }; |
8901 | myheader("test_ts" ); |
8902 | |
8903 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_ts" ); |
8904 | myquery(rc); |
8905 | |
8906 | rc= mysql_query(mysql, "CREATE TABLE test_ts(a DATE, b TIME, c TIMESTAMP)" ); |
8907 | myquery(rc); |
8908 | |
8909 | stmt= mysql_simple_prepare(mysql, "INSERT INTO test_ts VALUES(?, ?, ?), (?, ?, ?)" ); |
8910 | check_stmt(stmt); |
8911 | |
8912 | ts.year= 2003; |
8913 | ts.month= 07; |
8914 | ts.day= 12; |
8915 | ts.hour= 21; |
8916 | ts.minute= 07; |
8917 | ts.second= 46; |
8918 | ts.second_part= 0; |
8919 | length= (long)(strmov(strts, "2003-07-12 21:07:46" ) - strts); |
8920 | |
8921 | /* |
8922 | We need to bzero bind structure because mysql_stmt_bind_param checks all |
8923 | its members. |
8924 | */ |
8925 | bzero((char*) my_bind, sizeof(my_bind)); |
8926 | |
8927 | my_bind[0].buffer_type= MYSQL_TYPE_TIMESTAMP; |
8928 | my_bind[0].buffer= (void *)&ts; |
8929 | my_bind[0].buffer_length= sizeof(ts); |
8930 | |
8931 | my_bind[2]= my_bind[1]= my_bind[0]; |
8932 | |
8933 | my_bind[3].buffer_type= MYSQL_TYPE_STRING; |
8934 | my_bind[3].buffer= (void *)strts; |
8935 | my_bind[3].buffer_length= sizeof(strts); |
8936 | my_bind[3].length= &length; |
8937 | |
8938 | my_bind[5]= my_bind[4]= my_bind[3]; |
8939 | |
8940 | rc= mysql_stmt_bind_param(stmt, my_bind); |
8941 | check_execute(stmt, rc); |
8942 | |
8943 | rc= mysql_stmt_execute(stmt); |
8944 | check_execute(stmt, rc); |
8945 | |
8946 | mysql_stmt_close(stmt); |
8947 | |
8948 | verify_col_data("test_ts" , "a" , "2003-07-12" ); |
8949 | verify_col_data("test_ts" , "b" , "21:07:46" ); |
8950 | verify_col_data("test_ts" , "c" , "2003-07-12 21:07:46" ); |
8951 | |
8952 | stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_ts" ); |
8953 | check_stmt(stmt); |
8954 | |
8955 | prep_res= mysql_stmt_result_metadata(stmt); |
8956 | mytest(prep_res); |
8957 | |
8958 | rc= mysql_stmt_execute(stmt); |
8959 | check_execute(stmt, rc); |
8960 | |
8961 | rc= my_process_stmt_result(stmt); |
8962 | DIE_UNLESS(rc == 2); |
8963 | field_count= mysql_num_fields(prep_res); |
8964 | |
8965 | mysql_free_result(prep_res); |
8966 | mysql_stmt_close(stmt); |
8967 | |
8968 | for (name= 'a'; field_count--; name++) |
8969 | { |
8970 | int row_count= 0; |
8971 | |
8972 | sprintf(query, queries[field_count], name); |
8973 | |
8974 | if (!opt_silent) |
8975 | fprintf(stdout, "\n %s" , query); |
8976 | stmt= mysql_simple_prepare(mysql, query); |
8977 | check_stmt(stmt); |
8978 | |
8979 | rc= mysql_stmt_bind_param(stmt, my_bind); |
8980 | check_execute(stmt, rc); |
8981 | |
8982 | rc= mysql_stmt_execute(stmt); |
8983 | check_execute(stmt, rc); |
8984 | |
8985 | while (mysql_stmt_fetch(stmt) == 0) |
8986 | row_count++; |
8987 | |
8988 | if (!opt_silent) |
8989 | fprintf(stdout, "\n returned '%d' rows" , row_count); |
8990 | DIE_UNLESS(row_count == 2); |
8991 | mysql_stmt_close(stmt); |
8992 | } |
8993 | } |
8994 | |
8995 | |
8996 | /* Test for bug #1500. */ |
8997 | |
8998 | static void test_bug1500() |
8999 | { |
9000 | MYSQL_STMT *stmt; |
9001 | MYSQL_BIND my_bind[3]; |
9002 | int rc; |
9003 | int32 int_data[3]= {2, 3, 4}; |
9004 | const char *data; |
9005 | |
9006 | myheader("test_bug1500" ); |
9007 | |
9008 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bg1500" ); |
9009 | myquery(rc); |
9010 | |
9011 | rc= mysql_query(mysql, "CREATE TABLE test_bg1500 (i INT)" ); |
9012 | myquery(rc); |
9013 | |
9014 | rc= mysql_query(mysql, "INSERT INTO test_bg1500 VALUES (1), (2)" ); |
9015 | myquery(rc); |
9016 | |
9017 | rc= mysql_commit(mysql); |
9018 | myquery(rc); |
9019 | |
9020 | stmt= mysql_simple_prepare(mysql, "SELECT i FROM test_bg1500 WHERE i IN (?, ?, ?)" ); |
9021 | check_stmt(stmt); |
9022 | verify_param_count(stmt, 3); |
9023 | |
9024 | /* |
9025 | We need to bzero bind structure because mysql_stmt_bind_param checks all |
9026 | its members. |
9027 | */ |
9028 | bzero((char*) my_bind, sizeof(my_bind)); |
9029 | |
9030 | my_bind[0].buffer= (void *)int_data; |
9031 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
9032 | my_bind[2]= my_bind[1]= my_bind[0]; |
9033 | my_bind[1].buffer= (void *)(int_data + 1); |
9034 | my_bind[2].buffer= (void *)(int_data + 2); |
9035 | |
9036 | rc= mysql_stmt_bind_param(stmt, my_bind); |
9037 | check_execute(stmt, rc); |
9038 | |
9039 | rc= mysql_stmt_execute(stmt); |
9040 | check_execute(stmt, rc); |
9041 | |
9042 | rc= my_process_stmt_result(stmt); |
9043 | DIE_UNLESS(rc == 1); |
9044 | |
9045 | mysql_stmt_close(stmt); |
9046 | |
9047 | rc= mysql_query(mysql, "DROP TABLE test_bg1500" ); |
9048 | myquery(rc); |
9049 | |
9050 | rc= mysql_query(mysql, "CREATE TABLE test_bg1500 (s VARCHAR(25), FULLTEXT(s)) engine=MyISAM" ); |
9051 | myquery(rc); |
9052 | |
9053 | rc= mysql_query(mysql, |
9054 | "INSERT INTO test_bg1500 VALUES ('Gravedigger'), ('Greed'), ('Hollow Dogs')" ); |
9055 | myquery(rc); |
9056 | |
9057 | rc= mysql_commit(mysql); |
9058 | myquery(rc); |
9059 | |
9060 | stmt= mysql_simple_prepare(mysql, |
9061 | "SELECT s FROM test_bg1500 WHERE MATCH (s) AGAINST (?)" ); |
9062 | check_stmt(stmt); |
9063 | |
9064 | verify_param_count(stmt, 1); |
9065 | |
9066 | data= "Dogs" ; |
9067 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
9068 | my_bind[0].buffer= (void *) data; |
9069 | my_bind[0].buffer_length= strlen(data); |
9070 | my_bind[0].is_null= 0; |
9071 | my_bind[0].length= 0; |
9072 | |
9073 | rc= mysql_stmt_bind_param(stmt, my_bind); |
9074 | check_execute(stmt, rc); |
9075 | |
9076 | rc= mysql_stmt_execute(stmt); |
9077 | check_execute(stmt, rc); |
9078 | |
9079 | rc= my_process_stmt_result(stmt); |
9080 | DIE_UNLESS(rc == 1); |
9081 | |
9082 | mysql_stmt_close(stmt); |
9083 | |
9084 | /* This should work too */ |
9085 | stmt= mysql_simple_prepare(mysql, |
9086 | "SELECT s FROM test_bg1500 WHERE MATCH (s) AGAINST (CONCAT(?, 'digger'))" ); |
9087 | check_stmt(stmt); |
9088 | |
9089 | verify_param_count(stmt, 1); |
9090 | |
9091 | data= "Grave" ; |
9092 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
9093 | my_bind[0].buffer= (void *) data; |
9094 | my_bind[0].buffer_length= strlen(data); |
9095 | |
9096 | rc= mysql_stmt_bind_param(stmt, my_bind); |
9097 | check_execute(stmt, rc); |
9098 | |
9099 | rc= mysql_stmt_execute(stmt); |
9100 | check_execute(stmt, rc); |
9101 | |
9102 | rc= my_process_stmt_result(stmt); |
9103 | DIE_UNLESS(rc == 1); |
9104 | |
9105 | mysql_stmt_close(stmt); |
9106 | } |
9107 | |
9108 | |
9109 | static void test_bug1946() |
9110 | { |
9111 | MYSQL_STMT *stmt; |
9112 | int rc; |
9113 | const char *query= "INSERT INTO prepare_command VALUES (?)" ; |
9114 | |
9115 | myheader("test_bug1946" ); |
9116 | |
9117 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS prepare_command" ); |
9118 | myquery(rc); |
9119 | |
9120 | rc= mysql_query(mysql, "CREATE TABLE prepare_command(ID INT)" ); |
9121 | myquery(rc); |
9122 | |
9123 | stmt= mysql_simple_prepare(mysql, query); |
9124 | check_stmt(stmt); |
9125 | rc= mysql_real_query(mysql, query, strlen(query)); |
9126 | DIE_UNLESS(rc != 0); |
9127 | if (!opt_silent) |
9128 | fprintf(stdout, "Got error (as expected):\n" ); |
9129 | myerror(NULL); |
9130 | |
9131 | mysql_stmt_close(stmt); |
9132 | rc= mysql_query(mysql, "DROP TABLE prepare_command" ); |
9133 | } |
9134 | |
9135 | |
9136 | static void test_parse_error_and_bad_length() |
9137 | { |
9138 | MYSQL_STMT *stmt; |
9139 | int rc; |
9140 | |
9141 | /* check that we get 4 syntax errors over the 4 calls */ |
9142 | myheader("test_parse_error_and_bad_length" ); |
9143 | |
9144 | rc= mysql_query(mysql, "SHOW DATABAAAA" ); |
9145 | DIE_UNLESS(rc); |
9146 | if (!opt_silent) |
9147 | fprintf(stdout, "Got error (as expected): '%s'\n" , mysql_error(mysql)); |
9148 | rc= mysql_real_query(mysql, STRING_WITH_LEN("SHOW DATABASES\0AAAAAAAA" )); |
9149 | DIE_UNLESS(rc); |
9150 | if (!opt_silent) |
9151 | fprintf(stdout, "Got error (as expected): '%s'\n" , mysql_error(mysql)); |
9152 | |
9153 | stmt= mysql_simple_prepare(mysql, "SHOW DATABAAAA" ); |
9154 | DIE_UNLESS(!stmt); |
9155 | if (!opt_silent) |
9156 | fprintf(stdout, "Got error (as expected): '%s'\n" , mysql_error(mysql)); |
9157 | stmt= mysql_stmt_init(mysql); |
9158 | DIE_UNLESS(stmt); |
9159 | rc= mysql_stmt_prepare(stmt, STRING_WITH_LEN("SHOW DATABASES\0AAAAAAA" )); |
9160 | DIE_UNLESS(rc != 0); |
9161 | if (!opt_silent) |
9162 | fprintf(stdout, "Got error (as expected): '%s'\n" , mysql_stmt_error(stmt)); |
9163 | mysql_stmt_close(stmt); |
9164 | } |
9165 | |
9166 | |
9167 | static void test_bug2247() |
9168 | { |
9169 | MYSQL_STMT *stmt; |
9170 | MYSQL_RES *res; |
9171 | int rc; |
9172 | int i; |
9173 | const char *create= "CREATE TABLE bug2247(id INT UNIQUE AUTO_INCREMENT)" ; |
9174 | const char *insert= "INSERT INTO bug2247 VALUES (NULL)" ; |
9175 | const char *SELECT= "SELECT id FROM bug2247" ; |
9176 | const char *update= "UPDATE bug2247 SET id=id+10" ; |
9177 | const char *drop= "DROP TABLE IF EXISTS bug2247" ; |
9178 | ulonglong exp_count; |
9179 | enum { NUM_ROWS= 5 }; |
9180 | |
9181 | myheader("test_bug2247" ); |
9182 | |
9183 | if (!opt_silent) |
9184 | fprintf(stdout, "\nChecking if stmt_affected_rows is not affected by\n" |
9185 | "mysql_query ... " ); |
9186 | /* create table and insert few rows */ |
9187 | rc= mysql_query(mysql, drop); |
9188 | myquery(rc); |
9189 | |
9190 | rc= mysql_query(mysql, create); |
9191 | myquery(rc); |
9192 | |
9193 | stmt= mysql_simple_prepare(mysql, insert); |
9194 | check_stmt(stmt); |
9195 | for (i= 0; i < NUM_ROWS; ++i) |
9196 | { |
9197 | rc= mysql_stmt_execute(stmt); |
9198 | check_execute(stmt, rc); |
9199 | } |
9200 | exp_count= mysql_stmt_affected_rows(stmt); |
9201 | DIE_UNLESS(exp_count == 1); |
9202 | |
9203 | rc= mysql_query(mysql, SELECT); |
9204 | myquery(rc); |
9205 | /* |
9206 | mysql_store_result overwrites mysql->affected_rows. Check that |
9207 | mysql_stmt_affected_rows() returns the same value, whereas |
9208 | mysql_affected_rows() value is correct. |
9209 | */ |
9210 | res= mysql_store_result(mysql); |
9211 | mytest(res); |
9212 | |
9213 | DIE_UNLESS(mysql_affected_rows(mysql) == NUM_ROWS); |
9214 | DIE_UNLESS(exp_count == mysql_stmt_affected_rows(stmt)); |
9215 | |
9216 | rc= mysql_query(mysql, update); |
9217 | myquery(rc); |
9218 | DIE_UNLESS(mysql_affected_rows(mysql) == NUM_ROWS); |
9219 | DIE_UNLESS(exp_count == mysql_stmt_affected_rows(stmt)); |
9220 | |
9221 | mysql_free_result(res); |
9222 | mysql_stmt_close(stmt); |
9223 | |
9224 | /* check that mysql_stmt_store_result modifies mysql_stmt_affected_rows */ |
9225 | stmt= mysql_simple_prepare(mysql, SELECT); |
9226 | check_stmt(stmt); |
9227 | |
9228 | rc= mysql_stmt_execute(stmt); |
9229 | check_execute(stmt, rc); |
9230 | rc= mysql_stmt_store_result(stmt); |
9231 | check_execute(stmt, rc); |
9232 | exp_count= mysql_stmt_affected_rows(stmt); |
9233 | DIE_UNLESS(exp_count == NUM_ROWS); |
9234 | |
9235 | rc= mysql_query(mysql, insert); |
9236 | myquery(rc); |
9237 | DIE_UNLESS(mysql_affected_rows(mysql) == 1); |
9238 | DIE_UNLESS(mysql_stmt_affected_rows(stmt) == exp_count); |
9239 | |
9240 | mysql_stmt_close(stmt); |
9241 | if (!opt_silent) |
9242 | fprintf(stdout, "OK" ); |
9243 | } |
9244 | |
9245 | |
9246 | static void test_subqueries() |
9247 | { |
9248 | MYSQL_STMT *stmt; |
9249 | int rc, i; |
9250 | const char *query= "SELECT (SELECT SUM(a+b) FROM t2 where t1.b=t2.b GROUP BY t1.a LIMIT 1) as scalar_s, exists (select 1 from t2 where t2.a/2=t1.a) as exists_s, a in (select a+3 from t2) as in_s, (a-1, b-1) in (select a, b from t2) as in_row_s FROM t1, (select a x, b y from t2) tt WHERE x=a" ; |
9251 | |
9252 | myheader("test_subqueries" ); |
9253 | |
9254 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2" ); |
9255 | myquery(rc); |
9256 | |
9257 | rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);" ); |
9258 | myquery(rc); |
9259 | |
9260 | rc= mysql_query(mysql, |
9261 | "insert into t1 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);" ); |
9262 | myquery(rc); |
9263 | |
9264 | rc= mysql_query(mysql, "create table t2 select * from t1;" ); |
9265 | myquery(rc); |
9266 | |
9267 | stmt= mysql_simple_prepare(mysql, query); |
9268 | check_stmt(stmt); |
9269 | for (i= 0; i < 3; i++) |
9270 | { |
9271 | rc= mysql_stmt_execute(stmt); |
9272 | check_execute(stmt, rc); |
9273 | rc= my_process_stmt_result(stmt); |
9274 | DIE_UNLESS(rc == 5); |
9275 | } |
9276 | mysql_stmt_close(stmt); |
9277 | |
9278 | rc= mysql_query(mysql, "DROP TABLE t1, t2" ); |
9279 | myquery(rc); |
9280 | } |
9281 | |
9282 | |
9283 | static void test_bad_union() |
9284 | { |
9285 | MYSQL_STMT *stmt; |
9286 | const char *query= "SELECT 1, 2 union SELECT 1" ; |
9287 | |
9288 | myheader("test_bad_union" ); |
9289 | |
9290 | stmt= mysql_simple_prepare(mysql, query); |
9291 | DIE_UNLESS(stmt == 0); |
9292 | myerror(NULL); |
9293 | } |
9294 | |
9295 | |
9296 | static void test_distinct() |
9297 | { |
9298 | MYSQL_STMT *stmt; |
9299 | int rc, i; |
9300 | const char *query= |
9301 | "SELECT 2+count(distinct b), group_concat(a) FROM t1 group by a" ; |
9302 | |
9303 | myheader("test_distinct" ); |
9304 | |
9305 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1" ); |
9306 | myquery(rc); |
9307 | |
9308 | rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);" ); |
9309 | myquery(rc); |
9310 | |
9311 | rc= mysql_query(mysql, |
9312 | "insert into t1 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), \ |
9313 | (1, 10), (2, 20), (3, 30), (4, 40), (5, 50);" ); |
9314 | myquery(rc); |
9315 | |
9316 | for (i= 0; i < 3; i++) |
9317 | { |
9318 | stmt= mysql_simple_prepare(mysql, query); |
9319 | check_stmt(stmt); |
9320 | rc= mysql_stmt_execute(stmt); |
9321 | check_execute(stmt, rc); |
9322 | rc= my_process_stmt_result(stmt); |
9323 | DIE_UNLESS(rc == 5); |
9324 | mysql_stmt_close(stmt); |
9325 | } |
9326 | |
9327 | rc= mysql_query(mysql, "DROP TABLE t1" ); |
9328 | myquery(rc); |
9329 | } |
9330 | |
9331 | |
9332 | /* |
9333 | Test for bug#2248 "mysql_fetch without prior mysql_stmt_execute hangs" |
9334 | */ |
9335 | |
9336 | static void test_bug2248() |
9337 | { |
9338 | MYSQL_STMT *stmt; |
9339 | int rc; |
9340 | const char *query1= "SELECT DATABASE()" ; |
9341 | const char *query2= "INSERT INTO test_bug2248 VALUES (10)" ; |
9342 | |
9343 | myheader("test_bug2248" ); |
9344 | |
9345 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bug2248" ); |
9346 | myquery(rc); |
9347 | |
9348 | rc= mysql_query(mysql, "CREATE TABLE test_bug2248 (id int)" ); |
9349 | myquery(rc); |
9350 | |
9351 | stmt= mysql_simple_prepare(mysql, query1); |
9352 | check_stmt(stmt); |
9353 | |
9354 | /* This should not hang */ |
9355 | rc= mysql_stmt_fetch(stmt); |
9356 | check_execute_r(stmt, rc); |
9357 | |
9358 | /* And this too */ |
9359 | rc= mysql_stmt_store_result(stmt); |
9360 | check_execute_r(stmt, rc); |
9361 | |
9362 | mysql_stmt_close(stmt); |
9363 | |
9364 | stmt= mysql_simple_prepare(mysql, query2); |
9365 | check_stmt(stmt); |
9366 | |
9367 | rc= mysql_stmt_execute(stmt); |
9368 | check_execute(stmt, rc); |
9369 | |
9370 | /* This too should not hang but should return proper error */ |
9371 | rc= mysql_stmt_fetch(stmt); |
9372 | DIE_UNLESS(rc == 1); |
9373 | |
9374 | /* This too should not hang but should not bark */ |
9375 | rc= mysql_stmt_store_result(stmt); |
9376 | check_execute(stmt, rc); |
9377 | |
9378 | /* This should return proper error */ |
9379 | rc= mysql_stmt_fetch(stmt); |
9380 | check_execute_r(stmt, rc); |
9381 | DIE_UNLESS(rc == 1); |
9382 | |
9383 | mysql_stmt_close(stmt); |
9384 | |
9385 | rc= mysql_query(mysql, "DROP TABLE test_bug2248" ); |
9386 | myquery(rc); |
9387 | } |
9388 | |
9389 | |
9390 | static void test_subqueries_ref() |
9391 | { |
9392 | MYSQL_STMT *stmt; |
9393 | int rc, i; |
9394 | const char *query= "SELECT a as ccc from t1 outr where a+1=(SELECT 1+outr.a from t1 where outr.a+1=a+1 and a=1)" ; |
9395 | |
9396 | myheader("test_subqueries_ref" ); |
9397 | |
9398 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1" ); |
9399 | myquery(rc); |
9400 | |
9401 | rc= mysql_query(mysql, "CREATE TABLE t1 (a int);" ); |
9402 | myquery(rc); |
9403 | |
9404 | rc= mysql_query(mysql, |
9405 | "insert into t1 values (1), (2), (3), (4), (5);" ); |
9406 | myquery(rc); |
9407 | |
9408 | stmt= mysql_simple_prepare(mysql, query); |
9409 | check_stmt(stmt); |
9410 | for (i= 0; i < 3; i++) |
9411 | { |
9412 | rc= mysql_stmt_execute(stmt); |
9413 | check_execute(stmt, rc); |
9414 | rc= my_process_stmt_result(stmt); |
9415 | DIE_UNLESS(rc == 1); |
9416 | } |
9417 | mysql_stmt_close(stmt); |
9418 | |
9419 | rc= mysql_query(mysql, "DROP TABLE t1" ); |
9420 | myquery(rc); |
9421 | } |
9422 | |
9423 | |
9424 | static void test_union() |
9425 | { |
9426 | MYSQL_STMT *stmt; |
9427 | int rc; |
9428 | |
9429 | myheader("test_union" ); |
9430 | |
9431 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2" ); |
9432 | myquery(rc); |
9433 | |
9434 | rc= mysql_query(mysql, |
9435 | "CREATE TABLE t1 " |
9436 | "(id INTEGER NOT NULL PRIMARY KEY, " |
9437 | " name VARCHAR(20) NOT NULL)" ); |
9438 | myquery(rc); |
9439 | rc= mysql_query(mysql, |
9440 | "INSERT INTO t1 (id, name) VALUES " |
9441 | "(2, 'Ja'), (3, 'Ede'), " |
9442 | "(4, 'Haag'), (5, 'Kabul'), " |
9443 | "(6, 'Almere'), (7, 'Utrecht'), " |
9444 | "(8, 'Qandahar'), (9, 'Amsterdam'), " |
9445 | "(10, 'Amersfoort'), (11, 'Constantine')" ); |
9446 | myquery(rc); |
9447 | rc= mysql_query(mysql, |
9448 | "CREATE TABLE t2 " |
9449 | "(id INTEGER NOT NULL PRIMARY KEY, " |
9450 | " name VARCHAR(20) NOT NULL)" ); |
9451 | myquery(rc); |
9452 | rc= mysql_query(mysql, |
9453 | "INSERT INTO t2 (id, name) VALUES " |
9454 | "(4, 'Guam'), (5, 'Aruba'), " |
9455 | "(6, 'Angola'), (7, 'Albania'), " |
9456 | "(8, 'Anguilla'), (9, 'Argentina'), " |
9457 | "(10, 'Azerbaijan'), (11, 'Afghanistan'), " |
9458 | "(12, 'Burkina Faso'), (13, 'Faroe Islands')" ); |
9459 | myquery(rc); |
9460 | |
9461 | stmt= mysql_simple_prepare(mysql, |
9462 | "SELECT t1.name FROM t1 UNION " |
9463 | "SELECT t2.name FROM t2" ); |
9464 | check_stmt(stmt); |
9465 | |
9466 | rc= mysql_stmt_execute(stmt); |
9467 | check_execute(stmt, rc); |
9468 | rc= my_process_stmt_result(stmt); |
9469 | DIE_UNLESS(rc == 20); |
9470 | mysql_stmt_close(stmt); |
9471 | |
9472 | rc= mysql_query(mysql, "DROP TABLE t1, t2" ); |
9473 | myquery(rc); |
9474 | } |
9475 | |
9476 | |
9477 | static void test_bug3117() |
9478 | { |
9479 | MYSQL_STMT *stmt; |
9480 | MYSQL_BIND buffer; |
9481 | longlong lii; |
9482 | ulong length; |
9483 | my_bool is_null; |
9484 | int rc; |
9485 | |
9486 | myheader("test_bug3117" ); |
9487 | |
9488 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1" ); |
9489 | myquery(rc); |
9490 | |
9491 | rc= mysql_query(mysql, "CREATE TABLE t1 (id int auto_increment primary key)" ); |
9492 | myquery(rc); |
9493 | |
9494 | stmt= mysql_simple_prepare(mysql, "SELECT LAST_INSERT_ID()" ); |
9495 | check_stmt(stmt); |
9496 | |
9497 | rc= mysql_query(mysql, "INSERT INTO t1 VALUES (NULL)" ); |
9498 | myquery(rc); |
9499 | |
9500 | rc= mysql_stmt_execute(stmt); |
9501 | check_execute(stmt, rc); |
9502 | |
9503 | bzero((char*) &buffer, sizeof(buffer)); |
9504 | buffer.buffer_type= MYSQL_TYPE_LONGLONG; |
9505 | buffer.buffer_length= sizeof(lii); |
9506 | buffer.buffer= (void *)&lii; |
9507 | buffer.length= &length; |
9508 | buffer.is_null= &is_null; |
9509 | |
9510 | rc= mysql_stmt_bind_result(stmt, &buffer); |
9511 | check_execute(stmt, rc); |
9512 | |
9513 | rc= mysql_stmt_store_result(stmt); |
9514 | check_execute(stmt, rc); |
9515 | |
9516 | rc= mysql_stmt_fetch(stmt); |
9517 | check_execute(stmt, rc); |
9518 | |
9519 | DIE_UNLESS(is_null == 0 && lii == 1); |
9520 | if (!opt_silent) |
9521 | fprintf(stdout, "\n\tLAST_INSERT_ID()= 1 ok\n" ); |
9522 | |
9523 | rc= mysql_query(mysql, "INSERT INTO t1 VALUES (NULL)" ); |
9524 | myquery(rc); |
9525 | |
9526 | rc= mysql_stmt_execute(stmt); |
9527 | check_execute(stmt, rc); |
9528 | |
9529 | rc= mysql_stmt_fetch(stmt); |
9530 | check_execute(stmt, rc); |
9531 | |
9532 | DIE_UNLESS(is_null == 0 && lii == 2); |
9533 | if (!opt_silent) |
9534 | fprintf(stdout, "\tLAST_INSERT_ID()= 2 ok\n" ); |
9535 | |
9536 | mysql_stmt_close(stmt); |
9537 | |
9538 | rc= mysql_query(mysql, "DROP TABLE t1" ); |
9539 | myquery(rc); |
9540 | } |
9541 | |
9542 | |
9543 | static void test_join() |
9544 | { |
9545 | MYSQL_STMT *stmt; |
9546 | int rc, i, j; |
9547 | const char *query[]= {"SELECT * FROM t2 join t1 on (t1.a=t2.a)" , |
9548 | "SELECT * FROM t2 natural join t1" , |
9549 | "SELECT * FROM t2 join t1 using(a)" , |
9550 | "SELECT * FROM t2 left join t1 on(t1.a=t2.a)" , |
9551 | "SELECT * FROM t2 natural left join t1" , |
9552 | "SELECT * FROM t2 left join t1 using(a)" , |
9553 | "SELECT * FROM t2 right join t1 on(t1.a=t2.a)" , |
9554 | "SELECT * FROM t2 natural right join t1" , |
9555 | "SELECT * FROM t2 right join t1 using(a)" }; |
9556 | |
9557 | myheader("test_join" ); |
9558 | |
9559 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2" ); |
9560 | myquery(rc); |
9561 | |
9562 | rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);" ); |
9563 | myquery(rc); |
9564 | |
9565 | rc= mysql_query(mysql, |
9566 | "insert into t1 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);" ); |
9567 | myquery(rc); |
9568 | |
9569 | rc= mysql_query(mysql, "CREATE TABLE t2 (a int , c int);" ); |
9570 | myquery(rc); |
9571 | |
9572 | rc= mysql_query(mysql, |
9573 | "insert into t2 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);" ); |
9574 | myquery(rc); |
9575 | |
9576 | for (j= 0; j < 9; j++) |
9577 | { |
9578 | stmt= mysql_simple_prepare(mysql, query[j]); |
9579 | check_stmt(stmt); |
9580 | for (i= 0; i < 3; i++) |
9581 | { |
9582 | rc= mysql_stmt_execute(stmt); |
9583 | check_execute(stmt, rc); |
9584 | rc= my_process_stmt_result(stmt); |
9585 | DIE_UNLESS(rc == 5); |
9586 | } |
9587 | mysql_stmt_close(stmt); |
9588 | } |
9589 | |
9590 | rc= mysql_query(mysql, "DROP TABLE t1, t2" ); |
9591 | myquery(rc); |
9592 | } |
9593 | |
9594 | |
9595 | static void test_selecttmp() |
9596 | { |
9597 | MYSQL_STMT *stmt; |
9598 | int rc, i; |
9599 | const char *query= "select a, (select count(distinct t1.b) as sum from t1, t2 where t1.a=t2.a and t2.b > 0 and t1.a <= t3.b group by t1.a order by sum limit 1) from t3" ; |
9600 | |
9601 | myheader("test_select_tmp" ); |
9602 | |
9603 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2, t3" ); |
9604 | myquery(rc); |
9605 | |
9606 | rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);" ); |
9607 | myquery(rc); |
9608 | |
9609 | rc= mysql_query(mysql, "create table t2 (a int, b int);" ); |
9610 | myquery(rc); |
9611 | |
9612 | rc= mysql_query(mysql, "create table t3 (a int, b int);" ); |
9613 | myquery(rc); |
9614 | |
9615 | rc= mysql_query(mysql, |
9616 | "insert into t1 values (0, 100), (1, 2), (1, 3), (2, 2), (2, 7), \ |
9617 | (2, -1), (3, 10);" ); |
9618 | myquery(rc); |
9619 | rc= mysql_query(mysql, |
9620 | "insert into t2 values (0, 0), (1, 1), (2, 1), (3, 1), (4, 1);" ); |
9621 | myquery(rc); |
9622 | rc= mysql_query(mysql, |
9623 | "insert into t3 values (3, 3), (2, 2), (1, 1);" ); |
9624 | myquery(rc); |
9625 | |
9626 | stmt= mysql_simple_prepare(mysql, query); |
9627 | check_stmt(stmt); |
9628 | for (i= 0; i < 3; i++) |
9629 | { |
9630 | rc= mysql_stmt_execute(stmt); |
9631 | check_execute(stmt, rc); |
9632 | rc= my_process_stmt_result(stmt); |
9633 | DIE_UNLESS(rc == 3); |
9634 | } |
9635 | mysql_stmt_close(stmt); |
9636 | |
9637 | rc= mysql_query(mysql, "DROP TABLE t1, t2, t3" ); |
9638 | myquery(rc); |
9639 | } |
9640 | |
9641 | |
9642 | static void test_create_drop() |
9643 | { |
9644 | MYSQL_STMT *stmt_create, *stmt_drop, *stmt_select, *stmt_create_select; |
9645 | char *query; |
9646 | int rc, i; |
9647 | myheader("test_table_manipulation" ); |
9648 | |
9649 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2" ); |
9650 | myquery(rc); |
9651 | |
9652 | rc= mysql_query(mysql, "create table t2 (a int);" ); |
9653 | myquery(rc); |
9654 | |
9655 | rc= mysql_query(mysql, "create table t1 (a int);" ); |
9656 | myquery(rc); |
9657 | |
9658 | rc= mysql_query(mysql, "insert into t2 values (3), (2), (1);" ); |
9659 | myquery(rc); |
9660 | |
9661 | query= (char*)"create table t1 (a int)" ; |
9662 | stmt_create= mysql_simple_prepare(mysql, query); |
9663 | check_stmt(stmt_create); |
9664 | |
9665 | query= (char*)"drop table t1" ; |
9666 | stmt_drop= mysql_simple_prepare(mysql, query); |
9667 | check_stmt(stmt_drop); |
9668 | |
9669 | query= (char*)"select a in (select a from t2) from t1" ; |
9670 | stmt_select= mysql_simple_prepare(mysql, query); |
9671 | check_stmt(stmt_select); |
9672 | |
9673 | rc= mysql_query(mysql, "DROP TABLE t1" ); |
9674 | myquery(rc); |
9675 | |
9676 | query= (char*)"create table t1 select a from t2" ; |
9677 | stmt_create_select= mysql_simple_prepare(mysql, query); |
9678 | check_stmt(stmt_create_select); |
9679 | |
9680 | for (i= 0; i < 3; i++) |
9681 | { |
9682 | rc= mysql_stmt_execute(stmt_create); |
9683 | check_execute(stmt_create, rc); |
9684 | if (!opt_silent) |
9685 | fprintf(stdout, "created %i\n" , i); |
9686 | |
9687 | rc= mysql_stmt_execute(stmt_select); |
9688 | check_execute(stmt_select, rc); |
9689 | rc= my_process_stmt_result(stmt_select); |
9690 | DIE_UNLESS(rc == 0); |
9691 | |
9692 | rc= mysql_stmt_execute(stmt_drop); |
9693 | check_execute(stmt_drop, rc); |
9694 | if (!opt_silent) |
9695 | fprintf(stdout, "dropped %i\n" , i); |
9696 | |
9697 | rc= mysql_stmt_execute(stmt_create_select); |
9698 | check_execute(stmt_create, rc); |
9699 | if (!opt_silent) |
9700 | fprintf(stdout, "created select %i\n" , i); |
9701 | |
9702 | rc= mysql_stmt_execute(stmt_select); |
9703 | check_execute(stmt_select, rc); |
9704 | rc= my_process_stmt_result(stmt_select); |
9705 | DIE_UNLESS(rc == 3); |
9706 | |
9707 | rc= mysql_stmt_execute(stmt_drop); |
9708 | check_execute(stmt_drop, rc); |
9709 | if (!opt_silent) |
9710 | fprintf(stdout, "dropped %i\n" , i); |
9711 | } |
9712 | |
9713 | mysql_stmt_close(stmt_create); |
9714 | mysql_stmt_close(stmt_drop); |
9715 | mysql_stmt_close(stmt_select); |
9716 | mysql_stmt_close(stmt_create_select); |
9717 | |
9718 | rc= mysql_query(mysql, "DROP TABLE t2" ); |
9719 | myquery(rc); |
9720 | } |
9721 | |
9722 | |
9723 | static void test_rename() |
9724 | { |
9725 | MYSQL_STMT *stmt; |
9726 | const char *query= "rename table t1 to t2, t3 to t4" ; |
9727 | int rc; |
9728 | myheader("test_table_rename" ); |
9729 | |
9730 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2, t3, t4" ); |
9731 | myquery(rc); |
9732 | |
9733 | stmt= mysql_simple_prepare(mysql, query); |
9734 | check_stmt(stmt); |
9735 | |
9736 | rc= mysql_query(mysql, "create table t1 (a int)" ); |
9737 | myquery(rc); |
9738 | |
9739 | rc= mysql_stmt_execute(stmt); |
9740 | check_execute_r(stmt, rc); |
9741 | if (!opt_silent) |
9742 | fprintf(stdout, "rename without t3\n" ); |
9743 | |
9744 | rc= mysql_query(mysql, "create table t3 (a int)" ); |
9745 | myquery(rc); |
9746 | |
9747 | rc= mysql_stmt_execute(stmt); |
9748 | check_execute(stmt, rc); |
9749 | if (!opt_silent) |
9750 | fprintf(stdout, "rename with t3\n" ); |
9751 | |
9752 | rc= mysql_stmt_execute(stmt); |
9753 | check_execute_r(stmt, rc); |
9754 | if (!opt_silent) |
9755 | fprintf(stdout, "rename renamed\n" ); |
9756 | |
9757 | rc= mysql_query(mysql, "rename table t2 to t1, t4 to t3" ); |
9758 | myquery(rc); |
9759 | |
9760 | rc= mysql_stmt_execute(stmt); |
9761 | check_execute(stmt, rc); |
9762 | if (!opt_silent) |
9763 | fprintf(stdout, "rename reverted\n" ); |
9764 | |
9765 | mysql_stmt_close(stmt); |
9766 | |
9767 | rc= mysql_query(mysql, "DROP TABLE t2, t4" ); |
9768 | myquery(rc); |
9769 | } |
9770 | |
9771 | |
9772 | static void test_do_set() |
9773 | { |
9774 | MYSQL_STMT *stmt_do, *stmt_set; |
9775 | char *query; |
9776 | int rc, i; |
9777 | myheader("test_do_set" ); |
9778 | |
9779 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1" ); |
9780 | myquery(rc); |
9781 | |
9782 | rc= mysql_query(mysql, "create table t1 (a int)" ); |
9783 | myquery(rc); |
9784 | |
9785 | query= (char*)"do @var:=(1 in (select * from t1))" ; |
9786 | stmt_do= mysql_simple_prepare(mysql, query); |
9787 | check_stmt(stmt_do); |
9788 | |
9789 | query= (char*)"set @var=(1 in (select * from t1))" ; |
9790 | stmt_set= mysql_simple_prepare(mysql, query); |
9791 | check_stmt(stmt_set); |
9792 | |
9793 | for (i= 0; i < 3; i++) |
9794 | { |
9795 | rc= mysql_stmt_execute(stmt_do); |
9796 | check_execute(stmt_do, rc); |
9797 | if (!opt_silent) |
9798 | fprintf(stdout, "do %i\n" , i); |
9799 | rc= mysql_stmt_execute(stmt_set); |
9800 | check_execute(stmt_set, rc); |
9801 | if (!opt_silent) |
9802 | fprintf(stdout, "set %i\n" , i); |
9803 | } |
9804 | |
9805 | mysql_stmt_close(stmt_do); |
9806 | mysql_stmt_close(stmt_set); |
9807 | } |
9808 | |
9809 | |
9810 | static void test_multi() |
9811 | { |
9812 | MYSQL_STMT *stmt_delete, *stmt_update, *stmt_select1, *stmt_select2; |
9813 | char *query; |
9814 | MYSQL_BIND my_bind[1]; |
9815 | int rc, i; |
9816 | int32 param= 1; |
9817 | ulong length= 1; |
9818 | myheader("test_multi" ); |
9819 | |
9820 | /* |
9821 | We need to bzero bind structure because mysql_stmt_bind_param checks all |
9822 | its members. |
9823 | */ |
9824 | bzero((char*) my_bind, sizeof(my_bind)); |
9825 | |
9826 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
9827 | my_bind[0].buffer= (void *)¶m; |
9828 | my_bind[0].length= &length; |
9829 | |
9830 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2" ); |
9831 | myquery(rc); |
9832 | |
9833 | rc= mysql_query(mysql, "create table t1 (a int, b int)" ); |
9834 | myquery(rc); |
9835 | |
9836 | rc= mysql_query(mysql, "create table t2 (a int, b int)" ); |
9837 | myquery(rc); |
9838 | |
9839 | rc= mysql_query(mysql, "insert into t1 values (3, 3), (2, 2), (1, 1)" ); |
9840 | myquery(rc); |
9841 | |
9842 | rc= mysql_query(mysql, "insert into t2 values (3, 3), (2, 2), (1, 1)" ); |
9843 | myquery(rc); |
9844 | |
9845 | query= (char*)"delete t1, t2 from t1, t2 where t1.a=t2.a and t1.b=10" ; |
9846 | stmt_delete= mysql_simple_prepare(mysql, query); |
9847 | check_stmt(stmt_delete); |
9848 | |
9849 | query= (char*)"update t1, t2 set t1.b=10, t2.b=10 where t1.a=t2.a and t1.b=?" ; |
9850 | stmt_update= mysql_simple_prepare(mysql, query); |
9851 | check_stmt(stmt_update); |
9852 | |
9853 | query= (char*)"select * from t1" ; |
9854 | stmt_select1= mysql_simple_prepare(mysql, query); |
9855 | check_stmt(stmt_select1); |
9856 | |
9857 | query= (char*)"select * from t2" ; |
9858 | stmt_select2= mysql_simple_prepare(mysql, query); |
9859 | check_stmt(stmt_select2); |
9860 | |
9861 | for(i= 0; i < 3; i++) |
9862 | { |
9863 | rc= mysql_stmt_bind_param(stmt_update, my_bind); |
9864 | check_execute(stmt_update, rc); |
9865 | |
9866 | rc= mysql_stmt_execute(stmt_update); |
9867 | check_execute(stmt_update, rc); |
9868 | if (!opt_silent) |
9869 | fprintf(stdout, "update %ld\n" , (long) param); |
9870 | |
9871 | rc= mysql_stmt_execute(stmt_delete); |
9872 | check_execute(stmt_delete, rc); |
9873 | if (!opt_silent) |
9874 | fprintf(stdout, "delete %ld\n" , (long) param); |
9875 | |
9876 | rc= mysql_stmt_execute(stmt_select1); |
9877 | check_execute(stmt_select1, rc); |
9878 | rc= my_process_stmt_result(stmt_select1); |
9879 | DIE_UNLESS(rc == 3-param); |
9880 | |
9881 | rc= mysql_stmt_execute(stmt_select2); |
9882 | check_execute(stmt_select2, rc); |
9883 | rc= my_process_stmt_result(stmt_select2); |
9884 | DIE_UNLESS(rc == 3-param); |
9885 | |
9886 | param++; |
9887 | } |
9888 | |
9889 | mysql_stmt_close(stmt_delete); |
9890 | mysql_stmt_close(stmt_update); |
9891 | mysql_stmt_close(stmt_select1); |
9892 | mysql_stmt_close(stmt_select2); |
9893 | rc= mysql_query(mysql, "drop table t1, t2" ); |
9894 | myquery(rc); |
9895 | } |
9896 | |
9897 | |
9898 | static void test_insert_select() |
9899 | { |
9900 | MYSQL_STMT *stmt_insert, *stmt_select; |
9901 | char *query; |
9902 | int rc; |
9903 | uint i; |
9904 | myheader("test_insert_select" ); |
9905 | |
9906 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2" ); |
9907 | myquery(rc); |
9908 | |
9909 | rc= mysql_query(mysql, "create table t1 (a int)" ); |
9910 | myquery(rc); |
9911 | |
9912 | rc= mysql_query(mysql, "create table t2 (a int)" ); |
9913 | myquery(rc); |
9914 | |
9915 | rc= mysql_query(mysql, "insert into t2 values (1)" ); |
9916 | myquery(rc); |
9917 | |
9918 | query= (char*)"insert into t1 select a from t2" ; |
9919 | stmt_insert= mysql_simple_prepare(mysql, query); |
9920 | check_stmt(stmt_insert); |
9921 | |
9922 | query= (char*)"select * from t1" ; |
9923 | stmt_select= mysql_simple_prepare(mysql, query); |
9924 | check_stmt(stmt_select); |
9925 | |
9926 | for(i= 0; i < 3; i++) |
9927 | { |
9928 | rc= mysql_stmt_execute(stmt_insert); |
9929 | check_execute(stmt_insert, rc); |
9930 | if (!opt_silent) |
9931 | fprintf(stdout, "insert %u\n" , i); |
9932 | |
9933 | rc= mysql_stmt_execute(stmt_select); |
9934 | check_execute(stmt_select, rc); |
9935 | rc= my_process_stmt_result(stmt_select); |
9936 | DIE_UNLESS(rc == (int)(i+1)); |
9937 | } |
9938 | |
9939 | mysql_stmt_close(stmt_insert); |
9940 | mysql_stmt_close(stmt_select); |
9941 | rc= mysql_query(mysql, "drop table t1, t2" ); |
9942 | myquery(rc); |
9943 | } |
9944 | |
9945 | |
9946 | static void test_bind_nagative() |
9947 | { |
9948 | MYSQL_STMT *stmt_insert; |
9949 | char *query; |
9950 | int rc; |
9951 | MYSQL_BIND my_bind[1]; |
9952 | int32 my_val= 0; |
9953 | ulong my_length= 0L; |
9954 | my_bool my_null= FALSE; |
9955 | myheader("test_insert_select" ); |
9956 | |
9957 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1" ); |
9958 | myquery(rc); |
9959 | |
9960 | rc= mysql_query(mysql, "create temporary table t1 (c1 int unsigned)" ); |
9961 | myquery(rc); |
9962 | |
9963 | rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1), (-1)" ); |
9964 | myquery(rc); |
9965 | |
9966 | query= (char*)"INSERT INTO t1 VALUES (?)" ; |
9967 | stmt_insert= mysql_simple_prepare(mysql, query); |
9968 | check_stmt(stmt_insert); |
9969 | |
9970 | /* bind parameters */ |
9971 | bzero((char*) my_bind, sizeof(my_bind)); |
9972 | |
9973 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
9974 | my_bind[0].buffer= (void *)&my_val; |
9975 | my_bind[0].length= &my_length; |
9976 | my_bind[0].is_null= (char*)&my_null; |
9977 | |
9978 | rc= mysql_stmt_bind_param(stmt_insert, my_bind); |
9979 | check_execute(stmt_insert, rc); |
9980 | |
9981 | my_val= -1; |
9982 | rc= mysql_stmt_execute(stmt_insert); |
9983 | check_execute(stmt_insert, rc); |
9984 | |
9985 | mysql_stmt_close(stmt_insert); |
9986 | rc= mysql_query(mysql, "drop table t1" ); |
9987 | myquery(rc); |
9988 | } |
9989 | |
9990 | |
9991 | static void test_derived() |
9992 | { |
9993 | MYSQL_STMT *stmt; |
9994 | int rc, i; |
9995 | MYSQL_BIND my_bind[1]; |
9996 | int32 my_val= 0; |
9997 | ulong my_length= 0L; |
9998 | my_bool my_null= FALSE; |
9999 | const char *query= |
10000 | "select count(1) from (select f.id from t1 f where f.id=?) as x" ; |
10001 | |
10002 | myheader("test_derived" ); |
10003 | |
10004 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1" ); |
10005 | myquery(rc); |
10006 | |
10007 | rc= mysql_query(mysql, "create table t1 (id int(8), primary key (id)) \ |
10008 | ENGINE=InnoDB DEFAULT CHARSET=utf8" ); |
10009 | myquery(rc); |
10010 | |
10011 | rc= mysql_query(mysql, "insert into t1 values (1)" ); |
10012 | myquery(rc); |
10013 | |
10014 | stmt= mysql_simple_prepare(mysql, query); |
10015 | check_stmt(stmt); |
10016 | /* |
10017 | We need to bzero bind structure because mysql_stmt_bind_param checks all |
10018 | its members. |
10019 | */ |
10020 | bzero((char*) my_bind, sizeof(my_bind)); |
10021 | |
10022 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
10023 | my_bind[0].buffer= (void *)&my_val; |
10024 | my_bind[0].length= &my_length; |
10025 | my_bind[0].is_null= (char*)&my_null; |
10026 | my_val= 1; |
10027 | rc= mysql_stmt_bind_param(stmt, my_bind); |
10028 | check_execute(stmt, rc); |
10029 | |
10030 | for (i= 0; i < 3; i++) |
10031 | { |
10032 | rc= mysql_stmt_execute(stmt); |
10033 | check_execute(stmt, rc); |
10034 | rc= my_process_stmt_result(stmt); |
10035 | DIE_UNLESS(rc == 1); |
10036 | } |
10037 | mysql_stmt_close(stmt); |
10038 | |
10039 | rc= mysql_query(mysql, "DROP TABLE t1" ); |
10040 | myquery(rc); |
10041 | } |
10042 | |
10043 | |
10044 | static void test_xjoin() |
10045 | { |
10046 | MYSQL_STMT *stmt; |
10047 | int rc, i; |
10048 | const char *query= |
10049 | "select t.id, p1.value, n1.value, p2.value, n2.value from t3 t LEFT JOIN t1 p1 ON (p1.id=t.param1_id) LEFT JOIN t2 p2 ON (p2.id=t.param2_id) LEFT JOIN t4 n1 ON (n1.id=p1.name_id) LEFT JOIN t4 n2 ON (n2.id=p2.name_id) where t.id=1" ; |
10050 | |
10051 | myheader("test_xjoin" ); |
10052 | |
10053 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2, t3, t4" ); |
10054 | myquery(rc); |
10055 | |
10056 | rc= mysql_query(mysql, "create table t3 (id int(8), param1_id int(8), param2_id int(8)) ENGINE=InnoDB DEFAULT CHARSET=utf8" ); |
10057 | myquery(rc); |
10058 | |
10059 | rc= mysql_query(mysql, "create table t1 ( id int(8), name_id int(8), value varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8" ); |
10060 | myquery(rc); |
10061 | |
10062 | rc= mysql_query(mysql, "create table t2 (id int(8), name_id int(8), value varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8;" ); |
10063 | myquery(rc); |
10064 | |
10065 | rc= mysql_query(mysql, "create table t4(id int(8), value varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8" ); |
10066 | myquery(rc); |
10067 | |
10068 | rc= mysql_query(mysql, "insert into t3 values (1, 1, 1), (2, 2, null)" ); |
10069 | myquery(rc); |
10070 | |
10071 | rc= mysql_query(mysql, "insert into t1 values (1, 1, 'aaa'), (2, null, 'bbb')" ); |
10072 | myquery(rc); |
10073 | |
10074 | rc= mysql_query(mysql, "insert into t2 values (1, 2, 'ccc')" ); |
10075 | myquery(rc); |
10076 | |
10077 | rc= mysql_query(mysql, "insert into t4 values (1, 'Name1'), (2, null)" ); |
10078 | myquery(rc); |
10079 | |
10080 | stmt= mysql_simple_prepare(mysql, query); |
10081 | check_stmt(stmt); |
10082 | |
10083 | for (i= 0; i < 3; i++) |
10084 | { |
10085 | rc= mysql_stmt_execute(stmt); |
10086 | check_execute(stmt, rc); |
10087 | rc= my_process_stmt_result(stmt); |
10088 | DIE_UNLESS(rc == 1); |
10089 | } |
10090 | mysql_stmt_close(stmt); |
10091 | |
10092 | rc= mysql_query(mysql, "DROP TABLE t1, t2, t3, t4" ); |
10093 | myquery(rc); |
10094 | } |
10095 | |
10096 | |
10097 | static void test_bug3035() |
10098 | { |
10099 | MYSQL_STMT *stmt; |
10100 | int rc; |
10101 | MYSQL_BIND bind_array[12], *my_bind= bind_array, *bind_end= my_bind + 12; |
10102 | int8 int8_val; |
10103 | uint8 uint8_val; |
10104 | int16 int16_val; |
10105 | uint16 uint16_val; |
10106 | int32 int32_val; |
10107 | uint32 uint32_val; |
10108 | longlong int64_val; |
10109 | ulonglong uint64_val; |
10110 | double double_val, udouble_val, double_tmp; |
10111 | char longlong_as_string[22], ulonglong_as_string[22]; |
10112 | |
10113 | /* mins and maxes */ |
10114 | const int8 int8_min= -128; |
10115 | const int8 int8_max= 127; |
10116 | const uint8 uint8_min= 0; |
10117 | const uint8 uint8_max= 255; |
10118 | |
10119 | const int16 int16_min= -32768; |
10120 | const int16 int16_max= 32767; |
10121 | const uint16 uint16_min= 0; |
10122 | const uint16 uint16_max= 65535; |
10123 | |
10124 | const int32 int32_max= 2147483647L; |
10125 | const int32 int32_min= -int32_max - 1; |
10126 | const uint32 uint32_min= 0; |
10127 | const uint32 uint32_max= 4294967295U; |
10128 | |
10129 | /* it might not work okay everyplace */ |
10130 | const longlong int64_max= 9223372036854775807LL; |
10131 | const longlong int64_min= -int64_max - 1; |
10132 | |
10133 | const ulonglong uint64_min= 0U; |
10134 | const ulonglong uint64_max= 18446744073709551615ULL; |
10135 | |
10136 | const char *stmt_text; |
10137 | |
10138 | myheader("test_bug3035" ); |
10139 | |
10140 | stmt_text= "DROP TABLE IF EXISTS t1" ; |
10141 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
10142 | myquery(rc); |
10143 | |
10144 | stmt_text= "CREATE TABLE t1 (i8 TINYINT, ui8 TINYINT UNSIGNED, " |
10145 | "i16 SMALLINT, ui16 SMALLINT UNSIGNED, " |
10146 | "i32 INT, ui32 INT UNSIGNED, " |
10147 | "i64 BIGINT, ui64 BIGINT UNSIGNED, " |
10148 | "id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT)" ; |
10149 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
10150 | myquery(rc); |
10151 | |
10152 | bzero((char*) bind_array, sizeof(bind_array)); |
10153 | |
10154 | for (my_bind= bind_array; my_bind < bind_end; my_bind++) |
10155 | my_bind->error= &my_bind->error_value; |
10156 | |
10157 | bind_array[0].buffer_type= MYSQL_TYPE_TINY; |
10158 | bind_array[0].buffer= (void *) &int8_val; |
10159 | |
10160 | bind_array[1].buffer_type= MYSQL_TYPE_TINY; |
10161 | bind_array[1].buffer= (void *) &uint8_val; |
10162 | bind_array[1].is_unsigned= 1; |
10163 | |
10164 | bind_array[2].buffer_type= MYSQL_TYPE_SHORT; |
10165 | bind_array[2].buffer= (void *) &int16_val; |
10166 | |
10167 | bind_array[3].buffer_type= MYSQL_TYPE_SHORT; |
10168 | bind_array[3].buffer= (void *) &uint16_val; |
10169 | bind_array[3].is_unsigned= 1; |
10170 | |
10171 | bind_array[4].buffer_type= MYSQL_TYPE_LONG; |
10172 | bind_array[4].buffer= (void *) &int32_val; |
10173 | |
10174 | bind_array[5].buffer_type= MYSQL_TYPE_LONG; |
10175 | bind_array[5].buffer= (void *) &uint32_val; |
10176 | bind_array[5].is_unsigned= 1; |
10177 | |
10178 | bind_array[6].buffer_type= MYSQL_TYPE_LONGLONG; |
10179 | bind_array[6].buffer= (void *) &int64_val; |
10180 | |
10181 | bind_array[7].buffer_type= MYSQL_TYPE_LONGLONG; |
10182 | bind_array[7].buffer= (void *) &uint64_val; |
10183 | bind_array[7].is_unsigned= 1; |
10184 | |
10185 | stmt= mysql_stmt_init(mysql); |
10186 | check_stmt(stmt); |
10187 | |
10188 | stmt_text= "INSERT INTO t1 (i8, ui8, i16, ui16, i32, ui32, i64, ui64) " |
10189 | "VALUES (?, ?, ?, ?, ?, ?, ?, ?)" ; |
10190 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
10191 | check_execute(stmt, rc); |
10192 | |
10193 | mysql_stmt_bind_param(stmt, bind_array); |
10194 | |
10195 | int8_val= int8_min; |
10196 | uint8_val= uint8_min; |
10197 | int16_val= int16_min; |
10198 | uint16_val= uint16_min; |
10199 | int32_val= int32_min; |
10200 | uint32_val= uint32_min; |
10201 | int64_val= int64_min; |
10202 | uint64_val= uint64_min; |
10203 | |
10204 | rc= mysql_stmt_execute(stmt); |
10205 | check_execute(stmt, rc); |
10206 | |
10207 | int8_val= int8_max; |
10208 | uint8_val= uint8_max; |
10209 | int16_val= int16_max; |
10210 | uint16_val= uint16_max; |
10211 | int32_val= int32_max; |
10212 | uint32_val= uint32_max; |
10213 | int64_val= int64_max; |
10214 | uint64_val= uint64_max; |
10215 | |
10216 | rc= mysql_stmt_execute(stmt); |
10217 | check_execute(stmt, rc); |
10218 | |
10219 | stmt_text= "SELECT i8, ui8, i16, ui16, i32, ui32, i64, ui64, ui64, " |
10220 | "cast(ui64 as signed), ui64, cast(ui64 as signed)" |
10221 | "FROM t1 ORDER BY id ASC" ; |
10222 | |
10223 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
10224 | check_execute(stmt, rc); |
10225 | |
10226 | rc= mysql_stmt_execute(stmt); |
10227 | check_execute(stmt, rc); |
10228 | |
10229 | bind_array[8].buffer_type= MYSQL_TYPE_DOUBLE; |
10230 | bind_array[8].buffer= (void *) &udouble_val; |
10231 | |
10232 | bind_array[9].buffer_type= MYSQL_TYPE_DOUBLE; |
10233 | bind_array[9].buffer= (void *) &double_val; |
10234 | |
10235 | bind_array[10].buffer_type= MYSQL_TYPE_STRING; |
10236 | bind_array[10].buffer= (void *) &ulonglong_as_string; |
10237 | bind_array[10].buffer_length= sizeof(ulonglong_as_string); |
10238 | |
10239 | bind_array[11].buffer_type= MYSQL_TYPE_STRING; |
10240 | bind_array[11].buffer= (void *) &longlong_as_string; |
10241 | bind_array[11].buffer_length= sizeof(longlong_as_string); |
10242 | |
10243 | mysql_stmt_bind_result(stmt, bind_array); |
10244 | |
10245 | rc= mysql_stmt_fetch(stmt); |
10246 | check_execute(stmt, rc); |
10247 | |
10248 | DIE_UNLESS(int8_val == int8_min); |
10249 | DIE_UNLESS(uint8_val == uint8_min); |
10250 | DIE_UNLESS(int16_val == int16_min); |
10251 | DIE_UNLESS(uint16_val == uint16_min); |
10252 | DIE_UNLESS(int32_val == int32_min); |
10253 | DIE_UNLESS(uint32_val == uint32_min); |
10254 | DIE_UNLESS(int64_val == int64_min); |
10255 | DIE_UNLESS(uint64_val == uint64_min); |
10256 | DIE_UNLESS(double_val == (longlong) uint64_min); |
10257 | double_tmp= ulonglong2double(uint64_val); |
10258 | DIE_UNLESS(cmp_double(&udouble_val, &double_tmp)); |
10259 | DIE_UNLESS(!strcmp(longlong_as_string, "0" )); |
10260 | DIE_UNLESS(!strcmp(ulonglong_as_string, "0" )); |
10261 | |
10262 | rc= mysql_stmt_fetch(stmt); |
10263 | |
10264 | if (!opt_silent) |
10265 | { |
10266 | printf("Truncation mask: " ); |
10267 | for (my_bind= bind_array; my_bind < bind_end; my_bind++) |
10268 | printf("%d" , (int) my_bind->error_value); |
10269 | printf("\n" ); |
10270 | } |
10271 | DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED || rc == 0); |
10272 | |
10273 | DIE_UNLESS(int8_val == int8_max); |
10274 | DIE_UNLESS(uint8_val == uint8_max); |
10275 | DIE_UNLESS(int16_val == int16_max); |
10276 | DIE_UNLESS(uint16_val == uint16_max); |
10277 | DIE_UNLESS(int32_val == int32_max); |
10278 | DIE_UNLESS(uint32_val == uint32_max); |
10279 | DIE_UNLESS(int64_val == int64_max); |
10280 | DIE_UNLESS(uint64_val == uint64_max); |
10281 | DIE_UNLESS(double_val == (longlong) uint64_val); |
10282 | double_tmp= ulonglong2double(uint64_val); |
10283 | DIE_UNLESS(cmp_double(&udouble_val, &double_tmp)); |
10284 | DIE_UNLESS(!strcmp(longlong_as_string, "-1" )); |
10285 | DIE_UNLESS(!strcmp(ulonglong_as_string, "18446744073709551615" )); |
10286 | |
10287 | rc= mysql_stmt_fetch(stmt); |
10288 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
10289 | |
10290 | mysql_stmt_close(stmt); |
10291 | |
10292 | stmt_text= "DROP TABLE t1" ; |
10293 | mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
10294 | } |
10295 | |
10296 | |
10297 | static void test_union2() |
10298 | { |
10299 | MYSQL_STMT *stmt; |
10300 | int rc, i; |
10301 | |
10302 | myheader("test_union2" ); |
10303 | |
10304 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1" ); |
10305 | myquery(rc); |
10306 | |
10307 | rc= mysql_query(mysql, "CREATE TABLE t1(col1 INT, \ |
10308 | col2 VARCHAR(40), \ |
10309 | col3 SMALLINT, \ |
10310 | col4 TIMESTAMP)" ); |
10311 | myquery(rc); |
10312 | |
10313 | stmt= mysql_simple_prepare(mysql, |
10314 | "select col1 FROM t1 where col1=1 union distinct " |
10315 | "select col1 FROM t1 where col1=2" ); |
10316 | check_stmt(stmt); |
10317 | |
10318 | for (i= 0; i < 3; i++) |
10319 | { |
10320 | rc= mysql_stmt_execute(stmt); |
10321 | check_execute(stmt, rc); |
10322 | rc= my_process_stmt_result(stmt); |
10323 | DIE_UNLESS(rc == 0); |
10324 | } |
10325 | |
10326 | mysql_stmt_close(stmt); |
10327 | |
10328 | rc= mysql_query(mysql, "DROP TABLE t1" ); |
10329 | myquery(rc); |
10330 | } |
10331 | |
10332 | |
10333 | /* |
10334 | This tests for various mysql_stmt_send_long_data bugs described in #1664 |
10335 | */ |
10336 | |
10337 | static void test_bug1664() |
10338 | { |
10339 | MYSQL_STMT *stmt; |
10340 | int rc, int_data; |
10341 | const char *data; |
10342 | const char *str_data= "Simple string" ; |
10343 | MYSQL_BIND my_bind[2]; |
10344 | const char *query= "INSERT INTO test_long_data(col2, col1) VALUES(?, ?)" ; |
10345 | |
10346 | myheader("test_bug1664" ); |
10347 | |
10348 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data" ); |
10349 | myquery(rc); |
10350 | |
10351 | rc= mysql_query(mysql, "CREATE TABLE test_long_data(col1 int, col2 long varchar)" ); |
10352 | myquery(rc); |
10353 | |
10354 | stmt= mysql_stmt_init(mysql); |
10355 | check_stmt(stmt); |
10356 | rc= mysql_stmt_prepare(stmt, query, strlen(query)); |
10357 | check_execute(stmt, rc); |
10358 | |
10359 | verify_param_count(stmt, 2); |
10360 | |
10361 | bzero((char*) my_bind, sizeof(my_bind)); |
10362 | |
10363 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
10364 | my_bind[0].buffer= (void *)str_data; |
10365 | my_bind[0].buffer_length= strlen(str_data); |
10366 | |
10367 | my_bind[1].buffer= (void *)&int_data; |
10368 | my_bind[1].buffer_type= MYSQL_TYPE_LONG; |
10369 | |
10370 | rc= mysql_stmt_bind_param(stmt, my_bind); |
10371 | check_execute(stmt, rc); |
10372 | |
10373 | int_data= 1; |
10374 | |
10375 | /* |
10376 | Let us supply empty long_data. This should work and should |
10377 | not break following execution. |
10378 | */ |
10379 | data= "" ; |
10380 | rc= mysql_stmt_send_long_data(stmt, 0, data, strlen(data)); |
10381 | check_execute(stmt, rc); |
10382 | |
10383 | rc= mysql_stmt_execute(stmt); |
10384 | check_execute(stmt, rc); |
10385 | |
10386 | verify_col_data("test_long_data" , "col1" , "1" ); |
10387 | verify_col_data("test_long_data" , "col2" , "" ); |
10388 | |
10389 | rc= mysql_query(mysql, "DELETE FROM test_long_data" ); |
10390 | myquery(rc); |
10391 | |
10392 | /* This should pass OK */ |
10393 | data= (char *)"Data" ; |
10394 | rc= mysql_stmt_send_long_data(stmt, 0, data, strlen(data)); |
10395 | check_execute(stmt, rc); |
10396 | |
10397 | rc= mysql_stmt_execute(stmt); |
10398 | check_execute(stmt, rc); |
10399 | |
10400 | verify_col_data("test_long_data" , "col1" , "1" ); |
10401 | verify_col_data("test_long_data" , "col2" , "Data" ); |
10402 | |
10403 | /* clean up */ |
10404 | rc= mysql_query(mysql, "DELETE FROM test_long_data" ); |
10405 | myquery(rc); |
10406 | |
10407 | /* |
10408 | Now we are changing int parameter and don't do anything |
10409 | with first parameter. Second mysql_stmt_execute() should run |
10410 | OK treating this first parameter as string parameter. |
10411 | */ |
10412 | |
10413 | int_data= 2; |
10414 | /* execute */ |
10415 | rc= mysql_stmt_execute(stmt); |
10416 | check_execute(stmt, rc); |
10417 | |
10418 | verify_col_data("test_long_data" , "col1" , "2" ); |
10419 | verify_col_data("test_long_data" , "col2" , str_data); |
10420 | |
10421 | /* clean up */ |
10422 | rc= mysql_query(mysql, "DELETE FROM test_long_data" ); |
10423 | myquery(rc); |
10424 | |
10425 | /* |
10426 | Now we are sending other long data. It should not be |
10427 | concatened to previous. |
10428 | */ |
10429 | |
10430 | data= (char *)"SomeOtherData" ; |
10431 | rc= mysql_stmt_send_long_data(stmt, 0, data, strlen(data)); |
10432 | check_execute(stmt, rc); |
10433 | |
10434 | rc= mysql_stmt_execute(stmt); |
10435 | check_execute(stmt, rc); |
10436 | |
10437 | verify_col_data("test_long_data" , "col1" , "2" ); |
10438 | verify_col_data("test_long_data" , "col2" , "SomeOtherData" ); |
10439 | |
10440 | mysql_stmt_close(stmt); |
10441 | |
10442 | /* clean up */ |
10443 | rc= mysql_query(mysql, "DELETE FROM test_long_data" ); |
10444 | myquery(rc); |
10445 | |
10446 | /* Now let us test how mysql_stmt_reset works. */ |
10447 | stmt= mysql_stmt_init(mysql); |
10448 | check_stmt(stmt); |
10449 | rc= mysql_stmt_prepare(stmt, query, strlen(query)); |
10450 | check_execute(stmt, rc); |
10451 | rc= mysql_stmt_bind_param(stmt, my_bind); |
10452 | check_execute(stmt, rc); |
10453 | |
10454 | data= (char *)"SomeData" ; |
10455 | rc= mysql_stmt_send_long_data(stmt, 0, data, strlen(data)); |
10456 | check_execute(stmt, rc); |
10457 | |
10458 | rc= mysql_stmt_reset(stmt); |
10459 | check_execute(stmt, rc); |
10460 | |
10461 | rc= mysql_stmt_execute(stmt); |
10462 | check_execute(stmt, rc); |
10463 | |
10464 | verify_col_data("test_long_data" , "col1" , "2" ); |
10465 | verify_col_data("test_long_data" , "col2" , str_data); |
10466 | |
10467 | mysql_stmt_close(stmt); |
10468 | |
10469 | /* Final clean up */ |
10470 | rc= mysql_query(mysql, "DROP TABLE test_long_data" ); |
10471 | myquery(rc); |
10472 | } |
10473 | |
10474 | |
10475 | static void test_order_param() |
10476 | { |
10477 | MYSQL_STMT *stmt; |
10478 | int rc; |
10479 | |
10480 | myheader("test_order_param" ); |
10481 | |
10482 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1" ); |
10483 | myquery(rc); |
10484 | |
10485 | rc= mysql_query(mysql, "CREATE TABLE t1(a INT, b char(10))" ); |
10486 | myquery(rc); |
10487 | |
10488 | stmt= mysql_simple_prepare(mysql, |
10489 | "select sum(a) + 200, 1 from t1 " |
10490 | " union distinct " |
10491 | "select sum(a) + 200, 1 from t1 group by b " ); |
10492 | check_stmt(stmt); |
10493 | mysql_stmt_close(stmt); |
10494 | |
10495 | stmt= mysql_simple_prepare(mysql, |
10496 | "select sum(a) + 200, ? from t1 group by b " |
10497 | " union distinct " |
10498 | "select sum(a) + 200, 1 from t1 group by b " ); |
10499 | check_stmt(stmt); |
10500 | mysql_stmt_close(stmt); |
10501 | |
10502 | stmt= mysql_simple_prepare(mysql, |
10503 | "select sum(a) + 200, ? from t1 " |
10504 | " union distinct " |
10505 | "select sum(a) + 200, 1 from t1 group by b " ); |
10506 | check_stmt(stmt); |
10507 | mysql_stmt_close(stmt); |
10508 | |
10509 | rc= mysql_query(mysql, "DROP TABLE t1" ); |
10510 | myquery(rc); |
10511 | } |
10512 | |
10513 | |
10514 | static void test_union_param() |
10515 | { |
10516 | MYSQL_STMT *stmt; |
10517 | char *query; |
10518 | int rc, i; |
10519 | MYSQL_BIND my_bind[2]; |
10520 | char my_val[4]; |
10521 | ulong my_length= 3L; |
10522 | my_bool my_null= FALSE; |
10523 | myheader("test_union_param" ); |
10524 | |
10525 | strmov(my_val, "abc" ); |
10526 | |
10527 | query= (char*)"select ? as my_col union distinct select ?" ; |
10528 | stmt= mysql_simple_prepare(mysql, query); |
10529 | check_stmt(stmt); |
10530 | |
10531 | /* |
10532 | We need to bzero bind structure because mysql_stmt_bind_param checks all |
10533 | its members. |
10534 | */ |
10535 | bzero((char*) my_bind, sizeof(my_bind)); |
10536 | |
10537 | /* bind parameters */ |
10538 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
10539 | my_bind[0].buffer= (char*) &my_val; |
10540 | my_bind[0].buffer_length= 4; |
10541 | my_bind[0].length= &my_length; |
10542 | my_bind[0].is_null= (char*)&my_null; |
10543 | my_bind[1].buffer_type= MYSQL_TYPE_STRING; |
10544 | my_bind[1].buffer= (char*) &my_val; |
10545 | my_bind[1].buffer_length= 4; |
10546 | my_bind[1].length= &my_length; |
10547 | my_bind[1].is_null= (char*)&my_null; |
10548 | |
10549 | rc= mysql_stmt_bind_param(stmt, my_bind); |
10550 | check_execute(stmt, rc); |
10551 | |
10552 | for (i= 0; i < 3; i++) |
10553 | { |
10554 | rc= mysql_stmt_execute(stmt); |
10555 | check_execute(stmt, rc); |
10556 | rc= my_process_stmt_result(stmt); |
10557 | DIE_UNLESS(rc == 1); |
10558 | } |
10559 | |
10560 | mysql_stmt_close(stmt); |
10561 | } |
10562 | |
10563 | |
10564 | static void test_ps_i18n() |
10565 | { |
10566 | MYSQL_STMT *stmt; |
10567 | int rc; |
10568 | const char *stmt_text; |
10569 | MYSQL_BIND bind_array[2]; |
10570 | |
10571 | /* Represented as numbers to keep UTF8 tools from clobbering them. */ |
10572 | const char *koi8= "\xee\xd5\x2c\x20\xda\xc1\x20\xd2\xd9\xc2\xc1\xcc\xcb\xd5" ; |
10573 | const char *cp1251= "\xcd\xf3\x2c\x20\xe7\xe0\x20\xf0\xfb\xe1\xe0\xeb\xea\xf3" ; |
10574 | char buf1[16], buf2[16]; |
10575 | ulong buf1_len, buf2_len; |
10576 | |
10577 | |
10578 | myheader("test_ps_i18n" ); |
10579 | |
10580 | stmt_text= "DROP TABLE IF EXISTS t1" ; |
10581 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
10582 | myquery(rc); |
10583 | |
10584 | /* |
10585 | Create table with binary columns, set session character set to cp1251, |
10586 | client character set to koi8, and make sure that there is conversion |
10587 | on insert and no conversion on select |
10588 | */ |
10589 | |
10590 | stmt_text= "CREATE TABLE t1 (c1 VARBINARY(255), c2 VARBINARY(255))" ; |
10591 | |
10592 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
10593 | myquery(rc); |
10594 | |
10595 | stmt_text= "SET CHARACTER_SET_CLIENT=koi8r, " |
10596 | "CHARACTER_SET_CONNECTION=cp1251, " |
10597 | "CHARACTER_SET_RESULTS=koi8r" ; |
10598 | |
10599 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
10600 | myquery(rc); |
10601 | |
10602 | bzero((char*) bind_array, sizeof(bind_array)); |
10603 | |
10604 | bind_array[0].buffer_type= MYSQL_TYPE_STRING; |
10605 | bind_array[0].buffer= (void *) koi8; |
10606 | bind_array[0].buffer_length= strlen(koi8); |
10607 | |
10608 | bind_array[1].buffer_type= MYSQL_TYPE_STRING; |
10609 | bind_array[1].buffer= (void *) koi8; |
10610 | bind_array[1].buffer_length= strlen(koi8); |
10611 | |
10612 | stmt= mysql_stmt_init(mysql); |
10613 | check_stmt(stmt); |
10614 | |
10615 | stmt_text= "INSERT INTO t1 (c1, c2) VALUES (?, ?)" ; |
10616 | |
10617 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
10618 | check_execute(stmt, rc); |
10619 | |
10620 | mysql_stmt_bind_param(stmt, bind_array); |
10621 | |
10622 | mysql_stmt_send_long_data(stmt, 0, koi8, strlen(koi8)); |
10623 | |
10624 | rc= mysql_stmt_execute(stmt); |
10625 | check_execute(stmt, rc); |
10626 | |
10627 | stmt_text= "SELECT c1, c2 FROM t1" ; |
10628 | |
10629 | /* c1 and c2 are binary so no conversion will be done on select */ |
10630 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
10631 | check_execute(stmt, rc); |
10632 | |
10633 | rc= mysql_stmt_execute(stmt); |
10634 | check_execute(stmt, rc); |
10635 | |
10636 | bind_array[0].buffer= buf1; |
10637 | bind_array[0].buffer_length= sizeof(buf1); |
10638 | bind_array[0].length= &buf1_len; |
10639 | |
10640 | bind_array[1].buffer= buf2; |
10641 | bind_array[1].buffer_length= sizeof(buf2); |
10642 | bind_array[1].length= &buf2_len; |
10643 | |
10644 | mysql_stmt_bind_result(stmt, bind_array); |
10645 | |
10646 | rc= mysql_stmt_fetch(stmt); |
10647 | check_execute(stmt, rc); |
10648 | |
10649 | DIE_UNLESS(buf1_len == strlen(cp1251)); |
10650 | DIE_UNLESS(buf2_len == strlen(cp1251)); |
10651 | DIE_UNLESS(!memcmp(buf1, cp1251, buf1_len)); |
10652 | DIE_UNLESS(!memcmp(buf2, cp1251, buf1_len)); |
10653 | |
10654 | rc= mysql_stmt_fetch(stmt); |
10655 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
10656 | |
10657 | stmt_text= "DROP TABLE IF EXISTS t1" ; |
10658 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
10659 | myquery(rc); |
10660 | |
10661 | /* |
10662 | Now create table with two cp1251 columns, set client character |
10663 | set to koi8 and supply columns of one row as string and another as |
10664 | binary data. Binary data must not be converted on insert, and both |
10665 | columns must be converted to client character set on select. |
10666 | */ |
10667 | |
10668 | stmt_text= "CREATE TABLE t1 (c1 VARCHAR(255) CHARACTER SET cp1251, " |
10669 | "c2 VARCHAR(255) CHARACTER SET cp1251)" ; |
10670 | |
10671 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
10672 | myquery(rc); |
10673 | |
10674 | stmt_text= "INSERT INTO t1 (c1, c2) VALUES (?, ?)" ; |
10675 | |
10676 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
10677 | check_execute(stmt, rc); |
10678 | |
10679 | /* this data must be converted */ |
10680 | bind_array[0].buffer_type= MYSQL_TYPE_STRING; |
10681 | bind_array[0].buffer= (void *) koi8; |
10682 | bind_array[0].buffer_length= strlen(koi8); |
10683 | |
10684 | bind_array[1].buffer_type= MYSQL_TYPE_STRING; |
10685 | bind_array[1].buffer= (void *) koi8; |
10686 | bind_array[1].buffer_length= strlen(koi8); |
10687 | |
10688 | mysql_stmt_bind_param(stmt, bind_array); |
10689 | |
10690 | mysql_stmt_send_long_data(stmt, 0, koi8, strlen(koi8)); |
10691 | |
10692 | rc= mysql_stmt_execute(stmt); |
10693 | check_execute(stmt, rc); |
10694 | |
10695 | /* this data must not be converted */ |
10696 | bind_array[0].buffer_type= MYSQL_TYPE_BLOB; |
10697 | bind_array[0].buffer= (void *) cp1251; |
10698 | bind_array[0].buffer_length= strlen(cp1251); |
10699 | |
10700 | bind_array[1].buffer_type= MYSQL_TYPE_BLOB; |
10701 | bind_array[1].buffer= (void *) cp1251; |
10702 | bind_array[1].buffer_length= strlen(cp1251); |
10703 | |
10704 | mysql_stmt_bind_param(stmt, bind_array); |
10705 | |
10706 | mysql_stmt_send_long_data(stmt, 0, cp1251, strlen(cp1251)); |
10707 | |
10708 | rc= mysql_stmt_execute(stmt); |
10709 | check_execute(stmt, rc); |
10710 | |
10711 | /* Fetch data and verify that rows are in koi8 */ |
10712 | |
10713 | stmt_text= "SELECT c1, c2 FROM t1" ; |
10714 | |
10715 | /* c1 and c2 are binary so no conversion will be done on select */ |
10716 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
10717 | check_execute(stmt, rc); |
10718 | |
10719 | rc= mysql_stmt_execute(stmt); |
10720 | check_execute(stmt, rc); |
10721 | |
10722 | bind_array[0].buffer= buf1; |
10723 | bind_array[0].buffer_length= sizeof(buf1); |
10724 | bind_array[0].length= &buf1_len; |
10725 | |
10726 | bind_array[1].buffer= buf2; |
10727 | bind_array[1].buffer_length= sizeof(buf2); |
10728 | bind_array[1].length= &buf2_len; |
10729 | |
10730 | mysql_stmt_bind_result(stmt, bind_array); |
10731 | |
10732 | while ((rc= mysql_stmt_fetch(stmt)) == 0) |
10733 | { |
10734 | DIE_UNLESS(buf1_len == strlen(koi8)); |
10735 | DIE_UNLESS(buf2_len == strlen(koi8)); |
10736 | DIE_UNLESS(!memcmp(buf1, koi8, buf1_len)); |
10737 | DIE_UNLESS(!memcmp(buf2, koi8, buf1_len)); |
10738 | } |
10739 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
10740 | mysql_stmt_close(stmt); |
10741 | |
10742 | stmt_text= "DROP TABLE t1" ; |
10743 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
10744 | myquery(rc); |
10745 | stmt_text= "SET NAMES DEFAULT" ; |
10746 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
10747 | myquery(rc); |
10748 | } |
10749 | |
10750 | |
10751 | static void test_bug3796() |
10752 | { |
10753 | MYSQL_STMT *stmt; |
10754 | MYSQL_BIND my_bind[1]; |
10755 | const char *concat_arg0= "concat_with_" ; |
10756 | enum { OUT_BUFF_SIZE= 30 }; |
10757 | char out_buff[OUT_BUFF_SIZE]; |
10758 | char canonical_buff[OUT_BUFF_SIZE]; |
10759 | ulong out_length; |
10760 | const char *stmt_text; |
10761 | int rc; |
10762 | |
10763 | myheader("test_bug3796" ); |
10764 | |
10765 | /* Create and fill test table */ |
10766 | stmt_text= "DROP TABLE IF EXISTS t1" ; |
10767 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
10768 | myquery(rc); |
10769 | |
10770 | stmt_text= "CREATE TABLE t1 (a INT, b VARCHAR(30))" ; |
10771 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
10772 | myquery(rc); |
10773 | |
10774 | stmt_text= "INSERT INTO t1 VALUES(1, 'ONE'), (2, 'TWO')" ; |
10775 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
10776 | myquery(rc); |
10777 | |
10778 | /* Create statement handle and prepare it with select */ |
10779 | stmt= mysql_stmt_init(mysql); |
10780 | stmt_text= "SELECT concat(?, b) FROM t1" ; |
10781 | |
10782 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
10783 | check_execute(stmt, rc); |
10784 | |
10785 | /* Bind input buffers */ |
10786 | bzero((char*) my_bind, sizeof(my_bind)); |
10787 | |
10788 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
10789 | my_bind[0].buffer= (void *) concat_arg0; |
10790 | my_bind[0].buffer_length= strlen(concat_arg0); |
10791 | |
10792 | mysql_stmt_bind_param(stmt, my_bind); |
10793 | |
10794 | /* Execute the select statement */ |
10795 | rc= mysql_stmt_execute(stmt); |
10796 | check_execute(stmt, rc); |
10797 | |
10798 | my_bind[0].buffer= (void *) out_buff; |
10799 | my_bind[0].buffer_length= OUT_BUFF_SIZE; |
10800 | my_bind[0].length= &out_length; |
10801 | |
10802 | mysql_stmt_bind_result(stmt, my_bind); |
10803 | |
10804 | rc= mysql_stmt_fetch(stmt); |
10805 | if (!opt_silent) |
10806 | printf("Concat result: '%s'\n" , out_buff); |
10807 | check_execute(stmt, rc); |
10808 | strmov(canonical_buff, concat_arg0); |
10809 | strcat(canonical_buff, "ONE" ); |
10810 | DIE_UNLESS(strlen(canonical_buff) == out_length && |
10811 | strncmp(out_buff, canonical_buff, out_length) == 0); |
10812 | |
10813 | rc= mysql_stmt_fetch(stmt); |
10814 | check_execute(stmt, rc); |
10815 | strmov(canonical_buff + strlen(concat_arg0), "TWO" ); |
10816 | DIE_UNLESS(strlen(canonical_buff) == out_length && |
10817 | strncmp(out_buff, canonical_buff, out_length) == 0); |
10818 | if (!opt_silent) |
10819 | printf("Concat result: '%s'\n" , out_buff); |
10820 | |
10821 | rc= mysql_stmt_fetch(stmt); |
10822 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
10823 | |
10824 | mysql_stmt_close(stmt); |
10825 | |
10826 | stmt_text= "DROP TABLE IF EXISTS t1" ; |
10827 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
10828 | myquery(rc); |
10829 | } |
10830 | |
10831 | |
10832 | static void test_bug4026() |
10833 | { |
10834 | MYSQL_STMT *stmt; |
10835 | MYSQL_BIND my_bind[2]; |
10836 | MYSQL_TIME time_in, time_out; |
10837 | MYSQL_TIME datetime_in, datetime_out; |
10838 | const char *stmt_text; |
10839 | int rc; |
10840 | |
10841 | myheader("test_bug4026" ); |
10842 | |
10843 | /* Check that microseconds are inserted and selected successfully */ |
10844 | |
10845 | /* Create a statement handle and prepare it with select */ |
10846 | stmt= mysql_stmt_init(mysql); |
10847 | stmt_text= "SELECT ?, ?" ; |
10848 | |
10849 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
10850 | check_execute(stmt, rc); |
10851 | |
10852 | /* Bind input buffers */ |
10853 | bzero((char*) my_bind, sizeof(my_bind)); |
10854 | bzero((char*) &time_in, sizeof(time_in)); |
10855 | bzero((char*) &time_out, sizeof(time_out)); |
10856 | bzero((char*) &datetime_in, sizeof(datetime_in)); |
10857 | bzero((char*) &datetime_out, sizeof(datetime_out)); |
10858 | |
10859 | my_bind[0].buffer_type= MYSQL_TYPE_TIME; |
10860 | my_bind[0].buffer= (void *) &time_in; |
10861 | my_bind[1].buffer_type= MYSQL_TYPE_DATETIME; |
10862 | my_bind[1].buffer= (void *) &datetime_in; |
10863 | |
10864 | time_in.hour= 23; |
10865 | time_in.minute= 59; |
10866 | time_in.second= 59; |
10867 | time_in.second_part= 123456; |
10868 | /* |
10869 | This is not necessary, just to make DIE_UNLESS below work: this field |
10870 | is filled in when time is received from server |
10871 | */ |
10872 | time_in.time_type= MYSQL_TIMESTAMP_TIME; |
10873 | |
10874 | datetime_in= time_in; |
10875 | datetime_in.year= 2003; |
10876 | datetime_in.month= 12; |
10877 | datetime_in.day= 31; |
10878 | datetime_in.time_type= MYSQL_TIMESTAMP_DATETIME; |
10879 | |
10880 | mysql_stmt_bind_param(stmt, my_bind); |
10881 | |
10882 | /* Execute the select statement */ |
10883 | rc= mysql_stmt_execute(stmt); |
10884 | check_execute(stmt, rc); |
10885 | |
10886 | my_bind[0].buffer= (void *) &time_out; |
10887 | my_bind[1].buffer= (void *) &datetime_out; |
10888 | |
10889 | mysql_stmt_bind_result(stmt, my_bind); |
10890 | |
10891 | rc= mysql_stmt_fetch(stmt); |
10892 | DIE_UNLESS(rc == 0); |
10893 | if (!opt_silent) |
10894 | { |
10895 | printf("%d:%d:%d.%lu\n" , time_out.hour, time_out.minute, time_out.second, |
10896 | time_out.second_part); |
10897 | printf("%d-%d-%d %d:%d:%d.%lu\n" , datetime_out.year, datetime_out.month, |
10898 | datetime_out.day, datetime_out.hour, |
10899 | datetime_out.minute, datetime_out.second, |
10900 | datetime_out.second_part); |
10901 | } |
10902 | DIE_UNLESS(memcmp(&time_in, &time_out, sizeof(time_in)) == 0); |
10903 | DIE_UNLESS(memcmp(&datetime_in, &datetime_out, sizeof(datetime_in)) == 0); |
10904 | mysql_stmt_close(stmt); |
10905 | } |
10906 | |
10907 | |
10908 | static void test_bug4079() |
10909 | { |
10910 | MYSQL_STMT *stmt; |
10911 | MYSQL_BIND my_bind[1]; |
10912 | const char *stmt_text; |
10913 | uint32 res; |
10914 | int rc; |
10915 | |
10916 | myheader("test_bug4079" ); |
10917 | |
10918 | /* Create and fill table */ |
10919 | mysql_query(mysql, "DROP TABLE IF EXISTS t1" ); |
10920 | mysql_query(mysql, "CREATE TABLE t1 (a int)" ); |
10921 | mysql_query(mysql, "INSERT INTO t1 VALUES (1), (2)" ); |
10922 | |
10923 | /* Prepare erroneous statement */ |
10924 | stmt= mysql_stmt_init(mysql); |
10925 | stmt_text= "SELECT 1 < (SELECT a FROM t1)" ; |
10926 | |
10927 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
10928 | check_execute(stmt, rc); |
10929 | |
10930 | /* Execute the select statement */ |
10931 | rc= mysql_stmt_execute(stmt); |
10932 | check_execute(stmt, rc); |
10933 | |
10934 | /* Bind input buffers */ |
10935 | bzero((char*) my_bind, sizeof(my_bind)); |
10936 | |
10937 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
10938 | my_bind[0].buffer= (void *) &res; |
10939 | |
10940 | mysql_stmt_bind_result(stmt, my_bind); |
10941 | |
10942 | rc= mysql_stmt_fetch(stmt); |
10943 | DIE_UNLESS(rc != 0 && rc != MYSQL_NO_DATA); |
10944 | if (!opt_silent) |
10945 | printf("Got error from mysql_stmt_fetch (as expected):\n%s\n" , |
10946 | mysql_stmt_error(stmt)); |
10947 | /* buggy version of libmysql hanged up here */ |
10948 | mysql_stmt_close(stmt); |
10949 | } |
10950 | |
10951 | |
10952 | static void test_bug4236() |
10953 | { |
10954 | MYSQL_STMT *stmt; |
10955 | const char *stmt_text; |
10956 | int rc; |
10957 | MYSQL_STMT backup; |
10958 | |
10959 | myheader("test_bug4236" ); |
10960 | |
10961 | stmt= mysql_stmt_init(mysql); |
10962 | |
10963 | /* mysql_stmt_execute() of statement with statement id= 0 crashed server */ |
10964 | stmt_text= "SELECT 1" ; |
10965 | /* We need to prepare statement to pass by possible check in libmysql */ |
10966 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
10967 | check_execute(stmt, rc); |
10968 | /* Hack to check that server works OK if statement wasn't found */ |
10969 | backup.stmt_id= stmt->stmt_id; |
10970 | stmt->stmt_id= 0; |
10971 | rc= mysql_stmt_execute(stmt); |
10972 | DIE_UNLESS(rc); |
10973 | /* Restore original statement id to be able to reprepare it */ |
10974 | stmt->stmt_id= backup.stmt_id; |
10975 | |
10976 | mysql_stmt_close(stmt); |
10977 | } |
10978 | |
10979 | |
10980 | static void test_bug4030() |
10981 | { |
10982 | MYSQL_STMT *stmt; |
10983 | MYSQL_BIND my_bind[3]; |
10984 | MYSQL_TIME time_canonical, time_out; |
10985 | MYSQL_TIME date_canonical, date_out; |
10986 | MYSQL_TIME datetime_canonical, datetime_out; |
10987 | const char *stmt_text; |
10988 | int rc; |
10989 | |
10990 | myheader("test_bug4030" ); |
10991 | |
10992 | /* Check that microseconds are inserted and selected successfully */ |
10993 | |
10994 | /* Execute a query with time values in prepared mode */ |
10995 | stmt= mysql_stmt_init(mysql); |
10996 | stmt_text= "SELECT '23:59:59.123456', '2003-12-31', " |
10997 | "'2003-12-31 23:59:59.123456'" ; |
10998 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
10999 | check_execute(stmt, rc); |
11000 | rc= mysql_stmt_execute(stmt); |
11001 | check_execute(stmt, rc); |
11002 | |
11003 | /* Bind output buffers */ |
11004 | bzero((char*) my_bind, sizeof(my_bind)); |
11005 | bzero((char*) &time_canonical, sizeof(time_canonical)); |
11006 | bzero((char*) &time_out, sizeof(time_out)); |
11007 | bzero((char*) &date_canonical, sizeof(date_canonical)); |
11008 | bzero((char*) &date_out, sizeof(date_out)); |
11009 | bzero((char*) &datetime_canonical, sizeof(datetime_canonical)); |
11010 | bzero((char*) &datetime_out, sizeof(datetime_out)); |
11011 | |
11012 | my_bind[0].buffer_type= MYSQL_TYPE_TIME; |
11013 | my_bind[0].buffer= (void *) &time_out; |
11014 | my_bind[1].buffer_type= MYSQL_TYPE_DATE; |
11015 | my_bind[1].buffer= (void *) &date_out; |
11016 | my_bind[2].buffer_type= MYSQL_TYPE_DATETIME; |
11017 | my_bind[2].buffer= (void *) &datetime_out; |
11018 | |
11019 | time_canonical.hour= 23; |
11020 | time_canonical.minute= 59; |
11021 | time_canonical.second= 59; |
11022 | time_canonical.second_part= 123456; |
11023 | time_canonical.time_type= MYSQL_TIMESTAMP_TIME; |
11024 | |
11025 | date_canonical.year= 2003; |
11026 | date_canonical.month= 12; |
11027 | date_canonical.day= 31; |
11028 | date_canonical.time_type= MYSQL_TIMESTAMP_DATE; |
11029 | |
11030 | datetime_canonical= time_canonical; |
11031 | datetime_canonical.year= 2003; |
11032 | datetime_canonical.month= 12; |
11033 | datetime_canonical.day= 31; |
11034 | datetime_canonical.time_type= MYSQL_TIMESTAMP_DATETIME; |
11035 | |
11036 | mysql_stmt_bind_result(stmt, my_bind); |
11037 | |
11038 | rc= mysql_stmt_fetch(stmt); |
11039 | DIE_UNLESS(rc == 0); |
11040 | if (!opt_silent) |
11041 | { |
11042 | printf("%d:%d:%d.%lu\n" , time_out.hour, time_out.minute, time_out.second, |
11043 | time_out.second_part); |
11044 | printf("%d-%d-%d\n" , date_out.year, date_out.month, date_out.day); |
11045 | printf("%d-%d-%d %d:%d:%d.%lu\n" , datetime_out.year, datetime_out.month, |
11046 | datetime_out.day, datetime_out.hour, |
11047 | datetime_out.minute, datetime_out.second, |
11048 | datetime_out.second_part); |
11049 | } |
11050 | DIE_UNLESS(memcmp(&time_canonical, &time_out, sizeof(time_out)) == 0); |
11051 | DIE_UNLESS(memcmp(&date_canonical, &date_out, sizeof(date_out)) == 0); |
11052 | DIE_UNLESS(memcmp(&datetime_canonical, &datetime_out, sizeof(datetime_out)) == 0); |
11053 | mysql_stmt_close(stmt); |
11054 | } |
11055 | |
11056 | static void test_view() |
11057 | { |
11058 | MYSQL_STMT *stmt; |
11059 | int rc, i; |
11060 | MYSQL_BIND my_bind[1]; |
11061 | char str_data[50]; |
11062 | ulong length = 0L; |
11063 | long is_null = 0L; |
11064 | const char *query= |
11065 | "SELECT COUNT(*) FROM v1 WHERE SERVERNAME=?" ; |
11066 | |
11067 | myheader("test_view" ); |
11068 | |
11069 | rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,t2,t3,v1" ); |
11070 | myquery(rc); |
11071 | |
11072 | rc = mysql_query(mysql, "DROP VIEW IF EXISTS v1,t1,t2,t3" ); |
11073 | myquery(rc); |
11074 | rc= mysql_query(mysql,"CREATE TABLE t1 (" |
11075 | " SERVERGRP varchar(20) NOT NULL default '', " |
11076 | " DBINSTANCE varchar(20) NOT NULL default '', " |
11077 | " PRIMARY KEY (SERVERGRP)) " |
11078 | " CHARSET=latin1 collate=latin1_bin" ); |
11079 | myquery(rc); |
11080 | rc= mysql_query(mysql,"CREATE TABLE t2 (" |
11081 | " SERVERNAME varchar(20) NOT NULL, " |
11082 | " SERVERGRP varchar(20) NOT NULL, " |
11083 | " PRIMARY KEY (SERVERNAME)) " |
11084 | " CHARSET=latin1 COLLATE latin1_bin" ); |
11085 | myquery(rc); |
11086 | rc= mysql_query(mysql, |
11087 | "CREATE TABLE t3 (" |
11088 | " SERVERGRP varchar(20) BINARY NOT NULL, " |
11089 | " TABNAME varchar(30) NOT NULL, MAPSTATE char(1) NOT NULL, " |
11090 | " ACTSTATE char(1) NOT NULL , " |
11091 | " LOCAL_NAME varchar(30) NOT NULL, " |
11092 | " CHG_DATE varchar(8) NOT NULL default '00000000', " |
11093 | " CHG_TIME varchar(6) NOT NULL default '000000', " |
11094 | " MXUSER varchar(12) NOT NULL default '', " |
11095 | " PRIMARY KEY (SERVERGRP, TABNAME, MAPSTATE, ACTSTATE, " |
11096 | " LOCAL_NAME)) CHARSET=latin1 COLLATE latin1_bin" ); |
11097 | myquery(rc); |
11098 | rc= mysql_query(mysql,"CREATE VIEW v1 AS select sql_no_cache" |
11099 | " T0001.SERVERNAME AS SERVERNAME, T0003.TABNAME AS" |
11100 | " TABNAME,T0003.LOCAL_NAME AS LOCAL_NAME,T0002.DBINSTANCE AS" |
11101 | " DBINSTANCE from t2 T0001 join t1 T0002 join t3 T0003 where" |
11102 | " ((T0002.SERVERGRP = T0001.SERVERGRP) and" |
11103 | " (T0002.SERVERGRP = T0003.SERVERGRP)" |
11104 | " and (T0003.MAPSTATE = _latin1'A') and" |
11105 | " (T0003.ACTSTATE = _latin1' '))" ); |
11106 | myquery(rc); |
11107 | |
11108 | stmt= mysql_stmt_init(mysql); |
11109 | rc= mysql_stmt_prepare(stmt, query, strlen(query)); |
11110 | check_execute(stmt, rc); |
11111 | |
11112 | strmov(str_data, "TEST" ); |
11113 | bzero((char*) my_bind, sizeof(my_bind)); |
11114 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
11115 | my_bind[0].buffer= (char *)&str_data; |
11116 | my_bind[0].buffer_length= 50; |
11117 | my_bind[0].length= &length; |
11118 | length= 4; |
11119 | my_bind[0].is_null= (char*)&is_null; |
11120 | rc= mysql_stmt_bind_param(stmt, my_bind); |
11121 | check_execute(stmt,rc); |
11122 | |
11123 | for (i= 0; i < 3; i++) |
11124 | { |
11125 | rc= mysql_stmt_execute(stmt); |
11126 | check_execute(stmt, rc); |
11127 | rc= my_process_stmt_result(stmt); |
11128 | DIE_UNLESS(1 == rc); |
11129 | } |
11130 | mysql_stmt_close(stmt); |
11131 | |
11132 | rc= mysql_query(mysql, "DROP TABLE t1,t2,t3" ); |
11133 | myquery(rc); |
11134 | rc= mysql_query(mysql, "DROP VIEW v1" ); |
11135 | myquery(rc); |
11136 | } |
11137 | |
11138 | |
11139 | static void test_view_where() |
11140 | { |
11141 | MYSQL_STMT *stmt; |
11142 | int rc, i; |
11143 | const char *query= |
11144 | "select v1.c,v2.c from v1, v2" ; |
11145 | |
11146 | myheader("test_view_where" ); |
11147 | |
11148 | rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,v1,v2" ); |
11149 | myquery(rc); |
11150 | |
11151 | rc = mysql_query(mysql, "DROP VIEW IF EXISTS v1,v2,t1" ); |
11152 | myquery(rc); |
11153 | rc= mysql_query(mysql,"CREATE TABLE t1 (a int, b int)" ); |
11154 | myquery(rc); |
11155 | rc= mysql_query(mysql,"insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10)" ); |
11156 | myquery(rc); |
11157 | rc= mysql_query(mysql,"create view v1 (c) as select b from t1 where a<3" ); |
11158 | myquery(rc); |
11159 | rc= mysql_query(mysql,"create view v2 (c) as select b from t1 where a>=3" ); |
11160 | myquery(rc); |
11161 | |
11162 | stmt= mysql_stmt_init(mysql); |
11163 | rc= mysql_stmt_prepare(stmt, query, strlen(query)); |
11164 | check_execute(stmt, rc); |
11165 | |
11166 | for (i= 0; i < 3; i++) |
11167 | { |
11168 | rc= mysql_stmt_execute(stmt); |
11169 | check_execute(stmt, rc); |
11170 | rc= my_process_stmt_result(stmt); |
11171 | DIE_UNLESS(4 == rc); |
11172 | } |
11173 | mysql_stmt_close(stmt); |
11174 | |
11175 | rc= mysql_query(mysql, "DROP TABLE t1" ); |
11176 | myquery(rc); |
11177 | rc= mysql_query(mysql, "DROP VIEW v1, v2" ); |
11178 | myquery(rc); |
11179 | } |
11180 | |
11181 | |
11182 | static void test_view_2where() |
11183 | { |
11184 | MYSQL_STMT *stmt; |
11185 | int rc, i; |
11186 | MYSQL_BIND my_bind[8]; |
11187 | char parms[8][100]; |
11188 | ulong length[8]; |
11189 | const char *query= |
11190 | "select relid, report, handle, log_group, username, variant, type, " |
11191 | "version, erfdat, erftime, erfname, aedat, aetime, aename, dependvars, " |
11192 | "inactive from V_LTDX where mandt = ? and relid = ? and report = ? and " |
11193 | "handle = ? and log_group = ? and username in ( ? , ? ) and type = ?" ; |
11194 | |
11195 | myheader("test_view_2where" ); |
11196 | |
11197 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS LTDX" ); |
11198 | myquery(rc); |
11199 | rc= mysql_query(mysql, "DROP VIEW IF EXISTS V_LTDX" ); |
11200 | myquery(rc); |
11201 | rc= mysql_query(mysql, |
11202 | "CREATE TABLE LTDX (MANDT char(3) NOT NULL default '000', " |
11203 | " RELID char(2) NOT NULL, REPORT varchar(40) NOT NULL," |
11204 | " HANDLE varchar(4) NOT NULL, LOG_GROUP varchar(4) NOT NULL," |
11205 | " USERNAME varchar(12) NOT NULL," |
11206 | " VARIANT varchar(12) NOT NULL," |
11207 | " TYPE char(1) NOT NULL, SRTF2 int(11) NOT NULL," |
11208 | " VERSION varchar(6) NOT NULL default '000000'," |
11209 | " ERFDAT varchar(8) NOT NULL default '00000000'," |
11210 | " ERFTIME varchar(6) NOT NULL default '000000'," |
11211 | " ERFNAME varchar(12) NOT NULL," |
11212 | " AEDAT varchar(8) NOT NULL default '00000000'," |
11213 | " AETIME varchar(6) NOT NULL default '000000'," |
11214 | " AENAME varchar(12) NOT NULL," |
11215 | " DEPENDVARS varchar(10) NOT NULL," |
11216 | " INACTIVE char(1) NOT NULL, CLUSTR smallint(6) NOT NULL," |
11217 | " CLUSTD blob," |
11218 | " PRIMARY KEY (MANDT, RELID, REPORT, HANDLE, LOG_GROUP, " |
11219 | "USERNAME, VARIANT, TYPE, SRTF2))" |
11220 | " CHARSET=latin1 COLLATE latin1_bin" ); |
11221 | myquery(rc); |
11222 | rc= mysql_query(mysql, |
11223 | "CREATE VIEW V_LTDX AS select T0001.MANDT AS " |
11224 | " MANDT,T0001.RELID AS RELID,T0001.REPORT AS " |
11225 | " REPORT,T0001.HANDLE AS HANDLE,T0001.LOG_GROUP AS " |
11226 | " LOG_GROUP,T0001.USERNAME AS USERNAME,T0001.VARIANT AS " |
11227 | " VARIANT,T0001.TYPE AS TYPE,T0001.VERSION AS " |
11228 | " VERSION,T0001.ERFDAT AS ERFDAT,T0001.ERFTIME AS " |
11229 | " ERFTIME,T0001.ERFNAME AS ERFNAME,T0001.AEDAT AS " |
11230 | " AEDAT,T0001.AETIME AS AETIME,T0001.AENAME AS " |
11231 | " AENAME,T0001.DEPENDVARS AS DEPENDVARS,T0001.INACTIVE AS " |
11232 | " INACTIVE from LTDX T0001 where (T0001.SRTF2 = 0)" ); |
11233 | myquery(rc); |
11234 | bzero((char*) my_bind, sizeof(my_bind)); |
11235 | for (i=0; i < 8; i++) { |
11236 | strmov(parms[i], "1" ); |
11237 | my_bind[i].buffer_type = MYSQL_TYPE_VAR_STRING; |
11238 | my_bind[i].buffer = (char *)&parms[i]; |
11239 | my_bind[i].buffer_length = 100; |
11240 | my_bind[i].is_null = 0; |
11241 | my_bind[i].length = &length[i]; |
11242 | length[i] = 1; |
11243 | } |
11244 | stmt= mysql_stmt_init(mysql); |
11245 | rc= mysql_stmt_prepare(stmt, query, strlen(query)); |
11246 | check_execute(stmt, rc); |
11247 | |
11248 | rc= mysql_stmt_bind_param(stmt, my_bind); |
11249 | check_execute(stmt,rc); |
11250 | |
11251 | rc= mysql_stmt_execute(stmt); |
11252 | check_execute(stmt, rc); |
11253 | rc= my_process_stmt_result(stmt); |
11254 | DIE_UNLESS(0 == rc); |
11255 | |
11256 | mysql_stmt_close(stmt); |
11257 | |
11258 | rc= mysql_query(mysql, "DROP VIEW V_LTDX" ); |
11259 | myquery(rc); |
11260 | rc= mysql_query(mysql, "DROP TABLE LTDX" ); |
11261 | myquery(rc); |
11262 | } |
11263 | |
11264 | |
11265 | static void test_view_star() |
11266 | { |
11267 | MYSQL_STMT *stmt; |
11268 | int rc, i; |
11269 | MYSQL_BIND my_bind[8]; |
11270 | char parms[8][100]; |
11271 | ulong length[8]; |
11272 | const char *query= "SELECT * FROM vt1 WHERE a IN (?,?)" ; |
11273 | |
11274 | myheader("test_view_star" ); |
11275 | |
11276 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, vt1" ); |
11277 | myquery(rc); |
11278 | rc= mysql_query(mysql, "DROP VIEW IF EXISTS t1, vt1" ); |
11279 | myquery(rc); |
11280 | rc= mysql_query(mysql, "CREATE TABLE t1 (a int)" ); |
11281 | myquery(rc); |
11282 | rc= mysql_query(mysql, "CREATE VIEW vt1 AS SELECT a FROM t1" ); |
11283 | myquery(rc); |
11284 | bzero((char*) my_bind, sizeof(my_bind)); |
11285 | for (i= 0; i < 2; i++) { |
11286 | sprintf((char *)&parms[i], "%d" , i); |
11287 | my_bind[i].buffer_type = MYSQL_TYPE_VAR_STRING; |
11288 | my_bind[i].buffer = (char *)&parms[i]; |
11289 | my_bind[i].buffer_length = 100; |
11290 | my_bind[i].is_null = 0; |
11291 | my_bind[i].length = &length[i]; |
11292 | length[i] = 1; |
11293 | } |
11294 | |
11295 | stmt= mysql_stmt_init(mysql); |
11296 | rc= mysql_stmt_prepare(stmt, query, strlen(query)); |
11297 | check_execute(stmt, rc); |
11298 | |
11299 | rc= mysql_stmt_bind_param(stmt, my_bind); |
11300 | check_execute(stmt,rc); |
11301 | |
11302 | for (i= 0; i < 3; i++) |
11303 | { |
11304 | rc= mysql_stmt_execute(stmt); |
11305 | check_execute(stmt, rc); |
11306 | rc= my_process_stmt_result(stmt); |
11307 | DIE_UNLESS(0 == rc); |
11308 | } |
11309 | |
11310 | mysql_stmt_close(stmt); |
11311 | |
11312 | rc= mysql_query(mysql, "DROP TABLE t1" ); |
11313 | myquery(rc); |
11314 | rc= mysql_query(mysql, "DROP VIEW vt1" ); |
11315 | myquery(rc); |
11316 | } |
11317 | |
11318 | |
11319 | static void test_view_insert() |
11320 | { |
11321 | MYSQL_STMT *insert_stmt, *select_stmt; |
11322 | int rc, i; |
11323 | MYSQL_BIND my_bind[1]; |
11324 | int my_val = 0; |
11325 | ulong my_length = 0L; |
11326 | long my_null = 0L; |
11327 | const char *query= |
11328 | "insert into v1 values (?)" ; |
11329 | |
11330 | myheader("test_view_insert" ); |
11331 | |
11332 | rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,v1" ); |
11333 | myquery(rc); |
11334 | rc = mysql_query(mysql, "DROP VIEW IF EXISTS t1,v1" ); |
11335 | myquery(rc); |
11336 | |
11337 | rc= mysql_query(mysql,"create table t1 (a int, primary key (a))" ); |
11338 | myquery(rc); |
11339 | |
11340 | rc= mysql_query(mysql, "create view v1 as select a from t1 where a>=1" ); |
11341 | myquery(rc); |
11342 | |
11343 | insert_stmt= mysql_stmt_init(mysql); |
11344 | rc= mysql_stmt_prepare(insert_stmt, query, strlen(query)); |
11345 | check_execute(insert_stmt, rc); |
11346 | query= "select * from t1" ; |
11347 | select_stmt= mysql_stmt_init(mysql); |
11348 | rc= mysql_stmt_prepare(select_stmt, query, strlen(query)); |
11349 | check_execute(select_stmt, rc); |
11350 | |
11351 | bzero((char*) my_bind, sizeof(my_bind)); |
11352 | my_bind[0].buffer_type = MYSQL_TYPE_LONG; |
11353 | my_bind[0].buffer = (char *)&my_val; |
11354 | my_bind[0].length = &my_length; |
11355 | my_bind[0].is_null = (char*)&my_null; |
11356 | rc= mysql_stmt_bind_param(insert_stmt, my_bind); |
11357 | check_execute(insert_stmt, rc); |
11358 | |
11359 | for (i= 0; i < 3; i++) |
11360 | { |
11361 | int rowcount= 0; |
11362 | my_val= i; |
11363 | |
11364 | rc= mysql_stmt_execute(insert_stmt); |
11365 | check_execute(insert_stmt, rc); |
11366 | |
11367 | rc= mysql_stmt_execute(select_stmt); |
11368 | check_execute(select_stmt, rc); |
11369 | rowcount= (int)my_process_stmt_result(select_stmt); |
11370 | DIE_UNLESS((i+1) == rowcount); |
11371 | } |
11372 | mysql_stmt_close(insert_stmt); |
11373 | mysql_stmt_close(select_stmt); |
11374 | |
11375 | rc= mysql_query(mysql, "DROP VIEW v1" ); |
11376 | myquery(rc); |
11377 | rc= mysql_query(mysql, "DROP TABLE t1" ); |
11378 | myquery(rc); |
11379 | } |
11380 | |
11381 | |
11382 | static void test_left_join_view() |
11383 | { |
11384 | MYSQL_STMT *stmt; |
11385 | int rc, i; |
11386 | const char *query= |
11387 | "select t1.a, v1.x from t1 left join v1 on (t1.a= v1.x);" ; |
11388 | |
11389 | myheader("test_left_join_view" ); |
11390 | |
11391 | rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,v1" ); |
11392 | myquery(rc); |
11393 | |
11394 | rc = mysql_query(mysql, "DROP VIEW IF EXISTS v1,t1" ); |
11395 | myquery(rc); |
11396 | rc= mysql_query(mysql,"CREATE TABLE t1 (a int)" ); |
11397 | myquery(rc); |
11398 | rc= mysql_query(mysql,"insert into t1 values (1), (2), (3)" ); |
11399 | myquery(rc); |
11400 | rc= mysql_query(mysql,"create view v1 (x) as select a from t1 where a > 1" ); |
11401 | myquery(rc); |
11402 | stmt= mysql_stmt_init(mysql); |
11403 | rc= mysql_stmt_prepare(stmt, query, strlen(query)); |
11404 | check_execute(stmt, rc); |
11405 | |
11406 | for (i= 0; i < 3; i++) |
11407 | { |
11408 | rc= mysql_stmt_execute(stmt); |
11409 | check_execute(stmt, rc); |
11410 | rc= my_process_stmt_result(stmt); |
11411 | DIE_UNLESS(3 == rc); |
11412 | } |
11413 | mysql_stmt_close(stmt); |
11414 | |
11415 | rc= mysql_query(mysql, "DROP VIEW v1" ); |
11416 | myquery(rc); |
11417 | rc= mysql_query(mysql, "DROP TABLE t1" ); |
11418 | myquery(rc); |
11419 | } |
11420 | |
11421 | |
11422 | static void test_view_insert_fields() |
11423 | { |
11424 | MYSQL_STMT *stmt; |
11425 | char parm[11][1000]; |
11426 | ulong l[11]; |
11427 | int rc, i; |
11428 | MYSQL_BIND my_bind[11]; |
11429 | const char *query= "INSERT INTO `v1` ( `K1C4` ,`K2C4` ,`K3C4` ,`K4N4` ,`F1C4` ,`F2I4` ,`F3N5` ,`F7F8` ,`F6N4` ,`F5C8` ,`F9D8` ) VALUES( ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? )" ; |
11430 | |
11431 | myheader("test_view_insert_fields" ); |
11432 | |
11433 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, v1" ); |
11434 | myquery(rc); |
11435 | rc= mysql_query(mysql, "DROP VIEW IF EXISTS t1, v1" ); |
11436 | myquery(rc); |
11437 | rc= mysql_query(mysql, |
11438 | "CREATE TABLE t1 (K1C4 varchar(4) NOT NULL," |
11439 | "K2C4 varchar(4) NOT NULL, K3C4 varchar(4) NOT NULL," |
11440 | "K4N4 varchar(4) NOT NULL default '0000'," |
11441 | "F1C4 varchar(4) NOT NULL, F2I4 int(11) NOT NULL," |
11442 | "F3N5 varchar(5) NOT NULL default '00000'," |
11443 | "F4I4 int(11) NOT NULL default '0', F5C8 varchar(8) NOT NULL," |
11444 | "F6N4 varchar(4) NOT NULL default '0000'," |
11445 | "F7F8 double NOT NULL default '0'," |
11446 | "F8F8 double NOT NULL default '0'," |
11447 | "F9D8 decimal(8,2) NOT NULL default '0.00'," |
11448 | "PRIMARY KEY (K1C4,K2C4,K3C4,K4N4)) " |
11449 | "CHARSET=latin1 COLLATE latin1_bin" ); |
11450 | myquery(rc); |
11451 | rc= mysql_query(mysql, |
11452 | "CREATE VIEW v1 AS select sql_no_cache " |
11453 | " K1C4 AS K1C4, K2C4 AS K2C4, K3C4 AS K3C4, K4N4 AS K4N4, " |
11454 | " F1C4 AS F1C4, F2I4 AS F2I4, F3N5 AS F3N5," |
11455 | " F7F8 AS F7F8, F6N4 AS F6N4, F5C8 AS F5C8, F9D8 AS F9D8" |
11456 | " from t1 T0001" ); |
11457 | |
11458 | bzero((char*) my_bind, sizeof(my_bind)); |
11459 | for (i= 0; i < 11; i++) |
11460 | { |
11461 | l[i]= 20; |
11462 | my_bind[i].buffer_type= MYSQL_TYPE_STRING; |
11463 | my_bind[i].is_null= 0; |
11464 | my_bind[i].buffer= (char *)&parm[i]; |
11465 | |
11466 | strmov(parm[i], "1" ); |
11467 | my_bind[i].buffer_length= 2; |
11468 | my_bind[i].length= &l[i]; |
11469 | } |
11470 | stmt= mysql_stmt_init(mysql); |
11471 | rc= mysql_stmt_prepare(stmt, query, strlen(query)); |
11472 | check_execute(stmt, rc); |
11473 | rc= mysql_stmt_bind_param(stmt, my_bind); |
11474 | check_execute(stmt, rc); |
11475 | |
11476 | rc= mysql_stmt_execute(stmt); |
11477 | check_execute(stmt, rc); |
11478 | mysql_stmt_close(stmt); |
11479 | |
11480 | query= "select * from t1" ; |
11481 | stmt= mysql_stmt_init(mysql); |
11482 | rc= mysql_stmt_prepare(stmt, query, strlen(query)); |
11483 | check_execute(stmt, rc); |
11484 | rc= mysql_stmt_execute(stmt); |
11485 | check_execute(stmt, rc); |
11486 | rc= my_process_stmt_result(stmt); |
11487 | DIE_UNLESS(1 == rc); |
11488 | |
11489 | mysql_stmt_close(stmt); |
11490 | rc= mysql_query(mysql, "DROP VIEW v1" ); |
11491 | myquery(rc); |
11492 | rc= mysql_query(mysql, "DROP TABLE t1" ); |
11493 | myquery(rc); |
11494 | |
11495 | } |
11496 | |
11497 | static void test_bug5126() |
11498 | { |
11499 | MYSQL_STMT *stmt; |
11500 | MYSQL_BIND my_bind[2]; |
11501 | int32 c1, c2; |
11502 | const char *stmt_text; |
11503 | int rc; |
11504 | |
11505 | myheader("test_bug5126" ); |
11506 | |
11507 | stmt_text= "DROP TABLE IF EXISTS t1" ; |
11508 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
11509 | myquery(rc); |
11510 | |
11511 | stmt_text= "CREATE TABLE t1 (a mediumint, b int)" ; |
11512 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
11513 | myquery(rc); |
11514 | |
11515 | stmt_text= "INSERT INTO t1 VALUES (8386608, 1)" ; |
11516 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
11517 | myquery(rc); |
11518 | |
11519 | stmt= mysql_stmt_init(mysql); |
11520 | stmt_text= "SELECT a, b FROM t1" ; |
11521 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
11522 | check_execute(stmt, rc); |
11523 | rc= mysql_stmt_execute(stmt); |
11524 | check_execute(stmt, rc); |
11525 | |
11526 | /* Bind output buffers */ |
11527 | bzero((char*) my_bind, sizeof(my_bind)); |
11528 | |
11529 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
11530 | my_bind[0].buffer= &c1; |
11531 | my_bind[1].buffer_type= MYSQL_TYPE_LONG; |
11532 | my_bind[1].buffer= &c2; |
11533 | |
11534 | mysql_stmt_bind_result(stmt, my_bind); |
11535 | |
11536 | rc= mysql_stmt_fetch(stmt); |
11537 | DIE_UNLESS(rc == 0); |
11538 | DIE_UNLESS(c1 == 8386608 && c2 == 1); |
11539 | if (!opt_silent) |
11540 | printf("%ld, %ld\n" , (long) c1, (long) c2); |
11541 | mysql_stmt_close(stmt); |
11542 | } |
11543 | |
11544 | |
11545 | static void test_bug4231() |
11546 | { |
11547 | MYSQL_STMT *stmt; |
11548 | MYSQL_BIND my_bind[2]; |
11549 | MYSQL_TIME tm[2]; |
11550 | const char *stmt_text; |
11551 | int rc; |
11552 | |
11553 | myheader("test_bug4231" ); |
11554 | |
11555 | stmt_text= "DROP TABLE IF EXISTS t1" ; |
11556 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
11557 | myquery(rc); |
11558 | |
11559 | stmt_text= "CREATE TABLE t1 (a int)" ; |
11560 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
11561 | myquery(rc); |
11562 | |
11563 | stmt_text= "INSERT INTO t1 VALUES (1)" ; |
11564 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
11565 | myquery(rc); |
11566 | |
11567 | stmt= mysql_stmt_init(mysql); |
11568 | stmt_text= "SELECT a FROM t1 WHERE ? = ?" ; |
11569 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
11570 | check_execute(stmt, rc); |
11571 | |
11572 | /* Bind input buffers */ |
11573 | bzero((char*) my_bind, sizeof(my_bind)); |
11574 | bzero((char*) tm, sizeof(tm)); |
11575 | |
11576 | my_bind[0].buffer_type= MYSQL_TYPE_DATE; |
11577 | my_bind[0].buffer= &tm[0]; |
11578 | my_bind[1].buffer_type= MYSQL_TYPE_DATE; |
11579 | my_bind[1].buffer= &tm[1]; |
11580 | |
11581 | mysql_stmt_bind_param(stmt, my_bind); |
11582 | check_execute(stmt, rc); |
11583 | |
11584 | /* |
11585 | First set server-side params to some non-zero non-equal values: |
11586 | then we will check that they are not used when client sends |
11587 | new (zero) times. |
11588 | */ |
11589 | tm[0].time_type = MYSQL_TIMESTAMP_DATE; |
11590 | tm[0].year = 2000; |
11591 | tm[0].month = 1; |
11592 | tm[0].day = 1; |
11593 | tm[1]= tm[0]; |
11594 | --tm[1].year; /* tm[0] != tm[1] */ |
11595 | |
11596 | rc= mysql_stmt_execute(stmt); |
11597 | check_execute(stmt, rc); |
11598 | |
11599 | rc= mysql_stmt_fetch(stmt); |
11600 | |
11601 | /* binds are unequal, no rows should be returned */ |
11602 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
11603 | |
11604 | /* Set one of the dates to zero */ |
11605 | tm[0].year= tm[0].month= tm[0].day= 0; |
11606 | tm[1]= tm[0]; |
11607 | mysql_stmt_execute(stmt); |
11608 | rc= mysql_stmt_fetch(stmt); |
11609 | DIE_UNLESS(rc == 0); |
11610 | |
11611 | mysql_stmt_close(stmt); |
11612 | stmt_text= "DROP TABLE t1" ; |
11613 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
11614 | myquery(rc); |
11615 | } |
11616 | |
11617 | |
11618 | static void test_bug5399() |
11619 | { |
11620 | /* |
11621 | Ascii 97 is 'a', which gets mapped to Ascii 65 'A' unless internal |
11622 | statement id hash in the server uses binary collation. |
11623 | */ |
11624 | #define NUM_OF_USED_STMT 97 |
11625 | MYSQL_STMT *stmt_list[NUM_OF_USED_STMT]; |
11626 | MYSQL_STMT **stmt; |
11627 | MYSQL_BIND my_bind[1]; |
11628 | char buff[600]; |
11629 | int rc; |
11630 | int32 no; |
11631 | |
11632 | myheader("test_bug5399" ); |
11633 | |
11634 | bzero((char*) my_bind, sizeof(my_bind)); |
11635 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
11636 | my_bind[0].buffer= &no; |
11637 | |
11638 | for (stmt= stmt_list; stmt != stmt_list + NUM_OF_USED_STMT; ++stmt) |
11639 | { |
11640 | sprintf(buff, "select %d" , (int) (stmt - stmt_list)); |
11641 | *stmt= mysql_stmt_init(mysql); |
11642 | rc= mysql_stmt_prepare(*stmt, buff, strlen(buff)); |
11643 | check_execute(*stmt, rc); |
11644 | mysql_stmt_bind_result(*stmt, my_bind); |
11645 | } |
11646 | if (!opt_silent) |
11647 | printf("%d statements prepared.\n" , NUM_OF_USED_STMT); |
11648 | |
11649 | for (stmt= stmt_list; stmt != stmt_list + NUM_OF_USED_STMT; ++stmt) |
11650 | { |
11651 | rc= mysql_stmt_execute(*stmt); |
11652 | check_execute(*stmt, rc); |
11653 | rc= mysql_stmt_store_result(*stmt); |
11654 | check_execute(*stmt, rc); |
11655 | rc= mysql_stmt_fetch(*stmt); |
11656 | DIE_UNLESS(rc == 0); |
11657 | DIE_UNLESS((int32) (stmt - stmt_list) == no); |
11658 | } |
11659 | |
11660 | for (stmt= stmt_list; stmt != stmt_list + NUM_OF_USED_STMT; ++stmt) |
11661 | mysql_stmt_close(*stmt); |
11662 | #undef NUM_OF_USED_STMT |
11663 | } |
11664 | |
11665 | |
11666 | static void test_bug5194() |
11667 | { |
11668 | MYSQL_STMT *stmt; |
11669 | MYSQL_BIND *my_bind; |
11670 | char *query; |
11671 | char *param_str; |
11672 | int param_str_length; |
11673 | const char *stmt_text; |
11674 | int rc; |
11675 | float float_array[250] = |
11676 | { |
11677 | 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, |
11678 | 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, |
11679 | 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, |
11680 | 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, |
11681 | 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, |
11682 | 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, |
11683 | 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, |
11684 | 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, |
11685 | 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, |
11686 | 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, |
11687 | 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, |
11688 | 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, |
11689 | 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, |
11690 | 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, |
11691 | 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, |
11692 | 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, |
11693 | 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, |
11694 | 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, |
11695 | 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, |
11696 | 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, |
11697 | 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, |
11698 | 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, |
11699 | 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, |
11700 | 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, |
11701 | 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25 |
11702 | }; |
11703 | float *fa_ptr= float_array; |
11704 | /* Number of columns per row */ |
11705 | const int COLUMN_COUNT= sizeof(float_array)/sizeof(*float_array); |
11706 | /* Number of rows per bulk insert to start with */ |
11707 | const int MIN_ROWS_PER_INSERT= 262; |
11708 | /* Max number of rows per bulk insert to end with */ |
11709 | const int MAX_ROWS_PER_INSERT= 300; |
11710 | const int MAX_PARAM_COUNT= COLUMN_COUNT*MAX_ROWS_PER_INSERT; |
11711 | const char *query_template= "insert into t1 values %s" ; |
11712 | const int CHARS_PER_PARAM= 5; /* space needed to place ", ?" in the query */ |
11713 | const int uint16_max= 65535; |
11714 | int nrows, i; |
11715 | |
11716 | myheader("test_bug5194" ); |
11717 | |
11718 | stmt_text= "drop table if exists t1" ; |
11719 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
11720 | |
11721 | stmt_text= "create table if not exists t1" |
11722 | "(c1 float, c2 float, c3 float, c4 float, c5 float, c6 float, " |
11723 | "c7 float, c8 float, c9 float, c10 float, c11 float, c12 float, " |
11724 | "c13 float, c14 float, c15 float, c16 float, c17 float, c18 float, " |
11725 | "c19 float, c20 float, c21 float, c22 float, c23 float, c24 float, " |
11726 | "c25 float, c26 float, c27 float, c28 float, c29 float, c30 float, " |
11727 | "c31 float, c32 float, c33 float, c34 float, c35 float, c36 float, " |
11728 | "c37 float, c38 float, c39 float, c40 float, c41 float, c42 float, " |
11729 | "c43 float, c44 float, c45 float, c46 float, c47 float, c48 float, " |
11730 | "c49 float, c50 float, c51 float, c52 float, c53 float, c54 float, " |
11731 | "c55 float, c56 float, c57 float, c58 float, c59 float, c60 float, " |
11732 | "c61 float, c62 float, c63 float, c64 float, c65 float, c66 float, " |
11733 | "c67 float, c68 float, c69 float, c70 float, c71 float, c72 float, " |
11734 | "c73 float, c74 float, c75 float, c76 float, c77 float, c78 float, " |
11735 | "c79 float, c80 float, c81 float, c82 float, c83 float, c84 float, " |
11736 | "c85 float, c86 float, c87 float, c88 float, c89 float, c90 float, " |
11737 | "c91 float, c92 float, c93 float, c94 float, c95 float, c96 float, " |
11738 | "c97 float, c98 float, c99 float, c100 float, c101 float, c102 float, " |
11739 | "c103 float, c104 float, c105 float, c106 float, c107 float, c108 float, " |
11740 | "c109 float, c110 float, c111 float, c112 float, c113 float, c114 float, " |
11741 | "c115 float, c116 float, c117 float, c118 float, c119 float, c120 float, " |
11742 | "c121 float, c122 float, c123 float, c124 float, c125 float, c126 float, " |
11743 | "c127 float, c128 float, c129 float, c130 float, c131 float, c132 float, " |
11744 | "c133 float, c134 float, c135 float, c136 float, c137 float, c138 float, " |
11745 | "c139 float, c140 float, c141 float, c142 float, c143 float, c144 float, " |
11746 | "c145 float, c146 float, c147 float, c148 float, c149 float, c150 float, " |
11747 | "c151 float, c152 float, c153 float, c154 float, c155 float, c156 float, " |
11748 | "c157 float, c158 float, c159 float, c160 float, c161 float, c162 float, " |
11749 | "c163 float, c164 float, c165 float, c166 float, c167 float, c168 float, " |
11750 | "c169 float, c170 float, c171 float, c172 float, c173 float, c174 float, " |
11751 | "c175 float, c176 float, c177 float, c178 float, c179 float, c180 float, " |
11752 | "c181 float, c182 float, c183 float, c184 float, c185 float, c186 float, " |
11753 | "c187 float, c188 float, c189 float, c190 float, c191 float, c192 float, " |
11754 | "c193 float, c194 float, c195 float, c196 float, c197 float, c198 float, " |
11755 | "c199 float, c200 float, c201 float, c202 float, c203 float, c204 float, " |
11756 | "c205 float, c206 float, c207 float, c208 float, c209 float, c210 float, " |
11757 | "c211 float, c212 float, c213 float, c214 float, c215 float, c216 float, " |
11758 | "c217 float, c218 float, c219 float, c220 float, c221 float, c222 float, " |
11759 | "c223 float, c224 float, c225 float, c226 float, c227 float, c228 float, " |
11760 | "c229 float, c230 float, c231 float, c232 float, c233 float, c234 float, " |
11761 | "c235 float, c236 float, c237 float, c238 float, c239 float, c240 float, " |
11762 | "c241 float, c242 float, c243 float, c244 float, c245 float, c246 float, " |
11763 | "c247 float, c248 float, c249 float, c250 float)" ; |
11764 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
11765 | myquery(rc); |
11766 | |
11767 | my_bind= (MYSQL_BIND*) malloc(MAX_PARAM_COUNT * sizeof(MYSQL_BIND)); |
11768 | query= (char*) malloc(strlen(query_template) + |
11769 | MAX_PARAM_COUNT * CHARS_PER_PARAM + 1); |
11770 | param_str= (char*) malloc(COLUMN_COUNT * CHARS_PER_PARAM); |
11771 | |
11772 | if (my_bind == 0 || query == 0 || param_str == 0) |
11773 | { |
11774 | fprintf(stderr, "Can't allocate enough memory for query structs\n" ); |
11775 | if (my_bind) |
11776 | free(my_bind); |
11777 | if (query) |
11778 | free(query); |
11779 | if (param_str) |
11780 | free(param_str); |
11781 | return; |
11782 | } |
11783 | |
11784 | stmt= mysql_stmt_init(mysql); |
11785 | |
11786 | /* setup a template for one row of parameters */ |
11787 | sprintf(param_str, "(" ); |
11788 | for (i= 1; i < COLUMN_COUNT; ++i) |
11789 | strcat(param_str, "?, " ); |
11790 | strcat(param_str, "?)" ); |
11791 | param_str_length= strlen(param_str); |
11792 | |
11793 | /* setup bind array */ |
11794 | bzero((char*) my_bind, MAX_PARAM_COUNT * sizeof(MYSQL_BIND)); |
11795 | for (i= 0; i < MAX_PARAM_COUNT; ++i) |
11796 | { |
11797 | my_bind[i].buffer_type= MYSQL_TYPE_FLOAT; |
11798 | my_bind[i].buffer= fa_ptr; |
11799 | if (++fa_ptr == float_array + COLUMN_COUNT) |
11800 | fa_ptr= float_array; |
11801 | } |
11802 | |
11803 | /* |
11804 | Test each number of rows per bulk insert, so that we can see where |
11805 | MySQL fails. |
11806 | */ |
11807 | for (nrows= MIN_ROWS_PER_INSERT; nrows <= MAX_ROWS_PER_INSERT; ++nrows) |
11808 | { |
11809 | char *query_ptr; |
11810 | /* Create statement text for current number of rows */ |
11811 | sprintf(query, query_template, param_str); |
11812 | query_ptr= query + strlen(query); |
11813 | for (i= 1; i < nrows; ++i) |
11814 | { |
11815 | memcpy(query_ptr, ", " , 2); |
11816 | query_ptr+= 2; |
11817 | memcpy(query_ptr, param_str, param_str_length); |
11818 | query_ptr+= param_str_length; |
11819 | } |
11820 | *query_ptr= '\0'; |
11821 | |
11822 | rc= mysql_stmt_prepare(stmt, query, (ulong)(query_ptr - query)); |
11823 | if (rc && nrows * COLUMN_COUNT > uint16_max) |
11824 | { |
11825 | if (!opt_silent) |
11826 | printf("Failed to prepare a statement with %d placeholders " |
11827 | "(as expected).\n" , nrows * COLUMN_COUNT); |
11828 | break; |
11829 | } |
11830 | else |
11831 | check_execute(stmt, rc); |
11832 | |
11833 | if (!opt_silent) |
11834 | printf("Insert: query length= %d, row count= %d, param count= %lu\n" , |
11835 | (int) strlen(query), nrows, mysql_stmt_param_count(stmt)); |
11836 | |
11837 | /* bind the parameter array and execute the query */ |
11838 | rc= mysql_stmt_bind_param(stmt, my_bind); |
11839 | check_execute(stmt, rc); |
11840 | |
11841 | rc= mysql_stmt_execute(stmt); |
11842 | check_execute(stmt, rc); |
11843 | mysql_stmt_reset(stmt); |
11844 | } |
11845 | |
11846 | mysql_stmt_close(stmt); |
11847 | free(my_bind); |
11848 | free(query); |
11849 | free(param_str); |
11850 | stmt_text= "drop table t1" ; |
11851 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
11852 | myquery(rc); |
11853 | } |
11854 | |
11855 | |
11856 | static void test_bug5315() |
11857 | { |
11858 | MYSQL_STMT *stmt; |
11859 | const char *stmt_text; |
11860 | int rc; |
11861 | |
11862 | myheader("test_bug5315" ); |
11863 | |
11864 | stmt_text= "SELECT 1" ; |
11865 | stmt= mysql_stmt_init(mysql); |
11866 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
11867 | DIE_UNLESS(rc == 0); |
11868 | if (!opt_silent) |
11869 | printf("Executing mysql_change_user\n" ); |
11870 | mysql_change_user(mysql, opt_user, opt_password, current_db); |
11871 | if (!opt_silent) |
11872 | printf("Executing mysql_stmt_execute\n" ); |
11873 | rc= mysql_stmt_execute(stmt); |
11874 | DIE_UNLESS(rc != 0); |
11875 | if (rc) |
11876 | { |
11877 | if (!opt_silent) |
11878 | printf("Got error (as expected): '%s'\n" , mysql_stmt_error(stmt)); |
11879 | } |
11880 | /* check that connection is OK */ |
11881 | if (!opt_silent) |
11882 | printf("Executing mysql_stmt_close\n" ); |
11883 | mysql_stmt_close(stmt); |
11884 | if (!opt_silent) |
11885 | printf("Executing mysql_stmt_init\n" ); |
11886 | stmt= mysql_stmt_init(mysql); |
11887 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
11888 | DIE_UNLESS(rc == 0); |
11889 | rc= mysql_stmt_execute(stmt); |
11890 | DIE_UNLESS(rc == 0); |
11891 | mysql_stmt_close(stmt); |
11892 | } |
11893 | |
11894 | |
11895 | static void test_bug6049() |
11896 | { |
11897 | MYSQL_STMT *stmt; |
11898 | MYSQL_BIND my_bind[1]; |
11899 | MYSQL_RES *res; |
11900 | MYSQL_ROW row; |
11901 | const char *stmt_text; |
11902 | char buffer[30]; |
11903 | ulong length; |
11904 | int rc; |
11905 | |
11906 | myheader("test_bug6049" ); |
11907 | |
11908 | stmt_text= "SELECT MAKETIME(-25, 12, 12)" ; |
11909 | |
11910 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
11911 | myquery(rc); |
11912 | res= mysql_store_result(mysql); |
11913 | row= mysql_fetch_row(res); |
11914 | |
11915 | stmt= mysql_stmt_init(mysql); |
11916 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
11917 | check_execute(stmt, rc); |
11918 | rc= mysql_stmt_execute(stmt); |
11919 | check_execute(stmt, rc); |
11920 | |
11921 | bzero((char*) my_bind, sizeof(my_bind)); |
11922 | my_bind[0].buffer_type = MYSQL_TYPE_STRING; |
11923 | my_bind[0].buffer = &buffer; |
11924 | my_bind[0].buffer_length = sizeof(buffer); |
11925 | my_bind[0].length = &length; |
11926 | |
11927 | mysql_stmt_bind_result(stmt, my_bind); |
11928 | rc= mysql_stmt_fetch(stmt); |
11929 | DIE_UNLESS(rc == 0); |
11930 | |
11931 | if (!opt_silent) |
11932 | { |
11933 | printf("Result from query: %s\n" , row[0]); |
11934 | printf("Result from prepared statement: %s\n" , (char*) buffer); |
11935 | } |
11936 | |
11937 | DIE_UNLESS(strcmp(row[0], (char*) buffer) == 0); |
11938 | |
11939 | mysql_free_result(res); |
11940 | mysql_stmt_close(stmt); |
11941 | } |
11942 | |
11943 | |
11944 | static void test_bug6058() |
11945 | { |
11946 | MYSQL_STMT *stmt; |
11947 | MYSQL_BIND my_bind[1]; |
11948 | MYSQL_RES *res; |
11949 | MYSQL_ROW row; |
11950 | const char *stmt_text; |
11951 | char buffer[30]; |
11952 | ulong length; |
11953 | int rc; |
11954 | |
11955 | myheader("test_bug6058" ); |
11956 | |
11957 | rc= mysql_query(mysql, "SET SQL_MODE=''" ); |
11958 | myquery(rc); |
11959 | |
11960 | stmt_text= "SELECT CAST('0000-00-00' AS DATE)" ; |
11961 | |
11962 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
11963 | myquery(rc); |
11964 | res= mysql_store_result(mysql); |
11965 | row= mysql_fetch_row(res); |
11966 | |
11967 | stmt= mysql_stmt_init(mysql); |
11968 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
11969 | check_execute(stmt, rc); |
11970 | rc= mysql_stmt_execute(stmt); |
11971 | check_execute(stmt, rc); |
11972 | |
11973 | bzero((char*) my_bind, sizeof(my_bind)); |
11974 | my_bind[0].buffer_type = MYSQL_TYPE_STRING; |
11975 | my_bind[0].buffer = &buffer; |
11976 | my_bind[0].buffer_length = sizeof(buffer); |
11977 | my_bind[0].length = &length; |
11978 | |
11979 | mysql_stmt_bind_result(stmt, my_bind); |
11980 | rc= mysql_stmt_fetch(stmt); |
11981 | DIE_UNLESS(rc == 0); |
11982 | |
11983 | if (!opt_silent) |
11984 | { |
11985 | printf("Result from query: %s\n" , row[0]); |
11986 | printf("Result from prepared statement: %s\n" , buffer); |
11987 | } |
11988 | |
11989 | DIE_UNLESS(strcmp(row[0], buffer) == 0); |
11990 | |
11991 | mysql_free_result(res); |
11992 | mysql_stmt_close(stmt); |
11993 | } |
11994 | |
11995 | |
11996 | static void test_bug6059() |
11997 | { |
11998 | MYSQL_STMT *stmt; |
11999 | const char *stmt_text; |
12000 | |
12001 | myheader("test_bug6059" ); |
12002 | |
12003 | stmt_text= "SELECT 'foo' INTO OUTFILE 'x.3'" ; |
12004 | |
12005 | stmt= mysql_stmt_init(mysql); |
12006 | (void) mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
12007 | DIE_UNLESS(mysql_stmt_field_count(stmt) == 0); |
12008 | mysql_stmt_close(stmt); |
12009 | } |
12010 | |
12011 | |
12012 | static void test_bug6046() |
12013 | { |
12014 | MYSQL_STMT *stmt; |
12015 | const char *stmt_text; |
12016 | int rc; |
12017 | short b= 1; |
12018 | MYSQL_BIND my_bind[1]; |
12019 | |
12020 | myheader("test_bug6046" ); |
12021 | |
12022 | stmt_text= "DROP TABLE IF EXISTS t1" ; |
12023 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
12024 | myquery(rc); |
12025 | stmt_text= "CREATE TABLE t1 (a int, b int)" ; |
12026 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
12027 | myquery(rc); |
12028 | stmt_text= "INSERT INTO t1 VALUES (1,1),(2,2),(3,1),(4,2)" ; |
12029 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
12030 | myquery(rc); |
12031 | |
12032 | stmt= mysql_stmt_init(mysql); |
12033 | |
12034 | stmt_text= "SELECT t1.a FROM t1 NATURAL JOIN t1 as X1 " |
12035 | "WHERE t1.b > ? ORDER BY t1.a" ; |
12036 | |
12037 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
12038 | check_execute(stmt, rc); |
12039 | |
12040 | b= 1; |
12041 | bzero((char*) my_bind, sizeof(my_bind)); |
12042 | my_bind[0].buffer= &b; |
12043 | my_bind[0].buffer_type= MYSQL_TYPE_SHORT; |
12044 | |
12045 | mysql_stmt_bind_param(stmt, my_bind); |
12046 | |
12047 | rc= mysql_stmt_execute(stmt); |
12048 | check_execute(stmt, rc); |
12049 | mysql_stmt_store_result(stmt); |
12050 | |
12051 | rc= mysql_stmt_execute(stmt); |
12052 | check_execute(stmt, rc); |
12053 | |
12054 | mysql_stmt_close(stmt); |
12055 | } |
12056 | |
12057 | |
12058 | |
12059 | static void test_basic_cursors() |
12060 | { |
12061 | const char *basic_tables[]= |
12062 | { |
12063 | "DROP TABLE IF EXISTS t1, t2" , |
12064 | |
12065 | "CREATE TABLE t1 " |
12066 | "(id INTEGER NOT NULL PRIMARY KEY, " |
12067 | " name VARCHAR(20) NOT NULL)" , |
12068 | |
12069 | "INSERT INTO t1 (id, name) VALUES " |
12070 | " (2, 'Ja'), (3, 'Ede'), " |
12071 | " (4, 'Haag'), (5, 'Kabul'), " |
12072 | " (6, 'Almere'), (7, 'Utrecht'), " |
12073 | " (8, 'Qandahar'), (9, 'Amsterdam'), " |
12074 | " (10, 'Amersfoort'), (11, 'Constantine')" , |
12075 | |
12076 | "CREATE TABLE t2 " |
12077 | "(id INTEGER NOT NULL PRIMARY KEY, " |
12078 | " name VARCHAR(20) NOT NULL)" , |
12079 | |
12080 | "INSERT INTO t2 (id, name) VALUES " |
12081 | " (4, 'Guam'), (5, 'Aruba'), " |
12082 | " (6, 'Angola'), (7, 'Albania'), " |
12083 | " (8, 'Anguilla'), (9, 'Argentina'), " |
12084 | " (10, 'Azerbaijan'), (11, 'Afghanistan'), " |
12085 | " (12, 'Burkina Faso'), (13, 'Faroe Islands')" |
12086 | }; |
12087 | const char *queries[]= |
12088 | { |
12089 | "SELECT * FROM t1" , |
12090 | "SELECT * FROM t2" |
12091 | }; |
12092 | |
12093 | DBUG_ENTER("test_basic_cursors" ); |
12094 | myheader("test_basic_cursors" ); |
12095 | |
12096 | fill_tables(basic_tables, sizeof(basic_tables)/sizeof(*basic_tables)); |
12097 | |
12098 | fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH); |
12099 | fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT); |
12100 | DBUG_VOID_RETURN; |
12101 | } |
12102 | |
12103 | |
12104 | static void test_cursors_with_union() |
12105 | { |
12106 | const char *queries[]= |
12107 | { |
12108 | "SELECT t1.name FROM t1 UNION SELECT t2.name FROM t2" , |
12109 | "SELECT t1.id FROM t1 WHERE t1.id < 5" |
12110 | }; |
12111 | myheader("test_cursors_with_union" ); |
12112 | fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH); |
12113 | fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT); |
12114 | } |
12115 | |
12116 | |
12117 | static void test_cursors_with_procedure() |
12118 | { |
12119 | const char *queries[]= |
12120 | { |
12121 | "SELECT * FROM t1 procedure analyse()" |
12122 | }; |
12123 | myheader("test_cursors_with_procedure" ); |
12124 | fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH); |
12125 | fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT); |
12126 | } |
12127 | |
12128 | |
12129 | /* |
12130 | Altough mysql_create_db(), mysql_rm_db() are deprecated since 4.0 they |
12131 | should not crash server and should not hang in case of errors. |
12132 | |
12133 | Since those functions can't be seen in modern API (unless client library |
12134 | was compiled with USE_OLD_FUNCTIONS define) we use simple_command() macro. |
12135 | */ |
12136 | static void test_bug6081() |
12137 | { |
12138 | int rc; |
12139 | myheader("test_bug6081" ); |
12140 | |
12141 | rc= simple_command(mysql, COM_DROP_DB, (uchar*) current_db, |
12142 | (ulong)strlen(current_db), 0); |
12143 | if (rc == 0 && mysql_errno(mysql) != ER_UNKNOWN_COM_ERROR) |
12144 | { |
12145 | myerror(NULL); /* purecov: inspected */ |
12146 | die(__FILE__, __LINE__, "COM_DROP_DB failed" ); /* purecov: inspected */ |
12147 | } |
12148 | rc= simple_command(mysql, COM_DROP_DB, (uchar*) current_db, |
12149 | (ulong)strlen(current_db), 0); |
12150 | myquery_r(rc); |
12151 | rc= simple_command(mysql, COM_CREATE_DB, (uchar*) current_db, |
12152 | (ulong)strlen(current_db), 0); |
12153 | if (rc == 0 && mysql_errno(mysql) != ER_UNKNOWN_COM_ERROR) |
12154 | { |
12155 | myerror(NULL); /* purecov: inspected */ |
12156 | die(__FILE__, __LINE__, "COM_CREATE_DB failed" ); /* purecov: inspected */ |
12157 | } |
12158 | rc= simple_command(mysql, COM_CREATE_DB, (uchar*) current_db, |
12159 | (ulong)strlen(current_db), 0); |
12160 | myquery_r(rc); |
12161 | rc= mysql_select_db(mysql, current_db); |
12162 | myquery(rc); |
12163 | } |
12164 | |
12165 | |
12166 | static void test_bug6096() |
12167 | { |
12168 | MYSQL_STMT *stmt; |
12169 | MYSQL_RES *query_result, *stmt_metadata; |
12170 | const char *stmt_text; |
12171 | MYSQL_BIND my_bind[12]; |
12172 | MYSQL_FIELD *query_field_list, *stmt_field_list; |
12173 | ulong query_field_count, stmt_field_count; |
12174 | int rc; |
12175 | my_bool update_max_length= TRUE; |
12176 | uint i; |
12177 | |
12178 | myheader("test_bug6096" ); |
12179 | |
12180 | stmt_text= "drop table if exists t1" ; |
12181 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
12182 | myquery(rc); |
12183 | |
12184 | mysql_query(mysql, "set sql_mode=''" ); |
12185 | stmt_text= "create table t1 (c_tinyint tinyint, c_smallint smallint, " |
12186 | " c_mediumint mediumint, c_int int, " |
12187 | " c_bigint bigint, c_float float, " |
12188 | " c_double double, c_varchar varchar(20), " |
12189 | " c_char char(20), c_time time, c_date date, " |
12190 | " c_datetime datetime)" ; |
12191 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
12192 | myquery(rc); |
12193 | stmt_text= "insert into t1 values (-100, -20000, 30000000, 4, 8, 1.0, " |
12194 | "2.0, 'abc', 'def', now(), now(), now())" ; |
12195 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
12196 | myquery(rc); |
12197 | |
12198 | stmt_text= "select * from t1" ; |
12199 | |
12200 | /* Run select in prepared and non-prepared mode and compare metadata */ |
12201 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
12202 | myquery(rc); |
12203 | query_result= mysql_store_result(mysql); |
12204 | query_field_list= mysql_fetch_fields(query_result); |
12205 | query_field_count= mysql_num_fields(query_result); |
12206 | |
12207 | stmt= mysql_stmt_init(mysql); |
12208 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
12209 | check_execute(stmt, rc); |
12210 | rc= mysql_stmt_execute(stmt); |
12211 | check_execute(stmt, rc); |
12212 | mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, |
12213 | (void*) &update_max_length); |
12214 | mysql_stmt_store_result(stmt); |
12215 | stmt_metadata= mysql_stmt_result_metadata(stmt); |
12216 | stmt_field_list= mysql_fetch_fields(stmt_metadata); |
12217 | stmt_field_count= mysql_num_fields(stmt_metadata); |
12218 | DIE_UNLESS(stmt_field_count == query_field_count); |
12219 | |
12220 | /* Print out and check the metadata */ |
12221 | |
12222 | if (!opt_silent) |
12223 | { |
12224 | printf(" ------------------------------------------------------------\n" ); |
12225 | printf(" | Metadata \n" ); |
12226 | printf(" ------------------------------------------------------------\n" ); |
12227 | printf(" | Query | Prepared statement \n" ); |
12228 | printf(" ------------------------------------------------------------\n" ); |
12229 | printf(" field name | length | max_length | length | max_length\n" ); |
12230 | printf(" ------------------------------------------------------------\n" ); |
12231 | |
12232 | for (i= 0; i < query_field_count; ++i) |
12233 | { |
12234 | MYSQL_FIELD *f1= &query_field_list[i], *f2= &stmt_field_list[i]; |
12235 | printf(" %-11s | %9lu | %10lu | %9lu | %10lu \n" , |
12236 | f1->name, f1->length, f1->max_length, f2->length, f2->max_length); |
12237 | DIE_UNLESS(f1->length == f2->length); |
12238 | } |
12239 | printf(" ---------------------------------------------------------------\n" ); |
12240 | } |
12241 | |
12242 | /* Bind and fetch the data */ |
12243 | |
12244 | bzero((char*) my_bind, sizeof(my_bind)); |
12245 | for (i= 0; i < stmt_field_count; ++i) |
12246 | { |
12247 | my_bind[i].buffer_type= MYSQL_TYPE_STRING; |
12248 | my_bind[i].buffer_length= stmt_field_list[i].max_length + 1; |
12249 | my_bind[i].buffer= malloc(my_bind[i].buffer_length); |
12250 | } |
12251 | mysql_stmt_bind_result(stmt, my_bind); |
12252 | rc= mysql_stmt_fetch(stmt); |
12253 | check_execute(stmt, rc); |
12254 | rc= mysql_stmt_fetch(stmt); |
12255 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
12256 | |
12257 | /* Clean up */ |
12258 | |
12259 | for (i= 0; i < stmt_field_count; ++i) |
12260 | free(my_bind[i].buffer); |
12261 | mysql_stmt_close(stmt); |
12262 | mysql_free_result(query_result); |
12263 | mysql_free_result(stmt_metadata); |
12264 | stmt_text= "drop table t1" ; |
12265 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
12266 | myquery(rc); |
12267 | } |
12268 | |
12269 | |
12270 | /* |
12271 | Test of basic checks that are performed in server for components |
12272 | of MYSQL_TIME parameters. |
12273 | */ |
12274 | |
12275 | static void test_datetime_ranges() |
12276 | { |
12277 | const char *stmt_text; |
12278 | int rc, i; |
12279 | MYSQL_STMT *stmt; |
12280 | MYSQL_BIND my_bind[6]; |
12281 | MYSQL_TIME tm[6]; |
12282 | |
12283 | myheader("test_datetime_ranges" ); |
12284 | |
12285 | stmt_text= "drop table if exists t1" ; |
12286 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
12287 | myquery(rc); |
12288 | |
12289 | stmt_text= "create table t1 (year datetime, month datetime, day datetime, " |
12290 | "hour datetime, min datetime, sec datetime)" ; |
12291 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
12292 | myquery(rc); |
12293 | |
12294 | stmt= mysql_simple_prepare(mysql, |
12295 | "INSERT INTO t1 VALUES (?, ?, ?, ?, ?, ?)" ); |
12296 | check_stmt(stmt); |
12297 | verify_param_count(stmt, 6); |
12298 | |
12299 | bzero((char*) my_bind, sizeof(my_bind)); |
12300 | for (i= 0; i < 6; i++) |
12301 | { |
12302 | my_bind[i].buffer_type= MYSQL_TYPE_DATETIME; |
12303 | my_bind[i].buffer= &tm[i]; |
12304 | } |
12305 | rc= mysql_stmt_bind_param(stmt, my_bind); |
12306 | check_execute(stmt, rc); |
12307 | |
12308 | tm[0].year= 2004; tm[0].month= 11; tm[0].day= 10; |
12309 | tm[0].hour= 12; tm[0].minute= 30; tm[0].second= 30; |
12310 | tm[0].second_part= 0; tm[0].neg= 0; |
12311 | |
12312 | tm[5]= tm[4]= tm[3]= tm[2]= tm[1]= tm[0]; |
12313 | tm[0].year= 10000; tm[1].month= 13; tm[2].day= 32; |
12314 | tm[3].hour= 24; tm[4].minute= 60; tm[5].second= 60; |
12315 | |
12316 | rc= mysql_stmt_execute(stmt); |
12317 | check_execute(stmt, rc); |
12318 | my_process_warnings(mysql, 6); |
12319 | |
12320 | verify_col_data("t1" , "year" , "0000-00-00 00:00:00" ); |
12321 | verify_col_data("t1" , "month" , "0000-00-00 00:00:00" ); |
12322 | verify_col_data("t1" , "day" , "0000-00-00 00:00:00" ); |
12323 | verify_col_data("t1" , "hour" , "0000-00-00 00:00:00" ); |
12324 | verify_col_data("t1" , "min" , "0000-00-00 00:00:00" ); |
12325 | verify_col_data("t1" , "sec" , "0000-00-00 00:00:00" ); |
12326 | |
12327 | mysql_stmt_close(stmt); |
12328 | |
12329 | stmt_text= "delete from t1" ; |
12330 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
12331 | myquery(rc); |
12332 | |
12333 | stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 (year, month, day) " |
12334 | "VALUES (?, ?, ?)" ); |
12335 | check_stmt(stmt); |
12336 | verify_param_count(stmt, 3); |
12337 | |
12338 | /* |
12339 | We reuse contents of bind and tm arrays left from previous part of test. |
12340 | */ |
12341 | for (i= 0; i < 3; i++) |
12342 | my_bind[i].buffer_type= MYSQL_TYPE_DATE; |
12343 | |
12344 | rc= mysql_stmt_bind_param(stmt, my_bind); |
12345 | check_execute(stmt, rc); |
12346 | |
12347 | rc= mysql_stmt_execute(stmt); |
12348 | check_execute(stmt, rc); |
12349 | my_process_warnings(mysql, 3); |
12350 | |
12351 | verify_col_data("t1" , "year" , "0000-00-00 00:00:00" ); |
12352 | verify_col_data("t1" , "month" , "0000-00-00 00:00:00" ); |
12353 | verify_col_data("t1" , "day" , "0000-00-00 00:00:00" ); |
12354 | |
12355 | mysql_stmt_close(stmt); |
12356 | |
12357 | stmt_text= "drop table t1" ; |
12358 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
12359 | myquery(rc); |
12360 | |
12361 | stmt_text= "create table t1 (day_ovfl time, day time, hour time, min time, sec time)" ; |
12362 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
12363 | myquery(rc); |
12364 | |
12365 | stmt= mysql_simple_prepare(mysql, |
12366 | "INSERT INTO t1 VALUES (?, ?, ?, ?, ?)" ); |
12367 | check_stmt(stmt); |
12368 | verify_param_count(stmt, 5); |
12369 | |
12370 | /* |
12371 | Again we reuse what we can from previous part of test. |
12372 | */ |
12373 | for (i= 0; i < 5; i++) |
12374 | my_bind[i].buffer_type= MYSQL_TYPE_TIME; |
12375 | |
12376 | rc= mysql_stmt_bind_param(stmt, my_bind); |
12377 | check_execute(stmt, rc); |
12378 | |
12379 | tm[0].year= 0; tm[0].month= 0; tm[0].day= 10; |
12380 | tm[0].hour= 12; tm[0].minute= 30; tm[0].second= 30; |
12381 | tm[0].second_part= 0; tm[0].neg= 0; |
12382 | |
12383 | tm[4]= tm[3]= tm[2]= tm[1]= tm[0]; |
12384 | tm[0].day= 35; tm[1].day= 34; tm[2].hour= 30; tm[3].minute= 60; tm[4].second= 60; |
12385 | |
12386 | rc= mysql_stmt_execute(stmt); |
12387 | check_execute(stmt, rc); |
12388 | my_process_warnings(mysql, 2); |
12389 | |
12390 | verify_col_data("t1" , "day_ovfl" , "838:59:59" ); |
12391 | verify_col_data("t1" , "day" , "828:30:30" ); |
12392 | verify_col_data("t1" , "hour" , "270:30:30" ); |
12393 | verify_col_data("t1" , "min" , "00:00:00" ); |
12394 | verify_col_data("t1" , "sec" , "00:00:00" ); |
12395 | |
12396 | mysql_stmt_close(stmt); |
12397 | |
12398 | stmt_text= "drop table t1" ; |
12399 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
12400 | myquery(rc); |
12401 | } |
12402 | |
12403 | |
12404 | /* |
12405 | This test is used in: |
12406 | mysql-test/suite/binlog/binlog_stm_datetime_ranges_mdev15289.test |
12407 | */ |
12408 | static void test_datetime_ranges_mdev15289() |
12409 | { |
12410 | const char *stmt_text; |
12411 | int rc, i; |
12412 | MYSQL_STMT *stmt; |
12413 | MYSQL_BIND my_bind[4]; |
12414 | MYSQL_TIME tm[4]; |
12415 | |
12416 | myheader("test_datetime_ranges_mdev15289" ); |
12417 | |
12418 | stmt_text= "SET sql_mode=''" ; |
12419 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
12420 | myquery(rc); |
12421 | |
12422 | stmt_text= "create or replace table t1 " |
12423 | "(t time, d date, dt datetime,ts timestamp)" ; |
12424 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
12425 | myquery(rc); |
12426 | |
12427 | stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 VALUES (?, ?, ?, ?)" ); |
12428 | check_stmt(stmt); |
12429 | verify_param_count(stmt, 4); |
12430 | |
12431 | /*** Testing DATETIME ***/ |
12432 | bzero((char*) my_bind, sizeof(my_bind)); |
12433 | for (i= 0; i < 4; i++) |
12434 | { |
12435 | my_bind[i].buffer_type= MYSQL_TYPE_DATETIME; |
12436 | my_bind[i].buffer= &tm[i]; |
12437 | } |
12438 | rc= mysql_stmt_bind_param(stmt, my_bind); |
12439 | check_execute(stmt, rc); |
12440 | |
12441 | /* Notice bad year */ |
12442 | tm[0].year= 20010; tm[0].month= 1; tm[0].day= 2; |
12443 | tm[0].hour= 03; tm[0].minute= 04; tm[0].second= 05; |
12444 | tm[0].second_part= 0; tm[0].neg= 0; |
12445 | tm[0].time_type= MYSQL_TIMESTAMP_DATETIME; |
12446 | tm[3]= tm[2]= tm[1]= tm[0]; |
12447 | |
12448 | rc= mysql_stmt_execute(stmt); |
12449 | check_execute(stmt, rc); |
12450 | my_process_warnings(mysql, 4); |
12451 | |
12452 | verify_col_data("t1" , "t" , "00:00:00" ); |
12453 | verify_col_data("t1" , "d" , "0000-00-00" ); |
12454 | verify_col_data("t1" , "dt" , "0000-00-00 00:00:00" ); |
12455 | verify_col_data("t1" , "ts" , "0000-00-00 00:00:00" ); |
12456 | |
12457 | /*** Testing DATE ***/ |
12458 | bzero((char*) my_bind, sizeof(my_bind)); |
12459 | for (i= 0; i < 4; i++) |
12460 | { |
12461 | my_bind[i].buffer_type= MYSQL_TYPE_DATE; |
12462 | my_bind[i].buffer= &tm[i]; |
12463 | } |
12464 | rc= mysql_stmt_bind_param(stmt, my_bind); |
12465 | check_execute(stmt, rc); |
12466 | |
12467 | /* Notice bad year */ |
12468 | tm[0].year= 20010; tm[0].month= 1; tm[0].day= 2; |
12469 | tm[0].hour= 00; tm[0].minute= 00; tm[0].second= 00; |
12470 | tm[0].second_part= 0; tm[0].neg= 0; |
12471 | tm[0].time_type= MYSQL_TIMESTAMP_DATE; |
12472 | tm[3]= tm[2]= tm[1]= tm[0]; |
12473 | |
12474 | rc= mysql_stmt_execute(stmt); |
12475 | check_execute(stmt, rc); |
12476 | my_process_warnings(mysql, 4); |
12477 | |
12478 | verify_col_data("t1" , "t" , "00:00:00" ); |
12479 | verify_col_data("t1" , "d" , "0000-00-00" ); |
12480 | verify_col_data("t1" , "dt" , "0000-00-00 00:00:00" ); |
12481 | verify_col_data("t1" , "ts" , "0000-00-00 00:00:00" ); |
12482 | |
12483 | /*** Testing TIME ***/ |
12484 | bzero((char*) my_bind, sizeof(my_bind)); |
12485 | for (i= 0; i < 4; i++) |
12486 | { |
12487 | my_bind[i].buffer_type= MYSQL_TYPE_TIME; |
12488 | my_bind[i].buffer= &tm[i]; |
12489 | } |
12490 | rc= mysql_stmt_bind_param(stmt, my_bind); |
12491 | check_execute(stmt, rc); |
12492 | |
12493 | /* Notice bad hour */ |
12494 | tm[0].year= 0; tm[0].month= 0; tm[0].day= 0; |
12495 | tm[0].hour= 100; tm[0].minute= 64; tm[0].second= 05; |
12496 | tm[0].second_part= 0; tm[0].neg= 0; |
12497 | tm[0].time_type= MYSQL_TIMESTAMP_TIME; |
12498 | tm[3]= tm[2]= tm[1]= tm[0]; |
12499 | |
12500 | rc= mysql_stmt_execute(stmt); |
12501 | check_execute(stmt, rc); |
12502 | my_process_warnings(mysql, 4); |
12503 | |
12504 | verify_col_data("t1" , "t" , "00:00:00" ); |
12505 | verify_col_data("t1" , "d" , "0000-00-00" ); |
12506 | verify_col_data("t1" , "dt" , "0000-00-00 00:00:00" ); |
12507 | verify_col_data("t1" , "ts" , "0000-00-00 00:00:00" ); |
12508 | |
12509 | mysql_stmt_close(stmt); |
12510 | |
12511 | stmt_text= "drop table t1" ; |
12512 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
12513 | myquery(rc); |
12514 | } |
12515 | |
12516 | |
12517 | static void test_bug4172() |
12518 | { |
12519 | MYSQL_STMT *stmt; |
12520 | MYSQL_BIND my_bind[3]; |
12521 | const char *stmt_text; |
12522 | MYSQL_RES *res; |
12523 | MYSQL_ROW row; |
12524 | int rc; |
12525 | char f[100], d[100], e[100]; |
12526 | ulong f_len, d_len, e_len; |
12527 | |
12528 | myheader("test_bug4172" ); |
12529 | |
12530 | mysql_query(mysql, "DROP TABLE IF EXISTS t1" ); |
12531 | mysql_query(mysql, "CREATE TABLE t1 (f float, d double, e decimal(10,4))" ); |
12532 | mysql_query(mysql, "INSERT INTO t1 VALUES (12345.1234, 123456.123456, " |
12533 | "123456.1234)" ); |
12534 | |
12535 | stmt= mysql_stmt_init(mysql); |
12536 | stmt_text= "SELECT f, d, e FROM t1" ; |
12537 | |
12538 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
12539 | check_execute(stmt, rc); |
12540 | rc= mysql_stmt_execute(stmt); |
12541 | check_execute(stmt, rc); |
12542 | |
12543 | bzero((char*) my_bind, sizeof(my_bind)); |
12544 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
12545 | my_bind[0].buffer= f; |
12546 | my_bind[0].buffer_length= sizeof(f); |
12547 | my_bind[0].length= &f_len; |
12548 | my_bind[1].buffer_type= MYSQL_TYPE_STRING; |
12549 | my_bind[1].buffer= d; |
12550 | my_bind[1].buffer_length= sizeof(d); |
12551 | my_bind[1].length= &d_len; |
12552 | my_bind[2].buffer_type= MYSQL_TYPE_STRING; |
12553 | my_bind[2].buffer= e; |
12554 | my_bind[2].buffer_length= sizeof(e); |
12555 | my_bind[2].length= &e_len; |
12556 | |
12557 | mysql_stmt_bind_result(stmt, my_bind); |
12558 | |
12559 | mysql_stmt_store_result(stmt); |
12560 | rc= mysql_stmt_fetch(stmt); |
12561 | check_execute(stmt, rc); |
12562 | |
12563 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
12564 | myquery(rc); |
12565 | res= mysql_store_result(mysql); |
12566 | row= mysql_fetch_row(res); |
12567 | |
12568 | if (!opt_silent) |
12569 | { |
12570 | printf("Binary protocol: float=%s, double=%s, decimal(10,4)=%s\n" , |
12571 | f, d, e); |
12572 | printf("Text protocol: float=%s, double=%s, decimal(10,4)=%s\n" , |
12573 | row[0], row[1], row[2]); |
12574 | } |
12575 | DIE_UNLESS(!strcmp(f, row[0]) && !strcmp(d, row[1]) && !strcmp(e, row[2])); |
12576 | |
12577 | mysql_free_result(res); |
12578 | mysql_stmt_close(stmt); |
12579 | } |
12580 | |
12581 | |
12582 | static void test_conversion() |
12583 | { |
12584 | MYSQL_STMT *stmt; |
12585 | const char *stmt_text; |
12586 | int rc; |
12587 | MYSQL_BIND my_bind[1]; |
12588 | uchar buff[4]; |
12589 | ulong length; |
12590 | |
12591 | myheader("test_conversion" ); |
12592 | |
12593 | stmt_text= "DROP TABLE IF EXISTS t1" ; |
12594 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
12595 | myquery(rc); |
12596 | stmt_text= "CREATE TABLE t1 (a TEXT) DEFAULT CHARSET latin1" ; |
12597 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
12598 | myquery(rc); |
12599 | stmt_text= "SET character_set_connection=utf8, character_set_client=utf8, " |
12600 | " character_set_results=latin1" ; |
12601 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
12602 | myquery(rc); |
12603 | |
12604 | stmt= mysql_stmt_init(mysql); |
12605 | |
12606 | stmt_text= "INSERT INTO t1 (a) VALUES (?)" ; |
12607 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
12608 | check_execute(stmt, rc); |
12609 | |
12610 | bzero((char*) my_bind, sizeof(my_bind)); |
12611 | my_bind[0].buffer= (char*) buff; |
12612 | my_bind[0].length= &length; |
12613 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
12614 | |
12615 | mysql_stmt_bind_param(stmt, my_bind); |
12616 | |
12617 | buff[0]= (uchar) 0xC3; |
12618 | buff[1]= (uchar) 0xA0; |
12619 | length= 2; |
12620 | |
12621 | rc= mysql_stmt_execute(stmt); |
12622 | check_execute(stmt, rc); |
12623 | |
12624 | stmt_text= "SELECT a FROM t1" ; |
12625 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
12626 | check_execute(stmt, rc); |
12627 | rc= mysql_stmt_execute(stmt); |
12628 | check_execute(stmt, rc); |
12629 | |
12630 | my_bind[0].buffer_length= sizeof(buff); |
12631 | mysql_stmt_bind_result(stmt, my_bind); |
12632 | |
12633 | rc= mysql_stmt_fetch(stmt); |
12634 | DIE_UNLESS(rc == 0); |
12635 | DIE_UNLESS(length == 1); |
12636 | DIE_UNLESS(buff[0] == 0xE0); |
12637 | rc= mysql_stmt_fetch(stmt); |
12638 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
12639 | |
12640 | mysql_stmt_close(stmt); |
12641 | stmt_text= "DROP TABLE t1" ; |
12642 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
12643 | myquery(rc); |
12644 | stmt_text= "SET NAMES DEFAULT" ; |
12645 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
12646 | myquery(rc); |
12647 | } |
12648 | |
12649 | static void test_rewind(void) |
12650 | { |
12651 | MYSQL_STMT *stmt; |
12652 | MYSQL_BIND my_bind; |
12653 | int rc = 0; |
12654 | const char *stmt_text; |
12655 | long unsigned int length=4, Data=0; |
12656 | my_bool isnull=0; |
12657 | |
12658 | myheader("test_rewind" ); |
12659 | |
12660 | stmt_text= "CREATE TABLE t1 (a int)" ; |
12661 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
12662 | myquery(rc); |
12663 | stmt_text= "INSERT INTO t1 VALUES(2),(3),(4)" ; |
12664 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
12665 | myquery(rc); |
12666 | |
12667 | stmt= mysql_stmt_init(mysql); |
12668 | |
12669 | stmt_text= "SELECT * FROM t1" ; |
12670 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
12671 | check_execute(stmt, rc); |
12672 | |
12673 | bzero((char*) &my_bind, sizeof(MYSQL_BIND)); |
12674 | my_bind.buffer_type= MYSQL_TYPE_LONG; |
12675 | my_bind.buffer= (void *)&Data; /* this buffer won't be altered */ |
12676 | my_bind.length= &length; |
12677 | my_bind.is_null= &isnull; |
12678 | |
12679 | rc= mysql_stmt_execute(stmt); |
12680 | check_execute(stmt, rc); |
12681 | |
12682 | rc= mysql_stmt_store_result(stmt); |
12683 | DIE_UNLESS(rc == 0); |
12684 | |
12685 | rc= mysql_stmt_bind_result(stmt, &my_bind); |
12686 | DIE_UNLESS(rc == 0); |
12687 | |
12688 | /* retreive all result sets till we are at the end */ |
12689 | while(!mysql_stmt_fetch(stmt)) |
12690 | if (!opt_silent) |
12691 | printf("fetched result:%ld\n" , Data); |
12692 | |
12693 | DIE_UNLESS(rc != MYSQL_NO_DATA); |
12694 | |
12695 | /* seek to the first row */ |
12696 | mysql_stmt_data_seek(stmt, 0); |
12697 | |
12698 | /* now we should be able to fetch the results again */ |
12699 | /* but mysql_stmt_fetch returns MYSQL_NO_DATA */ |
12700 | while(!(rc= mysql_stmt_fetch(stmt))) |
12701 | if (!opt_silent) |
12702 | printf("fetched result after seek:%ld\n" , Data); |
12703 | |
12704 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
12705 | |
12706 | stmt_text= "DROP TABLE t1" ; |
12707 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
12708 | myquery(rc); |
12709 | rc= mysql_stmt_free_result(stmt); |
12710 | rc= mysql_stmt_close(stmt); |
12711 | } |
12712 | |
12713 | |
12714 | static void test_truncation() |
12715 | { |
12716 | MYSQL_STMT *stmt; |
12717 | const char *stmt_text; |
12718 | int rc; |
12719 | uint bind_count; |
12720 | MYSQL_BIND *bind_array, *my_bind; |
12721 | |
12722 | myheader("test_truncation" ); |
12723 | |
12724 | /* Prepare the test table */ |
12725 | rc= mysql_query(mysql, "drop table if exists t1" ); |
12726 | myquery(rc); |
12727 | |
12728 | stmt_text= "create table t1 (" |
12729 | "i8 tinyint, ui8 tinyint unsigned, " |
12730 | "i16 smallint, i16_1 smallint, " |
12731 | "ui16 smallint unsigned, i32 int, i32_1 int, " |
12732 | "d double, d_1 double, ch char(30), ch_1 char(30), " |
12733 | "tx text, tx_1 text, ch_2 char(30) " |
12734 | ")" ; |
12735 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
12736 | myquery(rc); |
12737 | |
12738 | { |
12739 | const char insert_text[]= |
12740 | "insert into t1 VALUES (" |
12741 | "-10, " /* i8 */ |
12742 | "200, " /* ui8 */ |
12743 | "32000, " /* i16 */ |
12744 | "-32767, " /* i16_1 */ |
12745 | "64000, " /* ui16 */ |
12746 | "1073741824, " /* i32 */ |
12747 | "1073741825, " /* i32_1 */ |
12748 | "123.456, " /* d */ |
12749 | "-12345678910, " /* d_1 */ |
12750 | "'111111111111111111111111111111'," /* ch */ |
12751 | "'abcdef', " /* ch_1 */ |
12752 | "'12345 ', " /* tx */ |
12753 | "'12345.67 ', " /* tx_1 */ |
12754 | "'12345.67abc'" /* ch_2 */ |
12755 | ")" ; |
12756 | rc= mysql_real_query(mysql, insert_text, strlen(insert_text)); |
12757 | myquery(rc); |
12758 | } |
12759 | |
12760 | stmt_text= "select i8 c1, i8 c2, ui8 c3, i16_1 c4, ui16 c5, " |
12761 | " i16 c6, ui16 c7, i32 c8, i32_1 c9, i32_1 c10, " |
12762 | " d c11, d_1 c12, d_1 c13, ch c14, ch_1 c15, tx c16, " |
12763 | " tx_1 c17, ch_2 c18 " |
12764 | "from t1" ; |
12765 | |
12766 | stmt= mysql_stmt_init(mysql); |
12767 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
12768 | check_execute(stmt, rc); |
12769 | rc= mysql_stmt_execute(stmt); |
12770 | check_execute(stmt, rc); |
12771 | bind_count= (uint) mysql_stmt_field_count(stmt); |
12772 | |
12773 | /*************** Fill in the bind structure and bind it **************/ |
12774 | bind_array= malloc(sizeof(MYSQL_BIND) * bind_count); |
12775 | bzero((char*) bind_array, sizeof(MYSQL_BIND) * bind_count); |
12776 | for (my_bind= bind_array; my_bind < bind_array + bind_count; my_bind++) |
12777 | my_bind->error= &my_bind->error_value; |
12778 | my_bind= bind_array; |
12779 | |
12780 | my_bind->buffer= malloc(sizeof(uint8)); |
12781 | my_bind->buffer_type= MYSQL_TYPE_TINY; |
12782 | my_bind->is_unsigned= TRUE; |
12783 | |
12784 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12785 | my_bind->buffer= malloc(sizeof(uint32)); |
12786 | my_bind->buffer_type= MYSQL_TYPE_LONG; |
12787 | my_bind->is_unsigned= TRUE; |
12788 | |
12789 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12790 | my_bind->buffer= malloc(sizeof(int8)); |
12791 | my_bind->buffer_type= MYSQL_TYPE_TINY; |
12792 | |
12793 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12794 | my_bind->buffer= malloc(sizeof(uint16)); |
12795 | my_bind->buffer_type= MYSQL_TYPE_SHORT; |
12796 | my_bind->is_unsigned= TRUE; |
12797 | |
12798 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12799 | my_bind->buffer= malloc(sizeof(int16)); |
12800 | my_bind->buffer_type= MYSQL_TYPE_SHORT; |
12801 | |
12802 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12803 | my_bind->buffer= malloc(sizeof(uint16)); |
12804 | my_bind->buffer_type= MYSQL_TYPE_SHORT; |
12805 | my_bind->is_unsigned= TRUE; |
12806 | |
12807 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12808 | my_bind->buffer= malloc(sizeof(int8)); |
12809 | my_bind->buffer_type= MYSQL_TYPE_TINY; |
12810 | my_bind->is_unsigned= TRUE; |
12811 | |
12812 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12813 | my_bind->buffer= malloc(sizeof(float)); |
12814 | my_bind->buffer_type= MYSQL_TYPE_FLOAT; |
12815 | |
12816 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12817 | my_bind->buffer= malloc(sizeof(float)); |
12818 | my_bind->buffer_type= MYSQL_TYPE_FLOAT; |
12819 | |
12820 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12821 | my_bind->buffer= malloc(sizeof(double)); |
12822 | my_bind->buffer_type= MYSQL_TYPE_DOUBLE; |
12823 | |
12824 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12825 | my_bind->buffer= malloc(sizeof(longlong)); |
12826 | my_bind->buffer_type= MYSQL_TYPE_LONGLONG; |
12827 | |
12828 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12829 | my_bind->buffer= malloc(sizeof(ulonglong)); |
12830 | my_bind->buffer_type= MYSQL_TYPE_LONGLONG; |
12831 | my_bind->is_unsigned= TRUE; |
12832 | |
12833 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12834 | my_bind->buffer= malloc(sizeof(longlong)); |
12835 | my_bind->buffer_type= MYSQL_TYPE_LONGLONG; |
12836 | |
12837 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12838 | my_bind->buffer= malloc(sizeof(longlong)); |
12839 | my_bind->buffer_type= MYSQL_TYPE_LONGLONG; |
12840 | |
12841 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12842 | my_bind->buffer= malloc(sizeof(longlong)); |
12843 | my_bind->buffer_type= MYSQL_TYPE_LONGLONG; |
12844 | |
12845 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12846 | my_bind->buffer= malloc(sizeof(longlong)); |
12847 | my_bind->buffer_type= MYSQL_TYPE_LONGLONG; |
12848 | |
12849 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12850 | my_bind->buffer= malloc(sizeof(double)); |
12851 | my_bind->buffer_type= MYSQL_TYPE_DOUBLE; |
12852 | |
12853 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12854 | my_bind->buffer= malloc(sizeof(double)); |
12855 | my_bind->buffer_type= MYSQL_TYPE_DOUBLE; |
12856 | |
12857 | rc= mysql_stmt_bind_result(stmt, bind_array); |
12858 | check_execute(stmt, rc); |
12859 | rc= mysql_stmt_fetch(stmt); |
12860 | DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED); |
12861 | |
12862 | /*************** Verify truncation results ***************************/ |
12863 | my_bind= bind_array; |
12864 | |
12865 | /* signed tiny -> tiny */ |
12866 | DIE_UNLESS(*my_bind->error && * (int8*) my_bind->buffer == -10); |
12867 | |
12868 | /* signed tiny -> uint32 */ |
12869 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12870 | DIE_UNLESS(*my_bind->error && * (int32*) my_bind->buffer == -10); |
12871 | |
12872 | /* unsigned tiny -> tiny */ |
12873 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12874 | DIE_UNLESS(*my_bind->error && * (uint8*) my_bind->buffer == 200); |
12875 | |
12876 | /* short -> ushort */ |
12877 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12878 | DIE_UNLESS(*my_bind->error && * (int16*) my_bind->buffer == -32767); |
12879 | |
12880 | /* ushort -> short */ |
12881 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12882 | DIE_UNLESS(*my_bind->error && * (uint16*) my_bind->buffer == 64000); |
12883 | |
12884 | /* short -> ushort (no truncation, data is in the range of target type) */ |
12885 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12886 | DIE_UNLESS(! *my_bind->error && * (uint16*) my_bind->buffer == 32000); |
12887 | |
12888 | /* ushort -> utiny */ |
12889 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12890 | DIE_UNLESS(*my_bind->error && * (int8*) my_bind->buffer == 0); |
12891 | |
12892 | /* int -> float: no truncation, the number is a power of two */ |
12893 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12894 | DIE_UNLESS(! *my_bind->error && * (float*) my_bind->buffer == 1073741824); |
12895 | |
12896 | /* int -> float: truncation, not enough bits in float */ |
12897 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12898 | DIE_UNLESS(*my_bind->error); |
12899 | |
12900 | /* int -> double: no truncation */ |
12901 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12902 | DIE_UNLESS(! *my_bind->error && * (double*) my_bind->buffer == 1073741825); |
12903 | |
12904 | /* double -> longlong: fractional part is lost */ |
12905 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12906 | |
12907 | /* double -> ulonglong, negative fp number to unsigned integer */ |
12908 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12909 | /* Value in the buffer is not defined: don't test it */ |
12910 | DIE_UNLESS(*my_bind->error); |
12911 | |
12912 | /* double -> longlong, negative fp number to signed integer: no loss */ |
12913 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12914 | DIE_UNLESS(! *my_bind->error && * (longlong*) my_bind->buffer == -12345678910LL); |
12915 | |
12916 | /* big numeric string -> number */ |
12917 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12918 | DIE_UNLESS(*my_bind->error); |
12919 | |
12920 | /* junk string -> number */ |
12921 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12922 | DIE_UNLESS(*my_bind->error && *(longlong*) my_bind->buffer == 0); |
12923 | |
12924 | /* string with trailing spaces -> number */ |
12925 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12926 | DIE_UNLESS(! *my_bind->error && *(longlong*) my_bind->buffer == 12345); |
12927 | |
12928 | /* string with trailing spaces -> double */ |
12929 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12930 | DIE_UNLESS(! *my_bind->error && *(double*) my_bind->buffer == 12345.67); |
12931 | |
12932 | /* string with trailing junk -> double */ |
12933 | DIE_UNLESS(my_bind++ < bind_array + bind_count); |
12934 | /* |
12935 | XXX: There must be a truncation error: but it's not the way the server |
12936 | behaves, so let's leave it for now. |
12937 | */ |
12938 | DIE_UNLESS(*(double*) my_bind->buffer == 12345.67); |
12939 | /* |
12940 | TODO: string -> double, double -> time, double -> string (truncation |
12941 | errors are not supported here yet) |
12942 | longlong -> time/date/datetime |
12943 | date -> time, date -> timestamp, date -> number |
12944 | time -> string, time -> date, time -> timestamp, |
12945 | number -> date string -> date |
12946 | */ |
12947 | /*************** Cleanup *********************************************/ |
12948 | |
12949 | mysql_stmt_close(stmt); |
12950 | |
12951 | for (my_bind= bind_array; my_bind < bind_array + bind_count; my_bind++) |
12952 | free(my_bind->buffer); |
12953 | free(bind_array); |
12954 | |
12955 | rc= mysql_query(mysql, "drop table t1" ); |
12956 | myquery(rc); |
12957 | } |
12958 | |
12959 | static void test_truncation_option() |
12960 | { |
12961 | MYSQL_STMT *stmt; |
12962 | const char *stmt_text; |
12963 | int rc; |
12964 | uint8 buf; |
12965 | my_bool option= 0; |
12966 | my_bool error; |
12967 | MYSQL_BIND my_bind; |
12968 | |
12969 | myheader("test_truncation_option" ); |
12970 | |
12971 | /* Prepare the test table */ |
12972 | stmt_text= "select -1" ; |
12973 | |
12974 | stmt= mysql_stmt_init(mysql); |
12975 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
12976 | check_execute(stmt, rc); |
12977 | rc= mysql_stmt_execute(stmt); |
12978 | check_execute(stmt, rc); |
12979 | |
12980 | bzero((char*) &my_bind, sizeof(my_bind)); |
12981 | |
12982 | my_bind.buffer= (void*) &buf; |
12983 | my_bind.buffer_type= MYSQL_TYPE_TINY; |
12984 | my_bind.is_unsigned= TRUE; |
12985 | my_bind.error= &error; |
12986 | |
12987 | rc= mysql_stmt_bind_result(stmt, &my_bind); |
12988 | check_execute(stmt, rc); |
12989 | rc= mysql_stmt_fetch(stmt); |
12990 | DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED); |
12991 | DIE_UNLESS(error); |
12992 | rc= mysql_options(mysql, MYSQL_REPORT_DATA_TRUNCATION, (char*) &option); |
12993 | myquery(rc); |
12994 | /* need to rebind for the new setting to take effect */ |
12995 | rc= mysql_stmt_bind_result(stmt, &my_bind); |
12996 | check_execute(stmt, rc); |
12997 | rc= mysql_stmt_execute(stmt); |
12998 | check_execute(stmt, rc); |
12999 | rc= mysql_stmt_fetch(stmt); |
13000 | check_execute(stmt, rc); |
13001 | /* The only change is rc - error pointers are still filled in */ |
13002 | DIE_UNLESS(error == 1); |
13003 | /* restore back the defaults */ |
13004 | option= 1; |
13005 | mysql_options(mysql, MYSQL_REPORT_DATA_TRUNCATION, (char*) &option); |
13006 | |
13007 | mysql_stmt_close(stmt); |
13008 | } |
13009 | |
13010 | |
13011 | /* Bug#6761 - mysql_list_fields doesn't work */ |
13012 | |
13013 | static void test_bug6761(void) |
13014 | { |
13015 | const char *stmt_text; |
13016 | MYSQL_RES *res; |
13017 | int rc; |
13018 | myheader("test_bug6761" ); |
13019 | |
13020 | stmt_text= "CREATE TABLE t1 (a int, b char(255), c decimal)" ; |
13021 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
13022 | myquery(rc); |
13023 | |
13024 | res= mysql_list_fields(mysql, "t1" , "%" ); |
13025 | DIE_UNLESS(res && mysql_num_fields(res) == 3); |
13026 | mysql_free_result(res); |
13027 | |
13028 | stmt_text= "DROP TABLE t1" ; |
13029 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
13030 | myquery(rc); |
13031 | } |
13032 | |
13033 | |
13034 | /* Bug#8330 - mysql_stmt_execute crashes (libmysql) */ |
13035 | |
13036 | static void test_bug8330() |
13037 | { |
13038 | const char *stmt_text; |
13039 | MYSQL_STMT *stmt[2]; |
13040 | int i, rc; |
13041 | const char *query= "select a,b from t1 where a=?" ; |
13042 | MYSQL_BIND my_bind[2]; |
13043 | long lval[2]; |
13044 | |
13045 | myheader("test_bug8330" ); |
13046 | |
13047 | stmt_text= "drop table if exists t1" ; |
13048 | /* in case some previos test failed */ |
13049 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
13050 | myquery(rc); |
13051 | stmt_text= "create table t1 (a int, b int)" ; |
13052 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
13053 | myquery(rc); |
13054 | |
13055 | bzero((char*) my_bind, sizeof(my_bind)); |
13056 | for (i=0; i < 2; i++) |
13057 | { |
13058 | stmt[i]= mysql_stmt_init(mysql); |
13059 | rc= mysql_stmt_prepare(stmt[i], query, strlen(query)); |
13060 | check_execute(stmt[i], rc); |
13061 | |
13062 | my_bind[i].buffer_type= MYSQL_TYPE_LONG; |
13063 | my_bind[i].buffer= (void*) &lval[i]; |
13064 | my_bind[i].is_null= 0; |
13065 | mysql_stmt_bind_param(stmt[i], &my_bind[i]); |
13066 | } |
13067 | |
13068 | rc= mysql_stmt_execute(stmt[0]); |
13069 | check_execute(stmt[0], rc); |
13070 | |
13071 | rc= mysql_stmt_execute(stmt[1]); |
13072 | DIE_UNLESS(rc && mysql_stmt_errno(stmt[1]) == CR_COMMANDS_OUT_OF_SYNC); |
13073 | rc= mysql_stmt_execute(stmt[0]); |
13074 | check_execute(stmt[0], rc); |
13075 | |
13076 | mysql_stmt_close(stmt[0]); |
13077 | mysql_stmt_close(stmt[1]); |
13078 | |
13079 | stmt_text= "drop table t1" ; |
13080 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
13081 | myquery(rc); |
13082 | } |
13083 | |
13084 | |
13085 | /* Bug#7990 - mysql_stmt_close doesn't reset mysql->net.last_error */ |
13086 | |
13087 | static void test_bug7990() |
13088 | { |
13089 | MYSQL_STMT *stmt; |
13090 | int rc; |
13091 | myheader("test_bug7990" ); |
13092 | |
13093 | stmt= mysql_stmt_init(mysql); |
13094 | rc= mysql_stmt_prepare(stmt, "foo" , 3); |
13095 | /* |
13096 | XXX: the fact that we store errno both in STMT and in |
13097 | MYSQL is not documented and is subject to change in 5.0 |
13098 | */ |
13099 | DIE_UNLESS(rc && mysql_stmt_errno(stmt) && mysql_errno(mysql)); |
13100 | mysql_stmt_close(stmt); |
13101 | DIE_UNLESS(!mysql_errno(mysql)); |
13102 | } |
13103 | |
13104 | /* |
13105 | Bug #15518 - Reusing a stmt that has failed during prepare |
13106 | does not clear error |
13107 | */ |
13108 | |
13109 | static void test_bug15518() |
13110 | { |
13111 | MYSQL_STMT *stmt; |
13112 | MYSQL* mysql1; |
13113 | int rc; |
13114 | myheader("test_bug15518" ); |
13115 | |
13116 | mysql1= mysql_client_init(NULL); |
13117 | |
13118 | if (!mysql_real_connect(mysql1, opt_host, opt_user, opt_password, |
13119 | opt_db ? opt_db : "test" , opt_port, opt_unix_socket, |
13120 | CLIENT_MULTI_STATEMENTS)) |
13121 | { |
13122 | fprintf(stderr, "Failed to connect to the database\n" ); |
13123 | DIE_UNLESS(0); |
13124 | } |
13125 | |
13126 | stmt= mysql_stmt_init(mysql1); |
13127 | |
13128 | /* |
13129 | The prepare of foo should fail with errno 1064 since |
13130 | it's not a valid query |
13131 | */ |
13132 | rc= mysql_stmt_prepare(stmt, "foo" , 3); |
13133 | if (!opt_silent) |
13134 | fprintf(stdout, "rc: %d, mysql_stmt_errno: %d, mysql_errno: %d\n" , |
13135 | rc, mysql_stmt_errno(stmt), mysql_errno(mysql1)); |
13136 | DIE_UNLESS(rc && mysql_stmt_errno(stmt) && mysql_errno(mysql1)); |
13137 | |
13138 | /* |
13139 | Use the same stmt and reprepare with another query that |
13140 | suceeds |
13141 | */ |
13142 | rc= mysql_stmt_prepare(stmt, "SHOW STATUS" , 12); |
13143 | if (!opt_silent) |
13144 | fprintf(stdout, "rc: %d, mysql_stmt_errno: %d, mysql_errno: %d\n" , |
13145 | rc, mysql_stmt_errno(stmt), mysql_errno(mysql1)); |
13146 | DIE_UNLESS(!rc || mysql_stmt_errno(stmt) || mysql_errno(mysql1)); |
13147 | |
13148 | mysql_stmt_close(stmt); |
13149 | DIE_UNLESS(!mysql_errno(mysql1)); |
13150 | |
13151 | /* |
13152 | part2, when connection to server has been closed |
13153 | after first prepare |
13154 | */ |
13155 | stmt= mysql_stmt_init(mysql1); |
13156 | rc= mysql_stmt_prepare(stmt, "foo" , 3); |
13157 | if (!opt_silent) |
13158 | fprintf(stdout, "rc: %d, mysql_stmt_errno: %d, mysql_errno: %d\n" , |
13159 | rc, mysql_stmt_errno(stmt), mysql_errno(mysql1)); |
13160 | DIE_UNLESS(rc && mysql_stmt_errno(stmt) && mysql_errno(mysql1)); |
13161 | |
13162 | /* Close connection to server */ |
13163 | mysql_close(mysql1); |
13164 | |
13165 | /* |
13166 | Use the same stmt and reprepare with another query that |
13167 | suceeds. The prepare should fail with error 2013 since |
13168 | connection to server has been closed. |
13169 | */ |
13170 | rc= mysql_stmt_prepare(stmt, "SHOW STATUS" , 12); |
13171 | if (!opt_silent) |
13172 | fprintf(stdout, "rc: %d, mysql_stmt_errno: %d\n" , |
13173 | rc, mysql_stmt_errno(stmt)); |
13174 | DIE_UNLESS(rc && mysql_stmt_errno(stmt)); |
13175 | |
13176 | mysql_stmt_close(stmt); |
13177 | } |
13178 | |
13179 | |
13180 | static void disable_query_logs() |
13181 | { |
13182 | int rc; |
13183 | rc= mysql_query(mysql, "set @@global.general_log=off" ); |
13184 | myquery(rc); |
13185 | rc= mysql_query(mysql, "set @@global.slow_query_log=off" ); |
13186 | myquery(rc); |
13187 | } |
13188 | |
13189 | |
13190 | static void enable_query_logs(int truncate) |
13191 | { |
13192 | int rc; |
13193 | |
13194 | rc= mysql_query(mysql, "set @save_global_general_log=@@global.general_log" ); |
13195 | myquery(rc); |
13196 | |
13197 | rc= mysql_query(mysql, "set @save_global_slow_query_log=@@global.slow_query_log" ); |
13198 | myquery(rc); |
13199 | |
13200 | rc= mysql_query(mysql, "set @@global.general_log=on" ); |
13201 | myquery(rc); |
13202 | |
13203 | rc= mysql_query(mysql, "set @@global.slow_query_log=on" ); |
13204 | myquery(rc); |
13205 | |
13206 | |
13207 | if (truncate) |
13208 | { |
13209 | rc= mysql_query(mysql, "truncate mysql.general_log" ); |
13210 | myquery(rc); |
13211 | |
13212 | rc= mysql_query(mysql, "truncate mysql.slow_log" ); |
13213 | myquery(rc); |
13214 | } |
13215 | } |
13216 | |
13217 | |
13218 | static void restore_query_logs() |
13219 | { |
13220 | int rc; |
13221 | rc= mysql_query(mysql, "set @@global.general_log=@save_global_general_log" ); |
13222 | myquery(rc); |
13223 | |
13224 | rc= mysql_query(mysql, "set @@global.slow_query_log=@save_global_slow_query_log" ); |
13225 | myquery(rc); |
13226 | } |
13227 | |
13228 | |
13229 | static void test_view_sp_list_fields() |
13230 | { |
13231 | int rc; |
13232 | MYSQL_RES *res; |
13233 | |
13234 | myheader("test_view_sp_list_fields" ); |
13235 | |
13236 | rc= mysql_query(mysql, "DROP FUNCTION IF EXISTS f1" ); |
13237 | myquery(rc); |
13238 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS v1, t1, t2" ); |
13239 | myquery(rc); |
13240 | rc= mysql_query(mysql, "DROP VIEW IF EXISTS v1, t1, t2" ); |
13241 | myquery(rc); |
13242 | rc= mysql_query(mysql, "create function f1 () returns int return 5" ); |
13243 | myquery(rc); |
13244 | rc= mysql_query(mysql, "create table t1 (s1 char,s2 char)" ); |
13245 | myquery(rc); |
13246 | rc= mysql_query(mysql, "create table t2 (s1 int);" ); |
13247 | myquery(rc); |
13248 | rc= mysql_query(mysql, "create view v1 as select s2,sum(s1) - \ |
13249 | count(s2) as vx from t1 group by s2 having sum(s1) - count(s2) < (select f1() \ |
13250 | from t2);" ); |
13251 | myquery(rc); |
13252 | res= mysql_list_fields(mysql, "v1" , NullS); |
13253 | DIE_UNLESS(res != 0 && mysql_num_fields(res) != 0); |
13254 | rc= mysql_query(mysql, "DROP FUNCTION f1" ); |
13255 | myquery(rc); |
13256 | rc= mysql_query(mysql, "DROP VIEW v1" ); |
13257 | myquery(rc); |
13258 | rc= mysql_query(mysql, "DROP TABLE t1, t2" ); |
13259 | mysql_free_result(res); |
13260 | myquery(rc); |
13261 | |
13262 | } |
13263 | |
13264 | |
13265 | /* |
13266 | Test mysql_real_escape_string() with gbk charset |
13267 | |
13268 | The important part is that 0x27 (') is the second-byte in a invalid |
13269 | two-byte GBK character here. But 0xbf5c is a valid GBK character, so |
13270 | it needs to be escaped as 0x5cbf27 |
13271 | */ |
13272 | #define TEST_BUG8378_IN "\xef\xbb\xbf\x27\xbf\x10" |
13273 | #define TEST_BUG8378_OUT "\xef\xbb\x5c\xbf\x5c\x27\x5c\xbf\x10" |
13274 | |
13275 | static void test_bug8378() |
13276 | { |
13277 | #if defined(HAVE_CHARSET_gbk) && !defined(EMBEDDED_LIBRARY) |
13278 | MYSQL *lmysql; |
13279 | char out[9]; /* strlen(TEST_BUG8378)*2+1 */ |
13280 | char buf[256]; |
13281 | int len, rc; |
13282 | |
13283 | myheader("test_bug8378" ); |
13284 | |
13285 | if (!opt_silent) |
13286 | fprintf(stdout, "\n Establishing a test connection ..." ); |
13287 | if (!(lmysql= mysql_client_init(NULL))) |
13288 | { |
13289 | myerror("mysql_client_init() failed" ); |
13290 | exit(1); |
13291 | } |
13292 | if (mysql_options(lmysql, MYSQL_SET_CHARSET_NAME, "gbk" )) |
13293 | { |
13294 | myerror("mysql_options() failed" ); |
13295 | exit(1); |
13296 | } |
13297 | if (!(mysql_real_connect(lmysql, opt_host, opt_user, |
13298 | opt_password, current_db, opt_port, |
13299 | opt_unix_socket, 0))) |
13300 | { |
13301 | myerror("connection failed" ); |
13302 | exit(1); |
13303 | } |
13304 | if (!opt_silent) |
13305 | fprintf(stdout, "OK" ); |
13306 | |
13307 | rc= mysql_query(lmysql, "SET SQL_MODE=''" ); |
13308 | myquery(rc); |
13309 | |
13310 | len= mysql_real_escape_string(lmysql, out, TEST_BUG8378_IN, 4); |
13311 | |
13312 | /* No escaping should have actually happened. */ |
13313 | DIE_UNLESS(memcmp(out, TEST_BUG8378_OUT, len) == 0); |
13314 | |
13315 | sprintf(buf, "SELECT '%s'" , out); |
13316 | |
13317 | rc=mysql_real_query(lmysql, buf, strlen(buf)); |
13318 | myquery(rc); |
13319 | |
13320 | mysql_close(lmysql); |
13321 | #endif |
13322 | } |
13323 | |
13324 | |
13325 | static void test_bug8722() |
13326 | { |
13327 | MYSQL_STMT *stmt; |
13328 | int rc; |
13329 | const char *stmt_text; |
13330 | |
13331 | myheader("test_bug8722" ); |
13332 | /* Prepare test data */ |
13333 | stmt_text= "drop table if exists t1, v1" ; |
13334 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
13335 | myquery(rc); |
13336 | stmt_text= "CREATE TABLE t1 (c1 varchar(10), c2 varchar(10), c3 varchar(10)," |
13337 | " c4 varchar(10), c5 varchar(10), c6 varchar(10)," |
13338 | " c7 varchar(10), c8 varchar(10), c9 varchar(10)," |
13339 | "c10 varchar(10))" ; |
13340 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
13341 | myquery(rc); |
13342 | stmt_text= "INSERT INTO t1 VALUES (1,2,3,4,5,6,7,8,9,10)" ; |
13343 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
13344 | myquery(rc); |
13345 | stmt_text= "CREATE VIEW v1 AS SELECT * FROM t1" ; |
13346 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
13347 | myquery(rc); |
13348 | /* Note: if you uncomment following block everything works fine */ |
13349 | /* |
13350 | rc= mysql_query(mysql, "sellect * from v1"); |
13351 | myquery(rc); |
13352 | mysql_free_result(mysql_store_result(mysql)); |
13353 | */ |
13354 | |
13355 | stmt= mysql_stmt_init(mysql); |
13356 | stmt_text= "select * from v1" ; |
13357 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
13358 | check_execute(stmt, rc); |
13359 | mysql_stmt_close(stmt); |
13360 | stmt_text= "drop table if exists t1, v1" ; |
13361 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
13362 | myquery(rc); |
13363 | } |
13364 | |
13365 | |
13366 | MYSQL_STMT *open_cursor(const char *query) |
13367 | { |
13368 | int rc; |
13369 | const ulong type= (ulong)CURSOR_TYPE_READ_ONLY; |
13370 | |
13371 | MYSQL_STMT *stmt= mysql_stmt_init(mysql); |
13372 | rc= mysql_stmt_prepare(stmt, query, strlen(query)); |
13373 | check_execute(stmt, rc); |
13374 | |
13375 | mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type); |
13376 | return stmt; |
13377 | } |
13378 | |
13379 | |
13380 | static void test_bug8880() |
13381 | { |
13382 | MYSQL_STMT *stmt_list[2], **stmt; |
13383 | MYSQL_STMT **stmt_list_end= (MYSQL_STMT**) stmt_list + 2; |
13384 | int rc; |
13385 | |
13386 | myheader("test_bug8880" ); |
13387 | |
13388 | mysql_query(mysql, "drop table if exists t1" ); |
13389 | mysql_query(mysql, "create table t1 (a int not null primary key, b int)" ); |
13390 | rc= mysql_query(mysql, "insert into t1 values (1,1)" ); |
13391 | myquery(rc); /* one check is enough */ |
13392 | /* |
13393 | when inserting 2 rows everything works well |
13394 | mysql_query(mysql, "INSERT INTO t1 VALUES (1,1),(2,2)"); |
13395 | */ |
13396 | for (stmt= stmt_list; stmt < stmt_list_end; stmt++) |
13397 | *stmt= open_cursor("select a from t1" ); |
13398 | for (stmt= stmt_list; stmt < stmt_list_end; stmt++) |
13399 | { |
13400 | rc= mysql_stmt_execute(*stmt); |
13401 | check_execute(*stmt, rc); |
13402 | } |
13403 | for (stmt= stmt_list; stmt < stmt_list_end; stmt++) |
13404 | mysql_stmt_close(*stmt); |
13405 | } |
13406 | |
13407 | /* |
13408 | Test executing a query with prepared statements while query cache is active |
13409 | */ |
13410 | |
13411 | static void test_open_cursor_prepared_statement_query_cache() |
13412 | { |
13413 | MYSQL_STMT *stmt; |
13414 | int rc; |
13415 | MYSQL_RES *result; |
13416 | |
13417 | myheader("test_open_cursor_prepared_statement_query_cache" ); |
13418 | if (! is_query_cache_available()) |
13419 | { |
13420 | fprintf(stdout, "Skipping test_open_cursor_prepared_statement_query_cache: Query cache not available.\n" ); |
13421 | return; |
13422 | } |
13423 | |
13424 | rc= mysql_query(mysql, "set global query_cache_type=ON" ); |
13425 | myquery(rc); |
13426 | rc= mysql_query(mysql, "set local query_cache_type=ON" ); |
13427 | myquery(rc); |
13428 | rc= mysql_query(mysql, "set global query_cache_size=1000000" ); |
13429 | myquery(rc); |
13430 | |
13431 | mysql_query(mysql, "drop table if exists t1" ); |
13432 | mysql_query(mysql, "create table t1 (a int not null primary key, b int)" ); |
13433 | rc= mysql_query(mysql, "insert into t1 values (1,1)" ); |
13434 | myquery(rc); /* one check is enough */ |
13435 | |
13436 | /* Store query in query cache */ |
13437 | rc= mysql_query(mysql, "SELECT * FROM t1" ); |
13438 | myquery(rc); |
13439 | result= mysql_store_result(mysql); |
13440 | mytest(result); |
13441 | (void) my_process_result_set(result); |
13442 | mysql_free_result(result); |
13443 | |
13444 | /* Test using a cursor */ |
13445 | stmt= open_cursor("select a from t1" ); |
13446 | rc= mysql_stmt_execute(stmt); |
13447 | check_execute(stmt, rc); |
13448 | mysql_stmt_close(stmt); |
13449 | |
13450 | rc= mysql_query(mysql, "set global query_cache_type=default" ); |
13451 | myquery(rc); |
13452 | rc= mysql_query(mysql, "set global query_cache_size=default" ); |
13453 | myquery(rc); |
13454 | } |
13455 | |
13456 | |
13457 | static void test_bug9159() |
13458 | { |
13459 | MYSQL_STMT *stmt; |
13460 | int rc; |
13461 | const char *stmt_text= "select a, b from t1" ; |
13462 | const unsigned long type= CURSOR_TYPE_READ_ONLY; |
13463 | |
13464 | myheader("test_bug9159" ); |
13465 | |
13466 | mysql_query(mysql, "drop table if exists t1" ); |
13467 | mysql_query(mysql, "create table t1 (a int not null primary key, b int)" ); |
13468 | rc= mysql_query(mysql, "insert into t1 values (1,1)" ); |
13469 | myquery(rc); |
13470 | |
13471 | stmt= mysql_stmt_init(mysql); |
13472 | mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
13473 | mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void *)&type); |
13474 | |
13475 | mysql_stmt_execute(stmt); |
13476 | mysql_stmt_close(stmt); |
13477 | rc= mysql_query(mysql, "drop table if exists t1" ); |
13478 | myquery(rc); |
13479 | } |
13480 | |
13481 | |
13482 | /* Crash when opening a cursor to a query with DISTICNT and no key */ |
13483 | |
13484 | static void test_bug9520() |
13485 | { |
13486 | MYSQL_STMT *stmt; |
13487 | MYSQL_BIND my_bind[1]; |
13488 | char a[6]; |
13489 | ulong a_len; |
13490 | int rc, row_count= 0; |
13491 | |
13492 | myheader("test_bug9520" ); |
13493 | |
13494 | mysql_query(mysql, "drop table if exists t1" ); |
13495 | mysql_query(mysql, "create table t1 (a char(5), b char(5), c char(5)," |
13496 | " primary key (a, b, c))" ); |
13497 | rc= mysql_query(mysql, "insert into t1 values ('x', 'y', 'z'), " |
13498 | " ('a', 'b', 'c'), ('k', 'l', 'm')" ); |
13499 | myquery(rc); |
13500 | |
13501 | stmt= open_cursor("select distinct b from t1" ); |
13502 | |
13503 | /* |
13504 | Not crashes with: |
13505 | stmt= open_cursor("select distinct a from t1"); |
13506 | */ |
13507 | |
13508 | rc= mysql_stmt_execute(stmt); |
13509 | check_execute(stmt, rc); |
13510 | |
13511 | bzero((char*) my_bind, sizeof(my_bind)); |
13512 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
13513 | my_bind[0].buffer= (char*) a; |
13514 | my_bind[0].buffer_length= sizeof(a); |
13515 | my_bind[0].length= &a_len; |
13516 | |
13517 | mysql_stmt_bind_result(stmt, my_bind); |
13518 | |
13519 | while (!(rc= mysql_stmt_fetch(stmt))) |
13520 | row_count++; |
13521 | |
13522 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
13523 | |
13524 | if (!opt_silent) |
13525 | printf("Fetched %d rows\n" , row_count); |
13526 | DBUG_ASSERT(row_count == 3); |
13527 | |
13528 | mysql_stmt_close(stmt); |
13529 | |
13530 | rc= mysql_query(mysql, "drop table t1" ); |
13531 | myquery(rc); |
13532 | } |
13533 | |
13534 | |
13535 | /* |
13536 | We can't have more than one cursor open for a prepared statement. |
13537 | Test re-executions of a PS with cursor; mysql_stmt_reset must close |
13538 | the cursor attached to the statement, if there is one. |
13539 | */ |
13540 | |
13541 | static void test_bug9478() |
13542 | { |
13543 | MYSQL_STMT *stmt; |
13544 | MYSQL_BIND my_bind[1]; |
13545 | char a[6]; |
13546 | ulong a_len; |
13547 | int rc, i; |
13548 | DBUG_ENTER("test_bug9478" ); |
13549 | |
13550 | myheader("test_bug9478" ); |
13551 | |
13552 | mysql_query(mysql, "drop table if exists t1" ); |
13553 | mysql_query(mysql, "create table t1 (id integer not null primary key, " |
13554 | " name varchar(20) not null)" ); |
13555 | rc= mysql_query(mysql, "insert into t1 (id, name) values " |
13556 | " (1, 'aaa'), (2, 'bbb'), (3, 'ccc')" ); |
13557 | myquery(rc); |
13558 | |
13559 | stmt= open_cursor("select name from t1 where id=2" ); |
13560 | |
13561 | bzero((char*) my_bind, sizeof(my_bind)); |
13562 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
13563 | my_bind[0].buffer= (char*) a; |
13564 | my_bind[0].buffer_length= sizeof(a); |
13565 | my_bind[0].length= &a_len; |
13566 | mysql_stmt_bind_result(stmt, my_bind); |
13567 | |
13568 | for (i= 0; i < 5; i++) |
13569 | { |
13570 | rc= mysql_stmt_execute(stmt); |
13571 | check_execute(stmt, rc); |
13572 | rc= mysql_stmt_fetch(stmt); |
13573 | check_execute(stmt, rc); |
13574 | if (!opt_silent && i == 0) |
13575 | printf("Fetched row: %s\n" , a); |
13576 | |
13577 | /* |
13578 | The query above is a one-row result set. Therefore, there is no |
13579 | cursor associated with it, as the server won't bother with opening |
13580 | a cursor for a one-row result set. The first row was read from the |
13581 | server in the fetch above. But there is eof packet pending in the |
13582 | network. mysql_stmt_execute will flush the packet and successfully |
13583 | execute the statement. |
13584 | */ |
13585 | |
13586 | rc= mysql_stmt_execute(stmt); |
13587 | check_execute(stmt, rc); |
13588 | |
13589 | rc= mysql_stmt_fetch(stmt); |
13590 | check_execute(stmt, rc); |
13591 | if (!opt_silent && i == 0) |
13592 | printf("Fetched row: %s\n" , a); |
13593 | rc= mysql_stmt_fetch(stmt); |
13594 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
13595 | |
13596 | { |
13597 | char buff[8]; |
13598 | /* Fill in the fetch packet */ |
13599 | int4store(buff, stmt->stmt_id); |
13600 | buff[4]= 1; /* prefetch rows */ |
13601 | rc= mysql_stmt_fetch(stmt); |
13602 | DIE_UNLESS(rc); |
13603 | if (!opt_silent && i == 0) |
13604 | printf("Got error (as expected): %s\n" , mysql_error(mysql)); |
13605 | } |
13606 | |
13607 | rc= mysql_stmt_execute(stmt); |
13608 | check_execute(stmt, rc); |
13609 | |
13610 | rc= mysql_stmt_fetch(stmt); |
13611 | check_execute(stmt, rc); |
13612 | if (!opt_silent && i == 0) |
13613 | printf("Fetched row: %s\n" , a); |
13614 | |
13615 | rc= mysql_stmt_reset(stmt); |
13616 | check_execute(stmt, rc); |
13617 | rc= mysql_stmt_fetch(stmt); |
13618 | DIE_UNLESS(rc && mysql_stmt_errno(stmt)); |
13619 | if (!opt_silent && i == 0) |
13620 | printf("Got error (as expected): %s\n" , mysql_stmt_error(stmt)); |
13621 | } |
13622 | rc= mysql_stmt_close(stmt); |
13623 | DIE_UNLESS(rc == 0); |
13624 | |
13625 | /* Test the case with a server side cursor */ |
13626 | stmt= open_cursor("select name from t1" ); |
13627 | |
13628 | mysql_stmt_bind_result(stmt, my_bind); |
13629 | |
13630 | for (i= 0; i < 5; i++) |
13631 | { |
13632 | DBUG_PRINT("loop" ,("i: %d" , i)); |
13633 | rc= mysql_stmt_execute(stmt); |
13634 | check_execute(stmt, rc); |
13635 | rc= mysql_stmt_fetch(stmt); |
13636 | check_execute(stmt, rc); |
13637 | if (!opt_silent && i == 0) |
13638 | printf("Fetched row: %s\n" , a); |
13639 | rc= mysql_stmt_execute(stmt); |
13640 | check_execute(stmt, rc); |
13641 | |
13642 | while (! (rc= mysql_stmt_fetch(stmt))) |
13643 | { |
13644 | if (!opt_silent && i == 0) |
13645 | printf("Fetched row: %s\n" , a); |
13646 | } |
13647 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
13648 | |
13649 | rc= mysql_stmt_execute(stmt); |
13650 | check_execute(stmt, rc); |
13651 | |
13652 | rc= mysql_stmt_fetch(stmt); |
13653 | check_execute(stmt, rc); |
13654 | if (!opt_silent && i == 0) |
13655 | printf("Fetched row: %s\n" , a); |
13656 | |
13657 | rc= mysql_stmt_reset(stmt); |
13658 | check_execute(stmt, rc); |
13659 | rc= mysql_stmt_fetch(stmt); |
13660 | DIE_UNLESS(rc && mysql_stmt_errno(stmt)); |
13661 | if (!opt_silent && i == 0) |
13662 | printf("Got error (as expected): %s\n" , mysql_stmt_error(stmt)); |
13663 | } |
13664 | |
13665 | rc= mysql_stmt_close(stmt); |
13666 | DIE_UNLESS(rc == 0); |
13667 | |
13668 | rc= mysql_query(mysql, "drop table t1" ); |
13669 | myquery(rc); |
13670 | DBUG_VOID_RETURN; |
13671 | } |
13672 | |
13673 | |
13674 | /* |
13675 | Error message is returned for unsupported features. |
13676 | Test also cursors with non-default PREFETCH_ROWS |
13677 | */ |
13678 | |
13679 | static void test_bug9643() |
13680 | { |
13681 | MYSQL_STMT *stmt; |
13682 | MYSQL_BIND my_bind[1]; |
13683 | int32 a; |
13684 | int rc; |
13685 | const char *stmt_text; |
13686 | int num_rows= 0; |
13687 | ulong type; |
13688 | ulong prefetch_rows= 5; |
13689 | |
13690 | myheader("test_bug9643" ); |
13691 | |
13692 | mysql_query(mysql, "drop table if exists t1" ); |
13693 | mysql_query(mysql, "create table t1 (id integer not null primary key)" ); |
13694 | rc= mysql_query(mysql, "insert into t1 (id) values " |
13695 | " (1), (2), (3), (4), (5), (6), (7), (8), (9)" ); |
13696 | myquery(rc); |
13697 | |
13698 | stmt= mysql_stmt_init(mysql); |
13699 | /* Not implemented in 5.0 */ |
13700 | type= (ulong) CURSOR_TYPE_SCROLLABLE; |
13701 | rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type); |
13702 | DIE_UNLESS(rc); |
13703 | if (! opt_silent) |
13704 | printf("Got error (as expected): %s\n" , mysql_stmt_error(stmt)); |
13705 | |
13706 | type= (ulong) CURSOR_TYPE_READ_ONLY; |
13707 | rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type); |
13708 | check_execute(stmt, rc); |
13709 | rc= mysql_stmt_attr_set(stmt, STMT_ATTR_PREFETCH_ROWS, |
13710 | (void*) &prefetch_rows); |
13711 | check_execute(stmt, rc); |
13712 | stmt_text= "select * from t1" ; |
13713 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
13714 | check_execute(stmt, rc); |
13715 | |
13716 | bzero((char*) my_bind, sizeof(my_bind)); |
13717 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
13718 | my_bind[0].buffer= (void*) &a; |
13719 | my_bind[0].buffer_length= sizeof(a); |
13720 | mysql_stmt_bind_result(stmt, my_bind); |
13721 | |
13722 | rc= mysql_stmt_execute(stmt); |
13723 | check_execute(stmt, rc); |
13724 | |
13725 | while ((rc= mysql_stmt_fetch(stmt)) == 0) |
13726 | ++num_rows; |
13727 | DIE_UNLESS(num_rows == 9); |
13728 | |
13729 | rc= mysql_stmt_close(stmt); |
13730 | DIE_UNLESS(rc == 0); |
13731 | |
13732 | rc= mysql_query(mysql, "drop table t1" ); |
13733 | myquery(rc); |
13734 | } |
13735 | |
13736 | /* |
13737 | Bug#11111: fetch from view returns wrong data |
13738 | */ |
13739 | |
13740 | static void test_bug11111() |
13741 | { |
13742 | MYSQL_STMT *stmt; |
13743 | MYSQL_BIND my_bind[2]; |
13744 | char buf[2][20]; |
13745 | ulong len[2]; |
13746 | int i; |
13747 | int rc; |
13748 | const char *query= "SELECT DISTINCT f1,ff2 FROM v1" ; |
13749 | |
13750 | myheader("test_bug11111" ); |
13751 | |
13752 | rc= mysql_query(mysql, "drop table if exists t1, t2, v1" ); |
13753 | myquery(rc); |
13754 | rc= mysql_query(mysql, "drop view if exists t1, t2, v1" ); |
13755 | myquery(rc); |
13756 | rc= mysql_query(mysql, "create table t1 (f1 int, f2 int)" ); |
13757 | myquery(rc); |
13758 | rc= mysql_query(mysql, "create table t2 (ff1 int, ff2 int)" ); |
13759 | myquery(rc); |
13760 | rc= mysql_query(mysql, "create view v1 as select * from t1, t2 where f1=ff1" ); |
13761 | myquery(rc); |
13762 | rc= mysql_query(mysql, "insert into t1 values (1,1), (2,2), (3,3)" ); |
13763 | myquery(rc); |
13764 | rc= mysql_query(mysql, "insert into t2 values (1,1), (2,2), (3,3)" ); |
13765 | myquery(rc); |
13766 | |
13767 | stmt= mysql_stmt_init(mysql); |
13768 | |
13769 | mysql_stmt_prepare(stmt, query, strlen(query)); |
13770 | mysql_stmt_execute(stmt); |
13771 | |
13772 | bzero((char*) my_bind, sizeof(my_bind)); |
13773 | for (i=0; i < 2; i++) |
13774 | { |
13775 | my_bind[i].buffer_type= MYSQL_TYPE_STRING; |
13776 | my_bind[i].buffer= (uchar* *)&buf[i]; |
13777 | my_bind[i].buffer_length= 20; |
13778 | my_bind[i].length= &len[i]; |
13779 | } |
13780 | |
13781 | rc= mysql_stmt_bind_result(stmt, my_bind); |
13782 | check_execute(stmt, rc); |
13783 | |
13784 | rc= mysql_stmt_fetch(stmt); |
13785 | check_execute(stmt, rc); |
13786 | if (!opt_silent) |
13787 | printf("return: %s" , buf[1]); |
13788 | DIE_UNLESS(!strcmp(buf[1],"1" )); |
13789 | mysql_stmt_close(stmt); |
13790 | rc= mysql_query(mysql, "drop view v1" ); |
13791 | myquery(rc); |
13792 | rc= mysql_query(mysql, "drop table t1, t2" ); |
13793 | myquery(rc); |
13794 | } |
13795 | |
13796 | /* |
13797 | Check that proper cleanups are done for prepared statement when |
13798 | fetching thorugh a cursor. |
13799 | */ |
13800 | |
13801 | static void test_bug10729() |
13802 | { |
13803 | MYSQL_STMT *stmt; |
13804 | MYSQL_BIND my_bind[1]; |
13805 | char a[21]; |
13806 | int rc; |
13807 | const char *stmt_text; |
13808 | int i= 0; |
13809 | const char *name_array[3]= { "aaa" , "bbb" , "ccc" }; |
13810 | ulong type; |
13811 | |
13812 | myheader("test_bug10729" ); |
13813 | |
13814 | mysql_query(mysql, "drop table if exists t1" ); |
13815 | mysql_query(mysql, "create table t1 (id integer not null primary key," |
13816 | "name VARCHAR(20) NOT NULL)" ); |
13817 | rc= mysql_query(mysql, "insert into t1 (id, name) values " |
13818 | "(1, 'aaa'), (2, 'bbb'), (3, 'ccc')" ); |
13819 | myquery(rc); |
13820 | |
13821 | stmt= mysql_stmt_init(mysql); |
13822 | |
13823 | type= (ulong) CURSOR_TYPE_READ_ONLY; |
13824 | rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type); |
13825 | check_execute(stmt, rc); |
13826 | stmt_text= "select name from t1" ; |
13827 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
13828 | check_execute(stmt, rc); |
13829 | |
13830 | bzero((char*) my_bind, sizeof(my_bind)); |
13831 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
13832 | my_bind[0].buffer= (void*) a; |
13833 | my_bind[0].buffer_length= sizeof(a); |
13834 | mysql_stmt_bind_result(stmt, my_bind); |
13835 | |
13836 | for (i= 0; i < 3; i++) |
13837 | { |
13838 | int row_no= 0; |
13839 | rc= mysql_stmt_execute(stmt); |
13840 | check_execute(stmt, rc); |
13841 | while ((rc= mysql_stmt_fetch(stmt)) == 0) |
13842 | { |
13843 | DIE_UNLESS(strcmp(a, name_array[row_no]) == 0); |
13844 | if (!opt_silent) |
13845 | printf("%d: %s\n" , row_no, a); |
13846 | ++row_no; |
13847 | } |
13848 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
13849 | } |
13850 | rc= mysql_stmt_close(stmt); |
13851 | DIE_UNLESS(rc == 0); |
13852 | |
13853 | rc= mysql_query(mysql, "drop table t1" ); |
13854 | myquery(rc); |
13855 | } |
13856 | |
13857 | |
13858 | /* |
13859 | Check that mysql_next_result works properly in case when one of |
13860 | the statements used in a multi-statement query is erroneous |
13861 | */ |
13862 | |
13863 | static void test_bug9992() |
13864 | { |
13865 | MYSQL *mysql1; |
13866 | MYSQL_RES* res ; |
13867 | int rc; |
13868 | |
13869 | myheader("test_bug9992" ); |
13870 | |
13871 | if (!opt_silent) |
13872 | printf("Establishing a connection with option CLIENT_MULTI_STATEMENTS..\n" ); |
13873 | |
13874 | mysql1= mysql_client_init(NULL); |
13875 | |
13876 | if (!mysql_real_connect(mysql1, opt_host, opt_user, opt_password, |
13877 | opt_db ? opt_db : "test" , opt_port, opt_unix_socket, |
13878 | CLIENT_MULTI_STATEMENTS)) |
13879 | { |
13880 | fprintf(stderr, "Failed to connect to the database\n" ); |
13881 | DIE_UNLESS(0); |
13882 | } |
13883 | |
13884 | |
13885 | /* Sic: SHOW DATABASE is incorrect syntax. */ |
13886 | rc= mysql_query(mysql1, "SHOW TABLES; SHOW DATABASE; SELECT 1;" ); |
13887 | |
13888 | if (rc) |
13889 | { |
13890 | fprintf(stderr, "[%d] %s\n" , mysql_errno(mysql1), mysql_error(mysql1)); |
13891 | DIE_UNLESS(0); |
13892 | } |
13893 | |
13894 | if (!opt_silent) |
13895 | printf("Testing mysql_store_result/mysql_next_result..\n" ); |
13896 | |
13897 | res= mysql_store_result(mysql1); |
13898 | DIE_UNLESS(res); |
13899 | mysql_free_result(res); |
13900 | rc= mysql_next_result(mysql1); |
13901 | DIE_UNLESS(rc == 1); /* Got errors, as expected */ |
13902 | |
13903 | if (!opt_silent) |
13904 | fprintf(stdout, "Got error, as expected:\n [%d] %s\n" , |
13905 | mysql_errno(mysql1), mysql_error(mysql1)); |
13906 | |
13907 | mysql_close(mysql1); |
13908 | } |
13909 | |
13910 | /* Bug#10736: cursors and subqueries, memroot management */ |
13911 | |
13912 | static void test_bug10736() |
13913 | { |
13914 | MYSQL_STMT *stmt; |
13915 | MYSQL_BIND my_bind[1]; |
13916 | char a[21]; |
13917 | int rc; |
13918 | const char *stmt_text; |
13919 | int i= 0; |
13920 | ulong type; |
13921 | |
13922 | myheader("test_bug10736" ); |
13923 | |
13924 | mysql_query(mysql, "drop table if exists t1" ); |
13925 | mysql_query(mysql, "create table t1 (id integer not null primary key," |
13926 | "name VARCHAR(20) NOT NULL)" ); |
13927 | rc= mysql_query(mysql, "insert into t1 (id, name) values " |
13928 | "(1, 'aaa'), (2, 'bbb'), (3, 'ccc')" ); |
13929 | myquery(rc); |
13930 | |
13931 | stmt= mysql_stmt_init(mysql); |
13932 | |
13933 | type= (ulong) CURSOR_TYPE_READ_ONLY; |
13934 | rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type); |
13935 | check_execute(stmt, rc); |
13936 | stmt_text= "select name from t1 where name=(select name from t1 where id=2)" ; |
13937 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
13938 | check_execute(stmt, rc); |
13939 | |
13940 | bzero((char*) my_bind, sizeof(my_bind)); |
13941 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
13942 | my_bind[0].buffer= (void*) a; |
13943 | my_bind[0].buffer_length= sizeof(a); |
13944 | mysql_stmt_bind_result(stmt, my_bind); |
13945 | |
13946 | for (i= 0; i < 3; i++) |
13947 | { |
13948 | int row_no= 0; |
13949 | rc= mysql_stmt_execute(stmt); |
13950 | check_execute(stmt, rc); |
13951 | while ((rc= mysql_stmt_fetch(stmt)) == 0) |
13952 | { |
13953 | if (!opt_silent) |
13954 | printf("%d: %s\n" , row_no, a); |
13955 | ++row_no; |
13956 | } |
13957 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
13958 | } |
13959 | rc= mysql_stmt_close(stmt); |
13960 | DIE_UNLESS(rc == 0); |
13961 | |
13962 | rc= mysql_query(mysql, "drop table t1" ); |
13963 | myquery(rc); |
13964 | } |
13965 | |
13966 | /* Bug#10794: cursors, packets out of order */ |
13967 | |
13968 | static void test_bug10794() |
13969 | { |
13970 | MYSQL_STMT *stmt, *stmt1; |
13971 | MYSQL_BIND my_bind[2]; |
13972 | char a[21]; |
13973 | int id_val; |
13974 | ulong a_len; |
13975 | int rc; |
13976 | const char *stmt_text; |
13977 | int i= 0; |
13978 | ulong type; |
13979 | |
13980 | myheader("test_bug10794" ); |
13981 | |
13982 | mysql_query(mysql, "drop table if exists t1" ); |
13983 | mysql_query(mysql, "create table t1 (id integer not null primary key," |
13984 | "name varchar(20) not null)" ); |
13985 | stmt= mysql_stmt_init(mysql); |
13986 | stmt_text= "insert into t1 (id, name) values (?, ?)" ; |
13987 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
13988 | check_execute(stmt, rc); |
13989 | bzero((char*) my_bind, sizeof(my_bind)); |
13990 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
13991 | my_bind[0].buffer= (void*) &id_val; |
13992 | my_bind[1].buffer_type= MYSQL_TYPE_STRING; |
13993 | my_bind[1].buffer= (void*) a; |
13994 | my_bind[1].length= &a_len; |
13995 | rc= mysql_stmt_bind_param(stmt, my_bind); |
13996 | check_execute(stmt, rc); |
13997 | for (i= 0; i < 42; i++) |
13998 | { |
13999 | id_val= (i+1)*10; |
14000 | sprintf(a, "a%d" , i); |
14001 | a_len= strlen(a); /* safety against broken sprintf */ |
14002 | rc= mysql_stmt_execute(stmt); |
14003 | check_execute(stmt, rc); |
14004 | } |
14005 | stmt_text= "select name from t1" ; |
14006 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
14007 | type= (ulong) CURSOR_TYPE_READ_ONLY; |
14008 | mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type); |
14009 | stmt1= mysql_stmt_init(mysql); |
14010 | mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, (const void*) &type); |
14011 | bzero((char*) my_bind, sizeof(my_bind)); |
14012 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
14013 | my_bind[0].buffer= (void*) a; |
14014 | my_bind[0].buffer_length= sizeof(a); |
14015 | my_bind[0].length= &a_len; |
14016 | rc= mysql_stmt_bind_result(stmt, my_bind); |
14017 | check_execute(stmt, rc); |
14018 | rc= mysql_stmt_execute(stmt); |
14019 | check_execute(stmt, rc); |
14020 | rc= mysql_stmt_fetch(stmt); |
14021 | check_execute(stmt, rc); |
14022 | if (!opt_silent) |
14023 | printf("Fetched row from stmt: %s\n" , a); |
14024 | /* Don't optimize: an attribute of the original test case */ |
14025 | mysql_stmt_free_result(stmt); |
14026 | mysql_stmt_reset(stmt); |
14027 | stmt_text= "select name from t1 where id=10" ; |
14028 | rc= mysql_stmt_prepare(stmt1, stmt_text, strlen(stmt_text)); |
14029 | check_execute(stmt1, rc); |
14030 | rc= mysql_stmt_bind_result(stmt1, my_bind); |
14031 | check_execute(stmt1, rc); |
14032 | rc= mysql_stmt_execute(stmt1); |
14033 | while (1) |
14034 | { |
14035 | rc= mysql_stmt_fetch(stmt1); |
14036 | if (rc == MYSQL_NO_DATA) |
14037 | { |
14038 | if (!opt_silent) |
14039 | printf("End of data in stmt1\n" ); |
14040 | break; |
14041 | } |
14042 | check_execute(stmt1, rc); |
14043 | if (!opt_silent) |
14044 | printf("Fetched row from stmt1: %s\n" , a); |
14045 | } |
14046 | mysql_stmt_close(stmt); |
14047 | mysql_stmt_close(stmt1); |
14048 | |
14049 | rc= mysql_query(mysql, "drop table t1" ); |
14050 | myquery(rc); |
14051 | } |
14052 | |
14053 | |
14054 | /* Bug#11172: cursors, crash on a fetch from a datetime column */ |
14055 | |
14056 | static void test_bug11172() |
14057 | { |
14058 | MYSQL_STMT *stmt; |
14059 | MYSQL_BIND bind_in[1], bind_out[2]; |
14060 | MYSQL_TIME hired; |
14061 | int rc; |
14062 | const char *stmt_text; |
14063 | int i= 0, id; |
14064 | ulong type; |
14065 | |
14066 | myheader("test_bug11172" ); |
14067 | |
14068 | mysql_query(mysql, "drop table if exists t1" ); |
14069 | mysql_query(mysql, "create table t1 (id integer not null primary key," |
14070 | "hired date not null)" ); |
14071 | rc= mysql_query(mysql, |
14072 | "insert into t1 (id, hired) values (1, '1933-08-24'), " |
14073 | "(2, '1965-01-01'), (3, '1949-08-17'), (4, '1945-07-07'), " |
14074 | "(5, '1941-05-15'), (6, '1978-09-15'), (7, '1936-03-28')" ); |
14075 | myquery(rc); |
14076 | stmt= mysql_stmt_init(mysql); |
14077 | stmt_text= "SELECT id, hired FROM t1 WHERE hired=?" ; |
14078 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
14079 | check_execute(stmt, rc); |
14080 | |
14081 | type= (ulong) CURSOR_TYPE_READ_ONLY; |
14082 | mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type); |
14083 | |
14084 | bzero((char*) bind_in, sizeof(bind_in)); |
14085 | bzero((char*) bind_out, sizeof(bind_out)); |
14086 | bzero((char*) &hired, sizeof(hired)); |
14087 | hired.year= 1965; |
14088 | hired.month= 1; |
14089 | hired.day= 1; |
14090 | bind_in[0].buffer_type= MYSQL_TYPE_DATE; |
14091 | bind_in[0].buffer= (void*) &hired; |
14092 | bind_in[0].buffer_length= sizeof(hired); |
14093 | bind_out[0].buffer_type= MYSQL_TYPE_LONG; |
14094 | bind_out[0].buffer= (void*) &id; |
14095 | bind_out[1]= bind_in[0]; |
14096 | |
14097 | for (i= 0; i < 3; i++) |
14098 | { |
14099 | rc= mysql_stmt_bind_param(stmt, bind_in); |
14100 | check_execute(stmt, rc); |
14101 | rc= mysql_stmt_bind_result(stmt, bind_out); |
14102 | check_execute(stmt, rc); |
14103 | rc= mysql_stmt_execute(stmt); |
14104 | check_execute(stmt, rc); |
14105 | while ((rc= mysql_stmt_fetch(stmt)) == 0) |
14106 | { |
14107 | if (!opt_silent) |
14108 | printf("fetched data %d:%d-%d-%d\n" , id, |
14109 | hired.year, hired.month, hired.day); |
14110 | } |
14111 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
14112 | if (!mysql_stmt_free_result(stmt)) |
14113 | mysql_stmt_reset(stmt); |
14114 | } |
14115 | mysql_stmt_close(stmt); |
14116 | mysql_rollback(mysql); |
14117 | mysql_rollback(mysql); |
14118 | |
14119 | rc= mysql_query(mysql, "drop table t1" ); |
14120 | myquery(rc); |
14121 | } |
14122 | |
14123 | |
14124 | /* Bug#11656: cursors, crash on a fetch from a query with distinct. */ |
14125 | |
14126 | static void test_bug11656() |
14127 | { |
14128 | MYSQL_STMT *stmt; |
14129 | MYSQL_BIND my_bind[2]; |
14130 | int rc; |
14131 | const char *stmt_text; |
14132 | char buf[2][20]; |
14133 | int i= 0; |
14134 | ulong type; |
14135 | |
14136 | myheader("test_bug11656" ); |
14137 | |
14138 | mysql_query(mysql, "drop table if exists t1" ); |
14139 | |
14140 | rc= mysql_query(mysql, "create table t1 (" |
14141 | "server varchar(40) not null, " |
14142 | "test_kind varchar(1) not null, " |
14143 | "test_id varchar(30) not null , " |
14144 | "primary key (server,test_kind,test_id))" ); |
14145 | myquery(rc); |
14146 | |
14147 | stmt_text= "select distinct test_kind, test_id from t1 " |
14148 | "where server in (?, ?)" ; |
14149 | stmt= mysql_stmt_init(mysql); |
14150 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
14151 | check_execute(stmt, rc); |
14152 | type= (ulong) CURSOR_TYPE_READ_ONLY; |
14153 | mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type); |
14154 | |
14155 | bzero((char*) my_bind, sizeof(my_bind)); |
14156 | strmov(buf[0], "pcint502_MY2" ); |
14157 | strmov(buf[1], "*" ); |
14158 | for (i=0; i < 2; i++) |
14159 | { |
14160 | my_bind[i].buffer_type= MYSQL_TYPE_STRING; |
14161 | my_bind[i].buffer= (uchar* *)&buf[i]; |
14162 | my_bind[i].buffer_length= strlen(buf[i]); |
14163 | } |
14164 | mysql_stmt_bind_param(stmt, my_bind); |
14165 | |
14166 | rc= mysql_stmt_execute(stmt); |
14167 | check_execute(stmt, rc); |
14168 | |
14169 | rc= mysql_stmt_fetch(stmt); |
14170 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
14171 | |
14172 | mysql_stmt_close(stmt); |
14173 | rc= mysql_query(mysql, "drop table t1" ); |
14174 | myquery(rc); |
14175 | } |
14176 | |
14177 | |
14178 | /* |
14179 | Check that the server signals when NO_BACKSLASH_ESCAPES mode is in effect, |
14180 | and mysql_real_escape_string() does the right thing as a result. |
14181 | */ |
14182 | |
14183 | static void test_bug10214() |
14184 | { |
14185 | int len; |
14186 | char out[8]; |
14187 | |
14188 | myheader("test_bug10214" ); |
14189 | |
14190 | DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES)); |
14191 | |
14192 | len= mysql_real_escape_string(mysql, out, "a'b\\c" , 5); |
14193 | DIE_UNLESS(memcmp(out, "a\\'b\\\\c" , len) == 0); |
14194 | |
14195 | mysql_query(mysql, "set sql_mode='NO_BACKSLASH_ESCAPES'" ); |
14196 | DIE_UNLESS(mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES); |
14197 | |
14198 | len= mysql_real_escape_string(mysql, out, "a'b\\c" , 5); |
14199 | DIE_UNLESS(memcmp(out, "a''b\\c" , len) == 0); |
14200 | |
14201 | mysql_query(mysql, "set sql_mode=''" ); |
14202 | } |
14203 | |
14204 | static void test_client_character_set() |
14205 | { |
14206 | MY_CHARSET_INFO cs; |
14207 | char *csname= (char*) "utf8" ; |
14208 | char *csdefault= (char*)mysql_character_set_name(mysql); |
14209 | int rc; |
14210 | |
14211 | myheader("test_client_character_set" ); |
14212 | |
14213 | rc= mysql_set_character_set(mysql, csname); |
14214 | DIE_UNLESS(rc == 0); |
14215 | |
14216 | mysql_get_character_set_info(mysql, &cs); |
14217 | DIE_UNLESS(!strcmp(cs.csname, "utf8" )); |
14218 | DIE_UNLESS(!strcmp(cs.name, "utf8_general_ci" )); |
14219 | /* Restore the default character set */ |
14220 | rc= mysql_set_character_set(mysql, csdefault); |
14221 | myquery(rc); |
14222 | } |
14223 | |
14224 | /* Test correct max length for MEDIUMTEXT and LONGTEXT columns */ |
14225 | |
14226 | static void test_bug9735() |
14227 | { |
14228 | MYSQL_RES *res; |
14229 | int rc; |
14230 | |
14231 | myheader("test_bug9735" ); |
14232 | |
14233 | rc= mysql_query(mysql, "drop table if exists t1" ); |
14234 | myquery(rc); |
14235 | rc= mysql_query(mysql, "create table t1 (a mediumtext, b longtext) " |
14236 | "character set latin1" ); |
14237 | myquery(rc); |
14238 | rc= mysql_query(mysql, "select * from t1" ); |
14239 | myquery(rc); |
14240 | res= mysql_store_result(mysql); |
14241 | verify_prepare_field(res, 0, "a" , "a" , MYSQL_TYPE_BLOB, |
14242 | "t1" , "t1" , current_db, (1U << 24)-1, 0); |
14243 | verify_prepare_field(res, 1, "b" , "b" , MYSQL_TYPE_BLOB, |
14244 | "t1" , "t1" , current_db, ~0U, 0); |
14245 | mysql_free_result(res); |
14246 | rc= mysql_query(mysql, "drop table t1" ); |
14247 | myquery(rc); |
14248 | } |
14249 | |
14250 | |
14251 | /* Bug#11183 "mysql_stmt_reset() doesn't reset information about error" */ |
14252 | |
14253 | static void test_bug11183() |
14254 | { |
14255 | int rc; |
14256 | MYSQL_STMT *stmt; |
14257 | char bug_statement[]= "insert into t1 values (1)" ; |
14258 | |
14259 | myheader("test_bug11183" ); |
14260 | |
14261 | mysql_query(mysql, "drop table t1 if exists" ); |
14262 | mysql_query(mysql, "create table t1 (a int)" ); |
14263 | |
14264 | stmt= mysql_stmt_init(mysql); |
14265 | DIE_UNLESS(stmt != 0); |
14266 | |
14267 | rc= mysql_stmt_prepare(stmt, bug_statement, strlen(bug_statement)); |
14268 | check_execute(stmt, rc); |
14269 | |
14270 | rc= mysql_query(mysql, "drop table t1" ); |
14271 | myquery(rc); |
14272 | |
14273 | /* Trying to execute statement that should fail on execute stage */ |
14274 | rc= mysql_stmt_execute(stmt); |
14275 | DIE_UNLESS(rc); |
14276 | |
14277 | mysql_stmt_reset(stmt); |
14278 | DIE_UNLESS(mysql_stmt_errno(stmt) == 0); |
14279 | |
14280 | mysql_query(mysql, "create table t1 (a int)" ); |
14281 | |
14282 | /* Trying to execute statement that should pass ok */ |
14283 | if (mysql_stmt_execute(stmt)) |
14284 | { |
14285 | mysql_stmt_reset(stmt); |
14286 | DIE_UNLESS(mysql_stmt_errno(stmt) == 0); |
14287 | } |
14288 | |
14289 | mysql_stmt_close(stmt); |
14290 | |
14291 | rc= mysql_query(mysql, "drop table t1" ); |
14292 | myquery(rc); |
14293 | } |
14294 | |
14295 | static void test_bug11037() |
14296 | { |
14297 | MYSQL_STMT *stmt; |
14298 | int rc; |
14299 | const char *stmt_text; |
14300 | |
14301 | myheader("test_bug11037" ); |
14302 | |
14303 | mysql_query(mysql, "drop table if exists t1" ); |
14304 | |
14305 | rc= mysql_query(mysql, "create table t1 (id int not null)" ); |
14306 | myquery(rc); |
14307 | |
14308 | rc= mysql_query(mysql, "insert into t1 values (1)" ); |
14309 | myquery(rc); |
14310 | |
14311 | stmt_text= "select id FROM t1" ; |
14312 | stmt= mysql_stmt_init(mysql); |
14313 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
14314 | |
14315 | /* expected error */ |
14316 | rc = mysql_stmt_fetch(stmt); |
14317 | DIE_UNLESS(rc==1); |
14318 | if (!opt_silent) |
14319 | fprintf(stdout, "Got error, as expected:\n [%d] %s\n" , |
14320 | mysql_stmt_errno(stmt), mysql_stmt_error(stmt)); |
14321 | |
14322 | rc= mysql_stmt_execute(stmt); |
14323 | check_execute(stmt, rc); |
14324 | |
14325 | rc= mysql_stmt_fetch(stmt); |
14326 | DIE_UNLESS(rc==0); |
14327 | |
14328 | rc= mysql_stmt_fetch(stmt); |
14329 | DIE_UNLESS(rc==MYSQL_NO_DATA); |
14330 | |
14331 | rc= mysql_stmt_fetch(stmt); |
14332 | DIE_UNLESS(rc==MYSQL_NO_DATA); |
14333 | |
14334 | mysql_stmt_close(stmt); |
14335 | rc= mysql_query(mysql, "drop table t1" ); |
14336 | myquery(rc); |
14337 | } |
14338 | |
14339 | /* Bug#10760: cursors, crash in a fetch after rollback. */ |
14340 | |
14341 | static void test_bug10760() |
14342 | { |
14343 | MYSQL_STMT *stmt; |
14344 | MYSQL_BIND my_bind[1]; |
14345 | int rc; |
14346 | const char *stmt_text; |
14347 | char id_buf[20]; |
14348 | ulong id_len; |
14349 | int i= 0; |
14350 | ulong type; |
14351 | |
14352 | myheader("test_bug10760" ); |
14353 | |
14354 | mysql_query(mysql, "drop table if exists t1, t2" ); |
14355 | |
14356 | /* create tables */ |
14357 | rc= mysql_query(mysql, "create table t1 (id integer not null primary key)" |
14358 | " engine=MyISAM" ); |
14359 | myquery(rc); |
14360 | for (; i < 42; ++i) |
14361 | { |
14362 | char buf[100]; |
14363 | sprintf(buf, "insert into t1 (id) values (%d)" , i+1); |
14364 | rc= mysql_query(mysql, buf); |
14365 | myquery(rc); |
14366 | } |
14367 | mysql_autocommit(mysql, FALSE); |
14368 | /* create statement */ |
14369 | stmt= mysql_stmt_init(mysql); |
14370 | type= (ulong) CURSOR_TYPE_READ_ONLY; |
14371 | mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type); |
14372 | |
14373 | /* |
14374 | 1: check that a deadlock within the same connection |
14375 | is resolved and an error is returned. The deadlock is modelled |
14376 | as follows: |
14377 | con1: open cursor for select * from t1; |
14378 | con1: insert into t1 (id) values (1) |
14379 | */ |
14380 | stmt_text= "select id from t1 order by 1" ; |
14381 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
14382 | check_execute(stmt, rc); |
14383 | rc= mysql_stmt_execute(stmt); |
14384 | check_execute(stmt, rc); |
14385 | rc= mysql_query(mysql, "update t1 set id=id+100" ); |
14386 | /* |
14387 | If cursors are not materialized, the update will return an error; |
14388 | we mainly test that it won't deadlock. |
14389 | */ |
14390 | if (rc && !opt_silent) |
14391 | printf("Got error (as expected): %s\n" , mysql_error(mysql)); |
14392 | /* |
14393 | 2: check that MyISAM tables used in cursors survive |
14394 | COMMIT/ROLLBACK. |
14395 | */ |
14396 | rc= mysql_rollback(mysql); /* should not close the cursor */ |
14397 | myquery(rc); |
14398 | rc= mysql_stmt_fetch(stmt); |
14399 | check_execute(stmt, rc); |
14400 | |
14401 | /* |
14402 | 3: check that cursors to InnoDB tables are closed (for now) by |
14403 | COMMIT/ROLLBACK. |
14404 | */ |
14405 | if (! have_innodb) |
14406 | { |
14407 | if (!opt_silent) |
14408 | printf("Testing that cursors are closed at COMMIT/ROLLBACK requires " |
14409 | "InnoDB.\n" ); |
14410 | } |
14411 | else |
14412 | { |
14413 | stmt_text= "select id from t1 order by 1" ; |
14414 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
14415 | check_execute(stmt, rc); |
14416 | |
14417 | rc= mysql_query(mysql, "alter table t1 engine=InnoDB" ); |
14418 | myquery(rc); |
14419 | |
14420 | bzero(my_bind, sizeof(my_bind)); |
14421 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
14422 | my_bind[0].buffer= (void*) id_buf; |
14423 | my_bind[0].buffer_length= sizeof(id_buf); |
14424 | my_bind[0].length= &id_len; |
14425 | check_execute(stmt, rc); |
14426 | mysql_stmt_bind_result(stmt, my_bind); |
14427 | |
14428 | rc= mysql_stmt_execute(stmt); |
14429 | rc= mysql_stmt_fetch(stmt); |
14430 | DIE_UNLESS(rc == 0); |
14431 | if (!opt_silent) |
14432 | printf("Fetched row %s\n" , id_buf); |
14433 | rc= mysql_rollback(mysql); /* should close the cursor */ |
14434 | myquery(rc); |
14435 | #if 0 |
14436 | rc= mysql_stmt_fetch(stmt); |
14437 | DIE_UNLESS(rc); |
14438 | if (!opt_silent) |
14439 | printf("Got error (as expected): %s\n" , mysql_error(mysql)); |
14440 | #endif |
14441 | } |
14442 | |
14443 | mysql_stmt_close(stmt); |
14444 | rc= mysql_query(mysql, "drop table t1" ); |
14445 | myquery(rc); |
14446 | mysql_autocommit(mysql, TRUE); /* restore default */ |
14447 | } |
14448 | |
14449 | static void test_bug12001() |
14450 | { |
14451 | MYSQL *mysql_local; |
14452 | MYSQL_RES *result; |
14453 | const char *query= "DROP TABLE IF EXISTS test_table;" |
14454 | "CREATE TABLE test_table(id INT);" |
14455 | "INSERT INTO test_table VALUES(10);" |
14456 | "UPDATE test_table SET id=20 WHERE id=10;" |
14457 | "SELECT * FROM test_table;" |
14458 | "INSERT INTO non_existent_table VALUES(11);" ; |
14459 | int rc, res; |
14460 | |
14461 | myheader("test_bug12001" ); |
14462 | |
14463 | if (!(mysql_local= mysql_client_init(NULL))) |
14464 | { |
14465 | fprintf(stdout, "\n mysql_client_init() failed" ); |
14466 | exit(1); |
14467 | } |
14468 | |
14469 | /* Create connection that supports multi statements */ |
14470 | if (!mysql_real_connect(mysql_local, opt_host, opt_user, |
14471 | opt_password, current_db, opt_port, |
14472 | opt_unix_socket, CLIENT_MULTI_STATEMENTS)) |
14473 | { |
14474 | fprintf(stdout, "\n mysql_real_connect() failed" ); |
14475 | exit(1); |
14476 | } |
14477 | |
14478 | rc= mysql_query(mysql_local, query); |
14479 | myquery(rc); |
14480 | |
14481 | do |
14482 | { |
14483 | if (mysql_field_count(mysql_local) && |
14484 | (result= mysql_use_result(mysql_local))) |
14485 | { |
14486 | mysql_free_result(result); |
14487 | } |
14488 | } |
14489 | while (!(res= mysql_next_result(mysql_local))); |
14490 | |
14491 | rc= mysql_query(mysql_local, "DROP TABLE IF EXISTS test_table" ); |
14492 | myquery(rc); |
14493 | |
14494 | mysql_close(mysql_local); |
14495 | DIE_UNLESS(res==1); |
14496 | } |
14497 | |
14498 | |
14499 | /* Bug#11909: wrong metadata if fetching from two cursors */ |
14500 | |
14501 | static void test_bug11909() |
14502 | { |
14503 | MYSQL_STMT *stmt1, *stmt2; |
14504 | MYSQL_BIND my_bind[7]; |
14505 | int rc; |
14506 | char firstname[20], midinit[20], lastname[20], workdept[20]; |
14507 | ulong firstname_len, midinit_len, lastname_len, workdept_len; |
14508 | uint32 empno; |
14509 | double salary; |
14510 | float bonus; |
14511 | const char *stmt_text; |
14512 | |
14513 | myheader("test_bug11909" ); |
14514 | |
14515 | stmt_text= "drop table if exists t1" ; |
14516 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
14517 | myquery(rc); |
14518 | |
14519 | stmt_text= "create table t1 (" |
14520 | " empno int(11) not null, firstname varchar(20) not null," |
14521 | " midinit varchar(20) not null, lastname varchar(20) not null," |
14522 | " workdept varchar(6) not null, salary double not null," |
14523 | " bonus float not null, primary key (empno)" |
14524 | ") default charset=latin1 collate=latin1_bin" ; |
14525 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
14526 | myquery(rc); |
14527 | |
14528 | stmt_text= "insert into t1 values " |
14529 | "(10, 'CHRISTINE', 'I', 'HAAS', 'A00', 52750, 1000), " |
14530 | "(20, 'MICHAEL', 'L', 'THOMPSON', 'B01', 41250, 800)," |
14531 | "(30, 'SALLY', 'A', 'KWAN', 'C01', 38250, 800)," |
14532 | "(50, 'JOHN', 'B', 'GEYER', 'E01', 40175, 800), " |
14533 | "(60, 'IRVING', 'F', 'STERN', 'D11', 32250, 500)" ; |
14534 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
14535 | myquery(rc); |
14536 | |
14537 | /* ****** Begin of trace ****** */ |
14538 | |
14539 | stmt1= open_cursor("SELECT empno, firstname, midinit, lastname," |
14540 | "workdept, salary, bonus FROM t1" ); |
14541 | |
14542 | bzero(my_bind, sizeof(my_bind)); |
14543 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
14544 | my_bind[0].buffer= (void*) &empno; |
14545 | |
14546 | my_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING; |
14547 | my_bind[1].buffer= (void*) firstname; |
14548 | my_bind[1].buffer_length= sizeof(firstname); |
14549 | my_bind[1].length= &firstname_len; |
14550 | |
14551 | my_bind[2].buffer_type= MYSQL_TYPE_VAR_STRING; |
14552 | my_bind[2].buffer= (void*) midinit; |
14553 | my_bind[2].buffer_length= sizeof(midinit); |
14554 | my_bind[2].length= &midinit_len; |
14555 | |
14556 | my_bind[3].buffer_type= MYSQL_TYPE_VAR_STRING; |
14557 | my_bind[3].buffer= (void*) lastname; |
14558 | my_bind[3].buffer_length= sizeof(lastname); |
14559 | my_bind[3].length= &lastname_len; |
14560 | |
14561 | my_bind[4].buffer_type= MYSQL_TYPE_VAR_STRING; |
14562 | my_bind[4].buffer= (void*) workdept; |
14563 | my_bind[4].buffer_length= sizeof(workdept); |
14564 | my_bind[4].length= &workdept_len; |
14565 | |
14566 | my_bind[5].buffer_type= MYSQL_TYPE_DOUBLE; |
14567 | my_bind[5].buffer= (void*) &salary; |
14568 | |
14569 | my_bind[6].buffer_type= MYSQL_TYPE_FLOAT; |
14570 | my_bind[6].buffer= (void*) &bonus; |
14571 | rc= mysql_stmt_bind_result(stmt1, my_bind); |
14572 | check_execute(stmt1, rc); |
14573 | |
14574 | rc= mysql_stmt_execute(stmt1); |
14575 | check_execute(stmt1, rc); |
14576 | |
14577 | rc= mysql_stmt_fetch(stmt1); |
14578 | DIE_UNLESS(rc == 0); |
14579 | DIE_UNLESS(empno == 10); |
14580 | DIE_UNLESS(strcmp(firstname, "CHRISTINE" ) == 0); |
14581 | DIE_UNLESS(strcmp(midinit, "I" ) == 0); |
14582 | DIE_UNLESS(strcmp(lastname, "HAAS" ) == 0); |
14583 | DIE_UNLESS(strcmp(workdept, "A00" ) == 0); |
14584 | DIE_UNLESS(salary == (double) 52750.0); |
14585 | DIE_UNLESS(bonus == (float) 1000.0); |
14586 | |
14587 | stmt2= open_cursor("SELECT empno, firstname FROM t1" ); |
14588 | rc= mysql_stmt_bind_result(stmt2, my_bind); |
14589 | check_execute(stmt2, rc); |
14590 | |
14591 | rc= mysql_stmt_execute(stmt2); |
14592 | check_execute(stmt2, rc); |
14593 | |
14594 | rc= mysql_stmt_fetch(stmt2); |
14595 | DIE_UNLESS(rc == 0); |
14596 | |
14597 | DIE_UNLESS(empno == 10); |
14598 | DIE_UNLESS(strcmp(firstname, "CHRISTINE" ) == 0); |
14599 | |
14600 | rc= mysql_stmt_reset(stmt2); |
14601 | check_execute(stmt2, rc); |
14602 | |
14603 | /* ERROR: next statement should return 0 */ |
14604 | |
14605 | rc= mysql_stmt_fetch(stmt1); |
14606 | DIE_UNLESS(rc == 0); |
14607 | |
14608 | mysql_stmt_close(stmt1); |
14609 | mysql_stmt_close(stmt2); |
14610 | rc= mysql_rollback(mysql); |
14611 | myquery(rc); |
14612 | |
14613 | rc= mysql_query(mysql, "drop table t1" ); |
14614 | myquery(rc); |
14615 | } |
14616 | |
14617 | /* Cursors: opening a cursor to a compilicated query with ORDER BY */ |
14618 | |
14619 | static void test_bug11901() |
14620 | { |
14621 | MYSQL_STMT *stmt; |
14622 | MYSQL_BIND my_bind[2]; |
14623 | int rc; |
14624 | char workdept[20]; |
14625 | ulong workdept_len; |
14626 | uint32 empno; |
14627 | const char *stmt_text; |
14628 | |
14629 | myheader("test_bug11901" ); |
14630 | |
14631 | stmt_text= "drop table if exists t1, t2" ; |
14632 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
14633 | myquery(rc); |
14634 | |
14635 | stmt_text= "create table t1 (" |
14636 | " empno int(11) not null, firstname varchar(20) not null," |
14637 | " midinit varchar(20) not null, lastname varchar(20) not null," |
14638 | " workdept varchar(6) not null, salary double not null," |
14639 | " bonus float not null, primary key (empno), " |
14640 | " unique key (workdept, empno) " |
14641 | ") default charset=latin1 collate=latin1_bin" ; |
14642 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
14643 | myquery(rc); |
14644 | |
14645 | stmt_text= "insert into t1 values " |
14646 | "(10, 'CHRISTINE', 'I', 'HAAS', 'A00', 52750, 1000)," |
14647 | "(20, 'MICHAEL', 'L', 'THOMPSON', 'B01', 41250, 800), " |
14648 | "(30, 'SALLY', 'A', 'KWAN', 'C01', 38250, 800), " |
14649 | "(50, 'JOHN', 'B', 'GEYER', 'E01', 40175, 800), " |
14650 | "(60, 'IRVING', 'F', 'STERN', 'D11', 32250, 500), " |
14651 | "(70, 'EVA', 'D', 'PULASKI', 'D21', 36170, 700), " |
14652 | "(90, 'EILEEN', 'W', 'HENDERSON', 'E11', 29750, 600), " |
14653 | "(100, 'THEODORE', 'Q', 'SPENSER', 'E21', 26150, 500), " |
14654 | "(110, 'VINCENZO', 'G', 'LUCCHESSI', 'A00', 46500, 900), " |
14655 | "(120, 'SEAN', '', 'O\\'CONNELL', 'A00', 29250, 600), " |
14656 | "(130, 'DOLORES', 'M', 'QUINTANA', 'C01', 23800, 500), " |
14657 | "(140, 'HEATHER', 'A', 'NICHOLLS', 'C01', 28420, 600), " |
14658 | "(150, 'BRUCE', '', 'ADAMSON', 'D11', 25280, 500), " |
14659 | "(160, 'ELIZABETH', 'R', 'PIANKA', 'D11', 22250, 400), " |
14660 | "(170, 'MASATOSHI', 'J', 'YOSHIMURA', 'D11', 24680, 500), " |
14661 | "(180, 'MARILYN', 'S', 'SCOUTTEN', 'D11', 21340, 500), " |
14662 | "(190, 'JAMES', 'H', 'WALKER', 'D11', 20450, 400), " |
14663 | "(200, 'DAVID', '', 'BROWN', 'D11', 27740, 600), " |
14664 | "(210, 'WILLIAM', 'T', 'JONES', 'D11', 18270, 400), " |
14665 | "(220, 'JENNIFER', 'K', 'LUTZ', 'D11', 29840, 600), " |
14666 | "(230, 'JAMES', 'J', 'JEFFERSON', 'D21', 22180, 400), " |
14667 | "(240, 'SALVATORE', 'M', 'MARINO', 'D21', 28760, 600), " |
14668 | "(250, 'DANIEL', 'S', 'SMITH', 'D21', 19180, 400), " |
14669 | "(260, 'SYBIL', 'P', 'JOHNSON', 'D21', 17250, 300), " |
14670 | "(270, 'MARIA', 'L', 'PEREZ', 'D21', 27380, 500), " |
14671 | "(280, 'ETHEL', 'R', 'SCHNEIDER', 'E11', 26250, 500), " |
14672 | "(290, 'JOHN', 'R', 'PARKER', 'E11', 15340, 300), " |
14673 | "(300, 'PHILIP', 'X', 'SMITH', 'E11', 17750, 400), " |
14674 | "(310, 'MAUDE', 'F', 'SETRIGHT', 'E11', 15900, 300), " |
14675 | "(320, 'RAMLAL', 'V', 'MEHTA', 'E21', 19950, 400), " |
14676 | "(330, 'WING', '', 'LEE', 'E21', 25370, 500), " |
14677 | "(340, 'JASON', 'R', 'GOUNOT', 'E21', 23840, 500)" ; |
14678 | |
14679 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
14680 | myquery(rc); |
14681 | |
14682 | stmt_text= "create table t2 (" |
14683 | " deptno varchar(6) not null, deptname varchar(20) not null," |
14684 | " mgrno int(11) not null, location varchar(20) not null," |
14685 | " admrdept varchar(6) not null, refcntd int(11) not null," |
14686 | " refcntu int(11) not null, primary key (deptno)" |
14687 | ") default charset=latin1 collate=latin1_bin" ; |
14688 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
14689 | myquery(rc); |
14690 | |
14691 | stmt_text= "insert into t2 values " |
14692 | "('A00', 'SPIFFY COMPUTER SERV', 10, '', 'A00', 0, 0), " |
14693 | "('B01', 'PLANNING', 20, '', 'A00', 0, 0), " |
14694 | "('C01', 'INFORMATION CENTER', 30, '', 'A00', 0, 0), " |
14695 | "('D01', 'DEVELOPMENT CENTER', 0, '', 'A00', 0, 0)," |
14696 | "('D11', 'MANUFACTURING SYSTEM', 60, '', 'D01', 0, 0), " |
14697 | "('D21', 'ADMINISTRATION SYSTE', 70, '', 'D01', 0, 0), " |
14698 | "('E01', 'SUPPORT SERVICES', 50, '', 'A00', 0, 0), " |
14699 | "('E11', 'OPERATIONS', 90, '', 'E01', 0, 0), " |
14700 | "('E21', 'SOFTWARE SUPPORT', 100,'', 'E01', 0, 0)" ; |
14701 | rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); |
14702 | myquery(rc); |
14703 | |
14704 | /* ****** Begin of trace ****** */ |
14705 | |
14706 | stmt= open_cursor("select t1.empno, t1.workdept " |
14707 | "from (t1 left join t2 on t2.deptno = t1.workdept) " |
14708 | "where t2.deptno in " |
14709 | " (select t2.deptno " |
14710 | " from (t1 left join t2 on t2.deptno = t1.workdept) " |
14711 | " where t1.empno = ?) " |
14712 | "order by 1" ); |
14713 | bzero(my_bind, sizeof(my_bind)); |
14714 | |
14715 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
14716 | my_bind[0].buffer= &empno; |
14717 | rc= mysql_stmt_bind_param(stmt, my_bind); |
14718 | check_execute(stmt, rc); |
14719 | |
14720 | my_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING; |
14721 | my_bind[1].buffer= (void*) workdept; |
14722 | my_bind[1].buffer_length= sizeof(workdept); |
14723 | my_bind[1].length= &workdept_len; |
14724 | |
14725 | rc= mysql_stmt_bind_result(stmt, my_bind); |
14726 | check_execute(stmt, rc); |
14727 | |
14728 | empno= 10; |
14729 | /* ERROR: next statement causes a server crash */ |
14730 | rc= mysql_stmt_execute(stmt); |
14731 | check_execute(stmt, rc); |
14732 | |
14733 | mysql_stmt_close(stmt); |
14734 | |
14735 | rc= mysql_query(mysql, "drop table t1, t2" ); |
14736 | myquery(rc); |
14737 | } |
14738 | |
14739 | /* Bug#11904: mysql_stmt_attr_set CURSOR_TYPE_READ_ONLY grouping wrong result */ |
14740 | |
14741 | static void test_bug11904() |
14742 | { |
14743 | MYSQL_STMT *stmt1; |
14744 | int rc; |
14745 | const char *stmt_text; |
14746 | const ulong type= (ulong)CURSOR_TYPE_READ_ONLY; |
14747 | MYSQL_BIND my_bind[2]; |
14748 | int country_id=0; |
14749 | char row_data[11]= {0}; |
14750 | |
14751 | myheader("test_bug11904" ); |
14752 | |
14753 | /* create tables */ |
14754 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS bug11904b" ); |
14755 | myquery(rc); |
14756 | rc= mysql_query(mysql, "CREATE TABLE bug11904b (id int, name char(10), primary key(id, name))" ); |
14757 | myquery(rc); |
14758 | |
14759 | rc= mysql_query(mysql, "INSERT INTO bug11904b VALUES (1, 'sofia'), (1,'plovdiv')," |
14760 | " (1,'varna'), (2,'LA'), (2,'new york'), (3,'heidelberg')," |
14761 | " (3,'berlin'), (3, 'frankfurt')" ); |
14762 | |
14763 | myquery(rc); |
14764 | mysql_commit(mysql); |
14765 | /* create statement */ |
14766 | stmt1= mysql_stmt_init(mysql); |
14767 | mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, (const void*) &type); |
14768 | |
14769 | stmt_text= "SELECT id, MIN(name) FROM bug11904b GROUP BY id" ; |
14770 | |
14771 | rc= mysql_stmt_prepare(stmt1, stmt_text, strlen(stmt_text)); |
14772 | check_execute(stmt1, rc); |
14773 | |
14774 | memset(my_bind, 0, sizeof(my_bind)); |
14775 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
14776 | my_bind[0].buffer=& country_id; |
14777 | my_bind[0].buffer_length= 0; |
14778 | my_bind[0].length= 0; |
14779 | |
14780 | my_bind[1].buffer_type= MYSQL_TYPE_STRING; |
14781 | my_bind[1].buffer=& row_data; |
14782 | my_bind[1].buffer_length= sizeof(row_data) - 1; |
14783 | my_bind[1].length= 0; |
14784 | |
14785 | rc= mysql_stmt_bind_result(stmt1, my_bind); |
14786 | check_execute(stmt1, rc); |
14787 | |
14788 | rc= mysql_stmt_execute(stmt1); |
14789 | check_execute(stmt1, rc); |
14790 | |
14791 | rc= mysql_stmt_fetch(stmt1); |
14792 | check_execute(stmt1, rc); |
14793 | DIE_UNLESS(country_id == 1); |
14794 | DIE_UNLESS(memcmp(row_data, "plovdiv" , 7) == 0); |
14795 | |
14796 | rc= mysql_stmt_fetch(stmt1); |
14797 | check_execute(stmt1, rc); |
14798 | DIE_UNLESS(country_id == 2); |
14799 | DIE_UNLESS(memcmp(row_data, "LA" , 2) == 0); |
14800 | |
14801 | rc= mysql_stmt_fetch(stmt1); |
14802 | check_execute(stmt1, rc); |
14803 | DIE_UNLESS(country_id == 3); |
14804 | DIE_UNLESS(memcmp(row_data, "berlin" , 6) == 0); |
14805 | |
14806 | rc= mysql_stmt_close(stmt1); |
14807 | check_execute(stmt1, rc); |
14808 | |
14809 | rc= mysql_query(mysql, "drop table bug11904b" ); |
14810 | myquery(rc); |
14811 | } |
14812 | |
14813 | |
14814 | /* Bug#12243: multiple cursors, crash in a fetch after commit. */ |
14815 | |
14816 | static void test_bug12243() |
14817 | { |
14818 | MYSQL_STMT *stmt1, *stmt2; |
14819 | int rc; |
14820 | const char *stmt_text; |
14821 | ulong type; |
14822 | |
14823 | myheader("test_bug12243" ); |
14824 | |
14825 | if (! have_innodb) |
14826 | { |
14827 | if (!opt_silent) |
14828 | printf("This test requires InnoDB.\n" ); |
14829 | return; |
14830 | } |
14831 | |
14832 | /* create tables */ |
14833 | mysql_query(mysql, "drop table if exists t1" ); |
14834 | mysql_query(mysql, "create table t1 (a int) engine=InnoDB" ); |
14835 | rc= mysql_query(mysql, "insert into t1 (a) values (1), (2)" ); |
14836 | myquery(rc); |
14837 | mysql_autocommit(mysql, FALSE); |
14838 | /* create statement */ |
14839 | stmt1= mysql_stmt_init(mysql); |
14840 | stmt2= mysql_stmt_init(mysql); |
14841 | type= (ulong) CURSOR_TYPE_READ_ONLY; |
14842 | mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, (const void*) &type); |
14843 | mysql_stmt_attr_set(stmt2, STMT_ATTR_CURSOR_TYPE, (const void*) &type); |
14844 | |
14845 | stmt_text= "select a from t1" ; |
14846 | |
14847 | rc= mysql_stmt_prepare(stmt1, stmt_text, strlen(stmt_text)); |
14848 | check_execute(stmt1, rc); |
14849 | rc= mysql_stmt_execute(stmt1); |
14850 | check_execute(stmt1, rc); |
14851 | rc= mysql_stmt_fetch(stmt1); |
14852 | check_execute(stmt1, rc); |
14853 | |
14854 | rc= mysql_stmt_prepare(stmt2, stmt_text, strlen(stmt_text)); |
14855 | check_execute(stmt2, rc); |
14856 | rc= mysql_stmt_execute(stmt2); |
14857 | check_execute(stmt2, rc); |
14858 | rc= mysql_stmt_fetch(stmt2); |
14859 | check_execute(stmt2, rc); |
14860 | |
14861 | rc= mysql_stmt_close(stmt1); |
14862 | check_execute(stmt1, rc); |
14863 | rc= mysql_commit(mysql); |
14864 | myquery(rc); |
14865 | rc= mysql_stmt_fetch(stmt2); |
14866 | check_execute(stmt2, rc); |
14867 | |
14868 | mysql_stmt_close(stmt2); |
14869 | rc= mysql_query(mysql, "drop table t1" ); |
14870 | myquery(rc); |
14871 | mysql_autocommit(mysql, TRUE); /* restore default */ |
14872 | } |
14873 | |
14874 | |
14875 | /* |
14876 | Bug#11718: query with function, join and order by returns wrong type |
14877 | */ |
14878 | |
14879 | static void test_bug11718() |
14880 | { |
14881 | MYSQL_RES *res; |
14882 | int rc; |
14883 | const char *query= "select str_to_date(concat(f3),'%Y%m%d') from t1,t2 " |
14884 | "where f1=f2 order by f1" ; |
14885 | |
14886 | myheader("test_bug11718" ); |
14887 | |
14888 | rc= mysql_query(mysql, "drop table if exists t1, t2" ); |
14889 | myquery(rc); |
14890 | rc= mysql_query(mysql, "create table t1 (f1 int)" ); |
14891 | myquery(rc); |
14892 | rc= mysql_query(mysql, "create table t2 (f2 int, f3 numeric(8))" ); |
14893 | myquery(rc); |
14894 | rc= mysql_query(mysql, "insert into t1 values (1), (2)" ); |
14895 | myquery(rc); |
14896 | rc= mysql_query(mysql, "insert into t2 values (1,20050101), (2,20050202)" ); |
14897 | myquery(rc); |
14898 | rc= mysql_query(mysql, query); |
14899 | myquery(rc); |
14900 | res = mysql_store_result(mysql); |
14901 | |
14902 | if (!opt_silent) |
14903 | printf("return type: %s" , (res->fields[0].type == MYSQL_TYPE_DATE)?"DATE" : |
14904 | "not DATE" ); |
14905 | DIE_UNLESS(res->fields[0].type == MYSQL_TYPE_DATE); |
14906 | mysql_free_result(res); |
14907 | rc= mysql_query(mysql, "drop table t1, t2" ); |
14908 | myquery(rc); |
14909 | } |
14910 | |
14911 | |
14912 | /* |
14913 | Bug #12925: Bad handling of maximum values in getopt |
14914 | */ |
14915 | static void test_bug12925() |
14916 | { |
14917 | myheader("test_bug12925" ); |
14918 | if (opt_getopt_ll_test) |
14919 | DIE_UNLESS(opt_getopt_ll_test == 25600LL*1024*1024); |
14920 | } |
14921 | |
14922 | |
14923 | /* |
14924 | Bug#14210 "Simple query with > operator on large table gives server |
14925 | crash" |
14926 | */ |
14927 | |
14928 | static void test_bug14210() |
14929 | { |
14930 | MYSQL_STMT *stmt; |
14931 | int rc, i; |
14932 | const char *stmt_text; |
14933 | ulong type; |
14934 | |
14935 | myheader("test_bug14210" ); |
14936 | |
14937 | mysql_query(mysql, "drop table if exists t1" ); |
14938 | /* |
14939 | To trigger the problem the table must be InnoDB, although the problem |
14940 | itself is not InnoDB related. In case the table is MyISAM this test |
14941 | is harmless. |
14942 | */ |
14943 | mysql_query(mysql, "create table t1 (a varchar(255)) engine=InnoDB" ); |
14944 | rc= mysql_query(mysql, "insert into t1 (a) values (repeat('a', 256))" ); |
14945 | myquery(rc); |
14946 | rc= mysql_query(mysql, "set @@session.max_heap_table_size=16384" ); |
14947 | /* Create a big enough table (more than max_heap_table_size) */ |
14948 | for (i= 0; i < 8; i++) |
14949 | { |
14950 | rc= mysql_query(mysql, "insert into t1 (a) select a from t1" ); |
14951 | myquery(rc); |
14952 | } |
14953 | /* create statement */ |
14954 | stmt= mysql_stmt_init(mysql); |
14955 | type= (ulong) CURSOR_TYPE_READ_ONLY; |
14956 | mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type); |
14957 | |
14958 | stmt_text= "select a from t1" ; |
14959 | |
14960 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
14961 | check_execute(stmt, rc); |
14962 | rc= mysql_stmt_execute(stmt); |
14963 | while ((rc= mysql_stmt_fetch(stmt)) == 0) |
14964 | ; |
14965 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
14966 | |
14967 | rc= mysql_stmt_close(stmt); |
14968 | |
14969 | rc= mysql_query(mysql, "drop table t1" ); |
14970 | myquery(rc); |
14971 | rc= mysql_query(mysql, "set @@session.max_heap_table_size=default" ); |
14972 | myquery(rc); |
14973 | } |
14974 | |
14975 | /* Bug#13488: wrong column metadata when fetching from cursor */ |
14976 | |
14977 | static void test_bug13488() |
14978 | { |
14979 | MYSQL_BIND my_bind[3]; |
14980 | MYSQL_STMT *stmt1; |
14981 | int rc, f1, f2, f3, i; |
14982 | const ulong type= CURSOR_TYPE_READ_ONLY; |
14983 | const char *query= "select * from t1 left join t2 on f1=f2 where f1=1" ; |
14984 | |
14985 | myheader("test_bug13488" ); |
14986 | |
14987 | rc= mysql_query(mysql, "drop table if exists t1, t2" ); |
14988 | myquery(rc); |
14989 | rc= mysql_query(mysql, "create table t1 (f1 int not null primary key)" ); |
14990 | myquery(rc); |
14991 | rc= mysql_query(mysql, "create table t2 (f2 int not null primary key, " |
14992 | "f3 int not null)" ); |
14993 | myquery(rc); |
14994 | rc= mysql_query(mysql, "insert into t1 values (1), (2)" ); |
14995 | myquery(rc); |
14996 | rc= mysql_query(mysql, "insert into t2 values (1,2), (2,4)" ); |
14997 | myquery(rc); |
14998 | |
14999 | memset(my_bind, 0, sizeof(my_bind)); |
15000 | for (i= 0; i < 3; i++) |
15001 | { |
15002 | my_bind[i].buffer_type= MYSQL_TYPE_LONG; |
15003 | my_bind[i].buffer_length= 4; |
15004 | my_bind[i].length= 0; |
15005 | } |
15006 | my_bind[0].buffer=&f1; |
15007 | my_bind[1].buffer=&f2; |
15008 | my_bind[2].buffer=&f3; |
15009 | |
15010 | stmt1= mysql_stmt_init(mysql); |
15011 | rc= mysql_stmt_attr_set(stmt1,STMT_ATTR_CURSOR_TYPE, (const void *)&type); |
15012 | check_execute(stmt1, rc); |
15013 | |
15014 | rc= mysql_stmt_prepare(stmt1, query, strlen(query)); |
15015 | check_execute(stmt1, rc); |
15016 | |
15017 | rc= mysql_stmt_execute(stmt1); |
15018 | check_execute(stmt1, rc); |
15019 | |
15020 | rc= mysql_stmt_bind_result(stmt1, my_bind); |
15021 | check_execute(stmt1, rc); |
15022 | |
15023 | rc= mysql_stmt_fetch(stmt1); |
15024 | check_execute(stmt1, rc); |
15025 | |
15026 | rc= mysql_stmt_free_result(stmt1); |
15027 | check_execute(stmt1, rc); |
15028 | |
15029 | rc= mysql_stmt_reset(stmt1); |
15030 | check_execute(stmt1, rc); |
15031 | |
15032 | rc= mysql_stmt_close(stmt1); |
15033 | check_execute(stmt1, rc); |
15034 | |
15035 | if (!opt_silent) |
15036 | { |
15037 | printf("data: f1: %d; f2: %d; f3: %d\n" , f1, f2, f3); |
15038 | printf("data is: %s\n" , |
15039 | (f1 == 1 && f2 == 1 && f3 == 2) ? "OK" : "wrong" ); |
15040 | } |
15041 | DIE_UNLESS(f1 == 1 && f2 == 1 && f3 == 2); |
15042 | rc= mysql_query(mysql, "drop table t1, t2" ); |
15043 | myquery(rc); |
15044 | } |
15045 | |
15046 | /* |
15047 | Bug#13524: warnings of a previous command are not reset when fetching |
15048 | from a cursor. |
15049 | */ |
15050 | |
15051 | static void test_bug13524() |
15052 | { |
15053 | MYSQL_STMT *stmt; |
15054 | int rc; |
15055 | unsigned int warning_count; |
15056 | const ulong type= CURSOR_TYPE_READ_ONLY; |
15057 | const char *query= "select * from t1" ; |
15058 | |
15059 | myheader("test_bug13524" ); |
15060 | |
15061 | rc= mysql_query(mysql, "drop table if exists t1, t2" ); |
15062 | myquery(rc); |
15063 | rc= mysql_query(mysql, "create table t1 (a int not null primary key)" ); |
15064 | myquery(rc); |
15065 | rc= mysql_query(mysql, "insert into t1 values (1), (2), (3), (4)" ); |
15066 | myquery(rc); |
15067 | |
15068 | stmt= mysql_stmt_init(mysql); |
15069 | rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type); |
15070 | check_execute(stmt, rc); |
15071 | |
15072 | rc= mysql_stmt_prepare(stmt, query, strlen(query)); |
15073 | check_execute(stmt, rc); |
15074 | |
15075 | rc= mysql_stmt_execute(stmt); |
15076 | check_execute(stmt, rc); |
15077 | |
15078 | rc= mysql_stmt_fetch(stmt); |
15079 | check_execute(stmt, rc); |
15080 | |
15081 | warning_count= mysql_warning_count(mysql); |
15082 | DIE_UNLESS(warning_count == 0); |
15083 | |
15084 | /* Check that DROP TABLE produced a warning (no such table) */ |
15085 | rc= mysql_query(mysql, "drop table if exists t2" ); |
15086 | myquery(rc); |
15087 | warning_count= mysql_warning_count(mysql); |
15088 | DIE_UNLESS(warning_count == 1); |
15089 | |
15090 | /* |
15091 | Check that fetch from a cursor cleared the warning from the previous |
15092 | command. |
15093 | */ |
15094 | rc= mysql_stmt_fetch(stmt); |
15095 | check_execute(stmt, rc); |
15096 | warning_count= mysql_warning_count(mysql); |
15097 | DIE_UNLESS(warning_count == 0); |
15098 | |
15099 | /* Cleanup */ |
15100 | mysql_stmt_close(stmt); |
15101 | rc= mysql_query(mysql, "drop table t1" ); |
15102 | myquery(rc); |
15103 | } |
15104 | |
15105 | /* |
15106 | Bug#14845 "mysql_stmt_fetch returns MYSQL_NO_DATA when COUNT(*) is 0" |
15107 | */ |
15108 | |
15109 | static void test_bug14845() |
15110 | { |
15111 | MYSQL_STMT *stmt; |
15112 | int rc; |
15113 | const ulong type= CURSOR_TYPE_READ_ONLY; |
15114 | const char *query= "select count(*) from t1 where 1 = 0" ; |
15115 | |
15116 | myheader("test_bug14845" ); |
15117 | |
15118 | rc= mysql_query(mysql, "drop table if exists t1" ); |
15119 | myquery(rc); |
15120 | rc= mysql_query(mysql, "create table t1 (id int(11) default null, " |
15121 | "name varchar(20) default null)" |
15122 | "engine=MyISAM DEFAULT CHARSET=utf8" ); |
15123 | myquery(rc); |
15124 | rc= mysql_query(mysql, "insert into t1 values (1,'abc'),(2,'def')" ); |
15125 | myquery(rc); |
15126 | |
15127 | stmt= mysql_stmt_init(mysql); |
15128 | rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type); |
15129 | check_execute(stmt, rc); |
15130 | |
15131 | rc= mysql_stmt_prepare(stmt, query, strlen(query)); |
15132 | check_execute(stmt, rc); |
15133 | |
15134 | rc= mysql_stmt_execute(stmt); |
15135 | check_execute(stmt, rc); |
15136 | |
15137 | rc= mysql_stmt_fetch(stmt); |
15138 | DIE_UNLESS(rc == 0); |
15139 | |
15140 | rc= mysql_stmt_fetch(stmt); |
15141 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
15142 | |
15143 | /* Cleanup */ |
15144 | mysql_stmt_close(stmt); |
15145 | rc= mysql_query(mysql, "drop table t1" ); |
15146 | myquery(rc); |
15147 | } |
15148 | |
15149 | |
15150 | /* |
15151 | Bug #15510: mysql_warning_count returns 0 after mysql_stmt_fetch which |
15152 | should warn |
15153 | */ |
15154 | static void test_bug15510() |
15155 | { |
15156 | MYSQL_STMT *stmt; |
15157 | int rc; |
15158 | const char *query= "select 1 from dual where 1/0" ; |
15159 | |
15160 | myheader("test_bug15510" ); |
15161 | |
15162 | rc= mysql_query(mysql, "set @@sql_mode='ERROR_FOR_DIVISION_BY_ZERO'" ); |
15163 | myquery(rc); |
15164 | |
15165 | stmt= mysql_stmt_init(mysql); |
15166 | |
15167 | rc= mysql_stmt_prepare(stmt, query, strlen(query)); |
15168 | check_execute(stmt, rc); |
15169 | |
15170 | rc= mysql_stmt_execute(stmt); |
15171 | check_execute(stmt, rc); |
15172 | |
15173 | rc= mysql_stmt_fetch(stmt); |
15174 | DIE_UNLESS(mysql_warning_count(mysql)); |
15175 | |
15176 | /* Cleanup */ |
15177 | mysql_stmt_close(stmt); |
15178 | rc= mysql_query(mysql, "set @@sql_mode=''" ); |
15179 | myquery(rc); |
15180 | } |
15181 | |
15182 | |
15183 | /* Test MYSQL_OPT_RECONNECT, Bug#15719 */ |
15184 | |
15185 | static void test_opt_reconnect() |
15186 | { |
15187 | MYSQL *lmysql; |
15188 | |
15189 | |
15190 | myheader("test_opt_reconnect" ); |
15191 | |
15192 | if (!(lmysql= mysql_client_init(NULL))) |
15193 | { |
15194 | myerror("mysql_client_init() failed" ); |
15195 | exit(1); |
15196 | } |
15197 | |
15198 | if (!opt_silent) |
15199 | fprintf(stdout, "reconnect before mysql_options: %d\n" , get_reconnect(lmysql)); |
15200 | DIE_UNLESS(get_reconnect(lmysql) == 0); |
15201 | |
15202 | if (mysql_options(lmysql, MYSQL_OPT_RECONNECT, &my_true)) |
15203 | { |
15204 | myerror("mysql_options failed: unknown option MYSQL_OPT_RECONNECT\n" ); |
15205 | DIE_UNLESS(0); |
15206 | } |
15207 | |
15208 | /* reconnect should be 1 */ |
15209 | if (!opt_silent) |
15210 | fprintf(stdout, "reconnect after mysql_options: %d\n" , get_reconnect(lmysql)); |
15211 | DIE_UNLESS(get_reconnect(lmysql) == 1); |
15212 | |
15213 | if (!(mysql_real_connect(lmysql, opt_host, opt_user, |
15214 | opt_password, current_db, opt_port, |
15215 | opt_unix_socket, 0))) |
15216 | { |
15217 | myerror("connection failed" ); |
15218 | DIE_UNLESS(0); |
15219 | } |
15220 | |
15221 | /* reconnect should still be 1 */ |
15222 | if (!opt_silent) |
15223 | fprintf(stdout, "reconnect after mysql_real_connect: %d\n" , |
15224 | get_reconnect(lmysql)); |
15225 | DIE_UNLESS(get_reconnect(lmysql) == 1); |
15226 | |
15227 | mysql_close(lmysql); |
15228 | |
15229 | if (!(lmysql= mysql_client_init(NULL))) |
15230 | { |
15231 | myerror("mysql_client_init() failed" ); |
15232 | DIE_UNLESS(0); |
15233 | } |
15234 | |
15235 | if (!opt_silent) |
15236 | fprintf(stdout, "reconnect before mysql_real_connect: %d\n" , get_reconnect(lmysql)); |
15237 | DIE_UNLESS(get_reconnect(lmysql) == 0); |
15238 | |
15239 | if (!(mysql_real_connect(lmysql, opt_host, opt_user, |
15240 | opt_password, current_db, opt_port, |
15241 | opt_unix_socket, 0))) |
15242 | { |
15243 | myerror("connection failed" ); |
15244 | DIE_UNLESS(0); |
15245 | } |
15246 | |
15247 | /* reconnect should still be 0 */ |
15248 | if (!opt_silent) |
15249 | fprintf(stdout, "reconnect after mysql_real_connect: %d\n" , |
15250 | get_reconnect(lmysql)); |
15251 | DIE_UNLESS(get_reconnect(lmysql) == 0); |
15252 | |
15253 | mysql_close(lmysql); |
15254 | } |
15255 | |
15256 | |
15257 | #ifndef EMBEDDED_LIBRARY |
15258 | |
15259 | static void test_bug12744() |
15260 | { |
15261 | MYSQL_STMT *prep_stmt = NULL; |
15262 | MYSQL *lmysql; |
15263 | int rc; |
15264 | myheader("test_bug12744" ); |
15265 | |
15266 | lmysql= mysql_client_init(NULL); |
15267 | DIE_UNLESS(lmysql); |
15268 | |
15269 | if (!mysql_real_connect(lmysql, opt_host, opt_user, opt_password, |
15270 | current_db, opt_port, opt_unix_socket, 0)) |
15271 | { |
15272 | fprintf(stderr, "Failed to connect to the database\n" ); |
15273 | DIE_UNLESS(0); |
15274 | } |
15275 | |
15276 | prep_stmt= mysql_stmt_init(lmysql); |
15277 | rc= mysql_stmt_prepare(prep_stmt, "SELECT 1" , 8); |
15278 | DIE_UNLESS(rc == 0); |
15279 | |
15280 | mysql_close(lmysql); |
15281 | |
15282 | rc= mysql_stmt_execute(prep_stmt); |
15283 | DIE_UNLESS(rc); |
15284 | rc= mysql_stmt_reset(prep_stmt); |
15285 | DIE_UNLESS(rc); |
15286 | rc= mysql_stmt_close(prep_stmt); |
15287 | DIE_UNLESS(rc == 0); |
15288 | } |
15289 | |
15290 | #endif /* EMBEDDED_LIBRARY */ |
15291 | |
15292 | /* Bug #16143: mysql_stmt_sqlstate returns an empty string instead of '00000' */ |
15293 | |
15294 | static void test_bug16143() |
15295 | { |
15296 | MYSQL_STMT *stmt; |
15297 | myheader("test_bug16143" ); |
15298 | |
15299 | stmt= mysql_stmt_init(mysql); |
15300 | /* Check mysql_stmt_sqlstate return "no error" */ |
15301 | DIE_UNLESS(strcmp(mysql_stmt_sqlstate(stmt), "00000" ) == 0); |
15302 | |
15303 | mysql_stmt_close(stmt); |
15304 | } |
15305 | |
15306 | |
15307 | /* Bug #16144: mysql_stmt_attr_get type error */ |
15308 | |
15309 | static void test_bug16144() |
15310 | { |
15311 | const my_bool flag_orig= (my_bool) 0xde; |
15312 | my_bool flag= flag_orig; |
15313 | MYSQL_STMT *stmt; |
15314 | myheader("test_bug16144" ); |
15315 | |
15316 | /* Check that attr_get returns correct data on little and big endian CPUs */ |
15317 | stmt= mysql_stmt_init(mysql); |
15318 | mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (const void*) &flag); |
15319 | mysql_stmt_attr_get(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &flag); |
15320 | DIE_UNLESS(flag == flag_orig); |
15321 | |
15322 | mysql_stmt_close(stmt); |
15323 | } |
15324 | |
15325 | /* |
15326 | Bug #15613: "libmysqlclient API function mysql_stmt_prepare returns wrong |
15327 | field length" |
15328 | */ |
15329 | |
15330 | static void test_bug15613() |
15331 | { |
15332 | MYSQL_STMT *stmt; |
15333 | const char *stmt_text; |
15334 | MYSQL_RES *metadata; |
15335 | MYSQL_FIELD *field; |
15336 | int rc; |
15337 | myheader("test_bug15613" ); |
15338 | |
15339 | /* I. Prepare the table */ |
15340 | rc= mysql_query(mysql, "set names latin1" ); |
15341 | myquery(rc); |
15342 | mysql_query(mysql, "drop table if exists t1" ); |
15343 | rc= mysql_query(mysql, |
15344 | "create table t1 (t text character set utf8, " |
15345 | "tt tinytext character set utf8, " |
15346 | "mt mediumtext character set utf8, " |
15347 | "lt longtext character set utf8, " |
15348 | "vl varchar(255) character set latin1," |
15349 | "vb varchar(255) character set binary," |
15350 | "vu varchar(255) character set utf8)" ); |
15351 | myquery(rc); |
15352 | |
15353 | stmt= mysql_stmt_init(mysql); |
15354 | |
15355 | /* II. Check SELECT metadata */ |
15356 | stmt_text= ("select t, tt, mt, lt, vl, vb, vu from t1" ); |
15357 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
15358 | metadata= mysql_stmt_result_metadata(stmt); |
15359 | field= mysql_fetch_fields(metadata); |
15360 | if (!opt_silent) |
15361 | { |
15362 | printf("Field lengths (client character set is latin1):\n" |
15363 | "text character set utf8:\t\t%lu\n" |
15364 | "tinytext character set utf8:\t\t%lu\n" |
15365 | "mediumtext character set utf8:\t\t%lu\n" |
15366 | "longtext character set utf8:\t\t%lu\n" |
15367 | "varchar(255) character set latin1:\t%lu\n" |
15368 | "varchar(255) character set binary:\t%lu\n" |
15369 | "varchar(255) character set utf8:\t%lu\n" , |
15370 | field[0].length, field[1].length, field[2].length, field[3].length, |
15371 | field[4].length, field[5].length, field[6].length); |
15372 | } |
15373 | DIE_UNLESS(field[0].length == 65535); |
15374 | DIE_UNLESS(field[1].length == 255); |
15375 | DIE_UNLESS(field[2].length == 16777215); |
15376 | DIE_UNLESS(field[3].length == 4294967295UL); |
15377 | DIE_UNLESS(field[4].length == 255); |
15378 | DIE_UNLESS(field[5].length == 255); |
15379 | DIE_UNLESS(field[6].length == 255); |
15380 | mysql_free_result(metadata); |
15381 | mysql_stmt_free_result(stmt); |
15382 | |
15383 | /* III. Cleanup */ |
15384 | rc= mysql_query(mysql, "drop table t1" ); |
15385 | myquery(rc); |
15386 | rc= mysql_query(mysql, "set names default" ); |
15387 | myquery(rc); |
15388 | mysql_stmt_close(stmt); |
15389 | } |
15390 | |
15391 | /* |
15392 | Bug#17667: An attacker has the opportunity to bypass query logging. |
15393 | |
15394 | Note! Also tests Bug#21813, where prepared statements are used to |
15395 | run queries |
15396 | */ |
15397 | static void test_bug17667() |
15398 | { |
15399 | int rc; |
15400 | MYSQL_STMT *stmt; |
15401 | enum query_type { QT_NORMAL, QT_PREPARED}; |
15402 | struct buffer_and_length { |
15403 | enum query_type qt; |
15404 | const char *buffer; |
15405 | const uint length; |
15406 | } statements[]= { |
15407 | { QT_NORMAL, "drop table if exists bug17667" , 29 }, |
15408 | { QT_NORMAL, "create table bug17667 (c varchar(20))" , 37 }, |
15409 | { QT_NORMAL, "insert into bug17667 (c) values ('regular') /* NUL=\0 with comment */" , 68 }, |
15410 | { QT_PREPARED, |
15411 | "insert into bug17667 (c) values ('prepared') /* NUL=\0 with comment */" , 69, }, |
15412 | { QT_NORMAL, "insert into bug17667 (c) values ('NUL=\0 in value')" , 50 }, |
15413 | { QT_NORMAL, "insert into bug17667 (c) values ('5 NULs=\0\0\0\0\0')" , 48 }, |
15414 | { QT_PREPARED, "insert into bug17667 (c) values ('6 NULs=\0\0\0\0\0\0')" , 50 }, |
15415 | { QT_NORMAL, "/* NUL=\0 with comment */ insert into bug17667 (c) values ('encore')" , 67 }, |
15416 | { QT_NORMAL, "drop table bug17667" , 19 }, |
15417 | { QT_NORMAL, NULL, 0 } }; |
15418 | |
15419 | struct buffer_and_length *statement_cursor; |
15420 | FILE *log_file; |
15421 | char *master_log_filename; |
15422 | |
15423 | myheader("test_bug17667" ); |
15424 | |
15425 | master_log_filename = (char *) malloc(strlen(opt_vardir) + strlen("/log/master.log" ) + 1); |
15426 | strxmov(master_log_filename, opt_vardir, "/log/master.log" , NullS); |
15427 | if (!opt_silent) |
15428 | printf("Opening '%s'\n" , master_log_filename); |
15429 | log_file= my_fopen(master_log_filename, (int) (O_RDONLY | O_BINARY), MYF(0)); |
15430 | free(master_log_filename); |
15431 | |
15432 | if (log_file == NULL) |
15433 | { |
15434 | if (!opt_silent) |
15435 | { |
15436 | printf("Could not find the log file, VARDIR/log/master.log, so " |
15437 | "test_bug17667 is not run.\n" |
15438 | "Run test from the mysql-test/mysql-test-run* program to set up " |
15439 | "correct environment for this test.\n\n" ); |
15440 | } |
15441 | return; |
15442 | } |
15443 | |
15444 | enable_query_logs(1); |
15445 | |
15446 | for (statement_cursor= statements; statement_cursor->buffer != NULL; |
15447 | statement_cursor++) |
15448 | { |
15449 | if (statement_cursor->qt == QT_NORMAL) |
15450 | { |
15451 | /* Run statement as normal query */ |
15452 | rc= mysql_real_query(mysql, statement_cursor->buffer, |
15453 | statement_cursor->length); |
15454 | myquery(rc); |
15455 | } |
15456 | else if (statement_cursor->qt == QT_PREPARED) |
15457 | { |
15458 | /* |
15459 | Run as prepared statement |
15460 | |
15461 | NOTE! All these queries should be in the log twice, |
15462 | one time for prepare and one time for execute |
15463 | */ |
15464 | stmt= mysql_stmt_init(mysql); |
15465 | |
15466 | rc= mysql_stmt_prepare(stmt, statement_cursor->buffer, |
15467 | statement_cursor->length); |
15468 | check_execute(stmt, rc); |
15469 | |
15470 | rc= mysql_stmt_execute(stmt); |
15471 | check_execute(stmt, rc); |
15472 | |
15473 | mysql_stmt_close(stmt); |
15474 | } |
15475 | else |
15476 | { |
15477 | DIE_UNLESS(0==1); |
15478 | } |
15479 | } |
15480 | |
15481 | /* Make sure the server has written the logs to disk before reading it */ |
15482 | rc= mysql_query(mysql, "flush logs" ); |
15483 | myquery(rc); |
15484 | |
15485 | for (statement_cursor= statements; statement_cursor->buffer != NULL; |
15486 | statement_cursor++) |
15487 | { |
15488 | int expected_hits= 1, hits= 0; |
15489 | char line_buffer[MAX_TEST_QUERY_LENGTH*2]; |
15490 | /* more than enough room for the query and some marginalia. */ |
15491 | |
15492 | /* Prepared statments always occurs twice in log */ |
15493 | if (statement_cursor->qt == QT_PREPARED) |
15494 | expected_hits++; |
15495 | |
15496 | /* Loop until we found expected number of log entries */ |
15497 | do { |
15498 | /* Loop until statement is found in log */ |
15499 | do { |
15500 | memset(line_buffer, '/', MAX_TEST_QUERY_LENGTH*2); |
15501 | |
15502 | if(fgets(line_buffer, MAX_TEST_QUERY_LENGTH*2, log_file) == NULL) |
15503 | { |
15504 | /* If fgets returned NULL, it indicates either error or EOF */ |
15505 | if (feof(log_file)) |
15506 | DIE("Found EOF before all statements where found" ); |
15507 | |
15508 | fprintf(stderr, "Got error %d while reading from file\n" , |
15509 | ferror(log_file)); |
15510 | DIE("Read error" ); |
15511 | } |
15512 | |
15513 | } while (my_memmem(line_buffer, MAX_TEST_QUERY_LENGTH*2, |
15514 | statement_cursor->buffer, |
15515 | statement_cursor->length) == NULL); |
15516 | hits++; |
15517 | } while (hits < expected_hits); |
15518 | |
15519 | if (!opt_silent) |
15520 | printf("Found statement starting with \"%s\"\n" , |
15521 | statement_cursor->buffer); |
15522 | } |
15523 | |
15524 | restore_query_logs(); |
15525 | |
15526 | if (!opt_silent) |
15527 | printf("success. All queries found intact in the log.\n" ); |
15528 | |
15529 | my_fclose(log_file, MYF(0)); |
15530 | } |
15531 | |
15532 | |
15533 | /* |
15534 | Bug#14169: type of group_concat() result changed to blob if tmp_table was |
15535 | used |
15536 | */ |
15537 | static void test_bug14169() |
15538 | { |
15539 | MYSQL_STMT *stmt; |
15540 | const char *stmt_text; |
15541 | MYSQL_RES *res; |
15542 | MYSQL_FIELD *field; |
15543 | int rc; |
15544 | |
15545 | myheader("test_bug14169" ); |
15546 | |
15547 | rc= mysql_query(mysql, "drop table if exists t1" ); |
15548 | myquery(rc); |
15549 | rc= mysql_query(mysql, "set session group_concat_max_len=1024" ); |
15550 | myquery(rc); |
15551 | rc= mysql_query(mysql, "create table t1 (f1 int unsigned, f2 varchar(255))" ); |
15552 | myquery(rc); |
15553 | rc= mysql_query(mysql, "insert into t1 values (1,repeat('a',255))," |
15554 | "(2,repeat('b',255))" ); |
15555 | myquery(rc); |
15556 | stmt= mysql_stmt_init(mysql); |
15557 | stmt_text= "select f2,group_concat(f1) from t1 group by f2" ; |
15558 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
15559 | myquery(rc); |
15560 | res= mysql_stmt_result_metadata(stmt); |
15561 | field= mysql_fetch_fields(res); |
15562 | if (!opt_silent) |
15563 | printf("GROUP_CONCAT() result type %i" , field[1].type); |
15564 | DIE_UNLESS(field[1].type == MYSQL_TYPE_BLOB); |
15565 | mysql_free_result(res); |
15566 | mysql_stmt_free_result(stmt); |
15567 | mysql_stmt_close(stmt); |
15568 | |
15569 | rc= mysql_query(mysql, "drop table t1" ); |
15570 | myquery(rc); |
15571 | |
15572 | rc= mysql_query(mysql, "set session group_concat_max_len=@@global.group_concat_max_len" ); |
15573 | myquery(rc); |
15574 | } |
15575 | |
15576 | /* |
15577 | Test that mysql_insert_id() behaves as documented in our manual |
15578 | */ |
15579 | static void test_mysql_insert_id() |
15580 | { |
15581 | my_ulonglong res; |
15582 | int rc; |
15583 | |
15584 | myheader("test_mysql_insert_id" ); |
15585 | |
15586 | rc= mysql_query(mysql, "drop table if exists t1,t2" ); |
15587 | myquery(rc); |
15588 | /* table without auto_increment column */ |
15589 | rc= mysql_query(mysql, "create table t1 (f1 int, f2 varchar(255), key(f1))" ); |
15590 | myquery(rc); |
15591 | rc= mysql_query(mysql, "insert into t1 values (1,'a')" ); |
15592 | myquery(rc); |
15593 | res= mysql_insert_id(mysql); |
15594 | DIE_UNLESS(res == 0); |
15595 | rc= mysql_query(mysql, "insert into t1 values (null,'b')" ); |
15596 | myquery(rc); |
15597 | res= mysql_insert_id(mysql); |
15598 | DIE_UNLESS(res == 0); |
15599 | rc= mysql_query(mysql, "insert into t1 select 5,'c'" ); |
15600 | myquery(rc); |
15601 | res= mysql_insert_id(mysql); |
15602 | DIE_UNLESS(res == 0); |
15603 | |
15604 | /* |
15605 | Test for bug #34889: mysql_client_test::test_mysql_insert_id test fails |
15606 | sporadically |
15607 | */ |
15608 | rc= mysql_query(mysql, "create table t2 (f1 int not null primary key auto_increment, f2 varchar(255))" ); |
15609 | myquery(rc); |
15610 | rc= mysql_query(mysql, "insert into t2 values (null,'b')" ); |
15611 | myquery(rc); |
15612 | rc= mysql_query(mysql, "insert into t1 select 5,'c'" ); |
15613 | myquery(rc); |
15614 | res= mysql_insert_id(mysql); |
15615 | DIE_UNLESS(res == 0); |
15616 | rc= mysql_query(mysql, "drop table t2" ); |
15617 | myquery(rc); |
15618 | |
15619 | rc= mysql_query(mysql, "insert into t1 select null,'d'" ); |
15620 | myquery(rc); |
15621 | res= mysql_insert_id(mysql); |
15622 | DIE_UNLESS(res == 0); |
15623 | rc= mysql_query(mysql, "insert into t1 values (null,last_insert_id(300))" ); |
15624 | myquery(rc); |
15625 | res= mysql_insert_id(mysql); |
15626 | DIE_UNLESS(res == 300); |
15627 | rc= mysql_query(mysql, "insert into t1 select null,last_insert_id(400)" ); |
15628 | myquery(rc); |
15629 | res= mysql_insert_id(mysql); |
15630 | /* |
15631 | Behaviour change: old code used to return 0; but 400 is consistent |
15632 | with INSERT VALUES, and the manual's section of mysql_insert_id() does not |
15633 | say INSERT SELECT should be different. |
15634 | */ |
15635 | DIE_UNLESS(res == 400); |
15636 | |
15637 | /* table with auto_increment column */ |
15638 | rc= mysql_query(mysql, "create table t2 (f1 int not null primary key auto_increment, f2 varchar(255))" ); |
15639 | myquery(rc); |
15640 | rc= mysql_query(mysql, "insert into t2 values (1,'a')" ); |
15641 | myquery(rc); |
15642 | res= mysql_insert_id(mysql); |
15643 | DIE_UNLESS(res == 1); |
15644 | /* this should not influence next INSERT if it doesn't have auto_inc */ |
15645 | rc= mysql_query(mysql, "insert into t1 values (10,'e')" ); |
15646 | myquery(rc); |
15647 | res= mysql_insert_id(mysql); |
15648 | DIE_UNLESS(res == 0); |
15649 | |
15650 | rc= mysql_query(mysql, "insert into t2 values (null,'b')" ); |
15651 | myquery(rc); |
15652 | res= mysql_insert_id(mysql); |
15653 | DIE_UNLESS(res == 2); |
15654 | rc= mysql_query(mysql, "insert into t2 select 5,'c'" ); |
15655 | myquery(rc); |
15656 | res= mysql_insert_id(mysql); |
15657 | /* |
15658 | Manual says that for multirow insert this should have been 5, but does not |
15659 | say for INSERT SELECT. This is a behaviour change: old code used to return |
15660 | 0. We try to be consistent with INSERT VALUES. |
15661 | */ |
15662 | DIE_UNLESS(res == 5); |
15663 | rc= mysql_query(mysql, "insert into t2 select null,'d'" ); |
15664 | myquery(rc); |
15665 | res= mysql_insert_id(mysql); |
15666 | DIE_UNLESS(res == 6); |
15667 | /* with more than one row */ |
15668 | rc= mysql_query(mysql, "insert into t2 values (10,'a'),(11,'b')" ); |
15669 | myquery(rc); |
15670 | res= mysql_insert_id(mysql); |
15671 | DIE_UNLESS(res == 11); |
15672 | rc= mysql_query(mysql, "insert into t2 select 12,'a' union select 13,'b'" ); |
15673 | myquery(rc); |
15674 | res= mysql_insert_id(mysql); |
15675 | /* |
15676 | Manual says that for multirow insert this should have been 13, but does |
15677 | not say for INSERT SELECT. This is a behaviour change: old code used to |
15678 | return 0. We try to be consistent with INSERT VALUES. |
15679 | */ |
15680 | DIE_UNLESS(res == 13); |
15681 | rc= mysql_query(mysql, "insert into t2 values (null,'a'),(null,'b')" ); |
15682 | myquery(rc); |
15683 | res= mysql_insert_id(mysql); |
15684 | DIE_UNLESS(res == 14); |
15685 | rc= mysql_query(mysql, "insert into t2 select null,'a' union select null,'b'" ); |
15686 | myquery(rc); |
15687 | res= mysql_insert_id(mysql); |
15688 | DIE_UNLESS(res == 16); |
15689 | rc= mysql_query(mysql, "insert into t2 select 12,'a' union select 13,'b'" ); |
15690 | myquery_r(rc); |
15691 | rc= mysql_query(mysql, "insert ignore into t2 select 12,'a' union select 13,'b'" ); |
15692 | myquery(rc); |
15693 | res= mysql_insert_id(mysql); |
15694 | DIE_UNLESS(res == 0); |
15695 | rc= mysql_query(mysql, "insert into t2 values (12,'a'),(13,'b')" ); |
15696 | myquery_r(rc); |
15697 | res= mysql_insert_id(mysql); |
15698 | DIE_UNLESS(res == 0); |
15699 | rc= mysql_query(mysql, "insert ignore into t2 values (12,'a'),(13,'b')" ); |
15700 | myquery(rc); |
15701 | res= mysql_insert_id(mysql); |
15702 | DIE_UNLESS(res == 0); |
15703 | /* mixing autogenerated and explicit values */ |
15704 | rc= mysql_query(mysql, "insert into t2 values (null,'e'),(12,'a'),(13,'b')" ); |
15705 | myquery_r(rc); |
15706 | rc= mysql_query(mysql, "insert into t2 values (null,'e'),(12,'a'),(13,'b'),(25,'g')" ); |
15707 | myquery_r(rc); |
15708 | rc= mysql_query(mysql, "insert into t2 values (null,last_insert_id(300))" ); |
15709 | myquery(rc); |
15710 | res= mysql_insert_id(mysql); |
15711 | /* |
15712 | according to the manual, this might be 20 or 300, but it looks like |
15713 | auto_increment column takes priority over last_insert_id(). |
15714 | */ |
15715 | DIE_UNLESS(res == 20); |
15716 | /* If first autogenerated number fails and 2nd works: */ |
15717 | rc= mysql_query(mysql, "drop table t2" ); |
15718 | myquery(rc); |
15719 | rc= mysql_query(mysql, "create table t2 (f1 int not null primary key " |
15720 | "auto_increment, f2 varchar(255), unique (f2))" ); |
15721 | myquery(rc); |
15722 | rc= mysql_query(mysql, "insert into t2 values (null,'e')" ); |
15723 | res= mysql_insert_id(mysql); |
15724 | DIE_UNLESS(res == 1); |
15725 | rc= mysql_query(mysql, "insert ignore into t2 values (null,'e'),(null,'a'),(null,'e')" ); |
15726 | myquery(rc); |
15727 | res= mysql_insert_id(mysql); |
15728 | DIE_UNLESS(res == 2); |
15729 | /* If autogenerated fails and explicit works: */ |
15730 | rc= mysql_query(mysql, "insert ignore into t2 values (null,'e'),(12,'c'),(null,'d')" ); |
15731 | myquery(rc); |
15732 | res= mysql_insert_id(mysql); |
15733 | /* |
15734 | Behaviour change: old code returned 3 (first autogenerated, even if it |
15735 | fails); we now return first successful autogenerated. |
15736 | */ |
15737 | DIE_UNLESS(res == 13); |
15738 | /* UPDATE may update mysql_insert_id() if it uses LAST_INSERT_ID(#) */ |
15739 | rc= mysql_query(mysql, "update t2 set f1=14 where f1=12" ); |
15740 | myquery(rc); |
15741 | res= mysql_insert_id(mysql); |
15742 | DIE_UNLESS(res == 0); |
15743 | rc= mysql_query(mysql, "update t2 set f1=0 where f1=14" ); |
15744 | myquery(rc); |
15745 | res= mysql_insert_id(mysql); |
15746 | DIE_UNLESS(res == 0); |
15747 | rc= mysql_query(mysql, "update t2 set f2=last_insert_id(372) where f1=0" ); |
15748 | myquery(rc); |
15749 | res= mysql_insert_id(mysql); |
15750 | DIE_UNLESS(res == 372); |
15751 | /* check that LAST_INSERT_ID() does not update mysql_insert_id(): */ |
15752 | rc= mysql_query(mysql, "insert into t2 values (null,'g')" ); |
15753 | myquery(rc); |
15754 | res= mysql_insert_id(mysql); |
15755 | DIE_UNLESS(res == 15); |
15756 | rc= mysql_query(mysql, "update t2 set f2=(@li:=last_insert_id()) where f1=15" ); |
15757 | myquery(rc); |
15758 | res= mysql_insert_id(mysql); |
15759 | DIE_UNLESS(res == 0); |
15760 | /* |
15761 | Behaviour change: now if ON DUPLICATE KEY UPDATE updates a row, |
15762 | mysql_insert_id() returns the id of the row, instead of not being |
15763 | affected. |
15764 | */ |
15765 | rc= mysql_query(mysql, "insert into t2 values (null,@li) on duplicate key " |
15766 | "update f2=concat('we updated ',f2)" ); |
15767 | myquery(rc); |
15768 | res= mysql_insert_id(mysql); |
15769 | DIE_UNLESS(res == 15); |
15770 | |
15771 | rc= mysql_query(mysql, "drop table t1,t2" ); |
15772 | myquery(rc); |
15773 | } |
15774 | |
15775 | /* |
15776 | Bug#20152: mysql_stmt_execute() writes to MYSQL_TYPE_DATE buffer |
15777 | */ |
15778 | |
15779 | static void test_bug20152() |
15780 | { |
15781 | MYSQL_BIND my_bind[1]; |
15782 | MYSQL_STMT *stmt; |
15783 | MYSQL_TIME tm; |
15784 | int rc; |
15785 | const char *query= "INSERT INTO t1 (f1) VALUES (?)" ; |
15786 | |
15787 | myheader("test_bug20152" ); |
15788 | |
15789 | memset(my_bind, 0, sizeof(my_bind)); |
15790 | my_bind[0].buffer_type= MYSQL_TYPE_DATE; |
15791 | my_bind[0].buffer= (void*)&tm; |
15792 | |
15793 | tm.year = 2006; |
15794 | tm.month = 6; |
15795 | tm.day = 18; |
15796 | tm.hour = 14; |
15797 | tm.minute = 9; |
15798 | tm.second = 42; |
15799 | |
15800 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1" ); |
15801 | myquery(rc); |
15802 | rc= mysql_query(mysql, "CREATE TABLE t1 (f1 DATE)" ); |
15803 | myquery(rc); |
15804 | |
15805 | stmt= mysql_stmt_init(mysql); |
15806 | rc= mysql_stmt_prepare(stmt, query, strlen(query)); |
15807 | check_execute(stmt, rc); |
15808 | rc= mysql_stmt_bind_param(stmt, my_bind); |
15809 | check_execute(stmt, rc); |
15810 | rc= mysql_stmt_execute(stmt); |
15811 | check_execute(stmt, rc); |
15812 | rc= mysql_stmt_close(stmt); |
15813 | check_execute(stmt, rc); |
15814 | rc= mysql_query(mysql, "DROP TABLE t1" ); |
15815 | myquery(rc); |
15816 | |
15817 | if (tm.hour == 14 && tm.minute == 9 && tm.second == 42) { |
15818 | if (!opt_silent) |
15819 | printf("OK!" ); |
15820 | } else { |
15821 | printf("[14:09:42] != [%02d:%02d:%02d]\n" , tm.hour, tm.minute, tm.second); |
15822 | DIE_UNLESS(0==1); |
15823 | } |
15824 | } |
15825 | |
15826 | /* Bug#15752 "Lost connection to MySQL server when calling a SP from C API" */ |
15827 | |
15828 | static void test_bug15752() |
15829 | { |
15830 | MYSQL mysql_local; |
15831 | int rc, i; |
15832 | const int ITERATION_COUNT= 100; |
15833 | const char *query= "CALL p1()" ; |
15834 | |
15835 | myheader("test_bug15752" ); |
15836 | |
15837 | rc= mysql_query(mysql, "drop procedure if exists p1" ); |
15838 | myquery(rc); |
15839 | rc= mysql_query(mysql, "create procedure p1() select 1" ); |
15840 | myquery(rc); |
15841 | |
15842 | mysql_client_init(&mysql_local); |
15843 | if (! mysql_real_connect(&mysql_local, opt_host, opt_user, |
15844 | opt_password, current_db, opt_port, |
15845 | opt_unix_socket, |
15846 | CLIENT_MULTI_STATEMENTS)) |
15847 | { |
15848 | printf("Unable connect to MySQL server: %s\n" , mysql_error(&mysql_local)); |
15849 | DIE_UNLESS(0); |
15850 | } |
15851 | rc= mysql_real_query(&mysql_local, query, strlen(query)); |
15852 | myquery(rc); |
15853 | mysql_free_result(mysql_store_result(&mysql_local)); |
15854 | |
15855 | rc= mysql_real_query(&mysql_local, query, strlen(query)); |
15856 | DIE_UNLESS(rc && mysql_errno(&mysql_local) == CR_COMMANDS_OUT_OF_SYNC); |
15857 | |
15858 | if (! opt_silent) |
15859 | printf("Got error (as expected): %s\n" , mysql_error(&mysql_local)); |
15860 | |
15861 | /* Check some other commands too */ |
15862 | |
15863 | DIE_UNLESS(mysql_next_result(&mysql_local) == 0); |
15864 | mysql_free_result(mysql_store_result(&mysql_local)); |
15865 | DIE_UNLESS(mysql_next_result(&mysql_local) == -1); |
15866 | |
15867 | /* The second problem is not reproducible: add the test case */ |
15868 | for (i = 0; i < ITERATION_COUNT; i++) |
15869 | { |
15870 | if (mysql_real_query(&mysql_local, query, strlen(query))) |
15871 | { |
15872 | printf("\ni=%d %s failed: %s\n" , i, query, mysql_error(&mysql_local)); |
15873 | break; |
15874 | } |
15875 | mysql_free_result(mysql_store_result(&mysql_local)); |
15876 | DIE_UNLESS(mysql_next_result(&mysql_local) == 0); |
15877 | mysql_free_result(mysql_store_result(&mysql_local)); |
15878 | DIE_UNLESS(mysql_next_result(&mysql_local) == -1); |
15879 | |
15880 | } |
15881 | mysql_close(&mysql_local); |
15882 | rc= mysql_query(mysql, "drop procedure p1" ); |
15883 | myquery(rc); |
15884 | } |
15885 | |
15886 | /* |
15887 | Bug#21206: memory corruption when too many cursors are opened at once |
15888 | |
15889 | Memory corruption happens when more than 1024 cursors are open |
15890 | simultaneously. |
15891 | */ |
15892 | static void test_bug21206() |
15893 | { |
15894 | const size_t cursor_count= 1025; |
15895 | |
15896 | const char *create_table[]= |
15897 | { |
15898 | "DROP TABLE IF EXISTS t1" , |
15899 | "CREATE TABLE t1 (i INT)" , |
15900 | "INSERT INTO t1 VALUES (1), (2), (3)" |
15901 | }; |
15902 | const char *query= "SELECT * FROM t1" ; |
15903 | |
15904 | Stmt_fetch *fetch_array= |
15905 | (Stmt_fetch*) calloc(cursor_count, sizeof(Stmt_fetch)); |
15906 | |
15907 | Stmt_fetch *fetch; |
15908 | |
15909 | DBUG_ENTER("test_bug21206" ); |
15910 | myheader("test_bug21206" ); |
15911 | |
15912 | fill_tables(create_table, sizeof(create_table) / sizeof(*create_table)); |
15913 | |
15914 | for (fetch= fetch_array; fetch < fetch_array + cursor_count; ++fetch) |
15915 | { |
15916 | /* Init will exit(1) in case of error */ |
15917 | stmt_fetch_init(fetch, (uint)(fetch - fetch_array), query); |
15918 | } |
15919 | |
15920 | for (fetch= fetch_array; fetch < fetch_array + cursor_count; ++fetch) |
15921 | stmt_fetch_close(fetch); |
15922 | |
15923 | free(fetch_array); |
15924 | |
15925 | DBUG_VOID_RETURN; |
15926 | } |
15927 | |
15928 | /* |
15929 | Ensure we execute the status code while testing |
15930 | */ |
15931 | |
15932 | static void test_status() |
15933 | { |
15934 | DBUG_ENTER("test_status" ); |
15935 | myheader("test_status" ); |
15936 | |
15937 | if (!mysql_stat(mysql)) |
15938 | { |
15939 | myerror("mysql_stat failed" ); /* purecov: inspected */ |
15940 | die(__FILE__, __LINE__, "mysql_stat failed" ); /* purecov: inspected */ |
15941 | } |
15942 | DBUG_VOID_RETURN; |
15943 | } |
15944 | |
15945 | /* |
15946 | Bug#21726: Incorrect result with multiple invocations of |
15947 | LAST_INSERT_ID |
15948 | |
15949 | Test that client gets updated value of insert_id on UPDATE that uses |
15950 | LAST_INSERT_ID(expr). |
15951 | select_query added to test for bug |
15952 | #26921 Problem in mysql_insert_id() Embedded C API function |
15953 | */ |
15954 | static void test_bug21726() |
15955 | { |
15956 | const char *create_table[]= |
15957 | { |
15958 | "DROP TABLE IF EXISTS t1" , |
15959 | "CREATE TABLE t1 (i INT)" , |
15960 | "INSERT INTO t1 VALUES (1)" , |
15961 | }; |
15962 | const char *update_query= "UPDATE t1 SET i= LAST_INSERT_ID(i + 1)" ; |
15963 | int rc; |
15964 | my_ulonglong insert_id; |
15965 | const char *select_query= "SELECT * FROM t1" ; |
15966 | MYSQL_RES *result; |
15967 | |
15968 | DBUG_ENTER("test_bug21726" ); |
15969 | myheader("test_bug21726" ); |
15970 | |
15971 | fill_tables(create_table, sizeof(create_table) / sizeof(*create_table)); |
15972 | |
15973 | rc= mysql_query(mysql, update_query); |
15974 | myquery(rc); |
15975 | insert_id= mysql_insert_id(mysql); |
15976 | DIE_UNLESS(insert_id == 2); |
15977 | |
15978 | rc= mysql_query(mysql, update_query); |
15979 | myquery(rc); |
15980 | insert_id= mysql_insert_id(mysql); |
15981 | DIE_UNLESS(insert_id == 3); |
15982 | |
15983 | rc= mysql_query(mysql, select_query); |
15984 | myquery(rc); |
15985 | insert_id= mysql_insert_id(mysql); |
15986 | DIE_UNLESS(insert_id == 3); |
15987 | result= mysql_store_result(mysql); |
15988 | mysql_free_result(result); |
15989 | |
15990 | DBUG_VOID_RETURN; |
15991 | } |
15992 | |
15993 | |
15994 | /* |
15995 | BUG#23383: mysql_affected_rows() returns different values than |
15996 | mysql_stmt_affected_rows() |
15997 | |
15998 | Test that both mysql_affected_rows() and mysql_stmt_affected_rows() |
15999 | return -1 on error, 0 when no rows were affected, and (positive) row |
16000 | count when some rows were affected. |
16001 | */ |
16002 | static void test_bug23383() |
16003 | { |
16004 | const char *insert_query= "INSERT INTO t1 VALUES (1), (2)" ; |
16005 | const char *update_query= "UPDATE t1 SET i= 4 WHERE i = 3" ; |
16006 | MYSQL_STMT *stmt; |
16007 | my_ulonglong row_count; |
16008 | int rc; |
16009 | |
16010 | DBUG_ENTER("test_bug23383" ); |
16011 | myheader("test_bug23383" ); |
16012 | |
16013 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1" ); |
16014 | myquery(rc); |
16015 | |
16016 | rc= mysql_query(mysql, "CREATE TABLE t1 (i INT UNIQUE)" ); |
16017 | myquery(rc); |
16018 | |
16019 | rc= mysql_query(mysql, insert_query); |
16020 | myquery(rc); |
16021 | row_count= mysql_affected_rows(mysql); |
16022 | DIE_UNLESS(row_count == 2); |
16023 | |
16024 | rc= mysql_query(mysql, insert_query); |
16025 | DIE_UNLESS(rc != 0); |
16026 | row_count= mysql_affected_rows(mysql); |
16027 | DIE_UNLESS(row_count == (my_ulonglong)-1); |
16028 | |
16029 | rc= mysql_query(mysql, update_query); |
16030 | myquery(rc); |
16031 | row_count= mysql_affected_rows(mysql); |
16032 | DIE_UNLESS(row_count == 0); |
16033 | |
16034 | rc= mysql_query(mysql, "DELETE FROM t1" ); |
16035 | myquery(rc); |
16036 | |
16037 | stmt= mysql_stmt_init(mysql); |
16038 | DIE_UNLESS(stmt != 0); |
16039 | |
16040 | rc= mysql_stmt_prepare(stmt, insert_query, strlen(insert_query)); |
16041 | check_execute(stmt, rc); |
16042 | |
16043 | rc= mysql_stmt_execute(stmt); |
16044 | check_execute(stmt, rc); |
16045 | row_count= mysql_stmt_affected_rows(stmt); |
16046 | DIE_UNLESS(row_count == 2); |
16047 | |
16048 | rc= mysql_stmt_execute(stmt); |
16049 | DIE_UNLESS(rc != 0); |
16050 | row_count= mysql_stmt_affected_rows(stmt); |
16051 | DIE_UNLESS(row_count == (my_ulonglong)-1); |
16052 | |
16053 | rc= mysql_stmt_prepare(stmt, update_query, strlen(update_query)); |
16054 | check_execute(stmt, rc); |
16055 | |
16056 | rc= mysql_stmt_execute(stmt); |
16057 | check_execute(stmt, rc); |
16058 | row_count= mysql_stmt_affected_rows(stmt); |
16059 | DIE_UNLESS(row_count == 0); |
16060 | |
16061 | rc= mysql_stmt_close(stmt); |
16062 | check_execute(stmt, rc); |
16063 | |
16064 | rc= mysql_query(mysql, "DROP TABLE t1" ); |
16065 | myquery(rc); |
16066 | |
16067 | DBUG_VOID_RETURN; |
16068 | } |
16069 | |
16070 | |
16071 | /* |
16072 | BUG#21635: MYSQL_FIELD struct's member strings seem to misbehave for |
16073 | expression cols |
16074 | |
16075 | Check that for MIN(), MAX(), COUNT() only MYSQL_FIELD::name is set |
16076 | to either expression or its alias, and db, org_table, table, |
16077 | org_name fields are empty strings. |
16078 | */ |
16079 | static void test_bug21635() |
16080 | { |
16081 | const char *expr[]= |
16082 | { |
16083 | "MIN(i)" , "MIN(i)" , |
16084 | "MIN(i) AS A1" , "A1" , |
16085 | "MAX(i)" , "MAX(i)" , |
16086 | "MAX(i) AS A2" , "A2" , |
16087 | "COUNT(i)" , "COUNT(i)" , |
16088 | "COUNT(i) AS A3" , "A3" , |
16089 | }; |
16090 | char query[MAX_TEST_QUERY_LENGTH]; |
16091 | char *query_end; |
16092 | MYSQL_RES *result; |
16093 | MYSQL_FIELD *field; |
16094 | unsigned int field_count, i, j; |
16095 | int rc; |
16096 | |
16097 | DBUG_ENTER("test_bug21635" ); |
16098 | myheader("test_bug21635" ); |
16099 | |
16100 | query_end= strxmov(query, "SELECT " , NullS); |
16101 | for (i= 0; i < sizeof(expr) / sizeof(*expr) / 2; ++i) |
16102 | query_end= strxmov(query_end, expr[i * 2], ", " , NullS); |
16103 | query_end= strxmov(query_end - 2, " FROM t1 GROUP BY i" , NullS); |
16104 | DIE_UNLESS(query_end - query < MAX_TEST_QUERY_LENGTH); |
16105 | |
16106 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1" ); |
16107 | myquery(rc); |
16108 | rc= mysql_query(mysql, "CREATE TABLE t1 (i INT)" ); |
16109 | myquery(rc); |
16110 | /* |
16111 | We need this loop to ensure correct behavior with both constant and |
16112 | non-constant tables. |
16113 | */ |
16114 | for (j= 0; j < 2 ; j++) |
16115 | { |
16116 | rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)" ); |
16117 | myquery(rc); |
16118 | |
16119 | rc= mysql_real_query(mysql, query, (ulong)(query_end - query)); |
16120 | myquery(rc); |
16121 | |
16122 | result= mysql_use_result(mysql); |
16123 | DIE_UNLESS(result); |
16124 | |
16125 | field_count= mysql_field_count(mysql); |
16126 | for (i= 0; i < field_count; ++i) |
16127 | { |
16128 | field= mysql_fetch_field_direct(result, i); |
16129 | if (!opt_silent) |
16130 | if (!opt_silent) |
16131 | printf("%s -> %s ... " , expr[i * 2], field->name); |
16132 | fflush(stdout); |
16133 | DIE_UNLESS(field->db[0] == 0 && field->org_table[0] == 0 && |
16134 | field->table[0] == 0 && field->org_name[0] == 0); |
16135 | DIE_UNLESS(strcmp(field->name, expr[i * 2 + 1]) == 0); |
16136 | if (!opt_silent) |
16137 | if (!opt_silent) |
16138 | puts("OK" ); |
16139 | } |
16140 | |
16141 | mysql_free_result(result); |
16142 | } |
16143 | rc= mysql_query(mysql, "DROP TABLE t1" ); |
16144 | myquery(rc); |
16145 | |
16146 | DBUG_VOID_RETURN; |
16147 | } |
16148 | |
16149 | /* |
16150 | Bug#24179 "select b into $var" fails with --cursor_protocol" |
16151 | The failure is correct, check that the returned message is meaningful. |
16152 | */ |
16153 | |
16154 | static void test_bug24179() |
16155 | { |
16156 | int rc; |
16157 | MYSQL_STMT *stmt; |
16158 | |
16159 | DBUG_ENTER("test_bug24179" ); |
16160 | myheader("test_bug24179" ); |
16161 | |
16162 | stmt= open_cursor("select 1 into @a" ); |
16163 | rc= mysql_stmt_execute(stmt); |
16164 | DIE_UNLESS(rc); |
16165 | if (!opt_silent) |
16166 | { |
16167 | printf("Got error (as expected): %d %s\n" , |
16168 | mysql_stmt_errno(stmt), |
16169 | mysql_stmt_error(stmt)); |
16170 | } |
16171 | DIE_UNLESS(mysql_stmt_errno(stmt) == 1323); |
16172 | mysql_stmt_close(stmt); |
16173 | |
16174 | DBUG_VOID_RETURN; |
16175 | } |
16176 | |
16177 | |
16178 | /** |
16179 | Bug#32265 Server returns different metadata if prepared statement is used |
16180 | */ |
16181 | |
16182 | static void test_bug32265() |
16183 | { |
16184 | int rc; |
16185 | MYSQL_STMT *stmt; |
16186 | MYSQL_FIELD *field; |
16187 | MYSQL_RES *metadata; |
16188 | |
16189 | DBUG_ENTER("test_bug32265" ); |
16190 | myheader("test_bug32265" ); |
16191 | |
16192 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1" ); |
16193 | myquery(rc); |
16194 | rc= mysql_query(mysql, "CREATE TABLE t1 (a INTEGER)" ); |
16195 | myquery(rc); |
16196 | rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)" ); |
16197 | myquery(rc); |
16198 | rc= mysql_query(mysql, "CREATE VIEW v1 AS SELECT * FROM t1" ); |
16199 | myquery(rc); |
16200 | |
16201 | stmt= open_cursor("SELECT * FROM t1" ); |
16202 | rc= mysql_stmt_execute(stmt); |
16203 | check_execute(stmt, rc); |
16204 | |
16205 | metadata= mysql_stmt_result_metadata(stmt); |
16206 | field= mysql_fetch_field(metadata); |
16207 | DIE_UNLESS(field); |
16208 | DIE_UNLESS(strcmp(field->table, "t1" ) == 0); |
16209 | DIE_UNLESS(strcmp(field->org_table, "t1" ) == 0); |
16210 | DIE_UNLESS(strcmp(field->db, "client_test_db" ) == 0); |
16211 | mysql_free_result(metadata); |
16212 | mysql_stmt_close(stmt); |
16213 | |
16214 | stmt= open_cursor("SELECT a '' FROM t1 ``" ); |
16215 | rc= mysql_stmt_execute(stmt); |
16216 | check_execute(stmt, rc); |
16217 | |
16218 | metadata= mysql_stmt_result_metadata(stmt); |
16219 | field= mysql_fetch_field(metadata); |
16220 | DIE_UNLESS(strcmp(field->table, "" ) == 0); |
16221 | DIE_UNLESS(strcmp(field->org_table, "t1" ) == 0); |
16222 | DIE_UNLESS(strcmp(field->db, "client_test_db" ) == 0); |
16223 | mysql_free_result(metadata); |
16224 | mysql_stmt_close(stmt); |
16225 | |
16226 | stmt= open_cursor("SELECT a '' FROM t1 ``" ); |
16227 | rc= mysql_stmt_execute(stmt); |
16228 | check_execute(stmt, rc); |
16229 | |
16230 | metadata= mysql_stmt_result_metadata(stmt); |
16231 | field= mysql_fetch_field(metadata); |
16232 | DIE_UNLESS(strcmp(field->table, "" ) == 0); |
16233 | DIE_UNLESS(strcmp(field->org_table, "t1" ) == 0); |
16234 | DIE_UNLESS(strcmp(field->db, "client_test_db" ) == 0); |
16235 | mysql_free_result(metadata); |
16236 | mysql_stmt_close(stmt); |
16237 | |
16238 | stmt= open_cursor("SELECT * FROM v1" ); |
16239 | rc= mysql_stmt_execute(stmt); |
16240 | check_execute(stmt, rc); |
16241 | |
16242 | metadata= mysql_stmt_result_metadata(stmt); |
16243 | field= mysql_fetch_field(metadata); |
16244 | DIE_UNLESS(strcmp(field->table, "v1" ) == 0); |
16245 | DIE_UNLESS(strcmp(field->org_table, "v1" ) == 0); |
16246 | DIE_UNLESS(strcmp(field->db, "client_test_db" ) == 0); |
16247 | mysql_free_result(metadata); |
16248 | mysql_stmt_close(stmt); |
16249 | |
16250 | stmt= open_cursor("SELECT * FROM v1 /* SIC */ GROUP BY 1" ); |
16251 | rc= mysql_stmt_execute(stmt); |
16252 | check_execute(stmt, rc); |
16253 | |
16254 | metadata= mysql_stmt_result_metadata(stmt); |
16255 | field= mysql_fetch_field(metadata); |
16256 | DIE_UNLESS(strcmp(field->table, "v1" ) == 0); |
16257 | DIE_UNLESS(strcmp(field->org_table, "v1" ) == 0); |
16258 | DIE_UNLESS(strcmp(field->db, "client_test_db" ) == 0); |
16259 | mysql_free_result(metadata); |
16260 | mysql_stmt_close(stmt); |
16261 | |
16262 | rc= mysql_query(mysql, "DROP VIEW v1" ); |
16263 | myquery(rc); |
16264 | rc= mysql_query(mysql, "DROP TABLE t1" ); |
16265 | myquery(rc); |
16266 | |
16267 | DBUG_VOID_RETURN; |
16268 | } |
16269 | |
16270 | /* |
16271 | Bug#28075 "COM_DEBUG crashes mysqld" |
16272 | */ |
16273 | |
16274 | static void test_bug28075() |
16275 | { |
16276 | int rc; |
16277 | |
16278 | DBUG_ENTER("test_bug28075" ); |
16279 | myheader("test_bug28075" ); |
16280 | |
16281 | rc= mysql_dump_debug_info(mysql); |
16282 | DIE_UNLESS(rc == 0); |
16283 | |
16284 | rc= mysql_ping(mysql); |
16285 | DIE_UNLESS(rc == 0); |
16286 | |
16287 | DBUG_VOID_RETURN; |
16288 | } |
16289 | |
16290 | |
16291 | /* |
16292 | Bug#27876 (SF with cyrillic variable name fails during execution (regression)) |
16293 | */ |
16294 | |
16295 | static void test_bug27876() |
16296 | { |
16297 | int rc; |
16298 | MYSQL_RES *result; |
16299 | |
16300 | uchar utf8_func[] = |
16301 | { |
16302 | 0xd1, 0x84, 0xd1, 0x83, 0xd0, 0xbd, 0xd0, 0xba, |
16303 | 0xd1, 0x86, 0xd0, 0xb8, 0xd0, 0xb9, 0xd0, 0xba, |
16304 | 0xd0, 0xb0, |
16305 | 0x00 |
16306 | }; |
16307 | |
16308 | uchar utf8_param[] = |
16309 | { |
16310 | 0xd0, 0xbf, 0xd0, 0xb0, 0xd1, 0x80, 0xd0, 0xb0, |
16311 | 0xd0, 0xbc, 0xd0, 0xb5, 0xd1, 0x82, 0xd1, 0x8a, |
16312 | 0xd1, 0x80, 0x5f, 0xd0, 0xb2, 0xd0, 0xb5, 0xd1, |
16313 | 0x80, 0xd1, 0x81, 0xd0, 0xb8, 0xd1, 0x8f, |
16314 | 0x00 |
16315 | }; |
16316 | |
16317 | char query[500]; |
16318 | |
16319 | DBUG_ENTER("test_bug27876" ); |
16320 | myheader("test_bug27876" ); |
16321 | |
16322 | rc= mysql_query(mysql, "set names utf8" ); |
16323 | myquery(rc); |
16324 | |
16325 | rc= mysql_query(mysql, "select version()" ); |
16326 | myquery(rc); |
16327 | result= mysql_store_result(mysql); |
16328 | mytest(result); |
16329 | mysql_free_result(result); |
16330 | |
16331 | sprintf(query, "DROP FUNCTION IF EXISTS %s" , (char*) utf8_func); |
16332 | rc= mysql_query(mysql, query); |
16333 | myquery(rc); |
16334 | |
16335 | sprintf(query, |
16336 | "CREATE FUNCTION %s( %s VARCHAR(25))" |
16337 | " RETURNS VARCHAR(25) DETERMINISTIC RETURN %s" , |
16338 | (char*) utf8_func, (char*) utf8_param, (char*) utf8_param); |
16339 | rc= mysql_query(mysql, query); |
16340 | myquery(rc); |
16341 | sprintf(query, "SELECT %s(VERSION())" , (char*) utf8_func); |
16342 | rc= mysql_query(mysql, query); |
16343 | myquery(rc); |
16344 | result= mysql_store_result(mysql); |
16345 | mytest(result); |
16346 | mysql_free_result(result); |
16347 | |
16348 | sprintf(query, "DROP FUNCTION %s" , (char*) utf8_func); |
16349 | rc= mysql_query(mysql, query); |
16350 | myquery(rc); |
16351 | |
16352 | rc= mysql_query(mysql, "set names default" ); |
16353 | myquery(rc); |
16354 | |
16355 | DBUG_VOID_RETURN; |
16356 | } |
16357 | |
16358 | |
16359 | /* |
16360 | Bug#28505: mysql_affected_rows() returns wrong value if CLIENT_FOUND_ROWS |
16361 | flag is set. |
16362 | */ |
16363 | |
16364 | static void test_bug28505() |
16365 | { |
16366 | my_ulonglong res; |
16367 | |
16368 | myquery(mysql_query(mysql, "drop table if exists t1" )); |
16369 | myquery(mysql_query(mysql, "create table t1(f1 int primary key)" )); |
16370 | myquery(mysql_query(mysql, "insert into t1 values(1)" )); |
16371 | myquery(mysql_query(mysql, |
16372 | "insert into t1 values(1) on duplicate key update f1=1" )); |
16373 | res= mysql_affected_rows(mysql); |
16374 | DIE_UNLESS(!res); |
16375 | myquery(mysql_query(mysql, "drop table t1" )); |
16376 | } |
16377 | |
16378 | |
16379 | /* |
16380 | Bug#28934: server crash when receiving malformed com_execute packets |
16381 | */ |
16382 | |
16383 | static void test_bug28934() |
16384 | { |
16385 | my_bool error= 0; |
16386 | MYSQL_BIND bind[5]; |
16387 | MYSQL_STMT *stmt; |
16388 | int cnt; |
16389 | |
16390 | myquery(mysql_query(mysql, "drop table if exists t1" )); |
16391 | myquery(mysql_query(mysql, "create table t1(id int)" )); |
16392 | |
16393 | myquery(mysql_query(mysql, "insert into t1 values(1),(2),(3),(4),(5)" )); |
16394 | stmt= mysql_simple_prepare(mysql,"select * from t1 where id in(?,?,?,?,?)" ); |
16395 | check_stmt(stmt); |
16396 | |
16397 | memset (&bind, 0, sizeof (bind)); |
16398 | for (cnt= 0; cnt < 5; cnt++) |
16399 | { |
16400 | bind[cnt].buffer_type= MYSQL_TYPE_LONG; |
16401 | bind[cnt].buffer= (char*)&cnt; |
16402 | bind[cnt].buffer_length= 0; |
16403 | } |
16404 | myquery(mysql_stmt_bind_param(stmt, bind)); |
16405 | |
16406 | stmt->param_count=2; |
16407 | error= mysql_stmt_execute(stmt); |
16408 | DIE_UNLESS(error != 0); |
16409 | myerror(NULL); |
16410 | mysql_stmt_close(stmt); |
16411 | |
16412 | myquery(mysql_query(mysql, "drop table t1" )); |
16413 | } |
16414 | |
16415 | /* |
16416 | Test mysql_change_user() C API and COM_CHANGE_USER |
16417 | */ |
16418 | |
16419 | static void test_change_user() |
16420 | { |
16421 | char buff[256]; |
16422 | const char *user_pw= "mysqltest_pw" ; |
16423 | const char *user_no_pw= "mysqltest_no_pw" ; |
16424 | const char *pw= "password" ; |
16425 | const char *db= "mysqltest_user_test_database" ; |
16426 | int rc; |
16427 | MYSQL* conn; |
16428 | DBUG_ENTER("test_change_user" ); |
16429 | myheader("test_change_user" ); |
16430 | |
16431 | /* Prepare environment */ |
16432 | sprintf(buff, "drop database if exists %s" , db); |
16433 | rc= mysql_query(mysql, buff); |
16434 | myquery(rc); |
16435 | |
16436 | sprintf(buff, "create database %s" , db); |
16437 | rc= mysql_query(mysql, buff); |
16438 | myquery(rc); |
16439 | |
16440 | rc= mysql_query(mysql, "SET SQL_MODE=''" ); |
16441 | myquery(rc); |
16442 | |
16443 | sprintf(buff, |
16444 | "grant select on %s.* to %s@'%%' identified by '%s'" , |
16445 | db, |
16446 | user_pw, |
16447 | pw); |
16448 | rc= mysql_query(mysql, buff); |
16449 | myquery(rc); |
16450 | |
16451 | sprintf(buff, |
16452 | "grant select on %s.* to %s@'localhost' identified by '%s'" , |
16453 | db, |
16454 | user_pw, |
16455 | pw); |
16456 | rc= mysql_query(mysql, buff); |
16457 | myquery(rc); |
16458 | |
16459 | sprintf(buff, |
16460 | "grant select on %s.* to %s@'%%'" , |
16461 | db, |
16462 | user_no_pw); |
16463 | rc= mysql_query(mysql, buff); |
16464 | myquery(rc); |
16465 | |
16466 | sprintf(buff, |
16467 | "grant select on %s.* to %s@'localhost'" , |
16468 | db, |
16469 | user_no_pw); |
16470 | rc= mysql_query(mysql, buff); |
16471 | myquery(rc); |
16472 | |
16473 | conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0); |
16474 | |
16475 | /* Try some combinations */ |
16476 | rc= mysql_change_user(conn, NULL, NULL, NULL); |
16477 | DIE_UNLESS(rc); |
16478 | if (! opt_silent) |
16479 | printf("Got error (as expected): %s\n" , mysql_error(conn)); |
16480 | |
16481 | |
16482 | rc= mysql_change_user(conn, "" , NULL, NULL); |
16483 | DIE_UNLESS(rc); |
16484 | if (! opt_silent) |
16485 | printf("Got error (as expected): %s\n" , mysql_error(conn)); |
16486 | |
16487 | rc= mysql_change_user(conn, "" , "" , NULL); |
16488 | DIE_UNLESS(rc); |
16489 | if (! opt_silent) |
16490 | printf("Got error (as expected): %s\n" , mysql_error(conn)); |
16491 | |
16492 | mysql_close(conn); |
16493 | conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0); |
16494 | |
16495 | rc= mysql_change_user(conn, "" , "" , "" ); |
16496 | DIE_UNLESS(rc); |
16497 | if (! opt_silent) |
16498 | printf("Got error (as expected): %s\n" , mysql_error(conn)); |
16499 | |
16500 | rc= mysql_change_user(conn, NULL, "" , "" ); |
16501 | DIE_UNLESS(rc); |
16502 | if (! opt_silent) |
16503 | printf("Got error (as expected): %s\n" , mysql_error(conn)); |
16504 | |
16505 | |
16506 | rc= mysql_change_user(conn, NULL, NULL, "" ); |
16507 | DIE_UNLESS(rc); |
16508 | if (! opt_silent) |
16509 | printf("Got error (as expected): %s\n" , mysql_error(conn)); |
16510 | |
16511 | mysql_close(conn); |
16512 | conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0); |
16513 | |
16514 | rc= mysql_change_user(conn, "" , NULL, "" ); |
16515 | DIE_UNLESS(rc); |
16516 | if (! opt_silent) |
16517 | printf("Got error (as expected): %s\n" , mysql_error(conn)); |
16518 | |
16519 | rc= mysql_change_user(conn, user_pw, NULL, "" ); |
16520 | DIE_UNLESS(rc); |
16521 | if (! opt_silent) |
16522 | printf("Got error (as expected): %s\n" , mysql_error(conn)); |
16523 | |
16524 | rc= mysql_change_user(conn, user_pw, "" , "" ); |
16525 | DIE_UNLESS(rc); |
16526 | if (! opt_silent) |
16527 | printf("Got error (as expected): %s\n" , mysql_error(conn)); |
16528 | |
16529 | mysql_close(conn); |
16530 | conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0); |
16531 | |
16532 | rc= mysql_change_user(conn, user_pw, "" , NULL); |
16533 | DIE_UNLESS(rc); |
16534 | if (! opt_silent) |
16535 | printf("Got error (as expected): %s\n" , mysql_error(conn)); |
16536 | |
16537 | rc= mysql_change_user(conn, user_pw, NULL, NULL); |
16538 | DIE_UNLESS(rc); |
16539 | if (! opt_silent) |
16540 | printf("Got error (as expected): %s\n" , mysql_error(conn)); |
16541 | |
16542 | rc= mysql_change_user(conn, user_pw, "" , db); |
16543 | DIE_UNLESS(rc); |
16544 | if (! opt_silent) |
16545 | printf("Got error (as expected): %s\n" , mysql_error(conn)); |
16546 | |
16547 | mysql_close(conn); |
16548 | conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0); |
16549 | |
16550 | rc= mysql_change_user(conn, user_pw, NULL, db); |
16551 | DIE_UNLESS(rc); |
16552 | if (! opt_silent) |
16553 | printf("Got error (as expected): %s\n" , mysql_error(conn)); |
16554 | |
16555 | rc= mysql_change_user(conn, user_pw, pw, db); |
16556 | myquery(rc); |
16557 | |
16558 | rc= mysql_change_user(conn, user_pw, pw, NULL); |
16559 | myquery(rc); |
16560 | |
16561 | rc= mysql_change_user(conn, user_pw, pw, "" ); |
16562 | myquery(rc); |
16563 | |
16564 | rc= mysql_change_user(conn, user_no_pw, pw, db); |
16565 | DIE_UNLESS(rc); |
16566 | if (! opt_silent) |
16567 | printf("Got error (as expected): %s\n" , mysql_error(conn)); |
16568 | |
16569 | rc= mysql_change_user(conn, user_no_pw, pw, "" ); |
16570 | DIE_UNLESS(rc); |
16571 | if (! opt_silent) |
16572 | printf("Got error (as expected): %s\n" , mysql_error(conn)); |
16573 | |
16574 | mysql_close(conn); |
16575 | conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0); |
16576 | |
16577 | rc= mysql_change_user(conn, user_no_pw, pw, NULL); |
16578 | DIE_UNLESS(rc); |
16579 | if (! opt_silent) |
16580 | printf("Got error (as expected): %s\n" , mysql_error(conn)); |
16581 | |
16582 | rc= mysql_change_user(conn, user_no_pw, "" , NULL); |
16583 | myquery(rc); |
16584 | |
16585 | rc= mysql_change_user(conn, user_no_pw, "" , "" ); |
16586 | myquery(rc); |
16587 | |
16588 | rc= mysql_change_user(conn, user_no_pw, "" , db); |
16589 | myquery(rc); |
16590 | |
16591 | rc= mysql_change_user(conn, user_no_pw, NULL, db); |
16592 | myquery(rc); |
16593 | |
16594 | rc= mysql_change_user(conn, "" , pw, db); |
16595 | DIE_UNLESS(rc); |
16596 | if (! opt_silent) |
16597 | printf("Got error (as expected): %s\n" , mysql_error(conn)); |
16598 | |
16599 | rc= mysql_change_user(conn, "" , pw, "" ); |
16600 | DIE_UNLESS(rc); |
16601 | if (! opt_silent) |
16602 | printf("Got error (as expected): %s\n" , mysql_error(conn)); |
16603 | |
16604 | mysql_close(conn); |
16605 | conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0); |
16606 | |
16607 | rc= mysql_change_user(conn, "" , pw, NULL); |
16608 | DIE_UNLESS(rc); |
16609 | if (! opt_silent) |
16610 | printf("Got error (as expected): %s\n" , mysql_error(conn)); |
16611 | |
16612 | rc= mysql_change_user(conn, NULL, pw, NULL); |
16613 | DIE_UNLESS(rc); |
16614 | if (! opt_silent) |
16615 | printf("Got error (as expected): %s\n" , mysql_error(conn)); |
16616 | |
16617 | rc= mysql_change_user(conn, NULL, NULL, db); |
16618 | DIE_UNLESS(rc); |
16619 | if (! opt_silent) |
16620 | printf("Got error (as expected): %s\n" , mysql_error(conn)); |
16621 | |
16622 | mysql_close(conn); |
16623 | conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0); |
16624 | |
16625 | rc= mysql_change_user(conn, NULL, "" , db); |
16626 | DIE_UNLESS(rc); |
16627 | if (! opt_silent) |
16628 | printf("Got error (as expected): %s\n" , mysql_error(conn)); |
16629 | |
16630 | rc= mysql_change_user(conn, "" , "" , db); |
16631 | DIE_UNLESS(rc); |
16632 | if (! opt_silent) |
16633 | printf("Got error (as expected): %s\n" , mysql_error(conn)); |
16634 | |
16635 | /* Cleanup the environment */ |
16636 | |
16637 | mysql_change_user(conn, opt_user, opt_password, current_db); |
16638 | |
16639 | mysql_close(conn); |
16640 | |
16641 | sprintf(buff, "drop database %s" , db); |
16642 | rc= mysql_query(mysql, buff); |
16643 | myquery(rc); |
16644 | |
16645 | sprintf(buff, "drop user %s@'%%'" , user_pw); |
16646 | rc= mysql_query(mysql, buff); |
16647 | myquery(rc); |
16648 | |
16649 | sprintf(buff, "drop user %s@'%%'" , user_no_pw); |
16650 | rc= mysql_query(mysql, buff); |
16651 | myquery(rc); |
16652 | |
16653 | sprintf(buff, "drop user %s@'localhost'" , user_pw); |
16654 | rc= mysql_query(mysql, buff); |
16655 | myquery(rc); |
16656 | |
16657 | sprintf(buff, "drop user %s@'localhost'" , user_no_pw); |
16658 | rc= mysql_query(mysql, buff); |
16659 | myquery(rc); |
16660 | |
16661 | DBUG_VOID_RETURN; |
16662 | } |
16663 | |
16664 | /* |
16665 | Bug#27592 (stack overrun when storing datetime value using prepared statements) |
16666 | */ |
16667 | |
16668 | static void test_bug27592() |
16669 | { |
16670 | const int NUM_ITERATIONS= 40; |
16671 | int i; |
16672 | int rc; |
16673 | MYSQL_STMT *stmt= NULL; |
16674 | MYSQL_BIND bind[1]; |
16675 | MYSQL_TIME time_val; |
16676 | |
16677 | DBUG_ENTER("test_bug27592" ); |
16678 | myheader("test_bug27592" ); |
16679 | |
16680 | mysql_query(mysql, "DROP TABLE IF EXISTS t1" ); |
16681 | mysql_query(mysql, "CREATE TABLE t1(c2 DATETIME)" ); |
16682 | |
16683 | stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 VALUES (?)" ); |
16684 | DIE_UNLESS(stmt); |
16685 | |
16686 | memset(bind, 0, sizeof(bind)); |
16687 | |
16688 | bind[0].buffer_type= MYSQL_TYPE_DATETIME; |
16689 | bind[0].buffer= (char *) &time_val; |
16690 | bind[0].length= NULL; |
16691 | |
16692 | for (i= 0; i < NUM_ITERATIONS; i++) |
16693 | { |
16694 | time_val.year= 2007; |
16695 | time_val.month= 6; |
16696 | time_val.day= 7; |
16697 | time_val.hour= 18; |
16698 | time_val.minute= 41; |
16699 | time_val.second= 3; |
16700 | |
16701 | time_val.second_part=0; |
16702 | time_val.neg=0; |
16703 | |
16704 | rc= mysql_stmt_bind_param(stmt, bind); |
16705 | check_execute(stmt, rc); |
16706 | |
16707 | rc= mysql_stmt_execute(stmt); |
16708 | check_execute(stmt, rc); |
16709 | } |
16710 | |
16711 | mysql_stmt_close(stmt); |
16712 | |
16713 | DBUG_VOID_RETURN; |
16714 | } |
16715 | |
16716 | /* |
16717 | Bug#29687 mysql_stmt_store_result memory leak in libmysqld |
16718 | */ |
16719 | |
16720 | static void test_bug29687() |
16721 | { |
16722 | const int NUM_ITERATIONS= 40; |
16723 | int i; |
16724 | int rc; |
16725 | MYSQL_STMT *stmt= NULL; |
16726 | |
16727 | DBUG_ENTER("test_bug29687" ); |
16728 | myheader("test_bug29687" ); |
16729 | |
16730 | stmt= mysql_simple_prepare(mysql, "SELECT 1 FROM dual WHERE 0=2" ); |
16731 | DIE_UNLESS(stmt); |
16732 | |
16733 | for (i= 0; i < NUM_ITERATIONS; i++) |
16734 | { |
16735 | rc= mysql_stmt_execute(stmt); |
16736 | check_execute(stmt, rc); |
16737 | mysql_stmt_store_result(stmt); |
16738 | while (mysql_stmt_fetch(stmt)==0); |
16739 | mysql_stmt_free_result(stmt); |
16740 | } |
16741 | |
16742 | mysql_stmt_close(stmt); |
16743 | DBUG_VOID_RETURN; |
16744 | } |
16745 | |
16746 | |
16747 | /* |
16748 | Bug #29692 Single row inserts can incorrectly report a huge number of |
16749 | row insertions |
16750 | */ |
16751 | |
16752 | static void test_bug29692() |
16753 | { |
16754 | MYSQL* conn; |
16755 | |
16756 | if (!(conn= mysql_client_init(NULL))) |
16757 | { |
16758 | myerror("test_bug29692 init failed" ); |
16759 | exit(1); |
16760 | } |
16761 | |
16762 | if (!(mysql_real_connect(conn, opt_host, opt_user, |
16763 | opt_password, opt_db ? opt_db:"test" , opt_port, |
16764 | opt_unix_socket, CLIENT_FOUND_ROWS))) |
16765 | { |
16766 | myerror("test_bug29692 connection failed" ); |
16767 | mysql_close(mysql); |
16768 | exit(1); |
16769 | } |
16770 | myquery(mysql_query(conn, "drop table if exists t1" )); |
16771 | myquery(mysql_query(conn, "create table t1(f1 int)" )); |
16772 | myquery(mysql_query(conn, "insert into t1 values(1)" )); |
16773 | DIE_UNLESS(1 == mysql_affected_rows(conn)); |
16774 | myquery(mysql_query(conn, "drop table t1" )); |
16775 | mysql_close(conn); |
16776 | } |
16777 | |
16778 | /** |
16779 | Bug#29306 Truncated data in MS Access with decimal (3,1) columns in a VIEW |
16780 | */ |
16781 | |
16782 | static void test_bug29306() |
16783 | { |
16784 | MYSQL_FIELD *field; |
16785 | int rc; |
16786 | MYSQL_RES *res; |
16787 | |
16788 | DBUG_ENTER("test_bug29306" ); |
16789 | myheader("test_bug29306" ); |
16790 | |
16791 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS tab17557" ); |
16792 | myquery(rc); |
16793 | rc= mysql_query(mysql, "DROP VIEW IF EXISTS view17557" ); |
16794 | myquery(rc); |
16795 | rc= mysql_query(mysql, "CREATE TABLE tab17557 (dd decimal (3,1))" ); |
16796 | myquery(rc); |
16797 | rc= mysql_query(mysql, "CREATE VIEW view17557 as SELECT dd FROM tab17557" ); |
16798 | myquery(rc); |
16799 | rc= mysql_query(mysql, "INSERT INTO tab17557 VALUES (7.6)" ); |
16800 | myquery(rc); |
16801 | |
16802 | /* Checking the view */ |
16803 | res= mysql_list_fields(mysql, "view17557" , NULL); |
16804 | while ((field= mysql_fetch_field(res))) |
16805 | { |
16806 | if (! opt_silent) |
16807 | { |
16808 | printf("field name %s\n" , field->name); |
16809 | printf("field table %s\n" , field->table); |
16810 | printf("field decimals %d\n" , field->decimals); |
16811 | if (field->decimals < 1) |
16812 | printf("Error! No decimals! \n" ); |
16813 | printf("\n\n" ); |
16814 | } |
16815 | DIE_UNLESS(field->decimals == 1); |
16816 | } |
16817 | mysql_free_result(res); |
16818 | |
16819 | rc= mysql_query(mysql, "DROP TABLE tab17557" ); |
16820 | myquery(rc); |
16821 | rc= mysql_query(mysql, "DROP VIEW view17557" ); |
16822 | myquery(rc); |
16823 | |
16824 | DBUG_VOID_RETURN; |
16825 | } |
16826 | /* |
16827 | Bug#30472: libmysql doesn't reset charset, insert_id after succ. |
16828 | mysql_change_user() call row insertions. |
16829 | */ |
16830 | |
16831 | static void bug30472_retrieve_charset_info(MYSQL *con, |
16832 | char *character_set_name, |
16833 | char *character_set_client, |
16834 | char *character_set_results, |
16835 | char *collation_connection) |
16836 | { |
16837 | MYSQL_RES *rs; |
16838 | MYSQL_ROW row; |
16839 | |
16840 | /* Get the cached client character set name. */ |
16841 | |
16842 | strcpy(character_set_name, mysql_character_set_name(con)); |
16843 | |
16844 | /* Retrieve server character set information. */ |
16845 | |
16846 | DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'character_set_client'" )); |
16847 | DIE_UNLESS(rs= mysql_store_result(con)); |
16848 | DIE_UNLESS(row= mysql_fetch_row(rs)); |
16849 | strcpy(character_set_client, row[1]); |
16850 | mysql_free_result(rs); |
16851 | |
16852 | DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'character_set_results'" )); |
16853 | DIE_UNLESS(rs= mysql_store_result(con)); |
16854 | DIE_UNLESS(row= mysql_fetch_row(rs)); |
16855 | strcpy(character_set_results, row[1]); |
16856 | mysql_free_result(rs); |
16857 | |
16858 | DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'collation_connection'" )); |
16859 | DIE_UNLESS(rs= mysql_store_result(con)); |
16860 | DIE_UNLESS(row= mysql_fetch_row(rs)); |
16861 | strcpy(collation_connection, row[1]); |
16862 | mysql_free_result(rs); |
16863 | } |
16864 | |
16865 | static void test_bug30472() |
16866 | { |
16867 | MYSQL con; |
16868 | |
16869 | char character_set_name_1[MY_CS_NAME_SIZE]; |
16870 | char character_set_client_1[MY_CS_NAME_SIZE]; |
16871 | char character_set_results_1[MY_CS_NAME_SIZE]; |
16872 | char collation_connnection_1[MY_CS_NAME_SIZE]; |
16873 | |
16874 | char character_set_name_2[MY_CS_NAME_SIZE]; |
16875 | char character_set_client_2[MY_CS_NAME_SIZE]; |
16876 | char character_set_results_2[MY_CS_NAME_SIZE]; |
16877 | char collation_connnection_2[MY_CS_NAME_SIZE]; |
16878 | |
16879 | char character_set_name_3[MY_CS_NAME_SIZE]; |
16880 | char character_set_client_3[MY_CS_NAME_SIZE]; |
16881 | char character_set_results_3[MY_CS_NAME_SIZE]; |
16882 | char collation_connnection_3[MY_CS_NAME_SIZE]; |
16883 | |
16884 | char character_set_name_4[MY_CS_NAME_SIZE]; |
16885 | char character_set_client_4[MY_CS_NAME_SIZE]; |
16886 | char character_set_results_4[MY_CS_NAME_SIZE]; |
16887 | char collation_connnection_4[MY_CS_NAME_SIZE]; |
16888 | |
16889 | /* Create a new connection. */ |
16890 | |
16891 | DIE_UNLESS(mysql_client_init(&con)); |
16892 | |
16893 | DIE_UNLESS(mysql_real_connect(&con, |
16894 | opt_host, |
16895 | opt_user, |
16896 | opt_password, |
16897 | opt_db ? opt_db : "test" , |
16898 | opt_port, |
16899 | opt_unix_socket, |
16900 | CLIENT_FOUND_ROWS)); |
16901 | |
16902 | /* Retrieve character set information. */ |
16903 | |
16904 | bug30472_retrieve_charset_info(&con, |
16905 | character_set_name_1, |
16906 | character_set_client_1, |
16907 | character_set_results_1, |
16908 | collation_connnection_1); |
16909 | |
16910 | /* Switch client character set. */ |
16911 | |
16912 | DIE_IF(mysql_set_character_set(&con, "latin2" )); |
16913 | |
16914 | /* Retrieve character set information. */ |
16915 | |
16916 | bug30472_retrieve_charset_info(&con, |
16917 | character_set_name_2, |
16918 | character_set_client_2, |
16919 | character_set_results_2, |
16920 | collation_connnection_2); |
16921 | |
16922 | /* |
16923 | Check that |
16924 | 1) character set has been switched and |
16925 | 2) new character set is different from the original one. |
16926 | */ |
16927 | |
16928 | DIE_UNLESS(strcmp(character_set_name_2, "latin2" ) == 0); |
16929 | DIE_UNLESS(strcmp(character_set_client_2, "latin2" ) == 0); |
16930 | DIE_UNLESS(strcmp(character_set_results_2, "latin2" ) == 0); |
16931 | DIE_UNLESS(strcmp(collation_connnection_2, "latin2_general_ci" ) == 0); |
16932 | |
16933 | DIE_UNLESS(strcmp(character_set_name_1, character_set_name_2) != 0); |
16934 | DIE_UNLESS(strcmp(character_set_client_1, character_set_client_2) != 0); |
16935 | DIE_UNLESS(strcmp(character_set_results_1, character_set_results_2) != 0); |
16936 | DIE_UNLESS(strcmp(collation_connnection_1, collation_connnection_2) != 0); |
16937 | |
16938 | /* Call mysql_change_user() with the same username, password, database. */ |
16939 | |
16940 | DIE_IF(mysql_change_user(&con, |
16941 | opt_user, |
16942 | opt_password, |
16943 | opt_db ? opt_db : "test" )); |
16944 | |
16945 | /* Retrieve character set information. */ |
16946 | |
16947 | bug30472_retrieve_charset_info(&con, |
16948 | character_set_name_3, |
16949 | character_set_client_3, |
16950 | character_set_results_3, |
16951 | collation_connnection_3); |
16952 | |
16953 | /* Check that character set information has been reset. */ |
16954 | |
16955 | DIE_UNLESS(strcmp(character_set_name_1, character_set_name_3) == 0); |
16956 | DIE_UNLESS(strcmp(character_set_client_1, character_set_client_3) == 0); |
16957 | DIE_UNLESS(strcmp(character_set_results_1, character_set_results_3) == 0); |
16958 | DIE_UNLESS(strcmp(collation_connnection_1, collation_connnection_3) == 0); |
16959 | |
16960 | /* Change connection-default character set in the client. */ |
16961 | |
16962 | mysql_options(&con, MYSQL_SET_CHARSET_NAME, "utf8" ); |
16963 | |
16964 | /* |
16965 | Call mysql_change_user() in order to check that new connection will |
16966 | have UTF8 character set on the client and on the server. |
16967 | */ |
16968 | |
16969 | DIE_IF(mysql_change_user(&con, |
16970 | opt_user, |
16971 | opt_password, |
16972 | opt_db ? opt_db : "test" )); |
16973 | |
16974 | /* Retrieve character set information. */ |
16975 | |
16976 | bug30472_retrieve_charset_info(&con, |
16977 | character_set_name_4, |
16978 | character_set_client_4, |
16979 | character_set_results_4, |
16980 | collation_connnection_4); |
16981 | |
16982 | /* Check that we have UTF8 on the server and on the client. */ |
16983 | |
16984 | DIE_UNLESS(strcmp(character_set_name_4, "utf8" ) == 0); |
16985 | DIE_UNLESS(strcmp(character_set_client_4, "utf8" ) == 0); |
16986 | DIE_UNLESS(strcmp(character_set_results_4, "utf8" ) == 0); |
16987 | DIE_UNLESS(strcmp(collation_connnection_4, "utf8_general_ci" ) == 0); |
16988 | |
16989 | /* That's it. Cleanup. */ |
16990 | |
16991 | mysql_close(&con); |
16992 | } |
16993 | |
16994 | static void bug20023_change_user(MYSQL *con) |
16995 | { |
16996 | DIE_IF(mysql_change_user(con, |
16997 | opt_user, |
16998 | opt_password, |
16999 | opt_db ? opt_db : "test" )); |
17000 | } |
17001 | |
17002 | static my_bool query_str_variable(MYSQL *con, |
17003 | const char *var_name, |
17004 | char *str, |
17005 | size_t len) |
17006 | { |
17007 | MYSQL_RES *rs; |
17008 | MYSQL_ROW row; |
17009 | |
17010 | char query_buffer[MAX_TEST_QUERY_LENGTH]; |
17011 | |
17012 | my_bool is_null; |
17013 | |
17014 | my_snprintf(query_buffer, sizeof (query_buffer), |
17015 | "SELECT %s" , var_name); |
17016 | |
17017 | DIE_IF(mysql_query(con, query_buffer)); |
17018 | DIE_UNLESS(rs= mysql_store_result(con)); |
17019 | DIE_UNLESS(row= mysql_fetch_row(rs)); |
17020 | |
17021 | is_null= row[0] == NULL; |
17022 | |
17023 | if (!is_null) |
17024 | my_snprintf(str, len, "%s" , row[0]); |
17025 | |
17026 | mysql_free_result(rs); |
17027 | |
17028 | return is_null; |
17029 | } |
17030 | |
17031 | static my_bool query_int_variable(MYSQL *con, |
17032 | const char *var_name, |
17033 | int *var_value) |
17034 | { |
17035 | char str[32]; |
17036 | my_bool is_null= query_str_variable(con, var_name, str, sizeof(str)); |
17037 | |
17038 | if (!is_null) |
17039 | *var_value= atoi(str); |
17040 | |
17041 | return is_null; |
17042 | } |
17043 | |
17044 | static void test_bug20023() |
17045 | { |
17046 | MYSQL con; |
17047 | |
17048 | int sql_big_selects_orig= 0; |
17049 | /* |
17050 | Type of max_join_size is ha_rows, which might be ulong or off_t |
17051 | depending on the platform or configure options. Preserve the string |
17052 | to avoid type overflow pitfalls. |
17053 | */ |
17054 | char max_join_size_orig[32]; |
17055 | |
17056 | int sql_big_selects_2= 0; |
17057 | int sql_big_selects_3= 0; |
17058 | int sql_big_selects_4= 0; |
17059 | int sql_big_selects_5= 0; |
17060 | |
17061 | char query_buffer[MAX_TEST_QUERY_LENGTH]; |
17062 | |
17063 | /* Create a new connection. */ |
17064 | |
17065 | DIE_UNLESS(mysql_client_init(&con)); |
17066 | |
17067 | DIE_UNLESS(mysql_real_connect(&con, |
17068 | opt_host, |
17069 | opt_user, |
17070 | opt_password, |
17071 | opt_db ? opt_db : "test" , |
17072 | opt_port, |
17073 | opt_unix_socket, |
17074 | CLIENT_FOUND_ROWS)); |
17075 | |
17076 | /*********************************************************************** |
17077 | Remember original SQL_BIG_SELECTS, MAX_JOIN_SIZE values. |
17078 | ***********************************************************************/ |
17079 | |
17080 | query_int_variable(&con, |
17081 | "@@session.sql_big_selects" , |
17082 | &sql_big_selects_orig); |
17083 | |
17084 | query_str_variable(&con, |
17085 | "@@global.max_join_size" , |
17086 | max_join_size_orig, |
17087 | sizeof(max_join_size_orig)); |
17088 | |
17089 | /*********************************************************************** |
17090 | Test that COM_CHANGE_USER resets the SQL_BIG_SELECTS to the initial value. |
17091 | ***********************************************************************/ |
17092 | |
17093 | /* Issue COM_CHANGE_USER. */ |
17094 | |
17095 | bug20023_change_user(&con); |
17096 | |
17097 | /* Query SQL_BIG_SELECTS. */ |
17098 | |
17099 | query_int_variable(&con, |
17100 | "@@session.sql_big_selects" , |
17101 | &sql_big_selects_2); |
17102 | |
17103 | /* Check that SQL_BIG_SELECTS is reset properly. */ |
17104 | |
17105 | DIE_UNLESS(sql_big_selects_orig == sql_big_selects_2); |
17106 | |
17107 | /*********************************************************************** |
17108 | Test that if MAX_JOIN_SIZE set to non-default value, |
17109 | SQL_BIG_SELECTS will be 0. |
17110 | ***********************************************************************/ |
17111 | |
17112 | /* Set MAX_JOIN_SIZE to some non-default value. */ |
17113 | |
17114 | DIE_IF(mysql_query(&con, "SET @@global.max_join_size = 10000" )); |
17115 | DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default" )); |
17116 | |
17117 | /* Issue COM_CHANGE_USER. */ |
17118 | |
17119 | bug20023_change_user(&con); |
17120 | |
17121 | /* Query SQL_BIG_SELECTS. */ |
17122 | |
17123 | query_int_variable(&con, |
17124 | "@@session.sql_big_selects" , |
17125 | &sql_big_selects_3); |
17126 | |
17127 | /* Check that SQL_BIG_SELECTS is 0. */ |
17128 | |
17129 | DIE_UNLESS(sql_big_selects_3 == 0); |
17130 | |
17131 | /*********************************************************************** |
17132 | Test that if MAX_JOIN_SIZE set to default value, |
17133 | SQL_BIG_SELECTS will be 1. |
17134 | ***********************************************************************/ |
17135 | |
17136 | /* Set MAX_JOIN_SIZE to the default value (2^64-1). */ |
17137 | |
17138 | DIE_IF(mysql_query(&con, "SET @@global.max_join_size = cast(-1 as unsigned int)" )); |
17139 | DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default" )); |
17140 | |
17141 | /* Issue COM_CHANGE_USER. */ |
17142 | |
17143 | bug20023_change_user(&con); |
17144 | |
17145 | /* Query SQL_BIG_SELECTS. */ |
17146 | |
17147 | query_int_variable(&con, |
17148 | "@@session.sql_big_selects" , |
17149 | &sql_big_selects_4); |
17150 | |
17151 | /* Check that SQL_BIG_SELECTS is 1. */ |
17152 | |
17153 | DIE_UNLESS(sql_big_selects_4 == 1); |
17154 | |
17155 | /*********************************************************************** |
17156 | Restore MAX_JOIN_SIZE. |
17157 | Check that SQL_BIG_SELECTS will be the original one. |
17158 | ***********************************************************************/ |
17159 | |
17160 | /* Restore MAX_JOIN_SIZE. */ |
17161 | |
17162 | my_snprintf(query_buffer, |
17163 | sizeof (query_buffer), |
17164 | "SET @@global.max_join_size = %s" , |
17165 | max_join_size_orig); |
17166 | |
17167 | DIE_IF(mysql_query(&con, query_buffer)); |
17168 | |
17169 | DIE_IF(mysql_query(&con, "SET @@global.max_join_size = cast(-1 as unsigned int)" )); |
17170 | DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default" )); |
17171 | |
17172 | /* Issue COM_CHANGE_USER. */ |
17173 | |
17174 | bug20023_change_user(&con); |
17175 | |
17176 | /* Query SQL_BIG_SELECTS. */ |
17177 | |
17178 | query_int_variable(&con, |
17179 | "@@session.sql_big_selects" , |
17180 | &sql_big_selects_5); |
17181 | |
17182 | /* Check that SQL_BIG_SELECTS is 1. */ |
17183 | |
17184 | DIE_UNLESS(sql_big_selects_5 == sql_big_selects_orig); |
17185 | |
17186 | /*********************************************************************** |
17187 | That's it. Cleanup. |
17188 | ***********************************************************************/ |
17189 | |
17190 | mysql_close(&con); |
17191 | } |
17192 | |
17193 | static void bug31418_impl() |
17194 | { |
17195 | MYSQL con; |
17196 | |
17197 | my_bool is_null; |
17198 | int rc= 0; |
17199 | |
17200 | /* Create a new connection. */ |
17201 | |
17202 | DIE_UNLESS(mysql_client_init(&con)); |
17203 | |
17204 | DIE_UNLESS(mysql_real_connect(&con, |
17205 | opt_host, |
17206 | opt_user, |
17207 | opt_password, |
17208 | opt_db ? opt_db : "test" , |
17209 | opt_port, |
17210 | opt_unix_socket, |
17211 | CLIENT_FOUND_ROWS)); |
17212 | |
17213 | /*********************************************************************** |
17214 | Check that lock is free: |
17215 | - IS_FREE_LOCK() should return 1; |
17216 | - IS_USED_LOCK() should return NULL; |
17217 | ***********************************************************************/ |
17218 | |
17219 | is_null= query_int_variable(&con, |
17220 | "IS_FREE_LOCK('bug31418')" , |
17221 | &rc); |
17222 | DIE_UNLESS(!is_null && rc); |
17223 | |
17224 | is_null= query_int_variable(&con, |
17225 | "IS_USED_LOCK('bug31418')" , |
17226 | &rc); |
17227 | DIE_UNLESS(is_null); |
17228 | |
17229 | /*********************************************************************** |
17230 | Acquire lock and check the lock status (the lock must be in use): |
17231 | - IS_FREE_LOCK() should return 0; |
17232 | - IS_USED_LOCK() should return non-zero thread id; |
17233 | ***********************************************************************/ |
17234 | |
17235 | query_int_variable(&con, "GET_LOCK('bug31418', 1)" , &rc); |
17236 | DIE_UNLESS(rc); |
17237 | |
17238 | is_null= query_int_variable(&con, |
17239 | "IS_FREE_LOCK('bug31418')" , |
17240 | &rc); |
17241 | DIE_UNLESS(!is_null && !rc); |
17242 | |
17243 | is_null= query_int_variable(&con, |
17244 | "IS_USED_LOCK('bug31418')" , |
17245 | &rc); |
17246 | DIE_UNLESS(!is_null && rc); |
17247 | |
17248 | /*********************************************************************** |
17249 | Issue COM_CHANGE_USER command and check the lock status |
17250 | (the lock must be free): |
17251 | - IS_FREE_LOCK() should return 1; |
17252 | - IS_USED_LOCK() should return NULL; |
17253 | **********************************************************************/ |
17254 | |
17255 | bug20023_change_user(&con); |
17256 | |
17257 | is_null= query_int_variable(&con, |
17258 | "IS_FREE_LOCK('bug31418')" , |
17259 | &rc); |
17260 | DIE_UNLESS(!is_null && rc); |
17261 | |
17262 | is_null= query_int_variable(&con, |
17263 | "IS_USED_LOCK('bug31418')" , |
17264 | &rc); |
17265 | DIE_UNLESS(is_null); |
17266 | |
17267 | /*********************************************************************** |
17268 | That's it. Cleanup. |
17269 | ***********************************************************************/ |
17270 | |
17271 | mysql_close(&con); |
17272 | } |
17273 | |
17274 | static void test_bug31418() |
17275 | { |
17276 | /* Run test case for BUG#31418 for three different connections. */ |
17277 | |
17278 | bug31418_impl(); |
17279 | |
17280 | bug31418_impl(); |
17281 | |
17282 | bug31418_impl(); |
17283 | } |
17284 | |
17285 | |
17286 | |
17287 | /** |
17288 | Bug#31669 Buffer overflow in mysql_change_user() |
17289 | */ |
17290 | |
17291 | #define LARGE_BUFFER_SIZE 2048 |
17292 | #define OLD_USERNAME_CHAR_LENGTH 16 |
17293 | |
17294 | static void test_bug31669() |
17295 | { |
17296 | int rc; |
17297 | static char buff[LARGE_BUFFER_SIZE+1]; |
17298 | #ifndef EMBEDDED_LIBRARY |
17299 | static char user[OLD_USERNAME_CHAR_LENGTH+1]; |
17300 | static char db[NAME_CHAR_LEN+1]; |
17301 | static char query[LARGE_BUFFER_SIZE*2]; |
17302 | #endif |
17303 | MYSQL* conn; |
17304 | |
17305 | DBUG_ENTER("test_bug31669" ); |
17306 | myheader("test_bug31669" ); |
17307 | |
17308 | conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0); |
17309 | |
17310 | rc= mysql_change_user(conn, NULL, NULL, NULL); |
17311 | DIE_UNLESS(rc); |
17312 | |
17313 | rc= mysql_change_user(conn, "" , "" , "" ); |
17314 | DIE_UNLESS(rc); |
17315 | |
17316 | memset(buff, 'a', sizeof(buff) - 1); |
17317 | buff[sizeof(buff) - 1]= 0; |
17318 | |
17319 | mysql_close(conn); |
17320 | conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0); |
17321 | |
17322 | rc= mysql_change_user(conn, buff, buff, buff); |
17323 | DIE_UNLESS(rc); |
17324 | |
17325 | rc = mysql_change_user(conn, opt_user, opt_password, current_db); |
17326 | DIE_UNLESS(!rc); |
17327 | |
17328 | #ifndef EMBEDDED_LIBRARY |
17329 | memset(db, 'a', sizeof(db)); |
17330 | db[NAME_CHAR_LEN]= 0; |
17331 | strxmov(query, "CREATE DATABASE IF NOT EXISTS " , db, NullS); |
17332 | rc= mysql_query(conn, query); |
17333 | myquery(rc); |
17334 | |
17335 | memset(user, 'b', sizeof(user)); |
17336 | user[OLD_USERNAME_CHAR_LENGTH]= 0; |
17337 | memset(buff, 'c', sizeof(buff)); |
17338 | buff[LARGE_BUFFER_SIZE]= 0; |
17339 | strxmov(query, "GRANT ALL PRIVILEGES ON *.* TO '" , user, "'@'%' IDENTIFIED BY " |
17340 | "'" , buff, "' WITH GRANT OPTION" , NullS); |
17341 | rc= mysql_query(conn, query); |
17342 | myquery(rc); |
17343 | |
17344 | strxmov(query, "GRANT ALL PRIVILEGES ON *.* TO '" , user, "'@'localhost' IDENTIFIED BY " |
17345 | "'" , buff, "' WITH GRANT OPTION" , NullS); |
17346 | rc= mysql_query(conn, query); |
17347 | myquery(rc); |
17348 | |
17349 | rc= mysql_query(conn, "FLUSH PRIVILEGES" ); |
17350 | myquery(rc); |
17351 | |
17352 | rc= mysql_change_user(conn, user, buff, db); |
17353 | DIE_UNLESS(!rc); |
17354 | |
17355 | user[OLD_USERNAME_CHAR_LENGTH-1]= 'a'; |
17356 | rc= mysql_change_user(conn, user, buff, db); |
17357 | DIE_UNLESS(rc); |
17358 | |
17359 | user[OLD_USERNAME_CHAR_LENGTH-1]= 'b'; |
17360 | buff[LARGE_BUFFER_SIZE-1]= 'd'; |
17361 | rc= mysql_change_user(conn, user, buff, db); |
17362 | DIE_UNLESS(rc); |
17363 | |
17364 | buff[LARGE_BUFFER_SIZE-1]= 'c'; |
17365 | db[NAME_CHAR_LEN-1]= 'e'; |
17366 | rc= mysql_change_user(conn, user, buff, db); |
17367 | DIE_UNLESS(rc); |
17368 | |
17369 | mysql_close(conn); |
17370 | conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0); |
17371 | |
17372 | db[NAME_CHAR_LEN-1]= 'a'; |
17373 | rc= mysql_change_user(conn, user, buff, db); |
17374 | DIE_UNLESS(!rc); |
17375 | |
17376 | rc= mysql_change_user(conn, user + 1, buff + 1, db + 1); |
17377 | DIE_UNLESS(rc); |
17378 | |
17379 | rc = mysql_change_user(conn, opt_user, opt_password, current_db); |
17380 | DIE_UNLESS(!rc); |
17381 | |
17382 | strxmov(query, "DROP DATABASE " , db, NullS); |
17383 | rc= mysql_query(conn, query); |
17384 | myquery(rc); |
17385 | |
17386 | strxmov(query, "DELETE FROM mysql.user WHERE User='" , user, "'" , NullS); |
17387 | rc= mysql_query(conn, query); |
17388 | myquery(rc); |
17389 | DIE_UNLESS(mysql_affected_rows(conn) == 2); |
17390 | #endif |
17391 | |
17392 | mysql_close(conn); |
17393 | |
17394 | DBUG_VOID_RETURN; |
17395 | } |
17396 | |
17397 | |
17398 | /** |
17399 | Bug#28386 the general log is incomplete |
17400 | */ |
17401 | |
17402 | static void test_bug28386() |
17403 | { |
17404 | int rc; |
17405 | MYSQL_STMT *stmt; |
17406 | MYSQL_RES *result; |
17407 | MYSQL_ROW row; |
17408 | MYSQL_BIND bind; |
17409 | const char hello[]= "hello world!" ; |
17410 | |
17411 | DBUG_ENTER("test_bug28386" ); |
17412 | myheader("test_bug28386" ); |
17413 | |
17414 | rc= mysql_query(mysql, "select @@global.log_output" ); |
17415 | myquery(rc); |
17416 | |
17417 | result= mysql_store_result(mysql); |
17418 | DIE_UNLESS(result); |
17419 | |
17420 | row= mysql_fetch_row(result); |
17421 | if (! strstr(row[0], "TABLE" )) |
17422 | { |
17423 | mysql_free_result(result); |
17424 | if (! opt_silent) |
17425 | printf("Skipping the test since logging to tables is not enabled\n" ); |
17426 | /* Log output is not to tables */ |
17427 | DBUG_VOID_RETURN; |
17428 | } |
17429 | mysql_free_result(result); |
17430 | |
17431 | enable_query_logs(1); |
17432 | |
17433 | stmt= mysql_simple_prepare(mysql, "SELECT ?" ); |
17434 | check_stmt(stmt); |
17435 | |
17436 | memset(&bind, 0, sizeof(bind)); |
17437 | |
17438 | bind.buffer_type= MYSQL_TYPE_STRING; |
17439 | bind.buffer= (void *) hello; |
17440 | bind.buffer_length= sizeof(hello); |
17441 | |
17442 | mysql_stmt_bind_param(stmt, &bind); |
17443 | mysql_stmt_send_long_data(stmt, 0, hello, sizeof(hello)); |
17444 | |
17445 | rc= mysql_stmt_execute(stmt); |
17446 | check_execute(stmt, rc); |
17447 | |
17448 | rc= my_process_stmt_result(stmt); |
17449 | DIE_UNLESS(rc == 1); |
17450 | |
17451 | rc= mysql_stmt_reset(stmt); |
17452 | check_execute(stmt, rc); |
17453 | |
17454 | rc= mysql_stmt_close(stmt); |
17455 | DIE_UNLESS(!rc); |
17456 | |
17457 | rc= mysql_query(mysql, "select * from mysql.general_log where " |
17458 | "command_type='Close stmt' or " |
17459 | "command_type='Reset stmt' or " |
17460 | "command_type='Long Data'" ); |
17461 | myquery(rc); |
17462 | |
17463 | result= mysql_store_result(mysql); |
17464 | mytest(result); |
17465 | |
17466 | DIE_UNLESS(mysql_num_rows(result) == 3); |
17467 | |
17468 | mysql_free_result(result); |
17469 | |
17470 | restore_query_logs(); |
17471 | |
17472 | DBUG_VOID_RETURN; |
17473 | } |
17474 | |
17475 | |
17476 | static void test_wl4166_1() |
17477 | { |
17478 | MYSQL_STMT *stmt; |
17479 | int int_data; |
17480 | char str_data[50]; |
17481 | char tiny_data; |
17482 | short small_data; |
17483 | longlong big_data; |
17484 | float real_data; |
17485 | double double_data; |
17486 | ulong length[7]; |
17487 | my_bool is_null[7]; |
17488 | MYSQL_BIND my_bind[7]; |
17489 | int rc; |
17490 | int i; |
17491 | |
17492 | myheader("test_wl4166_1" ); |
17493 | |
17494 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS table_4166" ); |
17495 | myquery(rc); |
17496 | |
17497 | rc= mysql_query(mysql, "CREATE TABLE table_4166(col1 tinyint NOT NULL, " |
17498 | "col2 varchar(15), col3 int, " |
17499 | "col4 smallint, col5 bigint, " |
17500 | "col6 float, col7 double, " |
17501 | "colX varchar(10) default NULL)" ); |
17502 | myquery(rc); |
17503 | |
17504 | stmt= mysql_simple_prepare(mysql, |
17505 | "INSERT INTO table_4166(col1, col2, col3, col4, col5, col6, col7) " |
17506 | "VALUES(?, ?, ?, ?, ?, ?, ?)" ); |
17507 | check_stmt(stmt); |
17508 | |
17509 | verify_param_count(stmt, 7); |
17510 | |
17511 | bzero(my_bind, sizeof(my_bind)); |
17512 | /* tinyint */ |
17513 | my_bind[0].buffer_type= MYSQL_TYPE_TINY; |
17514 | my_bind[0].buffer= (void *)&tiny_data; |
17515 | /* string */ |
17516 | my_bind[1].buffer_type= MYSQL_TYPE_STRING; |
17517 | my_bind[1].buffer= (void *)str_data; |
17518 | my_bind[1].buffer_length= 1000; /* Max string length */ |
17519 | /* integer */ |
17520 | my_bind[2].buffer_type= MYSQL_TYPE_LONG; |
17521 | my_bind[2].buffer= (void *)&int_data; |
17522 | /* short */ |
17523 | my_bind[3].buffer_type= MYSQL_TYPE_SHORT; |
17524 | my_bind[3].buffer= (void *)&small_data; |
17525 | /* bigint */ |
17526 | my_bind[4].buffer_type= MYSQL_TYPE_LONGLONG; |
17527 | my_bind[4].buffer= (void *)&big_data; |
17528 | /* float */ |
17529 | my_bind[5].buffer_type= MYSQL_TYPE_FLOAT; |
17530 | my_bind[5].buffer= (void *)&real_data; |
17531 | /* double */ |
17532 | my_bind[6].buffer_type= MYSQL_TYPE_DOUBLE; |
17533 | my_bind[6].buffer= (void *)&double_data; |
17534 | |
17535 | for (i= 0; i < (int) array_elements(my_bind); i++) |
17536 | { |
17537 | my_bind[i].length= &length[i]; |
17538 | my_bind[i].is_null= &is_null[i]; |
17539 | is_null[i]= 0; |
17540 | } |
17541 | |
17542 | rc= mysql_stmt_bind_param(stmt, my_bind); |
17543 | check_execute(stmt, rc); |
17544 | |
17545 | int_data= 320; |
17546 | small_data= 1867; |
17547 | big_data= 1000; |
17548 | real_data= 2; |
17549 | double_data= 6578.001; |
17550 | |
17551 | /* now, execute the prepared statement to insert 10 records.. */ |
17552 | for (tiny_data= 0; tiny_data < 10; tiny_data++) |
17553 | { |
17554 | length[1]= sprintf(str_data, "MySQL%d" , int_data); |
17555 | rc= mysql_stmt_execute(stmt); |
17556 | check_execute(stmt, rc); |
17557 | int_data += 25; |
17558 | small_data += 10; |
17559 | big_data += 100; |
17560 | real_data += 1; |
17561 | double_data += 10.09; |
17562 | } |
17563 | |
17564 | /* force a re-prepare with some DDL */ |
17565 | |
17566 | rc= mysql_query(mysql, |
17567 | "ALTER TABLE table_4166 change colX colX varchar(20) default NULL" ); |
17568 | myquery(rc); |
17569 | |
17570 | /* |
17571 | execute the prepared statement again, |
17572 | without changing the types of parameters already bound. |
17573 | */ |
17574 | |
17575 | for (tiny_data= 50; tiny_data < 60; tiny_data++) |
17576 | { |
17577 | length[1]= sprintf(str_data, "MySQL%d" , int_data); |
17578 | rc= mysql_stmt_execute(stmt); |
17579 | check_execute(stmt, rc); |
17580 | int_data += 25; |
17581 | small_data += 10; |
17582 | big_data += 100; |
17583 | real_data += 1; |
17584 | double_data += 10.09; |
17585 | } |
17586 | |
17587 | mysql_stmt_close(stmt); |
17588 | |
17589 | rc= mysql_query(mysql, "DROP TABLE table_4166" ); |
17590 | myquery(rc); |
17591 | } |
17592 | |
17593 | |
17594 | static void test_wl4166_2() |
17595 | { |
17596 | MYSQL_STMT *stmt; |
17597 | int c_int; |
17598 | MYSQL_TIME d_date; |
17599 | MYSQL_BIND bind_out[2]; |
17600 | int rc; |
17601 | |
17602 | myheader("test_wl4166_2" ); |
17603 | |
17604 | rc= mysql_query(mysql, "SET SQL_MODE=''" ); |
17605 | myquery(rc); |
17606 | |
17607 | rc= mysql_query(mysql, "drop table if exists t1" ); |
17608 | myquery(rc); |
17609 | rc= mysql_query(mysql, "create table t1 (c_int int, d_date date)" ); |
17610 | myquery(rc); |
17611 | rc= mysql_query(mysql, |
17612 | "insert into t1 (c_int, d_date) values (42, '1948-05-15')" ); |
17613 | myquery(rc); |
17614 | |
17615 | stmt= mysql_simple_prepare(mysql, "select * from t1" ); |
17616 | check_stmt(stmt); |
17617 | |
17618 | bzero(bind_out, sizeof(bind_out)); |
17619 | bind_out[0].buffer_type= MYSQL_TYPE_LONG; |
17620 | bind_out[0].buffer= (void*) &c_int; |
17621 | |
17622 | bind_out[1].buffer_type= MYSQL_TYPE_DATE; |
17623 | bind_out[1].buffer= (void*) &d_date; |
17624 | |
17625 | rc= mysql_stmt_bind_result(stmt, bind_out); |
17626 | check_execute(stmt, rc); |
17627 | |
17628 | /* int -> varchar transition */ |
17629 | |
17630 | rc= mysql_query(mysql, |
17631 | "alter table t1 change column c_int c_int varchar(11)" ); |
17632 | myquery(rc); |
17633 | |
17634 | rc= mysql_stmt_execute(stmt); |
17635 | check_execute(stmt, rc); |
17636 | |
17637 | rc= mysql_stmt_fetch(stmt); |
17638 | check_execute(stmt, rc); |
17639 | |
17640 | DIE_UNLESS(c_int == 42); |
17641 | DIE_UNLESS(d_date.year == 1948); |
17642 | DIE_UNLESS(d_date.month == 5); |
17643 | DIE_UNLESS(d_date.day == 15); |
17644 | |
17645 | rc= mysql_stmt_fetch(stmt); |
17646 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
17647 | |
17648 | /* varchar to int retrieval with truncation */ |
17649 | |
17650 | rc= mysql_query(mysql, "update t1 set c_int='abcde'" ); |
17651 | myquery(rc); |
17652 | |
17653 | rc= mysql_stmt_execute(stmt); |
17654 | check_execute(stmt, rc); |
17655 | |
17656 | rc= mysql_stmt_fetch(stmt); |
17657 | check_execute_r(stmt, rc); |
17658 | |
17659 | DIE_UNLESS(c_int == 0); |
17660 | |
17661 | rc= mysql_stmt_fetch(stmt); |
17662 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
17663 | |
17664 | /* alter table and increase the number of columns */ |
17665 | rc= mysql_query(mysql, "alter table t1 add column d_int int" ); |
17666 | myquery(rc); |
17667 | |
17668 | rc= mysql_stmt_execute(stmt); |
17669 | check_execute_r(stmt, rc); |
17670 | |
17671 | rc= mysql_stmt_reset(stmt); |
17672 | check_execute(stmt, rc); |
17673 | |
17674 | /* decrease the number of columns */ |
17675 | rc= mysql_query(mysql, "alter table t1 drop d_date, drop d_int" ); |
17676 | myquery(rc); |
17677 | |
17678 | rc= mysql_stmt_execute(stmt); |
17679 | check_execute_r(stmt, rc); |
17680 | |
17681 | mysql_stmt_close(stmt); |
17682 | rc= mysql_query(mysql, "drop table t1" ); |
17683 | myquery(rc); |
17684 | } |
17685 | |
17686 | |
17687 | /** |
17688 | Test how warnings generated during assignment of parameters |
17689 | are (currently not) preserve in case of reprepare. |
17690 | */ |
17691 | |
17692 | static void test_wl4166_3() |
17693 | { |
17694 | int rc; |
17695 | MYSQL_STMT *stmt; |
17696 | MYSQL_BIND my_bind[1]; |
17697 | MYSQL_TIME tm[1]; |
17698 | |
17699 | myheader("test_wl4166_3" ); |
17700 | |
17701 | rc= mysql_query(mysql, "drop table if exists t1" ); |
17702 | myquery(rc); |
17703 | |
17704 | rc= mysql_query(mysql, "create table t1 (year datetime)" ); |
17705 | myquery(rc); |
17706 | |
17707 | stmt= mysql_simple_prepare(mysql, "insert into t1 (year) values (?)" ); |
17708 | check_stmt(stmt); |
17709 | verify_param_count(stmt, 1); |
17710 | |
17711 | bzero((char*) my_bind, sizeof(my_bind)); |
17712 | my_bind[0].buffer_type= MYSQL_TYPE_DATETIME; |
17713 | my_bind[0].buffer= &tm[0]; |
17714 | |
17715 | rc= mysql_stmt_bind_param(stmt, my_bind); |
17716 | check_execute(stmt, rc); |
17717 | |
17718 | tm[0].year= 10000; |
17719 | tm[0].month= 1; tm[0].day= 1; |
17720 | tm[0].hour= 1; tm[0].minute= 1; tm[0].second= 1; |
17721 | tm[0].second_part= 0; tm[0].neg= 0; |
17722 | |
17723 | /* Cause a statement reprepare */ |
17724 | rc= mysql_query(mysql, "alter table t1 add column c int" ); |
17725 | myquery(rc); |
17726 | |
17727 | rc= mysql_stmt_execute(stmt); |
17728 | check_execute(stmt, rc); |
17729 | /* |
17730 | The warning about data truncation when assigning a parameter is lost. |
17731 | This is a bug. |
17732 | */ |
17733 | my_process_warnings(mysql, 0); |
17734 | |
17735 | verify_col_data("t1" , "year" , "0000-00-00 00:00:00" ); |
17736 | |
17737 | mysql_stmt_close(stmt); |
17738 | |
17739 | rc= mysql_query(mysql, "drop table t1" ); |
17740 | myquery(rc); |
17741 | } |
17742 | |
17743 | |
17744 | /** |
17745 | Test that long data parameters, as well as parameters |
17746 | that were originally in a different character set, are |
17747 | preserved in case of reprepare. |
17748 | */ |
17749 | |
17750 | static void test_wl4166_4() |
17751 | { |
17752 | MYSQL_STMT *stmt; |
17753 | int rc; |
17754 | const char *stmt_text; |
17755 | MYSQL_BIND bind_array[2]; |
17756 | |
17757 | /* Represented as numbers to keep UTF8 tools from clobbering them. */ |
17758 | const char *koi8= "\xee\xd5\x2c\x20\xda\xc1\x20\xd2\xd9\xc2\xc1\xcc\xcb\xd5" ; |
17759 | const char *cp1251= "\xcd\xf3\x2c\x20\xe7\xe0\x20\xf0\xfb\xe1\xe0\xeb\xea\xf3" ; |
17760 | char buf1[16], buf2[16]; |
17761 | ulong buf1_len, buf2_len; |
17762 | |
17763 | myheader("test_wl4166_4" ); |
17764 | |
17765 | rc= mysql_query(mysql, "drop table if exists t1" ); |
17766 | myquery(rc); |
17767 | |
17768 | /* |
17769 | Create table with binary columns, set session character set to cp1251, |
17770 | client character set to koi8, and make sure that there is conversion |
17771 | on insert and no conversion on select |
17772 | */ |
17773 | rc= mysql_query(mysql, |
17774 | "create table t1 (c1 varbinary(255), c2 varbinary(255))" ); |
17775 | myquery(rc); |
17776 | rc= mysql_query(mysql, "set character_set_client=koi8r, " |
17777 | "character_set_connection=cp1251, " |
17778 | "character_set_results=koi8r" ); |
17779 | myquery(rc); |
17780 | |
17781 | bzero((char*) bind_array, sizeof(bind_array)); |
17782 | |
17783 | bind_array[0].buffer_type= MYSQL_TYPE_STRING; |
17784 | |
17785 | bind_array[1].buffer_type= MYSQL_TYPE_STRING; |
17786 | bind_array[1].buffer= (void *) koi8; |
17787 | bind_array[1].buffer_length= strlen(koi8); |
17788 | |
17789 | stmt= mysql_stmt_init(mysql); |
17790 | check_stmt(stmt); |
17791 | |
17792 | stmt_text= "insert into t1 (c1, c2) values (?, ?)" ; |
17793 | |
17794 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
17795 | check_execute(stmt, rc); |
17796 | |
17797 | mysql_stmt_bind_param(stmt, bind_array); |
17798 | |
17799 | mysql_stmt_send_long_data(stmt, 0, koi8, strlen(koi8)); |
17800 | |
17801 | /* Cause a reprepare at statement execute */ |
17802 | rc= mysql_query(mysql, "alter table t1 add column d int" ); |
17803 | myquery(rc); |
17804 | |
17805 | rc= mysql_stmt_execute(stmt); |
17806 | check_execute(stmt, rc); |
17807 | |
17808 | stmt_text= "select c1, c2 from t1" ; |
17809 | |
17810 | /* c1 and c2 are binary so no conversion will be done on select */ |
17811 | rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
17812 | check_execute(stmt, rc); |
17813 | |
17814 | rc= mysql_stmt_execute(stmt); |
17815 | check_execute(stmt, rc); |
17816 | |
17817 | bind_array[0].buffer= buf1; |
17818 | bind_array[0].buffer_length= sizeof(buf1); |
17819 | bind_array[0].length= &buf1_len; |
17820 | |
17821 | bind_array[1].buffer= buf2; |
17822 | bind_array[1].buffer_length= sizeof(buf2); |
17823 | bind_array[1].length= &buf2_len; |
17824 | |
17825 | mysql_stmt_bind_result(stmt, bind_array); |
17826 | |
17827 | rc= mysql_stmt_fetch(stmt); |
17828 | check_execute(stmt, rc); |
17829 | |
17830 | DIE_UNLESS(buf1_len == strlen(cp1251)); |
17831 | DIE_UNLESS(buf2_len == strlen(cp1251)); |
17832 | DIE_UNLESS(!memcmp(buf1, cp1251, buf1_len)); |
17833 | DIE_UNLESS(!memcmp(buf2, cp1251, buf1_len)); |
17834 | |
17835 | rc= mysql_stmt_fetch(stmt); |
17836 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
17837 | |
17838 | mysql_stmt_close(stmt); |
17839 | |
17840 | rc= mysql_query(mysql, "drop table t1" ); |
17841 | myquery(rc); |
17842 | rc= mysql_query(mysql, "set names default" ); |
17843 | myquery(rc); |
17844 | } |
17845 | |
17846 | /** |
17847 | Bug#36004 mysql_stmt_prepare resets the list of warnings |
17848 | */ |
17849 | |
17850 | static void test_bug36004() |
17851 | { |
17852 | int rc, warning_count= 0; |
17853 | MYSQL_STMT *stmt; |
17854 | |
17855 | DBUG_ENTER("test_bug36004" ); |
17856 | myheader("test_bug36004" ); |
17857 | |
17858 | rc= mysql_query(mysql, "drop table if exists inexistant" ); |
17859 | myquery(rc); |
17860 | |
17861 | DIE_UNLESS(mysql_warning_count(mysql) == 1); |
17862 | query_int_variable(mysql, "@@warning_count" , &warning_count); |
17863 | DIE_UNLESS(warning_count); |
17864 | |
17865 | stmt= mysql_simple_prepare(mysql, "select 1" ); |
17866 | check_stmt(stmt); |
17867 | |
17868 | DIE_UNLESS(mysql_warning_count(mysql) == 0); |
17869 | query_int_variable(mysql, "@@warning_count" , &warning_count); |
17870 | DIE_UNLESS(warning_count); |
17871 | |
17872 | rc= mysql_stmt_execute(stmt); |
17873 | check_execute(stmt, rc); |
17874 | |
17875 | DIE_UNLESS(mysql_warning_count(mysql) == 0); |
17876 | mysql_stmt_close(stmt); |
17877 | |
17878 | query_int_variable(mysql, "@@warning_count" , &warning_count); |
17879 | DIE_UNLESS(warning_count); |
17880 | |
17881 | stmt= mysql_simple_prepare(mysql, "drop table if exists inexistant" ); |
17882 | check_stmt(stmt); |
17883 | |
17884 | query_int_variable(mysql, "@@warning_count" , &warning_count); |
17885 | DIE_UNLESS(warning_count == 0); |
17886 | mysql_stmt_close(stmt); |
17887 | |
17888 | DBUG_VOID_RETURN; |
17889 | } |
17890 | |
17891 | /** |
17892 | Test that COM_REFRESH issues a implicit commit. |
17893 | */ |
17894 | |
17895 | static void test_wl4284_1() |
17896 | { |
17897 | int rc; |
17898 | MYSQL_ROW row; |
17899 | MYSQL_RES *result; |
17900 | |
17901 | DBUG_ENTER("test_wl4284_1" ); |
17902 | myheader("test_wl4284_1" ); |
17903 | |
17904 | /* set AUTOCOMMIT to OFF */ |
17905 | rc= mysql_autocommit(mysql, FALSE); |
17906 | myquery(rc); |
17907 | |
17908 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS trans" ); |
17909 | myquery(rc); |
17910 | |
17911 | rc= mysql_query(mysql, "CREATE TABLE trans (a INT) ENGINE= InnoDB" ); |
17912 | myquery(rc); |
17913 | |
17914 | rc= mysql_query(mysql, "INSERT INTO trans VALUES(1)" ); |
17915 | myquery(rc); |
17916 | |
17917 | rc= mysql_refresh(mysql, REFRESH_GRANT | REFRESH_TABLES); |
17918 | myquery(rc); |
17919 | |
17920 | rc= mysql_rollback(mysql); |
17921 | myquery(rc); |
17922 | |
17923 | rc= mysql_query(mysql, "SELECT * FROM trans" ); |
17924 | myquery(rc); |
17925 | |
17926 | result= mysql_use_result(mysql); |
17927 | mytest(result); |
17928 | |
17929 | row= mysql_fetch_row(result); |
17930 | mytest(row); |
17931 | |
17932 | mysql_free_result(result); |
17933 | |
17934 | /* set AUTOCOMMIT to ON */ |
17935 | rc= mysql_autocommit(mysql, TRUE); |
17936 | myquery(rc); |
17937 | |
17938 | rc= mysql_query(mysql, "DROP TABLE trans" ); |
17939 | myquery(rc); |
17940 | |
17941 | DBUG_VOID_RETURN; |
17942 | } |
17943 | |
17944 | |
17945 | static void test_bug38486(void) |
17946 | { |
17947 | MYSQL_STMT *stmt; |
17948 | const char *stmt_text; |
17949 | unsigned long type= CURSOR_TYPE_READ_ONLY; |
17950 | |
17951 | DBUG_ENTER("test_bug38486" ); |
17952 | myheader("test_bug38486" ); |
17953 | |
17954 | stmt= mysql_stmt_init(mysql); |
17955 | mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*)&type); |
17956 | stmt_text= "CREATE TABLE t1 (a INT)" ; |
17957 | mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
17958 | mysql_stmt_execute(stmt); |
17959 | mysql_stmt_close(stmt); |
17960 | |
17961 | stmt= mysql_stmt_init(mysql); |
17962 | mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*)&type); |
17963 | stmt_text= "INSERT INTO t1 VALUES (1)" ; |
17964 | mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); |
17965 | mysql_stmt_execute(stmt); |
17966 | mysql_stmt_close(stmt); |
17967 | |
17968 | DBUG_VOID_RETURN; |
17969 | } |
17970 | |
17971 | |
17972 | /** |
17973 | Bug# 33831 mysql_real_connect() should fail if |
17974 | given an already connected MYSQL handle. |
17975 | */ |
17976 | |
17977 | static void test_bug33831(void) |
17978 | { |
17979 | MYSQL *l_mysql; |
17980 | |
17981 | DBUG_ENTER("test_bug33831" ); |
17982 | |
17983 | if (!(l_mysql= mysql_client_init(NULL))) |
17984 | { |
17985 | myerror("mysql_client_init() failed" ); |
17986 | DIE_UNLESS(0); |
17987 | } |
17988 | if (!(mysql_real_connect(l_mysql, opt_host, opt_user, |
17989 | opt_password, current_db, opt_port, |
17990 | opt_unix_socket, 0))) |
17991 | { |
17992 | myerror("connection failed" ); |
17993 | DIE_UNLESS(0); |
17994 | } |
17995 | |
17996 | if (mysql_real_connect(l_mysql, opt_host, opt_user, |
17997 | opt_password, current_db, opt_port, |
17998 | opt_unix_socket, 0)) |
17999 | { |
18000 | myerror("connection should have failed" ); |
18001 | DIE_UNLESS(0); |
18002 | } |
18003 | |
18004 | mysql_close(l_mysql); |
18005 | |
18006 | DBUG_VOID_RETURN; |
18007 | } |
18008 | |
18009 | |
18010 | static void test_bug40365(void) |
18011 | { |
18012 | uint rc, i; |
18013 | MYSQL_STMT *stmt= 0; |
18014 | MYSQL_BIND my_bind[2]; |
18015 | my_bool is_null[2]= {0}; |
18016 | MYSQL_TIME tm[2]; |
18017 | |
18018 | DBUG_ENTER("test_bug40365" ); |
18019 | |
18020 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1" ); |
18021 | myquery(rc); |
18022 | rc= mysql_query(mysql, "CREATE TABLE t1(c1 DATETIME, \ |
18023 | c2 DATE)" ); |
18024 | myquery(rc); |
18025 | |
18026 | stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 VALUES(?, ?)" ); |
18027 | check_stmt(stmt); |
18028 | verify_param_count(stmt, 2); |
18029 | |
18030 | bzero((char*) my_bind, sizeof(my_bind)); |
18031 | my_bind[0].buffer_type= MYSQL_TYPE_DATETIME; |
18032 | my_bind[1].buffer_type= MYSQL_TYPE_DATE; |
18033 | for (i= 0; i < (int) array_elements(my_bind); i++) |
18034 | { |
18035 | my_bind[i].buffer= (void *) &tm[i]; |
18036 | my_bind[i].is_null= &is_null[i]; |
18037 | } |
18038 | |
18039 | rc= mysql_stmt_bind_param(stmt, my_bind); |
18040 | check_execute(stmt, rc); |
18041 | |
18042 | for (i= 0; i < (int) array_elements(my_bind); i++) |
18043 | { |
18044 | tm[i].neg= 0; |
18045 | tm[i].second_part= 0; |
18046 | tm[i].year= 2009; |
18047 | tm[i].month= 2; |
18048 | tm[i].day= 29; |
18049 | tm[i].hour= 0; |
18050 | tm[i].minute= 0; |
18051 | tm[i].second= 0; |
18052 | } |
18053 | rc= mysql_stmt_execute(stmt); |
18054 | check_execute(stmt, rc); |
18055 | |
18056 | rc= mysql_commit(mysql); |
18057 | myquery(rc); |
18058 | mysql_stmt_close(stmt); |
18059 | |
18060 | stmt= mysql_simple_prepare(mysql, "SELECT * FROM t1" ); |
18061 | check_stmt(stmt); |
18062 | |
18063 | rc= mysql_stmt_bind_result(stmt, my_bind); |
18064 | check_execute(stmt, rc); |
18065 | |
18066 | rc= mysql_stmt_execute(stmt); |
18067 | check_execute(stmt, rc); |
18068 | |
18069 | rc= mysql_stmt_store_result(stmt); |
18070 | check_execute(stmt, rc); |
18071 | |
18072 | rc= mysql_stmt_fetch(stmt); |
18073 | check_execute(stmt, rc); |
18074 | |
18075 | if (!opt_silent) |
18076 | fprintf(stdout, "\n" ); |
18077 | |
18078 | for (i= 0; i < array_elements(my_bind); i++) |
18079 | { |
18080 | if (!opt_silent) |
18081 | fprintf(stdout, "\ntime[%d]: %02d-%02d-%02d " , |
18082 | i, tm[i].year, tm[i].month, tm[i].day); |
18083 | DIE_UNLESS(tm[i].year == 0); |
18084 | DIE_UNLESS(tm[i].month == 0); |
18085 | DIE_UNLESS(tm[i].day == 0); |
18086 | } |
18087 | mysql_stmt_close(stmt); |
18088 | rc= mysql_commit(mysql); |
18089 | myquery(rc); |
18090 | |
18091 | DBUG_VOID_RETURN; |
18092 | } |
18093 | |
18094 | |
18095 | /** |
18096 | Subtest for Bug#43560. Verifies that a loss of connection on the server side |
18097 | is handled well by the mysql_stmt_execute() call, i.e., no SIGSEGV due to |
18098 | a vio socket that is cleared upon closed connection. |
18099 | |
18100 | Assumes the presence of the close_conn_after_stmt_execute debug feature in |
18101 | the server. Verifies that it is connected to a debug server before proceeding |
18102 | with the test. |
18103 | */ |
18104 | static void test_bug43560(void) |
18105 | { |
18106 | MYSQL* conn; |
18107 | uint rc; |
18108 | MYSQL_STMT *stmt= 0; |
18109 | MYSQL_BIND bind; |
18110 | my_bool is_null= 0; |
18111 | char buffer[256]; |
18112 | const uint BUFSIZE= sizeof(buffer); |
18113 | const char* values[] = {"eins" , "zwei" , "drei" , "viele" , NULL}; |
18114 | const char insert_str[] = "INSERT INTO t1 (c2) VALUES (?)" ; |
18115 | unsigned long length; |
18116 | const unsigned int drop_db= opt_drop_db; |
18117 | |
18118 | DBUG_ENTER("test_bug43560" ); |
18119 | myheader("test_bug43560" ); |
18120 | |
18121 | /* Make sure we only run against a debug server. */ |
18122 | if (!strstr(mysql->server_version, "debug" )) |
18123 | { |
18124 | fprintf(stdout, "Skipping test_bug43560: server not DEBUG version\n" ); |
18125 | DBUG_VOID_RETURN; |
18126 | } |
18127 | if (opt_unix_socket) |
18128 | { |
18129 | fprintf(stdout, "Skipping test_bug43560: connected via UNIX socket\n" ); |
18130 | DBUG_VOID_RETURN; |
18131 | } |
18132 | /* |
18133 | Set up a separate connection for this test to avoid messing up the |
18134 | general MYSQL object used in other subtests. Use TCP protocol to avoid |
18135 | problems with the buffer semantics of AF_UNIX, and turn off auto reconnect. |
18136 | */ |
18137 | conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0); |
18138 | |
18139 | rc= mysql_query(conn, "DROP TABLE IF EXISTS t1" ); |
18140 | myquery(rc); |
18141 | rc= mysql_query(conn, |
18142 | "CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 CHAR(10))" ); |
18143 | myquery(rc); |
18144 | |
18145 | stmt= mysql_stmt_init(conn); |
18146 | check_stmt(stmt); |
18147 | rc= mysql_stmt_prepare(stmt, insert_str, strlen(insert_str)); |
18148 | check_execute(stmt, rc); |
18149 | |
18150 | bind.buffer_type= MYSQL_TYPE_STRING; |
18151 | bind.buffer_length= BUFSIZE; |
18152 | bind.buffer= buffer; |
18153 | bind.is_null= &is_null; |
18154 | bind.length= &length; |
18155 | rc= mysql_stmt_bind_param(stmt, &bind); |
18156 | check_execute(stmt, rc); |
18157 | |
18158 | /* First execute; should succeed. */ |
18159 | strncpy(buffer, values[0], BUFSIZE); |
18160 | length= strlen(buffer); |
18161 | rc= mysql_stmt_execute(stmt); |
18162 | check_execute(stmt, rc); |
18163 | |
18164 | /* |
18165 | Set up the server to close this session's server-side socket after |
18166 | next execution of prep statement. |
18167 | */ |
18168 | rc= mysql_query(conn,"SET SESSION debug='+d,close_conn_after_stmt_execute'" ); |
18169 | myquery(rc); |
18170 | |
18171 | /* Second execute; should fail due to socket closed during execution. */ |
18172 | strncpy(buffer, values[1], BUFSIZE); |
18173 | length= strlen(buffer); |
18174 | rc= mysql_stmt_execute(stmt); |
18175 | DIE_UNLESS(rc && mysql_stmt_errno(stmt) == CR_SERVER_LOST); |
18176 | |
18177 | /* |
18178 | Third execute; should fail (connection already closed), or SIGSEGV in |
18179 | case of a Bug#43560 type regression in which case the whole test fails. |
18180 | */ |
18181 | strncpy(buffer, values[2], BUFSIZE); |
18182 | length= strlen(buffer); |
18183 | rc= mysql_stmt_execute(stmt); |
18184 | DIE_UNLESS(rc && (mysql_stmt_errno(stmt) == CR_SERVER_LOST || |
18185 | mysql_stmt_errno(stmt) == CR_SERVER_GONE_ERROR)); |
18186 | |
18187 | opt_drop_db= 0; |
18188 | client_disconnect(conn); |
18189 | rc= mysql_query(mysql, "DROP TABLE t1" ); |
18190 | myquery(rc); |
18191 | opt_drop_db= drop_db; |
18192 | |
18193 | DBUG_VOID_RETURN; |
18194 | } |
18195 | |
18196 | |
18197 | /** |
18198 | Bug#36326: nested transaction and select |
18199 | */ |
18200 | |
18201 | static void test_bug36326() |
18202 | { |
18203 | int rc; |
18204 | |
18205 | DBUG_ENTER("test_bug36326" ); |
18206 | myheader("test_bug36326" ); |
18207 | |
18208 | if (! is_query_cache_available()) |
18209 | { |
18210 | fprintf(stdout, "Skipping test_bug36326: Query cache not available.\n" ); |
18211 | DBUG_VOID_RETURN; |
18212 | } |
18213 | |
18214 | rc= mysql_autocommit(mysql, TRUE); |
18215 | myquery(rc); |
18216 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1" ); |
18217 | myquery(rc); |
18218 | rc= mysql_query(mysql, "CREATE TABLE t1 (a INTEGER)" ); |
18219 | myquery(rc); |
18220 | rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)" ); |
18221 | myquery(rc); |
18222 | rc= mysql_query(mysql, "SET GLOBAL query_cache_type = 1" ); |
18223 | myquery(rc); |
18224 | rc= mysql_query(mysql, "SET LOCAL query_cache_type = 1" ); |
18225 | myquery(rc); |
18226 | rc= mysql_query(mysql, "SET GLOBAL query_cache_size = 1048576" ); |
18227 | myquery(rc); |
18228 | DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS)); |
18229 | DIE_UNLESS(mysql->server_status & SERVER_STATUS_AUTOCOMMIT); |
18230 | rc= mysql_query(mysql, "BEGIN" ); |
18231 | myquery(rc); |
18232 | DIE_UNLESS(mysql->server_status & SERVER_STATUS_IN_TRANS); |
18233 | rc= mysql_query(mysql, "SELECT * FROM t1" ); |
18234 | myquery(rc); |
18235 | rc= my_process_result(mysql); |
18236 | DIE_UNLESS(rc == 1); |
18237 | rc= mysql_rollback(mysql); |
18238 | myquery(rc); |
18239 | rc= mysql_query(mysql, "ROLLBACK" ); |
18240 | myquery(rc); |
18241 | DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS)); |
18242 | rc= mysql_query(mysql, "SELECT * FROM t1" ); |
18243 | myquery(rc); |
18244 | DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS)); |
18245 | rc= my_process_result(mysql); |
18246 | DIE_UNLESS(rc == 1); |
18247 | rc= mysql_query(mysql, "DROP TABLE t1" ); |
18248 | myquery(rc); |
18249 | rc= mysql_query(mysql, "SET GLOBAL query_cache_size = default" ); |
18250 | rc= mysql_query(mysql, "SET GLOBAL query_cache_type = default" ); |
18251 | myquery(rc); |
18252 | |
18253 | DBUG_VOID_RETURN; |
18254 | } |
18255 | |
18256 | /** |
18257 | Bug#41078: With CURSOR_TYPE_READ_ONLY mysql_stmt_fetch() returns short |
18258 | string value. |
18259 | */ |
18260 | |
18261 | static void test_bug41078(void) |
18262 | { |
18263 | uint rc; |
18264 | MYSQL_STMT *stmt= 0; |
18265 | MYSQL_BIND param, result; |
18266 | ulong cursor_type= CURSOR_TYPE_READ_ONLY; |
18267 | ulong len; |
18268 | char str[64]; |
18269 | const char param_str[]= "abcdefghijklmn" ; |
18270 | my_bool is_null, error; |
18271 | |
18272 | DBUG_ENTER("test_bug41078" ); |
18273 | |
18274 | rc= mysql_query(mysql, "SET NAMES UTF8" ); |
18275 | myquery(rc); |
18276 | |
18277 | stmt= mysql_simple_prepare(mysql, "SELECT ?" ); |
18278 | check_stmt(stmt); |
18279 | verify_param_count(stmt, 1); |
18280 | |
18281 | rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, &cursor_type); |
18282 | check_execute(stmt, rc); |
18283 | |
18284 | bzero(¶m, sizeof(param)); |
18285 | param.buffer_type= MYSQL_TYPE_STRING; |
18286 | param.buffer= (void *) param_str; |
18287 | len= sizeof(param_str) - 1; |
18288 | param.length= &len; |
18289 | |
18290 | rc= mysql_stmt_bind_param(stmt, ¶m); |
18291 | check_execute(stmt, rc); |
18292 | |
18293 | rc= mysql_stmt_execute(stmt); |
18294 | check_execute(stmt, rc); |
18295 | |
18296 | bzero(&result, sizeof(result)); |
18297 | result.buffer_type= MYSQL_TYPE_STRING; |
18298 | result.buffer= str; |
18299 | result.buffer_length= sizeof(str); |
18300 | result.is_null= &is_null; |
18301 | result.length= &len; |
18302 | result.error= &error; |
18303 | |
18304 | rc= mysql_stmt_bind_result(stmt, &result); |
18305 | check_execute(stmt, rc); |
18306 | |
18307 | rc= mysql_stmt_store_result(stmt); |
18308 | check_execute(stmt, rc); |
18309 | |
18310 | rc= mysql_stmt_fetch(stmt); |
18311 | check_execute(stmt, rc); |
18312 | |
18313 | DIE_UNLESS(len == sizeof(param_str) - 1 && !strcmp(str, param_str)); |
18314 | |
18315 | mysql_stmt_close(stmt); |
18316 | |
18317 | DBUG_VOID_RETURN; |
18318 | } |
18319 | |
18320 | /** |
18321 | Bug#45010: invalid memory reads during parsing some strange statements |
18322 | */ |
18323 | static void test_bug45010() |
18324 | { |
18325 | int rc; |
18326 | const char query1[]= "select a.\x80" , |
18327 | query2[]= "describe `table\xef" ; |
18328 | |
18329 | DBUG_ENTER("test_bug45010" ); |
18330 | myheader("test_bug45010" ); |
18331 | |
18332 | rc= mysql_query(mysql, "set names utf8" ); |
18333 | myquery(rc); |
18334 | |
18335 | /* \x80 (-128) could be used as a index of ident_map. */ |
18336 | rc= mysql_real_query(mysql, query1, sizeof(query1) - 1); |
18337 | DIE_UNLESS(rc); |
18338 | |
18339 | /* \xef (-17) could be used to skip 3 bytes past the buffer end. */ |
18340 | rc= mysql_real_query(mysql, query2, sizeof(query2) - 1); |
18341 | DIE_UNLESS(rc); |
18342 | |
18343 | rc= mysql_query(mysql, "set names default" ); |
18344 | myquery(rc); |
18345 | |
18346 | DBUG_VOID_RETURN; |
18347 | } |
18348 | |
18349 | /** |
18350 | Bug#44495: Prepared Statement: |
18351 | CALL p(<x>) - `thd->protocol == &thd->protocol_text' failed |
18352 | */ |
18353 | |
18354 | static void test_bug44495() |
18355 | { |
18356 | int rc; |
18357 | MYSQL con; |
18358 | MYSQL_STMT *stmt; |
18359 | |
18360 | DBUG_ENTER("test_bug44495" ); |
18361 | myheader("test_44495" ); |
18362 | |
18363 | rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1" ); |
18364 | myquery(rc); |
18365 | |
18366 | rc= mysql_query(mysql, "CREATE PROCEDURE p1(IN arg VARCHAR(25))" |
18367 | " BEGIN SET @stmt = CONCAT('SELECT \"', arg, '\"');" |
18368 | " PREPARE ps1 FROM @stmt;" |
18369 | " EXECUTE ps1;" |
18370 | " DROP PREPARE ps1;" |
18371 | "END;" ); |
18372 | myquery(rc); |
18373 | |
18374 | DIE_UNLESS(mysql_client_init(&con)); |
18375 | |
18376 | DIE_UNLESS(mysql_real_connect(&con, opt_host, opt_user, opt_password, |
18377 | current_db, opt_port, opt_unix_socket, |
18378 | CLIENT_MULTI_RESULTS)); |
18379 | |
18380 | stmt= mysql_simple_prepare(&con, "CALL p1('abc')" ); |
18381 | check_stmt(stmt); |
18382 | |
18383 | rc= mysql_stmt_execute(stmt); |
18384 | check_execute(stmt, rc); |
18385 | |
18386 | rc= my_process_stmt_result(stmt); |
18387 | DIE_UNLESS(rc == 1); |
18388 | |
18389 | mysql_stmt_close(stmt); |
18390 | |
18391 | mysql_close(&con); |
18392 | |
18393 | rc= mysql_query(mysql, "DROP PROCEDURE p1" ); |
18394 | myquery(rc); |
18395 | |
18396 | DBUG_VOID_RETURN; |
18397 | } |
18398 | |
18399 | static void test_bug53371() |
18400 | { |
18401 | int rc; |
18402 | MYSQL_RES *result; |
18403 | |
18404 | myheader("test_bug53371" ); |
18405 | |
18406 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1" ); |
18407 | myquery(rc); |
18408 | rc= mysql_query(mysql, "DROP DATABASE IF EXISTS bug53371" ); |
18409 | myquery(rc); |
18410 | rc= mysql_query(mysql, "DROP USER 'testbug'@localhost" ); |
18411 | |
18412 | rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)" ); |
18413 | myquery(rc); |
18414 | rc= mysql_query(mysql, "CREATE DATABASE bug53371" ); |
18415 | myquery(rc); |
18416 | rc= mysql_query(mysql, "GRANT SELECT ON bug53371.* to 'testbug'@localhost" ); |
18417 | myquery(rc); |
18418 | |
18419 | rc= mysql_change_user(mysql, "testbug" , NULL, "bug53371" ); |
18420 | myquery(rc); |
18421 | |
18422 | rc= mysql_query(mysql, "SHOW COLUMNS FROM client_test_db.t1" ); |
18423 | DIE_UNLESS(rc); |
18424 | DIE_UNLESS(mysql_errno(mysql) == 1142); |
18425 | |
18426 | result= mysql_list_fields(mysql, "../client_test_db/t1" , NULL); |
18427 | DIE_IF(result); |
18428 | |
18429 | result= mysql_list_fields(mysql, "#mysql50#/../client_test_db/t1" , NULL); |
18430 | DIE_IF(result); |
18431 | |
18432 | rc= mysql_change_user(mysql, opt_user, opt_password, current_db); |
18433 | myquery(rc); |
18434 | rc= mysql_query(mysql, "DROP TABLE t1" ); |
18435 | myquery(rc); |
18436 | rc= mysql_query(mysql, "DROP DATABASE bug53371" ); |
18437 | myquery(rc); |
18438 | rc= mysql_query(mysql, "DROP USER 'testbug'@localhost" ); |
18439 | myquery(rc); |
18440 | } |
18441 | |
18442 | |
18443 | |
18444 | /** |
18445 | Bug#42373: libmysql can mess a connection at connect |
18446 | */ |
18447 | static void test_bug42373() |
18448 | { |
18449 | int rc; |
18450 | MYSQL con; |
18451 | MYSQL_STMT *stmt; |
18452 | |
18453 | DBUG_ENTER("test_bug42373" ); |
18454 | myheader("test_42373" ); |
18455 | |
18456 | rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1" ); |
18457 | myquery(rc); |
18458 | |
18459 | rc= mysql_query(mysql, "CREATE PROCEDURE p1()" |
18460 | " BEGIN" |
18461 | " SELECT 1;" |
18462 | " INSERT INTO t1 VALUES (2);" |
18463 | "END;" ); |
18464 | myquery(rc); |
18465 | |
18466 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1" ); |
18467 | myquery(rc); |
18468 | |
18469 | rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)" ); |
18470 | myquery(rc); |
18471 | |
18472 | /* Try with a stored procedure. */ |
18473 | DIE_UNLESS(mysql_client_init(&con)); |
18474 | |
18475 | mysql_options(&con, MYSQL_INIT_COMMAND, "CALL p1()" ); |
18476 | |
18477 | DIE_UNLESS(mysql_real_connect(&con, opt_host, opt_user, opt_password, |
18478 | current_db, opt_port, opt_unix_socket, |
18479 | CLIENT_MULTI_STATEMENTS|CLIENT_MULTI_RESULTS)); |
18480 | |
18481 | stmt= mysql_simple_prepare(&con, "SELECT a FROM t1" ); |
18482 | check_stmt(stmt); |
18483 | |
18484 | rc= mysql_stmt_execute(stmt); |
18485 | check_execute(stmt, rc); |
18486 | |
18487 | rc= my_process_stmt_result(stmt); |
18488 | DIE_UNLESS(rc == 1); |
18489 | |
18490 | mysql_stmt_close(stmt); |
18491 | |
18492 | /* Now try with a multi-statement. */ |
18493 | DIE_UNLESS(mysql_client_init(&con)); |
18494 | |
18495 | mysql_options(&con, MYSQL_INIT_COMMAND, |
18496 | "SELECT 3; INSERT INTO t1 VALUES (4)" ); |
18497 | |
18498 | DIE_UNLESS(mysql_real_connect(&con, opt_host, opt_user, opt_password, |
18499 | current_db, opt_port, opt_unix_socket, |
18500 | CLIENT_MULTI_STATEMENTS|CLIENT_MULTI_RESULTS)); |
18501 | |
18502 | stmt= mysql_simple_prepare(&con, "SELECT a FROM t1" ); |
18503 | check_stmt(stmt); |
18504 | |
18505 | rc= mysql_stmt_execute(stmt); |
18506 | check_execute(stmt, rc); |
18507 | |
18508 | rc= my_process_stmt_result(stmt); |
18509 | DIE_UNLESS(rc == 2); |
18510 | |
18511 | mysql_stmt_close(stmt); |
18512 | mysql_close(&con); |
18513 | |
18514 | rc= mysql_query(mysql, "DROP TABLE t1" ); |
18515 | myquery(rc); |
18516 | |
18517 | rc= mysql_query(mysql, "DROP PROCEDURE p1" ); |
18518 | myquery(rc); |
18519 | |
18520 | DBUG_VOID_RETURN; |
18521 | } |
18522 | |
18523 | |
18524 | /** |
18525 | Bug#54041: MySQL 5.0.92 fails when tests from Connector/C suite run |
18526 | */ |
18527 | |
18528 | static void test_bug54041_impl() |
18529 | { |
18530 | int rc; |
18531 | MYSQL_STMT *stmt; |
18532 | MYSQL_BIND bind; |
18533 | |
18534 | DBUG_ENTER("test_bug54041" ); |
18535 | myheader("test_bug54041" ); |
18536 | |
18537 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1" ); |
18538 | myquery(rc); |
18539 | |
18540 | rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)" ); |
18541 | myquery(rc); |
18542 | |
18543 | stmt= mysql_simple_prepare(mysql, "SELECT a FROM t1 WHERE a > ?" ); |
18544 | check_stmt(stmt); |
18545 | verify_param_count(stmt, 1); |
18546 | |
18547 | memset(&bind, 0, sizeof(bind)); |
18548 | |
18549 | /* Any type that does not support long data handling. */ |
18550 | bind.buffer_type= MYSQL_TYPE_LONG; |
18551 | |
18552 | rc= mysql_stmt_bind_param(stmt, &bind); |
18553 | check_execute(stmt, rc); |
18554 | |
18555 | /* |
18556 | Trick the client API into sending a long data packet for |
18557 | the parameter. Long data is only supported for string and |
18558 | binary types. |
18559 | */ |
18560 | stmt->params[0].buffer_type= MYSQL_TYPE_STRING; |
18561 | |
18562 | rc= mysql_stmt_send_long_data(stmt, 0, "data" , 5); |
18563 | check_execute(stmt, rc); |
18564 | |
18565 | /* Undo API violation. */ |
18566 | stmt->params[0].buffer_type= MYSQL_TYPE_LONG; |
18567 | |
18568 | rc= mysql_stmt_execute(stmt); |
18569 | /* Incorrect arguments. */ |
18570 | check_execute_r(stmt, rc); |
18571 | |
18572 | mysql_stmt_close(stmt); |
18573 | |
18574 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1" ); |
18575 | myquery(rc); |
18576 | |
18577 | DBUG_VOID_RETURN; |
18578 | } |
18579 | |
18580 | |
18581 | /** |
18582 | Bug#54041: MySQL 5.0.92 fails when tests from Connector/C suite run |
18583 | */ |
18584 | |
18585 | static void test_bug54041() |
18586 | { |
18587 | enable_query_logs(0); |
18588 | test_bug54041_impl(); |
18589 | disable_query_logs(); |
18590 | test_bug54041_impl(); |
18591 | restore_query_logs(); |
18592 | } |
18593 | |
18594 | |
18595 | /** |
18596 | Bug#47485: mysql_store_result returns a result set for a prepared statement |
18597 | */ |
18598 | static void test_bug47485() |
18599 | { |
18600 | MYSQL_STMT *stmt; |
18601 | MYSQL_RES *res; |
18602 | MYSQL_BIND bind[2]; |
18603 | int rc; |
18604 | const char* sql_select = "SELECT 1, 'a'" ; |
18605 | int int_data; |
18606 | char str_data[16]; |
18607 | my_bool is_null[2]; |
18608 | my_bool error[2]; |
18609 | unsigned long length[2]; |
18610 | |
18611 | DBUG_ENTER("test_bug47485" ); |
18612 | myheader("test_bug47485" ); |
18613 | |
18614 | stmt= mysql_stmt_init(mysql); |
18615 | check_stmt(stmt); |
18616 | rc= mysql_stmt_prepare(stmt, sql_select, strlen(sql_select)); |
18617 | check_execute(stmt, rc); |
18618 | |
18619 | rc= mysql_stmt_execute(stmt); |
18620 | check_execute(stmt, rc); |
18621 | |
18622 | res = mysql_store_result(mysql); |
18623 | DIE_UNLESS(res == NULL); |
18624 | |
18625 | mysql_stmt_reset(stmt); |
18626 | |
18627 | rc= mysql_stmt_execute(stmt); |
18628 | check_execute(stmt, rc); |
18629 | |
18630 | res = mysql_use_result(mysql); |
18631 | DIE_UNLESS(res == NULL); |
18632 | |
18633 | mysql_stmt_reset(stmt); |
18634 | |
18635 | memset(bind, 0, sizeof(bind)); |
18636 | bind[0].buffer_type= MYSQL_TYPE_LONG; |
18637 | bind[0].buffer= (char *)&int_data; |
18638 | bind[0].is_null= &is_null[0]; |
18639 | bind[0].length= &length[0]; |
18640 | bind[0].error= &error[0]; |
18641 | |
18642 | bind[1].buffer_type= MYSQL_TYPE_STRING; |
18643 | bind[1].buffer= (char *)str_data; |
18644 | bind[1].buffer_length= sizeof(str_data); |
18645 | bind[1].is_null= &is_null[1]; |
18646 | bind[1].length= &length[1]; |
18647 | bind[1].error= &error[1]; |
18648 | |
18649 | rc= mysql_stmt_bind_result(stmt, bind); |
18650 | check_execute(stmt, rc); |
18651 | |
18652 | rc= mysql_stmt_execute(stmt); |
18653 | check_execute(stmt, rc); |
18654 | |
18655 | rc= mysql_stmt_store_result(stmt); |
18656 | check_execute(stmt, rc); |
18657 | |
18658 | while (!(rc= mysql_stmt_fetch(stmt))) |
18659 | ; |
18660 | |
18661 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
18662 | |
18663 | mysql_stmt_reset(stmt); |
18664 | |
18665 | memset(bind, 0, sizeof(bind)); |
18666 | bind[0].buffer_type= MYSQL_TYPE_LONG; |
18667 | bind[0].buffer= (char *)&int_data; |
18668 | bind[0].is_null= &is_null[0]; |
18669 | bind[0].length= &length[0]; |
18670 | bind[0].error= &error[0]; |
18671 | |
18672 | bind[1].buffer_type= MYSQL_TYPE_STRING; |
18673 | bind[1].buffer= (char *)str_data; |
18674 | bind[1].buffer_length= sizeof(str_data); |
18675 | bind[1].is_null= &is_null[1]; |
18676 | bind[1].length= &length[1]; |
18677 | bind[1].error= &error[1]; |
18678 | |
18679 | rc= mysql_stmt_bind_result(stmt, bind); |
18680 | check_execute(stmt, rc); |
18681 | |
18682 | rc= mysql_stmt_execute(stmt); |
18683 | check_execute(stmt, rc); |
18684 | |
18685 | while (!(rc= mysql_stmt_fetch(stmt))) |
18686 | ; |
18687 | |
18688 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
18689 | |
18690 | mysql_stmt_close(stmt); |
18691 | |
18692 | DBUG_VOID_RETURN; |
18693 | } |
18694 | |
18695 | |
18696 | /* |
18697 | Bug#58036 client utf32, utf16, ucs2 should be disallowed, they crash server |
18698 | */ |
18699 | static void test_bug58036() |
18700 | { |
18701 | MYSQL *conn; |
18702 | DBUG_ENTER("test_bug58036" ); |
18703 | myheader("test_bug58036" ); |
18704 | |
18705 | /* Part1: try to connect with ucs2 client character set */ |
18706 | conn= mysql_client_init(NULL); |
18707 | mysql_options(conn, MYSQL_SET_CHARSET_NAME, "ucs2" ); |
18708 | |
18709 | if (mysql_real_connect(conn, opt_host, opt_user, |
18710 | opt_password, opt_db ? opt_db : "test" , |
18711 | opt_port, opt_unix_socket, 0)) |
18712 | { |
18713 | if (!opt_silent) |
18714 | printf("mysql_real_connect() succeeded (failure expected)\n" ); |
18715 | mysql_close(conn); |
18716 | DIE("" ); |
18717 | } |
18718 | |
18719 | if (!opt_silent) |
18720 | printf("Got mysql_real_connect() error (expected): %s (%d)\n" , |
18721 | mysql_error(conn), mysql_errno(conn)); |
18722 | DIE_UNLESS(mysql_errno(conn) == ER_WRONG_VALUE_FOR_VAR || |
18723 | mysql_errno(conn)== CR_CANT_READ_CHARSET); |
18724 | mysql_close(conn); |
18725 | |
18726 | |
18727 | /* |
18728 | Part2: |
18729 | - connect with latin1 |
18730 | - then change client character set to ucs2 |
18731 | - then try mysql_change_user() |
18732 | */ |
18733 | conn= mysql_client_init(NULL); |
18734 | mysql_options(conn, MYSQL_SET_CHARSET_NAME, "latin1" ); |
18735 | if (!mysql_real_connect(conn, opt_host, opt_user, |
18736 | opt_password, opt_db ? opt_db : "test" , |
18737 | opt_port, opt_unix_socket, 0)) |
18738 | { |
18739 | if (!opt_silent) |
18740 | printf("mysql_real_connect() failed: %s (%d)\n" , |
18741 | mysql_error(conn), mysql_errno(conn)); |
18742 | mysql_close(conn); |
18743 | DIE("" ); |
18744 | } |
18745 | |
18746 | mysql_options(conn, MYSQL_SET_CHARSET_NAME, "ucs2" ); |
18747 | if (!mysql_change_user(conn, opt_user, opt_password, NULL)) |
18748 | { |
18749 | if (!opt_silent) |
18750 | printf("mysql_change_user() succedded, error expected!" ); |
18751 | mysql_close(conn); |
18752 | DIE("" ); |
18753 | } |
18754 | |
18755 | if (!opt_silent) |
18756 | printf("Got mysql_change_user() error (expected): %s (%d)\n" , |
18757 | mysql_error(conn), mysql_errno(conn)); |
18758 | mysql_close(conn); |
18759 | DBUG_VOID_RETURN; |
18760 | } |
18761 | |
18762 | |
18763 | /* |
18764 | Bug#49972: Crash in prepared statements. |
18765 | |
18766 | The following case lead to a server crash: |
18767 | - Use binary protocol; |
18768 | - Prepare a statement with OUT-parameter; |
18769 | - Execute the statement; |
18770 | - Cause re-prepare of the statement (change dependencies); |
18771 | - Execute the statement again -- crash here. |
18772 | */ |
18773 | |
18774 | static void test_bug49972() |
18775 | { |
18776 | int rc; |
18777 | MYSQL_STMT *stmt; |
18778 | |
18779 | MYSQL_BIND in_param_bind; |
18780 | MYSQL_BIND out_param_bind; |
18781 | int int_data; |
18782 | my_bool is_null; |
18783 | |
18784 | DBUG_ENTER("test_bug49972" ); |
18785 | myheader("test_bug49972" ); |
18786 | |
18787 | rc= mysql_query(mysql, "DROP FUNCTION IF EXISTS f1" ); |
18788 | myquery(rc); |
18789 | |
18790 | rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1" ); |
18791 | myquery(rc); |
18792 | |
18793 | rc= mysql_query(mysql, "CREATE FUNCTION f1() RETURNS INT RETURN 1" ); |
18794 | myquery(rc); |
18795 | |
18796 | rc= mysql_query(mysql, "CREATE PROCEDURE p1(IN a INT, OUT b INT) SET b = a" ); |
18797 | myquery(rc); |
18798 | |
18799 | stmt= mysql_simple_prepare(mysql, "CALL p1((SELECT f1()), ?)" ); |
18800 | check_stmt(stmt); |
18801 | |
18802 | bzero((char *) &in_param_bind, sizeof (in_param_bind)); |
18803 | |
18804 | in_param_bind.buffer_type= MYSQL_TYPE_LONG; |
18805 | in_param_bind.buffer= (char *) &int_data; |
18806 | in_param_bind.length= 0; |
18807 | in_param_bind.is_null= 0; |
18808 | |
18809 | rc= mysql_stmt_bind_param(stmt, &in_param_bind); |
18810 | |
18811 | rc= mysql_stmt_execute(stmt); |
18812 | check_execute(stmt, rc); |
18813 | |
18814 | { |
18815 | bzero(&out_param_bind, sizeof (out_param_bind)); |
18816 | |
18817 | out_param_bind.buffer_type= MYSQL_TYPE_LONG; |
18818 | out_param_bind.is_null= &is_null; |
18819 | out_param_bind.buffer= &int_data; |
18820 | out_param_bind.buffer_length= sizeof (int_data); |
18821 | |
18822 | rc= mysql_stmt_bind_result(stmt, &out_param_bind); |
18823 | check_execute(stmt, rc); |
18824 | |
18825 | rc= mysql_stmt_fetch(stmt); |
18826 | rc= mysql_stmt_fetch(stmt); |
18827 | DBUG_ASSERT(rc == MYSQL_NO_DATA); |
18828 | |
18829 | mysql_stmt_next_result(stmt); |
18830 | mysql_stmt_fetch(stmt); |
18831 | } |
18832 | |
18833 | rc= mysql_query(mysql, "DROP FUNCTION f1" ); |
18834 | myquery(rc); |
18835 | |
18836 | rc= mysql_query(mysql, "CREATE FUNCTION f1() RETURNS INT RETURN 1" ); |
18837 | myquery(rc); |
18838 | |
18839 | rc= mysql_stmt_execute(stmt); |
18840 | check_execute(stmt, rc); |
18841 | |
18842 | { |
18843 | bzero(&out_param_bind, sizeof (out_param_bind)); |
18844 | |
18845 | out_param_bind.buffer_type= MYSQL_TYPE_LONG; |
18846 | out_param_bind.is_null= &is_null; |
18847 | out_param_bind.buffer= &int_data; |
18848 | out_param_bind.buffer_length= sizeof (int_data); |
18849 | |
18850 | rc= mysql_stmt_bind_result(stmt, &out_param_bind); |
18851 | check_execute(stmt, rc); |
18852 | |
18853 | rc= mysql_stmt_fetch(stmt); |
18854 | rc= mysql_stmt_fetch(stmt); |
18855 | DBUG_ASSERT(rc == MYSQL_NO_DATA); |
18856 | |
18857 | mysql_stmt_next_result(stmt); |
18858 | mysql_stmt_fetch(stmt); |
18859 | } |
18860 | |
18861 | mysql_stmt_close(stmt); |
18862 | |
18863 | rc= mysql_query(mysql, "DROP PROCEDURE p1" ); |
18864 | myquery(rc); |
18865 | |
18866 | rc= mysql_query(mysql, "DROP FUNCTION f1" ); |
18867 | myquery(rc); |
18868 | |
18869 | DBUG_VOID_RETURN; |
18870 | } |
18871 | |
18872 | |
18873 | /* |
18874 | Bug #56976: Severe Denial Of Service in prepared statements |
18875 | */ |
18876 | static void test_bug56976() |
18877 | { |
18878 | MYSQL_STMT *stmt; |
18879 | MYSQL_BIND bind[1]; |
18880 | int rc; |
18881 | const char* query = "SELECT LENGTH(?)" ; |
18882 | char *long_buffer; |
18883 | unsigned long i, packet_len = 256 * 1024L; |
18884 | unsigned long dos_len = 35000000; |
18885 | |
18886 | DBUG_ENTER("test_bug56976" ); |
18887 | myheader("test_bug56976" ); |
18888 | |
18889 | stmt= mysql_stmt_init(mysql); |
18890 | check_stmt(stmt); |
18891 | |
18892 | rc= mysql_stmt_prepare(stmt, query, strlen(query)); |
18893 | check_execute(stmt, rc); |
18894 | |
18895 | memset(bind, 0, sizeof(bind)); |
18896 | bind[0].buffer_type = MYSQL_TYPE_TINY_BLOB; |
18897 | |
18898 | rc= mysql_stmt_bind_param(stmt, bind); |
18899 | check_execute(stmt, rc); |
18900 | |
18901 | long_buffer= (char*) my_malloc(packet_len, MYF(0)); |
18902 | DIE_UNLESS(long_buffer); |
18903 | |
18904 | memset(long_buffer, 'a', packet_len); |
18905 | |
18906 | for (i= 0; i < dos_len / packet_len; i++) |
18907 | { |
18908 | rc= mysql_stmt_send_long_data(stmt, 0, long_buffer, packet_len); |
18909 | check_execute(stmt, rc); |
18910 | } |
18911 | |
18912 | my_free(long_buffer); |
18913 | rc= mysql_stmt_execute(stmt); |
18914 | |
18915 | DIE_UNLESS(rc && mysql_stmt_errno(stmt) == ER_UNKNOWN_ERROR); |
18916 | |
18917 | mysql_stmt_close(stmt); |
18918 | |
18919 | DBUG_VOID_RETURN; |
18920 | } |
18921 | |
18922 | /* |
18923 | Test that CLIENT_PROGRESS works. |
18924 | */ |
18925 | |
18926 | uint progress_stage, progress_max_stage, progress_count; |
18927 | |
18928 | static void report_progress(const MYSQL *mysql __attribute__((unused)), |
18929 | uint stage, uint max_stage, |
18930 | double progress __attribute__((unused)), |
18931 | const char *proc_info __attribute__((unused)), |
18932 | uint proc_info_length __attribute__((unused))) |
18933 | { |
18934 | progress_stage= stage; |
18935 | progress_max_stage= max_stage; |
18936 | progress_count++; |
18937 | } |
18938 | |
18939 | |
18940 | static void test_progress_reporting() |
18941 | { |
18942 | int rc, i; |
18943 | MYSQL* conn; |
18944 | |
18945 | /* Progress reporting doesn't work yet with embedded server */ |
18946 | if (embedded_server_arg_count) |
18947 | return; |
18948 | |
18949 | myheader("test_progress_reporting" ); |
18950 | |
18951 | |
18952 | conn= client_connect(CLIENT_PROGRESS_OBSOLETE, MYSQL_PROTOCOL_TCP, 0); |
18953 | if (!(conn->server_capabilities & CLIENT_PROGRESS_OBSOLETE)) |
18954 | return; |
18955 | DIE_UNLESS(conn->client_flag & CLIENT_PROGRESS_OBSOLETE); |
18956 | |
18957 | mysql_options(conn, MYSQL_PROGRESS_CALLBACK, (void*) report_progress); |
18958 | rc= mysql_query(conn, "set @save=@@global.progress_report_time" ); |
18959 | myquery(rc); |
18960 | rc= mysql_query(conn, "set @@global.progress_report_time=1" ); |
18961 | myquery(rc); |
18962 | |
18963 | rc= mysql_query(conn, "drop table if exists t1,t2" ); |
18964 | myquery(rc); |
18965 | rc= mysql_query(conn, "create table t1 (f2 varchar(255)) engine=aria" ); |
18966 | myquery(rc); |
18967 | rc= mysql_query(conn, "create table t2 like t1" ); |
18968 | myquery(rc); |
18969 | rc= mysql_query(conn, "insert into t1 (f2) values (repeat('a',100)),(repeat('b',200)),(repeat('c',202)),(repeat('d',202)),(repeat('e',202)),(repeat('f',202)),(repeat('g',23))" ); |
18970 | myquery(rc); |
18971 | for (i= 0 ; i < 5 ; i++) |
18972 | { |
18973 | rc= mysql_query(conn, "insert into t2 (f2) select f2 from t1" ); |
18974 | myquery(rc); |
18975 | rc= mysql_query(conn, "insert into t1 (f2) select f2 from t2" ); |
18976 | myquery(rc); |
18977 | } |
18978 | |
18979 | progress_stage= progress_max_stage= progress_count= 0; |
18980 | rc= mysql_query(conn, "alter table t1 add f1 int primary key auto_increment, order by f2" ); |
18981 | myquery(rc); |
18982 | if (!opt_silent) |
18983 | printf("Got progress_count: %u stage: %u max_stage: %u\n" , |
18984 | progress_count, progress_stage, progress_max_stage); |
18985 | DIE_UNLESS(progress_count > 0 && progress_stage >=2 && progress_max_stage == 3); |
18986 | |
18987 | progress_stage= progress_max_stage= progress_count= 0; |
18988 | rc= mysql_query(conn, "create index f2 on t1 (f2)" ); |
18989 | myquery(rc); |
18990 | if (!opt_silent) |
18991 | printf("Got progress_count: %u stage: %u max_stage: %u\n" , |
18992 | progress_count, progress_stage, progress_max_stage); |
18993 | DIE_UNLESS(progress_count > 0 && progress_stage >=2 && progress_max_stage == 2); |
18994 | |
18995 | progress_stage= progress_max_stage= progress_count= 0; |
18996 | rc= mysql_query(conn, "drop index f2 on t1" ); |
18997 | myquery(rc); |
18998 | if (!opt_silent) |
18999 | printf("Got progress_count: %u stage: %u max_stage: %u\n" , |
19000 | progress_count, progress_stage, progress_max_stage); |
19001 | DIE_UNLESS(progress_count > 0 && progress_stage >=2 && progress_max_stage == 2); |
19002 | |
19003 | rc= mysql_query(conn, "set @@global.progress_report_time=@save" ); |
19004 | myquery(rc); |
19005 | mysql_close(conn); |
19006 | } |
19007 | |
19008 | /** |
19009 | MDEV-3885 - connection suicide via mysql_kill() causes assertion in server |
19010 | */ |
19011 | |
19012 | static void test_mdev3885() |
19013 | { |
19014 | int rc; |
19015 | MYSQL *conn; |
19016 | |
19017 | myheader("test_mdev3885" ); |
19018 | conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0); |
19019 | rc= mysql_kill(conn, mysql_thread_id(conn)); |
19020 | DIE_UNLESS(rc); |
19021 | mysql_close(conn); |
19022 | } |
19023 | |
19024 | |
19025 | /** |
19026 | Bug#57058 SERVER_QUERY_WAS_SLOW not wired up. |
19027 | */ |
19028 | |
19029 | static void test_bug57058() |
19030 | { |
19031 | MYSQL_RES *res; |
19032 | int rc; |
19033 | |
19034 | DBUG_ENTER("test_bug57058" ); |
19035 | myheader("test_bug57058" ); |
19036 | |
19037 | rc= mysql_query(mysql, "set @@session.long_query_time=0.1" ); |
19038 | myquery(rc); |
19039 | |
19040 | DIE_UNLESS(!(mysql->server_status & SERVER_QUERY_WAS_SLOW)); |
19041 | |
19042 | rc= mysql_query(mysql, "select sleep(1)" ); |
19043 | myquery(rc); |
19044 | |
19045 | /* |
19046 | Important: the flag is sent in the last EOF packet of |
19047 | the query, the one which ends the result. Read the |
19048 | result to see the "slow" status. |
19049 | */ |
19050 | res= mysql_store_result(mysql); |
19051 | |
19052 | DIE_UNLESS(mysql->server_status & SERVER_QUERY_WAS_SLOW); |
19053 | |
19054 | mysql_free_result(res); |
19055 | |
19056 | rc= mysql_query(mysql, "set @@session.long_query_time=default" ); |
19057 | myquery(rc); |
19058 | |
19059 | DBUG_VOID_RETURN; |
19060 | } |
19061 | |
19062 | |
19063 | /** |
19064 | Bug#11766854: 60075: MYSQL_LOAD_CLIENT_PLUGIN DOESN'T CLEAR ERROR |
19065 | */ |
19066 | |
19067 | static void test_bug11766854() |
19068 | { |
19069 | struct st_mysql_client_plugin *plugin; |
19070 | |
19071 | DBUG_ENTER("test_bug11766854" ); |
19072 | myheader("test_bug11766854" ); |
19073 | |
19074 | plugin= mysql_load_plugin(mysql, "foo" , -1, 0); |
19075 | DIE_UNLESS(plugin == 0); |
19076 | |
19077 | plugin= mysql_load_plugin(mysql, "qa_auth_client" , -1, 0); |
19078 | DIE_UNLESS(plugin != 0); |
19079 | DIE_IF(mysql_errno(mysql)); |
19080 | |
19081 | DBUG_VOID_RETURN; |
19082 | } |
19083 | |
19084 | /** |
19085 | Bug#12337762: 60075: MYSQL_LIST_FIELDS() RETURNS WRONG CHARSET FOR |
19086 | CHAR/VARCHAR/TEXT COLUMNS IN VIEWS |
19087 | */ |
19088 | static void test_bug12337762() |
19089 | { |
19090 | int rc,i=0; |
19091 | MYSQL_RES *result; |
19092 | MYSQL_FIELD *field; |
19093 | unsigned int tab_charsetnr[3]= {0}; |
19094 | |
19095 | DBUG_ENTER("test_bug12337762" ); |
19096 | myheader("test_bug12337762" ); |
19097 | |
19098 | /* |
19099 | Creating table with specific charset. |
19100 | */ |
19101 | rc= mysql_query(mysql, "drop table if exists charset_tab" ); |
19102 | rc= mysql_query(mysql, "create table charset_tab(" \ |
19103 | "txt1 varchar(32) character set Latin1," \ |
19104 | "txt2 varchar(32) character set Latin1 collate latin1_bin," \ |
19105 | "txt3 varchar(32) character set utf8 collate utf8_bin" \ |
19106 | ")" ); |
19107 | |
19108 | DIE_UNLESS(rc == 0); |
19109 | DIE_IF(mysql_errno(mysql)); |
19110 | |
19111 | /* |
19112 | Creating view from table created earlier. |
19113 | */ |
19114 | rc= mysql_query(mysql, "drop view if exists charset_view" ); |
19115 | rc= mysql_query(mysql, "create view charset_view as " \ |
19116 | "select * from charset_tab;" ); |
19117 | DIE_UNLESS(rc == 0); |
19118 | DIE_IF(mysql_errno(mysql)); |
19119 | |
19120 | /* |
19121 | Checking field information for table. |
19122 | */ |
19123 | result= mysql_list_fields(mysql, "charset_tab" , NULL); |
19124 | DIE_IF(mysql_errno(mysql)); |
19125 | i=0; |
19126 | while((field= mysql_fetch_field(result))) |
19127 | { |
19128 | printf("field name %s\n" , field->name); |
19129 | printf("field table %s\n" , field->table); |
19130 | printf("field type %d\n" , field->type); |
19131 | printf("field charset %d\n" , field->charsetnr); |
19132 | tab_charsetnr[i++]= field->charsetnr; |
19133 | printf("\n" ); |
19134 | } |
19135 | mysql_free_result(result); |
19136 | |
19137 | /* |
19138 | Checking field information for view. |
19139 | */ |
19140 | result= mysql_list_fields(mysql, "charset_view" , NULL); |
19141 | DIE_IF(mysql_errno(mysql)); |
19142 | i=0; |
19143 | while((field= mysql_fetch_field(result))) |
19144 | { |
19145 | printf("field name %s\n" , field->name); |
19146 | printf("field table %s\n" , field->table); |
19147 | printf("field type %d\n" , field->type); |
19148 | printf("field charset %d\n" , field->charsetnr); |
19149 | printf("\n" ); |
19150 | /* |
19151 | charset value for field must be same for both, view and table. |
19152 | */ |
19153 | DIE_UNLESS(field->charsetnr == tab_charsetnr[i++]); |
19154 | } |
19155 | mysql_free_result(result); |
19156 | |
19157 | DBUG_VOID_RETURN; |
19158 | } |
19159 | |
19160 | /* |
19161 | MDEV-4603: mysql_stmt_reset doesn't clear |
19162 | all result sets (from stored procedures). |
19163 | This test requires also fix for MDEV-4604 |
19164 | */ |
19165 | static void test_mdev4603() |
19166 | { |
19167 | MYSQL *my; |
19168 | MYSQL_STMT *stmt; |
19169 | int i, rc; |
19170 | int a[] = {10,20,30}; |
19171 | MYSQL_BIND bind[3]; |
19172 | |
19173 | myheader("test_mdev4603" ); |
19174 | my= mysql_client_init(NULL); |
19175 | |
19176 | if (!mysql_real_connect(my, opt_host, opt_user, |
19177 | opt_password, current_db, opt_port, |
19178 | opt_unix_socket, CLIENT_MULTI_RESULTS)) |
19179 | DIE("mysql_real_connect failed" ); |
19180 | |
19181 | /* 1st test: |
19182 | use a procedure with out param |
19183 | */ |
19184 | rc= mysql_query(my, "DROP PROCEDURE IF EXISTS p1" ); |
19185 | myquery(rc); |
19186 | |
19187 | rc= mysql_query(mysql, "CREATE PROCEDURE p1(OUT p_out VARCHAR(19), IN p_in INT, INOUT p_inout INT)" |
19188 | "BEGIN " |
19189 | " SET p_in = 300, p_out := 'This is OUT param', p_inout = 200; " |
19190 | " SELECT p_inout, p_in, substring(p_out, 9);" |
19191 | "END" ); |
19192 | myquery(rc); |
19193 | |
19194 | stmt= mysql_stmt_init(mysql); |
19195 | DIE_UNLESS(stmt != NULL); |
19196 | |
19197 | rc= mysql_stmt_prepare(stmt, "CALL P1(?,?,?)" , 14); |
19198 | DIE_UNLESS(rc == 0); |
19199 | |
19200 | DIE_UNLESS(mysql_stmt_param_count(stmt) == 3); |
19201 | |
19202 | memset(bind, 0, sizeof(MYSQL_BIND) * 3); |
19203 | for (i=0; i < 3; i++) |
19204 | { |
19205 | bind[i].buffer= &a[i]; |
19206 | bind[i].buffer_type= MYSQL_TYPE_LONG; |
19207 | } |
19208 | bind[0].buffer_type= MYSQL_TYPE_NULL; |
19209 | rc= mysql_stmt_bind_param(stmt, bind); |
19210 | DIE_UNLESS(rc == 0); |
19211 | |
19212 | rc= mysql_stmt_execute(stmt); |
19213 | DIE_UNLESS(rc == 0); |
19214 | |
19215 | rc= mysql_stmt_fetch(stmt); |
19216 | DIE_UNLESS(rc == 0); |
19217 | |
19218 | rc= mysql_stmt_reset(stmt); |
19219 | DIE_UNLESS(rc == 0); |
19220 | |
19221 | /*connection shouldn't be blocked now */ |
19222 | |
19223 | rc= mysql_query(mysql, "DROP PROCEDURE p1" ); |
19224 | myquery(rc); |
19225 | |
19226 | /* 2nd test: |
19227 | reset all result sets */ |
19228 | rc= mysql_query(my, "CREATE PROCEDURE p1() " |
19229 | "BEGIN" |
19230 | " SELECT 1,2,3 FROM DUAL;" |
19231 | " SELECT 'foo' FROM DUAL;" |
19232 | "END" ); |
19233 | myquery(rc); |
19234 | |
19235 | rc= mysql_stmt_prepare(stmt, "CALL P1()" , 9); |
19236 | DIE_UNLESS(rc == 0); |
19237 | |
19238 | rc= mysql_stmt_execute(stmt); |
19239 | DIE_UNLESS(rc == 0); |
19240 | |
19241 | rc= mysql_stmt_reset(stmt); |
19242 | DIE_UNLESS(rc == 0); |
19243 | |
19244 | /* 3rd test: |
19245 | mysql_stmt_close should also flush all pending |
19246 | result sets |
19247 | */ |
19248 | |
19249 | rc= mysql_stmt_prepare(stmt, "CALL P1()" , 9); |
19250 | DIE_UNLESS(rc == 0); |
19251 | |
19252 | rc= mysql_stmt_execute(stmt); |
19253 | DIE_UNLESS(rc == 0); |
19254 | |
19255 | rc= mysql_stmt_close(stmt); |
19256 | DIE_UNLESS(rc == 0); |
19257 | |
19258 | rc= mysql_query(my, "DROP PROCEDURE p1" ); |
19259 | myquery(rc); |
19260 | |
19261 | mysql_close(my); |
19262 | } |
19263 | |
19264 | /* |
19265 | BUG 11754979 - 46675: ON DUPLICATE KEY UPDATE AND UPDATECOUNT() POSSIBLY WRONG |
19266 | */ |
19267 | |
19268 | static void test_bug11754979() |
19269 | { |
19270 | MYSQL* conn; |
19271 | DBUG_ENTER("test_bug11754979" ); |
19272 | |
19273 | myheader("test_bug11754979" ); |
19274 | DIE_UNLESS((conn= mysql_client_init(NULL))); |
19275 | DIE_UNLESS(mysql_real_connect(conn, opt_host, opt_user, |
19276 | opt_password, opt_db ? opt_db:"test" , opt_port, |
19277 | opt_unix_socket, CLIENT_FOUND_ROWS)); |
19278 | myquery(mysql_query(conn, "DROP TABLE IF EXISTS t1" )); |
19279 | myquery(mysql_query(conn, "CREATE TABLE t1(id INT, label CHAR(1), PRIMARY KEY(id))" )); |
19280 | myquery(mysql_query(conn, "INSERT INTO t1(id, label) VALUES (1, 'a')" )); |
19281 | myquery(mysql_query(conn, "INSERT INTO t1(id, label) VALUES (1, 'a') " |
19282 | "ON DUPLICATE KEY UPDATE id = 4" )); |
19283 | DIE_UNLESS(mysql_affected_rows(conn) == 2); |
19284 | myquery(mysql_query(conn, "DROP TABLE t1" )); |
19285 | mysql_close(conn); |
19286 | |
19287 | DBUG_VOID_RETURN; |
19288 | } |
19289 | |
19290 | static void test_ps_sp_out_params() |
19291 | { |
19292 | MYSQL *my; |
19293 | MYSQL_STMT *stmt; |
19294 | MYSQL_BIND bind[1]; |
19295 | char buffer[20]; |
19296 | int status, rc; |
19297 | |
19298 | myheader("test_ps_sp_out_params" ); |
19299 | my= mysql_client_init(NULL); |
19300 | |
19301 | if (!mysql_real_connect(my, opt_host, opt_user, |
19302 | opt_password, current_db, opt_port, |
19303 | opt_unix_socket, CLIENT_MULTI_RESULTS)) |
19304 | DIE("mysql_real_connect failed" ); |
19305 | |
19306 | rc= mysql_query(my, "DROP PROCEDURE IF EXISTS p1" ); |
19307 | myquery(rc); |
19308 | |
19309 | rc= mysql_query(my, |
19310 | "CREATE PROCEDURE p1(OUT out_param VARCHAR(19)) " |
19311 | "BEGIN" |
19312 | " SELECT 'foo' FROM DUAL;" |
19313 | " SET out_param='foo';" |
19314 | " SELECT 'foo' FROM DUAL;" |
19315 | "END" ); |
19316 | myquery(rc); |
19317 | |
19318 | stmt= mysql_stmt_init(my); |
19319 | |
19320 | rc= mysql_stmt_prepare(stmt, "CALL P1(?)" , 10); |
19321 | DIE_UNLESS(rc==0); |
19322 | |
19323 | DIE_UNLESS(mysql_stmt_param_count(stmt) == 1); |
19324 | |
19325 | memset(bind, 0, sizeof(MYSQL_BIND)); |
19326 | bind[0].buffer= buffer; |
19327 | bind[0].buffer_length= sizeof(buffer); |
19328 | bind[0].buffer_type= MYSQL_TYPE_STRING; |
19329 | |
19330 | mysql_stmt_bind_param(stmt, bind); |
19331 | |
19332 | rc= mysql_stmt_execute(stmt); |
19333 | check_execute(stmt, rc); |
19334 | |
19335 | do { |
19336 | if (mysql_stmt_field_count(stmt)) |
19337 | { |
19338 | /* since server sends a status packet at the end, |
19339 | there must follow at least one additional packet */ |
19340 | DIE_UNLESS(mysql_more_results(stmt->mysql)); |
19341 | |
19342 | mysql_stmt_bind_result(stmt, bind); |
19343 | |
19344 | rc= mysql_stmt_fetch(stmt); |
19345 | DIE_UNLESS(rc== 0); |
19346 | |
19347 | DIE_UNLESS(strcmp(buffer, "foo" ) == 0); |
19348 | } |
19349 | status= mysql_stmt_next_result(stmt); |
19350 | } while (status == 0); |
19351 | |
19352 | rc= mysql_stmt_reset(stmt); |
19353 | DIE_UNLESS(rc== 0); |
19354 | |
19355 | mysql_stmt_close(stmt); |
19356 | mysql_close(my); |
19357 | |
19358 | printf("end\n" ); |
19359 | } |
19360 | |
19361 | /* |
19362 | Bug#13001491: MYSQL_REFRESH CRASHES WHEN STORED ROUTINES ARE RUN CONCURRENTLY. |
19363 | */ |
19364 | static void test_bug13001491() |
19365 | { |
19366 | int rc; |
19367 | char query[MAX_TEST_QUERY_LENGTH]; |
19368 | MYSQL *c; |
19369 | |
19370 | myheader("test_bug13001491" ); |
19371 | |
19372 | my_snprintf(query, MAX_TEST_QUERY_LENGTH, |
19373 | "GRANT ALL PRIVILEGES ON *.* TO mysqltest_u1@%s" , |
19374 | opt_host ? opt_host : "'localhost'" ); |
19375 | |
19376 | rc= mysql_query(mysql, query); |
19377 | myquery(rc); |
19378 | |
19379 | my_snprintf(query, MAX_TEST_QUERY_LENGTH, |
19380 | "GRANT RELOAD ON *.* TO mysqltest_u1@%s" , |
19381 | opt_host ? opt_host : "'localhost'" ); |
19382 | |
19383 | rc= mysql_query(mysql, query); |
19384 | myquery(rc); |
19385 | |
19386 | c= mysql_client_init(NULL); |
19387 | |
19388 | DIE_UNLESS(mysql_real_connect(c, opt_host, "mysqltest_u1" , NULL, |
19389 | current_db, opt_port, opt_unix_socket, |
19390 | CLIENT_MULTI_STATEMENTS | |
19391 | CLIENT_MULTI_RESULTS)); |
19392 | |
19393 | rc= mysql_query(c, "DROP PROCEDURE IF EXISTS p1" ); |
19394 | myquery(rc); |
19395 | |
19396 | rc= mysql_query(c, |
19397 | "CREATE PROCEDURE p1() " |
19398 | "BEGIN " |
19399 | " DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; " |
19400 | " SELECT COUNT(*) " |
19401 | " FROM INFORMATION_SCHEMA.PROCESSLIST " |
19402 | " GROUP BY user " |
19403 | " ORDER BY NULL " |
19404 | " INTO @a; " |
19405 | "END" ); |
19406 | myquery(rc); |
19407 | |
19408 | rc= mysql_query(c, "CALL p1()" ); |
19409 | myquery(rc); |
19410 | |
19411 | mysql_free_result(mysql_store_result(c)); |
19412 | |
19413 | /* Check that mysql_refresh() succeeds without REFRESH_LOG. */ |
19414 | rc= mysql_refresh(c, REFRESH_GRANT | |
19415 | REFRESH_TABLES | REFRESH_HOSTS | |
19416 | REFRESH_STATUS | REFRESH_THREADS); |
19417 | myquery(rc); |
19418 | |
19419 | /* |
19420 | Check that mysql_refresh(REFRESH_LOG) does not crash the server even if it |
19421 | fails. mysql_refresh(REFRESH_LOG) fails when error log points to unavailable |
19422 | location. |
19423 | */ |
19424 | mysql_refresh(c, REFRESH_LOG); |
19425 | |
19426 | rc= mysql_query(c, "DROP PROCEDURE p1" ); |
19427 | myquery(rc); |
19428 | |
19429 | mysql_close(c); |
19430 | c= NULL; |
19431 | |
19432 | my_snprintf(query, MAX_TEST_QUERY_LENGTH, |
19433 | "DROP USER mysqltest_u1@%s" , |
19434 | opt_host ? opt_host : "'localhost'" ); |
19435 | |
19436 | rc= mysql_query(mysql, query); |
19437 | myquery(rc); |
19438 | } |
19439 | |
19440 | static void test_mdev4326() |
19441 | { |
19442 | MYSQL_STMT *stmt; |
19443 | MYSQL_BIND bind; |
19444 | char query[]= "SELECT * FROM mysql.user LIMIT ?" ; |
19445 | char str_data[]= "1" ; |
19446 | unsigned long length= 0; |
19447 | int int_data= 1; |
19448 | int rc, count; |
19449 | my_bool is_null= 0; |
19450 | my_bool error= 0; |
19451 | myheader("test_mdev4326" ); |
19452 | |
19453 | rc= mysql_change_user(mysql, opt_user, opt_password, "mysql" ); |
19454 | myquery(rc); |
19455 | |
19456 | rc= mysql_query(mysql, "SET GLOBAL general_log = 1" ); |
19457 | myquery(rc); |
19458 | |
19459 | stmt= mysql_stmt_init(mysql); |
19460 | check_stmt(stmt); |
19461 | |
19462 | /* Numeric parameter test */ |
19463 | |
19464 | rc= mysql_stmt_prepare(stmt, query, strlen(query)); |
19465 | check_execute(stmt, rc); |
19466 | check_stmt(stmt); |
19467 | verify_param_count(stmt, 1); |
19468 | |
19469 | memset((char *)&bind, 0, sizeof(bind)); |
19470 | bind.buffer_type= MYSQL_TYPE_LONG; |
19471 | bind.buffer= (char *)&int_data; |
19472 | bind.is_null= &is_null; |
19473 | bind.length= &length; |
19474 | bind.error= &error; |
19475 | |
19476 | rc= mysql_stmt_bind_param(stmt, &bind); |
19477 | check_execute(stmt, rc); |
19478 | rc= mysql_stmt_execute(stmt); |
19479 | check_execute(stmt, rc); |
19480 | count= 0; |
19481 | while (!(rc= mysql_stmt_fetch(stmt))) |
19482 | count++; |
19483 | DIE_UNLESS(count == 1); |
19484 | rc= mysql_stmt_execute(stmt); |
19485 | check_execute(stmt, rc); |
19486 | count= 0; |
19487 | while (!(rc= mysql_stmt_fetch(stmt))) |
19488 | count++; |
19489 | DIE_UNLESS(count == 1); |
19490 | int_data= 0; |
19491 | rc= mysql_stmt_execute(stmt); |
19492 | check_execute(stmt, rc); |
19493 | count= 0; |
19494 | while (!(rc= mysql_stmt_fetch(stmt))) |
19495 | count++; |
19496 | DIE_UNLESS(count == 0); |
19497 | rc= mysql_stmt_close(stmt); |
19498 | check_execute(stmt, rc); |
19499 | |
19500 | /* String parameter test */ |
19501 | |
19502 | stmt= mysql_stmt_init(mysql); |
19503 | rc= mysql_stmt_prepare(stmt, query, strlen(query)); |
19504 | check_execute(stmt, rc); |
19505 | check_stmt(stmt); |
19506 | verify_param_count(stmt, 1); |
19507 | |
19508 | memset((char *)&bind, 0, sizeof(bind)); |
19509 | bind.buffer_type= MYSQL_TYPE_STRING; |
19510 | bind.buffer= (char *)str_data; |
19511 | length= bind.buffer_length= sizeof(str_data); |
19512 | bind.is_null= &is_null; |
19513 | bind.length= &length; |
19514 | bind.error= &error; |
19515 | |
19516 | rc= mysql_stmt_bind_param(stmt, &bind); |
19517 | check_execute(stmt, rc); |
19518 | rc= mysql_stmt_execute(stmt); |
19519 | check_execute(stmt, rc); |
19520 | count= 0; |
19521 | while (!(rc= mysql_stmt_fetch(stmt))) |
19522 | count++; |
19523 | DIE_UNLESS(count == 1); |
19524 | rc= mysql_stmt_execute(stmt); |
19525 | check_execute(stmt, rc); |
19526 | count= 0; |
19527 | while (!(rc= mysql_stmt_fetch(stmt))) |
19528 | count++; |
19529 | DIE_UNLESS(count == 1); |
19530 | str_data[0]= '0'; |
19531 | rc= mysql_stmt_execute(stmt); |
19532 | check_execute(stmt, rc); |
19533 | count= 0; |
19534 | while (!(rc= mysql_stmt_fetch(stmt))) |
19535 | count++; |
19536 | DIE_UNLESS(count == 0); |
19537 | rc= mysql_stmt_close(stmt); |
19538 | check_execute(stmt, rc); |
19539 | |
19540 | rc= mysql_change_user(mysql, opt_user, opt_password, current_db); |
19541 | myquery(rc); |
19542 | } |
19543 | |
19544 | /* Test uses MYSQL_PROTOCOL_SOCKET, not on Windows */ |
19545 | |
19546 | #ifndef _WIN32 |
19547 | /** |
19548 | BUG#17512527: LIST HANDLING INCORRECT IN MYSQL_PRUNE_STMT_LIST() |
19549 | */ |
19550 | static void test_bug17512527() |
19551 | { |
19552 | MYSQL *conn; |
19553 | MYSQL_STMT *stmt1, *stmt2; |
19554 | unsigned long thread_id; |
19555 | char query[MAX_TEST_QUERY_LENGTH]; |
19556 | int rc; |
19557 | |
19558 | conn= client_connect(0, MYSQL_PROTOCOL_SOCKET, 1); |
19559 | |
19560 | stmt1 = mysql_stmt_init(conn); |
19561 | check_stmt(stmt1); |
19562 | rc= mysql_stmt_prepare(stmt1, STRING_WITH_LEN("SELECT 1" )); |
19563 | check_execute(stmt1, rc); |
19564 | |
19565 | stmt2 = mysql_stmt_init(conn); |
19566 | check_stmt(stmt2); |
19567 | |
19568 | thread_id= mysql_thread_id(conn); |
19569 | sprintf(query, "KILL %lu" , thread_id); |
19570 | if (thread_query(query)) |
19571 | exit(1); |
19572 | |
19573 | rc= mysql_stmt_prepare(stmt2, STRING_WITH_LEN("SELECT 2" )); |
19574 | check_execute(stmt2, rc); |
19575 | |
19576 | rc= mysql_stmt_execute(stmt1); |
19577 | check_execute_r(stmt1, rc); |
19578 | |
19579 | rc= mysql_stmt_execute(stmt2); |
19580 | check_execute(stmt2, rc); |
19581 | |
19582 | mysql_close(conn); |
19583 | |
19584 | mysql_stmt_close(stmt2); |
19585 | mysql_stmt_close(stmt1); |
19586 | } |
19587 | #endif |
19588 | |
19589 | |
19590 | /* |
19591 | Check compressed protocol |
19592 | */ |
19593 | |
19594 | static void test_compressed_protocol() |
19595 | { |
19596 | MYSQL *mysql_local; |
19597 | char query[4096], *end; |
19598 | int i; |
19599 | myheader("test_compressed_protocol" ); |
19600 | |
19601 | if (!(mysql_local= mysql_client_init(NULL))) |
19602 | { |
19603 | fprintf(stderr, "\n mysql_client_init() failed" ); |
19604 | exit(1); |
19605 | } |
19606 | |
19607 | if (!(mysql_real_connect(mysql_local, opt_host, opt_user, |
19608 | opt_password, current_db, opt_port, |
19609 | opt_unix_socket, CLIENT_COMPRESS))) |
19610 | { |
19611 | fprintf(stderr, "\n connection failed(%s)" , mysql_error(mysql_local)); |
19612 | exit(1); |
19613 | } |
19614 | mysql_options(mysql_local,MYSQL_OPT_COMPRESS,NullS); |
19615 | |
19616 | end= strmov(strfill(strmov(query, "select length(\"" ),1000,'a'),"\")" ); |
19617 | |
19618 | for (i=0 ; i < 2 ; i++) |
19619 | { |
19620 | MYSQL_RES *res; |
19621 | |
19622 | int rc= mysql_real_query(mysql, query, (int) (end-query)); |
19623 | myquery(rc); |
19624 | res= mysql_store_result(mysql); |
19625 | DBUG_ASSERT(res != 0); |
19626 | mysql_free_result(res); |
19627 | } |
19628 | |
19629 | mysql_close(mysql_local); |
19630 | } |
19631 | |
19632 | /* |
19633 | Check big packets |
19634 | */ |
19635 | |
19636 | static void test_big_packet() |
19637 | { |
19638 | MYSQL *mysql_local; |
19639 | char *query, *end; |
19640 | /* We run the tests with a server with max packet size of 3200000 */ |
19641 | size_t big_packet= 31000000L; |
19642 | int i; |
19643 | MYSQL_PARAMETERS *mysql_params= mysql_get_parameters(); |
19644 | long org_max_allowed_packet= *mysql_params->p_max_allowed_packet; |
19645 | long opt_net_buffer_length= *mysql_params->p_net_buffer_length; |
19646 | |
19647 | myheader("test_big_packet" ); |
19648 | |
19649 | query= (char*) my_malloc(big_packet+1024, MYF(MY_WME)); |
19650 | DIE_UNLESS(query); |
19651 | |
19652 | if (!(mysql_local= mysql_client_init(NULL))) |
19653 | { |
19654 | fprintf(stderr, "\n mysql_client_init() failed" ); |
19655 | exit(1); |
19656 | } |
19657 | |
19658 | if (!(mysql_real_connect(mysql_local, opt_host, opt_user, |
19659 | opt_password, current_db, opt_port, |
19660 | opt_unix_socket, 0))) |
19661 | { |
19662 | mysql_close(mysql_local); |
19663 | fprintf(stderr, "\n connection failed(%s)" , mysql_error(mysql_local)); |
19664 | exit(1); |
19665 | } |
19666 | |
19667 | *mysql_params->p_max_allowed_packet= big_packet+1000; |
19668 | *mysql_params->p_net_buffer_length= 8L*256L*256L; |
19669 | |
19670 | end= strmov(strfill(strmov(query, "select length(\"" ), big_packet,'a'),"\")" ); |
19671 | |
19672 | for (i=0 ; i < 2 ; i++) |
19673 | { |
19674 | MYSQL_RES *res; |
19675 | int rc= mysql_real_query(mysql, query, (int) (end-query)); |
19676 | myquery(rc); |
19677 | res= mysql_store_result(mysql); |
19678 | DBUG_ASSERT(res != 0); |
19679 | mysql_free_result(res); |
19680 | } |
19681 | |
19682 | mysql_close(mysql_local); |
19683 | my_free(query); |
19684 | |
19685 | *mysql_params->p_max_allowed_packet= org_max_allowed_packet; |
19686 | *mysql_params->p_net_buffer_length = opt_net_buffer_length; |
19687 | } |
19688 | |
19689 | |
19690 | static void test_prepare_analyze() |
19691 | { |
19692 | MYSQL_STMT *stmt; |
19693 | const char *query= "ANALYZE SELECT 1" ; |
19694 | int rc; |
19695 | myheader("test_prepare_analyze" ); |
19696 | |
19697 | stmt= mysql_stmt_init(mysql); |
19698 | check_stmt(stmt); |
19699 | rc= mysql_stmt_prepare(stmt, query, strlen(query)); |
19700 | check_execute(stmt, rc); |
19701 | |
19702 | rc= mysql_stmt_execute(stmt); |
19703 | check_execute(stmt, rc); |
19704 | |
19705 | rc= mysql_stmt_store_result(stmt); |
19706 | check_execute(stmt, rc); |
19707 | |
19708 | while (!(rc= mysql_stmt_fetch(stmt))) |
19709 | ; |
19710 | |
19711 | DIE_UNLESS(rc == MYSQL_NO_DATA); |
19712 | |
19713 | rc= mysql_stmt_close(stmt); |
19714 | check_execute(stmt, rc); |
19715 | } |
19716 | |
19717 | static void test_mdev12579() |
19718 | { |
19719 | MYSQL_STMT *stmt= mysql_stmt_init(mysql); |
19720 | MYSQL_BIND bind[2]; |
19721 | int rc; |
19722 | long l=3; |
19723 | const char *data = "123456" ; |
19724 | |
19725 | rc= mysql_query(mysql, "CREATE TABLE mdev12579 (k integer,t LONGTEXT,b LONGBLOB,x integer)" ); |
19726 | myquery(rc); |
19727 | |
19728 | rc= mysql_stmt_prepare(stmt, "INSERT INTO mdev12579 VALUES (1,?,NULL,?)" , -1); |
19729 | myquery(rc); |
19730 | |
19731 | rc= mysql_stmt_send_long_data(stmt, 0, data, 6); |
19732 | rc= mysql_stmt_send_long_data(stmt, 0, data, 6); |
19733 | rc= mysql_stmt_send_long_data(stmt, 0, data, 6); |
19734 | |
19735 | memset(bind, 0, sizeof(MYSQL_BIND) * 2); |
19736 | bind[0].buffer_type= MYSQL_TYPE_VAR_STRING; |
19737 | bind[1].buffer_type= MYSQL_TYPE_LONG; |
19738 | bind[1].buffer= &l; |
19739 | mysql_stmt_bind_param(stmt, bind); |
19740 | |
19741 | rc= mysql_stmt_execute(stmt); |
19742 | check_execute(stmt, rc); |
19743 | |
19744 | mysql_stmt_close(stmt); |
19745 | |
19746 | rc= mysql_query(mysql, "DROP TABLE mdev12579" ); |
19747 | myquery(rc); |
19748 | } |
19749 | |
19750 | /* Test test_mdev14013 sql_mode=EMPTY_STRING_IS_NULL */ |
19751 | |
19752 | static void test_mdev14013() |
19753 | { |
19754 | MYSQL *lmysql; |
19755 | MYSQL_STMT *stmt1; |
19756 | MYSQL_BIND my_bind[2]; |
19757 | MYSQL_RES *result; |
19758 | char str_data[20]; |
19759 | unsigned int count; |
19760 | int rc; |
19761 | char query[MAX_TEST_QUERY_LENGTH]; |
19762 | |
19763 | myheader("test_mdev14013" ); |
19764 | |
19765 | if (!opt_silent) |
19766 | fprintf(stdout, "\n Establishing a test connection ..." ); |
19767 | if (!(lmysql= mysql_client_init(NULL))) |
19768 | { |
19769 | myerror("mysql_client_init() failed" ); |
19770 | exit(1); |
19771 | } |
19772 | if (!(mysql_real_connect(lmysql, opt_host, opt_user, |
19773 | opt_password, current_db, opt_port, |
19774 | opt_unix_socket, 0))) |
19775 | { |
19776 | myerror("connection failed" ); |
19777 | exit(1); |
19778 | } |
19779 | mysql_options(lmysql, MYSQL_OPT_RECONNECT, &my_true); |
19780 | if (!opt_silent) |
19781 | fprintf(stdout, "OK" ); |
19782 | |
19783 | /* set AUTOCOMMIT to ON*/ |
19784 | mysql_autocommit(lmysql, TRUE); |
19785 | |
19786 | strmov(query, "SET SQL_MODE= \"EMPTY_STRING_IS_NULL\"" ); |
19787 | if (!opt_silent) |
19788 | fprintf(stdout, "\n With %s" , query); |
19789 | rc= mysql_query(mysql, query); |
19790 | myquery(rc); |
19791 | |
19792 | rc= mysql_query(lmysql, "DROP TABLE IF EXISTS test_mdev14013" ); |
19793 | myquery(rc); |
19794 | |
19795 | rc= mysql_query(lmysql, "CREATE TABLE test_mdev14013(id int, val varchar(10))" ); |
19796 | myquery(rc); |
19797 | |
19798 | strmov(query, "INSERT INTO test_mdev14013(id,val) VALUES(?,?)" ); |
19799 | stmt1= mysql_simple_prepare(mysql, query); |
19800 | check_stmt(stmt1); |
19801 | |
19802 | verify_param_count(stmt1, 2); |
19803 | |
19804 | /* |
19805 | We need to bzero bind structure because mysql_stmt_bind_param checks all |
19806 | its members. |
19807 | */ |
19808 | bzero((char*) my_bind, sizeof(my_bind)); |
19809 | |
19810 | my_bind[0].buffer= (void *)&count; |
19811 | my_bind[0].buffer_type= MYSQL_TYPE_LONG; |
19812 | count= 100; |
19813 | |
19814 | strcpy(str_data,"" ); |
19815 | my_bind[1].buffer_type= MYSQL_TYPE_STRING; |
19816 | my_bind[1].buffer= (char *) str_data; |
19817 | my_bind[1].buffer_length= strlen(str_data); |
19818 | |
19819 | rc= mysql_stmt_bind_param(stmt1, my_bind); |
19820 | |
19821 | rc= mysql_stmt_execute(stmt1); |
19822 | check_execute(stmt1, rc); |
19823 | |
19824 | verify_st_affected_rows(stmt1, 1); |
19825 | |
19826 | rc= mysql_stmt_close(stmt1); |
19827 | |
19828 | strmov(query, "SET SQL_MODE= default" ); |
19829 | if (!opt_silent) |
19830 | fprintf(stdout, "\n With %s\n" , query); |
19831 | rc= mysql_query(mysql, query); |
19832 | myquery(rc); |
19833 | |
19834 | strmov(query, "INSERT INTO test_mdev14013(id,val) VALUES(?,?)" ); |
19835 | stmt1= mysql_simple_prepare(mysql, query); |
19836 | check_stmt(stmt1); |
19837 | |
19838 | count= 200; |
19839 | rc= mysql_stmt_bind_param(stmt1, my_bind); |
19840 | |
19841 | rc= mysql_stmt_execute(stmt1); |
19842 | check_execute(stmt1, rc); |
19843 | |
19844 | verify_st_affected_rows(stmt1, 1); |
19845 | |
19846 | rc= mysql_stmt_close(stmt1); |
19847 | if (!opt_silent) |
19848 | fprintf(stdout, "\n test_mdev14013(x) returned: %d" , rc); |
19849 | DIE_UNLESS( rc == 0); |
19850 | |
19851 | rc= mysql_query(mysql, "SELECT id, val FROM test_mdev14013 order by id" ); |
19852 | myquery(rc); |
19853 | |
19854 | result= mysql_store_result(mysql); |
19855 | mytest(result); |
19856 | |
19857 | rc= my_process_result_set(result); |
19858 | DIE_UNLESS(rc == 2); |
19859 | mysql_free_result(result); |
19860 | |
19861 | rc= mysql_query(mysql, "SELECT id, val FROM test_mdev14013 where val is null" ); |
19862 | myquery(rc); |
19863 | |
19864 | result= mysql_store_result(mysql); |
19865 | mytest(result); |
19866 | |
19867 | rc= my_process_result_set(result); |
19868 | DIE_UNLESS(rc == 1); |
19869 | mysql_free_result(result); |
19870 | |
19871 | myquery(mysql_query(mysql, "drop table test_mdev14013" )); |
19872 | mysql_close(lmysql); |
19873 | } |
19874 | |
19875 | static void test_mdev14013_1() |
19876 | { |
19877 | MYSQL *lmysql; |
19878 | MYSQL_STMT *stmt1; |
19879 | MYSQL_BIND my_bind[3]; |
19880 | char str_data[3][255]; |
19881 | int rc; |
19882 | char query[MAX_TEST_QUERY_LENGTH]; |
19883 | |
19884 | myheader("test_mdev14013_1" ); |
19885 | |
19886 | if (!opt_silent) |
19887 | fprintf(stdout, "\n Establishing a test connection ..." ); |
19888 | if (!(lmysql= mysql_client_init(NULL))) |
19889 | { |
19890 | myerror("mysql_client_init() failed" ); |
19891 | exit(1); |
19892 | } |
19893 | if (!(mysql_real_connect(lmysql, opt_host, opt_user, |
19894 | opt_password, current_db, opt_port, |
19895 | opt_unix_socket, 0))) |
19896 | { |
19897 | myerror("connection failed" ); |
19898 | exit(1); |
19899 | } |
19900 | mysql_options(lmysql, MYSQL_OPT_RECONNECT, &my_true); |
19901 | if (!opt_silent) |
19902 | fprintf(stdout, "OK" ); |
19903 | |
19904 | /* set AUTOCOMMIT to ON*/ |
19905 | mysql_autocommit(lmysql, TRUE); |
19906 | |
19907 | strmov(query, "SET SQL_MODE= \"EMPTY_STRING_IS_NULL\"" ); |
19908 | if (!opt_silent) |
19909 | fprintf(stdout, "\n With %s" , query); |
19910 | rc= mysql_query(mysql, query); |
19911 | myquery(rc); |
19912 | |
19913 | rc= mysql_query(mysql, |
19914 | "CREATE OR REPLACE PROCEDURE test_mdev14013_p1(" |
19915 | " IN i1 VARCHAR(255) , " |
19916 | " INOUT io1 VARCHAR(255), " |
19917 | " OUT o2 VARBINARY(255)) " |
19918 | "BEGIN " |
19919 | " SET o2 = concat(concat(coalesce(i1,'i1 is null'),' - '),coalesce(i1,'io1 is null')); " |
19920 | "END" ); |
19921 | myquery(rc); |
19922 | |
19923 | strmov(query, "CALL test_mdev14013_p1(?, ?, ?)" ); |
19924 | stmt1= mysql_simple_prepare(mysql, query); |
19925 | check_stmt(stmt1); |
19926 | |
19927 | /* Init PS-parameters. */ |
19928 | |
19929 | bzero((char *) my_bind, sizeof (my_bind)); |
19930 | |
19931 | strcpy(str_data[0],"" ); |
19932 | my_bind[0].buffer_type= MYSQL_TYPE_STRING; |
19933 | my_bind[0].buffer= (char *) str_data[0]; |
19934 | my_bind[0].buffer_length= strlen(str_data[0]); |
19935 | |
19936 | strcpy(str_data[1],"" ); |
19937 | my_bind[1].buffer_type= MYSQL_TYPE_STRING; |
19938 | my_bind[1].buffer= (char *) str_data[1]; |
19939 | my_bind[1].buffer_length= strlen(str_data[1]); |
19940 | |
19941 | strcpy(str_data[2],"" ); |
19942 | my_bind[2].buffer_type= MYSQL_TYPE_STRING; |
19943 | my_bind[2].buffer= (char *) str_data[2]; |
19944 | my_bind[2].buffer_length= strlen(str_data[2]); |
19945 | |
19946 | /* Bind parameters. */ |
19947 | |
19948 | rc= mysql_stmt_bind_param(stmt1, my_bind); |
19949 | check_execute(stmt1, rc); |
19950 | /* Execute */ |
19951 | |
19952 | rc= mysql_stmt_execute(stmt1); |
19953 | check_execute(stmt1, rc); |
19954 | |
19955 | my_bind[0].buffer_length= sizeof(str_data[0]); |
19956 | my_bind[1].buffer_length= sizeof(str_data[1]); |
19957 | |
19958 | mysql_stmt_bind_result(stmt1, my_bind); |
19959 | rc= mysql_stmt_fetch(stmt1); |
19960 | |
19961 | if (!opt_silent) |
19962 | fprintf(stdout,"\nstr_data[1]=%s\n" ,str_data[1]); |
19963 | |
19964 | DIE_UNLESS(strcmp(str_data[1], "i1 is null - io1 is null" ) == 0); |
19965 | |
19966 | rc= mysql_stmt_close(stmt1); |
19967 | DIE_UNLESS( rc == 0); |
19968 | |
19969 | myquery(mysql_query(mysql, "drop procedure test_mdev14013_p1" )); |
19970 | mysql_close(lmysql); |
19971 | } |
19972 | |
19973 | |
19974 | static void test_mdev14454_internal(const char *init, |
19975 | unsigned int csid, |
19976 | const char *value) |
19977 | { |
19978 | MYSQL_STMT *stmt; |
19979 | MYSQL_BIND bind; |
19980 | const char *stmtstr= "CALL P1(?)" ; |
19981 | char res[20]; |
19982 | int rc; |
19983 | |
19984 | if ((rc= mysql_query_or_error(mysql, init)) || |
19985 | (rc= mysql_query_or_error(mysql, "DROP PROCEDURE IF EXISTS p1" )) || |
19986 | (rc= mysql_query_or_error(mysql, |
19987 | "CREATE PROCEDURE p1" |
19988 | "(" |
19989 | " OUT param1 TEXT CHARACTER SET utf8" |
19990 | ")" |
19991 | "BEGIN " |
19992 | " SET param1 = _latin1'test\xFF'; " |
19993 | "END" ))) |
19994 | DIE("Initiation failed" ); |
19995 | |
19996 | stmt= mysql_stmt_init(mysql); |
19997 | rc= mysql_stmt_prepare(stmt, stmtstr, strlen(stmtstr)); |
19998 | DIE_UNLESS(rc == 0); |
19999 | DIE_UNLESS(mysql_stmt_param_count(stmt) == 1); |
20000 | |
20001 | bind.buffer_type= MYSQL_TYPE_NULL; |
20002 | rc= mysql_stmt_bind_param(stmt, &bind); |
20003 | DIE_UNLESS(rc == 0); |
20004 | |
20005 | rc= mysql_stmt_execute(stmt); |
20006 | DIE_UNLESS(rc == 0); |
20007 | |
20008 | memset(res, 0, sizeof(res)); |
20009 | memset(&bind, 0, sizeof(bind)); |
20010 | bind.buffer_type= MYSQL_TYPE_STRING; |
20011 | bind.buffer_length= sizeof(res); |
20012 | bind.buffer= res; |
20013 | |
20014 | do { |
20015 | if (mysql->server_status & SERVER_PS_OUT_PARAMS) |
20016 | { |
20017 | MYSQL_FIELD *field; |
20018 | printf("\nOUT param result set:\n" ); |
20019 | DIE_UNLESS(mysql_stmt_field_count(stmt) == 1); |
20020 | field= &stmt->fields[0]; |
20021 | printf("Field: %s\n" , field->name); |
20022 | printf("Type: %d\n" , field->type); |
20023 | printf("Collation: %d\n" , field->charsetnr); |
20024 | printf("Length: %lu\n" , field->length); |
20025 | DIE_UNLESS(stmt->fields[0].charsetnr == csid); |
20026 | |
20027 | rc= mysql_stmt_bind_result(stmt, &bind); |
20028 | DIE_UNLESS(rc == 0); |
20029 | rc= mysql_stmt_fetch(stmt); |
20030 | DIE_UNLESS(rc == 0); |
20031 | printf("Value: %s\n" , res); |
20032 | DIE_UNLESS(strcmp(res, value) == 0); |
20033 | } |
20034 | else if (mysql_stmt_field_count(stmt)) |
20035 | { |
20036 | printf("sp result set\n" ); |
20037 | } |
20038 | } while (mysql_stmt_next_result(stmt) == 0); |
20039 | |
20040 | mysql_stmt_close(stmt); |
20041 | DIE_UNLESS(mysql_query_or_error(mysql, "DROP PROCEDURE p1" ) == 0); |
20042 | } |
20043 | |
20044 | |
20045 | static void test_mdev14454() |
20046 | { |
20047 | myheader("test_mdev14454" ); |
20048 | test_mdev14454_internal("SET NAMES latin1" , 8, "test\xFF" ); |
20049 | test_mdev14454_internal("SET NAMES utf8" , 33, "test\xC3\xBF" ); |
20050 | } |
20051 | |
20052 | |
20053 | typedef struct { |
20054 | char sig[12]; |
20055 | char ver_cmd; |
20056 | char fam; |
20057 | short len; |
20058 | union { |
20059 | struct { /* for TCP/UDP over IPv4, len = 12 */ |
20060 | int src_addr; |
20061 | int dst_addr; |
20062 | short src_port; |
20063 | short dst_port; |
20064 | } ip4; |
20065 | struct { /* for TCP/UDP over IPv6, len = 36 */ |
20066 | char src_addr[16]; |
20067 | char dst_addr[16]; |
20068 | short src_port; |
20069 | short dst_port; |
20070 | } ip6; |
20071 | struct { /* for AF_UNIX sockets, len = 216 */ |
20072 | char src_addr[108]; |
20073 | char dst_addr[108]; |
20074 | } unx; |
20075 | } addr; |
20076 | } ; |
20077 | |
20078 | #ifndef EMBEDDED_LIBRARY |
20079 | static void (const char *ipaddr, int port) |
20080 | { |
20081 | |
20082 | int rc; |
20083 | MYSQL_RES *result; |
20084 | int family = (strchr(ipaddr,':') == NULL)?AF_INET:AF_INET6; |
20085 | char query[256]; |
20086 | char [256]; |
20087 | char addr_bin[16]; |
20088 | v2_proxy_header ; |
20089 | void *[2]; |
20090 | size_t [2]; |
20091 | int i; |
20092 | |
20093 | // normalize IPv4-mapped IPv6 addresses, e.g ::ffff:127.0.0.2 to 127.0.0.2 |
20094 | const char *normalized_addr= strncmp(ipaddr, "::ffff:" , 7)?ipaddr : ipaddr + 7; |
20095 | |
20096 | memset(&v2_header, 0, sizeof(v2_header)); |
20097 | sprintf(text_header,"PROXY %s %s %s %d 3306\r\n" ,family == AF_INET?"TCP4" :"TCP6" , ipaddr, ipaddr, port); |
20098 | |
20099 | inet_pton(family,ipaddr,addr_bin); |
20100 | |
20101 | memcpy(v2_header.sig, "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A" , 12); |
20102 | v2_header.ver_cmd = (0x2 << 4) | 0x1; /* Version (0x2) , Command = PROXY (0x1) */ |
20103 | if(family == AF_INET) |
20104 | { |
20105 | v2_header.fam= 0x11; |
20106 | v2_header.len= htons(12); |
20107 | v2_header.addr.ip4.src_port= htons(port); |
20108 | v2_header.addr.ip4.dst_port= htons(3306); |
20109 | memcpy(&v2_header.addr.ip4.src_addr,addr_bin, sizeof (v2_header.addr.ip4.src_addr)); |
20110 | memcpy(&v2_header.addr.ip4.dst_addr,addr_bin, sizeof (v2_header.addr.ip4.dst_addr)); |
20111 | } |
20112 | else |
20113 | { |
20114 | v2_header.fam= 0x21; |
20115 | v2_header.len= htons(36); |
20116 | v2_header.addr.ip6.src_port= htons(port); |
20117 | v2_header.addr.ip6.dst_port= htons(3306); |
20118 | memcpy(v2_header.addr.ip6.src_addr,addr_bin, sizeof (v2_header.addr.ip6.src_addr)); |
20119 | memcpy(v2_header.addr.ip6.dst_addr,addr_bin, sizeof (v2_header.addr.ip6.dst_addr)); |
20120 | } |
20121 | |
20122 | sprintf(query,"CREATE USER 'u'@'%s' IDENTIFIED BY 'password'" ,normalized_addr); |
20123 | rc= mysql_query(mysql, query); |
20124 | myquery(rc); |
20125 | |
20126 | header_data[0]= text_header; |
20127 | header_data[1]= &v2_header; |
20128 | |
20129 | header_lengths[0]= strlen(text_header); |
20130 | header_lengths[1]= family == AF_INET ? 28 : 52; |
20131 | |
20132 | for (i = 0; i < 2; i++) |
20133 | { |
20134 | MYSQL *m; |
20135 | size_t addrlen; |
20136 | MYSQL_ROW row; |
20137 | m = mysql_client_init(NULL); |
20138 | DIE_UNLESS(m); |
20139 | mysql_optionsv(m, MARIADB_OPT_PROXY_HEADER, header_data[i], header_lengths[i]); |
20140 | if (!mysql_real_connect(m, opt_host, "u" , "password" , NULL, opt_port, opt_unix_socket, 0)) |
20141 | { |
20142 | DIE_UNLESS(0); |
20143 | } |
20144 | rc= mysql_query(m, "select host from information_schema.processlist WHERE ID = connection_id()" ); |
20145 | myquery(rc); |
20146 | /* get the result */ |
20147 | result= mysql_store_result(m); |
20148 | mytest(result); |
20149 | row = mysql_fetch_row(result); |
20150 | addrlen = strlen(normalized_addr); |
20151 | printf("%.*s %.*s\n" , (int)addrlen, row[0], (int)addrlen, normalized_addr); |
20152 | DIE_UNLESS(strncmp(row[0], normalized_addr, addrlen) == 0); |
20153 | DIE_UNLESS(atoi(row[0] + addrlen+1) == port); |
20154 | mysql_close(m); |
20155 | } |
20156 | sprintf(query,"DROP USER 'u'@'%s'" ,normalized_addr); |
20157 | rc = mysql_query(mysql, query); |
20158 | myquery(rc); |
20159 | } |
20160 | |
20161 | |
20162 | /* Test proxy protocol with AF_UNIX (localhost) */ |
20163 | static void () |
20164 | { |
20165 | v2_proxy_header ; |
20166 | void * = &v2_header; |
20167 | size_t = 216 + 16; |
20168 | MYSQL *m; |
20169 | MYSQL_RES *result; |
20170 | MYSQL_ROW row; |
20171 | int rc; |
20172 | |
20173 | memset(&v2_header, 0, sizeof(v2_header)); |
20174 | memcpy(v2_header.sig, "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A" , 12); |
20175 | v2_header.ver_cmd = (0x2 << 4) | 0x1; /* Version (0x2) , Command = PROXY (0x1) */ |
20176 | v2_header.fam= 0x31; |
20177 | v2_header.len= htons(216); |
20178 | strcpy(v2_header.addr.unx.src_addr,"/tmp/mysql.sock" ); |
20179 | strcpy(v2_header.addr.unx.dst_addr,"/tmp/mysql.sock" ); |
20180 | rc = mysql_query(mysql, "CREATE USER 'u'@'localhost' IDENTIFIED BY 'password'" ); |
20181 | myquery(rc); |
20182 | m = mysql_client_init(NULL); |
20183 | DIE_UNLESS(m != NULL); |
20184 | mysql_optionsv(m, MARIADB_OPT_PROXY_HEADER, header_data, header_length); |
20185 | DIE_UNLESS(mysql_real_connect(m, opt_host, "u" , "password" , NULL, opt_port, opt_unix_socket, 0) == m); |
20186 | DIE_UNLESS(mysql_query(m, "select host from information_schema.processlist WHERE ID = connection_id()" ) == 0); |
20187 | /* get the result */ |
20188 | result= mysql_store_result(m); |
20189 | mytest(result); |
20190 | row = mysql_fetch_row(result); |
20191 | DIE_UNLESS(strcmp(row[0], "localhost" ) == 0); |
20192 | mysql_close(m); |
20193 | rc = mysql_query(mysql, "DROP USER 'u'@'localhost'" ); |
20194 | myquery(rc); |
20195 | } |
20196 | |
20197 | /* Proxy header ignoring */ |
20198 | static void () |
20199 | { |
20200 | int rc; |
20201 | MYSQL *m = mysql_client_init(NULL); |
20202 | v2_proxy_header ; |
20203 | DIE_UNLESS(m != NULL); |
20204 | mysql_optionsv(m, MARIADB_OPT_PROXY_HEADER, "PROXY UNKNOWN\r\n" ,15); |
20205 | DIE_UNLESS(mysql_real_connect(m, opt_host, "root" , "" , NULL, opt_port, opt_unix_socket, 0) == m); |
20206 | mysql_close(m); |
20207 | |
20208 | memcpy(v2_header.sig, "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A" , 12); |
20209 | v2_header.ver_cmd = (0x2 << 4) | 0x0; /* Version (0x2) , Command = LOCAL (0x0) */ |
20210 | v2_header.fam= 0x0; /* AF_UNSPEC*/ |
20211 | v2_header.len= htons(0); |
20212 | m = mysql_client_init(NULL); |
20213 | mysql_optionsv(m, MARIADB_OPT_PROXY_HEADER, &v2_header,16); |
20214 | DIE_UNLESS(mysql_real_connect(m, opt_host, "root" , "" , NULL, opt_port, opt_unix_socket, 0) == m); |
20215 | mysql_close(m); |
20216 | |
20217 | /* test for connection denied with empty proxy_protocol_networks */ |
20218 | rc = mysql_query(mysql, "select @@proxy_protocol_networks into @sv_proxy_protocol_networks" ); |
20219 | myquery(rc); |
20220 | mysql_query(mysql, "set global proxy_protocol_networks=default" ); |
20221 | myquery(rc); |
20222 | m = mysql_client_init(NULL); |
20223 | mysql_optionsv(m, MARIADB_OPT_PROXY_HEADER, &v2_header,16); |
20224 | DIE_UNLESS(mysql_real_connect(m, opt_host, "root" , "" , NULL, opt_port, opt_unix_socket, 0) == 0); |
20225 | mysql_close(m); |
20226 | mysql_query(mysql, "set global proxy_protocol_networks= @sv_proxy_protocol_networks" ); |
20227 | myquery(rc); |
20228 | } |
20229 | |
20230 | |
20231 | static void () |
20232 | { |
20233 | test_proxy_header_tcp("192.0.2.1" ,3333); |
20234 | test_proxy_header_tcp("2001:db8:85a3::8a2e:370:7334" ,2222); |
20235 | test_proxy_header_tcp("::ffff:192.0.2.1" ,2222); |
20236 | test_proxy_header_localhost(); |
20237 | test_proxy_header_ignore(); |
20238 | } |
20239 | |
20240 | |
20241 | static void test_bulk_autoinc() |
20242 | { |
20243 | int rc; |
20244 | MYSQL_STMT *stmt; |
20245 | MYSQL_BIND bind[1]; |
20246 | MYSQL_ROW row; |
20247 | char indicator[]= {0, STMT_INDICATOR_NULL, 0/*STMT_INDICATOR_IGNORE*/}; |
20248 | my_bool error[1]; |
20249 | int i, id[]= {2, 3, 777}, count= sizeof(id)/sizeof(id[0]); |
20250 | MYSQL_RES *result; |
20251 | |
20252 | rc= mysql_query(mysql, "DROP TABLE IF EXISTS ai_field_value" ); |
20253 | myquery(rc); |
20254 | rc= mysql_query(mysql, "CREATE TABLE ai_field_value (id int not null primary key auto_increment)" ); |
20255 | myquery(rc); |
20256 | stmt= mysql_stmt_init(mysql); |
20257 | rc= mysql_stmt_prepare(stmt, "INSERT INTO ai_field_value(id) values(?)" , -1); |
20258 | check_execute(stmt, rc); |
20259 | |
20260 | memset(bind, 0, sizeof(bind)); |
20261 | bind[0].buffer_type = MYSQL_TYPE_LONG; |
20262 | bind[0].buffer = (void *)id; |
20263 | bind[0].buffer_length = 0; |
20264 | bind[0].is_null = NULL; |
20265 | bind[0].length = NULL; |
20266 | bind[0].error = error; |
20267 | bind[0].u.indicator= indicator; |
20268 | |
20269 | mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, (void*)&count); |
20270 | rc= mysql_stmt_bind_param(stmt, bind); |
20271 | check_execute(stmt, rc); |
20272 | |
20273 | rc= mysql_stmt_execute(stmt); |
20274 | check_execute(stmt, rc); |
20275 | |
20276 | mysql_stmt_close(stmt); |
20277 | |
20278 | rc= mysql_query(mysql, "SELECT id FROM ai_field_value" ); |
20279 | myquery(rc); |
20280 | |
20281 | result= mysql_store_result(mysql); |
20282 | mytest(result); |
20283 | |
20284 | i= 0; |
20285 | while ((row= mysql_fetch_row(result))) |
20286 | { |
20287 | DIE_IF(atoi(row[0]) != id[i++]); |
20288 | } |
20289 | rc= mysql_query(mysql, "DROP TABLE ai_field_value" ); |
20290 | myquery(rc); |
20291 | } |
20292 | |
20293 | #endif |
20294 | |
20295 | |
20296 | static void print_metadata(MYSQL_RES *rs_metadata, int num_fields) |
20297 | { |
20298 | int i; |
20299 | MYSQL_FIELD *fields= mysql_fetch_fields(rs_metadata); |
20300 | |
20301 | for (i = 0; i < num_fields; ++i) |
20302 | { |
20303 | mct_log(" - %d: name: '%s'/'%s'; table: '%s'/'%s'; " |
20304 | "db: '%s'; catalog: '%s'; length: %d; max_length: %d; " |
20305 | "type: %d; decimals: %d\n" , |
20306 | (int) i, |
20307 | (const char *) fields[i].name, |
20308 | (const char *) fields[i].org_name, |
20309 | (const char *) fields[i].table, |
20310 | (const char *) fields[i].org_table, |
20311 | (const char *) fields[i].db, |
20312 | (const char *) fields[i].catalog, |
20313 | (int) fields[i].length, |
20314 | (int) fields[i].max_length, |
20315 | (int) fields[i].type, |
20316 | (int) fields[i].decimals); |
20317 | |
20318 | } |
20319 | } |
20320 | |
20321 | static void test_explain_meta() |
20322 | { |
20323 | MYSQL_STMT *stmt; |
20324 | int num_fields; |
20325 | char query[MAX_TEST_QUERY_LENGTH]; |
20326 | MYSQL_RES *rs_metadata; |
20327 | int rc; |
20328 | |
20329 | myheader("test_explain_meta" ); |
20330 | mct_start_logging("test_explain_meta" ); |
20331 | |
20332 | strmov(query, "SELECT 1" ); |
20333 | stmt= mysql_simple_prepare(mysql, query); |
20334 | check_stmt(stmt); |
20335 | |
20336 | rs_metadata= mysql_stmt_result_metadata(stmt); |
20337 | |
20338 | num_fields= mysql_stmt_field_count(stmt); |
20339 | mct_log("SELECT number of fields: %d\n" , (int) num_fields); |
20340 | if (num_fields != 1) |
20341 | { |
20342 | mct_close_log(); |
20343 | DIE("num_fields != 1" ); |
20344 | } |
20345 | mysql_stmt_close(stmt); |
20346 | |
20347 | strmov(query, "EXPLAIN SELECT 1" ); |
20348 | stmt= mysql_simple_prepare(mysql, query); |
20349 | check_stmt(stmt); |
20350 | |
20351 | rs_metadata= mysql_stmt_result_metadata(stmt); |
20352 | |
20353 | num_fields= mysql_stmt_field_count(stmt); |
20354 | mct_log("EXPALIN number of fields: %d\n" , (int) num_fields); |
20355 | if (num_fields != 10) |
20356 | { |
20357 | mct_close_log(); |
20358 | DIE("num_fields != 10" ); |
20359 | } |
20360 | print_metadata(rs_metadata, num_fields); |
20361 | mysql_stmt_close(stmt); |
20362 | |
20363 | strmov(query, "EXPLAIN format=json SELECT 1" ); |
20364 | stmt= mysql_simple_prepare(mysql, query); |
20365 | check_stmt(stmt); |
20366 | |
20367 | rs_metadata= mysql_stmt_result_metadata(stmt); |
20368 | |
20369 | num_fields= mysql_stmt_field_count(stmt); |
20370 | mct_log("EXPALIN JSON number of fields: %d\n" , (int) num_fields); |
20371 | if (num_fields != 1) |
20372 | { |
20373 | mct_close_log(); |
20374 | DIE("num_fields != 1" ); |
20375 | } |
20376 | print_metadata(rs_metadata, num_fields); |
20377 | mysql_stmt_close(stmt); |
20378 | |
20379 | |
20380 | strmov(query, "ANALYZE SELECT 1" ); |
20381 | stmt= mysql_simple_prepare(mysql, query); |
20382 | check_stmt(stmt); |
20383 | |
20384 | rs_metadata= mysql_stmt_result_metadata(stmt); |
20385 | |
20386 | num_fields= mysql_stmt_field_count(stmt); |
20387 | mct_log("ANALYZE number of fields: %d\n" , (int) num_fields); |
20388 | if (num_fields != 13) |
20389 | { |
20390 | mct_close_log(); |
20391 | DIE("num_fields != 13" ); |
20392 | } |
20393 | print_metadata(rs_metadata, num_fields); |
20394 | mysql_stmt_close(stmt); |
20395 | |
20396 | strmov(query, "ANALYZE format=json SELECT 1" ); |
20397 | stmt= mysql_simple_prepare(mysql, query); |
20398 | check_stmt(stmt); |
20399 | |
20400 | rs_metadata= mysql_stmt_result_metadata(stmt); |
20401 | |
20402 | num_fields= mysql_stmt_field_count(stmt); |
20403 | mct_log("ANALYZE JSON number of fields: %d\n" , (int) num_fields); |
20404 | if (num_fields != 1) |
20405 | { |
20406 | mct_close_log(); |
20407 | DIE("num_fields != 1" ); |
20408 | } |
20409 | print_metadata(rs_metadata, num_fields); |
20410 | mysql_stmt_close(stmt); |
20411 | |
20412 | rc= mysql_query(mysql, "CREATE TABLE t1 (a int)" ); |
20413 | myquery(rc); |
20414 | |
20415 | strmov(query, "EXPLAIN INSERT INTO t1 values (1)" ); |
20416 | stmt= mysql_simple_prepare(mysql, query); |
20417 | check_stmt(stmt); |
20418 | |
20419 | rs_metadata= mysql_stmt_result_metadata(stmt); |
20420 | |
20421 | num_fields= mysql_stmt_field_count(stmt); |
20422 | mct_log("EXPALIN INSERT number of fields: %d\n" , (int) num_fields); |
20423 | if (num_fields != 10) |
20424 | { |
20425 | mct_close_log(); |
20426 | DIE("num_fields != 10" ); |
20427 | } |
20428 | print_metadata(rs_metadata, num_fields); |
20429 | mysql_stmt_close(stmt); |
20430 | |
20431 | strmov(query, "EXPLAIN format=json INSERT INTO t1 values(1)" ); |
20432 | stmt= mysql_simple_prepare(mysql, query); |
20433 | check_stmt(stmt); |
20434 | |
20435 | rs_metadata= mysql_stmt_result_metadata(stmt); |
20436 | |
20437 | num_fields= mysql_stmt_field_count(stmt); |
20438 | mct_log("EXPALIN JSON INSERT number of fields: %d\n" , (int) num_fields); |
20439 | if (num_fields != 1) |
20440 | { |
20441 | mct_close_log(); |
20442 | DIE("num_fields != 1" ); |
20443 | } |
20444 | print_metadata(rs_metadata, num_fields); |
20445 | mysql_stmt_close(stmt); |
20446 | |
20447 | |
20448 | strmov(query, "ANALYZE INSERT INTO t1 values(1)" ); |
20449 | stmt= mysql_simple_prepare(mysql, query); |
20450 | check_stmt(stmt); |
20451 | |
20452 | rs_metadata= mysql_stmt_result_metadata(stmt); |
20453 | |
20454 | num_fields= mysql_stmt_field_count(stmt); |
20455 | mct_log("ANALYZE INSERT number of fields: %d\n" , (int) num_fields); |
20456 | if (num_fields != 13) |
20457 | { |
20458 | mct_close_log(); |
20459 | DIE("num_fields != 13" ); |
20460 | } |
20461 | print_metadata(rs_metadata, num_fields); |
20462 | mysql_stmt_close(stmt); |
20463 | |
20464 | strmov(query, "ANALYZE format=json INSERT INTO t1 values(1)" ); |
20465 | stmt= mysql_simple_prepare(mysql, query); |
20466 | check_stmt(stmt); |
20467 | |
20468 | rs_metadata= mysql_stmt_result_metadata(stmt); |
20469 | |
20470 | num_fields= mysql_stmt_field_count(stmt); |
20471 | mct_log("ANALYZE JSON INSERT number of fields: %d\n" , (int) num_fields); |
20472 | if (num_fields != 1) |
20473 | { |
20474 | mct_close_log(); |
20475 | DIE("num_fields != 1" ); |
20476 | } |
20477 | print_metadata(rs_metadata, num_fields); |
20478 | mysql_stmt_close(stmt); |
20479 | |
20480 | |
20481 | strmov(query, "EXPLAIN UPDATE t1 set a=2" ); |
20482 | stmt= mysql_simple_prepare(mysql, query); |
20483 | check_stmt(stmt); |
20484 | |
20485 | rs_metadata= mysql_stmt_result_metadata(stmt); |
20486 | |
20487 | num_fields= mysql_stmt_field_count(stmt); |
20488 | mct_log("EXPALIN UPDATE number of fields: %d\n" , (int) num_fields); |
20489 | if (num_fields != 10) |
20490 | { |
20491 | mct_close_log(); |
20492 | DIE("num_fields != 10" ); |
20493 | } |
20494 | print_metadata(rs_metadata, num_fields); |
20495 | mysql_stmt_close(stmt); |
20496 | |
20497 | strmov(query, "EXPLAIN format=json UPDATE t1 set a=2" ); |
20498 | stmt= mysql_simple_prepare(mysql, query); |
20499 | check_stmt(stmt); |
20500 | |
20501 | rs_metadata= mysql_stmt_result_metadata(stmt); |
20502 | |
20503 | num_fields= mysql_stmt_field_count(stmt); |
20504 | mct_log("EXPALIN JSON UPDATE number of fields: %d\n" , (int) num_fields); |
20505 | if (num_fields != 1) |
20506 | { |
20507 | mct_close_log(); |
20508 | DIE("num_fields != 1" ); |
20509 | } |
20510 | print_metadata(rs_metadata, num_fields); |
20511 | mysql_stmt_close(stmt); |
20512 | |
20513 | |
20514 | strmov(query, "ANALYZE UPDATE t1 set a=2" ); |
20515 | stmt= mysql_simple_prepare(mysql, query); |
20516 | check_stmt(stmt); |
20517 | |
20518 | rs_metadata= mysql_stmt_result_metadata(stmt); |
20519 | |
20520 | num_fields= mysql_stmt_field_count(stmt); |
20521 | mct_log("ANALYZE UPDATE number of fields: %d\n" , (int) num_fields); |
20522 | if (num_fields != 13) |
20523 | { |
20524 | mct_close_log(); |
20525 | DIE("num_fields != 13" ); |
20526 | } |
20527 | print_metadata(rs_metadata, num_fields); |
20528 | mysql_stmt_close(stmt); |
20529 | |
20530 | strmov(query, "ANALYZE format=json UPDATE t1 set a=2" ); |
20531 | stmt= mysql_simple_prepare(mysql, query); |
20532 | check_stmt(stmt); |
20533 | |
20534 | rs_metadata= mysql_stmt_result_metadata(stmt); |
20535 | |
20536 | num_fields= mysql_stmt_field_count(stmt); |
20537 | mct_log("ANALYZE JSON UPDATE number of fields: %d\n" , (int) num_fields); |
20538 | if (num_fields != 1) |
20539 | { |
20540 | mct_close_log(); |
20541 | DIE("num_fields != 1" ); |
20542 | } |
20543 | print_metadata(rs_metadata, num_fields); |
20544 | mysql_stmt_close(stmt); |
20545 | |
20546 | |
20547 | strmov(query, "EXPLAIN DELETE FROM t1" ); |
20548 | stmt= mysql_simple_prepare(mysql, query); |
20549 | check_stmt(stmt); |
20550 | |
20551 | rs_metadata= mysql_stmt_result_metadata(stmt); |
20552 | |
20553 | num_fields= mysql_stmt_field_count(stmt); |
20554 | mct_log("EXPALIN DELETE number of fields: %d\n" , (int) num_fields); |
20555 | if (num_fields != 10) |
20556 | { |
20557 | mct_close_log(); |
20558 | DIE("num_fields != 10" ); |
20559 | } |
20560 | print_metadata(rs_metadata, num_fields); |
20561 | mysql_stmt_close(stmt); |
20562 | |
20563 | strmov(query, "EXPLAIN format=json DELETE FROM t1" ); |
20564 | stmt= mysql_simple_prepare(mysql, query); |
20565 | check_stmt(stmt); |
20566 | |
20567 | rs_metadata= mysql_stmt_result_metadata(stmt); |
20568 | |
20569 | num_fields= mysql_stmt_field_count(stmt); |
20570 | mct_log("EXPALIN JSON DELETE number of fields: %d\n" , (int) num_fields); |
20571 | if (num_fields != 1) |
20572 | { |
20573 | mct_close_log(); |
20574 | DIE("num_fields != 1" ); |
20575 | } |
20576 | print_metadata(rs_metadata, num_fields); |
20577 | mysql_stmt_close(stmt); |
20578 | |
20579 | |
20580 | strmov(query, "ANALYZE DELETE FROM t1" ); |
20581 | stmt= mysql_simple_prepare(mysql, query); |
20582 | check_stmt(stmt); |
20583 | |
20584 | rs_metadata= mysql_stmt_result_metadata(stmt); |
20585 | |
20586 | num_fields= mysql_stmt_field_count(stmt); |
20587 | mct_log("ANALYZE DELETE number of fields: %d\n" , (int) num_fields); |
20588 | if (num_fields != 13) |
20589 | { |
20590 | mct_close_log(); |
20591 | DIE("num_fields != 13" ); |
20592 | } |
20593 | print_metadata(rs_metadata, num_fields); |
20594 | mysql_stmt_close(stmt); |
20595 | |
20596 | strmov(query, "ANALYZE format=json DELETE FROM t1" ); |
20597 | stmt= mysql_simple_prepare(mysql, query); |
20598 | check_stmt(stmt); |
20599 | |
20600 | rs_metadata= mysql_stmt_result_metadata(stmt); |
20601 | |
20602 | num_fields= mysql_stmt_field_count(stmt); |
20603 | mct_log("ANALYZE JSON DELETE number of fields: %d\n" , (int) num_fields); |
20604 | if (num_fields != 1) |
20605 | { |
20606 | mct_close_log(); |
20607 | DIE("num_fields != 1" ); |
20608 | } |
20609 | print_metadata(rs_metadata, num_fields); |
20610 | mysql_stmt_close(stmt); |
20611 | |
20612 | rc= mysql_query(mysql, "DROP TABLE t1" ); |
20613 | myquery(rc); |
20614 | mct_close_log(); |
20615 | } |
20616 | |
20617 | static struct my_tests_st my_tests[]= { |
20618 | { "disable_query_logs" , disable_query_logs }, |
20619 | { "test_view_sp_list_fields" , test_view_sp_list_fields }, |
20620 | { "client_query" , client_query }, |
20621 | { "test_prepare_insert_update" , test_prepare_insert_update}, |
20622 | #ifdef EMBEDDED_LIBRARY |
20623 | { "test_embedded_start_stop" , test_embedded_start_stop }, |
20624 | #endif |
20625 | #ifdef NOT_YET_WORKING |
20626 | { "test_drop_temp" , test_drop_temp }, |
20627 | #endif |
20628 | { "test_fetch_seek" , test_fetch_seek }, |
20629 | { "test_fetch_nobuffs" , test_fetch_nobuffs }, |
20630 | { "test_open_direct" , test_open_direct }, |
20631 | { "test_fetch_null" , test_fetch_null }, |
20632 | { "test_ps_null_param" , test_ps_null_param }, |
20633 | { "test_fetch_date" , test_fetch_date }, |
20634 | { "test_fetch_str" , test_fetch_str }, |
20635 | { "test_fetch_long" , test_fetch_long }, |
20636 | { "test_fetch_short" , test_fetch_short }, |
20637 | { "test_fetch_tiny" , test_fetch_tiny }, |
20638 | { "test_fetch_bigint" , test_fetch_bigint }, |
20639 | { "test_fetch_float" , test_fetch_float }, |
20640 | { "test_fetch_double" , test_fetch_double }, |
20641 | { "test_bind_result_ext" , test_bind_result_ext }, |
20642 | { "test_bind_result_ext1" , test_bind_result_ext1 }, |
20643 | { "test_select_direct" , test_select_direct }, |
20644 | { "test_select_prepare" , test_select_prepare }, |
20645 | { "test_select" , test_select }, |
20646 | { "test_select_version" , test_select_version }, |
20647 | { "test_ps_conj_select" , test_ps_conj_select }, |
20648 | { "test_select_show_table" , test_select_show_table }, |
20649 | { "test_func_fields" , test_func_fields }, |
20650 | { "test_long_data" , test_long_data }, |
20651 | { "test_insert" , test_insert }, |
20652 | { "test_set_variable" , test_set_variable }, |
20653 | { "test_select_show" , test_select_show }, |
20654 | { "test_prepare_noparam" , test_prepare_noparam }, |
20655 | { "test_bind_result" , test_bind_result }, |
20656 | { "test_prepare_simple" , test_prepare_simple }, |
20657 | { "test_prepare" , test_prepare }, |
20658 | { "test_null" , test_null }, |
20659 | { "test_debug_example" , test_debug_example }, |
20660 | { "test_update" , test_update }, |
20661 | { "test_simple_update" , test_simple_update }, |
20662 | { "test_simple_delete" , test_simple_delete }, |
20663 | { "test_double_compare" , test_double_compare }, |
20664 | { "client_store_result" , client_store_result }, |
20665 | { "client_use_result" , client_use_result }, |
20666 | { "test_tran_bdb" , test_tran_bdb }, |
20667 | { "test_tran_innodb" , test_tran_innodb }, |
20668 | { "test_prepare_ext" , test_prepare_ext }, |
20669 | { "test_prepare_syntax" , test_prepare_syntax }, |
20670 | { "test_field_names" , test_field_names }, |
20671 | { "test_field_flags" , test_field_flags }, |
20672 | { "test_long_data_str" , test_long_data_str }, |
20673 | { "test_long_data_str1" , test_long_data_str1 }, |
20674 | { "test_long_data_bin" , test_long_data_bin }, |
20675 | { "test_warnings" , test_warnings }, |
20676 | { "test_errors" , test_errors }, |
20677 | { "test_prepare_resultset" , test_prepare_resultset }, |
20678 | { "test_stmt_close" , test_stmt_close }, |
20679 | { "test_prepare_field_result" , test_prepare_field_result }, |
20680 | { "test_multi_stmt" , test_multi_stmt }, |
20681 | { "test_multi_statements" , test_multi_statements }, |
20682 | { "test_prepare_multi_statements" , test_prepare_multi_statements }, |
20683 | { "test_store_result" , test_store_result }, |
20684 | { "test_store_result1" , test_store_result1 }, |
20685 | { "test_store_result2" , test_store_result2 }, |
20686 | { "test_subselect" , test_subselect }, |
20687 | { "test_date" , test_date }, |
20688 | { "test_date_date" , test_date_date }, |
20689 | { "test_date_time" , test_date_time }, |
20690 | { "test_date_ts" , test_date_ts }, |
20691 | { "test_date_dt" , test_date_dt }, |
20692 | { "test_prepare_alter" , test_prepare_alter }, |
20693 | { "test_manual_sample" , test_manual_sample }, |
20694 | { "test_pure_coverage" , test_pure_coverage }, |
20695 | { "test_buffers" , test_buffers }, |
20696 | { "test_ushort_bug" , test_ushort_bug }, |
20697 | { "test_sshort_bug" , test_sshort_bug }, |
20698 | { "test_stiny_bug" , test_stiny_bug }, |
20699 | { "test_field_misc" , test_field_misc }, |
20700 | { "test_set_option" , test_set_option }, |
20701 | #ifndef EMBEDDED_LIBRARY |
20702 | { "test_prepare_grant" , test_prepare_grant }, |
20703 | |
20704 | #endif |
20705 | { "test_frm_bug" , test_frm_bug }, |
20706 | { "test_explain_bug" , test_explain_bug }, |
20707 | { "test_decimal_bug" , test_decimal_bug }, |
20708 | { "test_nstmts" , test_nstmts }, |
20709 | { "test_logs;" , test_logs }, |
20710 | { "test_cuted_rows" , test_cuted_rows }, |
20711 | { "test_fetch_offset" , test_fetch_offset }, |
20712 | { "test_fetch_column" , test_fetch_column }, |
20713 | { "test_mem_overun" , test_mem_overun }, |
20714 | { "test_list_fields" , test_list_fields }, |
20715 | { "test_list_fields_default" , test_list_fields_default }, |
20716 | { "test_free_result" , test_free_result }, |
20717 | { "test_free_store_result" , test_free_store_result }, |
20718 | { "test_sqlmode" , test_sqlmode }, |
20719 | { "test_ts" , test_ts }, |
20720 | { "test_bug1115" , test_bug1115 }, |
20721 | { "test_bug1180" , test_bug1180 }, |
20722 | { "test_bug1500" , test_bug1500 }, |
20723 | { "test_bug1644" , test_bug1644 }, |
20724 | { "test_bug1946" , test_bug1946 }, |
20725 | { "test_bug2248" , test_bug2248 }, |
20726 | { "test_parse_error_and_bad_length" , test_parse_error_and_bad_length }, |
20727 | { "test_bug2247" , test_bug2247 }, |
20728 | { "test_subqueries" , test_subqueries }, |
20729 | { "test_bad_union" , test_bad_union }, |
20730 | { "test_distinct" , test_distinct }, |
20731 | { "test_subqueries_ref" , test_subqueries_ref }, |
20732 | { "test_union" , test_union }, |
20733 | { "test_bug3117" , test_bug3117 }, |
20734 | { "test_join" , test_join }, |
20735 | { "test_selecttmp" , test_selecttmp }, |
20736 | { "test_create_drop" , test_create_drop }, |
20737 | { "test_rename" , test_rename }, |
20738 | { "test_do_set" , test_do_set }, |
20739 | { "test_multi" , test_multi }, |
20740 | { "test_insert_select" , test_insert_select }, |
20741 | { "test_bind_nagative" , test_bind_nagative }, |
20742 | { "test_derived" , test_derived }, |
20743 | { "test_xjoin" , test_xjoin }, |
20744 | { "test_bug3035" , test_bug3035 }, |
20745 | { "test_union2" , test_union2 }, |
20746 | { "test_bug1664" , test_bug1664 }, |
20747 | { "test_union_param" , test_union_param }, |
20748 | { "test_order_param" , test_order_param }, |
20749 | { "test_ps_i18n" , test_ps_i18n }, |
20750 | { "test_bug3796" , test_bug3796 }, |
20751 | { "test_bug4026" , test_bug4026 }, |
20752 | { "test_bug4079" , test_bug4079 }, |
20753 | { "test_bug4236" , test_bug4236 }, |
20754 | { "test_bug4030" , test_bug4030 }, |
20755 | { "test_bug5126" , test_bug5126 }, |
20756 | { "test_bug4231" , test_bug4231 }, |
20757 | { "test_bug5399" , test_bug5399 }, |
20758 | { "test_bug5194" , test_bug5194 }, |
20759 | { "test_bug5315" , test_bug5315 }, |
20760 | { "test_bug6049" , test_bug6049 }, |
20761 | { "test_bug6058" , test_bug6058 }, |
20762 | { "test_bug6059" , test_bug6059 }, |
20763 | { "test_bug6046" , test_bug6046 }, |
20764 | { "test_bug6081" , test_bug6081 }, |
20765 | { "test_bug6096" , test_bug6096 }, |
20766 | { "test_datetime_ranges" , test_datetime_ranges }, |
20767 | { "test_datetime_ranges_mdev15289" , test_datetime_ranges_mdev15289 }, |
20768 | { "test_bug4172" , test_bug4172 }, |
20769 | { "test_conversion" , test_conversion }, |
20770 | { "test_rewind" , test_rewind }, |
20771 | { "test_bug6761" , test_bug6761 }, |
20772 | { "test_view" , test_view }, |
20773 | { "test_view_where" , test_view_where }, |
20774 | { "test_view_2where" , test_view_2where }, |
20775 | { "test_view_star" , test_view_star }, |
20776 | { "test_view_insert" , test_view_insert }, |
20777 | { "test_left_join_view" , test_left_join_view }, |
20778 | { "test_view_insert_fields" , test_view_insert_fields }, |
20779 | { "test_basic_cursors" , test_basic_cursors }, |
20780 | { "test_cursors_with_union" , test_cursors_with_union }, |
20781 | { "test_cursors_with_procedure" , test_cursors_with_procedure }, |
20782 | { "test_truncation" , test_truncation }, |
20783 | { "test_truncation_option" , test_truncation_option }, |
20784 | { "test_client_character_set" , test_client_character_set }, |
20785 | { "test_bug8330" , test_bug8330 }, |
20786 | { "test_bug7990" , test_bug7990 }, |
20787 | { "test_bug8378" , test_bug8378 }, |
20788 | { "test_bug8722" , test_bug8722 }, |
20789 | { "test_bug8880" , test_bug8880 }, |
20790 | { "test_open_cursor_prepared_statement_query_cache" , |
20791 | test_open_cursor_prepared_statement_query_cache }, |
20792 | { "test_bug9159" , test_bug9159 }, |
20793 | { "test_bug9520" , test_bug9520 }, |
20794 | { "test_bug9478" , test_bug9478 }, |
20795 | { "test_bug9643" , test_bug9643 }, |
20796 | { "test_bug10729" , test_bug10729 }, |
20797 | { "test_bug11111" , test_bug11111 }, |
20798 | { "test_bug9992" , test_bug9992 }, |
20799 | { "test_bug10736" , test_bug10736 }, |
20800 | { "test_bug10794" , test_bug10794 }, |
20801 | { "test_bug11172" , test_bug11172 }, |
20802 | { "test_bug11656" , test_bug11656 }, |
20803 | { "test_bug10214" , test_bug10214 }, |
20804 | { "test_bug9735" , test_bug9735 }, |
20805 | { "test_bug11183" , test_bug11183 }, |
20806 | { "test_bug11037" , test_bug11037 }, |
20807 | { "test_bug10760" , test_bug10760 }, |
20808 | { "test_bug12001" , test_bug12001 }, |
20809 | { "test_bug11718" , test_bug11718 }, |
20810 | { "test_bug12925" , test_bug12925 }, |
20811 | { "test_bug11909" , test_bug11909 }, |
20812 | { "test_bug11901" , test_bug11901 }, |
20813 | { "test_bug11904" , test_bug11904 }, |
20814 | { "test_bug12243" , test_bug12243 }, |
20815 | { "test_bug14210" , test_bug14210 }, |
20816 | { "test_bug13488" , test_bug13488 }, |
20817 | { "test_bug13524" , test_bug13524 }, |
20818 | { "test_bug14845" , test_bug14845 }, |
20819 | { "test_opt_reconnect" , test_opt_reconnect }, |
20820 | { "test_bug15510" , test_bug15510}, |
20821 | #ifndef EMBEDDED_LIBRARY |
20822 | { "test_bug12744" , test_bug12744 }, |
20823 | #endif |
20824 | { "test_bug16143" , test_bug16143 }, |
20825 | { "test_bug16144" , test_bug16144 }, |
20826 | { "test_bug15613" , test_bug15613 }, |
20827 | { "test_bug20152" , test_bug20152 }, |
20828 | { "test_bug14169" , test_bug14169 }, |
20829 | { "test_bug17667" , test_bug17667 }, |
20830 | { "test_bug15752" , test_bug15752 }, |
20831 | { "test_mysql_insert_id" , test_mysql_insert_id }, |
20832 | { "test_bug19671" , test_bug19671 }, |
20833 | { "test_bug21206" , test_bug21206 }, |
20834 | { "test_bug21726" , test_bug21726 }, |
20835 | { "test_bug15518" , test_bug15518 }, |
20836 | { "test_bug23383" , test_bug23383 }, |
20837 | { "test_bug32265" , test_bug32265 }, |
20838 | { "test_bug21635" , test_bug21635 }, |
20839 | { "test_status" , test_status }, |
20840 | { "test_bug24179" , test_bug24179 }, |
20841 | { "test_ps_query_cache" , test_ps_query_cache }, |
20842 | { "test_bug28075" , test_bug28075 }, |
20843 | { "test_bug27876" , test_bug27876 }, |
20844 | { "test_bug28505" , test_bug28505 }, |
20845 | { "test_bug28934" , test_bug28934 }, |
20846 | { "test_bug27592" , test_bug27592 }, |
20847 | { "test_bug29687" , test_bug29687 }, |
20848 | { "test_bug29692" , test_bug29692 }, |
20849 | { "test_bug29306" , test_bug29306 }, |
20850 | { "test_change_user" , test_change_user }, |
20851 | { "test_bug30472" , test_bug30472 }, |
20852 | { "test_bug20023" , test_bug20023 }, |
20853 | { "test_bug45010" , test_bug45010 }, |
20854 | { "test_bug53371" , test_bug53371 }, |
20855 | { "test_bug31418" , test_bug31418 }, |
20856 | { "test_bug31669" , test_bug31669 }, |
20857 | { "test_bug28386" , test_bug28386 }, |
20858 | { "test_wl4166_1" , test_wl4166_1 }, |
20859 | { "test_wl4166_2" , test_wl4166_2 }, |
20860 | { "test_wl4166_3" , test_wl4166_3 }, |
20861 | { "test_wl4166_4" , test_wl4166_4 }, |
20862 | { "test_bug36004" , test_bug36004 }, |
20863 | { "test_wl4284_1" , test_wl4284_1 }, |
20864 | { "test_wl4435" , test_wl4435 }, |
20865 | { "test_wl4435_2" , test_wl4435_2 }, |
20866 | { "test_wl4435_3" , test_wl4435_3 }, |
20867 | { "test_bug38486" , test_bug38486 }, |
20868 | { "test_bug33831" , test_bug33831 }, |
20869 | { "test_bug40365" , test_bug40365 }, |
20870 | { "test_bug43560" , test_bug43560 }, |
20871 | { "test_bug36326" , test_bug36326 }, |
20872 | { "test_bug41078" , test_bug41078 }, |
20873 | { "test_bug44495" , test_bug44495 }, |
20874 | { "test_bug49972" , test_bug49972 }, |
20875 | { "test_bug42373" , test_bug42373 }, |
20876 | { "test_bug54041" , test_bug54041 }, |
20877 | { "test_bug47485" , test_bug47485 }, |
20878 | { "test_bug58036" , test_bug58036 }, |
20879 | { "test_bug57058" , test_bug57058 }, |
20880 | { "test_bug56976" , test_bug56976 }, |
20881 | { "test_mdev3885" , test_mdev3885 }, |
20882 | { "test_mdev4603" , test_mdev4603 }, |
20883 | { "test_bug11766854" , test_bug11766854 }, |
20884 | { "test_bug12337762" , test_bug12337762 }, |
20885 | { "test_progress_reporting" , test_progress_reporting }, |
20886 | { "test_bug11754979" , test_bug11754979 }, |
20887 | { "test_bug13001491" , test_bug13001491 }, |
20888 | { "test_mdev4326" , test_mdev4326 }, |
20889 | { "test_ps_sp_out_params" , test_ps_sp_out_params }, |
20890 | #ifndef _WIN32 |
20891 | { "test_bug17512527" , test_bug17512527}, |
20892 | #endif |
20893 | { "test_compressed_protocol" , test_compressed_protocol }, |
20894 | { "test_big_packet" , test_big_packet }, |
20895 | { "test_prepare_analyze" , test_prepare_analyze }, |
20896 | { "test_mdev12579" , test_mdev12579 }, |
20897 | { "test_mdev14013" , test_mdev14013 }, |
20898 | { "test_mdev14013_1" , test_mdev14013_1 }, |
20899 | { "test_mdev14454" , test_mdev14454 }, |
20900 | #ifndef EMBEDDED_LIBRARY |
20901 | { "test_proxy_header" , test_proxy_header}, |
20902 | { "test_bulk_autoinc" , test_bulk_autoinc}, |
20903 | #endif |
20904 | { "test_explain_meta" , test_explain_meta }, |
20905 | { 0, 0 } |
20906 | }; |
20907 | |
20908 | |
20909 | static struct my_tests_st *get_my_tests() { return my_tests; } |
20910 | |