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
43static const my_bool my_true= 1;
44
45
46/* Query processing */
47
48static 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
59static 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
104static 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
125static 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
145static 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
184static 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
258static 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
331static 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
383static 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
503char mct_log_file_path[FILE_PATH_SIZE];
504FILE *mct_log_file= NULL;
505
506void 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
551void 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
567void 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
579static 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
1002static 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
1132static 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
1317static 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
1370static 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
1401static 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
1581static 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
1666static 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
1769static 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
1844static 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
1924static 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
1946static 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
1971static 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
2011static 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
2073static 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
2145static 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 */
2203static 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*/
2260static 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*/
2289static 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
2516static 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(\
2531session_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
2628static 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
2717static 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 *)&num;
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
2822static 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
2886static 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
2966static 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
3050static 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
3142static 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
3301static 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
3380static 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
3463static 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
3564static 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
3612static 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
3700static 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
3820static 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
3954static 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
4113static 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
4252static 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
4276static 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
4300static 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
4324static 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
4349static 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
4374static 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
4399static 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
4421static 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
4541static 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
4588static 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
4616static 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
4641static 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
4720static 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
4753static 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
4811static 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
4932static 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
5034static 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
5117static 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
5249static 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
5413static 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
5470static void test_multi_statements()
5471{
5472 MYSQL *mysql_local;
5473 MYSQL_RES *result;
5474 int rc;
5475
5476 const char *query= "\
5477DROP TABLE IF EXISTS test_multi_tab;\
5478CREATE TABLE test_multi_tab(id int, name char(20));\
5479INSERT INTO test_multi_tab(id) VALUES(10), (20);\
5480INSERT INTO test_multi_tab VALUES(20, 'insert;comma');\
5481SELECT * FROM test_multi_tab;\
5482UPDATE test_multi_tab SET name='new;name' WHERE id=20;\
5483DELETE FROM test_multi_tab WHERE name='new;name';\
5484SELECT * FROM test_multi_tab;\
5485DELETE FROM test_multi_tab WHERE id=10;\
5486SELECT * FROM test_multi_tab;\
5487DROP TABLE test_multi_tab;\
5488select 1;\
5489DROP 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
5625static 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
5655static 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
5783static 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
5840static 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
5928static 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
6049static 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
6189static 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
6211static 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
6233static 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
6255static 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
6277static 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
6296static 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
6379static 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
6472static 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
6573static 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
6634static 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
6722static 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
6809static 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
6895static 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
7012static 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
7080static 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
7189static 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
7290static 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
7377static 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
7483static 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
7628static 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
7642static 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
7754static 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
7818static 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
7972static 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
8045static 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
8140static 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
8232static 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
8369static 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
8400static 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
8470static 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
8506static 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
8583static 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
8664static 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
8746static 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
8887static 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
8998static 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
9109static 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
9136static 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
9167static 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
9246static 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
9283static 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
9296static 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
9336static 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
9390static 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
9424static 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
9477static 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
9543static 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
9595static 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
9642static 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
9723static 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
9772static 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
9810static 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 *)&param;
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
9898static 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
9946static 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
9991static 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)) \
10008ENGINE=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
10044static 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
10097static 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
10297static 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
10337static 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
10475static 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
10514static 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
10564static 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
10751static 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
10832static 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
10908static 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
10952static 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
10980static 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
11056static 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
11139static 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
11182static 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
11265static 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
11319static 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
11382static 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
11422static 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
11497static 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
11545static 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
11618static 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
11666static 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
11856static 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
11895static 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
11944static 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
11996static 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
12012static 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
12059static 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
12104static 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
12117static 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*/
12136static 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
12166static 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
12275static 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*/
12408static 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
12517static 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
12582static 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
12649static 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
12714static 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
12959static 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
13013static 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
13036static 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
13087static 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
13109static 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
13180static 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
13190static 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
13218static 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
13229static 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) - \
13249count(s2) as vx from t1 group by s2 having sum(s1) - count(s2) < (select f1() \
13250from 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
13275static 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
13325static 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
13366MYSQL_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
13380static 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
13411static 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
13457static 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
13484static 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
13541static 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
13679static 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
13740static 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
13801static 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
13863static 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
13912static 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
13968static 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
14056static 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
14126static 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
14183static 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
14204static 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
14226static 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
14253static 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
14295static 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
14341static 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
14449static 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
14501static 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
14619static 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
14741static 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
14816static 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
14879static 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*/
14915static 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
14928static 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
14977static 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
15051static 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
15109static 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*/
15154static 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
15185static 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
15259static 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
15294static 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
15309static 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
15330static 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*/
15397static 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*/
15537static 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*/
15579static 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
15779static 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
15828static 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*/
15892static 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
15932static 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*/
15954static 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*/
16002static 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*/
16079static 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
16154static 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
16182static 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
16274static 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
16295static 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
16364static 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
16383static 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
16419static 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
16668static 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
16720static 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
16752static 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
16782static 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
16831static 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
16865static 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
16994static 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
17002static 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
17031static 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
17044static 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
17193static 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
17274static 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
17294static 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
17402static 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
17476static 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
17594static 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
17692static 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
17750static 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
17850static 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
17895static 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
17945static 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
17977static 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
18010static 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 */
18104static 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
18201static 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
18261static 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(&param, 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, &param);
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*/
18323static 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
18354static 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
18399static 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*/
18447static 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
18528static 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
18585static 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*/
18598static 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*/
18699static 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
18774static 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*/
18876static 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
18926uint progress_stage, progress_max_stage, progress_count;
18927
18928static 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
18940static 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
19012static 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
19029static 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
19067static 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*/
19088static 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*/
19165static 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
19268static 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
19290static 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*/
19364static 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
19440static 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*/
19550static 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
19594static 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
19636static 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
19690static 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
19717static 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
19752static 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
19875static 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
19974static 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
20045static 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
20053typedef 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} v2_proxy_header;
20077
20078#ifndef EMBEDDED_LIBRARY
20079static void test_proxy_header_tcp(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 text_header[256];
20087 char addr_bin[16];
20088 v2_proxy_header v2_header;
20089 void *header_data[2];
20090 size_t header_lengths[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) */
20163static void test_proxy_header_localhost()
20164{
20165 v2_proxy_header v2_header;
20166 void *header_data = &v2_header;
20167 size_t header_length= 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 */
20198static void test_proxy_header_ignore()
20199{
20200 int rc;
20201 MYSQL *m = mysql_client_init(NULL);
20202 v2_proxy_header v2_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
20231static void test_proxy_header()
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
20241static 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
20296static 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
20321static 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
20617static 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
20909static struct my_tests_st *get_my_tests() { return my_tests; }
20910