1 /* Copyright (c) 2002, 2014, Oracle and/or its affiliates.
2    Copyright (c) 2008, 2022, 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-1335  USA */
16 
17 /***************************************************************************
18  This is a test sample to test the new features in MySQL client-server
19  protocol
20 
21  Main author: venu ( venu@mysql.com )
22 ***************************************************************************/
23 
24 /*
25   XXX: PLEASE RUN THIS PROGRAM UNDER VALGRIND AND VERIFY THAT YOUR TEST
26   DOESN'T CONTAIN WARNINGS/ERRORS BEFORE YOU PUSH.
27 */
28 
29 
30 /*
31   The fw.c file includes all the mysql_client_test framework; this file
32   contains only the actual tests, plus the list of test functions to call.
33 */
34 #ifdef _MSC_VER
35 #pragma warning (disable : 4267)
36 #endif
37 
38 #include "mysql_client_fw.c"
39 #ifndef _WIN32
40 #include <arpa/inet.h>
41 #endif
42 
43 static const my_bool my_true= 1;
44 
45 
46 /* Query processing */
47 
get_reconnect(MYSQL * mysql)48 static my_bool get_reconnect(MYSQL *mysql)
49 {
50 #ifdef EMBEDDED_LIBRARY
51   return mysql->reconnect;
52 #else
53   my_bool reconnect;
54   mysql_get_option(mysql, MYSQL_OPT_RECONNECT, &reconnect);
55   return reconnect;
56 #endif
57 }
58 
client_query()59 static void client_query()
60 {
61   int rc;
62 
63   myheader("client_query");
64 
65   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
66   myquery(rc);
67 
68   rc= mysql_query(mysql, "CREATE TABLE t1("
69                          "id int primary key auto_increment, "
70                          "name varchar(20))");
71   myquery(rc);
72 
73   rc= mysql_query(mysql, "CREATE TABLE t1(id int, name varchar(20))");
74   myquery_r(rc);
75 
76   rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('mysql')");
77   myquery(rc);
78 
79   rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('monty')");
80   myquery(rc);
81 
82   rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('venu')");
83   myquery(rc);
84 
85   rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('deleted')");
86   myquery(rc);
87 
88   rc= mysql_query(mysql, "INSERT INTO t1(name) VALUES('deleted')");
89   myquery(rc);
90 
91   rc= mysql_query(mysql, "UPDATE t1 SET name= 'updated' "
92                           "WHERE name= 'deleted'");
93   myquery(rc);
94 
95   rc= mysql_query(mysql, "UPDATE t1 SET id= 3 WHERE name= 'updated'");
96   myquery_r(rc);
97 
98   myquery(mysql_query(mysql, "drop table t1"));
99 }
100 
101 
102 /* Store result processing */
103 
client_store_result()104 static void client_store_result()
105 {
106   MYSQL_RES *result;
107   int       rc;
108 
109   myheader("client_store_result");
110 
111   rc= mysql_query(mysql, "SELECT * FROM t1");
112   myquery(rc);
113 
114   /* get the result */
115   result= mysql_store_result(mysql);
116   mytest(result);
117 
118   (void) my_process_result_set(result);
119   mysql_free_result(result);
120 }
121 
122 
123 /* Fetch the results */
124 
client_use_result()125 static void client_use_result()
126 {
127   MYSQL_RES *result;
128   int       rc;
129   myheader("client_use_result");
130 
131   rc= mysql_query(mysql, "SELECT * FROM t1");
132   myquery(rc);
133 
134   /* get the result */
135   result= mysql_use_result(mysql);
136   mytest(result);
137 
138   (void) my_process_result_set(result);
139   mysql_free_result(result);
140 }
141 
142 
143 /* Query processing */
144 
test_debug_example()145 static void test_debug_example()
146 {
147   int rc;
148   MYSQL_RES *result;
149 
150   myheader("test_debug_example");
151 
152   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_debug_example");
153   myquery(rc);
154 
155   rc= mysql_query(mysql, "CREATE TABLE test_debug_example("
156                          "id INT PRIMARY KEY AUTO_INCREMENT, "
157                          "name VARCHAR(20), xxx INT)");
158   myquery(rc);
159 
160   rc= mysql_query(mysql, "INSERT INTO test_debug_example (name) "
161                          "VALUES ('mysql')");
162   myquery(rc);
163 
164   rc= mysql_query(mysql, "UPDATE test_debug_example SET name='updated' "
165                          "WHERE name='deleted'");
166   myquery(rc);
167 
168   rc= mysql_query(mysql, "SELECT * FROM test_debug_example where name='mysql'");
169   myquery(rc);
170 
171   result= mysql_use_result(mysql);
172   mytest(result);
173 
174   (void) my_process_result_set(result);
175   mysql_free_result(result);
176 
177   rc= mysql_query(mysql, "DROP TABLE test_debug_example");
178   myquery(rc);
179 }
180 
181 
182 /* Test autocommit feature for BDB tables */
183 
test_tran_bdb()184 static void test_tran_bdb()
185 {
186   MYSQL_RES *result;
187   MYSQL_ROW row;
188   int       rc;
189 
190   myheader("test_tran_bdb");
191 
192   /* set AUTOCOMMIT to OFF */
193   rc= mysql_autocommit(mysql, FALSE);
194   myquery(rc);
195 
196   rc= mysql_query(mysql, "DROP TABLE IF EXISTS my_demo_transaction");
197   myquery(rc);
198 
199 
200   /* create the table 'mytran_demo' of type BDB' or 'InnoDB' */
201   rc= mysql_query(mysql, "CREATE TABLE my_demo_transaction( "
202                          "col1 int , col2 varchar(30)) ENGINE= BDB");
203   myquery(rc);
204 
205   /* insert a row and commit the transaction */
206   rc= mysql_query(mysql, "INSERT INTO my_demo_transaction VALUES(10, 'venu')");
207   myquery(rc);
208 
209   rc= mysql_commit(mysql);
210   myquery(rc);
211 
212   /* now insert the second row, and roll back the transaction */
213   rc= mysql_query(mysql, "INSERT INTO my_demo_transaction VALUES(20, 'mysql')");
214   myquery(rc);
215 
216   rc= mysql_rollback(mysql);
217   myquery(rc);
218 
219   /* delete first row, and roll it back */
220   rc= mysql_query(mysql, "DELETE FROM my_demo_transaction WHERE col1= 10");
221   myquery(rc);
222 
223   rc= mysql_rollback(mysql);
224   myquery(rc);
225 
226   /* test the results now, only one row should exist */
227   rc= mysql_query(mysql, "SELECT * FROM my_demo_transaction");
228   myquery(rc);
229 
230   /* get the result */
231   result= mysql_store_result(mysql);
232   mytest(result);
233 
234   (void) my_process_result_set(result);
235   mysql_free_result(result);
236 
237   /* test the results now, only one row should exist */
238   rc= mysql_query(mysql, "SELECT * FROM my_demo_transaction");
239   myquery(rc);
240 
241   /* get the result */
242   result= mysql_use_result(mysql);
243   mytest(result);
244 
245   row= mysql_fetch_row(result);
246   mytest(row);
247 
248   row= mysql_fetch_row(result);
249   mytest_r(row);
250 
251   mysql_free_result(result);
252   mysql_autocommit(mysql, TRUE);
253 }
254 
255 
256 /* Test autocommit feature for InnoDB tables */
257 
test_tran_innodb()258 static void test_tran_innodb()
259 {
260   MYSQL_RES *result;
261   MYSQL_ROW row;
262   int       rc;
263 
264   myheader("test_tran_innodb");
265 
266   /* set AUTOCOMMIT to OFF */
267   rc= mysql_autocommit(mysql, FALSE);
268   myquery(rc);
269 
270   rc= mysql_query(mysql, "DROP TABLE IF EXISTS my_demo_transaction");
271   myquery(rc);
272 
273   /* create the table 'mytran_demo' of type BDB' or 'InnoDB' */
274   rc= mysql_query(mysql, "CREATE TABLE my_demo_transaction(col1 int, "
275                          "col2 varchar(30)) ENGINE= InnoDB");
276   myquery(rc);
277 
278   /* insert a row and commit the transaction */
279   rc= mysql_query(mysql, "INSERT INTO my_demo_transaction VALUES(10, 'venu')");
280   myquery(rc);
281 
282   rc= mysql_commit(mysql);
283   myquery(rc);
284 
285   /* now insert the second row, and roll back the transaction */
286   rc= mysql_query(mysql, "INSERT INTO my_demo_transaction VALUES(20, 'mysql')");
287   myquery(rc);
288 
289   rc= mysql_rollback(mysql);
290   myquery(rc);
291 
292   /* delete first row, and roll it back */
293   rc= mysql_query(mysql, "DELETE FROM my_demo_transaction WHERE col1= 10");
294   myquery(rc);
295 
296   rc= mysql_rollback(mysql);
297   myquery(rc);
298 
299   /* test the results now, only one row should exist */
300   rc= mysql_query(mysql, "SELECT * FROM my_demo_transaction");
301   myquery(rc);
302 
303   /* get the result */
304   result= mysql_store_result(mysql);
305   mytest(result);
306 
307   (void) my_process_result_set(result);
308   mysql_free_result(result);
309 
310   /* test the results now, only one row should exist */
311   rc= mysql_query(mysql, "SELECT * FROM my_demo_transaction");
312   myquery(rc);
313 
314   /* get the result */
315   result= mysql_use_result(mysql);
316   mytest(result);
317 
318   row= mysql_fetch_row(result);
319   mytest(row);
320 
321   row= mysql_fetch_row(result);
322   mytest_r(row);
323 
324   mysql_free_result(result);
325   mysql_autocommit(mysql, TRUE);
326 }
327 
328 
329 /* Test for BUG#7242 */
330 
test_prepare_insert_update()331 static void test_prepare_insert_update()
332 {
333   MYSQL_STMT *stmt;
334   int        rc;
335   int        i;
336   const char *testcase[]= {
337     "CREATE TABLE t1 (a INT, b INT, c INT, UNIQUE (A), UNIQUE(B))",
338     "INSERT t1 VALUES (1,2,10), (3,4,20)",
339     "INSERT t1 VALUES (5,6,30), (7,4,40), (8,9,60) ON DUPLICATE KEY UPDATE c=c+100",
340     "SELECT * FROM t1",
341     "INSERT t1 SET a=5 ON DUPLICATE KEY UPDATE b=0",
342     "SELECT * FROM t1",
343     "INSERT t1 VALUES (2,1,11), (7,4,40) ON DUPLICATE KEY UPDATE c=c+VALUES(a)",
344     NULL};
345   const char **cur_query;
346 
347   myheader("test_prepare_insert_update");
348 
349   for (cur_query= testcase; *cur_query; cur_query++)
350   {
351     char query[MAX_TEST_QUERY_LENGTH];
352     printf("\nRunning query: %s", *cur_query);
353     strmov(query, *cur_query);
354     stmt= mysql_simple_prepare(mysql, query);
355     check_stmt(stmt);
356 
357     verify_param_count(stmt, 0);
358     rc= mysql_stmt_execute(stmt);
359 
360     check_execute(stmt, rc);
361     /* try the last query several times */
362     if (!cur_query[1])
363     {
364       for (i=0; i < 3;i++)
365       {
366         printf("\nExecuting last statement again");
367         rc= mysql_stmt_execute(stmt);
368         check_execute(stmt, rc);
369         rc= mysql_stmt_execute(stmt);
370         check_execute(stmt, rc);
371       }
372     }
373     mysql_stmt_close(stmt);
374   }
375 
376   rc= mysql_commit(mysql);
377   myquery(rc);
378 }
379 
380 
381 /* Test simple prepares of all DML statements */
382 
test_prepare_simple()383 static void test_prepare_simple()
384 {
385   MYSQL_STMT *stmt;
386   int        rc;
387   char query[MAX_TEST_QUERY_LENGTH];
388 
389   myheader("test_prepare_simple");
390 
391   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_simple");
392   myquery(rc);
393 
394   rc= mysql_query(mysql, "CREATE TABLE test_prepare_simple("
395                          "id int, name varchar(50))");
396   myquery(rc);
397 
398   /* insert */
399   strmov(query, "INSERT INTO test_prepare_simple VALUES(?, ?)");
400   stmt= mysql_simple_prepare(mysql, query);
401   check_stmt(stmt);
402 
403   verify_param_count(stmt, 2);
404   mysql_stmt_close(stmt);
405 
406   /* update */
407   strmov(query, "UPDATE test_prepare_simple SET id=? "
408                 "WHERE id=? AND CONVERT(name USING utf8)= ?");
409   stmt= mysql_simple_prepare(mysql, query);
410   check_stmt(stmt);
411 
412   verify_param_count(stmt, 3);
413   mysql_stmt_close(stmt);
414 
415   /* delete */
416   strmov(query, "DELETE FROM test_prepare_simple WHERE id=10");
417   stmt= mysql_simple_prepare(mysql, query);
418   check_stmt(stmt);
419 
420   verify_param_count(stmt, 0);
421 
422   rc= mysql_stmt_execute(stmt);
423   check_execute(stmt, rc);
424   mysql_stmt_close(stmt);
425 
426   /* delete */
427   strmov(query, "DELETE FROM test_prepare_simple WHERE id=?");
428   stmt= mysql_simple_prepare(mysql, query);
429   check_stmt(stmt);
430 
431   verify_param_count(stmt, 1);
432 
433   mysql_stmt_close(stmt);
434 
435   /* select */
436   strmov(query, "SELECT * FROM test_prepare_simple WHERE id=? "
437                 "AND CONVERT(name USING utf8)= ?");
438   stmt= mysql_simple_prepare(mysql, query);
439   check_stmt(stmt);
440 
441   verify_param_count(stmt, 2);
442 
443   mysql_stmt_close(stmt);
444 
445   /* show create */
446   strmov(query, "SHOW CREATE TABLE test_prepare_simple");
447   stmt= mysql_simple_prepare(mysql, query);
448   check_stmt(stmt);
449   DIE_UNLESS(mysql_stmt_field_count(stmt) == 2);
450   mysql_stmt_close(stmt);
451 
452   /* show create database */
453   strmov(query, "SHOW CREATE DATABASE test");
454   stmt= mysql_simple_prepare(mysql, query);
455   check_stmt(stmt);
456   DIE_UNLESS(mysql_stmt_field_count(stmt) == 2);
457   mysql_stmt_close(stmt);
458 
459   /* show grants */
460   strmov(query, "SHOW GRANTS");
461   stmt= mysql_simple_prepare(mysql, query);
462   check_stmt(stmt);
463   DIE_UNLESS(mysql_stmt_field_count(stmt) == 1);
464   mysql_stmt_close(stmt);
465 
466   /* show slave status */
467   strmov(query, "SHOW SLAVE STATUS");
468   stmt= mysql_simple_prepare(mysql, query);
469   check_stmt(stmt);
470   DIE_UNLESS(mysql_stmt_field_count(stmt) == 53);
471   mysql_stmt_close(stmt);
472 
473   /* show master status */
474   strmov(query, "SHOW MASTER STATUS");
475   stmt= mysql_simple_prepare(mysql, query);
476   check_stmt(stmt);
477   DIE_UNLESS(mysql_stmt_field_count(stmt) == 4);
478   mysql_stmt_close(stmt);
479 
480   /* show create procedure */
481   strmov(query, "SHOW CREATE PROCEDURE e1;");
482   stmt= mysql_simple_prepare(mysql, query);
483   check_stmt(stmt);
484   DIE_UNLESS(mysql_stmt_field_count(stmt) == 6);
485   mysql_stmt_close(stmt);
486 
487   /* show create function */
488   strmov(query, "SHOW CREATE FUNCTION e1;");
489   stmt= mysql_simple_prepare(mysql, query);
490   check_stmt(stmt);
491   DIE_UNLESS(mysql_stmt_field_count(stmt) == 6);
492   mysql_stmt_close(stmt);
493 
494   /* now fetch the results ..*/
495   rc= mysql_commit(mysql);
496   myquery(rc);
497 }
498 
499 /************************************************************************/
500 
501 #define FILE_PATH_SIZE 4096
502 
503 char mct_log_file_path[FILE_PATH_SIZE];
504 FILE *mct_log_file= NULL;
505 
mct_start_logging(const char * test_case_name)506 void mct_start_logging(const char *test_case_name)
507 {
508   const char *tmp_dir= getenv("MYSQL_TMP_DIR");
509 
510   if (!tmp_dir)
511   {
512     printf("Warning: MYSQL_TMP_DIR is not set. Logging is disabled.\n");
513     return;
514   }
515 
516   if (mct_log_file)
517   {
518     printf("Warning: can not start logging for test case '%s' "
519            "because log is already open\n",
520            (const char *) test_case_name);
521     return;
522   }
523 
524   /*
525     Path is: <tmp_dir>/<test_case_name>.out.log
526     10 is length of '/' + '.out.log' + \0
527   */
528 
529   if (strlen(tmp_dir) + strlen(test_case_name) + 10 > FILE_PATH_SIZE)
530   {
531     printf("Warning: MYSQL_TMP_DIR is too long. Logging is disabled.\n");
532     return;
533   }
534 
535   my_snprintf(mct_log_file_path, FILE_PATH_SIZE,
536               "%s/%s.out.log",
537               (const char *) tmp_dir,
538               (const char *) test_case_name);
539 
540   mct_log_file= my_fopen(mct_log_file_path, O_WRONLY | O_BINARY, MYF(MY_WME));
541 
542   if (!mct_log_file)
543   {
544     printf("Warning: can not open log file (%s): %s. Logging is disabled.\n",
545         (const char *) mct_log_file_path,
546         (const char *) strerror(errno));
547     return;
548   }
549 }
550 
mct_log(const char * format,...)551 void mct_log(const char *format, ...)
552 {
553   va_list args;
554   va_start(args, format);
555   vprintf(format, args);
556   va_end(args);
557 
558   if (mct_log_file)
559   {
560     va_list args;
561     va_start(args, format);
562     vfprintf(mct_log_file, format, args);
563     va_end(args);
564   }
565 }
566 
mct_close_log()567 void mct_close_log()
568 {
569   if (!mct_log_file)
570     return;
571 
572   my_fclose(mct_log_file, MYF(0));
573   mct_log_file= NULL;
574 }
575 
576 #define WL4435_NUM_PARAMS 10
577 #define WL4435_STRING_SIZE 30
578 
test_wl4435()579 static void test_wl4435()
580 {
581   MYSQL_STMT *stmt;
582   int        rc;
583   char query[MAX_TEST_QUERY_LENGTH];
584 
585   char       str_data[20][WL4435_STRING_SIZE];
586   double     dbl_data[20];
587   char       dec_data[20][WL4435_STRING_SIZE];
588   int        int_data[20];
589   ulong      str_length= WL4435_STRING_SIZE;
590   my_bool    is_null;
591   MYSQL_BIND ps_params[WL4435_NUM_PARAMS];
592 
593   int exec_counter;
594 
595   myheader("test_wl4435");
596   mct_start_logging("test_wl4435");
597 
598   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
599   myquery(rc);
600 
601   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p2");
602   myquery(rc);
603 
604   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
605   myquery(rc);
606 
607   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t2");
608   myquery(rc);
609 
610   rc= mysql_query(mysql, "CREATE TABLE t1(a1 INT, a2 CHAR(32), "
611                        "  a3 DOUBLE(4, 2), a4 DECIMAL(3, 1))");
612   myquery(rc);
613 
614   rc= mysql_query(mysql, "CREATE TABLE t2(b0 INT, b1 INT, b2 CHAR(32), "
615                        "  b3 DOUBLE(4, 2), b4 DECIMAL(3, 1))");
616   myquery(rc);
617 
618   rc= mysql_query(mysql, "INSERT INTO t1 VALUES"
619     "(1, '11', 12.34, 56.7), "
620     "(2, '12', 56.78, 90.1), "
621     "(3, '13', 23.45, 67.8)");
622   myquery(rc);
623 
624   rc= mysql_query(mysql, "INSERT INTO t2 VALUES"
625     "(100, 10, '110', 70.70, 10.1), "
626     "(200, 20, '120', 80.80, 20.2), "
627     "(300, 30, '130', 90.90, 30.3)");
628   myquery(rc);
629 
630   rc= mysql_query(mysql,
631     "CREATE PROCEDURE p1("
632     "   IN v0 INT, "
633     "   OUT v_str_1 CHAR(32), "
634     "   OUT v_dbl_1 DOUBLE(4, 2), "
635     "   OUT v_dec_1 DECIMAL(6, 3), "
636     "   OUT v_int_1 INT, "
637     "   IN v1 INT, "
638     "   INOUT v_str_2 CHAR(64), "
639     "   INOUT v_dbl_2 DOUBLE(5, 3), "
640     "   INOUT v_dec_2 DECIMAL(7, 4), "
641     "   INOUT v_int_2 INT)"
642     "BEGIN "
643     "   SET v0 = -1; "
644     "   SET v1 = -1; "
645     "   SET v_str_1 = 'test_1'; "
646     "   SET v_dbl_1 = 12.34; "
647     "   SET v_dec_1 = 567.891; "
648     "   SET v_int_1 = 2345; "
649     "   SET v_str_2 = 'test_2'; "
650     "   SET v_dbl_2 = 67.891; "
651     "   SET v_dec_2 = 234.6789; "
652     "   SET v_int_2 = 6789; "
653     "   SELECT * FROM t1; "
654     "   SELECT * FROM t2; "
655     "END");
656   myquery(rc);
657 
658   rc= mysql_query(mysql,
659     "CREATE PROCEDURE p2("
660     "   IN i1 VARCHAR(255) CHARACTER SET koi8r, "
661     "   OUT o1 VARCHAR(255) CHARACTER SET cp1251, "
662     "   OUT o2 VARBINARY(255)) "
663     "BEGIN "
664     "   SET o1 = i1; "
665     "   SET o2 = i1; "
666     "END");
667   myquery(rc);
668 
669   strmov(query, "CALL p1(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
670   stmt= mysql_simple_prepare(mysql, query);
671   check_stmt(stmt);
672 
673   /* Init PS-parameters. */
674 
675   bzero((char *) ps_params, sizeof (ps_params));
676 
677   /* - v0 -- INT */
678 
679   ps_params[0].buffer_type= MYSQL_TYPE_LONG;
680   ps_params[0].buffer= (char *) &int_data[0];
681   ps_params[0].length= 0;
682   ps_params[0].is_null= 0;
683 
684   /* - v_str_1 -- CHAR(32) */
685 
686   ps_params[1].buffer_type= MYSQL_TYPE_STRING;
687   ps_params[1].buffer= (char *) str_data[0];
688   ps_params[1].buffer_length= WL4435_STRING_SIZE;
689   ps_params[1].length= &str_length;
690   ps_params[1].is_null= 0;
691 
692   /* - v_dbl_1 -- DOUBLE */
693 
694   ps_params[2].buffer_type= MYSQL_TYPE_DOUBLE;
695   ps_params[2].buffer= (char *) &dbl_data[0];
696   ps_params[2].length= 0;
697   ps_params[2].is_null= 0;
698 
699   /* - v_dec_1 -- DECIMAL */
700 
701   ps_params[3].buffer_type= MYSQL_TYPE_NEWDECIMAL;
702   ps_params[3].buffer= (char *) dec_data[0];
703   ps_params[3].buffer_length= WL4435_STRING_SIZE;
704   ps_params[3].length= 0;
705   ps_params[3].is_null= 0;
706 
707   /* - v_int_1 -- INT */
708 
709   ps_params[4].buffer_type= MYSQL_TYPE_LONG;
710   ps_params[4].buffer= (char *) &int_data[0];
711   ps_params[4].length= 0;
712   ps_params[4].is_null= 0;
713 
714   /* - v1 -- INT */
715 
716   ps_params[5].buffer_type= MYSQL_TYPE_LONG;
717   ps_params[5].buffer= (char *) &int_data[0];
718   ps_params[5].length= 0;
719   ps_params[5].is_null= 0;
720 
721   /* - v_str_2 -- CHAR(32) */
722 
723   ps_params[6].buffer_type= MYSQL_TYPE_STRING;
724   ps_params[6].buffer= (char *) str_data[0];
725   ps_params[6].buffer_length= WL4435_STRING_SIZE;
726   ps_params[6].length= &str_length;
727   ps_params[6].is_null= 0;
728 
729   /* - v_dbl_2 -- DOUBLE */
730 
731   ps_params[7].buffer_type= MYSQL_TYPE_DOUBLE;
732   ps_params[7].buffer= (char *) &dbl_data[0];
733   ps_params[7].length= 0;
734   ps_params[7].is_null= 0;
735 
736   /* - v_dec_2 -- DECIMAL */
737 
738   ps_params[8].buffer_type= MYSQL_TYPE_DECIMAL;
739   ps_params[8].buffer= (char *) dec_data[0];
740   ps_params[8].buffer_length= WL4435_STRING_SIZE;
741   ps_params[8].length= 0;
742   ps_params[8].is_null= 0;
743 
744   /* - v_int_2 -- INT */
745 
746   ps_params[9].buffer_type= MYSQL_TYPE_LONG;
747   ps_params[9].buffer= (char *) &int_data[0];
748   ps_params[9].length= 0;
749   ps_params[9].is_null= 0;
750 
751   /* Bind parameters. */
752 
753   rc= mysql_stmt_bind_param(stmt, ps_params);
754 
755   /* Execute! */
756 
757   for (exec_counter= 0; exec_counter < 3; ++exec_counter)
758   {
759     int i;
760     int num_fields;
761     MYSQL_BIND *rs_bind;
762 
763     mct_log("\nexec_counter: %d\n", (int) exec_counter);
764 
765     rc= mysql_stmt_execute(stmt);
766     check_execute(stmt, rc);
767 
768     while (1)
769     {
770       MYSQL_FIELD *fields;
771 
772       MYSQL_RES *rs_metadata= mysql_stmt_result_metadata(stmt);
773 
774       num_fields= mysql_stmt_field_count(stmt);
775       fields= mysql_fetch_fields(rs_metadata);
776 
777       rs_bind= (MYSQL_BIND *) malloc(sizeof (MYSQL_BIND) * num_fields);
778       bzero(rs_bind, sizeof (MYSQL_BIND) * num_fields);
779 
780       mct_log("num_fields: %d\n", (int) num_fields);
781 
782       for (i = 0; i < num_fields; ++i)
783       {
784         mct_log("  - %d: name: '%s'/'%s'; table: '%s'/'%s'; "
785                 "db: '%s'; catalog: '%s'; length: %d; max_length: %d; "
786                 "type: %d; decimals: %d\n",
787                 (int) i,
788                 (const char *) fields[i].name,
789                 (const char *) fields[i].org_name,
790                 (const char *) fields[i].table,
791                 (const char *) fields[i].org_table,
792                 (const char *) fields[i].db,
793                 (const char *) fields[i].catalog,
794                 (int) fields[i].length,
795                 (int) fields[i].max_length,
796                 (int) fields[i].type,
797                 (int) fields[i].decimals);
798 
799         rs_bind[i].buffer_type= fields[i].type;
800         rs_bind[i].is_null= &is_null;
801 
802         switch (fields[i].type)
803         {
804           case MYSQL_TYPE_LONG:
805             rs_bind[i].buffer= (char *) &(int_data[i]);
806             rs_bind[i].buffer_length= sizeof (int_data);
807             break;
808 
809           case MYSQL_TYPE_STRING:
810             rs_bind[i].buffer= (char *) str_data[i];
811             rs_bind[i].buffer_length= WL4435_STRING_SIZE;
812             rs_bind[i].length= &str_length;
813             break;
814 
815           case MYSQL_TYPE_DOUBLE:
816             rs_bind[i].buffer= (char *) &dbl_data[i];
817             rs_bind[i].buffer_length= sizeof (dbl_data);
818             break;
819 
820           case MYSQL_TYPE_NEWDECIMAL:
821             rs_bind[i].buffer= (char *) dec_data[i];
822             rs_bind[i].buffer_length= WL4435_STRING_SIZE;
823             rs_bind[i].length= &str_length;
824             break;
825 
826           default:
827             fprintf(stderr, "ERROR: unexpected type: %d.\n", fields[i].type);
828             exit(1);
829         }
830       }
831 
832       rc= mysql_stmt_bind_result(stmt, rs_bind);
833       check_execute(stmt, rc);
834 
835       mct_log("Data:\n");
836 
837       while (1)
838       {
839         int rc= mysql_stmt_fetch(stmt);
840 
841         if (rc == 1 || rc == MYSQL_NO_DATA)
842           break;
843 
844         mct_log(" ");
845 
846         for (i = 0; i < num_fields; ++i)
847         {
848           switch (rs_bind[i].buffer_type)
849           {
850             case MYSQL_TYPE_LONG:
851               mct_log(" int: %ld;",
852                       (long) *((int *) rs_bind[i].buffer));
853               break;
854 
855             case MYSQL_TYPE_STRING:
856               mct_log(" str: '%s';",
857                       (char *) rs_bind[i].buffer);
858               break;
859 
860             case MYSQL_TYPE_DOUBLE:
861               mct_log(" dbl: %lf;",
862                       (double) *((double *) rs_bind[i].buffer));
863               break;
864 
865             case MYSQL_TYPE_NEWDECIMAL:
866               mct_log(" dec: '%s';",
867                       (char *) rs_bind[i].buffer);
868               break;
869 
870             default:
871               printf("  unexpected type (%d)\n",
872                 rs_bind[i].buffer_type);
873           }
874         }
875         mct_log("\n");
876       }
877 
878       mct_log("EOF\n");
879 
880       rc= mysql_stmt_next_result(stmt);
881       mct_log("mysql_stmt_next_result(): %d; field_count: %d\n",
882               (int) rc, (int) mysql->field_count);
883 
884       free(rs_bind);
885       mysql_free_result(rs_metadata);
886 
887       if (rc > 0)
888       {
889         printf("Error: %s (errno: %d)\n",
890                mysql_stmt_error(stmt), mysql_stmt_errno(stmt));
891         DIE(rc > 0);
892       }
893 
894       if (rc)
895         break;
896 
897       if (!mysql->field_count)
898       {
899         /* This is the last OK-packet. No more resultsets. */
900         break;
901       }
902     }
903 
904   }
905 
906   mysql_stmt_close(stmt);
907 
908   mct_close_log();
909 
910   rc= mysql_commit(mysql);
911   myquery(rc);
912 
913   /* i18n part of test case. */
914 
915   {
916     const char *str_koi8r= "\xee\xd5\x2c\x20\xda\xc1\x20\xd2\xd9\xc2\xc1\xcc\xcb\xd5";
917     const char *str_cp1251= "\xcd\xf3\x2c\x20\xe7\xe0\x20\xf0\xfb\xe1\xe0\xeb\xea\xf3";
918     char o1_buffer[255];
919     ulong o1_length;
920     char o2_buffer[255];
921     ulong o2_length;
922 
923     MYSQL_BIND rs_bind[2];
924 
925     strmov(query, "CALL p2(?, ?, ?)");
926     stmt= mysql_simple_prepare(mysql, query);
927     check_stmt(stmt);
928 
929     /* Init PS-parameters. */
930 
931     bzero((char *) ps_params, sizeof (ps_params));
932 
933     ps_params[0].buffer_type= MYSQL_TYPE_STRING;
934     ps_params[0].buffer= (char *) str_koi8r;
935     ps_params[0].buffer_length= strlen(str_koi8r);
936 
937     ps_params[1].buffer_type= MYSQL_TYPE_STRING;
938     ps_params[1].buffer= o1_buffer;
939     ps_params[1].buffer_length= 0;
940 
941     ps_params[2].buffer_type= MYSQL_TYPE_STRING;
942     ps_params[2].buffer= o2_buffer;
943     ps_params[2].buffer_length= 0;
944 
945     /* Bind parameters. */
946 
947     rc= mysql_stmt_bind_param(stmt, ps_params);
948     check_execute(stmt, rc);
949 
950     /* Prevent converting to character_set_results. */
951 
952     rc= mysql_query(mysql, "SET NAMES binary");
953     myquery(rc);
954 
955     /* Execute statement. */
956 
957     rc= mysql_stmt_execute(stmt);
958     check_execute(stmt, rc);
959 
960     /* Bind result. */
961 
962     bzero(rs_bind, sizeof (rs_bind));
963 
964     rs_bind[0].buffer_type= MYSQL_TYPE_STRING;
965     rs_bind[0].buffer= o1_buffer;
966     rs_bind[0].buffer_length= sizeof (o1_buffer);
967     rs_bind[0].length= &o1_length;
968 
969     rs_bind[1].buffer_type= MYSQL_TYPE_BLOB;
970     rs_bind[1].buffer= o2_buffer;
971     rs_bind[1].buffer_length= sizeof (o2_buffer);
972     rs_bind[1].length= &o2_length;
973 
974     rc= mysql_stmt_bind_result(stmt, rs_bind);
975     check_execute(stmt, rc);
976 
977     /* Fetch result. */
978 
979     rc= mysql_stmt_fetch(stmt);
980     check_execute(stmt, rc);
981 
982     /* Check result. */
983 
984     DIE_UNLESS(o1_length == strlen(str_cp1251));
985     DIE_UNLESS(o2_length == strlen(str_koi8r));
986     DIE_UNLESS(!memcmp(o1_buffer, str_cp1251, o1_length));
987     DIE_UNLESS(!memcmp(o2_buffer, str_koi8r, o2_length));
988 
989     rc= mysql_stmt_fetch(stmt);
990     DIE_UNLESS(rc == MYSQL_NO_DATA);
991 
992     rc= mysql_stmt_next_result(stmt);
993     DIE_UNLESS(rc == 0 && mysql->field_count == 0);
994 
995     mysql_stmt_close(stmt);
996 
997     rc= mysql_commit(mysql);
998     myquery(rc);
999   }
1000 }
1001 
test_wl4435_2()1002 static void test_wl4435_2()
1003 {
1004   MYSQL_STMT *stmt;
1005   int  i;
1006   int  rc;
1007   char query[MAX_TEST_QUERY_LENGTH];
1008 
1009   myheader("test_wl4435_2");
1010   mct_start_logging("test_wl4435_2");
1011 
1012   /*
1013     Do a few iterations so that we catch any problem with incorrect
1014     handling/flushing prepared statement results.
1015   */
1016 
1017   for (i= 0; i < 10; ++i)
1018   {
1019     /*
1020       Prepare a procedure. That can be moved out of the loop, but it was
1021       left in the loop for the sake of having as many statements as
1022       possible.
1023     */
1024 
1025     rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
1026     myquery(rc);
1027 
1028     rc= mysql_query(mysql,
1029       "CREATE PROCEDURE p1()"
1030       "BEGIN "
1031       "  SELECT 1; "
1032       "  SELECT 2, 3 UNION SELECT 4, 5; "
1033       "  SELECT 6, 7, 8; "
1034       "END");
1035     myquery(rc);
1036 
1037     /* Invoke a procedure, that returns several result sets. */
1038 
1039     strmov(query, "CALL p1()");
1040     stmt= mysql_simple_prepare(mysql, query);
1041     check_stmt(stmt);
1042 
1043     /* Execute! */
1044 
1045     rc= mysql_stmt_execute(stmt);
1046     check_execute(stmt, rc);
1047 
1048     /* Flush all the results. */
1049 
1050     mysql_stmt_close(stmt);
1051 
1052     /* Clean up. */
1053     rc= mysql_commit(mysql);
1054     myquery(rc);
1055 
1056     rc= mysql_query(mysql, "DROP PROCEDURE p1");
1057     myquery(rc);
1058   }
1059   mct_close_log();
1060 }
1061 
1062 
1063 #define WL4435_TEST(sql_type, sql_value, \
1064                     c_api_in_type, c_api_out_type, \
1065                     c_type, c_type_ext, \
1066                     printf_args, assert_condition) \
1067 \
1068   do { \
1069   int rc; \
1070   MYSQL_STMT *ps; \
1071   MYSQL_BIND psp; \
1072   MYSQL_RES *rs_metadata; \
1073   MYSQL_FIELD *fields; \
1074   c_type pspv c_type_ext; \
1075   my_bool psp_null; \
1076   \
1077   bzero(&pspv, sizeof (pspv)); \
1078   \
1079   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1"); \
1080   myquery(rc); \
1081   \
1082   rc= mysql_query(mysql, \
1083     "CREATE PROCEDURE p1(OUT v " sql_type ") SET v = " sql_value ";"); \
1084   myquery(rc); \
1085   \
1086   ps = mysql_simple_prepare(mysql, "CALL p1(?)"); \
1087   check_stmt(ps); \
1088   \
1089   bzero(&psp, sizeof (psp)); \
1090   psp.buffer_type= c_api_in_type; \
1091   psp.is_null= &psp_null; \
1092   psp.buffer= (char *) &pspv; \
1093   psp.buffer_length= sizeof (psp); \
1094   \
1095   rc= mysql_stmt_bind_param(ps, &psp); \
1096   check_execute(ps, rc); \
1097   \
1098   rc= mysql_stmt_execute(ps); \
1099   check_execute(ps, rc); \
1100   \
1101   DIE_UNLESS(mysql->server_status & SERVER_PS_OUT_PARAMS); \
1102   DIE_UNLESS(mysql_stmt_field_count(ps) == 1); \
1103   \
1104   rs_metadata= mysql_stmt_result_metadata(ps); \
1105   fields= mysql_fetch_fields(rs_metadata); \
1106   mysql_free_result(rs_metadata);               \
1107   \
1108   rc= mysql_stmt_bind_result(ps, &psp); \
1109   check_execute(ps, rc); \
1110   \
1111   rc= mysql_stmt_fetch(ps); \
1112   DIE_UNLESS(rc == 0); \
1113   \
1114   DIE_UNLESS(fields[0].type == c_api_out_type); \
1115   printf printf_args; \
1116   printf("; in type: %d; out type: %d\n", \
1117          (int) c_api_in_type, (int) c_api_out_type); \
1118   \
1119   rc= mysql_stmt_fetch(ps); \
1120   DIE_UNLESS(rc == MYSQL_NO_DATA); \
1121   \
1122   rc= mysql_stmt_next_result(ps); \
1123   DIE_UNLESS(rc == 0); \
1124   \
1125   mysql_stmt_free_result(ps); \
1126   mysql_stmt_close(ps); \
1127   \
1128   DIE_UNLESS(assert_condition); \
1129   \
1130   } while (0)
1131 
test_wl4435_3()1132 static void test_wl4435_3()
1133 {
1134   char tmp[255];
1135 
1136   puts("");
1137 
1138   /*
1139   // The following types are not supported:
1140   //   - ENUM
1141   //   - SET
1142   //
1143   // The following types are supported but can not be used for
1144   // OUT-parameters:
1145   //   - MEDIUMINT;
1146   //   - BIT(..);
1147   //
1148   // The problem is that those types are not supported for IN-parameters,
1149   // and OUT-parameters should be bound as IN-parameters before execution.
1150   //
1151   // The following types should not be used:
1152   //   - MYSQL_TYPE_YEAR (use MYSQL_TYPE_SHORT instead);
1153   //   - MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB
1154   //     (use MYSQL_TYPE_BLOB instead);
1155   */
1156 
1157   WL4435_TEST("TINYINT", "127",
1158               MYSQL_TYPE_TINY, MYSQL_TYPE_TINY,
1159               char, ,
1160               ("  - TINYINT / char / MYSQL_TYPE_TINY:\t\t\t %d", (int) pspv),
1161               pspv == 127);
1162 
1163   WL4435_TEST("SMALLINT", "32767",
1164               MYSQL_TYPE_SHORT, MYSQL_TYPE_SHORT,
1165               short, ,
1166               ("  - SMALLINT / short / MYSQL_TYPE_SHORT:\t\t %d", (int) pspv),
1167               pspv == 32767);
1168 
1169   WL4435_TEST("INT", "2147483647",
1170               MYSQL_TYPE_LONG, MYSQL_TYPE_LONG,
1171               int, ,
1172               ("  - INT / int / MYSQL_TYPE_LONG:\t\t\t %d", pspv),
1173               pspv == 2147483647l);
1174 
1175   WL4435_TEST("BIGINT", "9223372036854775807",
1176               MYSQL_TYPE_LONGLONG, MYSQL_TYPE_LONGLONG,
1177               long long, ,
1178               ("  - BIGINT / long long / MYSQL_TYPE_LONGLONG:\t\t %lld", pspv),
1179               pspv == 9223372036854775807ll);
1180 
1181   WL4435_TEST("TIMESTAMP", "'2007-11-18 15:01:02'",
1182               MYSQL_TYPE_TIMESTAMP, MYSQL_TYPE_TIMESTAMP,
1183               MYSQL_TIME, ,
1184               ("  - TIMESTAMP / MYSQL_TIME / MYSQL_TYPE_TIMESTAMP:\t "
1185                "%.4d-%.2d-%.2d %.2d:%.2d:%.2d",
1186                (int) pspv.year, (int) pspv.month, (int) pspv.day,
1187                (int) pspv.hour, (int) pspv.minute, (int) pspv.second),
1188               pspv.year == 2007 && pspv.month == 11 && pspv.day == 18 &&
1189               pspv.hour == 15 && pspv.minute == 1 && pspv.second == 2);
1190 
1191   WL4435_TEST("DATETIME", "'1234-11-12 12:34:59'",
1192               MYSQL_TYPE_DATETIME, MYSQL_TYPE_DATETIME,
1193               MYSQL_TIME, ,
1194               ("  - DATETIME / MYSQL_TIME / MYSQL_TYPE_DATETIME:\t "
1195                "%.4d-%.2d-%.2d %.2d:%.2d:%.2d",
1196                (int) pspv.year, (int) pspv.month, (int) pspv.day,
1197                (int) pspv.hour, (int) pspv.minute, (int) pspv.second),
1198               pspv.year == 1234 && pspv.month == 11 && pspv.day == 12 &&
1199               pspv.hour == 12 && pspv.minute == 34 && pspv.second == 59);
1200 
1201   WL4435_TEST("TIME", "'123:45:01'",
1202               MYSQL_TYPE_TIME, MYSQL_TYPE_TIME,
1203               MYSQL_TIME, ,
1204               ("  - TIME / MYSQL_TIME / MYSQL_TYPE_TIME:\t\t "
1205                "%.3d:%.2d:%.2d",
1206                (int) pspv.hour, (int) pspv.minute, (int) pspv.second),
1207               pspv.hour == 123 && pspv.minute == 45 && pspv.second == 1);
1208 
1209   WL4435_TEST("DATE", "'1234-11-12'",
1210               MYSQL_TYPE_DATE, MYSQL_TYPE_DATE,
1211               MYSQL_TIME, ,
1212               ("  - DATE / MYSQL_TIME / MYSQL_TYPE_DATE:\t\t "
1213                "%.4d-%.2d-%.2d",
1214                (int) pspv.year, (int) pspv.month, (int) pspv.day),
1215               pspv.year == 1234 && pspv.month == 11 && pspv.day == 12);
1216 
1217   WL4435_TEST("YEAR", "'2010'",
1218               MYSQL_TYPE_SHORT, MYSQL_TYPE_YEAR,
1219               short, ,
1220               ("  - YEAR / short / MYSQL_TYPE_SHORT:\t\t\t %.4d", (int) pspv),
1221               pspv == 2010);
1222 
1223   WL4435_TEST("FLOAT(7, 4)", "123.4567",
1224               MYSQL_TYPE_FLOAT, MYSQL_TYPE_FLOAT,
1225               float, ,
1226               ("  - FLOAT / float / MYSQL_TYPE_FLOAT:\t\t\t %g", (double) pspv),
1227               pspv - 123.4567 < 0.0001);
1228 
1229   WL4435_TEST("DOUBLE(8, 5)", "123.45678",
1230               MYSQL_TYPE_DOUBLE, MYSQL_TYPE_DOUBLE,
1231               double, ,
1232               ("  - DOUBLE / double / MYSQL_TYPE_DOUBLE:\t\t %g", (double) pspv),
1233               pspv - 123.45678 < 0.00001);
1234 
1235   WL4435_TEST("DECIMAL(9, 6)", "123.456789",
1236               MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_NEWDECIMAL,
1237               char, [255],
1238               ("  - DECIMAL / char[] / MYSQL_TYPE_NEWDECIMAL:\t\t '%s'", (char *) pspv),
1239               !strcmp(pspv, "123.456789"));
1240 
1241   WL4435_TEST("CHAR(32)", "REPEAT('C', 16)",
1242               MYSQL_TYPE_STRING, MYSQL_TYPE_STRING,
1243               char, [255],
1244               ("  - CHAR(32) / char[] / MYSQL_TYPE_STRING:\t\t '%s'", (char *) pspv),
1245               !strcmp(pspv, "CCCCCCCCCCCCCCCC"));
1246 
1247   WL4435_TEST("VARCHAR(32)", "REPEAT('V', 16)",
1248               MYSQL_TYPE_VAR_STRING, MYSQL_TYPE_VAR_STRING,
1249               char, [255],
1250               ("  - VARCHAR(32) / char[] / MYSQL_TYPE_VAR_STRING:\t '%s'", (char *) pspv),
1251               !strcmp(pspv, "VVVVVVVVVVVVVVVV"));
1252 
1253   WL4435_TEST("TINYTEXT", "REPEAT('t', 16)",
1254               MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_BLOB,
1255               char, [255],
1256               ("  - TINYTEXT / char[] / MYSQL_TYPE_TINY_BLOB:\t\t '%s'", (char *) pspv),
1257               !strcmp(pspv, "tttttttttttttttt"));
1258 
1259   WL4435_TEST("TEXT", "REPEAT('t', 16)",
1260               MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB,
1261               char, [255],
1262               ("  - TEXT / char[] / MYSQL_TYPE_BLOB:\t\t\t '%s'", (char *) pspv),
1263               !strcmp(pspv, "tttttttttttttttt"));
1264 
1265   WL4435_TEST("MEDIUMTEXT", "REPEAT('t', 16)",
1266               MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_BLOB,
1267               char, [255],
1268               ("  - MEDIUMTEXT / char[] / MYSQL_TYPE_MEDIUM_BLOB:\t '%s'", (char *) pspv),
1269               !strcmp(pspv, "tttttttttttttttt"));
1270 
1271   WL4435_TEST("LONGTEXT", "REPEAT('t', 16)",
1272               MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_BLOB,
1273               char, [255],
1274               ("  - LONGTEXT / char[] / MYSQL_TYPE_LONG_BLOB:\t\t '%s'", (char *) pspv),
1275               !strcmp(pspv, "tttttttttttttttt"));
1276 
1277   WL4435_TEST("BINARY(32)", "REPEAT('\1', 16)",
1278               MYSQL_TYPE_STRING, MYSQL_TYPE_STRING,
1279               char, [255],
1280               ("  - BINARY(32) / char[] / MYSQL_TYPE_STRING:\t\t '%s'", (char *) pspv),
1281               memset(tmp, 1, 16) && !memcmp(tmp, pspv, 16));
1282 
1283   WL4435_TEST("VARBINARY(32)", "REPEAT('\1', 16)",
1284               MYSQL_TYPE_VAR_STRING, MYSQL_TYPE_VAR_STRING,
1285               char, [255],
1286               ("  - VARBINARY(32) / char[] / MYSQL_TYPE_VAR_STRING:\t '%s'", (char *) pspv),
1287               memset(tmp, 1, 16) && !memcmp(tmp, pspv, 16));
1288 
1289   WL4435_TEST("TINYBLOB", "REPEAT('\2', 16)",
1290               MYSQL_TYPE_TINY_BLOB, MYSQL_TYPE_BLOB,
1291               char, [255],
1292               ("  - TINYBLOB / char[] / MYSQL_TYPE_TINY_BLOB:\t\t '%s'", (char *) pspv),
1293               memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16));
1294 
1295   WL4435_TEST("BLOB", "REPEAT('\2', 16)",
1296               MYSQL_TYPE_BLOB, MYSQL_TYPE_BLOB,
1297               char, [255],
1298               ("  - BLOB / char[] / MYSQL_TYPE_BLOB:\t\t\t '%s'", (char *) pspv),
1299               memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16));
1300 
1301   WL4435_TEST("MEDIUMBLOB", "REPEAT('\2', 16)",
1302               MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_BLOB,
1303               char, [255],
1304               ("  - MEDIUMBLOB / char[] / MYSQL_TYPE_MEDIUM_BLOB:\t '%s'", (char *) pspv),
1305               memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16));
1306 
1307   WL4435_TEST("LONGBLOB", "REPEAT('\2', 16)",
1308               MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_BLOB,
1309               char, [255],
1310               ("  - LONGBLOB / char[] / MYSQL_TYPE_LONG_BLOB:\t\t '%s'", (char *) pspv),
1311               memset(tmp, 2, 16) && !memcmp(tmp, pspv, 16));
1312 }
1313 
1314 
1315 /* Test simple prepare field results */
1316 
test_prepare_field_result()1317 static void test_prepare_field_result()
1318 {
1319   MYSQL_STMT *stmt;
1320   MYSQL_RES  *result;
1321   int        rc;
1322   char query[MAX_TEST_QUERY_LENGTH];
1323 
1324   myheader("test_prepare_field_result");
1325 
1326   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_field_result");
1327   myquery(rc);
1328 
1329   rc= mysql_query(mysql, "CREATE TABLE test_prepare_field_result(int_c int, "
1330                          "var_c varchar(50), ts_c timestamp, "
1331                          "char_c char(4), date_c date, extra tinyint)");
1332   myquery(rc);
1333 
1334   /* insert */
1335   strmov(query, "SELECT int_c, var_c, date_c as date, ts_c, char_c FROM "
1336                 " test_prepare_field_result as t1 WHERE int_c=?");
1337   stmt= mysql_simple_prepare(mysql, query);
1338   check_stmt(stmt);
1339 
1340   verify_param_count(stmt, 1);
1341 
1342   result= mysql_stmt_result_metadata(stmt);
1343   mytest(result);
1344 
1345   my_print_result_metadata(result);
1346 
1347   if (!opt_silent)
1348     fprintf(stdout, "\n\n field attributes:\n");
1349   verify_prepare_field(result, 0, "int_c", "int_c", MYSQL_TYPE_LONG,
1350                        "t1", "test_prepare_field_result", current_db, 11, 0);
1351   verify_prepare_field(result, 1, "var_c", "var_c", MYSQL_TYPE_VAR_STRING,
1352                        "t1", "test_prepare_field_result", current_db, 50, 0);
1353   verify_prepare_field(result, 2, "date", "date_c", MYSQL_TYPE_DATE,
1354                        "t1", "test_prepare_field_result", current_db, 10, 0);
1355   verify_prepare_field(result, 3, "ts_c", "ts_c", MYSQL_TYPE_TIMESTAMP,
1356                        "t1", "test_prepare_field_result", current_db, 19, 0);
1357   verify_prepare_field(result, 4, "char_c", "char_c",
1358                        (mysql_get_server_version(mysql) <= 50000 ?
1359                         MYSQL_TYPE_VAR_STRING : MYSQL_TYPE_STRING),
1360                        "t1", "test_prepare_field_result", current_db, 4, 0);
1361 
1362   verify_field_count(result, 5);
1363   mysql_free_result(result);
1364   mysql_stmt_close(stmt);
1365 }
1366 
1367 
1368 /* Test simple prepare field results */
1369 
test_prepare_syntax()1370 static void test_prepare_syntax()
1371 {
1372   MYSQL_STMT *stmt;
1373   int        rc;
1374   char query[MAX_TEST_QUERY_LENGTH];
1375 
1376   myheader("test_prepare_syntax");
1377 
1378   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_syntax");
1379   myquery(rc);
1380 
1381   rc= mysql_query(mysql, "CREATE TABLE test_prepare_syntax("
1382                          "id int, name varchar(50), extra int)");
1383   myquery(rc);
1384 
1385   strmov(query, "INSERT INTO test_prepare_syntax VALUES(?");
1386   stmt= mysql_simple_prepare(mysql, query);
1387   check_stmt_r(stmt);
1388 
1389   strmov(query, "SELECT id, name FROM test_prepare_syntax WHERE id=? AND WHERE");
1390   stmt= mysql_simple_prepare(mysql, query);
1391   check_stmt_r(stmt);
1392 
1393   /* now fetch the results ..*/
1394   rc= mysql_commit(mysql);
1395   myquery(rc);
1396 }
1397 
1398 
1399 /* Test a simple prepare */
1400 
test_prepare()1401 static void test_prepare()
1402 {
1403   MYSQL_STMT *stmt;
1404   int        rc, i;
1405   int        int_data, o_int_data;
1406   char       str_data[50], data[50];
1407   char       tiny_data, o_tiny_data;
1408   short      small_data, o_small_data;
1409   longlong   big_data, o_big_data;
1410   float      real_data, o_real_data;
1411   double     double_data, o_double_data;
1412   ulong      length[7], len;
1413   my_bool    is_null[7];
1414   char	     llbuf[22];
1415   MYSQL_BIND my_bind[7];
1416   char query[MAX_TEST_QUERY_LENGTH];
1417 
1418   myheader("test_prepare");
1419 
1420   rc= mysql_autocommit(mysql, TRUE);
1421   myquery(rc);
1422 
1423   rc= mysql_query(mysql, "DROP TABLE IF EXISTS my_prepare");
1424   myquery(rc);
1425 
1426   rc= mysql_query(mysql, "CREATE TABLE my_prepare(col1 tinyint, "
1427                          "col2 varchar(15), col3 int, "
1428                          "col4 smallint, col5 bigint, "
1429                          "col6 float, col7 double )");
1430   myquery(rc);
1431 
1432   /* insert by prepare */
1433   strxmov(query, "INSERT INTO my_prepare VALUES(?, ?, ?, ?, ?, ?, ?)", NullS);
1434   stmt= mysql_simple_prepare(mysql, query);
1435   check_stmt(stmt);
1436 
1437   verify_param_count(stmt, 7);
1438 
1439   bzero((char*) my_bind, sizeof(my_bind));
1440 
1441   /* tinyint */
1442   my_bind[0].buffer_type= MYSQL_TYPE_TINY;
1443   my_bind[0].buffer= (void *)&tiny_data;
1444   /* string */
1445   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
1446   my_bind[1].buffer= (void *)str_data;
1447   my_bind[1].buffer_length= 1000;                  /* Max string length */
1448   /* integer */
1449   my_bind[2].buffer_type= MYSQL_TYPE_LONG;
1450   my_bind[2].buffer= (void *)&int_data;
1451   /* short */
1452   my_bind[3].buffer_type= MYSQL_TYPE_SHORT;
1453   my_bind[3].buffer= (void *)&small_data;
1454   /* bigint */
1455   my_bind[4].buffer_type= MYSQL_TYPE_LONGLONG;
1456   my_bind[4].buffer= (void *)&big_data;
1457   /* float */
1458   my_bind[5].buffer_type= MYSQL_TYPE_FLOAT;
1459   my_bind[5].buffer= (void *)&real_data;
1460   /* double */
1461   my_bind[6].buffer_type= MYSQL_TYPE_DOUBLE;
1462   my_bind[6].buffer= (void *)&double_data;
1463 
1464   for (i= 0; i < (int) array_elements(my_bind); i++)
1465   {
1466     my_bind[i].length= &length[i];
1467     my_bind[i].is_null= &is_null[i];
1468     is_null[i]= 0;
1469   }
1470 
1471   rc= mysql_stmt_bind_param(stmt, my_bind);
1472   check_execute(stmt, rc);
1473 
1474   int_data= 320;
1475   small_data= 1867;
1476   big_data= 1000;
1477   real_data= 2;
1478   double_data= 6578.001;
1479 
1480   /* now, execute the prepared statement to insert 10 records.. */
1481   for (tiny_data= 0; tiny_data < 100; tiny_data++)
1482   {
1483     length[1]= sprintf(str_data, "MySQL%d", int_data);
1484     rc= mysql_stmt_execute(stmt);
1485     check_execute(stmt, rc);
1486     int_data += 25;
1487     small_data += 10;
1488     big_data += 100;
1489     real_data += 1;
1490     double_data += 10.09;
1491   }
1492 
1493   mysql_stmt_close(stmt);
1494 
1495   /* now fetch the results ..*/
1496   rc= mysql_commit(mysql);
1497   myquery(rc);
1498 
1499   /* test the results now, only one row should exist */
1500   rc= my_stmt_result("SELECT * FROM my_prepare");
1501   DIE_UNLESS(tiny_data == (char) rc);
1502 
1503   stmt= mysql_simple_prepare(mysql, "SELECT * FROM my_prepare");
1504   check_stmt(stmt);
1505 
1506   rc= mysql_stmt_bind_result(stmt, my_bind);
1507   check_execute(stmt, rc);
1508 
1509   /* get the result */
1510   rc= mysql_stmt_execute(stmt);
1511   check_execute(stmt, rc);
1512 
1513   o_int_data= 320;
1514   o_small_data= 1867;
1515   o_big_data= 1000;
1516   o_real_data= 2;
1517   o_double_data= 6578.001;
1518 
1519   /* now, execute the prepared statement to insert 10 records.. */
1520   for (o_tiny_data= 0; o_tiny_data < 100; o_tiny_data++)
1521   {
1522     len= sprintf(data, "MySQL%d", o_int_data);
1523 
1524     rc= mysql_stmt_fetch(stmt);
1525     check_execute(stmt, rc);
1526 
1527     if (!opt_silent)
1528     {
1529       fprintf(stdout, "\n");
1530       fprintf(stdout, "\n\t tiny   : %d (%lu)", tiny_data, length[0]);
1531       fprintf(stdout, "\n\t short  : %d (%lu)", small_data, length[3]);
1532       fprintf(stdout, "\n\t int    : %d (%lu)", int_data, length[2]);
1533       fprintf(stdout, "\n\t big    : %s (%lu)", llstr(big_data, llbuf),
1534               length[4]);
1535 
1536       fprintf(stdout, "\n\t float  : %f (%lu)", real_data, length[5]);
1537       fprintf(stdout, "\n\t double : %f (%lu)", double_data, length[6]);
1538 
1539       fprintf(stdout, "\n\t str    : %s (%lu)", str_data, length[1]);
1540     }
1541 
1542     DIE_UNLESS(tiny_data == o_tiny_data);
1543     DIE_UNLESS(is_null[0] == 0);
1544     DIE_UNLESS(length[0] == 1);
1545 
1546     DIE_UNLESS(int_data == o_int_data);
1547     DIE_UNLESS(length[2] == 4);
1548 
1549     DIE_UNLESS(small_data == o_small_data);
1550     DIE_UNLESS(length[3] == 2);
1551 
1552     DIE_UNLESS(big_data == o_big_data);
1553     DIE_UNLESS(length[4] == 8);
1554 
1555     DIE_UNLESS(real_data == o_real_data);
1556     DIE_UNLESS(length[5] == 4);
1557 
1558     DIE_UNLESS(cmp_double(&double_data, &o_double_data));
1559     DIE_UNLESS(length[6] == 8);
1560 
1561     DIE_UNLESS(strcmp(data, str_data) == 0);
1562     DIE_UNLESS(length[1] == len);
1563 
1564     o_int_data += 25;
1565     o_small_data += 10;
1566     o_big_data += 100;
1567     o_real_data += 1;
1568     o_double_data += 10.09;
1569   }
1570 
1571   rc= mysql_stmt_fetch(stmt);
1572   DIE_UNLESS(rc == MYSQL_NO_DATA);
1573 
1574   mysql_stmt_close(stmt);
1575 
1576 }
1577 
1578 
1579 /* Test double comparision */
1580 
test_double_compare()1581 static void test_double_compare()
1582 {
1583   MYSQL_STMT *stmt;
1584   int        rc;
1585   char       real_data[10], tiny_data;
1586   double     double_data;
1587   MYSQL_RES  *result;
1588   MYSQL_BIND my_bind[3];
1589   ulong      length[3];
1590   char query[MAX_TEST_QUERY_LENGTH];
1591 
1592   myheader("test_double_compare");
1593 
1594   rc= mysql_autocommit(mysql, TRUE);
1595   myquery(rc);
1596 
1597   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_double_compare");
1598   myquery(rc);
1599 
1600   rc= mysql_query(mysql, "CREATE TABLE test_double_compare(col1 tinyint, "
1601                          " col2 float, col3 double )");
1602   myquery(rc);
1603 
1604   rc= mysql_query(mysql, "INSERT INTO test_double_compare "
1605                          "VALUES (1, 10.2, 34.5)");
1606   myquery(rc);
1607 
1608   strmov(query, "UPDATE test_double_compare SET col1=100 "
1609                 "WHERE col1 = ? AND col2 = ? AND COL3 = ?");
1610   stmt= mysql_simple_prepare(mysql, query);
1611   check_stmt(stmt);
1612 
1613   verify_param_count(stmt, 3);
1614 
1615   /* Always bzero bind array because there can be internal members */
1616   bzero((char*) my_bind, sizeof(my_bind));
1617 
1618   /* tinyint */
1619   my_bind[0].buffer_type= MYSQL_TYPE_TINY;
1620   my_bind[0].buffer= (void *)&tiny_data;
1621 
1622   /* string->float */
1623   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
1624   my_bind[1].buffer= (void *)&real_data;
1625   my_bind[1].buffer_length= sizeof(real_data);
1626   my_bind[1].length= &length[1];
1627   length[1]= 10;
1628 
1629   /* double */
1630   my_bind[2].buffer_type= MYSQL_TYPE_DOUBLE;
1631   my_bind[2].buffer= (void *)&double_data;
1632 
1633   tiny_data= 1;
1634   strmov(real_data, "10.2");
1635   double_data= 34.5;
1636   rc= mysql_stmt_bind_param(stmt, my_bind);
1637   check_execute(stmt, rc);
1638 
1639   rc= mysql_stmt_execute(stmt);
1640   check_execute(stmt, rc);
1641 
1642   verify_affected_rows(0);
1643 
1644   mysql_stmt_close(stmt);
1645 
1646   /* now fetch the results ..*/
1647   rc= mysql_commit(mysql);
1648   myquery(rc);
1649 
1650   /* test the results now, only one row should exist */
1651   rc= mysql_query(mysql, "SELECT * FROM test_double_compare");
1652   myquery(rc);
1653 
1654   /* get the result */
1655   result= mysql_store_result(mysql);
1656   mytest(result);
1657 
1658   rc= my_process_result_set(result);
1659   DIE_UNLESS((int)tiny_data == rc);
1660   mysql_free_result(result);
1661 }
1662 
1663 
1664 /* Test simple null */
1665 
test_null()1666 static void test_null()
1667 {
1668   MYSQL_STMT *stmt;
1669   int        rc;
1670   uint       nData;
1671   MYSQL_BIND my_bind[2];
1672   my_bool    is_null[2];
1673   char query[MAX_TEST_QUERY_LENGTH];
1674 
1675   myheader("test_null");
1676 
1677   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_null");
1678   myquery(rc);
1679 
1680   rc= mysql_query(mysql, "CREATE TABLE test_null(col1 int, col2 varchar(50))");
1681   myquery(rc);
1682 
1683   /* insert by prepare, wrong column name */
1684   strmov(query, "INSERT INTO test_null(col3, col2) VALUES(?, ?)");
1685   stmt= mysql_simple_prepare(mysql, query);
1686   check_stmt_r(stmt);
1687 
1688   strmov(query, "INSERT INTO test_null(col1, col2) VALUES(?, ?)");
1689   stmt= mysql_simple_prepare(mysql, query);
1690   check_stmt(stmt);
1691 
1692   verify_param_count(stmt, 2);
1693 
1694   /* Always bzero all members of bind parameter */
1695   bzero((char*) my_bind, sizeof(my_bind));
1696 
1697   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
1698   my_bind[0].is_null= &is_null[0];
1699   is_null[0]= 1;
1700   my_bind[1]= my_bind[0];
1701 
1702   rc= mysql_stmt_bind_param(stmt, my_bind);
1703   check_execute(stmt, rc);
1704 
1705   /* now, execute the prepared statement to insert 10 records.. */
1706   for (nData= 0; nData<10; nData++)
1707   {
1708     rc= mysql_stmt_execute(stmt);
1709     check_execute(stmt, rc);
1710   }
1711 
1712   /* Re-bind with MYSQL_TYPE_NULL */
1713   my_bind[0].buffer_type= MYSQL_TYPE_NULL;
1714   is_null[0]= 0; /* reset */
1715   my_bind[1]= my_bind[0];
1716 
1717   rc= mysql_stmt_bind_param(stmt, my_bind);
1718   check_execute(stmt, rc);
1719 
1720   for (nData= 0; nData<10; nData++)
1721   {
1722     rc= mysql_stmt_execute(stmt);
1723     check_execute(stmt, rc);
1724   }
1725 
1726   mysql_stmt_close(stmt);
1727 
1728   /* now fetch the results ..*/
1729   rc= mysql_commit(mysql);
1730   myquery(rc);
1731 
1732   nData*= 2;
1733   rc= my_stmt_result("SELECT * FROM test_null");;
1734   DIE_UNLESS((int) nData == rc);
1735 
1736   /* Fetch results */
1737   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
1738   my_bind[0].buffer= (void *)&nData; /* this buffer won't be altered */
1739   my_bind[0].length= 0;
1740   my_bind[1]= my_bind[0];
1741   my_bind[0].is_null= &is_null[0];
1742   my_bind[1].is_null= &is_null[1];
1743 
1744   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_null");
1745   check_stmt(stmt);
1746 
1747   rc= mysql_stmt_execute(stmt);
1748   check_execute(stmt, rc);
1749 
1750   rc= mysql_stmt_bind_result(stmt, my_bind);
1751   check_execute(stmt, rc);
1752 
1753   rc= 0;
1754   is_null[0]= is_null[1]= 0;
1755   while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
1756   {
1757     DIE_UNLESS(is_null[0]);
1758     DIE_UNLESS(is_null[1]);
1759     rc++;
1760     is_null[0]= is_null[1]= 0;
1761   }
1762   DIE_UNLESS(rc == (int) nData);
1763   mysql_stmt_close(stmt);
1764 }
1765 
1766 
1767 /* Test for NULL as PS parameter (BUG#3367, BUG#3371) */
1768 
test_ps_null_param()1769 static void test_ps_null_param()
1770 {
1771   MYSQL_STMT *stmt;
1772   int        rc;
1773 
1774   MYSQL_BIND in_bind;
1775   my_bool    in_is_null;
1776   long int   in_long;
1777 
1778   MYSQL_BIND out_bind;
1779   ulong      out_length;
1780   my_bool    out_is_null;
1781   char       out_str_data[20];
1782 
1783   const char *queries[]= {"select ?", "select ?+1",
1784                     "select col1 from test_ps_nulls where col1 <=> ?",
1785                     NULL
1786                     };
1787   const char **cur_query= queries;
1788 
1789   myheader("test_null_ps_param_in_result");
1790 
1791   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_ps_nulls");
1792   myquery(rc);
1793 
1794   rc= mysql_query(mysql, "CREATE TABLE test_ps_nulls(col1 int)");
1795   myquery(rc);
1796 
1797   rc= mysql_query(mysql, "INSERT INTO test_ps_nulls values (1), (null)");
1798   myquery(rc);
1799 
1800   /* Always bzero all members of bind parameter */
1801   bzero((char*) &in_bind, sizeof(in_bind));
1802   bzero((char*) &out_bind, sizeof(out_bind));
1803 
1804   in_bind.buffer_type= MYSQL_TYPE_LONG;
1805   in_bind.is_null= &in_is_null;
1806   in_bind.length= 0;
1807   in_bind.buffer= (void *)&in_long;
1808   in_is_null= 1;
1809   in_long= 1;
1810 
1811   out_bind.buffer_type= MYSQL_TYPE_STRING;
1812   out_bind.is_null= &out_is_null;
1813   out_bind.length= &out_length;
1814   out_bind.buffer= out_str_data;
1815   out_bind.buffer_length= array_elements(out_str_data);
1816 
1817   /* Execute several queries, all returning NULL in result. */
1818   for(cur_query= queries; *cur_query; cur_query++)
1819   {
1820     char query[MAX_TEST_QUERY_LENGTH];
1821     strmov(query, *cur_query);
1822     stmt= mysql_simple_prepare(mysql, query);
1823     check_stmt(stmt);
1824     verify_param_count(stmt, 1);
1825 
1826     rc= mysql_stmt_bind_param(stmt, &in_bind);
1827     check_execute(stmt, rc);
1828     rc= mysql_stmt_bind_result(stmt, &out_bind);
1829     check_execute(stmt, rc);
1830     rc= mysql_stmt_execute(stmt);
1831     check_execute(stmt, rc);
1832     rc= mysql_stmt_fetch(stmt);
1833     DIE_UNLESS(rc != MYSQL_NO_DATA);
1834     DIE_UNLESS(out_is_null);
1835     rc= mysql_stmt_fetch(stmt);
1836     DIE_UNLESS(rc == MYSQL_NO_DATA);
1837     mysql_stmt_close(stmt);
1838   }
1839 }
1840 
1841 
1842 /* Test fetch null */
1843 
test_fetch_null()1844 static void test_fetch_null()
1845 {
1846   MYSQL_STMT *stmt;
1847   int        rc;
1848   int        i, nData;
1849   MYSQL_BIND my_bind[11];
1850   ulong      length[11];
1851   my_bool    is_null[11];
1852   char query[MAX_TEST_QUERY_LENGTH];
1853 
1854   myheader("test_fetch_null");
1855 
1856   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_fetch_null");
1857   myquery(rc);
1858 
1859   rc= mysql_query(mysql, "CREATE TABLE test_fetch_null("
1860                          " col1 tinyint, col2 smallint, "
1861                          " col3 int, col4 bigint, "
1862                          " col5 float, col6 double, "
1863                          " col7 date, col8 time, "
1864                          " col9 varbinary(10), "
1865                          " col10 varchar(50), "
1866                          " col11 char(20))");
1867   myquery(rc);
1868 
1869   rc= mysql_query(mysql, "INSERT INTO test_fetch_null (col11) "
1870                          "VALUES (1000), (88), (389789)");
1871   myquery(rc);
1872 
1873   rc= mysql_commit(mysql);
1874   myquery(rc);
1875 
1876   /* fetch */
1877   bzero((char*) my_bind, sizeof(my_bind));
1878   for (i= 0; i < (int) array_elements(my_bind); i++)
1879   {
1880     my_bind[i].buffer_type= MYSQL_TYPE_LONG;
1881     my_bind[i].is_null= &is_null[i];
1882     my_bind[i].length= &length[i];
1883   }
1884   my_bind[i-1].buffer= (void *)&nData;              /* Last column is not null */
1885 
1886   strmov((char *)query , "SELECT * FROM test_fetch_null");
1887 
1888   rc= my_stmt_result(query);
1889   DIE_UNLESS(rc == 3);
1890 
1891   stmt= mysql_simple_prepare(mysql, query);
1892   check_stmt(stmt);
1893 
1894   rc= mysql_stmt_bind_result(stmt, my_bind);
1895   check_execute(stmt, rc);
1896 
1897   rc= mysql_stmt_execute(stmt);
1898   check_execute(stmt, rc);
1899 
1900   rc= 0;
1901   while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
1902   {
1903     rc++;
1904     for (i= 0; i < 10; i++)
1905     {
1906       if (!opt_silent)
1907         fprintf(stdout, "\n data[%d] : %s", i,
1908                 is_null[i] ? "NULL" : "NOT NULL");
1909       DIE_UNLESS(is_null[i]);
1910     }
1911     if (!opt_silent)
1912       fprintf(stdout, "\n data[%d]: %d", i, nData);
1913     DIE_UNLESS(nData == 1000 || nData == 88 || nData == 389789);
1914     DIE_UNLESS(is_null[i] == 0);
1915     DIE_UNLESS(length[i] == 4);
1916   }
1917   DIE_UNLESS(rc == 3);
1918   mysql_stmt_close(stmt);
1919 }
1920 
1921 
1922 /* Test simple select */
1923 
test_select_version()1924 static void test_select_version()
1925 {
1926   MYSQL_STMT *stmt;
1927   int        rc;
1928 
1929   myheader("test_select_version");
1930 
1931   stmt= mysql_simple_prepare(mysql, "SELECT @@version");
1932   check_stmt(stmt);
1933 
1934   verify_param_count(stmt, 0);
1935 
1936   rc= mysql_stmt_execute(stmt);
1937   check_execute(stmt, rc);
1938 
1939   my_process_stmt_result(stmt);
1940   mysql_stmt_close(stmt);
1941 }
1942 
1943 
1944 /* Test simple show */
1945 
test_select_show_table()1946 static void test_select_show_table()
1947 {
1948   MYSQL_STMT *stmt;
1949   int        rc, i;
1950 
1951   myheader("test_select_show_table");
1952 
1953   stmt= mysql_simple_prepare(mysql, "SHOW TABLES FROM mysql");
1954   check_stmt(stmt);
1955 
1956   verify_param_count(stmt, 0);
1957 
1958   for (i= 1; i < 3; i++)
1959   {
1960     rc= mysql_stmt_execute(stmt);
1961     check_execute(stmt, rc);
1962   }
1963 
1964   my_process_stmt_result(stmt);
1965   mysql_stmt_close(stmt);
1966 }
1967 
1968 
1969 /* Test simple select to debug */
1970 
test_select_direct()1971 static void test_select_direct()
1972 {
1973   int        rc;
1974   MYSQL_RES  *result;
1975 
1976   myheader("test_select_direct");
1977 
1978   rc= mysql_autocommit(mysql, TRUE);
1979   myquery(rc);
1980 
1981   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
1982   myquery(rc);
1983 
1984   rc= mysql_query(mysql, "CREATE TABLE test_select(id int, id1 tinyint, "
1985                                                  " id2 float, "
1986                                                  " id3 double, "
1987                                                  " name varchar(50))");
1988   myquery(rc);
1989 
1990   /* insert a row and commit the transaction */
1991   rc= mysql_query(mysql, "INSERT INTO test_select VALUES(10, 5, 2.3, 4.5, 'venu')");
1992   myquery(rc);
1993 
1994   rc= mysql_commit(mysql);
1995   myquery(rc);
1996 
1997   rc= mysql_query(mysql, "SELECT * FROM test_select");
1998   myquery(rc);
1999 
2000   /* get the result */
2001   result= mysql_store_result(mysql);
2002   mytest(result);
2003 
2004   (void) my_process_result_set(result);
2005   mysql_free_result(result);
2006 }
2007 
2008 
2009 /* Test simple select with prepare */
2010 
test_select_prepare()2011 static void test_select_prepare()
2012 {
2013   int        rc;
2014   MYSQL_STMT *stmt;
2015 
2016   myheader("test_select_prepare");
2017 
2018   rc= mysql_autocommit(mysql, TRUE);
2019   myquery(rc);
2020 
2021   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
2022   myquery(rc);
2023 
2024   rc= mysql_query(mysql, "CREATE TABLE test_select(id int, name varchar(50))");
2025   myquery(rc);
2026 
2027   /* insert a row and commit the transaction */
2028   rc= mysql_query(mysql, "INSERT INTO test_select VALUES(10, 'venu')");
2029   myquery(rc);
2030 
2031   rc= mysql_commit(mysql);
2032   myquery(rc);
2033 
2034   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_select");
2035   check_stmt(stmt);
2036 
2037   rc= mysql_stmt_execute(stmt);
2038   check_execute(stmt, rc);
2039 
2040   rc= my_process_stmt_result(stmt);
2041   DIE_UNLESS(rc == 1);
2042   mysql_stmt_close(stmt);
2043 
2044   rc= mysql_query(mysql, "DROP TABLE test_select");
2045   myquery(rc);
2046 
2047   rc= mysql_query(mysql, "CREATE TABLE test_select(id tinyint, id1 int, "
2048                                                 "  id2 float, id3 float, "
2049                                                 "  name varchar(50))");
2050   myquery(rc);
2051 
2052   /* insert a row and commit the transaction */
2053   rc= mysql_query(mysql, "INSERT INTO test_select(id, id1, id2, name) VALUES(10, 5, 2.3, 'venu')");
2054   myquery(rc);
2055 
2056   rc= mysql_commit(mysql);
2057   myquery(rc);
2058 
2059   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_select");
2060   check_stmt(stmt);
2061 
2062   rc= mysql_stmt_execute(stmt);
2063   check_execute(stmt, rc);
2064 
2065   rc= my_process_stmt_result(stmt);
2066   DIE_UNLESS(rc == 1);
2067   mysql_stmt_close(stmt);
2068 }
2069 
2070 
2071 /* Test simple select */
2072 
test_select()2073 static void test_select()
2074 {
2075   MYSQL_STMT *stmt;
2076   int        rc;
2077   char       szData[25];
2078   int        nData= 1;
2079   MYSQL_BIND my_bind[2];
2080   ulong length[2];
2081   char query[MAX_TEST_QUERY_LENGTH];
2082 
2083   myheader("test_select");
2084 
2085   rc= mysql_autocommit(mysql, TRUE);
2086   myquery(rc);
2087 
2088   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
2089   myquery(rc);
2090 
2091   rc= mysql_query(mysql, "CREATE TABLE test_select(id int, name varchar(50))");
2092   myquery(rc);
2093 
2094   /* insert a row and commit the transaction */
2095   rc= mysql_query(mysql, "INSERT INTO test_select VALUES(10, 'venu')");
2096   myquery(rc);
2097 
2098   /* now insert the second row, and roll back the transaction */
2099   rc= mysql_query(mysql, "INSERT INTO test_select VALUES(20, 'mysql')");
2100   myquery(rc);
2101 
2102   rc= mysql_commit(mysql);
2103   myquery(rc);
2104 
2105   strmov(query, "SELECT * FROM test_select WHERE id= ? "
2106                 "AND CONVERT(name USING utf8) =?");
2107   stmt= mysql_simple_prepare(mysql, query);
2108   check_stmt(stmt);
2109 
2110   verify_param_count(stmt, 2);
2111 
2112   /* Always bzero all members of bind parameter */
2113   bzero((char*) my_bind, sizeof(my_bind));
2114 
2115   /* string data */
2116   nData= 10;
2117   strmov(szData, (char *)"venu");
2118   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
2119   my_bind[1].buffer= (void *)szData;
2120   my_bind[1].buffer_length= 4;
2121   my_bind[1].length= &length[1];
2122   length[1]= 4;
2123 
2124   my_bind[0].buffer= (void *)&nData;
2125   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
2126 
2127   rc= mysql_stmt_bind_param(stmt, my_bind);
2128   check_execute(stmt, rc);
2129 
2130   rc= mysql_stmt_execute(stmt);
2131   check_execute(stmt, rc);
2132 
2133   rc= my_process_stmt_result(stmt);
2134   DIE_UNLESS(rc == 1);
2135 
2136   mysql_stmt_close(stmt);
2137 }
2138 
2139 
2140 /*
2141   Test for BUG#3420 ("select id1, value1 from t where id= ? or value= ?"
2142   returns all rows in the table)
2143 */
2144 
test_ps_conj_select()2145 static void test_ps_conj_select()
2146 {
2147   MYSQL_STMT *stmt;
2148   int        rc;
2149   MYSQL_BIND my_bind[2];
2150   int32      int_data;
2151   char       str_data[32];
2152   unsigned long str_length;
2153   char query[MAX_TEST_QUERY_LENGTH];
2154   myheader("test_ps_conj_select");
2155 
2156   rc= mysql_query(mysql, "drop table if exists t1");
2157   myquery(rc);
2158 
2159   rc= mysql_query(mysql, "create table t1 (id1 int(11) NOT NULL default '0', "
2160                          "value2 varchar(100), value1 varchar(100))");
2161   myquery(rc);
2162 
2163   rc= mysql_query(mysql, "insert into t1 values (1, 'hh', 'hh'), "
2164                           "(2, 'hh', 'hh'), (1, 'ii', 'ii'), (2, 'ii', 'ii')");
2165   myquery(rc);
2166 
2167   strmov(query, "SELECT id1, value1 from t1 where id1= ? or "
2168                 "CONVERT(value1 USING utf8)= ?");
2169   stmt= mysql_simple_prepare(mysql, query);
2170   check_stmt(stmt);
2171 
2172   verify_param_count(stmt, 2);
2173 
2174   /* Always bzero all members of bind parameter */
2175   bzero((char*) my_bind, sizeof(my_bind));
2176 
2177   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
2178   my_bind[0].buffer= (void *)&int_data;
2179 
2180   my_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
2181   my_bind[1].buffer= (void *)str_data;
2182   my_bind[1].buffer_length= array_elements(str_data);
2183   my_bind[1].length= &str_length;
2184 
2185   rc= mysql_stmt_bind_param(stmt, my_bind);
2186   check_execute(stmt, rc);
2187 
2188   int_data= 1;
2189   strmov(str_data, "hh");
2190   str_length= strlen(str_data);
2191 
2192   rc= mysql_stmt_execute(stmt);
2193   check_execute(stmt, rc);
2194 
2195   rc= my_process_stmt_result(stmt);
2196   DIE_UNLESS(rc == 3);
2197 
2198   mysql_stmt_close(stmt);
2199 }
2200 
2201 
2202 /* reads Qcache_hits from server and returns its value */
query_cache_hits(MYSQL * conn)2203 static uint query_cache_hits(MYSQL *conn)
2204 {
2205   MYSQL_RES *res;
2206   MYSQL_ROW row;
2207   int rc;
2208   uint result;
2209 
2210   rc= mysql_query(conn, "show status like 'qcache_hits'");
2211   myquery(rc);
2212   res= mysql_use_result(conn);
2213   DIE_UNLESS(res);
2214 
2215   row= mysql_fetch_row(res);
2216   DIE_UNLESS(row);
2217 
2218   result= atoi(row[1]);
2219   mysql_free_result(res);
2220   return result;
2221 }
2222 
2223 
2224 /*
2225   utility for the next test; expects 3 rows in the result from a SELECT,
2226   compares each row/field with an expected value.
2227  */
2228 #define test_ps_query_cache_result(i1,s1,l1,i2,s2,l2,i3,s3,l3)    \
2229   r_metadata= mysql_stmt_result_metadata(stmt);                   \
2230   DIE_UNLESS(r_metadata != NULL);                                 \
2231   rc= mysql_stmt_fetch(stmt);                                     \
2232   check_execute(stmt, rc);                                        \
2233   if (!opt_silent)                                                \
2234     fprintf(stdout, "\n row 1: %d, %s(%lu)", r_int_data,          \
2235             r_str_data, r_str_length);                            \
2236   DIE_UNLESS((r_int_data == i1) && (r_str_length == l1) &&        \
2237              (strcmp(r_str_data, s1) == 0));                      \
2238   rc= mysql_stmt_fetch(stmt);                                     \
2239   check_execute(stmt, rc);                                        \
2240   if (!opt_silent)                                                \
2241     fprintf(stdout, "\n row 2: %d, %s(%lu)", r_int_data,          \
2242             r_str_data, r_str_length);                            \
2243   DIE_UNLESS((r_int_data == i2) && (r_str_length == l2) &&        \
2244              (strcmp(r_str_data, s2) == 0));                      \
2245   rc= mysql_stmt_fetch(stmt);                                     \
2246   check_execute(stmt, rc);                                        \
2247   if (!opt_silent)                                                \
2248     fprintf(stdout, "\n row 3: %d, %s(%lu)", r_int_data,          \
2249             r_str_data, r_str_length);                            \
2250   DIE_UNLESS((r_int_data == i3) && (r_str_length == l3) &&        \
2251              (strcmp(r_str_data, s3) == 0));                      \
2252   rc= mysql_stmt_fetch(stmt);                                     \
2253   DIE_UNLESS(rc == MYSQL_NO_DATA);                                \
2254   mysql_free_result(r_metadata);
2255 
2256 
2257 /*
2258   Check that query cache is available in server.
2259 */
is_query_cache_available()2260 static my_bool is_query_cache_available()
2261 {
2262   int rc;
2263   MYSQL_RES *result;
2264   MYSQL_ROW row;
2265   int res= -1;
2266 
2267   rc= mysql_query(mysql, "SHOW VARIABLES LIKE 'have_query_cache'");
2268   myquery(rc);
2269 
2270   result= mysql_store_result(mysql);
2271   DIE_UNLESS(result);
2272 
2273   row= mysql_fetch_row(result);
2274   DIE_UNLESS(row != NULL);
2275   if (strcmp(row[1], "YES") == 0)
2276     res= 1;
2277   else if (strcmp(row[1], "NO") == 0)
2278     res= 0;
2279   mysql_free_result(result);
2280 
2281   DIE_UNLESS(res == 0 || res == 1);
2282   return res;
2283 }
2284 
2285 /*
2286   Test that prepared statements make use of the query cache just as normal
2287   statements (BUG#735).
2288 */
test_ps_query_cache()2289 static void test_ps_query_cache()
2290 {
2291   MYSQL      *lmysql= mysql;
2292   MYSQL_STMT *stmt;
2293   int        rc;
2294   MYSQL_BIND p_bind[2],r_bind[2]; /* p: param bind; r: result bind */
2295   int32      p_int_data, r_int_data;
2296   char       p_str_data[32], r_str_data[32];
2297   unsigned long p_str_length, r_str_length;
2298   MYSQL_RES  *r_metadata;
2299   char       query[MAX_TEST_QUERY_LENGTH];
2300   uint       hits1, hits2;
2301   enum enum_test_ps_query_cache
2302   {
2303     /*
2304       We iterate the same prepare/executes block, but have iterations where
2305       we vary the query cache conditions.
2306     */
2307     /* the query cache is enabled for the duration of prep&execs: */
2308     TEST_QCACHE_ON= 0,
2309     /*
2310       same but using a new connection (to see if qcache serves results from
2311       the previous connection as it should):
2312     */
2313     TEST_QCACHE_ON_WITH_OTHER_CONN,
2314     /*
2315       First border case: disables the query cache before prepare and
2316       re-enables it before execution (to test if we have no bug then):
2317     */
2318     TEST_QCACHE_OFF_ON,
2319     /*
2320       Second border case: enables the query cache before prepare and
2321       disables it before execution:
2322     */
2323     TEST_QCACHE_ON_OFF
2324   };
2325   enum enum_test_ps_query_cache iteration;
2326 
2327   myheader("test_ps_query_cache");
2328 
2329   if (! is_query_cache_available())
2330   {
2331     fprintf(stdout, "Skipping test_ps_query_cache: Query cache not available.\n");
2332     return;
2333   }
2334 
2335   rc= mysql_set_character_set(mysql, "utf8");
2336   myquery(rc);
2337 
2338   /* prepare the table */
2339 
2340   rc= mysql_query(mysql, "drop table if exists t1");
2341   myquery(rc);
2342 
2343   rc= mysql_query(mysql, "create table t1 (id1 int(11) NOT NULL default '0', "
2344                          "value2 varchar(100), value1 varchar(100))");
2345   myquery(rc);
2346 
2347   rc= mysql_query(mysql, "insert into t1 values (1, 'hh', 'hh'), "
2348                           "(2, 'hh', 'hh'), (1, 'ii', 'ii'), (2, 'ii', 'ii')");
2349   myquery(rc);
2350 
2351   rc= mysql_query(mysql,
2352                   "set @save_query_cache_type="
2353                   "@@global.query_cache_type,"
2354                   "@save_query_cache_size="
2355                   "@@global.query_cache_size");
2356   myquery(rc);
2357   rc= mysql_query(lmysql, "set global query_cache_type=ON");
2358   myquery(rc);
2359   rc= mysql_query(lmysql, "set local query_cache_type=ON");
2360   myquery(rc);
2361 
2362   for (iteration= TEST_QCACHE_ON; iteration <= TEST_QCACHE_ON_OFF; iteration++)
2363   {
2364 
2365     switch (iteration) {
2366     case TEST_QCACHE_ON:
2367     case TEST_QCACHE_ON_OFF:
2368       rc= mysql_query(lmysql, "set global query_cache_size=1000000");
2369       myquery(rc);
2370       break;
2371     case TEST_QCACHE_OFF_ON:
2372       rc= mysql_query(lmysql, "set global query_cache_size=0");
2373       myquery(rc);
2374       break;
2375     case TEST_QCACHE_ON_WITH_OTHER_CONN:
2376       if (!opt_silent)
2377         fprintf(stdout, "\n Establishing a test connection ...");
2378       if (!(lmysql= mysql_client_init(NULL)))
2379       {
2380         printf("mysql_client_init() failed");
2381         DIE_UNLESS(0);
2382       }
2383       if (!(mysql_real_connect(lmysql, opt_host, opt_user,
2384                                opt_password, current_db, opt_port,
2385                                opt_unix_socket, 0)))
2386       {
2387         printf("connection failed");
2388         mysql_close(lmysql);
2389         DIE_UNLESS(0);
2390       }
2391       rc= mysql_query(lmysql, "SET SQL_MODE=''");
2392       myquery(rc);
2393       rc= mysql_set_character_set(lmysql, "utf8");
2394       myquery(rc);
2395 
2396       if (!opt_silent)
2397         fprintf(stdout, "OK");
2398       break;
2399     }
2400 
2401     strmov(query, "select id1, value1 from t1 where id1= ? or "
2402            "CONVERT(value1 USING utf8)= ?");
2403     stmt= mysql_simple_prepare(lmysql, query);
2404     check_stmt(stmt);
2405 
2406     verify_param_count(stmt, 2);
2407 
2408     switch (iteration) {
2409     case TEST_QCACHE_OFF_ON:
2410       rc= mysql_query(lmysql, "set global query_cache_size=1000000");
2411       myquery(rc);
2412       break;
2413     case TEST_QCACHE_ON_OFF:
2414       rc= mysql_query(lmysql, "set global query_cache_size=0");
2415       myquery(rc);
2416     default:
2417       break;
2418     }
2419 
2420     bzero((char*) p_bind, sizeof(p_bind));
2421     p_bind[0].buffer_type= MYSQL_TYPE_LONG;
2422     p_bind[0].buffer= (void *)&p_int_data;
2423     p_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
2424     p_bind[1].buffer= (void *)p_str_data;
2425     p_bind[1].buffer_length= array_elements(p_str_data);
2426     p_bind[1].length= &p_str_length;
2427 
2428     rc= mysql_stmt_bind_param(stmt, p_bind);
2429     check_execute(stmt, rc);
2430 
2431     p_int_data= 1;
2432     strmov(p_str_data, "hh");
2433     p_str_length= strlen(p_str_data);
2434 
2435     bzero((char*) r_bind, sizeof(r_bind));
2436     r_bind[0].buffer_type= MYSQL_TYPE_LONG;
2437     r_bind[0].buffer= (void *)&r_int_data;
2438     r_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
2439     r_bind[1].buffer= (void *)r_str_data;
2440     r_bind[1].buffer_length= array_elements(r_str_data);
2441     r_bind[1].length= &r_str_length;
2442 
2443     rc= mysql_stmt_bind_result(stmt, r_bind);
2444     check_execute(stmt, rc);
2445 
2446     rc= mysql_stmt_execute(stmt);
2447     check_execute(stmt, rc);
2448 
2449     test_ps_query_cache_result(1, "hh", 2, 2, "hh", 2, 1, "ii", 2);
2450 
2451     /* now retry with the same parameter values and see qcache hits */
2452     hits1= query_cache_hits(lmysql);
2453     rc= mysql_stmt_execute(stmt);
2454     check_execute(stmt, rc);
2455     test_ps_query_cache_result(1, "hh", 2, 2, "hh", 2, 1, "ii", 2);
2456     hits2= query_cache_hits(lmysql);
2457     switch(iteration) {
2458     case TEST_QCACHE_ON_WITH_OTHER_CONN:
2459     case TEST_QCACHE_ON:                 /* should have hit */
2460       DIE_UNLESS(hits2-hits1 == 1);
2461       break;
2462     case TEST_QCACHE_OFF_ON:
2463     case TEST_QCACHE_ON_OFF:             /* should not have hit */
2464       DIE_UNLESS(hits2-hits1 == 0);
2465       break;
2466     }
2467 
2468     /* now modify parameter values and see qcache hits */
2469     strmov(p_str_data, "ii");
2470     p_str_length= strlen(p_str_data);
2471     rc= mysql_stmt_execute(stmt);
2472     check_execute(stmt, rc);
2473     test_ps_query_cache_result(1, "hh", 2, 1, "ii", 2, 2, "ii", 2);
2474     hits1= query_cache_hits(lmysql);
2475 
2476     switch(iteration) {
2477     case TEST_QCACHE_ON:
2478     case TEST_QCACHE_OFF_ON:
2479     case TEST_QCACHE_ON_OFF:             /* should not have hit */
2480       DIE_UNLESS(hits2-hits1 == 0);
2481       break;
2482     case TEST_QCACHE_ON_WITH_OTHER_CONN: /* should have hit */
2483       DIE_UNLESS(hits1-hits2 == 1);
2484       break;
2485     }
2486 
2487     rc= mysql_stmt_execute(stmt);
2488     check_execute(stmt, rc);
2489 
2490     test_ps_query_cache_result(1, "hh", 2, 1, "ii", 2, 2, "ii", 2);
2491     hits2= query_cache_hits(lmysql);
2492 
2493     mysql_stmt_close(stmt);
2494 
2495     switch(iteration) {
2496     case TEST_QCACHE_ON:                 /* should have hit */
2497       DIE_UNLESS(hits2-hits1 == 1);
2498       break;
2499     case TEST_QCACHE_OFF_ON:
2500     case TEST_QCACHE_ON_OFF:             /* should not have hit */
2501       DIE_UNLESS(hits2-hits1 == 0);
2502       break;
2503     case TEST_QCACHE_ON_WITH_OTHER_CONN: /* should have hit */
2504       DIE_UNLESS(hits2-hits1 == 1);
2505       break;
2506     }
2507 
2508   } /* for(iteration=...) */
2509 
2510   if (lmysql != mysql)
2511     mysql_close(lmysql);
2512 
2513   rc= mysql_query(mysql, "set global query_cache_size=@save_query_cache_size");
2514   myquery(rc);
2515   rc= mysql_query(mysql, "set global query_cache_type=@save_query_cache_type");
2516   myquery(rc);
2517 }
2518 
2519 
2520 /* Test BUG#1115 (incorrect string parameter value allocation) */
2521 
test_bug1115()2522 static void test_bug1115()
2523 {
2524   MYSQL_STMT *stmt;
2525   int rc;
2526   MYSQL_BIND my_bind[1];
2527   ulong length[1];
2528   char szData[11];
2529   char query[MAX_TEST_QUERY_LENGTH];
2530 
2531   myheader("test_bug1115");
2532 
2533   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
2534   myquery(rc);
2535 
2536   rc= mysql_query(mysql, "CREATE TABLE test_select(\
2537 session_id  char(9) NOT NULL, \
2538     a       int(8) unsigned NOT NULL, \
2539     b        int(5) NOT NULL, \
2540     c      int(5) NOT NULL, \
2541     d  datetime NOT NULL)");
2542   myquery(rc);
2543   rc= mysql_query(mysql, "INSERT INTO test_select VALUES "
2544                          "(\"abc\", 1, 2, 3, 2003-08-30), "
2545                          "(\"abd\", 1, 2, 3, 2003-08-30), "
2546                          "(\"abf\", 1, 2, 3, 2003-08-30), "
2547                          "(\"abg\", 1, 2, 3, 2003-08-30), "
2548                          "(\"abh\", 1, 2, 3, 2003-08-30), "
2549                          "(\"abj\", 1, 2, 3, 2003-08-30), "
2550                          "(\"abk\", 1, 2, 3, 2003-08-30), "
2551                          "(\"abl\", 1, 2, 3, 2003-08-30), "
2552                          "(\"abq\", 1, 2, 3, 2003-08-30) ");
2553   myquery(rc);
2554   rc= mysql_query(mysql, "INSERT INTO test_select VALUES "
2555                          "(\"abw\", 1, 2, 3, 2003-08-30), "
2556                          "(\"abe\", 1, 2, 3, 2003-08-30), "
2557                          "(\"abr\", 1, 2, 3, 2003-08-30), "
2558                          "(\"abt\", 1, 2, 3, 2003-08-30), "
2559                          "(\"aby\", 1, 2, 3, 2003-08-30), "
2560                          "(\"abu\", 1, 2, 3, 2003-08-30), "
2561                          "(\"abi\", 1, 2, 3, 2003-08-30), "
2562                          "(\"abo\", 1, 2, 3, 2003-08-30), "
2563                          "(\"abp\", 1, 2, 3, 2003-08-30), "
2564                          "(\"abz\", 1, 2, 3, 2003-08-30), "
2565                          "(\"abx\", 1, 2, 3, 2003-08-30)");
2566   myquery(rc);
2567 
2568   strmov(query, "SELECT * FROM test_select WHERE "
2569                 "CONVERT(session_id USING utf8)= ?");
2570   stmt= mysql_simple_prepare(mysql, query);
2571   check_stmt(stmt);
2572 
2573   verify_param_count(stmt, 1);
2574 
2575   /* Always bzero all members of bind parameter */
2576   bzero((char*) my_bind, sizeof(my_bind));
2577 
2578   strmov(szData, (char *)"abc");
2579   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2580   my_bind[0].buffer= (void *)szData;
2581   my_bind[0].buffer_length= 10;
2582   my_bind[0].length= &length[0];
2583   length[0]= 3;
2584 
2585   rc= mysql_stmt_bind_param(stmt, my_bind);
2586   check_execute(stmt, rc);
2587 
2588   rc= mysql_stmt_execute(stmt);
2589   check_execute(stmt, rc);
2590 
2591   rc= my_process_stmt_result(stmt);
2592   DIE_UNLESS(rc == 1);
2593 
2594   strmov(szData, (char *)"venu");
2595   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2596   my_bind[0].buffer= (void *)szData;
2597   my_bind[0].buffer_length= 10;
2598   my_bind[0].length= &length[0];
2599   length[0]= 4;
2600   my_bind[0].is_null= 0;
2601 
2602   rc= mysql_stmt_bind_param(stmt, my_bind);
2603   check_execute(stmt, rc);
2604 
2605   rc= mysql_stmt_execute(stmt);
2606   check_execute(stmt, rc);
2607 
2608   rc= my_process_stmt_result(stmt);
2609   DIE_UNLESS(rc == 0);
2610 
2611   strmov(szData, (char *)"abc");
2612   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2613   my_bind[0].buffer= (void *)szData;
2614   my_bind[0].buffer_length= 10;
2615   my_bind[0].length= &length[0];
2616   length[0]= 3;
2617   my_bind[0].is_null= 0;
2618 
2619   rc= mysql_stmt_bind_param(stmt, my_bind);
2620   check_execute(stmt, rc);
2621 
2622   rc= mysql_stmt_execute(stmt);
2623   check_execute(stmt, rc);
2624 
2625   rc= my_process_stmt_result(stmt);
2626   DIE_UNLESS(rc == 1);
2627 
2628   mysql_stmt_close(stmt);
2629 }
2630 
2631 
2632 /* Test BUG#1180 (optimized away part of WHERE clause) */
2633 
test_bug1180()2634 static void test_bug1180()
2635 {
2636   MYSQL_STMT *stmt;
2637   int rc;
2638   MYSQL_BIND my_bind[1];
2639   ulong length[1];
2640   char szData[11];
2641   char query[MAX_TEST_QUERY_LENGTH];
2642 
2643   myheader("test_select_bug");
2644 
2645   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_select");
2646   myquery(rc);
2647 
2648   rc= mysql_query(mysql, "CREATE TABLE test_select(session_id  char(9) NOT NULL)");
2649   myquery(rc);
2650   rc= mysql_query(mysql, "INSERT INTO test_select VALUES (\"abc\")");
2651   myquery(rc);
2652 
2653   strmov(query, "SELECT * FROM test_select WHERE ?= \"1111\" and "
2654                 "session_id= \"abc\"");
2655   stmt= mysql_simple_prepare(mysql, query);
2656   check_stmt(stmt);
2657 
2658   verify_param_count(stmt, 1);
2659 
2660   /* Always bzero all members of bind parameter */
2661   bzero((char*) my_bind, sizeof(my_bind));
2662 
2663   strmov(szData, (char *)"abc");
2664   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2665   my_bind[0].buffer= (void *)szData;
2666   my_bind[0].buffer_length= 10;
2667   my_bind[0].length= &length[0];
2668   length[0]= 3;
2669   my_bind[0].is_null= 0;
2670 
2671   rc= mysql_stmt_bind_param(stmt, my_bind);
2672   check_execute(stmt, rc);
2673 
2674   rc= mysql_stmt_execute(stmt);
2675   check_execute(stmt, rc);
2676 
2677   rc= my_process_stmt_result(stmt);
2678   DIE_UNLESS(rc == 0);
2679 
2680   strmov(szData, (char *)"1111");
2681   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2682   my_bind[0].buffer= (void *)szData;
2683   my_bind[0].buffer_length= 10;
2684   my_bind[0].length= &length[0];
2685   length[0]= 4;
2686   my_bind[0].is_null= 0;
2687 
2688   rc= mysql_stmt_bind_param(stmt, my_bind);
2689   check_execute(stmt, rc);
2690 
2691   rc= mysql_stmt_execute(stmt);
2692   check_execute(stmt, rc);
2693 
2694   rc= my_process_stmt_result(stmt);
2695   DIE_UNLESS(rc == 1);
2696 
2697   strmov(szData, (char *)"abc");
2698   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2699   my_bind[0].buffer= (void *)szData;
2700   my_bind[0].buffer_length= 10;
2701   my_bind[0].length= &length[0];
2702   length[0]= 3;
2703   my_bind[0].is_null= 0;
2704 
2705   rc= mysql_stmt_bind_param(stmt, my_bind);
2706   check_execute(stmt, rc);
2707 
2708   rc= mysql_stmt_execute(stmt);
2709   check_execute(stmt, rc);
2710 
2711   rc= my_process_stmt_result(stmt);
2712   DIE_UNLESS(rc == 0);
2713 
2714   mysql_stmt_close(stmt);
2715 }
2716 
2717 
2718 /*
2719   Test BUG#1644 (Insertion of more than 3 NULL columns with parameter
2720   binding fails)
2721 */
2722 
test_bug1644()2723 static void test_bug1644()
2724 {
2725   MYSQL_STMT *stmt;
2726   MYSQL_RES *result;
2727   MYSQL_ROW row;
2728   MYSQL_BIND my_bind[4];
2729   int num;
2730   my_bool isnull;
2731   int rc, i;
2732   char query[MAX_TEST_QUERY_LENGTH];
2733 
2734   myheader("test_bug1644");
2735 
2736   rc= mysql_query(mysql, "DROP TABLE IF EXISTS foo_dfr");
2737   myquery(rc);
2738 
2739   rc= mysql_query(mysql,
2740            "CREATE TABLE foo_dfr(col1 int, col2 int, col3 int, col4 int);");
2741   myquery(rc);
2742 
2743   strmov(query, "INSERT INTO foo_dfr VALUES (?, ?, ?, ? )");
2744   stmt= mysql_simple_prepare(mysql, query);
2745   check_stmt(stmt);
2746 
2747   verify_param_count(stmt, 4);
2748 
2749   /* Always bzero all members of bind parameter */
2750   bzero((char*) my_bind, sizeof(my_bind));
2751 
2752   num= 22;
2753   isnull= 0;
2754   for (i= 0 ; i < 4 ; i++)
2755   {
2756     my_bind[i].buffer_type= MYSQL_TYPE_LONG;
2757     my_bind[i].buffer= (void *)&num;
2758     my_bind[i].is_null= &isnull;
2759   }
2760 
2761   rc= mysql_stmt_bind_param(stmt, my_bind);
2762   check_execute(stmt, rc);
2763 
2764   rc= mysql_stmt_execute(stmt);
2765   check_execute(stmt, rc);
2766 
2767   isnull= 1;
2768   for (i= 0 ; i < 4 ; i++)
2769     my_bind[i].is_null= &isnull;
2770 
2771   rc= mysql_stmt_bind_param(stmt, my_bind);
2772   check_execute(stmt, rc);
2773 
2774   rc= mysql_stmt_execute(stmt);
2775   check_execute(stmt, rc);
2776 
2777   isnull= 0;
2778   num= 88;
2779   for (i= 0 ; i < 4 ; i++)
2780     my_bind[i].is_null= &isnull;
2781 
2782   rc= mysql_stmt_bind_param(stmt, my_bind);
2783   check_execute(stmt, rc);
2784 
2785   rc= mysql_stmt_execute(stmt);
2786   check_execute(stmt, rc);
2787 
2788   mysql_stmt_close(stmt);
2789 
2790   rc= mysql_query(mysql, "SELECT * FROM foo_dfr");
2791   myquery(rc);
2792 
2793   result= mysql_store_result(mysql);
2794   mytest(result);
2795 
2796   rc= my_process_result_set(result);
2797   DIE_UNLESS(rc == 3);
2798 
2799   mysql_data_seek(result, 0);
2800 
2801   row= mysql_fetch_row(result);
2802   mytest(row);
2803   for (i= 0 ; i < 4 ; i++)
2804   {
2805     DIE_UNLESS(strcmp(row[i], "22") == 0);
2806   }
2807   row= mysql_fetch_row(result);
2808   mytest(row);
2809   for (i= 0 ; i < 4 ; i++)
2810   {
2811     DIE_UNLESS(row[i] == 0);
2812   }
2813   row= mysql_fetch_row(result);
2814   mytest(row);
2815   for (i= 0 ; i < 4 ; i++)
2816   {
2817     DIE_UNLESS(strcmp(row[i], "88") == 0);
2818   }
2819   row= mysql_fetch_row(result);
2820   mytest_r(row);
2821 
2822   mysql_free_result(result);
2823 }
2824 
2825 
2826 /* Test simple select show */
2827 
test_select_show()2828 static void test_select_show()
2829 {
2830   MYSQL_STMT *stmt;
2831   int        rc;
2832   char query[MAX_TEST_QUERY_LENGTH];
2833 
2834   myheader("test_select_show");
2835 
2836   mysql_autocommit(mysql, TRUE);
2837 
2838   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_show");
2839   myquery(rc);
2840 
2841   rc= mysql_query(mysql, "CREATE TABLE test_show(id int(4) NOT NULL primary "
2842                          " key, name char(2))");
2843   myquery(rc);
2844 
2845   stmt= mysql_simple_prepare(mysql, "show columns from test_show");
2846   check_stmt(stmt);
2847 
2848   verify_param_count(stmt, 0);
2849 
2850   rc= mysql_stmt_execute(stmt);
2851   check_execute(stmt, rc);
2852 
2853   my_process_stmt_result(stmt);
2854   mysql_stmt_close(stmt);
2855 
2856   stmt= mysql_simple_prepare(mysql, "show tables from mysql like ?");
2857   check_stmt_r(stmt);
2858 
2859   strxmov(query, "show tables from ", current_db, " like \'test_show\'", NullS);
2860   stmt= mysql_simple_prepare(mysql, query);
2861   check_stmt(stmt);
2862 
2863   rc= mysql_stmt_execute(stmt);
2864   check_execute(stmt, rc);
2865 
2866   my_process_stmt_result(stmt);
2867   mysql_stmt_close(stmt);
2868 
2869   stmt= mysql_simple_prepare(mysql, "describe test_show");
2870   check_stmt(stmt);
2871 
2872   rc= mysql_stmt_execute(stmt);
2873   check_execute(stmt, rc);
2874 
2875   my_process_stmt_result(stmt);
2876   mysql_stmt_close(stmt);
2877 
2878   stmt= mysql_simple_prepare(mysql, "show keys from test_show");
2879   check_stmt(stmt);
2880 
2881   rc= mysql_stmt_execute(stmt);
2882   check_execute(stmt, rc);
2883 
2884   rc= my_process_stmt_result(stmt);
2885   DIE_UNLESS(rc == 1);
2886   mysql_stmt_close(stmt);
2887 }
2888 
2889 
2890 /* Test simple update */
2891 
test_simple_update()2892 static void test_simple_update()
2893 {
2894   MYSQL_STMT *stmt;
2895   int        rc;
2896   char       szData[25];
2897   int        nData= 1;
2898   MYSQL_RES  *result;
2899   MYSQL_BIND my_bind[2];
2900   ulong      length[2];
2901   char query[MAX_TEST_QUERY_LENGTH];
2902 
2903   myheader("test_simple_update");
2904 
2905   rc= mysql_autocommit(mysql, TRUE);
2906   myquery(rc);
2907 
2908   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_update");
2909   myquery(rc);
2910 
2911   rc= mysql_query(mysql, "CREATE TABLE test_update(col1 int, "
2912                          " col2 varchar(50), col3 int )");
2913   myquery(rc);
2914 
2915   rc= mysql_query(mysql, "INSERT INTO test_update VALUES(1, 'MySQL', 100)");
2916   myquery(rc);
2917 
2918   verify_affected_rows(1);
2919 
2920   rc= mysql_commit(mysql);
2921   myquery(rc);
2922 
2923   /* insert by prepare */
2924   strmov(query, "UPDATE test_update SET col2= ? WHERE col1= ?");
2925   stmt= mysql_simple_prepare(mysql, query);
2926   check_stmt(stmt);
2927 
2928   verify_param_count(stmt, 2);
2929 
2930   /* Always bzero all members of bind parameter */
2931   bzero((char*) my_bind, sizeof(my_bind));
2932 
2933   nData= 1;
2934   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
2935   my_bind[0].buffer= szData;                /* string data */
2936   my_bind[0].buffer_length= sizeof(szData);
2937   my_bind[0].length= &length[0];
2938   length[0]= sprintf(szData, "updated-data");
2939 
2940   my_bind[1].buffer= (void *) &nData;
2941   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
2942 
2943   rc= mysql_stmt_bind_param(stmt, my_bind);
2944   check_execute(stmt, rc);
2945 
2946   rc= mysql_stmt_execute(stmt);
2947   check_execute(stmt, rc);
2948   verify_affected_rows(1);
2949 
2950   mysql_stmt_close(stmt);
2951 
2952   /* now fetch the results ..*/
2953   rc= mysql_commit(mysql);
2954   myquery(rc);
2955 
2956   /* test the results now, only one row should exist */
2957   rc= mysql_query(mysql, "SELECT * FROM test_update");
2958   myquery(rc);
2959 
2960   /* get the result */
2961   result= mysql_store_result(mysql);
2962   mytest(result);
2963 
2964   rc= my_process_result_set(result);
2965   DIE_UNLESS(rc == 1);
2966   mysql_free_result(result);
2967 }
2968 
2969 
2970 /* Test simple long data handling */
2971 
test_long_data()2972 static void test_long_data()
2973 {
2974   MYSQL_STMT *stmt;
2975   int        rc, int_data;
2976   char       *data= NullS;
2977   MYSQL_RES  *result;
2978   MYSQL_BIND my_bind[3];
2979   char query[MAX_TEST_QUERY_LENGTH];
2980 
2981   myheader("test_long_data");
2982 
2983   rc= mysql_autocommit(mysql, TRUE);
2984   myquery(rc);
2985 
2986   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data");
2987   myquery(rc);
2988 
2989   rc= mysql_query(mysql, "CREATE TABLE test_long_data(col1 int, "
2990                          "      col2 long varchar, col3 long varbinary)");
2991   myquery(rc);
2992 
2993   strmov(query, "INSERT INTO test_long_data(col1, col2) VALUES(?)");
2994   stmt= mysql_simple_prepare(mysql, query);
2995   check_stmt_r(stmt);
2996 
2997   strmov(query, "INSERT INTO test_long_data(col1, col2, col3) VALUES(?, ?, ?)");
2998   stmt= mysql_simple_prepare(mysql, query);
2999   check_stmt(stmt);
3000 
3001   verify_param_count(stmt, 3);
3002 
3003   /* Always bzero all members of bind parameter */
3004   bzero((char*) my_bind, sizeof(my_bind));
3005 
3006   my_bind[0].buffer= (void *)&int_data;
3007   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
3008 
3009   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
3010 
3011   my_bind[2]= my_bind[1];
3012   rc= mysql_stmt_bind_param(stmt, my_bind);
3013   check_execute(stmt, rc);
3014 
3015   int_data= 999;
3016   data= (char *)"Michael";
3017 
3018   /* supply data in pieces */
3019   rc= mysql_stmt_send_long_data(stmt, 1, data, strlen(data));
3020   data= (char *)" 'Monty' Widenius";
3021   rc= mysql_stmt_send_long_data(stmt, 1, data, strlen(data));
3022   check_execute(stmt, rc);
3023   rc= mysql_stmt_send_long_data(stmt, 2, "Venu (venu@mysql.com)", 4);
3024   check_execute(stmt, rc);
3025 
3026   /* execute */
3027   rc= mysql_stmt_execute(stmt);
3028   if (!opt_silent)
3029     fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
3030   check_execute(stmt, rc);
3031 
3032   rc= mysql_commit(mysql);
3033   myquery(rc);
3034 
3035   /* now fetch the results ..*/
3036   rc= mysql_query(mysql, "SELECT * FROM test_long_data");
3037   myquery(rc);
3038 
3039   /* get the result */
3040   result= mysql_store_result(mysql);
3041   mytest(result);
3042 
3043   rc= my_process_result_set(result);
3044   DIE_UNLESS(rc == 1);
3045   mysql_free_result(result);
3046 
3047   verify_col_data("test_long_data", "col1", "999");
3048   verify_col_data("test_long_data", "col2", "Michael 'Monty' Widenius");
3049   verify_col_data("test_long_data", "col3", "Venu");
3050   mysql_stmt_close(stmt);
3051 }
3052 
3053 
3054 /* Test long data (string) handling */
3055 
test_long_data_str()3056 static void test_long_data_str()
3057 {
3058   MYSQL_STMT *stmt;
3059   int        rc, i;
3060   char       data[255];
3061   long       length;
3062   ulong      length1;
3063   MYSQL_RES  *result;
3064   MYSQL_BIND my_bind[2];
3065   my_bool    is_null[2];
3066   char query[MAX_TEST_QUERY_LENGTH];
3067 
3068   myheader("test_long_data_str");
3069 
3070   rc= mysql_autocommit(mysql, TRUE);
3071   myquery(rc);
3072 
3073   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data_str");
3074   myquery(rc);
3075 
3076   rc= mysql_query(mysql, "CREATE TABLE test_long_data_str(id int, longstr long varchar)");
3077   myquery(rc);
3078 
3079   strmov(query, "INSERT INTO test_long_data_str VALUES(?, ?)");
3080   stmt= mysql_simple_prepare(mysql, query);
3081   check_stmt(stmt);
3082 
3083   verify_param_count(stmt, 2);
3084 
3085   /* Always bzero all members of bind parameter */
3086   bzero((char*) my_bind, sizeof(my_bind));
3087 
3088   my_bind[0].buffer= (void *)&length;
3089   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
3090   my_bind[0].is_null= &is_null[0];
3091   is_null[0]= 0;
3092   length= 0;
3093 
3094   my_bind[1].buffer= data;                          /* string data */
3095   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
3096   my_bind[1].length= &length1;
3097   my_bind[1].is_null= &is_null[1];
3098   is_null[1]= 0;
3099   rc= mysql_stmt_bind_param(stmt, my_bind);
3100   check_execute(stmt, rc);
3101 
3102   length= 40;
3103   strmov(data, "MySQL AB");
3104 
3105   /* supply data in pieces */
3106   for(i= 0; i < 4; i++)
3107   {
3108     rc= mysql_stmt_send_long_data(stmt, 1, (char *)data, 5);
3109     check_execute(stmt, rc);
3110   }
3111   /* execute */
3112   rc= mysql_stmt_execute(stmt);
3113   if (!opt_silent)
3114     fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
3115   check_execute(stmt, rc);
3116 
3117   mysql_stmt_close(stmt);
3118 
3119   rc= mysql_commit(mysql);
3120   myquery(rc);
3121 
3122   /* now fetch the results ..*/
3123   rc= mysql_query(mysql, "SELECT LENGTH(longstr), longstr FROM test_long_data_str");
3124   myquery(rc);
3125 
3126   /* get the result */
3127   result= mysql_store_result(mysql);
3128   mytest(result);
3129 
3130   rc= my_process_result_set(result);
3131   DIE_UNLESS(rc == 1);
3132   mysql_free_result(result);
3133 
3134   sprintf(data, "%d", i*5);
3135   verify_col_data("test_long_data_str", "LENGTH(longstr)", data);
3136   data[0]= '\0';
3137   while (i--)
3138    strxmov(data, data, "MySQL", NullS);
3139   verify_col_data("test_long_data_str", "longstr", data);
3140 
3141   rc= mysql_query(mysql, "DROP TABLE test_long_data_str");
3142   myquery(rc);
3143 }
3144 
3145 
3146 /* Test long data (string) handling */
3147 
test_long_data_str1()3148 static void test_long_data_str1()
3149 {
3150   MYSQL_STMT *stmt;
3151   int        rc, i;
3152   char       data[255];
3153   long       length;
3154   ulong      max_blob_length, blob_length= 0, length1;
3155   my_bool    true_value;
3156   MYSQL_RES  *result;
3157   MYSQL_BIND my_bind[2];
3158   MYSQL_FIELD *field;
3159   char query[MAX_TEST_QUERY_LENGTH];
3160 
3161   myheader("test_long_data_str1");
3162 
3163   rc= mysql_autocommit(mysql, TRUE);
3164   myquery(rc);
3165 
3166   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data_str");
3167   myquery(rc);
3168 
3169   rc= mysql_query(mysql, "CREATE TABLE test_long_data_str(longstr long varchar, blb long varbinary)");
3170   myquery(rc);
3171 
3172   strmov(query, "INSERT INTO test_long_data_str VALUES(?, ?)");
3173   stmt= mysql_simple_prepare(mysql, query);
3174   check_stmt(stmt);
3175 
3176   verify_param_count(stmt, 2);
3177 
3178   /* Always bzero all members of bind parameter */
3179   bzero((char*) my_bind, sizeof(my_bind));
3180 
3181   my_bind[0].buffer= data;            /* string data */
3182   my_bind[0].buffer_length= sizeof(data);
3183   my_bind[0].length= &length1;
3184   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
3185   length1= 0;
3186 
3187   my_bind[1]= my_bind[0];
3188   my_bind[1].buffer_type= MYSQL_TYPE_BLOB;
3189 
3190   rc= mysql_stmt_bind_param(stmt, my_bind);
3191   check_execute(stmt, rc);
3192   length= sprintf(data, "MySQL AB");
3193 
3194   /* supply data in pieces */
3195   for (i= 0; i < 3; i++)
3196   {
3197     rc= mysql_stmt_send_long_data(stmt, 0, data, length);
3198     check_execute(stmt, rc);
3199 
3200     rc= mysql_stmt_send_long_data(stmt, 1, data, 2);
3201     check_execute(stmt, rc);
3202   }
3203 
3204   /* execute */
3205   rc= mysql_stmt_execute(stmt);
3206   if (!opt_silent)
3207     fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
3208   check_execute(stmt, rc);
3209 
3210   mysql_stmt_close(stmt);
3211 
3212   rc= mysql_commit(mysql);
3213   myquery(rc);
3214 
3215   /* now fetch the results ..*/
3216   rc= mysql_query(mysql, "SELECT LENGTH(longstr), longstr, LENGTH(blb), blb FROM test_long_data_str");
3217   myquery(rc);
3218 
3219   /* get the result */
3220   result= mysql_store_result(mysql);
3221 
3222   mysql_field_seek(result, 1);
3223   field= mysql_fetch_field(result);
3224   max_blob_length= field->max_length;
3225 
3226   mytest(result);
3227 
3228   rc= my_process_result_set(result);
3229   DIE_UNLESS(rc == 1);
3230   mysql_free_result(result);
3231 
3232   sprintf(data, "%ld", (long)i*length);
3233   verify_col_data("test_long_data_str", "length(longstr)", data);
3234 
3235   sprintf(data, "%d", i*2);
3236   verify_col_data("test_long_data_str", "length(blb)", data);
3237 
3238   /* Test length of field->max_length */
3239   stmt= mysql_simple_prepare(mysql, "SELECT * from test_long_data_str");
3240   check_stmt(stmt);
3241   verify_param_count(stmt, 0);
3242 
3243   rc= mysql_stmt_execute(stmt);
3244   check_execute(stmt, rc);
3245 
3246   rc= mysql_stmt_store_result(stmt);
3247   check_execute(stmt, rc);
3248 
3249   result= mysql_stmt_result_metadata(stmt);
3250   field= mysql_fetch_fields(result);
3251 
3252   /* First test what happens if STMT_ATTR_UPDATE_MAX_LENGTH is not used */
3253   DIE_UNLESS(field->max_length == 0);
3254   mysql_free_result(result);
3255 
3256   /* Enable updating of field->max_length */
3257   true_value= 1;
3258   mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &true_value);
3259   rc= mysql_stmt_execute(stmt);
3260   check_execute(stmt, rc);
3261 
3262   rc= mysql_stmt_store_result(stmt);
3263   check_execute(stmt, rc);
3264 
3265   result= mysql_stmt_result_metadata(stmt);
3266   field= mysql_fetch_fields(result);
3267 
3268   DIE_UNLESS(field->max_length == max_blob_length);
3269 
3270   /* Fetch results into a data buffer that is smaller than data */
3271   bzero((char*) my_bind, sizeof(*my_bind));
3272   my_bind[0].buffer_type= MYSQL_TYPE_BLOB;
3273   my_bind[0].buffer= (void *) &data; /* this buffer won't be altered */
3274   my_bind[0].buffer_length= 16;
3275   my_bind[0].length= &blob_length;
3276   my_bind[0].error= &my_bind[0].error_value;
3277   rc= mysql_stmt_bind_result(stmt, my_bind);
3278   data[16]= 0;
3279 
3280   rc= mysql_stmt_fetch(stmt);
3281   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
3282   DIE_UNLESS(my_bind[0].error_value);
3283   DIE_UNLESS(strlen(data) == 16);
3284   DIE_UNLESS(blob_length == max_blob_length);
3285 
3286   /* Fetch all data */
3287   bzero((char*) (my_bind+1), sizeof(*my_bind));
3288   my_bind[1].buffer_type= MYSQL_TYPE_BLOB;
3289   my_bind[1].buffer= (void *) &data; /* this buffer won't be altered */
3290   my_bind[1].buffer_length= sizeof(data);
3291   my_bind[1].length= &blob_length;
3292   bzero(data, sizeof(data));
3293   mysql_stmt_fetch_column(stmt, my_bind+1, 0, 0);
3294   DIE_UNLESS(strlen(data) == max_blob_length);
3295 
3296   mysql_free_result(result);
3297   mysql_stmt_close(stmt);
3298 
3299   /* Drop created table */
3300   rc= mysql_query(mysql, "DROP TABLE test_long_data_str");
3301   myquery(rc);
3302 }
3303 
3304 
3305 /* Test long data (binary) handling */
3306 
test_long_data_bin()3307 static void test_long_data_bin()
3308 {
3309   MYSQL_STMT *stmt;
3310   int        rc;
3311   char       data[255];
3312   long       length;
3313   MYSQL_RES  *result;
3314   MYSQL_BIND my_bind[2];
3315   char query[MAX_TEST_QUERY_LENGTH];
3316 
3317 
3318   myheader("test_long_data_bin");
3319 
3320   rc= mysql_autocommit(mysql, TRUE);
3321   myquery(rc);
3322 
3323   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data_bin");
3324   myquery(rc);
3325 
3326   rc= mysql_query(mysql, "CREATE TABLE test_long_data_bin(id int, longbin long varbinary)");
3327   myquery(rc);
3328 
3329   strmov(query, "INSERT INTO test_long_data_bin VALUES(?, ?)");
3330   stmt= mysql_simple_prepare(mysql, query);
3331   check_stmt(stmt);
3332 
3333   verify_param_count(stmt, 2);
3334 
3335   /* Always bzero all members of bind parameter */
3336   bzero((char*) my_bind, sizeof(my_bind));
3337 
3338   my_bind[0].buffer= (void *)&length;
3339   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
3340   length= 0;
3341 
3342   my_bind[1].buffer= data;           /* string data */
3343   my_bind[1].buffer_type= MYSQL_TYPE_LONG_BLOB;
3344   rc= mysql_stmt_bind_param(stmt, my_bind);
3345   check_execute(stmt, rc);
3346 
3347   length= 10;
3348   strmov(data, "MySQL AB");
3349 
3350   /* supply data in pieces */
3351   {
3352     int i;
3353     for (i= 0; i < 100; i++)
3354     {
3355       rc= mysql_stmt_send_long_data(stmt, 1, (char *)data, 4);
3356       check_execute(stmt, rc);
3357     }
3358   }
3359   /* execute */
3360   rc= mysql_stmt_execute(stmt);
3361   if (!opt_silent)
3362     fprintf(stdout, " mysql_stmt_execute() returned %d\n", rc);
3363   check_execute(stmt, rc);
3364 
3365   mysql_stmt_close(stmt);
3366 
3367   rc= mysql_commit(mysql);
3368   myquery(rc);
3369 
3370   /* now fetch the results ..*/
3371   rc= mysql_query(mysql, "SELECT LENGTH(longbin), longbin FROM test_long_data_bin");
3372   myquery(rc);
3373 
3374   /* get the result */
3375   result= mysql_store_result(mysql);
3376   mytest(result);
3377 
3378   rc= my_process_result_set(result);
3379   DIE_UNLESS(rc == 1);
3380   mysql_free_result(result);
3381 }
3382 
3383 
3384 /* Test simple delete */
3385 
test_simple_delete()3386 static void test_simple_delete()
3387 {
3388   MYSQL_STMT *stmt;
3389   int        rc;
3390   char       szData[30]= {0};
3391   int        nData= 1;
3392   MYSQL_RES  *result;
3393   MYSQL_BIND my_bind[2];
3394   ulong length[2];
3395   char query[MAX_TEST_QUERY_LENGTH];
3396 
3397   myheader("test_simple_delete");
3398 
3399   rc= mysql_autocommit(mysql, TRUE);
3400   myquery(rc);
3401 
3402   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_simple_delete");
3403   myquery(rc);
3404 
3405   rc= mysql_query(mysql, "CREATE TABLE test_simple_delete(col1 int, \
3406                                 col2 varchar(50), col3 int )");
3407   myquery(rc);
3408 
3409   rc= mysql_query(mysql, "INSERT INTO test_simple_delete VALUES(1, 'MySQL', 100)");
3410   myquery(rc);
3411 
3412   verify_affected_rows(1);
3413 
3414   rc= mysql_commit(mysql);
3415   myquery(rc);
3416 
3417   /* insert by prepare */
3418   strmov(query, "DELETE FROM test_simple_delete WHERE col1= ? AND "
3419                 "CONVERT(col2 USING utf8)= ? AND col3= 100");
3420   stmt= mysql_simple_prepare(mysql, query);
3421   check_stmt(stmt);
3422 
3423   verify_param_count(stmt, 2);
3424 
3425   /* Always bzero all members of bind parameter */
3426   bzero((char*) my_bind, sizeof(my_bind));
3427 
3428   nData= 1;
3429   strmov(szData, "MySQL");
3430   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
3431   my_bind[1].buffer= szData;               /* string data */
3432   my_bind[1].buffer_length= sizeof(szData);
3433   my_bind[1].length= &length[1];
3434   length[1]= 5;
3435 
3436   my_bind[0].buffer= (void *)&nData;
3437   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
3438 
3439   rc= mysql_stmt_bind_param(stmt, my_bind);
3440   check_execute(stmt, rc);
3441 
3442   rc= mysql_stmt_execute(stmt);
3443   check_execute(stmt, rc);
3444 
3445   verify_affected_rows(1);
3446 
3447   mysql_stmt_close(stmt);
3448 
3449   /* now fetch the results ..*/
3450   rc= mysql_commit(mysql);
3451   myquery(rc);
3452 
3453   /* test the results now, only one row should exist */
3454   rc= mysql_query(mysql, "SELECT * FROM test_simple_delete");
3455   myquery(rc);
3456 
3457   /* get the result */
3458   result= mysql_store_result(mysql);
3459   mytest(result);
3460 
3461   rc= my_process_result_set(result);
3462   DIE_UNLESS(rc == 0);
3463   mysql_free_result(result);
3464 }
3465 
3466 
3467 /* Test simple update */
3468 
test_update()3469 static void test_update()
3470 {
3471   MYSQL_STMT *stmt;
3472   int        rc;
3473   char       szData[25];
3474   int        nData= 1;
3475   MYSQL_RES  *result;
3476   MYSQL_BIND my_bind[2];
3477   ulong length[2];
3478   char query[MAX_TEST_QUERY_LENGTH];
3479 
3480   myheader("test_update");
3481 
3482   rc= mysql_autocommit(mysql, TRUE);
3483   myquery(rc);
3484 
3485   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_update");
3486   myquery(rc);
3487 
3488   rc= mysql_query(mysql, "CREATE TABLE test_update("
3489                                "col1 int primary key auto_increment, "
3490                                "col2 varchar(50), col3 int )");
3491   myquery(rc);
3492 
3493   strmov(query, "INSERT INTO test_update(col2, col3) VALUES(?, ?)");
3494   stmt= mysql_simple_prepare(mysql, query);
3495   check_stmt(stmt);
3496 
3497   verify_param_count(stmt, 2);
3498 
3499   /* Always bzero all members of bind parameter */
3500   bzero((char*) my_bind, sizeof(my_bind));
3501 
3502   /* string data */
3503   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
3504   my_bind[0].buffer= szData;
3505   my_bind[0].buffer_length= sizeof(szData);
3506   my_bind[0].length= &length[0];
3507   length[0]= sprintf(szData, "inserted-data");
3508 
3509   my_bind[1].buffer= (void *)&nData;
3510   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
3511 
3512   rc= mysql_stmt_bind_param(stmt, my_bind);
3513   check_execute(stmt, rc);
3514 
3515   nData= 100;
3516   rc= mysql_stmt_execute(stmt);
3517   check_execute(stmt, rc);
3518 
3519   verify_affected_rows(1);
3520   mysql_stmt_close(stmt);
3521 
3522   strmov(query, "UPDATE test_update SET col2= ? WHERE col3= ?");
3523   stmt= mysql_simple_prepare(mysql, query);
3524   check_stmt(stmt);
3525 
3526   verify_param_count(stmt, 2);
3527   nData= 100;
3528 
3529   /* Always bzero all members of bind parameter */
3530   bzero((char*) my_bind, sizeof(my_bind));
3531 
3532   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
3533   my_bind[0].buffer= szData;
3534   my_bind[0].buffer_length= sizeof(szData);
3535   my_bind[0].length= &length[0];
3536   length[0]= sprintf(szData, "updated-data");
3537 
3538   my_bind[1].buffer= (void *)&nData;
3539   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
3540 
3541   rc= mysql_stmt_bind_param(stmt, my_bind);
3542   check_execute(stmt, rc);
3543 
3544   rc= mysql_stmt_execute(stmt);
3545   check_execute(stmt, rc);
3546   verify_affected_rows(1);
3547 
3548   mysql_stmt_close(stmt);
3549 
3550   /* now fetch the results ..*/
3551   rc= mysql_commit(mysql);
3552   myquery(rc);
3553 
3554   /* test the results now, only one row should exist */
3555   rc= mysql_query(mysql, "SELECT * FROM test_update");
3556   myquery(rc);
3557 
3558   /* get the result */
3559   result= mysql_store_result(mysql);
3560   mytest(result);
3561 
3562   rc= my_process_result_set(result);
3563   DIE_UNLESS(rc == 1);
3564   mysql_free_result(result);
3565 }
3566 
3567 
3568 /* Test prepare without parameters */
3569 
test_prepare_noparam()3570 static void test_prepare_noparam()
3571 {
3572   MYSQL_STMT *stmt;
3573   int        rc;
3574   MYSQL_RES  *result;
3575   char query[MAX_TEST_QUERY_LENGTH];
3576 
3577   myheader("test_prepare_noparam");
3578 
3579   rc= mysql_query(mysql, "DROP TABLE IF EXISTS my_prepare");
3580   myquery(rc);
3581 
3582 
3583   rc= mysql_query(mysql, "CREATE TABLE my_prepare(col1 int, col2 varchar(50))");
3584   myquery(rc);
3585 
3586   /* insert by prepare */
3587   strmov(query, "INSERT INTO my_prepare VALUES(10, 'venu')");
3588   stmt= mysql_simple_prepare(mysql, query);
3589   check_stmt(stmt);
3590 
3591   verify_param_count(stmt, 0);
3592 
3593   rc= mysql_stmt_execute(stmt);
3594   check_execute(stmt, rc);
3595 
3596   mysql_stmt_close(stmt);
3597 
3598   /* now fetch the results ..*/
3599   rc= mysql_commit(mysql);
3600   myquery(rc);
3601 
3602   /* test the results now, only one row should exist */
3603   rc= mysql_query(mysql, "SELECT * FROM my_prepare");
3604   myquery(rc);
3605 
3606   /* get the result */
3607   result= mysql_store_result(mysql);
3608   mytest(result);
3609 
3610   rc= my_process_result_set(result);
3611   DIE_UNLESS(rc == 1);
3612   mysql_free_result(result);
3613 }
3614 
3615 
3616 /* Test simple bind result */
3617 
test_bind_result()3618 static void test_bind_result()
3619 {
3620   MYSQL_STMT *stmt;
3621   int        rc;
3622   int        nData;
3623   ulong      length1;
3624   char       szData[100];
3625   MYSQL_BIND my_bind[2];
3626   my_bool    is_null[2];
3627 
3628   myheader("test_bind_result");
3629 
3630   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_result");
3631   myquery(rc);
3632 
3633   rc= mysql_query(mysql, "CREATE TABLE test_bind_result(col1 int , col2 varchar(50))");
3634   myquery(rc);
3635 
3636   rc= mysql_query(mysql, "INSERT INTO test_bind_result VALUES(10, 'venu')");
3637   myquery(rc);
3638 
3639   rc= mysql_query(mysql, "INSERT INTO test_bind_result VALUES(20, 'MySQL')");
3640   myquery(rc);
3641 
3642   rc= mysql_query(mysql, "INSERT INTO test_bind_result(col2) VALUES('monty')");
3643   myquery(rc);
3644 
3645   rc= mysql_commit(mysql);
3646   myquery(rc);
3647 
3648   /* fetch */
3649 
3650   bzero((char*) my_bind, sizeof(my_bind));
3651   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
3652   my_bind[0].buffer= (void *) &nData;      /* integer data */
3653   my_bind[0].is_null= &is_null[0];
3654 
3655   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
3656   my_bind[1].buffer= szData;                /* string data */
3657   my_bind[1].buffer_length= sizeof(szData);
3658   my_bind[1].length= &length1;
3659   my_bind[1].is_null= &is_null[1];
3660 
3661   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_bind_result");
3662   check_stmt(stmt);
3663 
3664   rc= mysql_stmt_bind_result(stmt, my_bind);
3665   check_execute(stmt, rc);
3666 
3667   rc= mysql_stmt_execute(stmt);
3668   check_execute(stmt, rc);
3669 
3670   rc= mysql_stmt_fetch(stmt);
3671   check_execute(stmt, rc);
3672 
3673   if (!opt_silent)
3674     fprintf(stdout, "\n row 1: %d, %s(%lu)", nData, szData, length1);
3675   DIE_UNLESS(nData == 10);
3676   DIE_UNLESS(strcmp(szData, "venu") == 0);
3677   DIE_UNLESS(length1 == 4);
3678 
3679   rc= mysql_stmt_fetch(stmt);
3680   check_execute(stmt, rc);
3681 
3682   if (!opt_silent)
3683     fprintf(stdout, "\n row 2: %d, %s(%lu)", nData, szData, length1);
3684   DIE_UNLESS(nData == 20);
3685   DIE_UNLESS(strcmp(szData, "MySQL") == 0);
3686   DIE_UNLESS(length1 == 5);
3687 
3688   rc= mysql_stmt_fetch(stmt);
3689   check_execute(stmt, rc);
3690 
3691   if (!opt_silent && is_null[0])
3692     fprintf(stdout, "\n row 3: NULL, %s(%lu)", szData, length1);
3693   DIE_UNLESS(is_null[0]);
3694   DIE_UNLESS(strcmp(szData, "monty") == 0);
3695   DIE_UNLESS(length1 == 5);
3696 
3697   rc= mysql_stmt_fetch(stmt);
3698   DIE_UNLESS(rc == MYSQL_NO_DATA);
3699 
3700   mysql_stmt_close(stmt);
3701 }
3702 
3703 
3704 /* Test ext bind result */
3705 
test_bind_result_ext()3706 static void test_bind_result_ext()
3707 {
3708   MYSQL_STMT *stmt;
3709   int        rc, i;
3710   uchar      t_data;
3711   short      s_data;
3712   int        i_data;
3713   longlong   b_data;
3714   float      f_data;
3715   double     d_data;
3716   char       szData[20], bData[20];
3717   ulong       szLength, bLength;
3718   MYSQL_BIND my_bind[8];
3719   ulong      length[8];
3720   my_bool    is_null[8];
3721   char	     llbuf[22];
3722   myheader("test_bind_result_ext");
3723 
3724   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_result");
3725   myquery(rc);
3726 
3727   rc= mysql_query(mysql, "CREATE TABLE test_bind_result(c1 tinyint, "
3728                                                       " c2 smallint, "
3729                                                       " c3 int, c4 bigint, "
3730                                                       " c5 float, c6 double, "
3731                                                       " c7 varbinary(10), "
3732                                                       " c8 varchar(50))");
3733   myquery(rc);
3734 
3735   rc= mysql_query(mysql, "INSERT INTO test_bind_result "
3736                          "VALUES (19, 2999, 3999, 4999999, "
3737                          " 2345.6, 5678.89563, 'venu', 'mysql')");
3738   myquery(rc);
3739 
3740   rc= mysql_commit(mysql);
3741   myquery(rc);
3742 
3743   bzero((char*) my_bind, sizeof(my_bind));
3744   for (i= 0; i < (int) array_elements(my_bind); i++)
3745   {
3746     my_bind[i].length=  &length[i];
3747     my_bind[i].is_null= &is_null[i];
3748   }
3749 
3750   my_bind[0].buffer_type= MYSQL_TYPE_TINY;
3751   my_bind[0].buffer= (void *)&t_data;
3752 
3753   my_bind[1].buffer_type= MYSQL_TYPE_SHORT;
3754   my_bind[2].buffer_type= MYSQL_TYPE_LONG;
3755 
3756   my_bind[3].buffer_type= MYSQL_TYPE_LONGLONG;
3757   my_bind[1].buffer= (void *)&s_data;
3758 
3759   my_bind[2].buffer= (void *)&i_data;
3760   my_bind[3].buffer= (void *)&b_data;
3761 
3762   my_bind[4].buffer_type= MYSQL_TYPE_FLOAT;
3763   my_bind[4].buffer= (void *)&f_data;
3764 
3765   my_bind[5].buffer_type= MYSQL_TYPE_DOUBLE;
3766   my_bind[5].buffer= (void *)&d_data;
3767 
3768   my_bind[6].buffer_type= MYSQL_TYPE_STRING;
3769   my_bind[6].buffer= (void *)szData;
3770   my_bind[6].buffer_length= sizeof(szData);
3771   my_bind[6].length= &szLength;
3772 
3773   my_bind[7].buffer_type= MYSQL_TYPE_TINY_BLOB;
3774   my_bind[7].buffer= (void *)&bData;
3775   my_bind[7].length= &bLength;
3776   my_bind[7].buffer_length= sizeof(bData);
3777 
3778   stmt= mysql_simple_prepare(mysql, "select * from test_bind_result");
3779   check_stmt(stmt);
3780 
3781   rc= mysql_stmt_bind_result(stmt, my_bind);
3782   check_execute(stmt, rc);
3783 
3784   rc= mysql_stmt_execute(stmt);
3785   check_execute(stmt, rc);
3786 
3787   rc= mysql_stmt_fetch(stmt);
3788   check_execute(stmt, rc);
3789 
3790   if (!opt_silent)
3791   {
3792     fprintf(stdout, "\n data (tiny)   : %d", t_data);
3793     fprintf(stdout, "\n data (short)  : %d", s_data);
3794     fprintf(stdout, "\n data (int)    : %d", i_data);
3795     fprintf(stdout, "\n data (big)    : %s", llstr(b_data, llbuf));
3796 
3797     fprintf(stdout, "\n data (float)  : %f", f_data);
3798     fprintf(stdout, "\n data (double) : %f", d_data);
3799 
3800     fprintf(stdout, "\n data (str)    : %s(%lu)", szData, szLength);
3801 
3802     bData[bLength]= '\0';                         /* bData is binary */
3803     fprintf(stdout, "\n data (bin)    : %s(%lu)", bData, bLength);
3804   }
3805 
3806   DIE_UNLESS(t_data == 19);
3807   DIE_UNLESS(s_data == 2999);
3808   DIE_UNLESS(i_data == 3999);
3809   DIE_UNLESS(b_data == 4999999);
3810   /*DIE_UNLESS(f_data == 2345.60);*/
3811   /*DIE_UNLESS(d_data == 5678.89563);*/
3812   DIE_UNLESS(strcmp(szData, "venu") == 0);
3813   DIE_UNLESS(strncmp(bData, "mysql", 5) == 0);
3814   DIE_UNLESS(szLength == 4);
3815   DIE_UNLESS(bLength == 5);
3816 
3817   rc= mysql_stmt_fetch(stmt);
3818   DIE_UNLESS(rc == MYSQL_NO_DATA);
3819 
3820   mysql_stmt_close(stmt);
3821 }
3822 
3823 
3824 /* Test ext bind result */
3825 
test_bind_result_ext1()3826 static void test_bind_result_ext1()
3827 {
3828   MYSQL_STMT *stmt;
3829   uint       i;
3830   int        rc;
3831   char       t_data[20];
3832   float      s_data;
3833   short      i_data;
3834   uchar      b_data;
3835   int        f_data;
3836   long       bData;
3837   char       d_data[20];
3838   double     szData;
3839   MYSQL_BIND my_bind[8];
3840   ulong      length[8];
3841   my_bool    is_null[8];
3842   myheader("test_bind_result_ext1");
3843 
3844   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_result");
3845   myquery(rc);
3846 
3847   rc= mysql_query(mysql, "CREATE TABLE test_bind_result(c1 tinyint, c2 smallint, \
3848                                                         c3 int, c4 bigint, \
3849                                                         c5 float, c6 double, \
3850                                                         c7 varbinary(10), \
3851                                                         c8 varchar(10))");
3852   myquery(rc);
3853 
3854   rc= mysql_query(mysql, "INSERT INTO test_bind_result VALUES(120, 2999, 3999, 54, \
3855                                                               2.6, 58.89, \
3856                                                               '206', '6.7')");
3857   myquery(rc);
3858 
3859   rc= mysql_commit(mysql);
3860   myquery(rc);
3861 
3862   bzero((char*) my_bind, sizeof(my_bind));
3863   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
3864   my_bind[0].buffer= (void *) t_data;
3865   my_bind[0].buffer_length= sizeof(t_data);
3866   my_bind[0].error= &my_bind[0].error_value;
3867 
3868   my_bind[1].buffer_type= MYSQL_TYPE_FLOAT;
3869   my_bind[1].buffer= (void *)&s_data;
3870   my_bind[1].buffer_length= 0;
3871   my_bind[1].error= &my_bind[1].error_value;
3872 
3873   my_bind[2].buffer_type= MYSQL_TYPE_SHORT;
3874   my_bind[2].buffer= (void *)&i_data;
3875   my_bind[2].buffer_length= 0;
3876   my_bind[2].error= &my_bind[2].error_value;
3877 
3878   my_bind[3].buffer_type= MYSQL_TYPE_TINY;
3879   my_bind[3].buffer= (void *)&b_data;
3880   my_bind[3].buffer_length= 0;
3881   my_bind[3].error= &my_bind[3].error_value;
3882 
3883   my_bind[4].buffer_type= MYSQL_TYPE_LONG;
3884   my_bind[4].buffer= (void *)&f_data;
3885   my_bind[4].buffer_length= 0;
3886   my_bind[4].error= &my_bind[4].error_value;
3887 
3888   my_bind[5].buffer_type= MYSQL_TYPE_STRING;
3889   my_bind[5].buffer= (void *)d_data;
3890   my_bind[5].buffer_length= sizeof(d_data);
3891   my_bind[5].error= &my_bind[5].error_value;
3892 
3893   my_bind[6].buffer_type= MYSQL_TYPE_LONG;
3894   my_bind[6].buffer= (void *)&bData;
3895   my_bind[6].buffer_length= 0;
3896   my_bind[6].error= &my_bind[6].error_value;
3897 
3898   my_bind[7].buffer_type= MYSQL_TYPE_DOUBLE;
3899   my_bind[7].buffer= (void *)&szData;
3900   my_bind[7].buffer_length= 0;
3901   my_bind[7].error= &my_bind[7].error_value;
3902 
3903   for (i= 0; i < array_elements(my_bind); i++)
3904   {
3905     my_bind[i].is_null= &is_null[i];
3906     my_bind[i].length= &length[i];
3907   }
3908 
3909   stmt= mysql_simple_prepare(mysql, "select * from test_bind_result");
3910   check_stmt(stmt);
3911 
3912   rc= mysql_stmt_bind_result(stmt, my_bind);
3913   check_execute(stmt, rc);
3914 
3915   rc= mysql_stmt_execute(stmt);
3916   check_execute(stmt, rc);
3917 
3918   rc= mysql_stmt_fetch(stmt);
3919   printf("rc=%d\n", rc);
3920   DIE_UNLESS(rc == 0);
3921 
3922   if (!opt_silent)
3923   {
3924     fprintf(stdout, "\n data (tiny)   : %s(%lu)", t_data, length[0]);
3925     fprintf(stdout, "\n data (short)  : %f(%lu)", s_data, length[1]);
3926     fprintf(stdout, "\n data (int)    : %d(%lu)", i_data, length[2]);
3927     fprintf(stdout, "\n data (big)    : %d(%lu)", b_data, length[3]);
3928 
3929     fprintf(stdout, "\n data (float)  : %d(%lu)", f_data, length[4]);
3930     fprintf(stdout, "\n data (double) : %s(%lu)", d_data, length[5]);
3931 
3932     fprintf(stdout, "\n data (bin)    : %ld(%lu)", bData, length[6]);
3933     fprintf(stdout, "\n data (str)    : %g(%lu)", szData, length[7]);
3934   }
3935 
3936   DIE_UNLESS(strcmp(t_data, "120") == 0);
3937   DIE_UNLESS(i_data == 3999);
3938   DIE_UNLESS(f_data == 2);
3939   DIE_UNLESS(strcmp(d_data, "58.89") == 0);
3940   DIE_UNLESS(b_data == 54);
3941 
3942   DIE_UNLESS(length[0] == 3);
3943   DIE_UNLESS(length[1] == 4);
3944   DIE_UNLESS(length[2] == 2);
3945   DIE_UNLESS(length[3] == 1);
3946   DIE_UNLESS(length[4] == 4);
3947   DIE_UNLESS(length[5] == 5);
3948   DIE_UNLESS(length[6] == 4);
3949   DIE_UNLESS(length[7] == 8);
3950 
3951   rc= mysql_stmt_fetch(stmt);
3952   DIE_UNLESS(rc == MYSQL_NO_DATA);
3953 
3954   mysql_stmt_close(stmt);
3955 }
3956 
3957 
3958 /* Generalized fetch conversion routine for all basic types */
3959 
bind_fetch(int row_count)3960 static void bind_fetch(int row_count)
3961 {
3962   MYSQL_STMT   *stmt;
3963   int          rc, i, count= row_count;
3964   int32        data[10];
3965   int8         i8_data;
3966   int16        i16_data;
3967   int32        i32_data;
3968   longlong     i64_data;
3969   float        f_data;
3970   double       d_data;
3971   char         s_data[10];
3972   ulong        length[10];
3973   MYSQL_BIND   my_bind[7];
3974   my_bool      is_null[7];
3975 
3976   stmt= mysql_simple_prepare(mysql, "INSERT INTO test_bind_fetch VALUES "
3977                                     "(?, ?, ?, ?, ?, ?, ?)");
3978   check_stmt(stmt);
3979 
3980   verify_param_count(stmt, 7);
3981 
3982   /* Always bzero all members of bind parameter */
3983   bzero((char*) my_bind, sizeof(my_bind));
3984 
3985   for (i= 0; i < (int) array_elements(my_bind); i++)
3986   {
3987     my_bind[i].buffer_type= MYSQL_TYPE_LONG;
3988     my_bind[i].buffer= (void *) &data[i];
3989   }
3990   rc= mysql_stmt_bind_param(stmt, my_bind);
3991   check_execute(stmt, rc);
3992 
3993   while (count--)
3994   {
3995     rc= 10+count;
3996     for (i= 0; i < (int) array_elements(my_bind); i++)
3997     {
3998       data[i]= rc+i;
3999       rc+= 12;
4000     }
4001     rc= mysql_stmt_execute(stmt);
4002     check_execute(stmt, rc);
4003   }
4004 
4005   rc= mysql_commit(mysql);
4006   myquery(rc);
4007 
4008   mysql_stmt_close(stmt);
4009 
4010   rc= my_stmt_result("SELECT * FROM test_bind_fetch");
4011   DIE_UNLESS(row_count == rc);
4012 
4013   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_bind_fetch");
4014   check_stmt(stmt);
4015 
4016   for (i= 0; i < (int) array_elements(my_bind); i++)
4017   {
4018     my_bind[i].buffer= (void *) &data[i];
4019     my_bind[i].length= &length[i];
4020     my_bind[i].is_null= &is_null[i];
4021   }
4022 
4023   my_bind[0].buffer_type= MYSQL_TYPE_TINY;
4024   my_bind[0].buffer= (void *)&i8_data;
4025 
4026   my_bind[1].buffer_type= MYSQL_TYPE_SHORT;
4027   my_bind[1].buffer= (void *)&i16_data;
4028 
4029   my_bind[2].buffer_type= MYSQL_TYPE_LONG;
4030   my_bind[2].buffer= (void *)&i32_data;
4031 
4032   my_bind[3].buffer_type= MYSQL_TYPE_LONGLONG;
4033   my_bind[3].buffer= (void *)&i64_data;
4034 
4035   my_bind[4].buffer_type= MYSQL_TYPE_FLOAT;
4036   my_bind[4].buffer= (void *)&f_data;
4037 
4038   my_bind[5].buffer_type= MYSQL_TYPE_DOUBLE;
4039   my_bind[5].buffer= (void *)&d_data;
4040 
4041   my_bind[6].buffer_type= MYSQL_TYPE_STRING;
4042   my_bind[6].buffer= (void *)&s_data;
4043   my_bind[6].buffer_length= sizeof(s_data);
4044 
4045   rc= mysql_stmt_bind_result(stmt, my_bind);
4046   check_execute(stmt, rc);
4047 
4048   rc= mysql_stmt_execute(stmt);
4049   check_execute(stmt, rc);
4050 
4051   rc= mysql_stmt_store_result(stmt);
4052   check_execute(stmt, rc);
4053 
4054   while (row_count--)
4055   {
4056     rc= mysql_stmt_fetch(stmt);
4057     check_execute(stmt, rc);
4058 
4059     if (!opt_silent)
4060     {
4061       fprintf(stdout, "\n");
4062       fprintf(stdout, "\n tiny     : %ld(%lu)", (ulong) i8_data, length[0]);
4063       fprintf(stdout, "\n short    : %ld(%lu)", (ulong) i16_data, length[1]);
4064       fprintf(stdout, "\n int      : %ld(%lu)", (ulong) i32_data, length[2]);
4065       fprintf(stdout, "\n longlong : %ld(%lu)", (ulong) i64_data, length[3]);
4066       fprintf(stdout, "\n float    : %f(%lu)",  f_data,  length[4]);
4067       fprintf(stdout, "\n double   : %g(%lu)",  d_data,  length[5]);
4068       fprintf(stdout, "\n char     : %s(%lu)",  s_data,  length[6]);
4069     }
4070     rc= 10+row_count;
4071 
4072     /* TINY */
4073     DIE_UNLESS((int) i8_data == rc);
4074     DIE_UNLESS(length[0] == 1);
4075     rc+= 13;
4076 
4077     /* SHORT */
4078     DIE_UNLESS((int) i16_data == rc);
4079     DIE_UNLESS(length[1] == 2);
4080     rc+= 13;
4081 
4082     /* LONG */
4083     DIE_UNLESS((int) i32_data == rc);
4084     DIE_UNLESS(length[2] == 4);
4085     rc+= 13;
4086 
4087     /* LONGLONG */
4088     DIE_UNLESS((int) i64_data == rc);
4089     DIE_UNLESS(length[3] == 8);
4090     rc+= 13;
4091 
4092     /* FLOAT */
4093     DIE_UNLESS((int)f_data == rc);
4094     DIE_UNLESS(length[4] == 4);
4095     rc+= 13;
4096 
4097     /* DOUBLE */
4098     DIE_UNLESS((int)d_data == rc);
4099     DIE_UNLESS(length[5] == 8);
4100     rc+= 13;
4101 
4102     /* CHAR */
4103     {
4104       char buff[20];
4105       long len= sprintf(buff, "%d", rc);
4106       DIE_UNLESS(strcmp(s_data, buff) == 0);
4107       DIE_UNLESS(length[6] == (ulong) len);
4108     }
4109   }
4110   rc= mysql_stmt_fetch(stmt);
4111   DIE_UNLESS(rc == MYSQL_NO_DATA);
4112 
4113   mysql_stmt_close(stmt);
4114 }
4115 
4116 
4117 /* Test fetching of date, time and ts */
4118 
test_fetch_date()4119 static void test_fetch_date()
4120 {
4121   MYSQL_STMT *stmt;
4122   uint       i;
4123   int        rc, year;
4124   char       date[25], my_time[25], ts[25], ts_4[25], ts_6[20], dt[20];
4125   ulong      d_length, t_length, ts_length, ts4_length, ts6_length,
4126              dt_length, y_length;
4127   MYSQL_BIND my_bind[8];
4128   my_bool    is_null[8];
4129   ulong      length[8];
4130 
4131   myheader("test_fetch_date");
4132 
4133   /* Will not work if sql_mode is NO_ZERO_DATE (implicit if TRADITIONAL) */
4134   rc= mysql_query(mysql, "SET SQL_MODE=''");
4135   myquery(rc);
4136 
4137   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_result");
4138   myquery(rc);
4139 
4140   rc= mysql_query(mysql, "CREATE TABLE test_bind_result(c1 date, c2 time, \
4141                                                         c3 timestamp, \
4142                                                         c4 year, \
4143                                                         c5 datetime, \
4144                                                         c6 timestamp, \
4145                                                         c7 timestamp)");
4146   myquery(rc);
4147 
4148   rc= mysql_query(mysql, "SET SQL_MODE=''");
4149   rc= mysql_query(mysql, "INSERT INTO test_bind_result VALUES('2002-01-02', \
4150                                                               '12:49:00', \
4151                                                               '2002-01-02 17:46:59', \
4152                                                               2010, \
4153                                                               '2010-07-10', \
4154                                                               '2020', '1999-12-29')");
4155   myquery(rc);
4156 
4157   rc= mysql_commit(mysql);
4158   myquery(rc);
4159 
4160   bzero((char*) my_bind, sizeof(my_bind));
4161   for (i= 0; i < array_elements(my_bind); i++)
4162   {
4163     my_bind[i].is_null= &is_null[i];
4164     my_bind[i].length= &length[i];
4165   }
4166 
4167   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
4168   my_bind[1]= my_bind[2]= my_bind[0];
4169 
4170   my_bind[0].buffer= (void *)&date;
4171   my_bind[0].buffer_length= sizeof(date);
4172   my_bind[0].length= &d_length;
4173 
4174   my_bind[1].buffer= (void *)&my_time;
4175   my_bind[1].buffer_length= sizeof(my_time);
4176   my_bind[1].length= &t_length;
4177 
4178   my_bind[2].buffer= (void *)&ts;
4179   my_bind[2].buffer_length= sizeof(ts);
4180   my_bind[2].length= &ts_length;
4181 
4182   my_bind[3].buffer_type= MYSQL_TYPE_LONG;
4183   my_bind[3].buffer= (void *)&year;
4184   my_bind[3].length= &y_length;
4185 
4186   my_bind[4].buffer_type= MYSQL_TYPE_STRING;
4187   my_bind[4].buffer= (void *)&dt;
4188   my_bind[4].buffer_length= sizeof(dt);
4189   my_bind[4].length= &dt_length;
4190 
4191   my_bind[5].buffer_type= MYSQL_TYPE_STRING;
4192   my_bind[5].buffer= (void *)&ts_4;
4193   my_bind[5].buffer_length= sizeof(ts_4);
4194   my_bind[5].length= &ts4_length;
4195 
4196   my_bind[6].buffer_type= MYSQL_TYPE_STRING;
4197   my_bind[6].buffer= (void *)&ts_6;
4198   my_bind[6].buffer_length= sizeof(ts_6);
4199   my_bind[6].length= &ts6_length;
4200 
4201   rc= my_stmt_result("SELECT * FROM test_bind_result");
4202   DIE_UNLESS(rc == 1);
4203 
4204   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_bind_result");
4205   check_stmt(stmt);
4206 
4207   rc= mysql_stmt_bind_result(stmt, my_bind);
4208   check_execute(stmt, rc);
4209 
4210   rc= mysql_stmt_execute(stmt);
4211   check_execute(stmt, rc);
4212 
4213   ts_4[0]= '\0';
4214   rc= mysql_stmt_fetch(stmt);
4215   check_execute(stmt, rc);
4216 
4217   if (!opt_silent)
4218   {
4219     fprintf(stdout, "\n date   : %s(%lu)", date, d_length);
4220     fprintf(stdout, "\n time   : %s(%lu)", my_time, t_length);
4221     fprintf(stdout, "\n ts     : %s(%lu)", ts, ts_length);
4222     fprintf(stdout, "\n year   : %d(%lu)", year, y_length);
4223     fprintf(stdout, "\n dt     : %s(%lu)", dt,  dt_length);
4224     fprintf(stdout, "\n ts(4)  : %s(%lu)", ts_4, ts4_length);
4225     fprintf(stdout, "\n ts(6)  : %s(%lu)", ts_6, ts6_length);
4226   }
4227 
4228   DIE_UNLESS(strcmp(date, "2002-01-02") == 0);
4229   DIE_UNLESS(d_length == 10);
4230 
4231   DIE_UNLESS(strcmp(my_time, "12:49:00") == 0);
4232   DIE_UNLESS(t_length == 8);
4233 
4234   DIE_UNLESS(strcmp(ts, "2002-01-02 17:46:59") == 0);
4235   DIE_UNLESS(ts_length == 19);
4236 
4237   DIE_UNLESS(year == 2010);
4238   DIE_UNLESS(y_length == 4);
4239 
4240   DIE_UNLESS(strcmp(dt, "2010-07-10 00:00:00") == 0);
4241   DIE_UNLESS(dt_length == 19);
4242 
4243   DIE_UNLESS(strcmp(ts_4, "0000-00-00 00:00:00") == 0);
4244   DIE_UNLESS(ts4_length == strlen("0000-00-00 00:00:00"));
4245 
4246   DIE_UNLESS(strcmp(ts_6, "1999-12-29 00:00:00") == 0);
4247   DIE_UNLESS(ts6_length == 19);
4248 
4249   rc= mysql_stmt_fetch(stmt);
4250   DIE_UNLESS(rc == MYSQL_NO_DATA);
4251 
4252   mysql_stmt_close(stmt);
4253 }
4254 
4255 
4256 /* Test fetching of str to all types */
4257 
test_fetch_str()4258 static void test_fetch_str()
4259 {
4260   int rc;
4261 
4262   myheader("test_fetch_str");
4263 
4264   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4265   myquery(rc);
4266 
4267   rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 char(10), \
4268                                                      c2 char(10), \
4269                                                      c3 char(20), \
4270                                                      c4 char(20), \
4271                                                      c5 char(30), \
4272                                                      c6 char(40), \
4273                                                      c7 char(20))");
4274   myquery(rc);
4275 
4276   bind_fetch(3);
4277 }
4278 
4279 
4280 /* Test fetching of long to all types */
4281 
test_fetch_long()4282 static void test_fetch_long()
4283 {
4284   int rc;
4285 
4286   myheader("test_fetch_long");
4287 
4288   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4289   myquery(rc);
4290 
4291   rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 int unsigned, \
4292                                                      c2 int unsigned, \
4293                                                      c3 int, \
4294                                                      c4 int, \
4295                                                      c5 int, \
4296                                                      c6 int unsigned, \
4297                                                      c7 int)");
4298   myquery(rc);
4299 
4300   bind_fetch(4);
4301 }
4302 
4303 
4304 /* Test fetching of short to all types */
4305 
test_fetch_short()4306 static void test_fetch_short()
4307 {
4308   int rc;
4309 
4310   myheader("test_fetch_short");
4311 
4312   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4313   myquery(rc);
4314 
4315   rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 smallint unsigned, \
4316                                                      c2 smallint, \
4317                                                      c3 smallint unsigned, \
4318                                                      c4 smallint, \
4319                                                      c5 smallint, \
4320                                                      c6 smallint, \
4321                                                      c7 smallint unsigned)");
4322   myquery(rc);
4323 
4324   bind_fetch(5);
4325 }
4326 
4327 
4328 /* Test fetching of tiny to all types */
4329 
test_fetch_tiny()4330 static void test_fetch_tiny()
4331 {
4332   int rc;
4333 
4334   myheader("test_fetch_tiny");
4335 
4336   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4337   myquery(rc);
4338 
4339   rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 tinyint unsigned, \
4340                                                      c2 tinyint, \
4341                                                      c3 tinyint unsigned, \
4342                                                      c4 tinyint, \
4343                                                      c5 tinyint, \
4344                                                      c6 tinyint, \
4345                                                      c7 tinyint unsigned)");
4346   myquery(rc);
4347 
4348   bind_fetch(3);
4349 
4350 }
4351 
4352 
4353 /* Test fetching of longlong to all types */
4354 
test_fetch_bigint()4355 static void test_fetch_bigint()
4356 {
4357   int rc;
4358 
4359   myheader("test_fetch_bigint");
4360 
4361   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4362   myquery(rc);
4363 
4364   rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 bigint, \
4365                                                      c2 bigint, \
4366                                                      c3 bigint unsigned, \
4367                                                      c4 bigint unsigned, \
4368                                                      c5 bigint unsigned, \
4369                                                      c6 bigint unsigned, \
4370                                                      c7 bigint unsigned)");
4371   myquery(rc);
4372 
4373   bind_fetch(2);
4374 
4375 }
4376 
4377 
4378 /* Test fetching of float to all types */
4379 
test_fetch_float()4380 static void test_fetch_float()
4381 {
4382   int rc;
4383 
4384   myheader("test_fetch_float");
4385 
4386   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4387   myquery(rc);
4388 
4389   rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 float(3), \
4390                                                      c2 float, \
4391                                                      c3 float unsigned, \
4392                                                      c4 float, \
4393                                                      c5 float, \
4394                                                      c6 float, \
4395                                                      c7 float(10) unsigned)");
4396   myquery(rc);
4397 
4398   bind_fetch(2);
4399 
4400 }
4401 
4402 
4403 /* Test fetching of double to all types */
4404 
test_fetch_double()4405 static void test_fetch_double()
4406 {
4407   int rc;
4408 
4409   myheader("test_fetch_double");
4410 
4411   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bind_fetch");
4412   myquery(rc);
4413 
4414   rc= mysql_query(mysql, "CREATE TABLE test_bind_fetch(c1 double(5, 2), "
4415                          "c2 double unsigned, c3 double unsigned, "
4416                          "c4 double unsigned, c5 double unsigned, "
4417                          "c6 double unsigned, c7 double unsigned)");
4418   myquery(rc);
4419 
4420   bind_fetch(3);
4421 
4422 }
4423 
4424 
4425 /* Test simple prepare with all possible types */
4426 
test_prepare_ext()4427 static void test_prepare_ext()
4428 {
4429   MYSQL_STMT *stmt;
4430   int        rc;
4431   char       *sql;
4432   int        nData= 1;
4433   char       tData= 1;
4434   short      sData= 10;
4435   longlong   bData= 20;
4436   MYSQL_BIND my_bind[6];
4437   char query[MAX_TEST_QUERY_LENGTH];
4438   myheader("test_prepare_ext");
4439 
4440   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_ext");
4441   myquery(rc);
4442 
4443   sql= (char *)"CREATE TABLE test_prepare_ext"
4444                "("
4445                " c1  tinyint,"
4446                " c2  smallint,"
4447                " c3  mediumint,"
4448                " c4  int,"
4449                " c5  integer,"
4450                " c6  bigint,"
4451                " c7  float,"
4452                " c8  double,"
4453                " c9  double precision,"
4454                " c10 real,"
4455                " c11 decimal(7, 4),"
4456                " c12 numeric(8, 4),"
4457                " c13 date,"
4458                " c14 datetime,"
4459                " c15 timestamp,"
4460                " c16 time,"
4461                " c17 year,"
4462                " c18 bit,"
4463                " c19 bool,"
4464                " c20 char,"
4465                " c21 char(10),"
4466                " c22 varchar(30),"
4467                " c23 tinyblob,"
4468                " c24 tinytext,"
4469                " c25 blob,"
4470                " c26 text,"
4471                " c27 mediumblob,"
4472                " c28 mediumtext,"
4473                " c29 longblob,"
4474                " c30 longtext,"
4475                " c31 enum('one', 'two', 'three'),"
4476                " c32 set('monday', 'tuesday', 'wednesday'))";
4477 
4478   rc= mysql_query(mysql, sql);
4479   myquery(rc);
4480 
4481   /* insert by prepare - all integers */
4482   strmov(query, (char *)"INSERT INTO test_prepare_ext(c1, c2, c3, c4, c5, c6) VALUES(?, ?, ?, ?, ?, ?)");
4483   stmt= mysql_simple_prepare(mysql, query);
4484   check_stmt(stmt);
4485 
4486   verify_param_count(stmt, 6);
4487 
4488   /* Always bzero all members of bind parameter */
4489   bzero((char*) my_bind, sizeof(my_bind));
4490 
4491   /*tinyint*/
4492   my_bind[0].buffer_type= MYSQL_TYPE_TINY;
4493   my_bind[0].buffer= (void *)&tData;
4494 
4495   /*smallint*/
4496   my_bind[1].buffer_type= MYSQL_TYPE_SHORT;
4497   my_bind[1].buffer= (void *)&sData;
4498 
4499   /*mediumint*/
4500   my_bind[2].buffer_type= MYSQL_TYPE_LONG;
4501   my_bind[2].buffer= (void *)&nData;
4502 
4503   /*int*/
4504   my_bind[3].buffer_type= MYSQL_TYPE_LONG;
4505   my_bind[3].buffer= (void *)&nData;
4506 
4507   /*integer*/
4508   my_bind[4].buffer_type= MYSQL_TYPE_LONG;
4509   my_bind[4].buffer= (void *)&nData;
4510 
4511   /*bigint*/
4512   my_bind[5].buffer_type= MYSQL_TYPE_LONGLONG;
4513   my_bind[5].buffer= (void *)&bData;
4514 
4515   rc= mysql_stmt_bind_param(stmt, my_bind);
4516   check_execute(stmt, rc);
4517 
4518   /*
4519   *  integer to integer
4520   */
4521   for (nData= 0; nData<10; nData++, tData++, sData++, bData++)
4522   {
4523     rc= mysql_stmt_execute(stmt);
4524     check_execute(stmt, rc);
4525   }
4526   mysql_stmt_close(stmt);
4527 
4528   /* now fetch the results ..*/
4529 
4530   stmt= mysql_simple_prepare(mysql, "SELECT c1, c2, c3, c4, c5, c6 "
4531                                     "FROM test_prepare_ext");
4532   check_stmt(stmt);
4533 
4534   /* get the result */
4535   rc= mysql_stmt_execute(stmt);
4536   check_execute(stmt, rc);
4537 
4538   rc= my_process_stmt_result(stmt);
4539   DIE_UNLESS(nData == rc);
4540 
4541   mysql_stmt_close(stmt);
4542 }
4543 
4544 
4545 /* Test real and alias names */
4546 
test_field_names()4547 static void test_field_names()
4548 {
4549   int        rc;
4550   MYSQL_RES  *result;
4551 
4552   myheader("test_field_names");
4553 
4554   if (!opt_silent)
4555     fprintf(stdout, "\n %d, %d, %d", MYSQL_TYPE_DECIMAL, MYSQL_TYPE_NEWDATE, MYSQL_TYPE_ENUM);
4556   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_field_names1");
4557   myquery(rc);
4558 
4559   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_field_names2");
4560   myquery(rc);
4561 
4562   rc= mysql_query(mysql, "CREATE TABLE test_field_names1(id int, name varchar(50))");
4563   myquery(rc);
4564 
4565   rc= mysql_query(mysql, "CREATE TABLE test_field_names2(id int, name varchar(50))");
4566   myquery(rc);
4567 
4568   /* with table name included with TRUE column name */
4569   rc= mysql_query(mysql, "SELECT id as 'id-alias' FROM test_field_names1");
4570   myquery(rc);
4571 
4572   result= mysql_use_result(mysql);
4573   mytest(result);
4574 
4575   rc= my_process_result_set(result);
4576   DIE_UNLESS(rc == 0);
4577   mysql_free_result(result);
4578 
4579   /* with table name included with TRUE column name */
4580   rc= mysql_query(mysql, "SELECT t1.id as 'id-alias', test_field_names2.name FROM test_field_names1 t1, test_field_names2");
4581   myquery(rc);
4582 
4583   result= mysql_use_result(mysql);
4584   mytest(result);
4585 
4586   rc= my_process_result_set(result);
4587   DIE_UNLESS(rc == 0);
4588   mysql_free_result(result);
4589 }
4590 
4591 
4592 /* Test warnings */
4593 
test_warnings()4594 static void test_warnings()
4595 {
4596   int        rc;
4597   MYSQL_RES  *result;
4598 
4599   myheader("test_warnings");
4600 
4601   mysql_query(mysql, "DROP TABLE if exists test_non_exists");
4602 
4603   rc= mysql_query(mysql, "DROP TABLE if exists test_non_exists");
4604   myquery(rc);
4605 
4606   if (!opt_silent)
4607     fprintf(stdout, "\n total warnings: %d", mysql_warning_count(mysql));
4608   rc= mysql_query(mysql, "SHOW WARNINGS");
4609   myquery(rc);
4610 
4611   result= mysql_store_result(mysql);
4612   mytest(result);
4613 
4614   rc= my_process_result_set(result);
4615   DIE_UNLESS(rc == 1);
4616   mysql_free_result(result);
4617 }
4618 
4619 
4620 /* Test errors */
4621 
test_errors()4622 static void test_errors()
4623 {
4624   int        rc;
4625   MYSQL_RES  *result;
4626 
4627   myheader("test_errors");
4628 
4629   mysql_query(mysql, "DROP TABLE if exists test_non_exists");
4630 
4631   rc= mysql_query(mysql, "DROP TABLE test_non_exists");
4632   myquery_r(rc);
4633 
4634   rc= mysql_query(mysql, "SHOW ERRORS");
4635   myquery(rc);
4636 
4637   result= mysql_store_result(mysql);
4638   mytest(result);
4639 
4640   (void) my_process_result_set(result);
4641   mysql_free_result(result);
4642 }
4643 
4644 
4645 /* Test simple prepare-insert */
4646 
test_insert()4647 static void test_insert()
4648 {
4649   MYSQL_STMT *stmt;
4650   int        rc;
4651   char       str_data[50];
4652   char       tiny_data;
4653   MYSQL_RES  *result;
4654   MYSQL_BIND my_bind[2];
4655   ulong      length;
4656 
4657   myheader("test_insert");
4658 
4659   rc= mysql_autocommit(mysql, TRUE);
4660   myquery(rc);
4661 
4662   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prep_insert");
4663   myquery(rc);
4664 
4665   rc= mysql_query(mysql, "CREATE TABLE test_prep_insert(col1 tinyint, \
4666                                 col2 varchar(50))");
4667   myquery(rc);
4668 
4669   /* insert by prepare */
4670   stmt= mysql_simple_prepare(mysql,
4671                              "INSERT INTO test_prep_insert VALUES(?, ?)");
4672   check_stmt(stmt);
4673 
4674   verify_param_count(stmt, 2);
4675 
4676   /*
4677     We need to bzero bind structure because mysql_stmt_bind_param checks all
4678     its members.
4679   */
4680   bzero((char*) my_bind, sizeof(my_bind));
4681 
4682   /* tinyint */
4683   my_bind[0].buffer_type= MYSQL_TYPE_TINY;
4684   my_bind[0].buffer= (void *)&tiny_data;
4685 
4686   /* string */
4687   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
4688   my_bind[1].buffer= str_data;
4689   my_bind[1].buffer_length= sizeof(str_data);;
4690   my_bind[1].length= &length;
4691 
4692   rc= mysql_stmt_bind_param(stmt, my_bind);
4693   check_execute(stmt, rc);
4694 
4695   /* now, execute the prepared statement to insert 10 records.. */
4696   for (tiny_data= 0; tiny_data < 3; tiny_data++)
4697   {
4698     length= sprintf(str_data, "MySQL%d", tiny_data);
4699     rc= mysql_stmt_execute(stmt);
4700     check_execute(stmt, rc);
4701   }
4702 
4703   mysql_stmt_close(stmt);
4704 
4705   /* now fetch the results ..*/
4706   rc= mysql_commit(mysql);
4707   myquery(rc);
4708 
4709   /* test the results now, only one row should exist */
4710   rc= mysql_query(mysql, "SELECT * FROM test_prep_insert");
4711   myquery(rc);
4712 
4713   /* get the result */
4714   result= mysql_store_result(mysql);
4715   mytest(result);
4716 
4717   rc= my_process_result_set(result);
4718   DIE_UNLESS((int) tiny_data == rc);
4719   mysql_free_result(result);
4720 
4721 }
4722 
4723 
4724 /* Test simple prepare-resultset info */
4725 
test_prepare_resultset()4726 static void test_prepare_resultset()
4727 {
4728   MYSQL_STMT *stmt;
4729   int        rc;
4730   MYSQL_RES  *result;
4731 
4732   myheader("test_prepare_resultset");
4733 
4734   rc= mysql_autocommit(mysql, TRUE);
4735   myquery(rc);
4736 
4737   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_resultset");
4738   myquery(rc);
4739 
4740   rc= mysql_query(mysql, "CREATE TABLE test_prepare_resultset(id int, \
4741                                 name varchar(50), extra double)");
4742   myquery(rc);
4743 
4744   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_prepare_resultset");
4745   check_stmt(stmt);
4746 
4747   verify_param_count(stmt, 0);
4748 
4749   result= mysql_stmt_result_metadata(stmt);
4750   mytest(result);
4751   my_print_result_metadata(result);
4752   mysql_free_result(result);
4753   mysql_stmt_close(stmt);
4754 }
4755 
4756 
4757 /* Test field flags (verify .NET provider) */
4758 
test_field_flags()4759 static void test_field_flags()
4760 {
4761   int          rc;
4762   MYSQL_RES    *result;
4763   MYSQL_FIELD  *field;
4764   unsigned int i;
4765 
4766 
4767   myheader("test_field_flags");
4768 
4769   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_field_flags");
4770   myquery(rc);
4771 
4772   rc= mysql_query(mysql, "CREATE TABLE test_field_flags(id int NOT NULL AUTO_INCREMENT PRIMARY KEY, \
4773                                                         id1 int NOT NULL, \
4774                                                         id2 int UNIQUE, \
4775                                                         id3 int, \
4776                                                         id4 int NOT NULL, \
4777                                                         id5 int, \
4778                                                         KEY(id3, id4))");
4779   myquery(rc);
4780 
4781   /* with table name included with TRUE column name */
4782   rc= mysql_query(mysql, "SELECT * FROM test_field_flags");
4783   myquery(rc);
4784 
4785   result= mysql_use_result(mysql);
4786   mytest(result);
4787 
4788   mysql_field_seek(result, 0);
4789   if (!opt_silent)
4790     fputc('\n', stdout);
4791 
4792   for(i= 0; i< mysql_num_fields(result); i++)
4793   {
4794     field= mysql_fetch_field(result);
4795     if (!opt_silent)
4796     {
4797       fprintf(stdout, "\n field:%d", i);
4798       if (field->flags & NOT_NULL_FLAG)
4799         fprintf(stdout, "\n  NOT_NULL_FLAG");
4800       if (field->flags & PRI_KEY_FLAG)
4801         fprintf(stdout, "\n  PRI_KEY_FLAG");
4802       if (field->flags & UNIQUE_KEY_FLAG)
4803         fprintf(stdout, "\n  UNIQUE_KEY_FLAG");
4804       if (field->flags & MULTIPLE_KEY_FLAG)
4805         fprintf(stdout, "\n  MULTIPLE_KEY_FLAG");
4806       if (field->flags & AUTO_INCREMENT_FLAG)
4807         fprintf(stdout, "\n  AUTO_INCREMENT_FLAG");
4808 
4809     }
4810   }
4811   mysql_free_result(result);
4812 }
4813 
4814 
4815 /* Test mysql_stmt_close for open stmts */
4816 
test_stmt_close()4817 static void test_stmt_close()
4818 {
4819   MYSQL *lmysql;
4820   MYSQL_STMT *stmt1, *stmt2, *stmt3, *stmt_x;
4821   MYSQL_BIND  my_bind[1];
4822   MYSQL_RES   *result;
4823   unsigned int  count;
4824   int   rc;
4825   char query[MAX_TEST_QUERY_LENGTH];
4826 
4827   myheader("test_stmt_close");
4828 
4829   if (!opt_silent)
4830     fprintf(stdout, "\n Establishing a test connection ...");
4831   if (!(lmysql= mysql_client_init(NULL)))
4832   {
4833     myerror("mysql_client_init() failed");
4834     exit(1);
4835   }
4836   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
4837                            opt_password, current_db, opt_port,
4838                            opt_unix_socket, 0)))
4839   {
4840     myerror("connection failed");
4841     exit(1);
4842   }
4843   mysql_options(lmysql, MYSQL_OPT_RECONNECT, &my_true);
4844   if (!opt_silent)
4845     fprintf(stdout, "OK");
4846 
4847 
4848   /* set AUTOCOMMIT to ON*/
4849   mysql_autocommit(lmysql, TRUE);
4850 
4851   rc= mysql_query(lmysql, "SET SQL_MODE = ''");
4852   myquery(rc);
4853 
4854   rc= mysql_query(lmysql, "DROP TABLE IF EXISTS test_stmt_close");
4855   myquery(rc);
4856 
4857   rc= mysql_query(lmysql, "CREATE TABLE test_stmt_close(id int)");
4858   myquery(rc);
4859 
4860   strmov(query, "DO \"nothing\"");
4861   stmt1= mysql_simple_prepare(lmysql, query);
4862   check_stmt(stmt1);
4863 
4864   verify_param_count(stmt1, 0);
4865 
4866   strmov(query, "INSERT INTO test_stmt_close(id) VALUES(?)");
4867   stmt_x= mysql_simple_prepare(mysql, query);
4868   check_stmt(stmt_x);
4869 
4870   verify_param_count(stmt_x, 1);
4871 
4872   strmov(query, "UPDATE test_stmt_close SET id= ? WHERE id= ?");
4873   stmt3= mysql_simple_prepare(lmysql, query);
4874   check_stmt(stmt3);
4875 
4876   verify_param_count(stmt3, 2);
4877 
4878   strmov(query, "SELECT * FROM test_stmt_close WHERE id= ?");
4879   stmt2= mysql_simple_prepare(lmysql, query);
4880   check_stmt(stmt2);
4881 
4882   verify_param_count(stmt2, 1);
4883 
4884   rc= mysql_stmt_close(stmt1);
4885   if (!opt_silent)
4886     fprintf(stdout, "\n mysql_close_stmt(1) returned: %d", rc);
4887   DIE_UNLESS(rc == 0);
4888 
4889   /*
4890     Originally we were going to close all statements automatically in
4891     mysql_close(). This proved to not work well - users weren't able to
4892     close statements by hand once mysql_close() had been called.
4893     Now mysql_close() doesn't free any statements, so this test doesn't
4894     serve its original designation any more.
4895     Here we free stmt2 and stmt3 by hand to avoid memory leaks.
4896   */
4897   mysql_stmt_close(stmt2);
4898   mysql_stmt_close(stmt3);
4899   mysql_close(lmysql);
4900 
4901   /*
4902     We need to bzero bind structure because mysql_stmt_bind_param checks all
4903     its members.
4904   */
4905   bzero((char*) my_bind, sizeof(my_bind));
4906 
4907   my_bind[0].buffer= (void *)&count;
4908   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
4909   count= 100;
4910 
4911   rc= mysql_stmt_bind_param(stmt_x, my_bind);
4912   check_execute(stmt_x, rc);
4913 
4914   rc= mysql_stmt_execute(stmt_x);
4915   check_execute(stmt_x, rc);
4916 
4917   verify_st_affected_rows(stmt_x, 1);
4918 
4919   rc= mysql_stmt_close(stmt_x);
4920   if (!opt_silent)
4921     fprintf(stdout, "\n mysql_close_stmt(x) returned: %d", rc);
4922   DIE_UNLESS( rc == 0);
4923 
4924   rc= mysql_query(mysql, "SELECT id FROM test_stmt_close");
4925   myquery(rc);
4926 
4927   result= mysql_store_result(mysql);
4928   mytest(result);
4929 
4930   rc= my_process_result_set(result);
4931   DIE_UNLESS(rc == 1);
4932   mysql_free_result(result);
4933 }
4934 
4935 
4936 /* Test simple set variable prepare */
4937 
test_set_variable()4938 static void test_set_variable()
4939 {
4940   MYSQL_STMT *stmt, *stmt1;
4941   int        rc;
4942   int        set_count, def_count, get_count;
4943   ulong      length;
4944   char       var[NAME_LEN+1];
4945   MYSQL_BIND set_bind[1], get_bind[2];
4946 
4947   myheader("test_set_variable");
4948 
4949   mysql_autocommit(mysql, TRUE);
4950 
4951   stmt1= mysql_simple_prepare(mysql, "show variables like 'max_error_count'");
4952   check_stmt(stmt1);
4953 
4954   /*
4955     We need to bzero bind structure because mysql_stmt_bind_param checks all
4956     its members.
4957   */
4958   bzero((char*) get_bind, sizeof(get_bind));
4959 
4960   get_bind[0].buffer_type= MYSQL_TYPE_STRING;
4961   get_bind[0].buffer= (void *)var;
4962   get_bind[0].length= &length;
4963   get_bind[0].buffer_length= (int)NAME_LEN;
4964   length= NAME_LEN;
4965 
4966   get_bind[1].buffer_type= MYSQL_TYPE_LONG;
4967   get_bind[1].buffer= (void *)&get_count;
4968 
4969   rc= mysql_stmt_execute(stmt1);
4970   check_execute(stmt1, rc);
4971 
4972   rc= mysql_stmt_bind_result(stmt1, get_bind);
4973   check_execute(stmt1, rc);
4974 
4975   rc= mysql_stmt_fetch(stmt1);
4976   check_execute(stmt1, rc);
4977 
4978   if (!opt_silent)
4979     fprintf(stdout, "\n max_error_count(default): %d", get_count);
4980   def_count= get_count;
4981 
4982   DIE_UNLESS(strcmp(var, "max_error_count") == 0);
4983   rc= mysql_stmt_fetch(stmt1);
4984   DIE_UNLESS(rc == MYSQL_NO_DATA);
4985 
4986   stmt= mysql_simple_prepare(mysql, "set max_error_count= ?");
4987   check_stmt(stmt);
4988 
4989   bzero((char*) set_bind, sizeof(set_bind));
4990 
4991   set_bind[0].buffer_type= MYSQL_TYPE_LONG;
4992   set_bind[0].buffer= (void *)&set_count;
4993 
4994   rc= mysql_stmt_bind_param(stmt, set_bind);
4995   check_execute(stmt, rc);
4996 
4997   set_count= 31;
4998   rc= mysql_stmt_execute(stmt);
4999   check_execute(stmt, rc);
5000 
5001   mysql_commit(mysql);
5002 
5003   rc= mysql_stmt_execute(stmt1);
5004   check_execute(stmt1, rc);
5005 
5006   rc= mysql_stmt_fetch(stmt1);
5007   check_execute(stmt1, rc);
5008 
5009   if (!opt_silent)
5010     fprintf(stdout, "\n max_error_count         : %d", get_count);
5011   DIE_UNLESS(get_count == set_count);
5012 
5013   rc= mysql_stmt_fetch(stmt1);
5014   DIE_UNLESS(rc == MYSQL_NO_DATA);
5015 
5016   /* restore back to default */
5017   set_count= def_count;
5018   rc= mysql_stmt_execute(stmt);
5019   check_execute(stmt, rc);
5020 
5021   rc= mysql_stmt_execute(stmt1);
5022   check_execute(stmt1, rc);
5023 
5024   rc= mysql_stmt_fetch(stmt1);
5025   check_execute(stmt1, rc);
5026 
5027   if (!opt_silent)
5028     fprintf(stdout, "\n max_error_count(default): %d", get_count);
5029   DIE_UNLESS(get_count == set_count);
5030 
5031   rc= mysql_stmt_fetch(stmt1);
5032   DIE_UNLESS(rc == MYSQL_NO_DATA);
5033 
5034   mysql_stmt_close(stmt);
5035   mysql_stmt_close(stmt1);
5036 }
5037 
5038 /* Test FUNCTION field info / DATE_FORMAT() table_name . */
5039 
test_func_fields()5040 static void test_func_fields()
5041 {
5042   int        rc;
5043   MYSQL_RES  *result;
5044   MYSQL_FIELD *field;
5045 
5046   myheader("test_func_fields");
5047 
5048   rc= mysql_autocommit(mysql, TRUE);
5049   myquery(rc);
5050 
5051   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_dateformat");
5052   myquery(rc);
5053 
5054   rc= mysql_query(mysql, "CREATE TABLE test_dateformat(id int, \
5055                                                        ts timestamp)");
5056   myquery(rc);
5057 
5058   rc= mysql_query(mysql, "INSERT INTO test_dateformat(id) values(10)");
5059   myquery(rc);
5060 
5061   rc= mysql_query(mysql, "SELECT ts FROM test_dateformat");
5062   myquery(rc);
5063 
5064   result= mysql_store_result(mysql);
5065   mytest(result);
5066 
5067   field= mysql_fetch_field(result);
5068   mytest(field);
5069   if (!opt_silent)
5070     fprintf(stdout, "\n table name: `%s` (expected: `%s`)", field->table,
5071             "test_dateformat");
5072   DIE_UNLESS(strcmp(field->table, "test_dateformat") == 0);
5073 
5074   field= mysql_fetch_field(result);
5075   mytest_r(field); /* no more fields */
5076 
5077   mysql_free_result(result);
5078 
5079   /* DATE_FORMAT */
5080   rc= mysql_query(mysql, "SELECT DATE_FORMAT(ts, '%Y') AS 'venu' FROM test_dateformat");
5081   myquery(rc);
5082 
5083   result= mysql_store_result(mysql);
5084   mytest(result);
5085 
5086   field= mysql_fetch_field(result);
5087   mytest(field);
5088   if (!opt_silent)
5089     fprintf(stdout, "\n table name: `%s` (expected: `%s`)", field->table, "");
5090   DIE_UNLESS(field->table[0] == '\0');
5091 
5092   field= mysql_fetch_field(result);
5093   mytest_r(field); /* no more fields */
5094 
5095   mysql_free_result(result);
5096 
5097   /* FIELD ALIAS TEST */
5098   rc= mysql_query(mysql, "SELECT DATE_FORMAT(ts, '%Y')  AS 'YEAR' FROM test_dateformat");
5099   myquery(rc);
5100 
5101   result= mysql_store_result(mysql);
5102   mytest(result);
5103 
5104   field= mysql_fetch_field(result);
5105   mytest(field);
5106   if (!opt_silent)
5107   {
5108     printf("\n field name: `%s` (expected: `%s`)", field->name, "YEAR");
5109     printf("\n field org name: `%s` (expected: `%s`)", field->org_name, "");
5110   }
5111   DIE_UNLESS(strcmp(field->name, "YEAR") == 0);
5112   DIE_UNLESS(field->org_name[0] == '\0');
5113 
5114   field= mysql_fetch_field(result);
5115   mytest_r(field); /* no more fields */
5116 
5117   mysql_free_result(result);
5118 }
5119 
5120 
5121 /* Multiple stmts .. */
5122 
test_multi_stmt()5123 static void test_multi_stmt()
5124 {
5125 
5126   MYSQL_STMT  *stmt, *stmt1, *stmt2;
5127   int         rc;
5128   uint32      id;
5129   char        name[50];
5130   MYSQL_BIND  my_bind[2];
5131   ulong       length[2];
5132   my_bool     is_null[2];
5133   myheader("test_multi_stmt");
5134 
5135   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_multi_table");
5136   myquery(rc);
5137 
5138   rc= mysql_query(mysql, "CREATE TABLE test_multi_table(id int, name char(20))");
5139   myquery(rc);
5140 
5141   rc= mysql_query(mysql, "INSERT INTO test_multi_table values(10, 'mysql')");
5142   myquery(rc);
5143 
5144   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_multi_table "
5145                                     "WHERE id= ?");
5146   check_stmt(stmt);
5147 
5148   stmt2= mysql_simple_prepare(mysql, "UPDATE test_multi_table "
5149                                      "SET name='updated' WHERE id=10");
5150   check_stmt(stmt2);
5151 
5152   verify_param_count(stmt, 1);
5153 
5154   /*
5155     We need to bzero bind structure because mysql_stmt_bind_param checks all
5156     its members.
5157   */
5158   bzero((char*) my_bind, sizeof(my_bind));
5159 
5160   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
5161   my_bind[0].buffer= (void *)&id;
5162   my_bind[0].is_null= &is_null[0];
5163   my_bind[0].length= &length[0];
5164   is_null[0]= 0;
5165   length[0]= 0;
5166 
5167   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
5168   my_bind[1].buffer= (void *)name;
5169   my_bind[1].buffer_length= sizeof(name);
5170   my_bind[1].length= &length[1];
5171   my_bind[1].is_null= &is_null[1];
5172 
5173   rc= mysql_stmt_bind_param(stmt, my_bind);
5174   check_execute(stmt, rc);
5175 
5176   rc= mysql_stmt_bind_result(stmt, my_bind);
5177   check_execute(stmt, rc);
5178 
5179   id= 10;
5180   rc= mysql_stmt_execute(stmt);
5181   check_execute(stmt, rc);
5182 
5183   id= 999;
5184   rc= mysql_stmt_fetch(stmt);
5185   check_execute(stmt, rc);
5186 
5187   if (!opt_silent)
5188   {
5189     fprintf(stdout, "\n int_data: %lu(%lu)", (ulong) id, length[0]);
5190     fprintf(stdout, "\n str_data: %s(%lu)", name, length[1]);
5191   }
5192   DIE_UNLESS(id == 10);
5193   DIE_UNLESS(strcmp(name, "mysql") == 0);
5194 
5195   rc= mysql_stmt_fetch(stmt);
5196   DIE_UNLESS(rc == MYSQL_NO_DATA);
5197 
5198   /* alter the table schema now */
5199   stmt1= mysql_simple_prepare(mysql, "DELETE FROM test_multi_table "
5200                                      "WHERE id= ? AND "
5201                                      "CONVERT(name USING utf8)=?");
5202   check_stmt(stmt1);
5203 
5204   verify_param_count(stmt1, 2);
5205 
5206   rc= mysql_stmt_bind_param(stmt1, my_bind);
5207   check_execute(stmt1, rc);
5208 
5209   rc= mysql_stmt_execute(stmt2);
5210   check_execute(stmt2, rc);
5211 
5212   verify_st_affected_rows(stmt2, 1);
5213 
5214   rc= mysql_stmt_execute(stmt);
5215   check_execute(stmt, rc);
5216 
5217   rc= mysql_stmt_fetch(stmt);
5218   check_execute(stmt, rc);
5219 
5220   if (!opt_silent)
5221   {
5222     fprintf(stdout, "\n int_data: %lu(%lu)", (ulong) id, length[0]);
5223     fprintf(stdout, "\n str_data: %s(%lu)", name, length[1]);
5224   }
5225   DIE_UNLESS(id == 10);
5226   DIE_UNLESS(strcmp(name, "updated") == 0);
5227 
5228   rc= mysql_stmt_fetch(stmt);
5229   DIE_UNLESS(rc == MYSQL_NO_DATA);
5230 
5231   rc= mysql_stmt_execute(stmt1);
5232   check_execute(stmt1, rc);
5233 
5234   verify_st_affected_rows(stmt1, 1);
5235 
5236   mysql_stmt_close(stmt1);
5237 
5238   rc= mysql_stmt_execute(stmt);
5239   check_execute(stmt, rc);
5240 
5241   rc= mysql_stmt_fetch(stmt);
5242   DIE_UNLESS(rc == MYSQL_NO_DATA);
5243 
5244   rc= my_stmt_result("SELECT * FROM test_multi_table");
5245   DIE_UNLESS(rc == 0);
5246 
5247   mysql_stmt_close(stmt);
5248   mysql_stmt_close(stmt2);
5249 
5250 }
5251 
5252 
5253 /* Test simple sample - manual */
5254 
test_manual_sample()5255 static void test_manual_sample()
5256 {
5257   unsigned int param_count;
5258   MYSQL_STMT   *stmt;
5259   short        small_data= 1;
5260   int          int_data= 2;
5261   int          rc;
5262   char         str_data[50]= "std_data";
5263   ulonglong    affected_rows;
5264   MYSQL_BIND   my_bind[3];
5265   my_bool      is_null;
5266   char query[MAX_TEST_QUERY_LENGTH];
5267 
5268   myheader("test_manual_sample");
5269 
5270   /*
5271     Sample which is incorporated directly in the manual under Prepared
5272     statements section (Example from mysql_stmt_execute()
5273   */
5274 
5275   mysql_autocommit(mysql, 1);
5276   if (mysql_query(mysql, "DROP TABLE IF EXISTS test_table"))
5277   {
5278     fprintf(stderr, "\n drop table failed");
5279     fprintf(stderr, "\n %s", mysql_error(mysql));
5280     exit(1);
5281   }
5282   if (mysql_query(mysql, "CREATE TABLE test_table(col1 int, col2 varchar(50), \
5283                                                  col3 smallint, \
5284                                                  col4 timestamp)"))
5285   {
5286     fprintf(stderr, "\n create table failed");
5287     fprintf(stderr, "\n %s", mysql_error(mysql));
5288     exit(1);
5289   }
5290 
5291   /* Prepare a insert query with 3 parameters */
5292   strmov(query, "INSERT INTO test_table(col1, col2, col3) values(?, ?, ?)");
5293   if (!(stmt= mysql_simple_prepare(mysql, query)))
5294   {
5295     fprintf(stderr, "\n prepare, insert failed");
5296     fprintf(stderr, "\n %s", mysql_error(mysql));
5297     exit(1);
5298   }
5299   if (!opt_silent)
5300     fprintf(stdout, "\n prepare, insert successful");
5301 
5302   /* Get the parameter count from the statement */
5303   param_count= mysql_stmt_param_count(stmt);
5304 
5305   if (!opt_silent)
5306     fprintf(stdout, "\n total parameters in insert: %d", param_count);
5307   if (param_count != 3) /* validate parameter count */
5308   {
5309     fprintf(stderr, "\n invalid parameter count returned by MySQL");
5310     exit(1);
5311   }
5312 
5313   /* Bind the data for the parameters */
5314 
5315   /*
5316     We need to bzero bind structure because mysql_stmt_bind_param checks all
5317     its members.
5318   */
5319   bzero((char*) my_bind, sizeof(my_bind));
5320 
5321   /* INTEGER PART */
5322   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
5323   my_bind[0].buffer= (void *)&int_data;
5324 
5325   /* STRING PART */
5326   my_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
5327   my_bind[1].buffer= (void *)str_data;
5328   my_bind[1].buffer_length= sizeof(str_data);
5329 
5330   /* SMALLINT PART */
5331   my_bind[2].buffer_type= MYSQL_TYPE_SHORT;
5332   my_bind[2].buffer= (void *)&small_data;
5333   my_bind[2].is_null= &is_null;
5334   is_null= 0;
5335 
5336   /* Bind the buffers */
5337   if (mysql_stmt_bind_param(stmt, my_bind))
5338   {
5339     fprintf(stderr, "\n param bind failed");
5340     fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
5341     exit(1);
5342   }
5343 
5344   /* Specify the data */
5345   int_data= 10;             /* integer */
5346   strmov(str_data, "MySQL"); /* string  */
5347 
5348   /* INSERT SMALLINT data as NULL */
5349   is_null= 1;
5350 
5351   /* Execute the insert statement - 1*/
5352   if (mysql_stmt_execute(stmt))
5353   {
5354     fprintf(stderr, "\n execute 1 failed");
5355     fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
5356     exit(1);
5357   }
5358 
5359   /* Get the total rows affected */
5360   affected_rows= mysql_stmt_affected_rows(stmt);
5361 
5362   if (!opt_silent)
5363     fprintf(stdout, "\n total affected rows: %ld", (ulong) affected_rows);
5364   if (affected_rows != 1) /* validate affected rows */
5365   {
5366     fprintf(stderr, "\n invalid affected rows by MySQL");
5367     exit(1);
5368   }
5369 
5370   /* Re-execute the insert, by changing the values */
5371   int_data= 1000;
5372   strmov(str_data, "The most popular open source database");
5373   small_data= 1000;         /* smallint */
5374   is_null= 0;               /* reset */
5375 
5376   /* Execute the insert statement - 2*/
5377   if (mysql_stmt_execute(stmt))
5378   {
5379     fprintf(stderr, "\n execute 2 failed");
5380     fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
5381     exit(1);
5382   }
5383 
5384   /* Get the total rows affected */
5385   affected_rows= mysql_stmt_affected_rows(stmt);
5386 
5387   if (!opt_silent)
5388     fprintf(stdout, "\n total affected rows: %ld", (ulong) affected_rows);
5389   if (affected_rows != 1) /* validate affected rows */
5390   {
5391     fprintf(stderr, "\n invalid affected rows by MySQL");
5392     exit(1);
5393   }
5394 
5395   /* Close the statement */
5396   if (mysql_stmt_close(stmt))
5397   {
5398     fprintf(stderr, "\n failed while closing the statement");
5399     fprintf(stderr, "\n %s", mysql_stmt_error(stmt));
5400     exit(1);
5401   }
5402   rc= my_stmt_result("SELECT * FROM test_table");
5403   DIE_UNLESS(rc == 2);
5404 
5405   /* DROP THE TABLE */
5406   if (mysql_query(mysql, "DROP TABLE test_table"))
5407   {
5408     fprintf(stderr, "\n drop table failed");
5409     fprintf(stderr, "\n %s", mysql_error(mysql));
5410     exit(1);
5411   }
5412   if (!opt_silent)
5413     fprintf(stdout, "Success !!!");
5414 }
5415 
5416 
5417 /* Test alter table scenario in the middle of prepare */
5418 
test_prepare_alter()5419 static void test_prepare_alter()
5420 {
5421   MYSQL_STMT  *stmt;
5422   int         rc, id;
5423   MYSQL_BIND  my_bind[1];
5424   my_bool     is_null;
5425 
5426   myheader("test_prepare_alter");
5427 
5428   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prep_alter");
5429   myquery(rc);
5430 
5431   rc= mysql_query(mysql, "CREATE TABLE test_prep_alter(id int, name char(20))");
5432   myquery(rc);
5433 
5434   rc= mysql_query(mysql, "INSERT INTO test_prep_alter values(10, 'venu'), (20, 'mysql')");
5435   myquery(rc);
5436 
5437   stmt= mysql_simple_prepare(mysql, "INSERT INTO test_prep_alter VALUES(?, 'monty')");
5438   check_stmt(stmt);
5439 
5440   verify_param_count(stmt, 1);
5441 
5442   /*
5443     We need to bzero bind structure because mysql_stmt_bind_param checks all
5444     its members.
5445   */
5446   bzero((char*) my_bind, sizeof(my_bind));
5447 
5448   is_null= 0;
5449   my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
5450   my_bind[0].buffer= (void *)&id;
5451   my_bind[0].is_null= &is_null;
5452 
5453   rc= mysql_stmt_bind_param(stmt, my_bind);
5454   check_execute(stmt, rc);
5455 
5456   id= 30;
5457   rc= mysql_stmt_execute(stmt);
5458   check_execute(stmt, rc);
5459 
5460   if (thread_query("ALTER TABLE test_prep_alter change id id_new varchar(20)"))
5461     exit(1);
5462 
5463   is_null= 1;
5464   rc= mysql_stmt_execute(stmt);
5465   check_execute(stmt, rc);
5466 
5467   rc= my_stmt_result("SELECT * FROM test_prep_alter");
5468   DIE_UNLESS(rc == 4);
5469 
5470   mysql_stmt_close(stmt);
5471 }
5472 
5473 
5474 /* Test the support of multi-statement executions */
5475 
test_multi_statements()5476 static void test_multi_statements()
5477 {
5478   MYSQL *mysql_local;
5479   MYSQL_RES *result;
5480   int    rc;
5481 
5482   const char *query= "\
5483 DROP TABLE IF EXISTS test_multi_tab;\
5484 CREATE TABLE test_multi_tab(id int, name char(20));\
5485 INSERT INTO test_multi_tab(id) VALUES(10), (20);\
5486 INSERT INTO test_multi_tab VALUES(20, 'insert;comma');\
5487 SELECT * FROM test_multi_tab;\
5488 UPDATE test_multi_tab SET name='new;name' WHERE id=20;\
5489 DELETE FROM test_multi_tab WHERE name='new;name';\
5490 SELECT * FROM test_multi_tab;\
5491 DELETE FROM test_multi_tab WHERE id=10;\
5492 SELECT * FROM test_multi_tab;\
5493 DROP TABLE test_multi_tab;\
5494 select 1;\
5495 DROP TABLE IF EXISTS test_multi_tab";
5496   uint count, exp_value;
5497   uint rows[]= {0, 0, 2, 1, 3, 2, 2, 1, 1, 0, 0, 1, 0};
5498 
5499   myheader("test_multi_statements");
5500 
5501   /*
5502     First test that we get an error for multi statements
5503     (Because default connection is not opened with CLIENT_MULTI_STATEMENTS)
5504   */
5505   rc= mysql_query(mysql, query); /* syntax error */
5506   myquery_r(rc);
5507 
5508   rc= mysql_next_result(mysql);
5509   DIE_UNLESS(rc == -1);
5510   rc= mysql_more_results(mysql);
5511   DIE_UNLESS(rc == 0);
5512 
5513   if (!(mysql_local= mysql_client_init(NULL)))
5514   {
5515     fprintf(stdout, "\n mysql_client_init() failed");
5516     exit(1);
5517   }
5518 
5519   /* Create connection that supports multi statements */
5520   if (!(mysql_real_connect(mysql_local, opt_host, opt_user,
5521                            opt_password, current_db, opt_port,
5522                            opt_unix_socket, CLIENT_MULTI_STATEMENTS)))
5523   {
5524     fprintf(stdout, "\n connection failed(%s)", mysql_error(mysql_local));
5525     exit(1);
5526   }
5527   mysql_options(mysql_local, MYSQL_OPT_RECONNECT, &my_true);
5528 
5529   rc= mysql_query(mysql_local, query);
5530   myquery(rc);
5531 
5532   for (count= 0 ; count < array_elements(rows) ; count++)
5533   {
5534     if (!opt_silent)
5535       fprintf(stdout, "\n Query %d: ", count);
5536     if ((result= mysql_store_result(mysql_local)))
5537     {
5538       (void) my_process_result_set(result);
5539       mysql_free_result(result);
5540     }
5541     else if (!opt_silent)
5542       fprintf(stdout, "OK, %ld row(s) affected, %ld warning(s)\n",
5543               (ulong) mysql_affected_rows(mysql_local),
5544               (ulong) mysql_warning_count(mysql_local));
5545 
5546     exp_value= (uint) mysql_affected_rows(mysql_local);
5547     if (rows[count] !=  exp_value)
5548     {
5549       fprintf(stderr, "row %d  had affected rows: %d, should be %d\n",
5550               count, exp_value, rows[count]);
5551       exit(1);
5552     }
5553     if (count != array_elements(rows) -1)
5554     {
5555       if (!(rc= mysql_more_results(mysql_local)))
5556       {
5557         fprintf(stdout,
5558                 "mysql_more_result returned wrong value: %d for row %d\n",
5559                 rc, count);
5560         exit(1);
5561       }
5562       if ((rc= mysql_next_result(mysql_local)))
5563       {
5564         exp_value= mysql_errno(mysql_local);
5565 
5566         exit(1);
5567       }
5568     }
5569     else
5570     {
5571       rc= mysql_more_results(mysql_local);
5572       DIE_UNLESS(rc == 0);
5573       rc= mysql_next_result(mysql_local);
5574       DIE_UNLESS(rc == -1);
5575     }
5576   }
5577 
5578   /* check that errors abort multi statements */
5579 
5580   rc= mysql_query(mysql_local, "select 1+1+a;select 1+1");
5581   myquery_r(rc);
5582   rc= mysql_more_results(mysql_local);
5583   DIE_UNLESS(rc == 0);
5584   rc= mysql_next_result(mysql_local);
5585   DIE_UNLESS(rc == -1);
5586 
5587   rc= mysql_query(mysql_local, "select 1+1;select 1+1+a;select 1");
5588   myquery(rc);
5589   result= mysql_store_result(mysql_local);
5590   mytest(result);
5591   mysql_free_result(result);
5592   rc= mysql_more_results(mysql_local);
5593   DIE_UNLESS(rc == 1);
5594   rc= mysql_next_result(mysql_local);
5595   DIE_UNLESS(rc > 0);
5596 
5597   /*
5598     Ensure that we can now do a simple query (this checks that the server is
5599     not trying to send us the results for the last 'select 1'
5600   */
5601   rc= mysql_query(mysql_local, "select 1+1+1");
5602   myquery(rc);
5603   result= mysql_store_result(mysql_local);
5604   mytest(result);
5605   (void) my_process_result_set(result);
5606   mysql_free_result(result);
5607 
5608   /*
5609     Check if errors in one of the queries handled properly.
5610   */
5611   rc= mysql_query(mysql_local, "select 1; select * from not_existing_table");
5612   myquery(rc);
5613   result= mysql_store_result(mysql_local);
5614   mysql_free_result(result);
5615 
5616   rc= mysql_next_result(mysql_local);
5617   DIE_UNLESS(rc > 0);
5618 
5619   rc= mysql_next_result(mysql_local);
5620   DIE_UNLESS(rc < 0);
5621 
5622   mysql_close(mysql_local);
5623 }
5624 
5625 
5626 /*
5627   Check that Prepared statement cannot contain several
5628   SQL statements
5629 */
5630 
test_prepare_multi_statements()5631 static void test_prepare_multi_statements()
5632 {
5633   MYSQL *mysql_local;
5634   MYSQL_STMT *stmt;
5635   char query[MAX_TEST_QUERY_LENGTH];
5636   myheader("test_prepare_multi_statements");
5637 
5638   if (!(mysql_local= mysql_client_init(NULL)))
5639   {
5640     fprintf(stderr, "\n mysql_client_init() failed");
5641     exit(1);
5642   }
5643 
5644   if (!(mysql_real_connect(mysql_local, opt_host, opt_user,
5645                            opt_password, current_db, opt_port,
5646                            opt_unix_socket, CLIENT_MULTI_STATEMENTS)))
5647   {
5648     fprintf(stderr, "\n connection failed(%s)", mysql_error(mysql_local));
5649     exit(1);
5650   }
5651   mysql_options(mysql_local, MYSQL_OPT_RECONNECT, &my_true);
5652   strmov(query, "select 1; select 'another value'");
5653   stmt= mysql_simple_prepare(mysql_local, query);
5654   check_stmt_r(stmt);
5655   mysql_close(mysql_local);
5656 }
5657 
5658 
5659 /* Test simple bind store result */
5660 
test_store_result()5661 static void test_store_result()
5662 {
5663   MYSQL_STMT *stmt;
5664   int        rc;
5665   int32      nData;
5666   char       szData[100];
5667   MYSQL_BIND my_bind[2];
5668   ulong      length, length1;
5669   my_bool    is_null[2];
5670 
5671   myheader("test_store_result");
5672 
5673   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_store_result");
5674   myquery(rc);
5675 
5676   rc= mysql_query(mysql, "CREATE TABLE test_store_result(col1 int , col2 varchar(50))");
5677   myquery(rc);
5678 
5679   rc= mysql_query(mysql, "INSERT INTO test_store_result VALUES(10, 'venu'), (20, 'mysql')");
5680   myquery(rc);
5681 
5682   rc= mysql_query(mysql, "INSERT INTO test_store_result(col2) VALUES('monty')");
5683   myquery(rc);
5684 
5685   rc= mysql_commit(mysql);
5686   myquery(rc);
5687 
5688   /* fetch */
5689   bzero((char*) my_bind, sizeof(my_bind));
5690   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
5691   my_bind[0].buffer= (void *) &nData;       /* integer data */
5692   my_bind[0].length= &length;
5693   my_bind[0].is_null= &is_null[0];
5694 
5695   length= 0;
5696   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
5697   my_bind[1].buffer= szData;                /* string data */
5698   my_bind[1].buffer_length= sizeof(szData);
5699   my_bind[1].length= &length1;
5700   my_bind[1].is_null= &is_null[1];
5701   length1= 0;
5702 
5703   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_store_result");
5704   check_stmt(stmt);
5705 
5706   rc= mysql_stmt_bind_result(stmt, my_bind);
5707   check_execute(stmt, rc);
5708 
5709   rc= mysql_stmt_execute(stmt);
5710   check_execute(stmt, rc);
5711 
5712   rc= mysql_stmt_store_result(stmt);
5713   check_execute(stmt, rc);
5714 
5715   rc= mysql_stmt_fetch(stmt);
5716   check_execute(stmt, rc);
5717 
5718   if (!opt_silent)
5719     fprintf(stdout, "\n row 1: %ld, %s(%lu)", (long) nData, szData, length1);
5720   DIE_UNLESS(nData == 10);
5721   DIE_UNLESS(strcmp(szData, "venu") == 0);
5722   DIE_UNLESS(length1 == 4);
5723 
5724   rc= mysql_stmt_fetch(stmt);
5725   check_execute(stmt, rc);
5726 
5727   if (!opt_silent)
5728     fprintf(stdout, "\n row 2: %ld, %s(%lu)", (long) nData, szData, length1);
5729   DIE_UNLESS(nData == 20);
5730   DIE_UNLESS(strcmp(szData, "mysql") == 0);
5731   DIE_UNLESS(length1 == 5);
5732 
5733   length= 99;
5734   rc= mysql_stmt_fetch(stmt);
5735   check_execute(stmt, rc);
5736 
5737   if (!opt_silent && is_null[0])
5738     fprintf(stdout, "\n row 3: NULL, %s(%lu)", szData, length1);
5739   DIE_UNLESS(is_null[0]);
5740   DIE_UNLESS(strcmp(szData, "monty") == 0);
5741   DIE_UNLESS(length1 == 5);
5742 
5743   rc= mysql_stmt_fetch(stmt);
5744   DIE_UNLESS(rc == MYSQL_NO_DATA);
5745 
5746   rc= mysql_stmt_execute(stmt);
5747   check_execute(stmt, rc);
5748 
5749   rc= mysql_stmt_store_result(stmt);
5750   check_execute(stmt, rc);
5751 
5752   rc= mysql_stmt_fetch(stmt);
5753   check_execute(stmt, rc);
5754 
5755   if (!opt_silent)
5756     fprintf(stdout, "\n row 1: %ld, %s(%lu)", (long) nData, szData, length1);
5757   DIE_UNLESS(nData == 10);
5758   DIE_UNLESS(strcmp(szData, "venu") == 0);
5759   DIE_UNLESS(length1 == 4);
5760 
5761   rc= mysql_stmt_fetch(stmt);
5762   check_execute(stmt, rc);
5763 
5764   if (!opt_silent)
5765     fprintf(stdout, "\n row 2: %ld, %s(%lu)", (long) nData, szData, length1);
5766   DIE_UNLESS(nData == 20);
5767   DIE_UNLESS(strcmp(szData, "mysql") == 0);
5768   DIE_UNLESS(length1 == 5);
5769 
5770   length= 99;
5771   rc= mysql_stmt_fetch(stmt);
5772   check_execute(stmt, rc);
5773 
5774   if (!opt_silent && is_null[0])
5775     fprintf(stdout, "\n row 3: NULL, %s(%lu)", szData, length1);
5776   DIE_UNLESS(is_null[0]);
5777   DIE_UNLESS(strcmp(szData, "monty") == 0);
5778   DIE_UNLESS(length1 == 5);
5779 
5780   rc= mysql_stmt_fetch(stmt);
5781   DIE_UNLESS(rc == MYSQL_NO_DATA);
5782 
5783   mysql_stmt_close(stmt);
5784 }
5785 
5786 
5787 /* Test simple bind store result */
5788 
test_store_result1()5789 static void test_store_result1()
5790 {
5791   MYSQL_STMT *stmt;
5792   int        rc;
5793 
5794   myheader("test_store_result1");
5795 
5796   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_store_result");
5797   myquery(rc);
5798 
5799   rc= mysql_query(mysql, "CREATE TABLE test_store_result(col1 int , col2 varchar(50))");
5800   myquery(rc);
5801 
5802   rc= mysql_query(mysql, "INSERT INTO test_store_result VALUES(10, 'venu'), (20, 'mysql')");
5803   myquery(rc);
5804 
5805   rc= mysql_query(mysql, "INSERT INTO test_store_result(col2) VALUES('monty')");
5806   myquery(rc);
5807 
5808   rc= mysql_commit(mysql);
5809   myquery(rc);
5810 
5811   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_store_result");
5812   check_stmt(stmt);
5813 
5814   rc= mysql_stmt_execute(stmt);
5815   check_execute(stmt, rc);
5816 
5817   rc= mysql_stmt_store_result(stmt);
5818   check_execute(stmt, rc);
5819 
5820   rc= 0;
5821   while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
5822     rc++;
5823   if (!opt_silent)
5824     fprintf(stdout, "\n total rows: %d", rc);
5825   DIE_UNLESS(rc == 3);
5826 
5827   rc= mysql_stmt_execute(stmt);
5828   check_execute(stmt, rc);
5829 
5830   rc= mysql_stmt_store_result(stmt);
5831   check_execute(stmt, rc);
5832 
5833   rc= 0;
5834   while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
5835     rc++;
5836   if (!opt_silent)
5837     fprintf(stdout, "\n total rows: %d", rc);
5838   DIE_UNLESS(rc == 3);
5839 
5840   mysql_stmt_close(stmt);
5841 }
5842 
5843 
5844 /* Another test for bind and store result */
5845 
test_store_result2()5846 static void test_store_result2()
5847 {
5848   MYSQL_STMT *stmt;
5849   int        rc;
5850   int        nData;
5851   ulong      length;
5852   MYSQL_BIND my_bind[1];
5853   char query[MAX_TEST_QUERY_LENGTH];
5854 
5855   myheader("test_store_result2");
5856 
5857   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_store_result");
5858   myquery(rc);
5859 
5860   rc= mysql_query(mysql, "CREATE TABLE test_store_result(col1 int , col2 varchar(50))");
5861   myquery(rc);
5862 
5863   rc= mysql_query(mysql, "INSERT INTO test_store_result VALUES(10, 'venu'), (20, 'mysql')");
5864   myquery(rc);
5865 
5866   rc= mysql_query(mysql, "INSERT INTO test_store_result(col2) VALUES('monty')");
5867   myquery(rc);
5868 
5869   rc= mysql_commit(mysql);
5870   myquery(rc);
5871 
5872   /*
5873     We need to bzero bind structure because mysql_stmt_bind_param checks all
5874     its members.
5875   */
5876   bzero((char*) my_bind, sizeof(my_bind));
5877 
5878   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
5879   my_bind[0].buffer= (void *) &nData;      /* integer data */
5880   my_bind[0].length= &length;
5881   my_bind[0].is_null= 0;
5882 
5883   strmov((char *)query , "SELECT col1 FROM test_store_result where col1= ?");
5884   stmt= mysql_simple_prepare(mysql, query);
5885   check_stmt(stmt);
5886 
5887   rc= mysql_stmt_bind_param(stmt, my_bind);
5888   check_execute(stmt, rc);
5889 
5890   rc= mysql_stmt_bind_result(stmt, my_bind);
5891   check_execute(stmt, rc);
5892 
5893   nData= 10; length= 0;
5894   rc= mysql_stmt_execute(stmt);
5895   check_execute(stmt, rc);
5896 
5897   nData= 0;
5898   rc= mysql_stmt_store_result(stmt);
5899   check_execute(stmt, rc);
5900 
5901   rc= mysql_stmt_fetch(stmt);
5902   check_execute(stmt, rc);
5903 
5904   if (!opt_silent)
5905     fprintf(stdout, "\n row 1: %d", nData);
5906   DIE_UNLESS(nData == 10);
5907 
5908   rc= mysql_stmt_fetch(stmt);
5909   DIE_UNLESS(rc == MYSQL_NO_DATA);
5910 
5911   nData= 20;
5912   rc= mysql_stmt_execute(stmt);
5913   check_execute(stmt, rc);
5914 
5915   nData= 0;
5916   rc= mysql_stmt_store_result(stmt);
5917   check_execute(stmt, rc);
5918 
5919   rc= mysql_stmt_fetch(stmt);
5920   check_execute(stmt, rc);
5921 
5922   if (!opt_silent)
5923     fprintf(stdout, "\n row 1: %d", nData);
5924   DIE_UNLESS(nData == 20);
5925 
5926   rc= mysql_stmt_fetch(stmt);
5927   DIE_UNLESS(rc == MYSQL_NO_DATA);
5928   mysql_stmt_close(stmt);
5929 }
5930 
5931 
5932 /* Test simple subselect prepare */
5933 
test_subselect()5934 static void test_subselect()
5935 {
5936 
5937   MYSQL_STMT *stmt;
5938   int        rc, id;
5939   MYSQL_BIND my_bind[1];
5940   DBUG_ENTER("test_subselect");
5941 
5942   myheader("test_subselect");
5943 
5944   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_sub1");
5945   myquery(rc);
5946 
5947   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_sub2");
5948   myquery(rc);
5949 
5950   rc= mysql_query(mysql, "CREATE TABLE test_sub1(id int)");
5951   myquery(rc);
5952 
5953   rc= mysql_query(mysql, "CREATE TABLE test_sub2(id int, id1 int)");
5954   myquery(rc);
5955 
5956   rc= mysql_query(mysql, "INSERT INTO test_sub1 values(2)");
5957   myquery(rc);
5958 
5959   rc= mysql_query(mysql, "INSERT INTO test_sub2 VALUES(1, 7), (2, 7)");
5960   myquery(rc);
5961 
5962   rc= mysql_commit(mysql);
5963   myquery(rc);
5964 
5965   /* fetch */
5966   /*
5967     We need to bzero bind structure because mysql_stmt_bind_param checks all
5968     its members.
5969   */
5970   bzero((char*) my_bind, sizeof(my_bind));
5971 
5972   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
5973   my_bind[0].buffer= (void *) &id;
5974   my_bind[0].length= 0;
5975   my_bind[0].is_null= 0;
5976 
5977   stmt= mysql_simple_prepare(mysql, "INSERT INTO test_sub2(id) SELECT * FROM test_sub1 WHERE id= ?");
5978   check_stmt(stmt);
5979 
5980   rc= mysql_stmt_bind_param(stmt, my_bind);
5981   check_execute(stmt, rc);
5982 
5983   id= 2;
5984   rc= mysql_stmt_execute(stmt);
5985   check_execute(stmt, rc);
5986 
5987   verify_st_affected_rows(stmt, 1);
5988 
5989   id= 9;
5990   rc= mysql_stmt_execute(stmt);
5991   check_execute(stmt, rc);
5992 
5993   verify_st_affected_rows(stmt, 0);
5994 
5995   mysql_stmt_close(stmt);
5996 
5997   rc= my_stmt_result("SELECT * FROM test_sub2");
5998   DIE_UNLESS(rc == 3);
5999 
6000   rc= my_stmt_result("SELECT ROW(1, 7) IN (select id, id1 "
6001                      "from test_sub2 WHERE id1= 8)");
6002   DIE_UNLESS(rc == 1);
6003   rc= my_stmt_result("SELECT ROW(1, 7) IN (select id, id1 "
6004                      "from test_sub2 WHERE id1= 7)");
6005   DIE_UNLESS(rc == 1);
6006 
6007   stmt= mysql_simple_prepare(mysql, ("SELECT ROW(1, 7) IN (select id, id1 "
6008                                      "from test_sub2 WHERE id1= ?)"));
6009   check_stmt(stmt);
6010 
6011   rc= mysql_stmt_bind_param(stmt, my_bind);
6012   check_execute(stmt, rc);
6013 
6014   rc= mysql_stmt_bind_result(stmt, my_bind);
6015   check_execute(stmt, rc);
6016 
6017   id= 7;
6018   rc= mysql_stmt_execute(stmt);
6019   check_execute(stmt, rc);
6020 
6021   rc= mysql_stmt_fetch(stmt);
6022   check_execute(stmt, rc);
6023 
6024   if (!opt_silent)
6025     fprintf(stdout, "\n row 1: %d", id);
6026   DIE_UNLESS(id == 1);
6027 
6028   rc= mysql_stmt_fetch(stmt);
6029   DIE_UNLESS(rc == MYSQL_NO_DATA);
6030 
6031   id= 8;
6032   rc= mysql_stmt_execute(stmt);
6033   check_execute(stmt, rc);
6034 
6035   rc= mysql_stmt_fetch(stmt);
6036   check_execute(stmt, rc);
6037 
6038   if (!opt_silent)
6039     fprintf(stdout, "\n row 1: %d", id);
6040   DIE_UNLESS(id == 0);
6041 
6042   rc= mysql_stmt_fetch(stmt);
6043   DIE_UNLESS(rc == MYSQL_NO_DATA);
6044 
6045   mysql_stmt_close(stmt);
6046   DBUG_VOID_RETURN;
6047 }
6048 
6049 
6050 /*
6051   Generalized conversion routine to handle DATE, TIME and DATETIME
6052   conversion using MYSQL_TIME structure
6053 */
6054 
test_bind_date_conv(uint row_count)6055 static void test_bind_date_conv(uint row_count)
6056 {
6057   MYSQL_STMT   *stmt= 0;
6058   uint         rc, i, count= row_count;
6059   ulong        length[4];
6060   MYSQL_BIND   my_bind[4];
6061   my_bool      is_null[4]= {0};
6062   MYSQL_TIME   tm[4];
6063   ulong        second_part;
6064   uint         year, month, day, hour, minute, sec;
6065   uint         now_year= 1990, now_month= 3, now_day= 13;
6066 
6067   rc= mysql_query(mysql, "SET timestamp=UNIX_TIMESTAMP('1990-03-13')");
6068   myquery(rc);
6069 
6070   stmt= mysql_simple_prepare(mysql, "INSERT INTO test_date VALUES(?, ?, ?, ?)");
6071   check_stmt(stmt);
6072 
6073   verify_param_count(stmt, 4);
6074 
6075   /*
6076     We need to bzero bind structure because mysql_stmt_bind_param checks all
6077     its members.
6078   */
6079   bzero((char*) my_bind, sizeof(my_bind));
6080 
6081   my_bind[0].buffer_type= MYSQL_TYPE_TIMESTAMP;
6082   my_bind[1].buffer_type= MYSQL_TYPE_TIME;
6083   my_bind[2].buffer_type= MYSQL_TYPE_DATETIME;
6084   my_bind[3].buffer_type= MYSQL_TYPE_DATE;
6085 
6086   for (i= 0; i < (int) array_elements(my_bind); i++)
6087   {
6088     my_bind[i].buffer= (void *) &tm[i];
6089     my_bind[i].is_null= &is_null[i];
6090     my_bind[i].length= &length[i];
6091     my_bind[i].buffer_length= 30;
6092     length[i]= 20;
6093   }
6094 
6095   second_part= 0;
6096 
6097   year= 2000;
6098   month= 01;
6099   day= 10;
6100 
6101   hour= 11;
6102   minute= 16;
6103   sec= 20;
6104 
6105   rc= mysql_stmt_bind_param(stmt, my_bind);
6106   check_execute(stmt, rc);
6107 
6108   for (count= 0; count < row_count; count++)
6109   {
6110     for (i= 0; i < (int) array_elements(my_bind); i++)
6111     {
6112       tm[i].neg= 0;
6113       tm[i].second_part= second_part+count;
6114       if (my_bind[i].buffer_type != MYSQL_TYPE_TIME)
6115       {
6116         tm[i].year= year+count;
6117         tm[i].month= month+count;
6118         tm[i].day= day+count;
6119       }
6120       else
6121         tm[i].year= tm[i].month= tm[i].day= 0;
6122       if (my_bind[i].buffer_type != MYSQL_TYPE_DATE)
6123       {
6124         tm[i].hour= hour+count;
6125         tm[i].minute= minute+count;
6126         tm[i].second= sec+count;
6127       }
6128       else
6129         tm[i].hour= tm[i].minute= tm[i].second= 0;
6130     }
6131     rc= mysql_stmt_execute(stmt);
6132     check_execute(stmt, rc);
6133   }
6134 
6135   rc= mysql_commit(mysql);
6136   myquery(rc);
6137 
6138   mysql_stmt_close(stmt);
6139 
6140   rc= my_stmt_result("SELECT * FROM test_date");
6141   DIE_UNLESS(row_count == rc);
6142 
6143   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_date");
6144   check_stmt(stmt);
6145 
6146   rc= mysql_stmt_bind_result(stmt, my_bind);
6147   check_execute(stmt, rc);
6148 
6149   rc= mysql_stmt_execute(stmt);
6150   check_execute(stmt, rc);
6151 
6152   rc= mysql_stmt_store_result(stmt);
6153   check_execute(stmt, rc);
6154 
6155   for (count= 0; count < row_count; count++)
6156   {
6157     rc= mysql_stmt_fetch(stmt);
6158     DIE_UNLESS(rc == 0 || rc == MYSQL_DATA_TRUNCATED);
6159 
6160     if (!opt_silent)
6161       fprintf(stdout, "\n");
6162     for (i= 0; i < array_elements(my_bind); i++)
6163     {
6164       if (!opt_silent)
6165         fprintf(stdout, "\ntime[%d]: %02d-%02d-%02d %02d:%02d:%02d.%02lu",
6166                 i, tm[i].year, tm[i].month, tm[i].day,
6167                 tm[i].hour, tm[i].minute, tm[i].second,
6168                 tm[i].second_part);
6169       DIE_UNLESS(tm[i].year == 0 || tm[i].year == year + count ||
6170                  (tm[i].year == now_year &&
6171                   my_bind[i].buffer_type == MYSQL_TYPE_TIME));
6172       DIE_UNLESS(tm[i].month == 0 || tm[i].month == month + count ||
6173                  (tm[i].month == now_month &&
6174                   my_bind[i].buffer_type == MYSQL_TYPE_TIME));
6175       DIE_UNLESS(tm[i].day == 0 || tm[i].day == day + count ||
6176                  (tm[i].day == now_day &&
6177                   my_bind[i].buffer_type == MYSQL_TYPE_TIME));
6178 
6179       DIE_UNLESS(tm[i].hour == 0 || tm[i].hour == hour+count);
6180       DIE_UNLESS(tm[i].minute == 0 || tm[i].minute == minute+count);
6181       DIE_UNLESS(tm[i].second == 0 || tm[i].second == sec+count);
6182       DIE_UNLESS(tm[i].second_part == 0 ||
6183                  tm[i].second_part == second_part+count);
6184     }
6185   }
6186   rc= mysql_stmt_fetch(stmt);
6187   DIE_UNLESS(rc == MYSQL_NO_DATA);
6188 
6189   mysql_stmt_close(stmt);
6190 }
6191 
6192 
6193 /* Test DATE, TIME, DATETIME and TS with MYSQL_TIME conversion */
6194 
test_date()6195 static void test_date()
6196 {
6197   int        rc;
6198 
6199   myheader("test_date");
6200 
6201   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6202   myquery(rc);
6203 
6204   rc= mysql_query(mysql, "CREATE TABLE test_date(c1 TIMESTAMP, \
6205                                                  c2 TIME, \
6206                                                  c3 DATETIME, \
6207                                                  c4 DATE)");
6208 
6209   myquery(rc);
6210 
6211   test_bind_date_conv(5);
6212 }
6213 
6214 
6215 /* Test all time types to DATE and DATE to all types */
6216 
test_date_date()6217 static void test_date_date()
6218 {
6219   int        rc;
6220 
6221   myheader("test_date_date");
6222 
6223   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6224   myquery(rc);
6225 
6226   rc= mysql_query(mysql, "CREATE TABLE test_date(c1 DATE, \
6227                                                  c2 DATE, \
6228                                                  c3 DATE, \
6229                                                  c4 DATE)");
6230 
6231   myquery(rc);
6232 
6233   test_bind_date_conv(3);
6234 }
6235 
6236 
6237 /* Test all time types to TIME and TIME to all types */
6238 
test_date_time()6239 static void test_date_time()
6240 {
6241   int        rc;
6242 
6243   myheader("test_date_time");
6244 
6245   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6246   myquery(rc);
6247 
6248   rc= mysql_query(mysql, "CREATE TABLE test_date(c1 TIME, \
6249                                                  c2 TIME, \
6250                                                  c3 TIME, \
6251                                                  c4 TIME)");
6252 
6253   myquery(rc);
6254 
6255   test_bind_date_conv(3);
6256 }
6257 
6258 
6259 /* Test all time types to TIMESTAMP and TIMESTAMP to all types */
6260 
test_date_ts()6261 static void test_date_ts()
6262 {
6263   int        rc;
6264 
6265   myheader("test_date_ts");
6266 
6267   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6268   myquery(rc);
6269 
6270   rc= mysql_query(mysql, "CREATE TABLE test_date(c1 TIMESTAMP, \
6271                                                  c2 TIMESTAMP, \
6272                                                  c3 TIMESTAMP, \
6273                                                  c4 TIMESTAMP)");
6274 
6275   myquery(rc);
6276 
6277   test_bind_date_conv(2);
6278 }
6279 
6280 
6281 /* Test all time types to DATETIME and DATETIME to all types */
6282 
test_date_dt()6283 static void test_date_dt()
6284 {
6285   int rc;
6286 
6287   myheader("test_date_dt");
6288 
6289   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_date");
6290   myquery(rc);
6291 
6292   rc= mysql_query(mysql, "CREATE TABLE test_date(c1 datetime, "
6293                          " c2 datetime, c3 datetime, c4 date)");
6294   myquery(rc);
6295 
6296   test_bind_date_conv(2);
6297 }
6298 
6299 
6300 /* Misc tests to keep pure coverage happy */
6301 
test_pure_coverage()6302 static void test_pure_coverage()
6303 {
6304   MYSQL_STMT *stmt;
6305   MYSQL_BIND my_bind[2];
6306   int        rc;
6307   ulong      length;
6308 
6309   myheader("test_pure_coverage");
6310 
6311   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_pure");
6312   myquery(rc);
6313 
6314   rc= mysql_query(mysql, "CREATE TABLE test_pure(c1 int, c2 varchar(20))");
6315   myquery(rc);
6316 
6317   stmt= mysql_simple_prepare(mysql, "insert into test_pure(c67788) values(10)");
6318   check_stmt_r(stmt);
6319 
6320   /* Query without params and result should allow to bind 0 arrays */
6321   stmt= mysql_simple_prepare(mysql, "insert into test_pure(c2) values(10)");
6322   check_stmt(stmt);
6323 
6324   rc= mysql_stmt_bind_param(stmt, (MYSQL_BIND*)0);
6325   check_execute(stmt, rc);
6326 
6327   rc= mysql_stmt_execute(stmt);
6328   check_execute(stmt, rc);
6329 
6330   rc= mysql_stmt_bind_result(stmt, (MYSQL_BIND*)0);
6331   DIE_UNLESS(rc == 1);
6332 
6333   mysql_stmt_close(stmt);
6334 
6335   stmt= mysql_simple_prepare(mysql, "insert into test_pure(c2) values(?)");
6336   check_stmt(stmt);
6337 
6338   /*
6339     We need to bzero bind structure because mysql_stmt_bind_param checks all
6340     its members.
6341   */
6342   bzero((char*) my_bind, sizeof(my_bind));
6343 
6344   my_bind[0].length= &length;
6345   my_bind[0].is_null= 0;
6346   my_bind[0].buffer_length= 0;
6347 
6348   my_bind[0].buffer_type= MYSQL_TYPE_GEOMETRY;
6349   rc= mysql_stmt_bind_param(stmt, my_bind);
6350   check_execute_r(stmt, rc); /* unsupported buffer type */
6351 
6352   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
6353   rc= mysql_stmt_bind_param(stmt, my_bind);
6354   check_execute(stmt, rc);
6355 
6356   rc= mysql_stmt_store_result(stmt);
6357   check_execute(stmt, rc);
6358 
6359   mysql_stmt_close(stmt);
6360 
6361   stmt= mysql_simple_prepare(mysql, "select * from test_pure");
6362   check_execute(stmt, rc);
6363 
6364   rc= mysql_stmt_execute(stmt);
6365   check_execute(stmt, rc);
6366 
6367   my_bind[0].buffer_type= MYSQL_TYPE_GEOMETRY;
6368   rc= mysql_stmt_bind_result(stmt, my_bind);
6369   check_execute(stmt, rc); /* MariaDB C/C converts geometry to string */
6370 
6371   rc= mysql_stmt_store_result(stmt);
6372   DIE_IF(rc);
6373 
6374   rc= mysql_stmt_store_result(stmt);
6375   DIE_UNLESS(rc); /* Old error must be reset first */
6376 
6377   mysql_stmt_close(stmt);
6378 
6379   mysql_query(mysql, "DROP TABLE test_pure");
6380 }
6381 
6382 
6383 /* Test for string buffer fetch */
6384 
test_buffers()6385 static void test_buffers()
6386 {
6387   MYSQL_STMT *stmt;
6388   MYSQL_BIND my_bind[1];
6389   int        rc;
6390   ulong      length;
6391   my_bool    is_null;
6392   char       buffer[20];
6393 
6394   myheader("test_buffers");
6395 
6396   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_buffer");
6397   myquery(rc);
6398 
6399   rc= mysql_query(mysql, "CREATE TABLE test_buffer(str varchar(20))");
6400   myquery(rc);
6401 
6402   rc= mysql_query(mysql, "insert into test_buffer values('MySQL')\
6403                           , ('Database'), ('Open-Source'), ('Popular')");
6404   myquery(rc);
6405 
6406   stmt= mysql_simple_prepare(mysql, "select str from test_buffer");
6407   check_stmt(stmt);
6408 
6409   rc= mysql_stmt_execute(stmt);
6410   check_execute(stmt, rc);
6411 
6412   bzero(buffer, sizeof(buffer));              /* Avoid overruns in printf() */
6413 
6414   bzero((char*) my_bind, sizeof(my_bind));
6415   my_bind[0].length= &length;
6416   my_bind[0].is_null= &is_null;
6417   my_bind[0].buffer_length= 1;
6418   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
6419   my_bind[0].buffer= (void *)buffer;
6420   my_bind[0].error= &my_bind[0].error_value;
6421 
6422   rc= mysql_stmt_bind_result(stmt, my_bind);
6423   check_execute(stmt, rc);
6424 
6425   rc= mysql_stmt_store_result(stmt);
6426   check_execute(stmt, rc);
6427 
6428   buffer[1]= 'X';
6429   rc= mysql_stmt_fetch(stmt);
6430   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
6431   DIE_UNLESS(my_bind[0].error_value);
6432   if (!opt_silent)
6433     fprintf(stdout, "\n data: %s (%lu)", buffer, length);
6434   DIE_UNLESS(buffer[0] == 'M');
6435   DIE_UNLESS(buffer[1] == 'X');
6436   DIE_UNLESS(length == 5);
6437 
6438   my_bind[0].buffer_length= 8;
6439   rc= mysql_stmt_bind_result(stmt, my_bind);/* re-bind */
6440   check_execute(stmt, rc);
6441 
6442   rc= mysql_stmt_fetch(stmt);
6443   check_execute(stmt, rc);
6444   if (!opt_silent)
6445     fprintf(stdout, "\n data: %s (%lu)", buffer, length);
6446   DIE_UNLESS(strncmp(buffer, "Database", 8) == 0);
6447   DIE_UNLESS(length == 8);
6448 
6449   my_bind[0].buffer_length= 12;
6450   rc= mysql_stmt_bind_result(stmt, my_bind);/* re-bind */
6451   check_execute(stmt, rc);
6452 
6453   rc= mysql_stmt_fetch(stmt);
6454   check_execute(stmt, rc);
6455   if (!opt_silent)
6456     fprintf(stdout, "\n data: %s (%lu)", buffer, length);
6457   DIE_UNLESS(strcmp(buffer, "Open-Source") == 0);
6458   DIE_UNLESS(length == 11);
6459 
6460   my_bind[0].buffer_length= 6;
6461   rc= mysql_stmt_bind_result(stmt, my_bind);/* re-bind */
6462   check_execute(stmt, rc);
6463 
6464   rc= mysql_stmt_fetch(stmt);
6465   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
6466   DIE_UNLESS(my_bind[0].error_value);
6467   if (!opt_silent)
6468     fprintf(stdout, "\n data: %s (%lu)", buffer, length);
6469   DIE_UNLESS(strncmp(buffer, "Popula", 6) == 0);
6470   DIE_UNLESS(length == 7);
6471 
6472   mysql_stmt_close(stmt);
6473 }
6474 
6475 
6476 /* Test the direct query execution in the middle of open stmts */
6477 
test_open_direct()6478 static void test_open_direct()
6479 {
6480   MYSQL_STMT  *stmt;
6481   MYSQL_RES   *result;
6482   int         rc;
6483 
6484   myheader("test_open_direct");
6485 
6486   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_open_direct");
6487   myquery(rc);
6488 
6489   rc= mysql_query(mysql, "CREATE TABLE test_open_direct(id int, name char(6))");
6490   myquery(rc);
6491 
6492   stmt= mysql_simple_prepare(mysql, "INSERT INTO test_open_direct values(10, 'mysql')");
6493   check_stmt(stmt);
6494 
6495   rc= mysql_query(mysql, "SELECT * FROM test_open_direct");
6496   myquery(rc);
6497 
6498   result= mysql_store_result(mysql);
6499   mytest(result);
6500 
6501   rc= my_process_result_set(result);
6502   DIE_UNLESS(rc == 0);
6503   mysql_free_result(result);
6504 
6505   rc= mysql_stmt_execute(stmt);
6506   check_execute(stmt, rc);
6507 
6508   verify_st_affected_rows(stmt, 1);
6509 
6510   rc= mysql_query(mysql, "SELECT * FROM test_open_direct");
6511   myquery(rc);
6512 
6513   result= mysql_store_result(mysql);
6514   mytest(result);
6515 
6516   rc= my_process_result_set(result);
6517   DIE_UNLESS(rc == 1);
6518   mysql_free_result(result);
6519 
6520   rc= mysql_stmt_execute(stmt);
6521   check_execute(stmt, rc);
6522 
6523   verify_st_affected_rows(stmt, 1);
6524 
6525   rc= mysql_query(mysql, "SELECT * FROM test_open_direct");
6526   myquery(rc);
6527 
6528   result= mysql_store_result(mysql);
6529   mytest(result);
6530 
6531   rc= my_process_result_set(result);
6532   DIE_UNLESS(rc == 2);
6533   mysql_free_result(result);
6534 
6535   mysql_stmt_close(stmt);
6536 
6537   /* run a direct query in the middle of a fetch */
6538   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_open_direct");
6539   check_stmt(stmt);
6540 
6541   rc= mysql_stmt_execute(stmt);
6542   check_execute(stmt, rc);
6543 
6544   rc= mysql_stmt_fetch(stmt);
6545   check_execute(stmt, rc);
6546 
6547   rc= mysql_query(mysql, "INSERT INTO test_open_direct(id) VALUES(20)");
6548   myquery_r(rc);
6549 
6550   rc= mysql_stmt_close(stmt);
6551   check_execute(stmt, rc);
6552 
6553   rc= mysql_query(mysql, "INSERT INTO test_open_direct(id) VALUES(20)");
6554   myquery(rc);
6555 
6556   /* run a direct query with store result */
6557   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_open_direct");
6558   check_stmt(stmt);
6559 
6560   rc= mysql_stmt_execute(stmt);
6561   check_execute(stmt, rc);
6562 
6563   rc= mysql_stmt_store_result(stmt);
6564   check_execute(stmt, rc);
6565 
6566   rc= mysql_stmt_fetch(stmt);
6567   check_execute(stmt, rc);
6568 
6569   rc= mysql_query(mysql, "drop table test_open_direct");
6570   myquery(rc);
6571 
6572   rc= mysql_stmt_close(stmt);
6573   check_execute(stmt, rc);
6574 }
6575 
6576 
6577 /* Test fetch without prior bound buffers */
6578 
test_fetch_nobuffs()6579 static void test_fetch_nobuffs()
6580 {
6581   MYSQL_STMT *stmt;
6582   MYSQL_BIND my_bind[4];
6583   char       str[4][50];
6584   int        rc;
6585 
6586   myheader("test_fetch_nobuffs");
6587 
6588   stmt= mysql_simple_prepare(mysql, "SELECT DATABASE(), CURRENT_USER(), \
6589                               CURRENT_DATE(), CURRENT_TIME()");
6590   check_stmt(stmt);
6591 
6592   rc= mysql_stmt_execute(stmt);
6593   check_execute(stmt, rc);
6594 
6595   rc= 0;
6596   while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
6597     rc++;
6598 
6599   if (!opt_silent)
6600     fprintf(stdout, "\n total rows        : %d", rc);
6601   DIE_UNLESS(rc == 1);
6602 
6603   bzero((char*) my_bind, sizeof(MYSQL_BIND));
6604   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
6605   my_bind[0].buffer= (void *)str[0];
6606   my_bind[0].buffer_length= sizeof(str[0]);
6607   my_bind[1]= my_bind[2]= my_bind[3]= my_bind[0];
6608   my_bind[1].buffer= (void *)str[1];
6609   my_bind[2].buffer= (void *)str[2];
6610   my_bind[3].buffer= (void *)str[3];
6611 
6612   rc= mysql_stmt_bind_result(stmt, my_bind);
6613   check_execute(stmt, rc);
6614 
6615   rc= mysql_stmt_execute(stmt);
6616   check_execute(stmt, rc);
6617 
6618   rc= 0;
6619   while (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
6620   {
6621     rc++;
6622     if (!opt_silent)
6623     {
6624       fprintf(stdout, "\n CURRENT_DATABASE(): %s", str[0]);
6625       fprintf(stdout, "\n CURRENT_USER()    : %s", str[1]);
6626       fprintf(stdout, "\n CURRENT_DATE()    : %s", str[2]);
6627       fprintf(stdout, "\n CURRENT_TIME()    : %s", str[3]);
6628     }
6629   }
6630   if (!opt_silent)
6631     fprintf(stdout, "\n total rows        : %d", rc);
6632   DIE_UNLESS(rc == 1);
6633 
6634   mysql_stmt_close(stmt);
6635 }
6636 
6637 
6638 /* Test a misc bug */
6639 
test_ushort_bug()6640 static void test_ushort_bug()
6641 {
6642   MYSQL_STMT *stmt;
6643   MYSQL_BIND my_bind[4];
6644   ushort     short_value;
6645   uint32     long_value;
6646   ulong      s_length, l_length, ll_length, t_length;
6647   ulonglong  longlong_value;
6648   int        rc;
6649   uchar      tiny_value;
6650   char       llbuf[22];
6651   myheader("test_ushort_bug");
6652 
6653   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_ushort");
6654   myquery(rc);
6655 
6656   rc= mysql_query(mysql, "CREATE TABLE test_ushort(a smallint unsigned, \
6657                                                   b smallint unsigned, \
6658                                                   c smallint unsigned, \
6659                                                   d smallint unsigned)");
6660   myquery(rc);
6661 
6662   rc= mysql_query(mysql,
6663                   "INSERT INTO test_ushort VALUES(35999, 35999, 35999, 200)");
6664   myquery(rc);
6665 
6666 
6667   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_ushort");
6668   check_stmt(stmt);
6669 
6670   rc= mysql_stmt_execute(stmt);
6671   check_execute(stmt, rc);
6672 
6673   bzero((char*) my_bind, sizeof(my_bind));
6674   my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
6675   my_bind[0].buffer= (void *)&short_value;
6676   my_bind[0].is_unsigned= TRUE;
6677   my_bind[0].length= &s_length;
6678 
6679   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
6680   my_bind[1].buffer= (void *)&long_value;
6681   my_bind[1].length= &l_length;
6682 
6683   my_bind[2].buffer_type= MYSQL_TYPE_LONGLONG;
6684   my_bind[2].buffer= (void *)&longlong_value;
6685   my_bind[2].length= &ll_length;
6686 
6687   my_bind[3].buffer_type= MYSQL_TYPE_TINY;
6688   my_bind[3].buffer= (void *)&tiny_value;
6689   my_bind[3].is_unsigned= TRUE;
6690   my_bind[3].length= &t_length;
6691 
6692   rc= mysql_stmt_bind_result(stmt, my_bind);
6693   check_execute(stmt, rc);
6694 
6695   rc= mysql_stmt_fetch(stmt);
6696   check_execute(stmt, rc);
6697 
6698   if (!opt_silent)
6699   {
6700     fprintf(stdout, "\n ushort   : %d (%ld)", short_value, s_length);
6701     fprintf(stdout, "\n ulong    : %lu (%ld)", (ulong) long_value, l_length);
6702     fprintf(stdout, "\n longlong : %s (%ld)", llstr(longlong_value, llbuf),
6703             ll_length);
6704     fprintf(stdout, "\n tinyint  : %d   (%ld)", tiny_value, t_length);
6705   }
6706 
6707   DIE_UNLESS(short_value == 35999);
6708   DIE_UNLESS(s_length == 2);
6709 
6710   DIE_UNLESS(long_value == 35999);
6711   DIE_UNLESS(l_length == 4);
6712 
6713   DIE_UNLESS(longlong_value == 35999);
6714   DIE_UNLESS(ll_length == 8);
6715 
6716   DIE_UNLESS(tiny_value == 200);
6717   DIE_UNLESS(t_length == 1);
6718 
6719   rc= mysql_stmt_fetch(stmt);
6720   DIE_UNLESS(rc == MYSQL_NO_DATA);
6721 
6722   mysql_stmt_close(stmt);
6723 }
6724 
6725 
6726 /* Test a misc smallint-signed conversion bug */
6727 
test_sshort_bug()6728 static void test_sshort_bug()
6729 {
6730   MYSQL_STMT *stmt;
6731   MYSQL_BIND my_bind[4];
6732   short      short_value;
6733   int32      long_value;
6734   ulong      s_length, l_length, ll_length, t_length;
6735   ulonglong  longlong_value;
6736   int        rc;
6737   uchar      tiny_value;
6738   char       llbuf[22];
6739 
6740   myheader("test_sshort_bug");
6741 
6742   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_sshort");
6743   myquery(rc);
6744 
6745   rc= mysql_query(mysql, "CREATE TABLE test_sshort(a smallint signed, \
6746                                                   b smallint signed, \
6747                                                   c smallint unsigned, \
6748                                                   d smallint unsigned)");
6749   myquery(rc);
6750 
6751   rc= mysql_query(mysql, "INSERT INTO test_sshort VALUES(-5999, -5999, 35999, 200)");
6752   myquery(rc);
6753 
6754 
6755   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_sshort");
6756   check_stmt(stmt);
6757 
6758   rc= mysql_stmt_execute(stmt);
6759   check_execute(stmt, rc);
6760 
6761   bzero((char*) my_bind, sizeof(my_bind));
6762   my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
6763   my_bind[0].buffer= (void *)&short_value;
6764   my_bind[0].length= &s_length;
6765 
6766   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
6767   my_bind[1].buffer= (void *)&long_value;
6768   my_bind[1].length= &l_length;
6769 
6770   my_bind[2].buffer_type= MYSQL_TYPE_LONGLONG;
6771   my_bind[2].buffer= (void *)&longlong_value;
6772   my_bind[2].length= &ll_length;
6773 
6774   my_bind[3].buffer_type= MYSQL_TYPE_TINY;
6775   my_bind[3].buffer= (void *)&tiny_value;
6776   my_bind[3].is_unsigned= TRUE;
6777   my_bind[3].length= &t_length;
6778 
6779   rc= mysql_stmt_bind_result(stmt, my_bind);
6780   check_execute(stmt, rc);
6781 
6782   rc= mysql_stmt_fetch(stmt);
6783   check_execute(stmt, rc);
6784 
6785   if (!opt_silent)
6786   {
6787     fprintf(stdout, "\n sshort   : %d (%ld)", short_value, s_length);
6788     fprintf(stdout, "\n slong    : %ld (%ld)", (long) long_value, l_length);
6789     fprintf(stdout, "\n longlong : %s (%ld)", llstr(longlong_value, llbuf),
6790             ll_length);
6791     fprintf(stdout, "\n tinyint  : %d   (%ld)", tiny_value, t_length);
6792   }
6793 
6794   DIE_UNLESS(short_value == -5999);
6795   DIE_UNLESS(s_length == 2);
6796 
6797   DIE_UNLESS(long_value == -5999);
6798   DIE_UNLESS(l_length == 4);
6799 
6800   DIE_UNLESS(longlong_value == 35999);
6801   DIE_UNLESS(ll_length == 8);
6802 
6803   DIE_UNLESS(tiny_value == 200);
6804   DIE_UNLESS(t_length == 1);
6805 
6806   rc= mysql_stmt_fetch(stmt);
6807   DIE_UNLESS(rc == MYSQL_NO_DATA);
6808 
6809   mysql_stmt_close(stmt);
6810 }
6811 
6812 
6813 /* Test a misc tinyint-signed conversion bug */
6814 
test_stiny_bug()6815 static void test_stiny_bug()
6816 {
6817   MYSQL_STMT *stmt;
6818   MYSQL_BIND my_bind[4];
6819   short      short_value;
6820   int32      long_value;
6821   ulong      s_length, l_length, ll_length, t_length;
6822   ulonglong  longlong_value;
6823   int        rc;
6824   uchar      tiny_value;
6825   char       llbuf[22];
6826 
6827   myheader("test_stiny_bug");
6828 
6829   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_stiny");
6830   myquery(rc);
6831 
6832   rc= mysql_query(mysql, "CREATE TABLE test_stiny(a tinyint signed, \
6833                                                   b tinyint signed, \
6834                                                   c tinyint unsigned, \
6835                                                   d tinyint unsigned)");
6836   myquery(rc);
6837 
6838   rc= mysql_query(mysql, "INSERT INTO test_stiny VALUES(-128, -127, 255, 0)");
6839   myquery(rc);
6840 
6841 
6842   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_stiny");
6843   check_stmt(stmt);
6844 
6845   rc= mysql_stmt_execute(stmt);
6846   check_execute(stmt, rc);
6847 
6848   bzero((char*) my_bind, sizeof(my_bind));
6849   my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
6850   my_bind[0].buffer= (void *)&short_value;
6851   my_bind[0].length= &s_length;
6852 
6853   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
6854   my_bind[1].buffer= (void *)&long_value;
6855   my_bind[1].length= &l_length;
6856 
6857   my_bind[2].buffer_type= MYSQL_TYPE_LONGLONG;
6858   my_bind[2].buffer= (void *)&longlong_value;
6859   my_bind[2].length= &ll_length;
6860 
6861   my_bind[3].buffer_type= MYSQL_TYPE_TINY;
6862   my_bind[3].buffer= (void *)&tiny_value;
6863   my_bind[3].length= &t_length;
6864 
6865   rc= mysql_stmt_bind_result(stmt, my_bind);
6866   check_execute(stmt, rc);
6867 
6868   rc= mysql_stmt_fetch(stmt);
6869   check_execute(stmt, rc);
6870 
6871   if (!opt_silent)
6872   {
6873     fprintf(stdout, "\n sshort   : %d (%ld)", short_value, s_length);
6874     fprintf(stdout, "\n slong    : %ld (%ld)", (long) long_value, l_length);
6875     fprintf(stdout, "\n longlong : %s  (%ld)", llstr(longlong_value, llbuf),
6876             ll_length);
6877     fprintf(stdout, "\n tinyint  : %d    (%ld)", tiny_value, t_length);
6878   }
6879 
6880   DIE_UNLESS(short_value == -128);
6881   DIE_UNLESS(s_length == 2);
6882 
6883   DIE_UNLESS(long_value == -127);
6884   DIE_UNLESS(l_length == 4);
6885 
6886   DIE_UNLESS(longlong_value == 255);
6887   DIE_UNLESS(ll_length == 8);
6888 
6889   DIE_UNLESS(tiny_value == 0);
6890   DIE_UNLESS(t_length == 1);
6891 
6892   rc= mysql_stmt_fetch(stmt);
6893   DIE_UNLESS(rc == MYSQL_NO_DATA);
6894 
6895   mysql_stmt_close(stmt);
6896 }
6897 
6898 
6899 /* Test misc field information, bug: #74 */
6900 
test_field_misc()6901 static void test_field_misc()
6902 {
6903   MYSQL_STMT  *stmt;
6904   MYSQL_RES   *result;
6905   int         rc;
6906 
6907   myheader("test_field_misc");
6908 
6909   rc= mysql_query(mysql, "SELECT @@autocommit");
6910   myquery(rc);
6911 
6912   result= mysql_store_result(mysql);
6913   mytest(result);
6914 
6915   rc= my_process_result_set(result);
6916   DIE_UNLESS(rc == 1);
6917 
6918   verify_prepare_field(result, 0,
6919                        "@@autocommit", "",  /* field and its org name */
6920                        MYSQL_TYPE_LONGLONG, /* field type */
6921                        "", "",              /* table and its org name */
6922                        "", 1, 0);           /* db name, length(its bool flag)*/
6923 
6924   mysql_free_result(result);
6925 
6926   stmt= mysql_simple_prepare(mysql, "SELECT @@autocommit");
6927   check_stmt(stmt);
6928 
6929   rc= mysql_stmt_execute(stmt);
6930   check_execute(stmt, rc);
6931 
6932   result= mysql_stmt_result_metadata(stmt);
6933   mytest(result);
6934 
6935   rc= my_process_stmt_result(stmt);
6936   DIE_UNLESS(rc == 1);
6937 
6938   verify_prepare_field(result, 0,
6939                        "@@autocommit", "",  /* field and its org name */
6940                        MYSQL_TYPE_LONGLONG, /* field type */
6941                        "", "",              /* table and its org name */
6942                        "", 1, 0);           /* db name, length(its bool flag)*/
6943 
6944   mysql_free_result(result);
6945   mysql_stmt_close(stmt);
6946 
6947   stmt= mysql_simple_prepare(mysql, "SELECT @@max_error_count");
6948   check_stmt(stmt);
6949 
6950   result= mysql_stmt_result_metadata(stmt);
6951   mytest(result);
6952 
6953   rc= mysql_stmt_execute(stmt);
6954   check_execute(stmt, rc);
6955 
6956   rc= my_process_stmt_result(stmt);
6957   DIE_UNLESS(rc == 1);
6958 
6959   verify_prepare_field(result, 0,
6960                        "@@max_error_count", "",   /* field and its org name */
6961                        MYSQL_TYPE_LONGLONG, /* field type */
6962                        "", "",              /* table and its org name */
6963                        /* db name, length */
6964                        "", MY_INT64_NUM_DECIMAL_DIGITS , 0);
6965 
6966   mysql_free_result(result);
6967   mysql_stmt_close(stmt);
6968 
6969   stmt= mysql_simple_prepare(mysql, "SELECT @@max_allowed_packet");
6970   check_stmt(stmt);
6971 
6972   result= mysql_stmt_result_metadata(stmt);
6973   mytest(result);
6974 
6975   rc= mysql_stmt_execute(stmt);
6976   check_execute(stmt, rc);
6977 
6978   DIE_UNLESS(1 == my_process_stmt_result(stmt));
6979 
6980   verify_prepare_field(result, 0,
6981                        "@@max_allowed_packet", "", /* field and its org name */
6982                        MYSQL_TYPE_LONGLONG, /* field type */
6983                        "", "",              /* table and its org name */
6984                        /* db name, length */
6985                        "", MY_INT64_NUM_DECIMAL_DIGITS, 0);
6986 
6987   mysql_free_result(result);
6988   mysql_stmt_close(stmt);
6989 
6990   stmt= mysql_simple_prepare(mysql, "SELECT @@sql_warnings");
6991   check_stmt(stmt);
6992 
6993   result= mysql_stmt_result_metadata(stmt);
6994   mytest(result);
6995 
6996   rc= mysql_stmt_execute(stmt);
6997   check_execute(stmt, rc);
6998 
6999   rc= my_process_stmt_result(stmt);
7000   DIE_UNLESS(rc == 1);
7001 
7002   verify_prepare_field(result, 0,
7003                        "@@sql_warnings", "",  /* field and its org name */
7004                        MYSQL_TYPE_LONGLONG,   /* field type */
7005                        "", "",                /* table and its org name */
7006                        "", 1, 0);             /* db name, length */
7007 
7008   mysql_free_result(result);
7009   mysql_stmt_close(stmt);
7010 }
7011 
7012 
7013 /*
7014   Test SET OPTION feature with prepare stmts
7015   bug #85 (reported by mark@mysql.com)
7016 */
7017 
test_set_option()7018 static void test_set_option()
7019 {
7020   MYSQL_STMT *stmt;
7021   MYSQL_RES  *result;
7022   int        rc;
7023 
7024   myheader("test_set_option");
7025 
7026   mysql_autocommit(mysql, TRUE);
7027 
7028   /* LIMIT the rows count to 2 */
7029   rc= mysql_query(mysql, "SET SQL_SELECT_LIMIT= 2");
7030   myquery(rc);
7031 
7032   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_limit");
7033   myquery(rc);
7034 
7035   rc= mysql_query(mysql, "CREATE TABLE test_limit(a tinyint)");
7036   myquery(rc);
7037 
7038   rc= mysql_query(mysql, "INSERT INTO test_limit VALUES(10), (20), (30), (40)");
7039   myquery(rc);
7040 
7041   if (!opt_silent)
7042     fprintf(stdout, "\n with SQL_SELECT_LIMIT= 2 (direct)");
7043   rc= mysql_query(mysql, "SELECT * FROM test_limit");
7044   myquery(rc);
7045 
7046   result= mysql_store_result(mysql);
7047   mytest(result);
7048 
7049   rc= my_process_result_set(result);
7050   DIE_UNLESS(rc == 2);
7051 
7052   mysql_free_result(result);
7053 
7054   if (!opt_silent)
7055     fprintf(stdout, "\n with SQL_SELECT_LIMIT=2 (prepare)");
7056   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_limit");
7057   check_stmt(stmt);
7058 
7059   rc= mysql_stmt_execute(stmt);
7060   check_execute(stmt, rc);
7061 
7062   rc= my_process_stmt_result(stmt);
7063   DIE_UNLESS(rc == 2);
7064 
7065   mysql_stmt_close(stmt);
7066 
7067   /* RESET the LIMIT the rows count to 0 */
7068   if (!opt_silent)
7069     fprintf(stdout, "\n with SQL_SELECT_LIMIT=DEFAULT (prepare)");
7070   rc= mysql_query(mysql, "SET SQL_SELECT_LIMIT=DEFAULT");
7071   myquery(rc);
7072 
7073   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_limit");
7074   check_stmt(stmt);
7075 
7076   rc= mysql_stmt_execute(stmt);
7077   check_execute(stmt, rc);
7078 
7079   rc= my_process_stmt_result(stmt);
7080   DIE_UNLESS(rc == 4);
7081 
7082   mysql_stmt_close(stmt);
7083 }
7084 
7085 #ifdef EMBEDDED_LIBRARY
test_embedded_start_stop()7086 static void test_embedded_start_stop()
7087 {
7088   MYSQL *mysql_emb=NULL;
7089   int i, j;
7090   int argc= original_argc;                    // Start with the original args
7091   char **argv, **my_argv;
7092   char test_name[]= "test_embedded_start_stop";
7093 #define EMBEDDED_RESTARTS 64
7094 
7095   myheader("test_embedded_start_stop");
7096 
7097   /* Must stop the main embedded server, since we use the same config. */
7098   client_disconnect(mysql);    /* disconnect from server */
7099   free_defaults(defaults_argv);
7100   mysql_server_end();
7101   /* Free everything allocated by my_once_alloc */
7102   my_end(0);
7103 
7104   /*
7105     Use a copy of the original arguments.
7106     The arguments will be altered when reading the configs and parsing
7107     options.
7108   */
7109   my_argv= malloc((argc + 1) * sizeof(char*));
7110   if (!my_argv)
7111     exit(1);
7112 
7113   /* Test restarting the embedded library many times. */
7114   for (i= 1; i <= EMBEDDED_RESTARTS; i++)
7115   {
7116     argv= my_argv;
7117     argv[0]= test_name;
7118     for (j= 1; j < argc; j++)
7119       argv[j]= original_argv[j];
7120 
7121     /* Initialize everything again. */
7122     MY_INIT(argv[0]);
7123 
7124     /* Load the client defaults from the .cnf file[s]. */
7125     load_defaults_or_exit("my", client_test_load_default_groups, &argc, &argv);
7126 
7127     /* Parse the options (including the ones given from defaults files). */
7128     get_options(&argc, &argv);
7129 
7130     /* mysql_library_init is the same as mysql_server_init. */
7131     if (mysql_library_init(embedded_server_arg_count,
7132                            embedded_server_args,
7133                            (char**) embedded_server_groups))
7134     {
7135       myerror("mysql_library_init failed");
7136       exit(1);
7137     }
7138 
7139     /* Create a client connection. */
7140     if (!(mysql_emb= mysql_client_init(NULL)))
7141     {
7142       myerror("mysql_client_init failed");
7143       exit(1);
7144     }
7145 
7146     /* Connect it and see if we can use the database. */
7147     if (!(mysql_real_connect(mysql_emb, opt_host, opt_user,
7148                              opt_password, current_db, 0,
7149                              NULL, 0)))
7150     {
7151       myerror("mysql_real_connect failed");
7152     }
7153 
7154     /* Close the client connection */
7155     mysql_close(mysql_emb);
7156     mysql_emb = NULL;
7157     /* Free arguments allocated for defaults files. */
7158     free_defaults(defaults_argv);
7159     /* mysql_library_end is a define for mysql_server_end. */
7160     mysql_library_end();
7161     /* Free everything allocated by my_once_alloc */
7162     my_end(0);
7163   }
7164 
7165   argc= original_argc;
7166   argv= my_argv;
7167   argv[0]= test_name;
7168   for (j= 1; j < argc; j++)
7169     argv[j]= original_argv[j];
7170 
7171   MY_INIT(argv[0]);
7172 
7173   load_defaults_or_exit("my", client_test_load_default_groups, &argc, &argv);
7174   get_options(&argc, &argv);
7175 
7176   /* Must start the main embedded server again after the test. */
7177   if (mysql_server_init(embedded_server_arg_count,
7178                         embedded_server_args,
7179                         (char**) embedded_server_groups))
7180     DIE("Can't initialize MySQL server");
7181 
7182   /* connect to server with no flags, default protocol, auto reconnect true */
7183   mysql= client_connect(0, MYSQL_PROTOCOL_DEFAULT, 1);
7184   free(my_argv);
7185 }
7186 #endif /* EMBEDDED_LIBRARY */
7187 
7188 
7189 /*
7190   Test a misc GRANT option
7191   bug #89 (reported by mark@mysql.com)
7192 */
7193 
7194 #ifndef EMBEDDED_LIBRARY
test_prepare_grant()7195 static void test_prepare_grant()
7196 {
7197   int rc;
7198   char query[MAX_TEST_QUERY_LENGTH];
7199 
7200   myheader("test_prepare_grant");
7201 
7202   mysql_autocommit(mysql, TRUE);
7203 
7204   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_grant");
7205   myquery(rc);
7206 
7207   rc= mysql_query(mysql, "CREATE TABLE test_grant(a tinyint primary key auto_increment)");
7208   myquery(rc);
7209 
7210   strxmov(query, "GRANT INSERT, UPDATE, SELECT ON ", current_db,
7211                 ".test_grant TO 'test_grant'@",
7212                 opt_host ? opt_host : "'localhost'", NullS);
7213 
7214   if (mysql_query(mysql, query))
7215   {
7216     myerror("GRANT failed");
7217 
7218     /*
7219        If server started with --skip-grant-tables, skip this test, else
7220        exit to indicate an error
7221 
7222        ER_UNKNOWN_COM_ERROR= 1047
7223      */
7224     if (mysql_errno(mysql) != 1047)
7225       exit(1);
7226   }
7227   else
7228   {
7229     MYSQL *org_mysql= mysql, *lmysql;
7230     MYSQL_STMT *stmt;
7231 
7232     if (!opt_silent)
7233       fprintf(stdout, "\n Establishing a test connection ...");
7234     if (!(lmysql= mysql_client_init(NULL)))
7235     {
7236       myerror("mysql_client_init() failed");
7237       exit(1);
7238     }
7239     if (!(mysql_real_connect(lmysql, opt_host, "test_grant",
7240                              "", current_db, opt_port,
7241                              opt_unix_socket, 0)))
7242     {
7243       myerror("connection failed");
7244       mysql_close(lmysql);
7245       exit(1);
7246     }
7247     mysql_options(lmysql, MYSQL_OPT_RECONNECT, &my_true);
7248     if (!opt_silent)
7249       fprintf(stdout, "OK");
7250 
7251     mysql= lmysql;
7252     rc= mysql_query(mysql, "INSERT INTO test_grant VALUES(NULL)");
7253     myquery(rc);
7254 
7255     rc= mysql_query(mysql, "INSERT INTO test_grant(a) VALUES(NULL)");
7256     myquery(rc);
7257 
7258     execute_prepare_query("INSERT INTO test_grant(a) VALUES(NULL)", 1);
7259     execute_prepare_query("INSERT INTO test_grant VALUES(NULL)", 1);
7260     execute_prepare_query("UPDATE test_grant SET a=9 WHERE a=1", 1);
7261     rc= my_stmt_result("SELECT a FROM test_grant");
7262     DIE_UNLESS(rc == 4);
7263 
7264     /* Both DELETE expected to fail as user does not have DELETE privs */
7265 
7266     rc= mysql_query(mysql, "DELETE FROM test_grant");
7267     myquery_r(rc);
7268 
7269     stmt= mysql_simple_prepare(mysql, "DELETE FROM test_grant");
7270     check_stmt_r(stmt);
7271 
7272     rc= my_stmt_result("SELECT * FROM test_grant");
7273     DIE_UNLESS(rc == 4);
7274 
7275     mysql_close(lmysql);
7276     mysql= org_mysql;
7277 
7278     rc= mysql_query(mysql, "delete from mysql.user where User='test_grant'");
7279     myquery(rc);
7280     DIE_UNLESS(1 == mysql_affected_rows(mysql));
7281 
7282     rc= mysql_query(mysql, "delete from mysql.tables_priv where User='test_grant'");
7283     myquery(rc);
7284     DIE_UNLESS(1 == mysql_affected_rows(mysql));
7285 
7286   }
7287 }
7288 #endif /* EMBEDDED_LIBRARY */
7289 
7290 /*
7291   Test a crash when invalid/corrupted .frm is used in the
7292   SHOW TABLE STATUS
7293   bug #93 (reported by serg@mysql.com).
7294 */
7295 
test_frm_bug()7296 static void test_frm_bug()
7297 {
7298   MYSQL_STMT *stmt;
7299   MYSQL_BIND my_bind[2];
7300   MYSQL_RES  *result;
7301   MYSQL_ROW  row;
7302   FILE       *test_file;
7303   char       data_dir[FN_REFLEN];
7304   char       test_frm[FN_REFLEN];
7305   int        rc;
7306 
7307   myheader("test_frm_bug");
7308 
7309   mysql_autocommit(mysql, TRUE);
7310 
7311   rc= mysql_query(mysql, "drop table if exists test_frm_bug");
7312   myquery(rc);
7313 
7314   rc= mysql_query(mysql, "flush tables");
7315   myquery(rc);
7316 
7317   stmt= mysql_simple_prepare(mysql, "show variables like 'datadir'");
7318   check_stmt(stmt);
7319 
7320   rc= mysql_stmt_execute(stmt);
7321   check_execute(stmt, rc);
7322 
7323   bzero((char*) my_bind, sizeof(my_bind));
7324   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
7325   my_bind[0].buffer= data_dir;
7326   my_bind[0].buffer_length= FN_REFLEN;
7327   my_bind[1]= my_bind[0];
7328 
7329   rc= mysql_stmt_bind_result(stmt, my_bind);
7330   check_execute(stmt, rc);
7331 
7332   rc= mysql_stmt_fetch(stmt);
7333   check_execute(stmt, rc);
7334 
7335   if (!opt_silent)
7336     fprintf(stdout, "\n data directory: %s", data_dir);
7337 
7338   rc= mysql_stmt_fetch(stmt);
7339   DIE_UNLESS(rc == MYSQL_NO_DATA);
7340 
7341   strxmov(test_frm, data_dir, "/", current_db, "/", "test_frm_bug.frm", NullS);
7342 
7343   if (!opt_silent)
7344     fprintf(stdout, "\n test_frm: %s", test_frm);
7345 
7346   if (!(test_file= my_fopen(test_frm, (int) (O_RDWR | O_CREAT), MYF(MY_WME))))
7347   {
7348     fprintf(stdout, "\n ERROR: my_fopen failed for '%s'", test_frm);
7349     fprintf(stdout, "\n test cancelled");
7350     exit(1);
7351   }
7352   if (!opt_silent)
7353     fprintf(test_file, "this is a junk file for test");
7354 
7355   rc= mysql_query(mysql, "SHOW TABLE STATUS like 'test_frm_bug'");
7356   myquery(rc);
7357 
7358   result= mysql_store_result(mysql);
7359   mytest(result);/* It can't be NULL */
7360 
7361   rc= my_process_result_set(result);
7362   DIE_UNLESS(rc == 1);
7363 
7364   mysql_data_seek(result, 0);
7365 
7366   row= mysql_fetch_row(result);
7367   mytest(row);
7368 
7369   if (!opt_silent)
7370     fprintf(stdout, "\n Comment: %s", row[17]);
7371   DIE_UNLESS(row[17] != 0);
7372 
7373   mysql_free_result(result);
7374   mysql_stmt_close(stmt);
7375 
7376   my_fclose(test_file, MYF(0));
7377   mysql_query(mysql, "drop table if exists test_frm_bug");
7378 }
7379 
7380 
7381 /* Test DECIMAL conversion */
7382 
test_decimal_bug()7383 static void test_decimal_bug()
7384 {
7385   MYSQL_STMT *stmt;
7386   MYSQL_BIND my_bind[1];
7387   char       data[30];
7388   int        rc;
7389   my_bool    is_null;
7390 
7391   myheader("test_decimal_bug");
7392 
7393   mysql_autocommit(mysql, TRUE);
7394 
7395   rc= mysql_query(mysql, "drop table if exists test_decimal_bug");
7396   myquery(rc);
7397 
7398   rc= mysql_query(mysql, "create table test_decimal_bug(c1 decimal(10, 2))");
7399   myquery(rc);
7400 
7401   rc= mysql_query(mysql, "insert into test_decimal_bug value(8), (10.22), (5.61)");
7402   myquery(rc);
7403 
7404   stmt= mysql_simple_prepare(mysql, "select c1 from test_decimal_bug where c1= ?");
7405   check_stmt(stmt);
7406 
7407   /*
7408     We need to bzero bind structure because mysql_stmt_bind_param checks all
7409     its members.
7410   */
7411   bzero((char*) my_bind, sizeof(my_bind));
7412 
7413   my_bind[0].buffer_type= MYSQL_TYPE_NEWDECIMAL;
7414   my_bind[0].buffer= (void *)data;
7415   my_bind[0].buffer_length= 25;
7416   my_bind[0].is_null= &is_null;
7417 
7418   is_null= 0;
7419   rc= mysql_stmt_bind_param(stmt, my_bind);
7420   check_execute(stmt, rc);
7421 
7422   strmov(data, "8.0");
7423   rc= mysql_stmt_execute(stmt);
7424   check_execute(stmt, rc);
7425 
7426   data[0]= 0;
7427   rc= mysql_stmt_bind_result(stmt, my_bind);
7428   check_execute(stmt, rc);
7429 
7430   rc= mysql_stmt_fetch(stmt);
7431   check_execute(stmt, rc);
7432 
7433   if (!opt_silent)
7434     fprintf(stdout, "\n data: %s", data);
7435   DIE_UNLESS(strcmp(data, "8.00") == 0);
7436 
7437   rc= mysql_stmt_fetch(stmt);
7438   DIE_UNLESS(rc == MYSQL_NO_DATA);
7439 
7440   strmov(data, "5.61");
7441   rc= mysql_stmt_execute(stmt);
7442   check_execute(stmt, rc);
7443 
7444   data[0]= 0;
7445   rc= mysql_stmt_bind_result(stmt, my_bind);
7446   check_execute(stmt, rc);
7447 
7448   rc= mysql_stmt_fetch(stmt);
7449   check_execute(stmt, rc);
7450 
7451   if (!opt_silent)
7452     fprintf(stdout, "\n data: %s", data);
7453   DIE_UNLESS(strcmp(data, "5.61") == 0);
7454 
7455   rc= mysql_stmt_fetch(stmt);
7456   DIE_UNLESS(rc == MYSQL_NO_DATA);
7457 
7458   is_null= 1;
7459   rc= mysql_stmt_execute(stmt);
7460   check_execute(stmt, rc);
7461 
7462   rc= mysql_stmt_fetch(stmt);
7463   DIE_UNLESS(rc == MYSQL_NO_DATA);
7464 
7465   strmov(data, "10.22"); is_null= 0;
7466   rc= mysql_stmt_execute(stmt);
7467   check_execute(stmt, rc);
7468 
7469   data[0]= 0;
7470   rc= mysql_stmt_bind_result(stmt, my_bind);
7471   check_execute(stmt, rc);
7472 
7473   rc= mysql_stmt_fetch(stmt);
7474   check_execute(stmt, rc);
7475 
7476   if (!opt_silent)
7477     fprintf(stdout, "\n data: %s", data);
7478   DIE_UNLESS(strcmp(data, "10.22") == 0);
7479 
7480   rc= mysql_stmt_fetch(stmt);
7481   DIE_UNLESS(rc == MYSQL_NO_DATA);
7482 
7483   mysql_stmt_close(stmt);
7484 }
7485 
7486 
7487 /* Test EXPLAIN bug (#115, reported by mark@mysql.com & georg@php.net). */
7488 
test_explain_bug()7489 static void test_explain_bug()
7490 {
7491   MYSQL_STMT *stmt;
7492   MYSQL_RES  *result;
7493   int        rc;
7494 
7495   myheader("test_explain_bug");
7496 
7497   mysql_autocommit(mysql, TRUE);
7498 
7499   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_explain");
7500   myquery(rc);
7501 
7502   rc= mysql_query(mysql, "CREATE TABLE test_explain(id int, name char(2))");
7503   myquery(rc);
7504 
7505   stmt= mysql_simple_prepare(mysql, "explain test_explain");
7506   check_stmt(stmt);
7507 
7508   rc= mysql_stmt_execute(stmt);
7509   check_execute(stmt, rc);
7510 
7511   rc= my_process_stmt_result(stmt);
7512   DIE_UNLESS(rc == 2);
7513 
7514   result= mysql_stmt_result_metadata(stmt);
7515   mytest(result);
7516 
7517   if (!opt_silent)
7518     fprintf(stdout, "\n total fields in the result: %d",
7519             mysql_num_fields(result));
7520   DIE_UNLESS(6 == mysql_num_fields(result));
7521 
7522   verify_prepare_field(result, 0, "Field", "COLUMN_NAME",
7523                        mysql_get_server_version(mysql) <= 50000 ?
7524                        MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
7525                        0, 0, "information_schema", 64, 0);
7526 
7527   verify_prepare_field(result, 1, "Type", "COLUMN_TYPE", MYSQL_TYPE_BLOB,
7528                        0, 0, "information_schema", 0, 0);
7529 
7530   verify_prepare_field(result, 2, "Null", "IS_NULLABLE",
7531                        mysql_get_server_version(mysql) <= 50000 ?
7532                        MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
7533                        0, 0, "information_schema", 3, 0);
7534 
7535   verify_prepare_field(result, 3, "Key", "COLUMN_KEY",
7536                        mysql_get_server_version(mysql) <= 50000 ?
7537                        MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
7538                        0, 0, "information_schema", 3, 0);
7539 
7540   if ( mysql_get_server_version(mysql) >= 50027 )
7541   {
7542     /*  The patch for bug#23037 changes column type of DEAULT to blob */
7543     verify_prepare_field(result, 4, "Default", "COLUMN_DEFAULT",
7544                          MYSQL_TYPE_BLOB, 0, 0, "information_schema", 0, 0);
7545   }
7546   else
7547   {
7548     verify_prepare_field(result, 4, "Default", "COLUMN_DEFAULT",
7549                          mysql_get_server_version(mysql) >= 50027 ?
7550                          MYSQL_TYPE_BLOB :
7551                          mysql_get_server_version(mysql) <= 50000 ?
7552                          MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
7553                          0, 0, "information_schema",
7554                          mysql_get_server_version(mysql) >= 50027 ? 0 :64, 0);
7555   }
7556 
7557   verify_prepare_field(result, 5, "Extra", "EXTRA",
7558                        mysql_get_server_version(mysql) <= 50000 ?
7559                        MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING,
7560                        0, 0, "information_schema", 30, 0);
7561 
7562   mysql_free_result(result);
7563   mysql_stmt_close(stmt);
7564 
7565   stmt= mysql_simple_prepare(mysql, "explain select id, name FROM test_explain");
7566   check_stmt(stmt);
7567 
7568   rc= mysql_stmt_execute(stmt);
7569   check_execute(stmt, rc);
7570 
7571   rc= my_process_stmt_result(stmt);
7572   DIE_UNLESS(rc == 1);
7573 
7574   result= mysql_stmt_result_metadata(stmt);
7575   mytest(result);
7576 
7577   if (!opt_silent)
7578     fprintf(stdout, "\n total fields in the result: %d",
7579             mysql_num_fields(result));
7580   DIE_UNLESS(10 == mysql_num_fields(result));
7581 
7582   verify_prepare_field(result, 0, "id", "", MYSQL_TYPE_LONGLONG,
7583                        "", "", "", 3, 0);
7584 
7585   verify_prepare_field(result, 1, "select_type", "", MYSQL_TYPE_VAR_STRING,
7586                        "", "", "", 19, 0);
7587 
7588   verify_prepare_field(result, 2, "table", "", MYSQL_TYPE_VAR_STRING,
7589                        "", "", "", NAME_CHAR_LEN, 0);
7590 
7591   verify_prepare_field(result, 3, "type", "", MYSQL_TYPE_VAR_STRING,
7592                        "", "", "", 10, 0);
7593 
7594   verify_prepare_field(result, 4, "possible_keys", "", MYSQL_TYPE_VAR_STRING,
7595                        "", "", "", NAME_CHAR_LEN*MAX_KEY, 0);
7596 
7597   verify_prepare_field(result, 5, "key", "", MYSQL_TYPE_VAR_STRING,
7598                        "", "", "", NAME_CHAR_LEN, 0);
7599 
7600   if (mysql_get_server_version(mysql) <= 50000)
7601   {
7602     verify_prepare_field(result, 6, "key_len", "", MYSQL_TYPE_LONGLONG, "",
7603                          "", "", 3, 0);
7604   }
7605   else
7606   {
7607     verify_prepare_field(result, 6, "key_len", "", MYSQL_TYPE_VAR_STRING, "",
7608                          "", "", NAME_CHAR_LEN*MAX_KEY, 0);
7609   }
7610 
7611   /* The length of this may verify between MariaDB versions (1024 / 2048) */
7612   verify_prepare_field(result, 7, "ref", "", MYSQL_TYPE_VAR_STRING,
7613                        "", "", "", NAME_CHAR_LEN * HA_MAX_KEY_SEG, 0);
7614 
7615   verify_prepare_field(result, 8, "rows", "", MYSQL_TYPE_VAR_STRING,
7616                        "", "", "", NAME_CHAR_LEN, 0);
7617 
7618   verify_prepare_field(result, 9, "Extra", "", MYSQL_TYPE_VAR_STRING,
7619                        "", "", "", 255, 0);
7620 
7621   mysql_free_result(result);
7622   mysql_stmt_close(stmt);
7623 }
7624 
7625 #ifdef NOT_YET_WORKING
7626 
7627 /*
7628   Test math functions.
7629   Bug #148 (reported by salle@mysql.com).
7630 */
7631 
7632 #define myerrno(n) check_errcode(n)
7633 
check_errcode(const unsigned int err)7634 static void check_errcode(const unsigned int err)
7635 {
7636   if (!opt_silent || mysql_errno(mysql) != err)
7637   {
7638     if (mysql->server_version)
7639       fprintf(stdout, "\n [MySQL-%s]", mysql->server_version);
7640     else
7641       fprintf(stdout, "\n [MySQL]");
7642     fprintf(stdout, "[%d] %s\n", mysql_errno(mysql), mysql_error(mysql));
7643   }
7644   DIE_UNLESS(mysql_errno(mysql) == err);
7645 }
7646 
7647 
test_drop_temp()7648 static void test_drop_temp()
7649 {
7650   int rc;
7651 
7652   myheader("test_drop_temp");
7653 
7654   rc= mysql_query(mysql, "DROP DATABASE IF EXISTS test_drop_temp_db");
7655   myquery(rc);
7656 
7657   rc= mysql_query(mysql, "CREATE DATABASE test_drop_temp_db");
7658   myquery(rc);
7659 
7660   rc= mysql_query(mysql, "CREATE TABLE test_drop_temp_db.t1(c1 int, c2 char(1))");
7661   myquery(rc);
7662 
7663   rc= mysql_query(mysql, "delete from mysql.db where Db='test_drop_temp_db'");
7664   myquery(rc);
7665 
7666   rc= mysql_query(mysql, "delete from mysql.db where Db='test_drop_temp_db'");
7667   myquery(rc);
7668 
7669   strxmov(query, "GRANT SELECT, USAGE, DROP ON test_drop_temp_db.* TO test_temp@",
7670                 opt_host ? opt_host : "localhost", NullS);
7671 
7672   if (mysql_query(mysql, query))
7673   {
7674     myerror("GRANT failed");
7675 
7676     /*
7677        If server started with --skip-grant-tables, skip this test, else
7678        exit to indicate an error
7679 
7680        ER_UNKNOWN_COM_ERROR= 1047
7681      */
7682     if (mysql_errno(mysql) != 1047)
7683       exit(1);
7684   }
7685   else
7686   {
7687     MYSQL *org_mysql= mysql, *lmysql;
7688 
7689     if (!opt_silent)
7690       fprintf(stdout, "\n Establishing a test connection ...");
7691     if (!(lmysql= mysql_client_init(NULL)))
7692     {
7693       myerror("mysql_client_init() failed");
7694       exit(1);
7695     }
7696 
7697     rc= mysql_query(mysql, "flush privileges");
7698     myquery(rc);
7699 
7700     if (!(mysql_real_connect(lmysql, opt_host ? opt_host : "localhost", "test_temp",
7701                              "", "test_drop_temp_db", opt_port,
7702                              opt_unix_socket, 0)))
7703     {
7704       mysql= lmysql;
7705       myerror("connection failed");
7706       mysql_close(lmysql);
7707       exit(1);
7708     }
7709     mysql_options(lmysql, MYSQL_OPT_RECONNECT, &my_true);
7710     if (!opt_silent)
7711       fprintf(stdout, "OK");
7712 
7713     mysql= lmysql;
7714     rc= mysql_query(mysql, "INSERT INTO t1 VALUES(10, 'C')");
7715     myerrno((uint)1142);
7716 
7717     rc= mysql_query(mysql, "DROP TABLE t1");
7718     myerrno((uint)1142);
7719 
7720     mysql= org_mysql;
7721     rc= mysql_query(mysql, "CREATE TEMPORARY TABLE test_drop_temp_db.t1(c1 int)");
7722     myquery(rc);
7723 
7724     rc= mysql_query(mysql, "CREATE TEMPORARY TABLE test_drop_temp_db.t2 LIKE test_drop_temp_db.t1");
7725     myquery(rc);
7726 
7727     mysql= lmysql;
7728 
7729     rc= mysql_query(mysql, "DROP TABLE t1, t2");
7730     myquery_r(rc);
7731 
7732     rc= mysql_query(mysql, "DROP TEMPORARY TABLE t1");
7733     myquery_r(rc);
7734 
7735     rc= mysql_query(mysql, "DROP TEMPORARY TABLE t2");
7736     myquery_r(rc);
7737 
7738     mysql_close(lmysql);
7739     mysql= org_mysql;
7740 
7741     rc= mysql_query(mysql, "drop database test_drop_temp_db");
7742     myquery(rc);
7743     DIE_UNLESS(1 == mysql_affected_rows(mysql));
7744 
7745     rc= mysql_query(mysql, "delete from mysql.user where User='test_temp'");
7746     myquery(rc);
7747     DIE_UNLESS(1 == mysql_affected_rows(mysql));
7748 
7749 
7750     rc= mysql_query(mysql, "delete from mysql.tables_priv where User='test_temp'");
7751     myquery(rc);
7752     DIE_UNLESS(1 == mysql_affected_rows(mysql));
7753   }
7754 }
7755 #endif
7756 
7757 
7758 /* Test warnings for cuted rows */
7759 
test_cuted_rows()7760 static void test_cuted_rows()
7761 {
7762   int        rc, count;
7763   MYSQL_RES  *result;
7764 
7765   myheader("test_cuted_rows");
7766 
7767   mysql_query(mysql, "DROP TABLE if exists t1");
7768   mysql_query(mysql, "DROP TABLE if exists t2");
7769 
7770   rc= mysql_query(mysql, "CREATE TABLE t1(c1 tinyint)");
7771   myquery(rc);
7772 
7773   rc= mysql_query(mysql, "CREATE TABLE t2(c1 int not null)");
7774   myquery(rc);
7775 
7776   rc= mysql_query(mysql, "INSERT INTO t1 values(10), (NULL), (NULL)");
7777   myquery(rc);
7778 
7779   count= mysql_warning_count(mysql);
7780   if (!opt_silent)
7781     fprintf(stdout, "\n total warnings: %d", count);
7782   DIE_UNLESS(count == 0);
7783 
7784   rc= mysql_query(mysql, "INSERT INTO t2 SELECT * FROM t1");
7785   myquery(rc);
7786 
7787   count= mysql_warning_count(mysql);
7788   if (!opt_silent)
7789     fprintf(stdout, "\n total warnings: %d", count);
7790   DIE_UNLESS(count == 2);
7791 
7792   rc= mysql_query(mysql, "SHOW WARNINGS");
7793   myquery(rc);
7794 
7795   result= mysql_store_result(mysql);
7796   mytest(result);
7797 
7798   rc= my_process_result_set(result);
7799   DIE_UNLESS(rc == 2);
7800   mysql_free_result(result);
7801 
7802   rc= mysql_query(mysql, "INSERT INTO t1 VALUES('junk'), (876789)");
7803   myquery(rc);
7804 
7805   count= mysql_warning_count(mysql);
7806   if (!opt_silent)
7807     fprintf(stdout, "\n total warnings: %d", count);
7808   DIE_UNLESS(count == 2);
7809 
7810   rc= mysql_query(mysql, "SHOW WARNINGS");
7811   myquery(rc);
7812 
7813   result= mysql_store_result(mysql);
7814   mytest(result);
7815 
7816   rc= my_process_result_set(result);
7817   DIE_UNLESS(rc == 2);
7818   mysql_free_result(result);
7819 }
7820 
7821 
7822 /* Test update/binary logs */
7823 
test_logs()7824 static void test_logs()
7825 {
7826   MYSQL_STMT *stmt;
7827   MYSQL_BIND my_bind[2];
7828   char       data[255];
7829   ulong      length;
7830   int        rc;
7831   short      id;
7832 
7833   myheader("test_logs");
7834 
7835 
7836   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_logs");
7837   myquery(rc);
7838 
7839   rc= mysql_query(mysql, "CREATE TABLE test_logs(id smallint, name varchar(20))");
7840   myquery(rc);
7841 
7842   strmov((char *)data, "INSERT INTO test_logs VALUES(?, ?)");
7843   stmt= mysql_simple_prepare(mysql, data);
7844   check_stmt(stmt);
7845 
7846   /*
7847     We need to bzero bind structure because mysql_stmt_bind_param checks all
7848     its members.
7849   */
7850   bzero((char*) my_bind, sizeof(my_bind));
7851 
7852   my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
7853   my_bind[0].buffer= (void *)&id;
7854 
7855   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
7856   my_bind[1].buffer= (void *)&data;
7857   my_bind[1].buffer_length= 255;
7858   my_bind[1].length= &length;
7859 
7860   id= 9876;
7861   length= (ulong)(strmov((char *)data, "MySQL - Open Source Database")- data);
7862 
7863   rc= mysql_stmt_bind_param(stmt, my_bind);
7864   check_execute(stmt, rc);
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   strmov((char *)data, "\"");
7876   length= 1;
7877 
7878   rc= mysql_stmt_execute(stmt);
7879   check_execute(stmt, rc);
7880 
7881   length= (ulong)(strmov((char *)data, "my\'sql\'")-data);
7882   rc= mysql_stmt_execute(stmt);
7883   check_execute(stmt, rc);
7884 
7885   length= (ulong)(strmov((char *)data, "my\"sql\"")-data);
7886   rc= mysql_stmt_execute(stmt);
7887   check_execute(stmt, rc);
7888 
7889   mysql_stmt_close(stmt);
7890 
7891   strmov((char *)data, "INSERT INTO test_logs VALUES(20, 'mysql')");
7892   stmt= mysql_simple_prepare(mysql, data);
7893   check_stmt(stmt);
7894 
7895   rc= mysql_stmt_execute(stmt);
7896   check_execute(stmt, rc);
7897 
7898   rc= mysql_stmt_execute(stmt);
7899   check_execute(stmt, rc);
7900 
7901   mysql_stmt_close(stmt);
7902 
7903   strmov((char *)data, "SELECT * FROM test_logs WHERE id=?");
7904   stmt= mysql_simple_prepare(mysql, data);
7905   check_stmt(stmt);
7906 
7907   rc= mysql_stmt_bind_param(stmt, my_bind);
7908   check_execute(stmt, rc);
7909 
7910   rc= mysql_stmt_execute(stmt);
7911   check_execute(stmt, rc);
7912 
7913   my_bind[1].buffer_length= 255;
7914   rc= mysql_stmt_bind_result(stmt, my_bind);
7915   check_execute(stmt, rc);
7916 
7917   rc= mysql_stmt_fetch(stmt);
7918   check_execute(stmt, rc);
7919 
7920   if (!opt_silent)
7921   {
7922     fprintf(stdout, "id    : %d\n", id);
7923     fprintf(stdout, "name  : %s(%ld)\n", data, length);
7924   }
7925 
7926   DIE_UNLESS(id == 9876);
7927   DIE_UNLESS(length == 19 || length == 20); /* Due to VARCHAR(20) */
7928   DIE_UNLESS(is_prefix(data, "MySQL - Open Source") == 1);
7929 
7930   rc= mysql_stmt_fetch(stmt);
7931   check_execute(stmt, rc);
7932 
7933   if (!opt_silent)
7934     fprintf(stdout, "\n name  : %s(%ld)", data, length);
7935 
7936   DIE_UNLESS(length == 1);
7937   DIE_UNLESS(strcmp(data, "'") == 0);
7938 
7939   rc= mysql_stmt_fetch(stmt);
7940   check_execute(stmt, rc);
7941 
7942   if (!opt_silent)
7943     fprintf(stdout, "\n name  : %s(%ld)", data, length);
7944 
7945   DIE_UNLESS(length == 1);
7946   DIE_UNLESS(strcmp(data, "\"") == 0);
7947 
7948   rc= mysql_stmt_fetch(stmt);
7949   check_execute(stmt, rc);
7950 
7951   if (!opt_silent)
7952     fprintf(stdout, "\n name  : %s(%ld)", data, length);
7953 
7954   DIE_UNLESS(length == 7);
7955   DIE_UNLESS(strcmp(data, "my\'sql\'") == 0);
7956 
7957   rc= mysql_stmt_fetch(stmt);
7958   check_execute(stmt, rc);
7959 
7960   if (!opt_silent)
7961     fprintf(stdout, "\n name  : %s(%ld)", data, length);
7962 
7963   DIE_UNLESS(length == 7);
7964   /*DIE_UNLESS(strcmp(data, "my\"sql\"") == 0); */
7965 
7966   rc= mysql_stmt_fetch(stmt);
7967   DIE_UNLESS(rc == MYSQL_NO_DATA);
7968 
7969   mysql_stmt_close(stmt);
7970 
7971   rc= mysql_query(mysql, "DROP TABLE test_logs");
7972   myquery(rc);
7973 }
7974 
7975 
7976 /* Test 'n' statements create and close */
7977 
test_nstmts()7978 static void test_nstmts()
7979 {
7980   MYSQL_STMT  *stmt;
7981   char        query[255];
7982   int         rc;
7983   static uint i, total_stmts= 2000;
7984   MYSQL_BIND  my_bind[1];
7985 
7986   myheader("test_nstmts");
7987 
7988   mysql_autocommit(mysql, TRUE);
7989 
7990   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_nstmts");
7991   myquery(rc);
7992 
7993   rc= mysql_query(mysql, "CREATE TABLE test_nstmts(id int)");
7994   myquery(rc);
7995 
7996   /*
7997     We need to bzero bind structure because mysql_stmt_bind_param checks all
7998     its members.
7999   */
8000   bzero((char*) my_bind, sizeof(my_bind));
8001 
8002   my_bind[0].buffer= (void *)&i;
8003   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8004 
8005   for (i= 0; i < total_stmts; i++)
8006   {
8007     if (!opt_silent)
8008       fprintf(stdout, "\r stmt: %d", i);
8009 
8010     strmov(query, "insert into test_nstmts values(?)");
8011     stmt= mysql_simple_prepare(mysql, query);
8012     check_stmt(stmt);
8013 
8014     rc= mysql_stmt_bind_param(stmt, my_bind);
8015     check_execute(stmt, rc);
8016 
8017     rc= mysql_stmt_execute(stmt);
8018     check_execute(stmt, rc);
8019 
8020     mysql_stmt_close(stmt);
8021   }
8022 
8023   stmt= mysql_simple_prepare(mysql, " select count(*) from test_nstmts");
8024   check_stmt(stmt);
8025 
8026   rc= mysql_stmt_execute(stmt);
8027   check_execute(stmt, rc);
8028 
8029   i= 0;
8030   rc= mysql_stmt_bind_result(stmt, my_bind);
8031   check_execute(stmt, rc);
8032 
8033   rc= mysql_stmt_fetch(stmt);
8034   check_execute(stmt, rc);
8035   if (!opt_silent)
8036     fprintf(stdout, "\n total rows: %d", i);
8037   DIE_UNLESS( i == total_stmts);
8038 
8039   rc= mysql_stmt_fetch(stmt);
8040   DIE_UNLESS(rc == MYSQL_NO_DATA);
8041 
8042   mysql_stmt_close(stmt);
8043 
8044   rc= mysql_query(mysql, "DROP TABLE test_nstmts");
8045   myquery(rc);
8046 }
8047 
8048 
8049 /* Test stmt seek() functions */
8050 
test_fetch_seek()8051 static void test_fetch_seek()
8052 {
8053   MYSQL_STMT *stmt;
8054   MYSQL_BIND my_bind[3];
8055   MYSQL_ROW_OFFSET row;
8056   int        rc;
8057   int32      c1;
8058   char       c2[11], c3[20];
8059 
8060   myheader("test_fetch_seek");
8061   rc= mysql_query(mysql, "drop table if exists t1");
8062 
8063   myquery(rc);
8064 
8065   rc= mysql_query(mysql, "create table t1(c1 int primary key auto_increment, c2 char(10), c3 timestamp)");
8066   myquery(rc);
8067 
8068   rc= mysql_query(mysql, "insert into t1(c2) values('venu'), ('mysql'), ('open'), ('source')");
8069   myquery(rc);
8070 
8071   stmt= mysql_simple_prepare(mysql, "select * from t1");
8072   check_stmt(stmt);
8073 
8074   bzero((char*) my_bind, sizeof(my_bind));
8075   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8076   my_bind[0].buffer= (void *)&c1;
8077 
8078   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
8079   my_bind[1].buffer= (void *)c2;
8080   my_bind[1].buffer_length= sizeof(c2);
8081 
8082   my_bind[2]= my_bind[1];
8083   my_bind[2].buffer= (void *)c3;
8084   my_bind[2].buffer_length= sizeof(c3);
8085 
8086   rc= mysql_stmt_execute(stmt);
8087   check_execute(stmt, rc);
8088 
8089   rc= mysql_stmt_bind_result(stmt, my_bind);
8090   check_execute(stmt, rc);
8091 
8092   rc= mysql_stmt_store_result(stmt);
8093   check_execute(stmt, rc);
8094 
8095   rc= mysql_stmt_fetch(stmt);
8096   check_execute(stmt, rc);
8097 
8098   if (!opt_silent)
8099     fprintf(stdout, "\n row 0: %ld, %s, %s", (long) c1, c2, c3);
8100 
8101   row= mysql_stmt_row_tell(stmt);
8102 
8103   row= mysql_stmt_row_seek(stmt, row);
8104 
8105   rc= mysql_stmt_fetch(stmt);
8106   check_execute(stmt, rc);
8107 
8108   if (!opt_silent)
8109     fprintf(stdout, "\n row 2: %ld, %s, %s", (long) c1, c2, c3);
8110 
8111   row= mysql_stmt_row_seek(stmt, row);
8112 
8113   rc= mysql_stmt_fetch(stmt);
8114   check_execute(stmt, rc);
8115 
8116   if (!opt_silent)
8117     fprintf(stdout, "\n row 2: %ld, %s, %s", (long) c1, c2, c3);
8118 
8119   mysql_stmt_data_seek(stmt, 0);
8120 
8121   rc= mysql_stmt_fetch(stmt);
8122   check_execute(stmt, rc);
8123 
8124   if (!opt_silent)
8125     fprintf(stdout, "\n row 0: %ld, %s, %s", (long) c1, c2, c3);
8126 
8127   rc= mysql_stmt_fetch(stmt);
8128   check_execute(stmt, rc);
8129 
8130   rc= mysql_stmt_fetch(stmt);
8131   check_execute(stmt, rc);
8132 
8133   rc= mysql_stmt_fetch(stmt);
8134   check_execute(stmt, rc);
8135 
8136   rc= mysql_stmt_fetch(stmt);
8137   DIE_UNLESS(rc == MYSQL_NO_DATA);
8138 
8139   mysql_stmt_close(stmt);
8140   myquery(mysql_query(mysql, "drop table t1"));
8141 }
8142 
8143 
8144 /* Test mysql_stmt_fetch_column() with offset */
8145 
test_fetch_offset()8146 static void test_fetch_offset()
8147 {
8148   MYSQL_STMT *stmt;
8149   MYSQL_BIND my_bind[1];
8150   char       data[11];
8151   ulong      length;
8152   int        rc;
8153   my_bool    is_null;
8154 
8155 
8156   myheader("test_fetch_offset");
8157 
8158   rc= mysql_query(mysql, "drop table if exists t1");
8159   myquery(rc);
8160 
8161   rc= mysql_query(mysql, "create table t1(a char(10))");
8162   myquery(rc);
8163 
8164   rc= mysql_query(mysql, "insert into t1 values('abcdefghij'), (null)");
8165   myquery(rc);
8166 
8167   stmt= mysql_simple_prepare(mysql, "select * from t1");
8168   check_stmt(stmt);
8169 
8170   bzero((char*) my_bind, sizeof(my_bind));
8171   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8172   my_bind[0].buffer= (void *)data;
8173   my_bind[0].buffer_length= 11;
8174   my_bind[0].is_null= &is_null;
8175   my_bind[0].length= &length;
8176 
8177   rc= mysql_stmt_execute(stmt);
8178   check_execute(stmt, rc);
8179 
8180   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8181   check_execute_r(stmt, rc);
8182 
8183   rc= mysql_stmt_execute(stmt);
8184   check_execute(stmt, rc);
8185 
8186   rc= mysql_stmt_bind_result(stmt, my_bind);
8187   check_execute(stmt, rc);
8188 
8189   rc= mysql_stmt_store_result(stmt);
8190   check_execute(stmt, rc);
8191 
8192   rc= mysql_stmt_fetch(stmt);
8193   check_execute(stmt, rc);
8194 
8195   data[0]= '\0';
8196   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8197   check_execute(stmt, rc);
8198   if (!opt_silent)
8199     fprintf(stdout, "\n col 1: %s (%ld)", data, length);
8200   DIE_UNLESS(strncmp(data, "abcd", 4) == 0 && length == 10);
8201 
8202   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 5);
8203   check_execute(stmt, rc);
8204   if (!opt_silent)
8205     fprintf(stdout, "\n col 1: %s (%ld)", data, length);
8206   DIE_UNLESS(strncmp(data, "fg", 2) == 0 && length == 10);
8207 
8208   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 9);
8209   check_execute(stmt, rc);
8210   if (!opt_silent)
8211     fprintf(stdout, "\n col 0: %s (%ld)", data, length);
8212   DIE_UNLESS(strncmp(data, "j", 1) == 0 && length == 10);
8213 
8214   rc= mysql_stmt_fetch(stmt);
8215   check_execute(stmt, rc);
8216 
8217   is_null= 0;
8218 
8219   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8220   check_execute(stmt, rc);
8221 
8222   DIE_UNLESS(is_null == 1);
8223 
8224   rc= mysql_stmt_fetch(stmt);
8225   DIE_UNLESS(rc == MYSQL_NO_DATA);
8226 
8227   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8228   check_execute_r(stmt, rc);
8229 
8230   mysql_stmt_close(stmt);
8231 
8232   myquery(mysql_query(mysql, "drop table t1"));
8233 }
8234 
8235 
8236 /* Test mysql_stmt_fetch_column() */
8237 
test_fetch_column()8238 static void test_fetch_column()
8239 {
8240   MYSQL_STMT *stmt;
8241   MYSQL_BIND my_bind[2];
8242   char       c2[20], bc2[20];
8243   ulong      l1, l2, bl1, bl2;
8244   int        rc, c1, bc1;
8245 
8246   myheader("test_fetch_column");
8247 
8248   rc= mysql_query(mysql, "drop table if exists t1");
8249   myquery(rc);
8250 
8251   rc= mysql_query(mysql, "create table t1(c1 int primary key auto_increment, c2 char(10))");
8252   myquery(rc);
8253 
8254   rc= mysql_query(mysql, "insert into t1(c2) values('venu'), ('mysql')");
8255   myquery(rc);
8256 
8257   stmt= mysql_simple_prepare(mysql, "select * from t1 order by c2 desc");
8258   check_stmt(stmt);
8259 
8260   bzero((char*) my_bind, sizeof(my_bind));
8261   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8262   my_bind[0].buffer= (void *)&bc1;
8263   my_bind[0].buffer_length= 0;
8264   my_bind[0].is_null= 0;
8265   my_bind[0].length= &bl1;
8266   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
8267   my_bind[1].buffer= (void *)bc2;
8268   my_bind[1].buffer_length= 7;
8269   my_bind[1].is_null= 0;
8270   my_bind[1].length= &bl2;
8271 
8272   rc= mysql_stmt_execute(stmt);
8273   check_execute(stmt, rc);
8274 
8275   rc= mysql_stmt_bind_result(stmt, my_bind);
8276   check_execute(stmt, rc);
8277 
8278   rc= mysql_stmt_store_result(stmt);
8279   check_execute(stmt, rc);
8280 
8281   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0); /* No-op at this point */
8282   check_execute_r(stmt, rc);
8283 
8284   rc= mysql_stmt_fetch(stmt);
8285   check_execute(stmt, rc);
8286 
8287   if (!opt_silent)
8288     fprintf(stdout, "\n row 0: %d, %s", bc1, bc2);
8289 
8290   c2[0]= '\0'; l2= 0;
8291   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8292   my_bind[0].buffer= (void *)c2;
8293   my_bind[0].buffer_length= 7;
8294   my_bind[0].is_null= 0;
8295   my_bind[0].length= &l2;
8296 
8297   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8298   check_execute(stmt, rc);
8299   if (!opt_silent)
8300     fprintf(stdout, "\n col 1: %s(%ld)", c2, l2);
8301   DIE_UNLESS(strncmp(c2, "venu", 4) == 0 && l2 == 4);
8302 
8303   c2[0]= '\0'; l2= 0;
8304   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8305   check_execute(stmt, rc);
8306   if (!opt_silent)
8307     fprintf(stdout, "\n col 1: %s(%ld)", c2, l2);
8308   DIE_UNLESS(strcmp(c2, "venu") == 0 && l2 == 4);
8309 
8310   c1= 0;
8311   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8312   my_bind[0].buffer= (void *)&c1;
8313   my_bind[0].buffer_length= 0;
8314   my_bind[0].is_null= 0;
8315   my_bind[0].length= &l1;
8316 
8317   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8318   check_execute(stmt, rc);
8319   if (!opt_silent)
8320     fprintf(stdout, "\n col 0: %d(%ld)", c1, l1);
8321   DIE_UNLESS(c1 == 1 && l1 == 4);
8322 
8323   rc= mysql_stmt_fetch(stmt);
8324   check_execute(stmt, rc);
8325 
8326   if (!opt_silent)
8327     fprintf(stdout, "\n row 1: %d, %s", bc1, bc2);
8328 
8329   c2[0]= '\0'; l2= 0;
8330   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8331   my_bind[0].buffer= (void *)c2;
8332   my_bind[0].buffer_length= 7;
8333   my_bind[0].is_null= 0;
8334   my_bind[0].length= &l2;
8335 
8336   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8337   check_execute(stmt, rc);
8338   if (!opt_silent)
8339     fprintf(stdout, "\n col 1: %s(%ld)", c2, l2);
8340   DIE_UNLESS(strncmp(c2, "mysq", 4) == 0 && l2 == 5);
8341 
8342   c2[0]= '\0'; l2= 0;
8343   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8344   check_execute(stmt, rc);
8345   if (!opt_silent)
8346     fprintf(stdout, "\n col 1: %si(%ld)", c2, l2);
8347   DIE_UNLESS(strcmp(c2, "mysql") == 0 && l2 == 5);
8348 
8349   c1= 0;
8350   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8351   my_bind[0].buffer= (void *)&c1;
8352   my_bind[0].buffer_length= 0;
8353   my_bind[0].is_null= 0;
8354   my_bind[0].length= &l1;
8355 
8356   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8357   check_execute(stmt, rc);
8358   if (!opt_silent)
8359     fprintf(stdout, "\n col 0: %d(%ld)", c1, l1);
8360   DIE_UNLESS(c1 == 2 && l1 == 4);
8361 
8362   rc= mysql_stmt_fetch(stmt);
8363   DIE_UNLESS(rc == MYSQL_NO_DATA);
8364 
8365   rc= mysql_stmt_fetch_column(stmt, my_bind, 1, 0);
8366   check_execute_r(stmt, rc);
8367 
8368   mysql_stmt_close(stmt);
8369   myquery(mysql_query(mysql, "drop table t1"));
8370 }
8371 
8372 
8373 /* Test mysql_list_fields() */
8374 
test_list_fields()8375 static void test_list_fields()
8376 {
8377   MYSQL_RES *result;
8378   int rc;
8379   myheader("test_list_fields");
8380 
8381   rc= mysql_query(mysql, "drop table if exists t1");
8382   myquery(rc);
8383 
8384   rc= mysql_query(mysql, "create table t1(c1 int primary key auto_increment, c2 char(10) default 'mysql')");
8385   myquery(rc);
8386 
8387   result= mysql_list_fields(mysql, "t1", NULL);
8388   mytest(result);
8389 
8390   rc= my_process_result_set(result);
8391   DIE_UNLESS(rc == 0);
8392 
8393   verify_prepare_field(result, 0, "c1", "c1", MYSQL_TYPE_LONG,
8394                        "t1", "t1",
8395                        current_db, 11, "0");
8396 
8397   verify_prepare_field(result, 1, "c2", "c2", MYSQL_TYPE_STRING,
8398                        "t1", "t1",
8399                        current_db, 10, "mysql");
8400 
8401   mysql_free_result(result);
8402   myquery(mysql_query(mysql, "drop table t1"));
8403 }
8404 
8405 
8406 /* Test mysql_list_fields() with information_schema */
8407 
test_list_information_schema_fields()8408 static void test_list_information_schema_fields()
8409 {
8410   MYSQL_RES *result;
8411   int rc;
8412   myheader("test_list_information_schema_fields");
8413 
8414   rc= mysql_select_db(mysql, "information_schema");
8415   myquery(rc);
8416   result= mysql_list_fields(mysql, "all_plugins", NULL);
8417   mytest(result);
8418   rc= my_process_result_set(result);
8419   DIE_UNLESS(rc == 0);
8420   mysql_free_result(result);
8421   rc= mysql_select_db(mysql, current_db);
8422   myquery(rc);
8423 }
8424 
8425 
test_list_fields_blob()8426 static void test_list_fields_blob()
8427 {
8428   MYSQL_RES *result;
8429   int rc;
8430   myheader("test_list_fields_blob");
8431 
8432   rc= mysql_query(mysql, "drop table if exists t1");
8433   myquery(rc);
8434 
8435   rc= mysql_query(mysql, "create table t1(c1 tinyblob, c2 blob, c3 mediumblob, c4 longblob)");
8436   myquery(rc);
8437 
8438   result= mysql_list_fields(mysql, "t1", NULL);
8439   mytest(result);
8440 
8441   rc= my_process_result_set(result);
8442   DIE_UNLESS(rc == 0);
8443 
8444   /*
8445     All BLOB variant Fields are displayed as MYSQL_TYPE_BLOB in
8446     the result set metadata. Note, some Items display the exact
8447     BLOB type. This inconsistency should be fixed eventually.
8448   */
8449   verify_prepare_field(result, 0, "c1", "c1", MYSQL_TYPE_BLOB,
8450                        "t1", "t1",
8451                        current_db, 255, NULL);
8452 
8453   verify_prepare_field(result, 1, "c2", "c2", MYSQL_TYPE_BLOB,
8454                        "t1", "t1",
8455                        current_db, 65535, NULL);
8456 
8457   verify_prepare_field(result, 2, "c3", "c3", MYSQL_TYPE_BLOB,
8458                        "t1", "t1",
8459                        current_db, 16777215, NULL);
8460 
8461   verify_prepare_field(result, 3, "c4", "c4", MYSQL_TYPE_BLOB,
8462                        "t1", "t1",
8463                        current_db, 4294967295ULL, NULL);
8464 
8465   mysql_free_result(result);
8466   myquery(mysql_query(mysql, "drop table t1"));
8467 }
8468 
8469 
test_list_fields_default()8470 static void test_list_fields_default()
8471 {
8472   int rc, i;
8473   myheader("test_list_fields_default");
8474 
8475   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
8476   myquery(rc);
8477 
8478   rc= mysql_query(mysql,
8479                   "CREATE TABLE t1 ("
8480                   " i1 INT NOT NULL DEFAULT 0,"
8481                   " i3 BIGINT UNSIGNED NOT NULL DEFAULT 0xFFFFFFFFFFFFFFFF,"
8482                   " s1 VARCHAR(10) CHARACTER SET latin1 NOT NULL DEFAULT 's1def',"
8483                   " d1 DECIMAL(31,1) NOT NULL DEFAULT 111111111122222222223333333333.9,"
8484                   " t1 DATETIME(6) NOT NULL DEFAULT '2001-01-01 10:20:30.123456',"
8485                   " e1 ENUM('a','b') NOT NULL DEFAULT 'a'"
8486                   ")");
8487   myquery(rc);
8488 
8489   rc= mysql_query(mysql, "DROP VIEW IF EXISTS v1");
8490   myquery(rc);
8491 
8492   rc= mysql_query(mysql, "CREATE VIEW v1 AS SELECT * FROM t1");
8493   myquery(rc);
8494 
8495   /*
8496     Checking that mysql_list_fields() returns the same result
8497     for a TABLE and a VIEW on the same table.
8498   */
8499   for (i= 0; i < 2; i++)
8500   {
8501     const char *table_name= i == 0 ? "t1" : "v1";
8502     MYSQL_RES *result= mysql_list_fields(mysql, table_name, NULL);
8503     mytest(result);
8504 
8505     rc= my_process_result_set(result);
8506     DIE_UNLESS(rc == 0);
8507 
8508     verify_prepare_field(result, 0, "i1", "i1", MYSQL_TYPE_LONG,
8509                          table_name, table_name, current_db,
8510                          11, "0");
8511 
8512     verify_prepare_field(result, 1, "i3", "i3", MYSQL_TYPE_LONGLONG,
8513                          table_name, table_name, current_db,
8514                          20, "18446744073709551615");
8515 
8516     verify_prepare_field(result, 2, "s1", "s1", MYSQL_TYPE_VAR_STRING,
8517                          table_name, table_name, current_db,
8518                          10, "s1def");
8519 
8520     verify_prepare_field(result, 3, "d1", "d1", MYSQL_TYPE_NEWDECIMAL,
8521                          table_name, table_name, current_db,
8522                          33, "111111111122222222223333333333.9");
8523 
8524     verify_prepare_field(result, 4, "t1", "t1", MYSQL_TYPE_DATETIME,
8525                          table_name, table_name, current_db,
8526                          26, "2001-01-01 10:20:30.123456");
8527 
8528     verify_prepare_field(result, 5, "e1", "e1", MYSQL_TYPE_STRING,
8529                          table_name, table_name, current_db,
8530                          1, "a");
8531 
8532     mysql_free_result(result);
8533   }
8534 
8535   myquery(mysql_query(mysql, "DROP VIEW v1"));
8536   myquery(mysql_query(mysql, "DROP TABLE t1"));
8537 }
8538 
8539 
8540 /**
8541   Note, this test covers MDEV-18408 and MDEV-18685
8542 */
8543 
test_mdev18408()8544 static void test_mdev18408()
8545 {
8546   MYSQL_RES *result;
8547   int rc;
8548   myheader("test_mdev18408s");
8549 
8550   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
8551   myquery(rc);
8552 
8553   rc= mysql_query(mysql, "DROP VIEW IF EXISTS v1");
8554   myquery(rc);
8555 
8556   rc= mysql_query(mysql, "CREATE TABLE t1 (c1 TIMESTAMP NULL DEFAULT NULL)");
8557   myquery(rc);
8558 
8559   rc= mysql_query(mysql, "CREATE VIEW v1 AS SELECT c1 FROM t1");
8560   myquery(rc);
8561 
8562   result= mysql_list_fields(mysql, "v1", NULL);
8563   mytest(result);
8564 
8565   rc= my_process_result_set(result);
8566   DIE_UNLESS(rc == 0);
8567 
8568   verify_prepare_field(result, 0, "c1", "c1", MYSQL_TYPE_TIMESTAMP,
8569                        "v1", "v1",  current_db, 19, 0);
8570 
8571   mysql_free_result(result);
8572   myquery(mysql_query(mysql, "DROP VIEW v1"));
8573   myquery(mysql_query(mysql, "DROP TABLE t1"));
8574 }
8575 
8576 
test_bug19671()8577 static void test_bug19671()
8578 {
8579   MYSQL_RES *result;
8580   int rc;
8581   myheader("test_bug19671");
8582 
8583   mysql_query(mysql, "set sql_mode=''");
8584   rc= mysql_query(mysql, "drop table if exists t1");
8585   myquery(rc);
8586 
8587   rc= mysql_query(mysql, "drop view if exists v1");
8588   myquery(rc);
8589 
8590   rc= mysql_query(mysql, "create table t1(f1 int)");
8591   myquery(rc);
8592 
8593   rc= mysql_query(mysql, "create view v1 as select va.* from t1 va");
8594   myquery(rc);
8595 
8596   result= mysql_list_fields(mysql, "v1", NULL);
8597   mytest(result);
8598 
8599   rc= my_process_result_set(result);
8600   DIE_UNLESS(rc == 0);
8601 
8602   verify_prepare_field(result, 0, "f1", "f1", MYSQL_TYPE_LONG,
8603                        "v1", "v1", current_db, 11, NULL);
8604 
8605   mysql_free_result(result);
8606   myquery(mysql_query(mysql, "drop view v1"));
8607   myquery(mysql_query(mysql, "drop table t1"));
8608 }
8609 
8610 
8611 /* Test a memory ovverun bug */
8612 
test_mem_overun()8613 static void test_mem_overun()
8614 {
8615   char       buffer[10000], field[10];
8616   MYSQL_STMT *stmt;
8617   MYSQL_RES  *field_res;
8618   int        rc, length;
8619   unsigned   i;
8620 
8621   myheader("test_mem_overun");
8622 
8623   /*
8624     Test a memory ovverun bug when a table had 1000 fields with
8625     a row of data
8626   */
8627   rc= mysql_query(mysql, "drop table if exists t_mem_overun");
8628   myquery(rc);
8629 
8630   strxmov(buffer, "create table t_mem_overun(", NullS);
8631   for (i= 0; i < 1000; i++)
8632   {
8633     sprintf(field, "c%u int", i);
8634     strxmov(buffer, buffer, field, ", ", NullS);
8635   }
8636   length= strlen(buffer);
8637   buffer[length-2]= ')';
8638   buffer[--length]= '\0';
8639 
8640   rc= mysql_real_query(mysql, buffer, length);
8641   myquery(rc);
8642 
8643   strxmov(buffer, "insert into t_mem_overun values(", NullS);
8644   for (i= 0; i < 1000; i++)
8645   {
8646     strxmov(buffer, buffer, "1, ", NullS);
8647   }
8648   length= strlen(buffer);
8649   buffer[length-2]= ')';
8650   buffer[--length]= '\0';
8651 
8652   rc= mysql_real_query(mysql, buffer, length);
8653   myquery(rc);
8654 
8655   rc= mysql_query(mysql, "select * from t_mem_overun");
8656   myquery(rc);
8657 
8658   rc= my_process_result(mysql);
8659   DIE_UNLESS(rc == 1);
8660 
8661   stmt= mysql_simple_prepare(mysql, "select * from t_mem_overun");
8662   check_stmt(stmt);
8663 
8664   rc= mysql_stmt_execute(stmt);
8665   check_execute(stmt, rc);
8666 
8667   field_res= mysql_stmt_result_metadata(stmt);
8668   mytest(field_res);
8669 
8670   if (!opt_silent)
8671     fprintf(stdout, "\n total fields : %d", mysql_num_fields(field_res));
8672   DIE_UNLESS( 1000 == mysql_num_fields(field_res));
8673 
8674   rc= mysql_stmt_store_result(stmt);
8675   check_execute(stmt, rc);
8676 
8677   rc= mysql_stmt_fetch(stmt);
8678   check_execute(stmt, rc);
8679 
8680   rc= mysql_stmt_fetch(stmt);
8681   DIE_UNLESS(rc == MYSQL_NO_DATA);
8682 
8683   mysql_free_result(field_res);
8684 
8685   mysql_stmt_close(stmt);
8686 }
8687 
8688 
8689 /* Test mysql_stmt_free_result() */
8690 
test_free_result()8691 static void test_free_result()
8692 {
8693   MYSQL_STMT *stmt;
8694   MYSQL_BIND my_bind[1];
8695   char       c2[5];
8696   ulong      bl1, l2;
8697   int        rc, c1, bc1;
8698 
8699   myheader("test_free_result");
8700 
8701   rc= mysql_query(mysql, "drop table if exists test_free_result");
8702   myquery(rc);
8703 
8704   rc= mysql_query(mysql, "create table test_free_result("
8705                          "c1 int primary key auto_increment)");
8706   myquery(rc);
8707 
8708   rc= mysql_query(mysql, "insert into test_free_result values(), (), ()");
8709   myquery(rc);
8710 
8711   stmt= mysql_simple_prepare(mysql, "select * from test_free_result");
8712   check_stmt(stmt);
8713 
8714   bzero((char*) my_bind, sizeof(my_bind));
8715   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8716   my_bind[0].buffer= (void *)&bc1;
8717   my_bind[0].length= &bl1;
8718 
8719   rc= mysql_stmt_execute(stmt);
8720   check_execute(stmt, rc);
8721 
8722   rc= mysql_stmt_bind_result(stmt, my_bind);
8723   check_execute(stmt, rc);
8724 
8725   rc= mysql_stmt_fetch(stmt);
8726   check_execute(stmt, rc);
8727 
8728   c2[0]= '\0'; l2= 0;
8729   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8730   my_bind[0].buffer= (void *)c2;
8731   my_bind[0].buffer_length= 7;
8732   my_bind[0].is_null= 0;
8733   my_bind[0].length= &l2;
8734 
8735   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8736   check_execute(stmt, rc);
8737   if (!opt_silent)
8738     fprintf(stdout, "\n col 0: %s(%ld)", c2, l2);
8739   DIE_UNLESS(strncmp(c2, "1", 1) == 0 && l2 == 1);
8740 
8741   rc= mysql_stmt_fetch(stmt);
8742   check_execute(stmt, rc);
8743 
8744   c1= 0, l2= 0;
8745   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8746   my_bind[0].buffer= (void *)&c1;
8747   my_bind[0].buffer_length= 0;
8748   my_bind[0].is_null= 0;
8749   my_bind[0].length= &l2;
8750 
8751   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8752   check_execute(stmt, rc);
8753   if (!opt_silent)
8754     fprintf(stdout, "\n col 0: %d(%ld)", c1, l2);
8755   DIE_UNLESS(c1 == 2 && l2 == 4);
8756 
8757   rc= mysql_query(mysql, "drop table test_free_result");
8758   myquery_r(rc); /* error should be, COMMANDS OUT OF SYNC */
8759 
8760   rc= mysql_stmt_free_result(stmt);
8761   check_execute(stmt, rc);
8762 
8763   rc= mysql_query(mysql, "drop table test_free_result");
8764   myquery(rc);  /* should be successful */
8765 
8766   mysql_stmt_close(stmt);
8767 }
8768 
8769 
8770 /* Test mysql_stmt_store_result() */
8771 
test_free_store_result()8772 static void test_free_store_result()
8773 {
8774   MYSQL_STMT *stmt;
8775   MYSQL_BIND my_bind[1];
8776   char       c2[5];
8777   ulong      bl1, l2;
8778   int        rc, c1, bc1;
8779 
8780   myheader("test_free_store_result");
8781 
8782   rc= mysql_query(mysql, "drop table if exists test_free_result");
8783   myquery(rc);
8784 
8785   rc= mysql_query(mysql, "create table test_free_result(c1 int primary key auto_increment)");
8786   myquery(rc);
8787 
8788   rc= mysql_query(mysql, "insert into test_free_result values(), (), ()");
8789   myquery(rc);
8790 
8791   stmt= mysql_simple_prepare(mysql, "select * from test_free_result");
8792   check_stmt(stmt);
8793 
8794   bzero((char*) my_bind, sizeof(my_bind));
8795   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8796   my_bind[0].buffer= (void *)&bc1;
8797   my_bind[0].buffer_length= 0;
8798   my_bind[0].is_null= 0;
8799   my_bind[0].length= &bl1;
8800 
8801   rc= mysql_stmt_execute(stmt);
8802   check_execute(stmt, rc);
8803 
8804   rc= mysql_stmt_bind_result(stmt, my_bind);
8805   check_execute(stmt, rc);
8806 
8807   rc= mysql_stmt_store_result(stmt);
8808   check_execute(stmt, rc);
8809 
8810   rc= mysql_stmt_fetch(stmt);
8811   check_execute(stmt, rc);
8812 
8813   c2[0]= '\0'; l2= 0;
8814   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8815   my_bind[0].buffer= (void *)c2;
8816   my_bind[0].buffer_length= 7;
8817   my_bind[0].is_null= 0;
8818   my_bind[0].length= &l2;
8819 
8820   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8821   check_execute(stmt, rc);
8822   if (!opt_silent)
8823     fprintf(stdout, "\n col 1: %s(%ld)", c2, l2);
8824   DIE_UNLESS(strncmp(c2, "1", 1) == 0 && l2 == 1);
8825 
8826   rc= mysql_stmt_fetch(stmt);
8827   check_execute(stmt, rc);
8828 
8829   c1= 0, l2= 0;
8830   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
8831   my_bind[0].buffer= (void *)&c1;
8832   my_bind[0].buffer_length= 0;
8833   my_bind[0].is_null= 0;
8834   my_bind[0].length= &l2;
8835 
8836   rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0);
8837   check_execute(stmt, rc);
8838   if (!opt_silent)
8839     fprintf(stdout, "\n col 0: %d(%ld)", c1, l2);
8840   DIE_UNLESS(c1 == 2 && l2 == 4);
8841 
8842   rc= mysql_stmt_free_result(stmt);
8843   check_execute(stmt, rc);
8844 
8845   rc= mysql_query(mysql, "drop table test_free_result");
8846   myquery(rc);
8847 
8848   mysql_stmt_close(stmt);
8849 }
8850 
8851 
8852 /* Test SQLmode */
8853 
test_sqlmode()8854 static void test_sqlmode()
8855 {
8856   MYSQL_STMT *stmt;
8857   MYSQL_BIND my_bind[2];
8858   char       c1[5], c2[5];
8859   int        rc;
8860   char query[MAX_TEST_QUERY_LENGTH];
8861 
8862   myheader("test_sqlmode");
8863 
8864   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_piping");
8865   myquery(rc);
8866 
8867   rc= mysql_query(mysql, "CREATE TABLE test_piping(name varchar(10))");
8868   myquery(rc);
8869 
8870   /* PIPES_AS_CONCAT */
8871   strmov(query, "SET SQL_MODE= \"PIPES_AS_CONCAT\"");
8872   if (!opt_silent)
8873     fprintf(stdout, "\n With %s", query);
8874   rc= mysql_query(mysql, query);
8875   myquery(rc);
8876 
8877   strmov(query, "INSERT INTO test_piping VALUES(?||?)");
8878   if (!opt_silent)
8879     fprintf(stdout, "\n  query: %s", query);
8880   stmt= mysql_simple_prepare(mysql, query);
8881   check_stmt(stmt);
8882 
8883   if (!opt_silent)
8884     fprintf(stdout, "\n  total parameters: %ld", mysql_stmt_param_count(stmt));
8885 
8886   /*
8887     We need to bzero bind structure because mysql_stmt_bind_param checks all
8888     its members.
8889   */
8890   bzero((char*) my_bind, sizeof(my_bind));
8891 
8892   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
8893   my_bind[0].buffer= (void *)c1;
8894   my_bind[0].buffer_length= 2;
8895 
8896   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
8897   my_bind[1].buffer= (void *)c2;
8898   my_bind[1].buffer_length= 3;
8899 
8900   rc= mysql_stmt_bind_param(stmt, my_bind);
8901   check_execute(stmt, rc);
8902 
8903   strmov(c1, "My"); strmov(c2, "SQL");
8904   rc= mysql_stmt_execute(stmt);
8905   check_execute(stmt, rc);
8906   mysql_stmt_close(stmt);
8907 
8908   verify_col_data("test_piping", "name", "MySQL");
8909 
8910   rc= mysql_query(mysql, "DELETE FROM test_piping");
8911   myquery(rc);
8912 
8913   strmov(query, "SELECT connection_id    ()");
8914   if (!opt_silent)
8915     fprintf(stdout, "\n  query: %s", query);
8916   stmt= mysql_simple_prepare(mysql, query);
8917   check_stmt(stmt);
8918   mysql_stmt_close(stmt);
8919 
8920   /* ANSI */
8921   strmov(query, "SET SQL_MODE= \"ANSI\"");
8922   if (!opt_silent)
8923     fprintf(stdout, "\n With %s", query);
8924   rc= mysql_query(mysql, query);
8925   myquery(rc);
8926 
8927   strmov(query, "INSERT INTO test_piping VALUES(?||?)");
8928   if (!opt_silent)
8929     fprintf(stdout, "\n  query: %s", query);
8930   stmt= mysql_simple_prepare(mysql, query);
8931   check_stmt(stmt);
8932   if (!opt_silent)
8933     fprintf(stdout, "\n  total parameters: %ld", mysql_stmt_param_count(stmt));
8934 
8935   rc= mysql_stmt_bind_param(stmt, my_bind);
8936   check_execute(stmt, rc);
8937 
8938   strmov(c1, "My"); strmov(c2, "SQL");
8939   rc= mysql_stmt_execute(stmt);
8940   check_execute(stmt, rc);
8941 
8942   mysql_stmt_close(stmt);
8943   verify_col_data("test_piping", "name", "MySQL");
8944 
8945   /* ANSI mode spaces ... */
8946   strmov(query, "SELECT connection_id    ()");
8947   if (!opt_silent)
8948     fprintf(stdout, "\n  query: %s", query);
8949   stmt= mysql_simple_prepare(mysql, query);
8950   check_stmt(stmt);
8951 
8952   rc= mysql_stmt_execute(stmt);
8953   check_execute(stmt, rc);
8954 
8955   rc= mysql_stmt_fetch(stmt);
8956   check_execute(stmt, rc);
8957 
8958   rc= mysql_stmt_fetch(stmt);
8959   DIE_UNLESS(rc == MYSQL_NO_DATA);
8960   if (!opt_silent)
8961     fprintf(stdout, "\n  returned 1 row\n");
8962 
8963   mysql_stmt_close(stmt);
8964 
8965   /* IGNORE SPACE MODE */
8966   strmov(query, "SET SQL_MODE= \"IGNORE_SPACE\"");
8967   if (!opt_silent)
8968     fprintf(stdout, "\n With %s", query);
8969   rc= mysql_query(mysql, query);
8970   myquery(rc);
8971 
8972   strmov(query, "SELECT connection_id    ()");
8973   if (!opt_silent)
8974     fprintf(stdout, "\n  query: %s", query);
8975   stmt= mysql_simple_prepare(mysql, query);
8976   check_stmt(stmt);
8977 
8978   rc= mysql_stmt_execute(stmt);
8979   check_execute(stmt, rc);
8980 
8981   rc= mysql_stmt_fetch(stmt);
8982   check_execute(stmt, rc);
8983 
8984   rc= mysql_stmt_fetch(stmt);
8985   DIE_UNLESS(rc == MYSQL_NO_DATA);
8986   if (!opt_silent)
8987     fprintf(stdout, "\n  returned 1 row");
8988 
8989   mysql_stmt_close(stmt);
8990 }
8991 
8992 
8993 /* Test for timestamp handling */
8994 
test_ts()8995 static void test_ts()
8996 {
8997   MYSQL_STMT *stmt;
8998   MYSQL_BIND my_bind[6];
8999   MYSQL_TIME ts;
9000   MYSQL_RES  *prep_res;
9001   char       strts[30];
9002   ulong      length;
9003   int        rc, field_count;
9004   char       name;
9005   char query[MAX_TEST_QUERY_LENGTH];
9006   const char *queries [3]= {"SELECT a, b, c FROM test_ts WHERE %c=?",
9007                             "SELECT a, b, c FROM test_ts WHERE %c=CAST(? AS TIME)",
9008                             "SELECT a, b, c FROM test_ts WHERE %c=CAST(? AS DATE)"};
9009   myheader("test_ts");
9010 
9011   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_ts");
9012   myquery(rc);
9013 
9014   rc= mysql_query(mysql, "CREATE TABLE test_ts(a DATE, b TIME, c TIMESTAMP)");
9015   myquery(rc);
9016 
9017   stmt= mysql_simple_prepare(mysql, "INSERT INTO test_ts VALUES(?, ?, ?), (?, ?, ?)");
9018   check_stmt(stmt);
9019 
9020   ts.year= 2003;
9021   ts.month= 07;
9022   ts.day= 12;
9023   ts.hour= 21;
9024   ts.minute= 07;
9025   ts.second= 46;
9026   ts.second_part= 0;
9027   length= (long)(strmov(strts, "2003-07-12 21:07:46") - strts);
9028 
9029   /*
9030     We need to bzero bind structure because mysql_stmt_bind_param checks all
9031     its members.
9032   */
9033   bzero((char*) my_bind, sizeof(my_bind));
9034 
9035   my_bind[0].buffer_type= MYSQL_TYPE_TIMESTAMP;
9036   my_bind[0].buffer= (void *)&ts;
9037   my_bind[0].buffer_length= sizeof(ts);
9038 
9039   my_bind[2]= my_bind[1]= my_bind[0];
9040 
9041   my_bind[3].buffer_type= MYSQL_TYPE_STRING;
9042   my_bind[3].buffer= (void *)strts;
9043   my_bind[3].buffer_length= sizeof(strts);
9044   my_bind[3].length= &length;
9045 
9046   my_bind[5]= my_bind[4]= my_bind[3];
9047 
9048   rc= mysql_stmt_bind_param(stmt, my_bind);
9049   check_execute(stmt, rc);
9050 
9051   rc= mysql_stmt_execute(stmt);
9052   check_execute(stmt, rc);
9053 
9054   mysql_stmt_close(stmt);
9055 
9056   verify_col_data("test_ts", "a", "2003-07-12");
9057   verify_col_data("test_ts", "b", "21:07:46");
9058   verify_col_data("test_ts", "c", "2003-07-12 21:07:46");
9059 
9060   stmt= mysql_simple_prepare(mysql, "SELECT * FROM test_ts");
9061   check_stmt(stmt);
9062 
9063   prep_res= mysql_stmt_result_metadata(stmt);
9064   mytest(prep_res);
9065 
9066   rc= mysql_stmt_execute(stmt);
9067   check_execute(stmt, rc);
9068 
9069   rc= my_process_stmt_result(stmt);
9070   DIE_UNLESS(rc == 2);
9071   field_count= mysql_num_fields(prep_res);
9072 
9073   mysql_free_result(prep_res);
9074   mysql_stmt_close(stmt);
9075 
9076   for (name= 'a'; field_count--; name++)
9077   {
9078     int row_count= 0;
9079 
9080     sprintf(query, queries[field_count], name);
9081 
9082     if (!opt_silent)
9083       fprintf(stdout, "\n  %s", query);
9084     stmt= mysql_simple_prepare(mysql, query);
9085     check_stmt(stmt);
9086 
9087     rc= mysql_stmt_bind_param(stmt, my_bind);
9088     check_execute(stmt, rc);
9089 
9090     rc= mysql_stmt_execute(stmt);
9091     check_execute(stmt, rc);
9092 
9093     while (mysql_stmt_fetch(stmt) == 0)
9094       row_count++;
9095 
9096     if (!opt_silent)
9097       fprintf(stdout, "\n   returned '%d' rows", row_count);
9098     DIE_UNLESS(row_count == 2);
9099     mysql_stmt_close(stmt);
9100   }
9101 }
9102 
9103 
9104 /* Test for bug #1500. */
9105 
test_bug1500()9106 static void test_bug1500()
9107 {
9108   MYSQL_STMT *stmt;
9109   MYSQL_BIND my_bind[3];
9110   int        rc;
9111   int32 int_data[3]= {2, 3, 4};
9112   const char *data;
9113 
9114   myheader("test_bug1500");
9115 
9116   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bg1500");
9117   myquery(rc);
9118 
9119   rc= mysql_query(mysql, "CREATE TABLE test_bg1500 (i INT)");
9120   myquery(rc);
9121 
9122   rc= mysql_query(mysql, "INSERT INTO test_bg1500 VALUES (1), (2)");
9123   myquery(rc);
9124 
9125   rc= mysql_commit(mysql);
9126   myquery(rc);
9127 
9128   stmt= mysql_simple_prepare(mysql, "SELECT i FROM test_bg1500 WHERE i IN (?, ?, ?)");
9129   check_stmt(stmt);
9130   verify_param_count(stmt, 3);
9131 
9132   /*
9133     We need to bzero bind structure because mysql_stmt_bind_param checks all
9134     its members.
9135   */
9136   bzero((char*) my_bind, sizeof(my_bind));
9137 
9138   my_bind[0].buffer= (void *)int_data;
9139   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
9140   my_bind[2]= my_bind[1]= my_bind[0];
9141   my_bind[1].buffer= (void *)(int_data + 1);
9142   my_bind[2].buffer= (void *)(int_data + 2);
9143 
9144   rc= mysql_stmt_bind_param(stmt, my_bind);
9145   check_execute(stmt, rc);
9146 
9147   rc= mysql_stmt_execute(stmt);
9148   check_execute(stmt, rc);
9149 
9150   rc= my_process_stmt_result(stmt);
9151   DIE_UNLESS(rc == 1);
9152 
9153   mysql_stmt_close(stmt);
9154 
9155   rc= mysql_query(mysql, "DROP TABLE test_bg1500");
9156   myquery(rc);
9157 
9158   rc= mysql_query(mysql, "CREATE TABLE test_bg1500 (s VARCHAR(25), FULLTEXT(s)) engine=MyISAM");
9159   myquery(rc);
9160 
9161   rc= mysql_query(mysql,
9162         "INSERT INTO test_bg1500 VALUES ('Gravedigger'), ('Greed'), ('Hollow Dogs')");
9163   myquery(rc);
9164 
9165   rc= mysql_commit(mysql);
9166   myquery(rc);
9167 
9168   stmt= mysql_simple_prepare(mysql,
9169           "SELECT s FROM test_bg1500 WHERE MATCH (s) AGAINST (?)");
9170   check_stmt(stmt);
9171 
9172   verify_param_count(stmt, 1);
9173 
9174   data= "Dogs";
9175   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
9176   my_bind[0].buffer= (void *) data;
9177   my_bind[0].buffer_length= strlen(data);
9178   my_bind[0].is_null= 0;
9179   my_bind[0].length= 0;
9180 
9181   rc= mysql_stmt_bind_param(stmt, my_bind);
9182   check_execute(stmt, rc);
9183 
9184   rc= mysql_stmt_execute(stmt);
9185   check_execute(stmt, rc);
9186 
9187   rc= my_process_stmt_result(stmt);
9188   DIE_UNLESS(rc == 1);
9189 
9190   mysql_stmt_close(stmt);
9191 
9192   /* This should work too */
9193   stmt= mysql_simple_prepare(mysql,
9194           "SELECT s FROM test_bg1500 WHERE MATCH (s) AGAINST (CONCAT(?, 'digger'))");
9195   check_stmt(stmt);
9196 
9197   verify_param_count(stmt, 1);
9198 
9199   data= "Grave";
9200   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
9201   my_bind[0].buffer= (void *) data;
9202   my_bind[0].buffer_length= strlen(data);
9203 
9204   rc= mysql_stmt_bind_param(stmt, my_bind);
9205   check_execute(stmt, rc);
9206 
9207   rc= mysql_stmt_execute(stmt);
9208   check_execute(stmt, rc);
9209 
9210   rc= my_process_stmt_result(stmt);
9211   DIE_UNLESS(rc == 1);
9212 
9213   mysql_stmt_close(stmt);
9214 }
9215 
9216 
test_bug1946()9217 static void test_bug1946()
9218 {
9219   MYSQL_STMT *stmt;
9220   int rc;
9221   const char *query= "INSERT INTO prepare_command VALUES (?)";
9222 
9223   myheader("test_bug1946");
9224 
9225   rc= mysql_query(mysql, "DROP TABLE IF EXISTS prepare_command");
9226   myquery(rc);
9227 
9228   rc= mysql_query(mysql, "CREATE TABLE prepare_command(ID INT)");
9229   myquery(rc);
9230 
9231   stmt= mysql_simple_prepare(mysql, query);
9232   check_stmt(stmt);
9233   rc= mysql_real_query(mysql, query, strlen(query));
9234   DIE_UNLESS(rc != 0);
9235   if (!opt_silent)
9236     fprintf(stdout, "Got error (as expected):\n");
9237   myerror(NULL);
9238 
9239   mysql_stmt_close(stmt);
9240   rc= mysql_query(mysql, "DROP TABLE prepare_command");
9241 }
9242 
9243 
test_parse_error_and_bad_length()9244 static void test_parse_error_and_bad_length()
9245 {
9246   MYSQL_STMT *stmt;
9247   int rc;
9248 
9249   /* check that we get 4 syntax errors over the 4 calls */
9250   myheader("test_parse_error_and_bad_length");
9251 
9252   rc= mysql_query(mysql, "SHOW DATABAAAA");
9253   DIE_UNLESS(rc);
9254   if (!opt_silent)
9255     fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
9256   rc= mysql_real_query(mysql, STRING_WITH_LEN("SHOW DATABASES\0AAAAAAAA"));
9257   DIE_UNLESS(rc);
9258   if (!opt_silent)
9259     fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
9260 
9261   stmt= mysql_simple_prepare(mysql, "SHOW DATABAAAA");
9262   DIE_UNLESS(!stmt);
9263   if (!opt_silent)
9264     fprintf(stdout, "Got error (as expected): '%s'\n", mysql_error(mysql));
9265   stmt= mysql_stmt_init(mysql);
9266   DIE_UNLESS(stmt);
9267   rc= mysql_stmt_prepare(stmt, STRING_WITH_LEN("SHOW DATABASES\0AAAAAAA"));
9268   DIE_UNLESS(rc != 0);
9269   if (!opt_silent)
9270     fprintf(stdout, "Got error (as expected): '%s'\n", mysql_stmt_error(stmt));
9271   mysql_stmt_close(stmt);
9272 }
9273 
9274 
test_bug2247()9275 static void test_bug2247()
9276 {
9277   MYSQL_STMT *stmt;
9278   MYSQL_RES *res;
9279   int rc;
9280   int i;
9281   const char *create= "CREATE TABLE bug2247(id INT UNIQUE AUTO_INCREMENT)";
9282   const char *insert= "INSERT INTO bug2247 VALUES (NULL)";
9283   const char *SELECT= "SELECT id FROM bug2247";
9284   const char *update= "UPDATE bug2247 SET id=id+10";
9285   const char *drop= "DROP TABLE IF EXISTS bug2247";
9286   ulonglong exp_count;
9287   enum { NUM_ROWS= 5 };
9288 
9289   myheader("test_bug2247");
9290 
9291   if (!opt_silent)
9292     fprintf(stdout, "\nChecking if stmt_affected_rows is not affected by\n"
9293                   "mysql_query ... ");
9294   /* create table and insert few rows */
9295   rc= mysql_query(mysql, drop);
9296   myquery(rc);
9297 
9298   rc= mysql_query(mysql, create);
9299   myquery(rc);
9300 
9301   stmt= mysql_simple_prepare(mysql, insert);
9302   check_stmt(stmt);
9303   for (i= 0; i < NUM_ROWS; ++i)
9304   {
9305     rc= mysql_stmt_execute(stmt);
9306     check_execute(stmt, rc);
9307   }
9308   exp_count= mysql_stmt_affected_rows(stmt);
9309   DIE_UNLESS(exp_count == 1);
9310 
9311   rc= mysql_query(mysql, SELECT);
9312   myquery(rc);
9313   /*
9314     mysql_store_result overwrites mysql->affected_rows. Check that
9315     mysql_stmt_affected_rows() returns the same value, whereas
9316     mysql_affected_rows() value is correct.
9317   */
9318   res= mysql_store_result(mysql);
9319   mytest(res);
9320 
9321   DIE_UNLESS(mysql_affected_rows(mysql) == NUM_ROWS);
9322   DIE_UNLESS(exp_count == mysql_stmt_affected_rows(stmt));
9323 
9324   rc= mysql_query(mysql, update);
9325   myquery(rc);
9326   DIE_UNLESS(mysql_affected_rows(mysql) == NUM_ROWS);
9327   DIE_UNLESS(exp_count == mysql_stmt_affected_rows(stmt));
9328 
9329   mysql_free_result(res);
9330   mysql_stmt_close(stmt);
9331 
9332   /* check that mysql_stmt_store_result modifies mysql_stmt_affected_rows */
9333   stmt= mysql_simple_prepare(mysql, SELECT);
9334   check_stmt(stmt);
9335 
9336   rc= mysql_stmt_execute(stmt);
9337   check_execute(stmt, rc);
9338   rc= mysql_stmt_store_result(stmt);
9339   check_execute(stmt, rc);
9340   exp_count= mysql_stmt_affected_rows(stmt);
9341   DIE_UNLESS(exp_count == NUM_ROWS);
9342 
9343   rc= mysql_query(mysql, insert);
9344   myquery(rc);
9345   DIE_UNLESS(mysql_affected_rows(mysql) == 1);
9346   DIE_UNLESS(mysql_stmt_affected_rows(stmt) == exp_count);
9347 
9348   mysql_stmt_close(stmt);
9349   if (!opt_silent)
9350     fprintf(stdout, "OK");
9351 }
9352 
9353 
test_subqueries()9354 static void test_subqueries()
9355 {
9356   MYSQL_STMT *stmt;
9357   int rc, i;
9358   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";
9359 
9360   myheader("test_subqueries");
9361 
9362   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9363   myquery(rc);
9364 
9365   rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);");
9366   myquery(rc);
9367 
9368   rc= mysql_query(mysql,
9369                   "insert into t1 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);");
9370   myquery(rc);
9371 
9372   rc= mysql_query(mysql, "create table t2 select * from t1;");
9373   myquery(rc);
9374 
9375   stmt= mysql_simple_prepare(mysql, query);
9376   check_stmt(stmt);
9377   for (i= 0; i < 3; i++)
9378   {
9379     rc= mysql_stmt_execute(stmt);
9380     check_execute(stmt, rc);
9381     rc= my_process_stmt_result(stmt);
9382     DIE_UNLESS(rc == 5);
9383   }
9384   mysql_stmt_close(stmt);
9385 
9386   rc= mysql_query(mysql, "DROP TABLE t1, t2");
9387   myquery(rc);
9388 }
9389 
9390 
test_bad_union()9391 static void test_bad_union()
9392 {
9393   MYSQL_STMT *stmt;
9394   const char *query= "SELECT 1, 2 union SELECT 1";
9395 
9396   myheader("test_bad_union");
9397 
9398   stmt= mysql_simple_prepare(mysql, query);
9399   DIE_UNLESS(stmt == 0);
9400   myerror(NULL);
9401 }
9402 
9403 
test_distinct()9404 static void test_distinct()
9405 {
9406   MYSQL_STMT *stmt;
9407   int rc, i;
9408   const char *query=
9409     "SELECT 2+count(distinct b), group_concat(a) FROM t1 group by a";
9410 
9411   myheader("test_distinct");
9412 
9413   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9414   myquery(rc);
9415 
9416   rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);");
9417   myquery(rc);
9418 
9419   rc= mysql_query(mysql,
9420                   "insert into t1 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), \
9421 (1, 10), (2, 20), (3, 30), (4, 40), (5, 50);");
9422   myquery(rc);
9423 
9424   for (i= 0; i < 3; i++)
9425   {
9426     stmt= mysql_simple_prepare(mysql, query);
9427     check_stmt(stmt);
9428     rc= mysql_stmt_execute(stmt);
9429     check_execute(stmt, rc);
9430     rc= my_process_stmt_result(stmt);
9431     DIE_UNLESS(rc == 5);
9432     mysql_stmt_close(stmt);
9433   }
9434 
9435   rc= mysql_query(mysql, "DROP TABLE t1");
9436   myquery(rc);
9437 }
9438 
9439 
9440 /*
9441   Test for bug#2248 "mysql_fetch without prior mysql_stmt_execute hangs"
9442 */
9443 
test_bug2248()9444 static void test_bug2248()
9445 {
9446   MYSQL_STMT *stmt;
9447   int rc;
9448   const char *query1= "SELECT DATABASE()";
9449   const char *query2= "INSERT INTO test_bug2248 VALUES (10)";
9450 
9451   myheader("test_bug2248");
9452 
9453   rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_bug2248");
9454   myquery(rc);
9455 
9456   rc= mysql_query(mysql, "CREATE TABLE test_bug2248 (id int)");
9457   myquery(rc);
9458 
9459   stmt= mysql_simple_prepare(mysql, query1);
9460   check_stmt(stmt);
9461 
9462   /* This should not hang */
9463   rc= mysql_stmt_fetch(stmt);
9464   check_execute_r(stmt, rc);
9465 
9466   /* And this too */
9467   rc= mysql_stmt_store_result(stmt);
9468   check_execute_r(stmt, rc);
9469 
9470   mysql_stmt_close(stmt);
9471 
9472   stmt= mysql_simple_prepare(mysql, query2);
9473   check_stmt(stmt);
9474 
9475   rc= mysql_stmt_execute(stmt);
9476   check_execute(stmt, rc);
9477 
9478   /* This too should not hang but should return proper error */
9479   rc= mysql_stmt_fetch(stmt);
9480   DIE_UNLESS(rc == 1);
9481 
9482   /* This too should not hang but should not bark */
9483   rc= mysql_stmt_store_result(stmt);
9484   check_execute(stmt, rc);
9485 
9486   /* This should return proper error */
9487   rc= mysql_stmt_fetch(stmt);
9488   check_execute_r(stmt, rc);
9489   DIE_UNLESS(rc == 1);
9490 
9491   mysql_stmt_close(stmt);
9492 
9493   rc= mysql_query(mysql, "DROP TABLE test_bug2248");
9494   myquery(rc);
9495 }
9496 
9497 
test_subqueries_ref()9498 static void test_subqueries_ref()
9499 {
9500   MYSQL_STMT *stmt;
9501   int rc, i;
9502   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)";
9503 
9504   myheader("test_subqueries_ref");
9505 
9506   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9507   myquery(rc);
9508 
9509   rc= mysql_query(mysql, "CREATE TABLE t1 (a int);");
9510   myquery(rc);
9511 
9512   rc= mysql_query(mysql,
9513                   "insert into t1 values (1), (2), (3), (4), (5);");
9514   myquery(rc);
9515 
9516   stmt= mysql_simple_prepare(mysql, query);
9517   check_stmt(stmt);
9518   for (i= 0; i < 3; i++)
9519   {
9520     rc= mysql_stmt_execute(stmt);
9521     check_execute(stmt, rc);
9522     rc= my_process_stmt_result(stmt);
9523     DIE_UNLESS(rc == 1);
9524   }
9525   mysql_stmt_close(stmt);
9526 
9527   rc= mysql_query(mysql, "DROP TABLE t1");
9528   myquery(rc);
9529 }
9530 
9531 
test_union()9532 static void test_union()
9533 {
9534   MYSQL_STMT *stmt;
9535   int rc;
9536 
9537   myheader("test_union");
9538 
9539   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9540   myquery(rc);
9541 
9542   rc= mysql_query(mysql,
9543                   "CREATE TABLE t1 "
9544                   "(id INTEGER NOT NULL PRIMARY KEY, "
9545                   " name VARCHAR(20) NOT NULL)");
9546   myquery(rc);
9547   rc= mysql_query(mysql,
9548                   "INSERT INTO t1 (id, name) VALUES "
9549                   "(2, 'Ja'), (3, 'Ede'), "
9550                   "(4, 'Haag'), (5, 'Kabul'), "
9551                   "(6, 'Almere'), (7, 'Utrecht'), "
9552                   "(8, 'Qandahar'), (9, 'Amsterdam'), "
9553                   "(10, 'Amersfoort'), (11, 'Constantine')");
9554   myquery(rc);
9555   rc= mysql_query(mysql,
9556                   "CREATE TABLE t2 "
9557                   "(id INTEGER NOT NULL PRIMARY KEY, "
9558                   " name VARCHAR(20) NOT NULL)");
9559   myquery(rc);
9560   rc= mysql_query(mysql,
9561                   "INSERT INTO t2 (id, name) VALUES "
9562                   "(4, 'Guam'), (5, 'Aruba'), "
9563                   "(6, 'Angola'), (7, 'Albania'), "
9564                   "(8, 'Anguilla'), (9, 'Argentina'), "
9565                   "(10, 'Azerbaijan'), (11, 'Afghanistan'), "
9566                   "(12, 'Burkina Faso'), (13, 'Faroe Islands')");
9567   myquery(rc);
9568 
9569   stmt= mysql_simple_prepare(mysql,
9570                              "SELECT t1.name FROM t1 UNION "
9571                              "SELECT t2.name FROM t2");
9572   check_stmt(stmt);
9573 
9574   rc= mysql_stmt_execute(stmt);
9575   check_execute(stmt, rc);
9576   rc= my_process_stmt_result(stmt);
9577   DIE_UNLESS(rc == 20);
9578   mysql_stmt_close(stmt);
9579 
9580   rc= mysql_query(mysql, "DROP TABLE t1, t2");
9581   myquery(rc);
9582 }
9583 
9584 
test_bug3117()9585 static void test_bug3117()
9586 {
9587   MYSQL_STMT *stmt;
9588   MYSQL_BIND buffer;
9589   longlong lii;
9590   ulong length;
9591   my_bool is_null;
9592   int rc;
9593 
9594   myheader("test_bug3117");
9595 
9596   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9597   myquery(rc);
9598 
9599   rc= mysql_query(mysql, "CREATE TABLE t1 (id int auto_increment primary key)");
9600   myquery(rc);
9601 
9602   stmt= mysql_simple_prepare(mysql, "SELECT LAST_INSERT_ID()");
9603   check_stmt(stmt);
9604 
9605   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (NULL)");
9606   myquery(rc);
9607 
9608   rc= mysql_stmt_execute(stmt);
9609   check_execute(stmt, rc);
9610 
9611   bzero((char*) &buffer, sizeof(buffer));
9612   buffer.buffer_type= MYSQL_TYPE_LONGLONG;
9613   buffer.buffer_length= sizeof(lii);
9614   buffer.buffer= (void *)&lii;
9615   buffer.length= &length;
9616   buffer.is_null= &is_null;
9617 
9618   rc= mysql_stmt_bind_result(stmt, &buffer);
9619   check_execute(stmt, rc);
9620 
9621   rc= mysql_stmt_store_result(stmt);
9622   check_execute(stmt, rc);
9623 
9624   rc= mysql_stmt_fetch(stmt);
9625   check_execute(stmt, rc);
9626 
9627   DIE_UNLESS(is_null == 0 && lii == 1);
9628   if (!opt_silent)
9629     fprintf(stdout, "\n\tLAST_INSERT_ID()= 1 ok\n");
9630 
9631   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (NULL)");
9632   myquery(rc);
9633 
9634   rc= mysql_stmt_execute(stmt);
9635   check_execute(stmt, rc);
9636 
9637   rc= mysql_stmt_fetch(stmt);
9638   check_execute(stmt, rc);
9639 
9640   DIE_UNLESS(is_null == 0 && lii == 2);
9641   if (!opt_silent)
9642     fprintf(stdout, "\tLAST_INSERT_ID()= 2 ok\n");
9643 
9644   mysql_stmt_close(stmt);
9645 
9646   rc= mysql_query(mysql, "DROP TABLE t1");
9647   myquery(rc);
9648 }
9649 
9650 
test_join()9651 static void test_join()
9652 {
9653   MYSQL_STMT *stmt;
9654   int rc, i, j;
9655   const char *query[]= {"SELECT * FROM t2 join t1 on (t1.a=t2.a)",
9656                         "SELECT * FROM t2 natural join t1",
9657                         "SELECT * FROM t2 join t1 using(a)",
9658                         "SELECT * FROM t2 left join t1 on(t1.a=t2.a)",
9659                         "SELECT * FROM t2 natural left join t1",
9660                         "SELECT * FROM t2 left join t1 using(a)",
9661                         "SELECT * FROM t2 right join t1 on(t1.a=t2.a)",
9662                         "SELECT * FROM t2 natural right join t1",
9663                         "SELECT * FROM t2 right join t1 using(a)"};
9664 
9665   myheader("test_join");
9666 
9667   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9668   myquery(rc);
9669 
9670   rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);");
9671   myquery(rc);
9672 
9673   rc= mysql_query(mysql,
9674                   "insert into t1 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);");
9675   myquery(rc);
9676 
9677   rc= mysql_query(mysql, "CREATE TABLE t2 (a int , c int);");
9678   myquery(rc);
9679 
9680   rc= mysql_query(mysql,
9681                   "insert into t2 values (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);");
9682   myquery(rc);
9683 
9684   for (j= 0; j < 9; j++)
9685   {
9686     stmt= mysql_simple_prepare(mysql, query[j]);
9687     check_stmt(stmt);
9688     for (i= 0; i < 3; i++)
9689     {
9690       rc= mysql_stmt_execute(stmt);
9691       check_execute(stmt, rc);
9692       rc= my_process_stmt_result(stmt);
9693       DIE_UNLESS(rc == 5);
9694     }
9695     mysql_stmt_close(stmt);
9696   }
9697 
9698   rc= mysql_query(mysql, "DROP TABLE t1, t2");
9699   myquery(rc);
9700 }
9701 
9702 
test_selecttmp()9703 static void test_selecttmp()
9704 {
9705   MYSQL_STMT *stmt;
9706   int rc, i;
9707   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";
9708 
9709   myheader("test_select_tmp");
9710 
9711   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2, t3");
9712   myquery(rc);
9713 
9714   rc= mysql_query(mysql, "CREATE TABLE t1 (a int , b int);");
9715   myquery(rc);
9716 
9717   rc= mysql_query(mysql, "create table t2 (a int, b int);");
9718   myquery(rc);
9719 
9720   rc= mysql_query(mysql, "create table t3 (a int, b int);");
9721   myquery(rc);
9722 
9723   rc= mysql_query(mysql,
9724                   "insert into t1 values (0, 100), (1, 2), (1, 3), (2, 2), (2, 7), \
9725 (2, -1), (3, 10);");
9726   myquery(rc);
9727   rc= mysql_query(mysql,
9728                   "insert into t2 values (0, 0), (1, 1), (2, 1), (3, 1), (4, 1);");
9729   myquery(rc);
9730   rc= mysql_query(mysql,
9731                   "insert into t3 values (3, 3), (2, 2), (1, 1);");
9732   myquery(rc);
9733 
9734   stmt= mysql_simple_prepare(mysql, query);
9735   check_stmt(stmt);
9736   for (i= 0; i < 3; i++)
9737   {
9738     rc= mysql_stmt_execute(stmt);
9739     check_execute(stmt, rc);
9740     rc= my_process_stmt_result(stmt);
9741     DIE_UNLESS(rc == 3);
9742   }
9743   mysql_stmt_close(stmt);
9744 
9745   rc= mysql_query(mysql, "DROP TABLE t1, t2, t3");
9746   myquery(rc);
9747 }
9748 
9749 
test_create_drop()9750 static void test_create_drop()
9751 {
9752   MYSQL_STMT *stmt_create, *stmt_drop, *stmt_select, *stmt_create_select;
9753   char *query;
9754   int rc, i;
9755   myheader("test_table_manipulation");
9756 
9757   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9758   myquery(rc);
9759 
9760   rc= mysql_query(mysql, "create table t2 (a int);");
9761   myquery(rc);
9762 
9763   rc= mysql_query(mysql, "create table t1 (a int);");
9764   myquery(rc);
9765 
9766   rc= mysql_query(mysql, "insert into t2 values (3), (2), (1);");
9767   myquery(rc);
9768 
9769   query= (char*)"create table t1 (a int)";
9770   stmt_create= mysql_simple_prepare(mysql, query);
9771   check_stmt(stmt_create);
9772 
9773   query= (char*)"drop table t1";
9774   stmt_drop= mysql_simple_prepare(mysql, query);
9775   check_stmt(stmt_drop);
9776 
9777   query= (char*)"select a in (select a from t2) from t1";
9778   stmt_select= mysql_simple_prepare(mysql, query);
9779   check_stmt(stmt_select);
9780 
9781   rc= mysql_query(mysql, "DROP TABLE t1");
9782   myquery(rc);
9783 
9784   query= (char*)"create table t1 select a from t2";
9785   stmt_create_select= mysql_simple_prepare(mysql, query);
9786   check_stmt(stmt_create_select);
9787 
9788   for (i= 0; i < 3; i++)
9789   {
9790     rc= mysql_stmt_execute(stmt_create);
9791     check_execute(stmt_create, rc);
9792     if (!opt_silent)
9793       fprintf(stdout, "created %i\n", i);
9794 
9795     rc= mysql_stmt_execute(stmt_select);
9796     check_execute(stmt_select, rc);
9797     rc= my_process_stmt_result(stmt_select);
9798     DIE_UNLESS(rc == 0);
9799 
9800     rc= mysql_stmt_execute(stmt_drop);
9801     check_execute(stmt_drop, rc);
9802     if (!opt_silent)
9803       fprintf(stdout, "dropped %i\n", i);
9804 
9805     rc= mysql_stmt_execute(stmt_create_select);
9806     check_execute(stmt_create, rc);
9807     if (!opt_silent)
9808       fprintf(stdout, "created select %i\n", i);
9809 
9810     rc= mysql_stmt_execute(stmt_select);
9811     check_execute(stmt_select, rc);
9812     rc= my_process_stmt_result(stmt_select);
9813     DIE_UNLESS(rc == 3);
9814 
9815     rc= mysql_stmt_execute(stmt_drop);
9816     check_execute(stmt_drop, rc);
9817     if (!opt_silent)
9818       fprintf(stdout, "dropped %i\n", i);
9819   }
9820 
9821   mysql_stmt_close(stmt_create);
9822   mysql_stmt_close(stmt_drop);
9823   mysql_stmt_close(stmt_select);
9824   mysql_stmt_close(stmt_create_select);
9825 
9826   rc= mysql_query(mysql, "DROP TABLE t2");
9827   myquery(rc);
9828 }
9829 
9830 
test_rename()9831 static void test_rename()
9832 {
9833   MYSQL_STMT *stmt;
9834   const char *query= "rename table t1 to t2, t3 to t4";
9835   int rc;
9836   myheader("test_table_rename");
9837 
9838   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2, t3, t4");
9839   myquery(rc);
9840 
9841   stmt= mysql_simple_prepare(mysql, query);
9842   check_stmt(stmt);
9843 
9844   rc= mysql_query(mysql, "create table t1 (a int)");
9845   myquery(rc);
9846 
9847   rc= mysql_stmt_execute(stmt);
9848   check_execute_r(stmt, rc);
9849   if (!opt_silent)
9850     fprintf(stdout, "rename without t3\n");
9851 
9852   rc= mysql_query(mysql, "create table t3 (a int)");
9853   myquery(rc);
9854 
9855   rc= mysql_stmt_execute(stmt);
9856   check_execute(stmt, rc);
9857   if (!opt_silent)
9858     fprintf(stdout, "rename with t3\n");
9859 
9860   rc= mysql_stmt_execute(stmt);
9861   check_execute_r(stmt, rc);
9862   if (!opt_silent)
9863     fprintf(stdout, "rename renamed\n");
9864 
9865   rc= mysql_query(mysql, "rename table t2 to t1, t4 to t3");
9866   myquery(rc);
9867 
9868   rc= mysql_stmt_execute(stmt);
9869   check_execute(stmt, rc);
9870   if (!opt_silent)
9871     fprintf(stdout, "rename reverted\n");
9872 
9873   mysql_stmt_close(stmt);
9874 
9875   rc= mysql_query(mysql, "DROP TABLE t2, t4");
9876   myquery(rc);
9877 }
9878 
9879 
test_do_set()9880 static void test_do_set()
9881 {
9882   MYSQL_STMT *stmt_do, *stmt_set;
9883   char *query;
9884   int rc, i;
9885   myheader("test_do_set");
9886 
9887   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
9888   myquery(rc);
9889 
9890   rc= mysql_query(mysql, "create table t1 (a int)");
9891   myquery(rc);
9892 
9893   query= (char*)"do @var:=(1 in (select * from t1))";
9894   stmt_do= mysql_simple_prepare(mysql, query);
9895   check_stmt(stmt_do);
9896 
9897   query= (char*)"set @var=(1 in (select * from t1))";
9898   stmt_set= mysql_simple_prepare(mysql, query);
9899   check_stmt(stmt_set);
9900 
9901   for (i= 0; i < 3; i++)
9902   {
9903     rc= mysql_stmt_execute(stmt_do);
9904     check_execute(stmt_do, rc);
9905     if (!opt_silent)
9906       fprintf(stdout, "do %i\n", i);
9907     rc= mysql_stmt_execute(stmt_set);
9908     check_execute(stmt_set, rc);
9909     if (!opt_silent)
9910       fprintf(stdout, "set %i\n", i);
9911   }
9912 
9913   mysql_stmt_close(stmt_do);
9914   mysql_stmt_close(stmt_set);
9915 }
9916 
9917 
test_multi()9918 static void test_multi()
9919 {
9920   MYSQL_STMT *stmt_delete, *stmt_update, *stmt_select1, *stmt_select2;
9921   char *query;
9922   MYSQL_BIND my_bind[1];
9923   int rc, i;
9924   int32 param= 1;
9925   ulong length= 1;
9926   myheader("test_multi");
9927 
9928   /*
9929     We need to bzero bind structure because mysql_stmt_bind_param checks all
9930     its members.
9931   */
9932   bzero((char*) my_bind, sizeof(my_bind));
9933 
9934   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
9935   my_bind[0].buffer= (void *)&param;
9936   my_bind[0].length= &length;
9937 
9938   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
9939   myquery(rc);
9940 
9941   rc= mysql_query(mysql, "create table t1 (a int, b int)");
9942   myquery(rc);
9943 
9944   rc= mysql_query(mysql, "create table t2 (a int, b int)");
9945   myquery(rc);
9946 
9947   rc= mysql_query(mysql, "insert into t1 values (3, 3), (2, 2), (1, 1)");
9948   myquery(rc);
9949 
9950   rc= mysql_query(mysql, "insert into t2 values (3, 3), (2, 2), (1, 1)");
9951   myquery(rc);
9952 
9953   query= (char*)"delete t1, t2 from t1, t2 where t1.a=t2.a and t1.b=10";
9954   stmt_delete= mysql_simple_prepare(mysql, query);
9955   check_stmt(stmt_delete);
9956 
9957   query= (char*)"update t1, t2 set t1.b=10, t2.b=10 where t1.a=t2.a and t1.b=?";
9958   stmt_update= mysql_simple_prepare(mysql, query);
9959   check_stmt(stmt_update);
9960 
9961   query= (char*)"select * from t1";
9962   stmt_select1= mysql_simple_prepare(mysql, query);
9963   check_stmt(stmt_select1);
9964 
9965   query= (char*)"select * from t2";
9966   stmt_select2= mysql_simple_prepare(mysql, query);
9967   check_stmt(stmt_select2);
9968 
9969   for(i= 0; i < 3; i++)
9970   {
9971     rc= mysql_stmt_bind_param(stmt_update, my_bind);
9972     check_execute(stmt_update, rc);
9973 
9974     rc= mysql_stmt_execute(stmt_update);
9975     check_execute(stmt_update, rc);
9976     if (!opt_silent)
9977       fprintf(stdout, "update %ld\n", (long) param);
9978 
9979     rc= mysql_stmt_execute(stmt_delete);
9980     check_execute(stmt_delete, rc);
9981     if (!opt_silent)
9982       fprintf(stdout, "delete %ld\n", (long) param);
9983 
9984     rc= mysql_stmt_execute(stmt_select1);
9985     check_execute(stmt_select1, rc);
9986     rc= my_process_stmt_result(stmt_select1);
9987     DIE_UNLESS(rc == 3-param);
9988 
9989     rc= mysql_stmt_execute(stmt_select2);
9990     check_execute(stmt_select2, rc);
9991     rc= my_process_stmt_result(stmt_select2);
9992     DIE_UNLESS(rc == 3-param);
9993 
9994     param++;
9995   }
9996 
9997   mysql_stmt_close(stmt_delete);
9998   mysql_stmt_close(stmt_update);
9999   mysql_stmt_close(stmt_select1);
10000   mysql_stmt_close(stmt_select2);
10001   rc= mysql_query(mysql, "drop table t1, t2");
10002   myquery(rc);
10003 }
10004 
10005 
test_insert_select()10006 static void test_insert_select()
10007 {
10008   MYSQL_STMT *stmt_insert, *stmt_select;
10009   char *query;
10010   int rc;
10011   uint i;
10012   myheader("test_insert_select");
10013 
10014   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2");
10015   myquery(rc);
10016 
10017   rc= mysql_query(mysql, "create table t1 (a int)");
10018   myquery(rc);
10019 
10020   rc= mysql_query(mysql, "create table t2 (a int)");
10021   myquery(rc);
10022 
10023   rc= mysql_query(mysql, "insert into t2 values (1)");
10024   myquery(rc);
10025 
10026   query= (char*)"insert into t1 select a from t2";
10027   stmt_insert= mysql_simple_prepare(mysql, query);
10028   check_stmt(stmt_insert);
10029 
10030   query= (char*)"select * from t1";
10031   stmt_select= mysql_simple_prepare(mysql, query);
10032   check_stmt(stmt_select);
10033 
10034   for(i= 0; i < 3; i++)
10035   {
10036     rc= mysql_stmt_execute(stmt_insert);
10037     check_execute(stmt_insert, rc);
10038     if (!opt_silent)
10039       fprintf(stdout, "insert %u\n", i);
10040 
10041     rc= mysql_stmt_execute(stmt_select);
10042     check_execute(stmt_select, rc);
10043     rc= my_process_stmt_result(stmt_select);
10044     DIE_UNLESS(rc == (int)(i+1));
10045   }
10046 
10047   mysql_stmt_close(stmt_insert);
10048   mysql_stmt_close(stmt_select);
10049   rc= mysql_query(mysql, "drop table t1, t2");
10050   myquery(rc);
10051 }
10052 
10053 
test_bind_nagative()10054 static void test_bind_nagative()
10055 {
10056   MYSQL_STMT *stmt_insert;
10057   char *query;
10058   int rc;
10059   MYSQL_BIND      my_bind[1];
10060   int32           my_val= 0;
10061   ulong           my_length= 0L;
10062   my_bool         my_null= FALSE;
10063   myheader("test_insert_select");
10064 
10065   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
10066   myquery(rc);
10067 
10068   rc= mysql_query(mysql, "create temporary table t1 (c1 int unsigned)");
10069   myquery(rc);
10070 
10071   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1), (-1)");
10072   myquery(rc);
10073 
10074   query= (char*)"INSERT INTO t1 VALUES (?)";
10075   stmt_insert= mysql_simple_prepare(mysql, query);
10076   check_stmt(stmt_insert);
10077 
10078   /* bind parameters */
10079   bzero((char*) my_bind, sizeof(my_bind));
10080 
10081   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
10082   my_bind[0].buffer= (void *)&my_val;
10083   my_bind[0].length= &my_length;
10084   my_bind[0].is_null= (char*)&my_null;
10085 
10086   rc= mysql_stmt_bind_param(stmt_insert, my_bind);
10087   check_execute(stmt_insert, rc);
10088 
10089   my_val= -1;
10090   rc= mysql_stmt_execute(stmt_insert);
10091   check_execute(stmt_insert, rc);
10092 
10093   mysql_stmt_close(stmt_insert);
10094   rc= mysql_query(mysql, "drop table t1");
10095   myquery(rc);
10096 }
10097 
10098 
test_derived()10099 static void test_derived()
10100 {
10101   MYSQL_STMT *stmt;
10102   int rc, i;
10103   MYSQL_BIND      my_bind[1];
10104   int32           my_val= 0;
10105   ulong           my_length= 0L;
10106   my_bool         my_null= FALSE;
10107   const char *query=
10108     "select count(1) from (select f.id from t1 f where f.id=?) as x";
10109 
10110   myheader("test_derived");
10111 
10112   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
10113   myquery(rc);
10114 
10115   rc= mysql_query(mysql, "create table t1 (id  int(8), primary key (id)) \
10116 ENGINE=InnoDB DEFAULT CHARSET=utf8");
10117   myquery(rc);
10118 
10119   rc= mysql_query(mysql, "insert into t1 values (1)");
10120   myquery(rc);
10121 
10122   stmt= mysql_simple_prepare(mysql, query);
10123   check_stmt(stmt);
10124   /*
10125     We need to bzero bind structure because mysql_stmt_bind_param checks all
10126     its members.
10127   */
10128   bzero((char*) my_bind, sizeof(my_bind));
10129 
10130   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
10131   my_bind[0].buffer= (void *)&my_val;
10132   my_bind[0].length= &my_length;
10133   my_bind[0].is_null= (char*)&my_null;
10134   my_val= 1;
10135   rc= mysql_stmt_bind_param(stmt, my_bind);
10136   check_execute(stmt, rc);
10137 
10138   for (i= 0; i < 3; i++)
10139   {
10140     rc= mysql_stmt_execute(stmt);
10141     check_execute(stmt, rc);
10142     rc= my_process_stmt_result(stmt);
10143     DIE_UNLESS(rc == 1);
10144   }
10145   mysql_stmt_close(stmt);
10146 
10147   rc= mysql_query(mysql, "DROP TABLE t1");
10148   myquery(rc);
10149 }
10150 
10151 
test_xjoin()10152 static void test_xjoin()
10153 {
10154   MYSQL_STMT *stmt;
10155   int rc, i;
10156   const char *query=
10157     "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";
10158 
10159   myheader("test_xjoin");
10160 
10161   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, t2, t3, t4");
10162   myquery(rc);
10163 
10164   rc= mysql_query(mysql, "create table t3 (id int(8), param1_id int(8), param2_id int(8)) ENGINE=InnoDB DEFAULT CHARSET=utf8");
10165   myquery(rc);
10166 
10167   rc= mysql_query(mysql, "create table t1 ( id int(8), name_id int(8), value varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8");
10168   myquery(rc);
10169 
10170   rc= mysql_query(mysql, "create table t2 (id int(8), name_id int(8), value varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8;");
10171   myquery(rc);
10172 
10173   rc= mysql_query(mysql, "create table t4(id int(8), value varchar(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8");
10174   myquery(rc);
10175 
10176   rc= mysql_query(mysql, "insert into t3 values (1, 1, 1), (2, 2, null)");
10177   myquery(rc);
10178 
10179   rc= mysql_query(mysql, "insert into t1 values (1, 1, 'aaa'), (2, null, 'bbb')");
10180   myquery(rc);
10181 
10182   rc= mysql_query(mysql, "insert into t2 values (1, 2, 'ccc')");
10183   myquery(rc);
10184 
10185   rc= mysql_query(mysql, "insert into t4 values (1, 'Name1'), (2, null)");
10186   myquery(rc);
10187 
10188   stmt= mysql_simple_prepare(mysql, query);
10189   check_stmt(stmt);
10190 
10191   for (i= 0; i < 3; i++)
10192   {
10193     rc= mysql_stmt_execute(stmt);
10194     check_execute(stmt, rc);
10195     rc= my_process_stmt_result(stmt);
10196     DIE_UNLESS(rc == 1);
10197   }
10198   mysql_stmt_close(stmt);
10199 
10200   rc= mysql_query(mysql, "DROP TABLE t1, t2, t3, t4");
10201   myquery(rc);
10202 }
10203 
10204 
test_bug3035()10205 static void test_bug3035()
10206 {
10207   MYSQL_STMT *stmt;
10208   int rc;
10209   MYSQL_BIND bind_array[12], *my_bind= bind_array, *bind_end= my_bind + 12;
10210   int8 int8_val;
10211   uint8 uint8_val;
10212   int16 int16_val;
10213   uint16 uint16_val;
10214   int32 int32_val;
10215   uint32 uint32_val;
10216   longlong int64_val;
10217   ulonglong uint64_val;
10218   double double_val, udouble_val, double_tmp;
10219   char longlong_as_string[22], ulonglong_as_string[22];
10220 
10221   /* mins and maxes */
10222   const int8 int8_min= -128;
10223   const int8 int8_max= 127;
10224   const uint8 uint8_min= 0;
10225   const uint8 uint8_max= 255;
10226 
10227   const int16 int16_min= -32768;
10228   const int16 int16_max= 32767;
10229   const uint16 uint16_min= 0;
10230   const uint16 uint16_max= 65535;
10231 
10232   const int32 int32_max= 2147483647L;
10233   const int32 int32_min= -int32_max - 1;
10234   const uint32 uint32_min= 0;
10235   const uint32 uint32_max= 4294967295U;
10236 
10237   /* it might not work okay everyplace */
10238   const longlong int64_max= 9223372036854775807LL;
10239   const longlong int64_min= -int64_max - 1;
10240 
10241   const ulonglong uint64_min= 0U;
10242   const ulonglong uint64_max= 18446744073709551615ULL;
10243 
10244   const char *stmt_text;
10245 
10246   myheader("test_bug3035");
10247 
10248   stmt_text= "DROP TABLE IF EXISTS t1";
10249   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10250   myquery(rc);
10251 
10252   stmt_text= "CREATE TABLE t1 (i8 TINYINT, ui8 TINYINT UNSIGNED, "
10253                               "i16 SMALLINT, ui16 SMALLINT UNSIGNED, "
10254                               "i32 INT, ui32 INT UNSIGNED, "
10255                               "i64 BIGINT, ui64 BIGINT UNSIGNED, "
10256                               "id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT)";
10257   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10258   myquery(rc);
10259 
10260   bzero((char*) bind_array, sizeof(bind_array));
10261 
10262   for (my_bind= bind_array; my_bind < bind_end; my_bind++)
10263     my_bind->error= &my_bind->error_value;
10264 
10265   bind_array[0].buffer_type= MYSQL_TYPE_TINY;
10266   bind_array[0].buffer= (void *) &int8_val;
10267 
10268   bind_array[1].buffer_type= MYSQL_TYPE_TINY;
10269   bind_array[1].buffer= (void *) &uint8_val;
10270   bind_array[1].is_unsigned= 1;
10271 
10272   bind_array[2].buffer_type= MYSQL_TYPE_SHORT;
10273   bind_array[2].buffer= (void *) &int16_val;
10274 
10275   bind_array[3].buffer_type= MYSQL_TYPE_SHORT;
10276   bind_array[3].buffer= (void *) &uint16_val;
10277   bind_array[3].is_unsigned= 1;
10278 
10279   bind_array[4].buffer_type= MYSQL_TYPE_LONG;
10280   bind_array[4].buffer= (void *) &int32_val;
10281 
10282   bind_array[5].buffer_type= MYSQL_TYPE_LONG;
10283   bind_array[5].buffer= (void *) &uint32_val;
10284   bind_array[5].is_unsigned= 1;
10285 
10286   bind_array[6].buffer_type= MYSQL_TYPE_LONGLONG;
10287   bind_array[6].buffer= (void *) &int64_val;
10288 
10289   bind_array[7].buffer_type= MYSQL_TYPE_LONGLONG;
10290   bind_array[7].buffer= (void *) &uint64_val;
10291   bind_array[7].is_unsigned= 1;
10292 
10293   stmt= mysql_stmt_init(mysql);
10294   check_stmt(stmt);
10295 
10296   stmt_text= "INSERT INTO t1 (i8, ui8, i16, ui16, i32, ui32, i64, ui64) "
10297                      "VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
10298   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10299   check_execute(stmt, rc);
10300 
10301   mysql_stmt_bind_param(stmt, bind_array);
10302 
10303   int8_val= int8_min;
10304   uint8_val= uint8_min;
10305   int16_val= int16_min;
10306   uint16_val= uint16_min;
10307   int32_val= int32_min;
10308   uint32_val= uint32_min;
10309   int64_val= int64_min;
10310   uint64_val= uint64_min;
10311 
10312   rc= mysql_stmt_execute(stmt);
10313   check_execute(stmt, rc);
10314 
10315   int8_val= int8_max;
10316   uint8_val= uint8_max;
10317   int16_val= int16_max;
10318   uint16_val= uint16_max;
10319   int32_val= int32_max;
10320   uint32_val= uint32_max;
10321   int64_val= int64_max;
10322   uint64_val= uint64_max;
10323 
10324   rc= mysql_stmt_execute(stmt);
10325   check_execute(stmt, rc);
10326 
10327   stmt_text= "SELECT i8, ui8, i16, ui16, i32, ui32, i64, ui64, ui64, "
10328              "cast(ui64 as signed), ui64, cast(ui64 as signed)"
10329              "FROM t1 ORDER BY id ASC";
10330 
10331   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10332   check_execute(stmt, rc);
10333 
10334   rc= mysql_stmt_execute(stmt);
10335   check_execute(stmt, rc);
10336 
10337   bind_array[8].buffer_type= MYSQL_TYPE_DOUBLE;
10338   bind_array[8].buffer= (void *) &udouble_val;
10339 
10340   bind_array[9].buffer_type= MYSQL_TYPE_DOUBLE;
10341   bind_array[9].buffer= (void *) &double_val;
10342 
10343   bind_array[10].buffer_type= MYSQL_TYPE_STRING;
10344   bind_array[10].buffer= (void *) &ulonglong_as_string;
10345   bind_array[10].buffer_length= sizeof(ulonglong_as_string);
10346 
10347   bind_array[11].buffer_type= MYSQL_TYPE_STRING;
10348   bind_array[11].buffer= (void *) &longlong_as_string;
10349   bind_array[11].buffer_length= sizeof(longlong_as_string);
10350 
10351   mysql_stmt_bind_result(stmt, bind_array);
10352 
10353   rc= mysql_stmt_fetch(stmt);
10354   check_execute(stmt, rc);
10355 
10356   DIE_UNLESS(int8_val == int8_min);
10357   DIE_UNLESS(uint8_val == uint8_min);
10358   DIE_UNLESS(int16_val == int16_min);
10359   DIE_UNLESS(uint16_val == uint16_min);
10360   DIE_UNLESS(int32_val == int32_min);
10361   DIE_UNLESS(uint32_val == uint32_min);
10362   DIE_UNLESS(int64_val == int64_min);
10363   DIE_UNLESS(uint64_val == uint64_min);
10364   DIE_UNLESS(double_val == (longlong) uint64_min);
10365   double_tmp= ulonglong2double(uint64_val);
10366   DIE_UNLESS(cmp_double(&udouble_val, &double_tmp));
10367   DIE_UNLESS(!strcmp(longlong_as_string, "0"));
10368   DIE_UNLESS(!strcmp(ulonglong_as_string, "0"));
10369 
10370   rc= mysql_stmt_fetch(stmt);
10371 
10372   if (!opt_silent)
10373   {
10374     printf("Truncation mask: ");
10375     for (my_bind= bind_array; my_bind < bind_end; my_bind++)
10376       printf("%d", (int) my_bind->error_value);
10377     printf("\n");
10378   }
10379   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED || rc == 0);
10380 
10381   DIE_UNLESS(int8_val == int8_max);
10382   DIE_UNLESS(uint8_val == uint8_max);
10383   DIE_UNLESS(int16_val == int16_max);
10384   DIE_UNLESS(uint16_val == uint16_max);
10385   DIE_UNLESS(int32_val == int32_max);
10386   DIE_UNLESS(uint32_val == uint32_max);
10387   DIE_UNLESS(int64_val == int64_max);
10388   DIE_UNLESS(uint64_val == uint64_max);
10389   DIE_UNLESS(double_val == (longlong) uint64_val);
10390   double_tmp= ulonglong2double(uint64_val);
10391   DIE_UNLESS(cmp_double(&udouble_val, &double_tmp));
10392   DIE_UNLESS(!strcmp(longlong_as_string, "-1"));
10393   DIE_UNLESS(!strcmp(ulonglong_as_string, "18446744073709551615"));
10394 
10395   rc= mysql_stmt_fetch(stmt);
10396   DIE_UNLESS(rc == MYSQL_NO_DATA);
10397 
10398   mysql_stmt_close(stmt);
10399 
10400   stmt_text= "DROP TABLE t1";
10401   mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10402 }
10403 
10404 
test_union2()10405 static void test_union2()
10406 {
10407   MYSQL_STMT *stmt;
10408   int rc, i;
10409 
10410   myheader("test_union2");
10411 
10412   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
10413   myquery(rc);
10414 
10415   rc= mysql_query(mysql, "CREATE TABLE t1(col1 INT, \
10416                                          col2 VARCHAR(40),      \
10417                                          col3 SMALLINT, \
10418                                          col4 TIMESTAMP)");
10419   myquery(rc);
10420 
10421   stmt= mysql_simple_prepare(mysql,
10422                              "select col1 FROM t1 where col1=1 union distinct "
10423                              "select col1 FROM t1 where col1=2");
10424   check_stmt(stmt);
10425 
10426   for (i= 0; i < 3; i++)
10427   {
10428     rc= mysql_stmt_execute(stmt);
10429     check_execute(stmt, rc);
10430     rc= my_process_stmt_result(stmt);
10431     DIE_UNLESS(rc == 0);
10432   }
10433 
10434   mysql_stmt_close(stmt);
10435 
10436   rc= mysql_query(mysql, "DROP TABLE t1");
10437   myquery(rc);
10438 }
10439 
10440 
10441 /*
10442   This tests for various mysql_stmt_send_long_data bugs described in #1664
10443 */
10444 
test_bug1664()10445 static void test_bug1664()
10446 {
10447     MYSQL_STMT *stmt;
10448     int        rc, int_data;
10449     const char *data;
10450     const char *str_data= "Simple string";
10451     MYSQL_BIND my_bind[2];
10452     const char *query= "INSERT INTO test_long_data(col2, col1) VALUES(?, ?)";
10453 
10454     myheader("test_bug1664");
10455 
10456     rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_long_data");
10457     myquery(rc);
10458 
10459     rc= mysql_query(mysql, "CREATE TABLE test_long_data(col1 int, col2 long varchar)");
10460     myquery(rc);
10461 
10462     stmt= mysql_stmt_init(mysql);
10463     check_stmt(stmt);
10464     rc= mysql_stmt_prepare(stmt, query, strlen(query));
10465     check_execute(stmt, rc);
10466 
10467     verify_param_count(stmt, 2);
10468 
10469     bzero((char*) my_bind, sizeof(my_bind));
10470 
10471     my_bind[0].buffer_type= MYSQL_TYPE_STRING;
10472     my_bind[0].buffer= (void *)str_data;
10473     my_bind[0].buffer_length= strlen(str_data);
10474 
10475     my_bind[1].buffer= (void *)&int_data;
10476     my_bind[1].buffer_type= MYSQL_TYPE_LONG;
10477 
10478     rc= mysql_stmt_bind_param(stmt, my_bind);
10479     check_execute(stmt, rc);
10480 
10481     int_data= 1;
10482 
10483     /*
10484       Let us supply empty long_data. This should work and should
10485       not break following execution.
10486     */
10487     data= "";
10488     rc= mysql_stmt_send_long_data(stmt, 0, data, strlen(data));
10489     check_execute(stmt, rc);
10490 
10491     rc= mysql_stmt_execute(stmt);
10492     check_execute(stmt, rc);
10493 
10494     verify_col_data("test_long_data", "col1", "1");
10495     verify_col_data("test_long_data", "col2", "");
10496 
10497     rc= mysql_query(mysql, "DELETE FROM test_long_data");
10498     myquery(rc);
10499 
10500     /* This should pass OK */
10501     data= (char *)"Data";
10502     rc= mysql_stmt_send_long_data(stmt, 0, data, strlen(data));
10503     check_execute(stmt, rc);
10504 
10505     rc= mysql_stmt_execute(stmt);
10506     check_execute(stmt, rc);
10507 
10508     verify_col_data("test_long_data", "col1", "1");
10509     verify_col_data("test_long_data", "col2", "Data");
10510 
10511     /* clean up */
10512     rc= mysql_query(mysql, "DELETE FROM test_long_data");
10513     myquery(rc);
10514 
10515     /*
10516       Now we are changing int parameter and don't do anything
10517       with first parameter. Second mysql_stmt_execute() should run
10518       OK treating this first parameter as string parameter.
10519     */
10520 
10521     int_data= 2;
10522     /* execute */
10523     rc= mysql_stmt_execute(stmt);
10524     check_execute(stmt, rc);
10525 
10526     verify_col_data("test_long_data", "col1", "2");
10527     verify_col_data("test_long_data", "col2", str_data);
10528 
10529     /* clean up */
10530     rc= mysql_query(mysql, "DELETE FROM test_long_data");
10531     myquery(rc);
10532 
10533     /*
10534       Now we are sending other long data. It should not be
10535       concatened to previous.
10536     */
10537 
10538     data= (char *)"SomeOtherData";
10539     rc= mysql_stmt_send_long_data(stmt, 0, data, strlen(data));
10540     check_execute(stmt, rc);
10541 
10542     rc= mysql_stmt_execute(stmt);
10543     check_execute(stmt, rc);
10544 
10545     verify_col_data("test_long_data", "col1", "2");
10546     verify_col_data("test_long_data", "col2", "SomeOtherData");
10547 
10548     mysql_stmt_close(stmt);
10549 
10550     /* clean up */
10551     rc= mysql_query(mysql, "DELETE FROM test_long_data");
10552     myquery(rc);
10553 
10554     /* Now let us test how mysql_stmt_reset works. */
10555     stmt= mysql_stmt_init(mysql);
10556     check_stmt(stmt);
10557     rc= mysql_stmt_prepare(stmt, query, strlen(query));
10558     check_execute(stmt, rc);
10559     rc= mysql_stmt_bind_param(stmt, my_bind);
10560     check_execute(stmt, rc);
10561 
10562     data= (char *)"SomeData";
10563     rc= mysql_stmt_send_long_data(stmt, 0, data, strlen(data));
10564     check_execute(stmt, rc);
10565 
10566     rc= mysql_stmt_reset(stmt);
10567     check_execute(stmt, rc);
10568 
10569     rc= mysql_stmt_execute(stmt);
10570     check_execute(stmt, rc);
10571 
10572     verify_col_data("test_long_data", "col1", "2");
10573     verify_col_data("test_long_data", "col2", str_data);
10574 
10575     mysql_stmt_close(stmt);
10576 
10577     /* Final clean up */
10578     rc= mysql_query(mysql, "DROP TABLE test_long_data");
10579     myquery(rc);
10580 }
10581 
10582 
test_order_param()10583 static void test_order_param()
10584 {
10585   MYSQL_STMT *stmt;
10586   int rc;
10587 
10588   myheader("test_order_param");
10589 
10590   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
10591   myquery(rc);
10592 
10593   rc= mysql_query(mysql, "CREATE TABLE t1(a INT, b char(10))");
10594   myquery(rc);
10595 
10596   stmt= mysql_simple_prepare(mysql,
10597                              "select sum(a) + 200, 1 from t1 "
10598                              " union distinct "
10599                              "select sum(a) + 200, 1 from t1 group by b ");
10600   check_stmt(stmt);
10601   mysql_stmt_close(stmt);
10602 
10603   stmt= mysql_simple_prepare(mysql,
10604                              "select sum(a) + 200, ? from t1 group by b "
10605                              " union distinct "
10606                              "select sum(a) + 200, 1 from t1 group by b ");
10607   check_stmt(stmt);
10608   mysql_stmt_close(stmt);
10609 
10610   stmt= mysql_simple_prepare(mysql,
10611                              "select sum(a) + 200, ? from t1 "
10612                              " union distinct "
10613                              "select sum(a) + 200, 1 from t1 group by b ");
10614   check_stmt(stmt);
10615   mysql_stmt_close(stmt);
10616 
10617   rc= mysql_query(mysql, "DROP TABLE t1");
10618   myquery(rc);
10619 }
10620 
10621 
test_union_param()10622 static void test_union_param()
10623 {
10624   MYSQL_STMT *stmt;
10625   char *query;
10626   int rc, i;
10627   MYSQL_BIND      my_bind[2];
10628   char            my_val[4];
10629   ulong           my_length= 3L;
10630   my_bool         my_null= FALSE;
10631   myheader("test_union_param");
10632 
10633   strmov(my_val, "abc");
10634 
10635   query= (char*)"select ? as my_col union distinct select ?";
10636   stmt= mysql_simple_prepare(mysql, query);
10637   check_stmt(stmt);
10638 
10639   /*
10640     We need to bzero bind structure because mysql_stmt_bind_param checks all
10641     its members.
10642   */
10643   bzero((char*) my_bind, sizeof(my_bind));
10644 
10645   /* bind parameters */
10646   my_bind[0].buffer_type=    MYSQL_TYPE_STRING;
10647   my_bind[0].buffer=         (char*) &my_val;
10648   my_bind[0].buffer_length=  4;
10649   my_bind[0].length=         &my_length;
10650   my_bind[0].is_null=        (char*)&my_null;
10651   my_bind[1].buffer_type=    MYSQL_TYPE_STRING;
10652   my_bind[1].buffer=         (char*) &my_val;
10653   my_bind[1].buffer_length=  4;
10654   my_bind[1].length=         &my_length;
10655   my_bind[1].is_null=        (char*)&my_null;
10656 
10657   rc= mysql_stmt_bind_param(stmt, my_bind);
10658   check_execute(stmt, rc);
10659 
10660   for (i= 0; i < 3; i++)
10661   {
10662     rc= mysql_stmt_execute(stmt);
10663     check_execute(stmt, rc);
10664     rc= my_process_stmt_result(stmt);
10665     DIE_UNLESS(rc == 1);
10666   }
10667 
10668   mysql_stmt_close(stmt);
10669 }
10670 
10671 
test_ps_i18n()10672 static void test_ps_i18n()
10673 {
10674   MYSQL_STMT *stmt;
10675   int rc;
10676   const char *stmt_text;
10677   MYSQL_BIND bind_array[2];
10678 
10679   /* Represented as numbers to keep UTF8 tools from clobbering them. */
10680   const char *koi8= "\xee\xd5\x2c\x20\xda\xc1\x20\xd2\xd9\xc2\xc1\xcc\xcb\xd5";
10681   const char *cp1251= "\xcd\xf3\x2c\x20\xe7\xe0\x20\xf0\xfb\xe1\xe0\xeb\xea\xf3";
10682   char buf1[16], buf2[16];
10683   ulong buf1_len, buf2_len;
10684 
10685 
10686   myheader("test_ps_i18n");
10687 
10688   stmt_text= "DROP TABLE IF EXISTS t1";
10689   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10690   myquery(rc);
10691 
10692   /*
10693     Create table with binary columns, set session character set to cp1251,
10694     client character set to koi8, and make sure that there is conversion
10695     on insert and no conversion on select
10696   */
10697 
10698   stmt_text= "CREATE TABLE t1 (c1 VARBINARY(255), c2 VARBINARY(255))";
10699 
10700   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10701   myquery(rc);
10702 
10703   stmt_text= "SET CHARACTER_SET_CLIENT=koi8r, "
10704                  "CHARACTER_SET_CONNECTION=cp1251, "
10705                  "CHARACTER_SET_RESULTS=koi8r";
10706 
10707   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10708   myquery(rc);
10709 
10710   bzero((char*) bind_array, sizeof(bind_array));
10711 
10712   bind_array[0].buffer_type= MYSQL_TYPE_STRING;
10713   bind_array[0].buffer= (void *) koi8;
10714   bind_array[0].buffer_length= strlen(koi8);
10715 
10716   bind_array[1].buffer_type= MYSQL_TYPE_STRING;
10717   bind_array[1].buffer= (void *) koi8;
10718   bind_array[1].buffer_length= strlen(koi8);
10719 
10720   stmt= mysql_stmt_init(mysql);
10721   check_stmt(stmt);
10722 
10723   stmt_text= "INSERT INTO t1 (c1, c2) VALUES (?, ?)";
10724 
10725   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10726   check_execute(stmt, rc);
10727 
10728   mysql_stmt_bind_param(stmt, bind_array);
10729 
10730   mysql_stmt_send_long_data(stmt, 0, koi8, strlen(koi8));
10731 
10732   rc= mysql_stmt_execute(stmt);
10733   check_execute(stmt, rc);
10734 
10735   stmt_text= "SELECT c1, c2 FROM t1";
10736 
10737   /* c1 and c2 are binary so no conversion will be done on select */
10738   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10739   check_execute(stmt, rc);
10740 
10741   rc= mysql_stmt_execute(stmt);
10742   check_execute(stmt, rc);
10743 
10744   bind_array[0].buffer= buf1;
10745   bind_array[0].buffer_length= sizeof(buf1);
10746   bind_array[0].length= &buf1_len;
10747 
10748   bind_array[1].buffer= buf2;
10749   bind_array[1].buffer_length= sizeof(buf2);
10750   bind_array[1].length= &buf2_len;
10751 
10752   mysql_stmt_bind_result(stmt, bind_array);
10753 
10754   rc= mysql_stmt_fetch(stmt);
10755   check_execute(stmt, rc);
10756 
10757   DIE_UNLESS(buf1_len == strlen(cp1251));
10758   DIE_UNLESS(buf2_len == strlen(cp1251));
10759   DIE_UNLESS(!memcmp(buf1, cp1251, buf1_len));
10760   DIE_UNLESS(!memcmp(buf2, cp1251, buf1_len));
10761 
10762   rc= mysql_stmt_fetch(stmt);
10763   DIE_UNLESS(rc == MYSQL_NO_DATA);
10764 
10765   stmt_text= "DROP TABLE IF EXISTS t1";
10766   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10767   myquery(rc);
10768 
10769   /*
10770     Now create table with two cp1251 columns, set client character
10771     set to koi8 and supply columns of one row as string and another as
10772     binary data. Binary data must not be converted on insert, and both
10773     columns must be converted to client character set on select.
10774   */
10775 
10776   stmt_text= "CREATE TABLE t1 (c1 VARCHAR(255) CHARACTER SET cp1251, "
10777                               "c2 VARCHAR(255) CHARACTER SET cp1251)";
10778 
10779   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10780   myquery(rc);
10781 
10782   stmt_text= "INSERT INTO t1 (c1, c2) VALUES (?, ?)";
10783 
10784   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10785   check_execute(stmt, rc);
10786 
10787   /* this data must be converted */
10788   bind_array[0].buffer_type= MYSQL_TYPE_STRING;
10789   bind_array[0].buffer= (void *) koi8;
10790   bind_array[0].buffer_length= strlen(koi8);
10791 
10792   bind_array[1].buffer_type= MYSQL_TYPE_STRING;
10793   bind_array[1].buffer= (void *) koi8;
10794   bind_array[1].buffer_length= strlen(koi8);
10795 
10796   mysql_stmt_bind_param(stmt, bind_array);
10797 
10798   mysql_stmt_send_long_data(stmt, 0, koi8, strlen(koi8));
10799 
10800   rc= mysql_stmt_execute(stmt);
10801   check_execute(stmt, rc);
10802 
10803   /* this data must not be converted */
10804   bind_array[0].buffer_type= MYSQL_TYPE_BLOB;
10805   bind_array[0].buffer= (void *) cp1251;
10806   bind_array[0].buffer_length= strlen(cp1251);
10807 
10808   bind_array[1].buffer_type= MYSQL_TYPE_BLOB;
10809   bind_array[1].buffer= (void *) cp1251;
10810   bind_array[1].buffer_length= strlen(cp1251);
10811 
10812   mysql_stmt_bind_param(stmt, bind_array);
10813 
10814   mysql_stmt_send_long_data(stmt, 0, cp1251, strlen(cp1251));
10815 
10816   rc= mysql_stmt_execute(stmt);
10817   check_execute(stmt, rc);
10818 
10819   /* Fetch data and verify that rows are in koi8 */
10820 
10821   stmt_text= "SELECT c1, c2 FROM t1";
10822 
10823   /* c1 and c2 are binary so no conversion will be done on select */
10824   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10825   check_execute(stmt, rc);
10826 
10827   rc= mysql_stmt_execute(stmt);
10828   check_execute(stmt, rc);
10829 
10830   bind_array[0].buffer= buf1;
10831   bind_array[0].buffer_length= sizeof(buf1);
10832   bind_array[0].length= &buf1_len;
10833 
10834   bind_array[1].buffer= buf2;
10835   bind_array[1].buffer_length= sizeof(buf2);
10836   bind_array[1].length= &buf2_len;
10837 
10838   mysql_stmt_bind_result(stmt, bind_array);
10839 
10840   while ((rc= mysql_stmt_fetch(stmt)) == 0)
10841   {
10842     DIE_UNLESS(buf1_len == strlen(koi8));
10843     DIE_UNLESS(buf2_len == strlen(koi8));
10844     DIE_UNLESS(!memcmp(buf1, koi8, buf1_len));
10845     DIE_UNLESS(!memcmp(buf2, koi8, buf1_len));
10846   }
10847   DIE_UNLESS(rc == MYSQL_NO_DATA);
10848   mysql_stmt_close(stmt);
10849 
10850   stmt_text= "DROP TABLE t1";
10851   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10852   myquery(rc);
10853   stmt_text= "SET NAMES DEFAULT";
10854   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10855   myquery(rc);
10856 }
10857 
10858 
test_bug3796()10859 static void test_bug3796()
10860 {
10861   MYSQL_STMT *stmt;
10862   MYSQL_BIND my_bind[1];
10863   const char *concat_arg0= "concat_with_";
10864   enum { OUT_BUFF_SIZE= 30 };
10865   char out_buff[OUT_BUFF_SIZE];
10866   char canonical_buff[OUT_BUFF_SIZE];
10867   ulong out_length;
10868   const char *stmt_text;
10869   int rc;
10870 
10871   myheader("test_bug3796");
10872 
10873   /* Create and fill test table */
10874   stmt_text= "DROP TABLE IF EXISTS t1";
10875   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10876   myquery(rc);
10877 
10878   stmt_text= "CREATE TABLE t1 (a INT, b VARCHAR(30))";
10879   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10880   myquery(rc);
10881 
10882   stmt_text= "INSERT INTO t1 VALUES(1, 'ONE'), (2, 'TWO')";
10883   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10884   myquery(rc);
10885 
10886   /* Create statement handle and prepare it with select */
10887   stmt= mysql_stmt_init(mysql);
10888   stmt_text= "SELECT concat(?, b) FROM t1";
10889 
10890   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10891   check_execute(stmt, rc);
10892 
10893   /* Bind input buffers */
10894   bzero((char*) my_bind, sizeof(my_bind));
10895 
10896   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
10897   my_bind[0].buffer= (void *) concat_arg0;
10898   my_bind[0].buffer_length= strlen(concat_arg0);
10899 
10900   mysql_stmt_bind_param(stmt, my_bind);
10901 
10902   /* Execute the select statement */
10903   rc= mysql_stmt_execute(stmt);
10904   check_execute(stmt, rc);
10905 
10906   my_bind[0].buffer= (void *) out_buff;
10907   my_bind[0].buffer_length= OUT_BUFF_SIZE;
10908   my_bind[0].length= &out_length;
10909 
10910   mysql_stmt_bind_result(stmt, my_bind);
10911 
10912   rc= mysql_stmt_fetch(stmt);
10913   if (!opt_silent)
10914     printf("Concat result: '%s'\n", out_buff);
10915   check_execute(stmt, rc);
10916   strmov(canonical_buff, concat_arg0);
10917   strcat(canonical_buff, "ONE");
10918   DIE_UNLESS(strlen(canonical_buff) == out_length &&
10919          strncmp(out_buff, canonical_buff, out_length) == 0);
10920 
10921   rc= mysql_stmt_fetch(stmt);
10922   check_execute(stmt, rc);
10923   strmov(canonical_buff + strlen(concat_arg0), "TWO");
10924   DIE_UNLESS(strlen(canonical_buff) == out_length &&
10925          strncmp(out_buff, canonical_buff, out_length) == 0);
10926   if (!opt_silent)
10927     printf("Concat result: '%s'\n", out_buff);
10928 
10929   rc= mysql_stmt_fetch(stmt);
10930   DIE_UNLESS(rc == MYSQL_NO_DATA);
10931 
10932   mysql_stmt_close(stmt);
10933 
10934   stmt_text= "DROP TABLE IF EXISTS t1";
10935   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
10936   myquery(rc);
10937 }
10938 
10939 
test_bug4026()10940 static void test_bug4026()
10941 {
10942   MYSQL_STMT *stmt;
10943   MYSQL_BIND my_bind[2];
10944   MYSQL_TIME time_in, time_out;
10945   MYSQL_TIME datetime_in, datetime_out;
10946   const char *stmt_text;
10947   int rc;
10948 
10949   myheader("test_bug4026");
10950 
10951   /* Check that microseconds are inserted and selected successfully */
10952 
10953   /* Create a statement handle and prepare it with select */
10954   stmt= mysql_stmt_init(mysql);
10955   stmt_text= "SELECT ?, ?";
10956 
10957   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
10958   check_execute(stmt, rc);
10959 
10960   /* Bind input buffers */
10961   bzero((char*) my_bind, sizeof(my_bind));
10962   bzero((char*) &time_in, sizeof(time_in));
10963   bzero((char*) &time_out, sizeof(time_out));
10964   bzero((char*) &datetime_in, sizeof(datetime_in));
10965   bzero((char*) &datetime_out, sizeof(datetime_out));
10966 
10967   my_bind[0].buffer_type= MYSQL_TYPE_TIME;
10968   my_bind[0].buffer= (void *) &time_in;
10969   my_bind[1].buffer_type= MYSQL_TYPE_DATETIME;
10970   my_bind[1].buffer= (void *) &datetime_in;
10971 
10972   time_in.hour= 23;
10973   time_in.minute= 59;
10974   time_in.second= 59;
10975   time_in.second_part= 123456;
10976   /*
10977     This is not necessary, just to make DIE_UNLESS below work: this field
10978     is filled in when time is received from server
10979   */
10980   time_in.time_type= MYSQL_TIMESTAMP_TIME;
10981 
10982   datetime_in= time_in;
10983   datetime_in.year= 2003;
10984   datetime_in.month= 12;
10985   datetime_in.day= 31;
10986   datetime_in.time_type= MYSQL_TIMESTAMP_DATETIME;
10987 
10988   mysql_stmt_bind_param(stmt, my_bind);
10989 
10990   /* Execute the select statement */
10991   rc= mysql_stmt_execute(stmt);
10992   check_execute(stmt, rc);
10993 
10994   my_bind[0].buffer= (void *) &time_out;
10995   my_bind[1].buffer= (void *) &datetime_out;
10996 
10997   mysql_stmt_bind_result(stmt, my_bind);
10998 
10999   rc= mysql_stmt_fetch(stmt);
11000   DIE_UNLESS(rc == 0);
11001   if (!opt_silent)
11002   {
11003     printf("%d:%d:%d.%lu\n", time_out.hour, time_out.minute, time_out.second,
11004            time_out.second_part);
11005     printf("%d-%d-%d %d:%d:%d.%lu\n", datetime_out.year, datetime_out.month,
11006            datetime_out.day, datetime_out.hour,
11007            datetime_out.minute, datetime_out.second,
11008            datetime_out.second_part);
11009   }
11010   DIE_UNLESS(memcmp(&time_in, &time_out, sizeof(time_in)) == 0);
11011   DIE_UNLESS(memcmp(&datetime_in, &datetime_out, sizeof(datetime_in)) == 0);
11012   mysql_stmt_close(stmt);
11013 }
11014 
11015 
test_bug4079()11016 static void test_bug4079()
11017 {
11018   MYSQL_STMT *stmt;
11019   MYSQL_BIND my_bind[1];
11020   const char *stmt_text;
11021   uint32 res;
11022   int rc;
11023 
11024   myheader("test_bug4079");
11025 
11026   /* Create and fill table */
11027   mysql_query(mysql, "DROP TABLE IF EXISTS t1");
11028   mysql_query(mysql, "CREATE TABLE t1 (a int)");
11029   mysql_query(mysql, "INSERT INTO t1 VALUES (1), (2)");
11030 
11031   /* Prepare erroneous statement */
11032   stmt= mysql_stmt_init(mysql);
11033   stmt_text= "SELECT 1 < (SELECT a FROM t1)";
11034 
11035   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11036   check_execute(stmt, rc);
11037 
11038   /* Execute the select statement */
11039   rc= mysql_stmt_execute(stmt);
11040   check_execute(stmt, rc);
11041 
11042   /* Bind input buffers */
11043   bzero((char*) my_bind, sizeof(my_bind));
11044 
11045   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
11046   my_bind[0].buffer= (void *) &res;
11047 
11048   mysql_stmt_bind_result(stmt, my_bind);
11049 
11050   rc= mysql_stmt_fetch(stmt);
11051   DIE_UNLESS(rc != 0 && rc != MYSQL_NO_DATA);
11052   if (!opt_silent)
11053     printf("Got error from mysql_stmt_fetch (as expected):\n%s\n",
11054            mysql_stmt_error(stmt));
11055   /* buggy version of libmysql hanged up here */
11056   mysql_stmt_close(stmt);
11057 }
11058 
11059 
test_bug4236()11060 static void test_bug4236()
11061 {
11062   MYSQL_STMT *stmt;
11063   const char *stmt_text;
11064   int rc;
11065   MYSQL_STMT backup;
11066 
11067   myheader("test_bug4236");
11068 
11069   stmt= mysql_stmt_init(mysql);
11070 
11071   /* mysql_stmt_execute() of statement with statement id= 0 crashed server */
11072   stmt_text= "SELECT 1";
11073   /* We need to prepare statement to pass by possible check in libmysql */
11074   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11075   check_execute(stmt, rc);
11076   /* Hack to check that server works OK if statement wasn't found */
11077   backup.stmt_id= stmt->stmt_id;
11078   stmt->stmt_id= 0;
11079   rc= mysql_stmt_execute(stmt);
11080   DIE_UNLESS(rc);
11081   /* Restore original statement id to be able to reprepare it */
11082   stmt->stmt_id= backup.stmt_id;
11083 
11084   mysql_stmt_close(stmt);
11085 }
11086 
11087 
test_bug4030()11088 static void test_bug4030()
11089 {
11090   MYSQL_STMT *stmt;
11091   MYSQL_BIND my_bind[3];
11092   MYSQL_TIME time_canonical, time_out;
11093   MYSQL_TIME date_canonical, date_out;
11094   MYSQL_TIME datetime_canonical, datetime_out;
11095   const char *stmt_text;
11096   int rc;
11097 
11098   myheader("test_bug4030");
11099 
11100   /* Check that microseconds are inserted and selected successfully */
11101 
11102   /* Execute a query with time values in prepared mode */
11103   stmt= mysql_stmt_init(mysql);
11104   stmt_text= "SELECT '23:59:59.123456', '2003-12-31', "
11105              "'2003-12-31 23:59:59.123456'";
11106   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11107   check_execute(stmt, rc);
11108   rc= mysql_stmt_execute(stmt);
11109   check_execute(stmt, rc);
11110 
11111   /* Bind output buffers */
11112   bzero((char*) my_bind, sizeof(my_bind));
11113   bzero((char*) &time_canonical, sizeof(time_canonical));
11114   bzero((char*) &time_out, sizeof(time_out));
11115   bzero((char*) &date_canonical, sizeof(date_canonical));
11116   bzero((char*) &date_out, sizeof(date_out));
11117   bzero((char*) &datetime_canonical, sizeof(datetime_canonical));
11118   bzero((char*) &datetime_out, sizeof(datetime_out));
11119 
11120   my_bind[0].buffer_type= MYSQL_TYPE_TIME;
11121   my_bind[0].buffer= (void *) &time_out;
11122   my_bind[1].buffer_type= MYSQL_TYPE_DATE;
11123   my_bind[1].buffer= (void *) &date_out;
11124   my_bind[2].buffer_type= MYSQL_TYPE_DATETIME;
11125   my_bind[2].buffer= (void *) &datetime_out;
11126 
11127   time_canonical.hour= 23;
11128   time_canonical.minute= 59;
11129   time_canonical.second= 59;
11130   time_canonical.second_part= 123456;
11131   time_canonical.time_type= MYSQL_TIMESTAMP_TIME;
11132 
11133   date_canonical.year= 2003;
11134   date_canonical.month= 12;
11135   date_canonical.day= 31;
11136   date_canonical.time_type= MYSQL_TIMESTAMP_DATE;
11137 
11138   datetime_canonical= time_canonical;
11139   datetime_canonical.year= 2003;
11140   datetime_canonical.month= 12;
11141   datetime_canonical.day= 31;
11142   datetime_canonical.time_type= MYSQL_TIMESTAMP_DATETIME;
11143 
11144   mysql_stmt_bind_result(stmt, my_bind);
11145 
11146   rc= mysql_stmt_fetch(stmt);
11147   DIE_UNLESS(rc == 0);
11148   if (!opt_silent)
11149   {
11150     printf("%d:%d:%d.%lu\n", time_out.hour, time_out.minute, time_out.second,
11151            time_out.second_part);
11152     printf("%d-%d-%d\n", date_out.year, date_out.month, date_out.day);
11153     printf("%d-%d-%d %d:%d:%d.%lu\n", datetime_out.year, datetime_out.month,
11154            datetime_out.day, datetime_out.hour,
11155            datetime_out.minute, datetime_out.second,
11156            datetime_out.second_part);
11157   }
11158   DIE_UNLESS(memcmp(&time_canonical, &time_out, sizeof(time_out)) == 0);
11159   DIE_UNLESS(memcmp(&date_canonical, &date_out, sizeof(date_out)) == 0);
11160   DIE_UNLESS(memcmp(&datetime_canonical, &datetime_out, sizeof(datetime_out)) == 0);
11161   mysql_stmt_close(stmt);
11162 }
11163 
test_view()11164 static void test_view()
11165 {
11166   MYSQL_STMT *stmt;
11167   int rc, i;
11168   MYSQL_BIND      my_bind[1];
11169   char            str_data[50];
11170   ulong           length = 0L;
11171   long            is_null = 0L;
11172   const char *query=
11173     "SELECT COUNT(*) FROM v1 WHERE SERVERNAME=?";
11174 
11175   myheader("test_view");
11176 
11177   rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,t2,t3,v1");
11178   myquery(rc);
11179 
11180   rc = mysql_query(mysql, "DROP VIEW IF EXISTS v1,t1,t2,t3");
11181   myquery(rc);
11182   rc= mysql_query(mysql,"CREATE TABLE t1 ("
11183                         " SERVERGRP varchar(20) NOT NULL default '', "
11184                         " DBINSTANCE varchar(20) NOT NULL default '', "
11185                         " PRIMARY KEY  (SERVERGRP)) "
11186                         " CHARSET=latin1 collate=latin1_bin");
11187   myquery(rc);
11188   rc= mysql_query(mysql,"CREATE TABLE t2 ("
11189                         " SERVERNAME varchar(20) NOT NULL, "
11190                         " SERVERGRP varchar(20) NOT NULL, "
11191                         " PRIMARY KEY (SERVERNAME)) "
11192                         " CHARSET=latin1 COLLATE latin1_bin");
11193   myquery(rc);
11194   rc= mysql_query(mysql,
11195                   "CREATE TABLE t3 ("
11196                   " SERVERGRP varchar(20) BINARY NOT NULL, "
11197                   " TABNAME varchar(30) NOT NULL, MAPSTATE char(1) NOT NULL, "
11198                   " ACTSTATE char(1) NOT NULL , "
11199                   " LOCAL_NAME varchar(30) NOT NULL, "
11200                   " CHG_DATE varchar(8) NOT NULL default '00000000', "
11201                   " CHG_TIME varchar(6) NOT NULL default '000000', "
11202                   " MXUSER varchar(12) NOT NULL default '', "
11203                   " PRIMARY KEY (SERVERGRP, TABNAME, MAPSTATE, ACTSTATE, "
11204                   " LOCAL_NAME)) CHARSET=latin1 COLLATE latin1_bin");
11205   myquery(rc);
11206   rc= mysql_query(mysql,"CREATE VIEW v1 AS select sql_no_cache"
11207                   " T0001.SERVERNAME AS SERVERNAME, T0003.TABNAME AS"
11208                   " TABNAME,T0003.LOCAL_NAME AS LOCAL_NAME,T0002.DBINSTANCE AS"
11209                   " DBINSTANCE from t2 T0001 join t1 T0002 join t3 T0003 where"
11210                   " ((T0002.SERVERGRP = T0001.SERVERGRP) and"
11211                   " (T0002.SERVERGRP = T0003.SERVERGRP)"
11212                   " and (T0003.MAPSTATE = _latin1'A') and"
11213                   " (T0003.ACTSTATE = _latin1' '))");
11214   myquery(rc);
11215 
11216   stmt= mysql_stmt_init(mysql);
11217   rc= mysql_stmt_prepare(stmt, query, strlen(query));
11218   check_execute(stmt, rc);
11219 
11220   strmov(str_data, "TEST");
11221   bzero((char*) my_bind, sizeof(my_bind));
11222   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
11223   my_bind[0].buffer= (char *)&str_data;
11224   my_bind[0].buffer_length= 50;
11225   my_bind[0].length= &length;
11226   length= 4;
11227   my_bind[0].is_null= (char*)&is_null;
11228   rc= mysql_stmt_bind_param(stmt, my_bind);
11229   check_execute(stmt,rc);
11230 
11231   for (i= 0; i < 3; i++)
11232   {
11233     rc= mysql_stmt_execute(stmt);
11234     check_execute(stmt, rc);
11235     rc= my_process_stmt_result(stmt);
11236     DIE_UNLESS(1 == rc);
11237   }
11238   mysql_stmt_close(stmt);
11239 
11240   rc= mysql_query(mysql, "DROP TABLE t1,t2,t3");
11241   myquery(rc);
11242   rc= mysql_query(mysql, "DROP VIEW v1");
11243   myquery(rc);
11244 }
11245 
11246 
test_view_where()11247 static void test_view_where()
11248 {
11249   MYSQL_STMT *stmt;
11250   int rc, i;
11251   const char *query=
11252     "select v1.c,v2.c from v1, v2";
11253 
11254   myheader("test_view_where");
11255 
11256   rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,v1,v2");
11257   myquery(rc);
11258 
11259   rc = mysql_query(mysql, "DROP VIEW IF EXISTS v1,v2,t1");
11260   myquery(rc);
11261   rc= mysql_query(mysql,"CREATE TABLE t1 (a int, b int)");
11262   myquery(rc);
11263   rc= mysql_query(mysql,"insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10)");
11264   myquery(rc);
11265   rc= mysql_query(mysql,"create view v1 (c) as select b from t1 where a<3");
11266   myquery(rc);
11267   rc= mysql_query(mysql,"create view v2 (c) as select b from t1 where a>=3");
11268   myquery(rc);
11269 
11270   stmt= mysql_stmt_init(mysql);
11271   rc= mysql_stmt_prepare(stmt, query, strlen(query));
11272   check_execute(stmt, rc);
11273 
11274   for (i= 0; i < 3; i++)
11275   {
11276     rc= mysql_stmt_execute(stmt);
11277     check_execute(stmt, rc);
11278     rc= my_process_stmt_result(stmt);
11279     DIE_UNLESS(4 == rc);
11280   }
11281   mysql_stmt_close(stmt);
11282 
11283   rc= mysql_query(mysql, "DROP TABLE t1");
11284   myquery(rc);
11285   rc= mysql_query(mysql, "DROP VIEW v1, v2");
11286   myquery(rc);
11287 }
11288 
11289 
test_view_2where()11290 static void test_view_2where()
11291 {
11292   MYSQL_STMT *stmt;
11293   int rc, i;
11294   MYSQL_BIND      my_bind[8];
11295   char            parms[8][100];
11296   ulong           length[8];
11297   const char *query=
11298     "select relid, report, handle, log_group, username, variant, type, "
11299     "version, erfdat, erftime, erfname, aedat, aetime, aename, dependvars, "
11300     "inactive from V_LTDX where mandt = ? and relid = ? and report = ? and "
11301     "handle = ? and log_group = ? and username in ( ? , ? ) and type = ?";
11302 
11303   myheader("test_view_2where");
11304 
11305   rc= mysql_query(mysql, "DROP TABLE IF EXISTS LTDX");
11306   myquery(rc);
11307   rc= mysql_query(mysql, "DROP VIEW IF EXISTS V_LTDX");
11308   myquery(rc);
11309   rc= mysql_query(mysql,
11310                   "CREATE TABLE LTDX (MANDT char(3) NOT NULL default '000', "
11311                   " RELID char(2) NOT NULL, REPORT varchar(40) NOT NULL,"
11312                   " HANDLE varchar(4) NOT NULL, LOG_GROUP varchar(4) NOT NULL,"
11313                   " USERNAME varchar(12) NOT NULL,"
11314                   " VARIANT varchar(12) NOT NULL,"
11315                   " TYPE char(1) NOT NULL, SRTF2 int(11) NOT NULL,"
11316                   " VERSION varchar(6) NOT NULL default '000000',"
11317                   " ERFDAT varchar(8) NOT NULL default '00000000',"
11318                   " ERFTIME varchar(6) NOT NULL default '000000',"
11319                   " ERFNAME varchar(12) NOT NULL,"
11320                   " AEDAT varchar(8) NOT NULL default '00000000',"
11321                   " AETIME varchar(6) NOT NULL default '000000',"
11322                   " AENAME varchar(12) NOT NULL,"
11323                   " DEPENDVARS varchar(10) NOT NULL,"
11324                   " INACTIVE char(1) NOT NULL, CLUSTR smallint(6) NOT NULL,"
11325                   " CLUSTD blob,"
11326                   " PRIMARY KEY (MANDT, RELID, REPORT, HANDLE, LOG_GROUP, "
11327                                 "USERNAME, VARIANT, TYPE, SRTF2))"
11328                  " CHARSET=latin1 COLLATE latin1_bin");
11329   myquery(rc);
11330   rc= mysql_query(mysql,
11331                   "CREATE VIEW V_LTDX AS select T0001.MANDT AS "
11332                   " MANDT,T0001.RELID AS RELID,T0001.REPORT AS "
11333                   " REPORT,T0001.HANDLE AS HANDLE,T0001.LOG_GROUP AS "
11334                   " LOG_GROUP,T0001.USERNAME AS USERNAME,T0001.VARIANT AS "
11335                   " VARIANT,T0001.TYPE AS TYPE,T0001.VERSION AS "
11336                   " VERSION,T0001.ERFDAT AS ERFDAT,T0001.ERFTIME AS "
11337                   " ERFTIME,T0001.ERFNAME AS ERFNAME,T0001.AEDAT AS "
11338                   " AEDAT,T0001.AETIME AS AETIME,T0001.AENAME AS "
11339                   " AENAME,T0001.DEPENDVARS AS DEPENDVARS,T0001.INACTIVE AS "
11340                   " INACTIVE from LTDX T0001 where (T0001.SRTF2 = 0)");
11341   myquery(rc);
11342   bzero((char*) my_bind, sizeof(my_bind));
11343   for (i=0; i < 8; i++) {
11344     strmov(parms[i], "1");
11345     my_bind[i].buffer_type = MYSQL_TYPE_VAR_STRING;
11346     my_bind[i].buffer = (char *)&parms[i];
11347     my_bind[i].buffer_length = 100;
11348     my_bind[i].is_null = 0;
11349     my_bind[i].length = &length[i];
11350     length[i] = 1;
11351   }
11352   stmt= mysql_stmt_init(mysql);
11353   rc= mysql_stmt_prepare(stmt, query, strlen(query));
11354   check_execute(stmt, rc);
11355 
11356   rc= mysql_stmt_bind_param(stmt, my_bind);
11357   check_execute(stmt,rc);
11358 
11359   rc= mysql_stmt_execute(stmt);
11360   check_execute(stmt, rc);
11361   rc= my_process_stmt_result(stmt);
11362   DIE_UNLESS(0 == rc);
11363 
11364   mysql_stmt_close(stmt);
11365 
11366   rc= mysql_query(mysql, "DROP VIEW V_LTDX");
11367   myquery(rc);
11368   rc= mysql_query(mysql, "DROP TABLE LTDX");
11369   myquery(rc);
11370 }
11371 
11372 
test_view_star()11373 static void test_view_star()
11374 {
11375   MYSQL_STMT *stmt;
11376   int rc, i;
11377   MYSQL_BIND      my_bind[8];
11378   char            parms[8][100];
11379   ulong           length[8];
11380   const char *query= "SELECT * FROM vt1 WHERE a IN (?,?)";
11381 
11382   myheader("test_view_star");
11383 
11384   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, vt1");
11385   myquery(rc);
11386   rc= mysql_query(mysql, "DROP VIEW IF EXISTS t1, vt1");
11387   myquery(rc);
11388   rc= mysql_query(mysql, "CREATE TABLE t1 (a int)");
11389   myquery(rc);
11390   rc= mysql_query(mysql, "CREATE VIEW vt1 AS SELECT a FROM t1");
11391   myquery(rc);
11392   bzero((char*) my_bind, sizeof(my_bind));
11393   for (i= 0; i < 2; i++) {
11394     sprintf((char *)&parms[i], "%d", i);
11395     my_bind[i].buffer_type = MYSQL_TYPE_VAR_STRING;
11396     my_bind[i].buffer = (char *)&parms[i];
11397     my_bind[i].buffer_length = 100;
11398     my_bind[i].is_null = 0;
11399     my_bind[i].length = &length[i];
11400     length[i] = 1;
11401   }
11402 
11403   stmt= mysql_stmt_init(mysql);
11404   rc= mysql_stmt_prepare(stmt, query, strlen(query));
11405   check_execute(stmt, rc);
11406 
11407   rc= mysql_stmt_bind_param(stmt, my_bind);
11408   check_execute(stmt,rc);
11409 
11410   for (i= 0; i < 3; i++)
11411   {
11412     rc= mysql_stmt_execute(stmt);
11413     check_execute(stmt, rc);
11414     rc= my_process_stmt_result(stmt);
11415     DIE_UNLESS(0 == rc);
11416   }
11417 
11418   mysql_stmt_close(stmt);
11419 
11420   rc= mysql_query(mysql, "DROP TABLE t1");
11421   myquery(rc);
11422   rc= mysql_query(mysql, "DROP VIEW vt1");
11423   myquery(rc);
11424 }
11425 
11426 
test_view_insert()11427 static void test_view_insert()
11428 {
11429   MYSQL_STMT *insert_stmt, *select_stmt;
11430   int rc, i;
11431   MYSQL_BIND      my_bind[1];
11432   int             my_val = 0;
11433   ulong           my_length = 0L;
11434   long            my_null = 0L;
11435   const char *query=
11436     "insert into v1 values (?)";
11437 
11438   myheader("test_view_insert");
11439 
11440   rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,v1");
11441   myquery(rc);
11442   rc = mysql_query(mysql, "DROP VIEW IF EXISTS t1,v1");
11443   myquery(rc);
11444 
11445   rc= mysql_query(mysql,"create table t1 (a int, primary key (a))");
11446   myquery(rc);
11447 
11448   rc= mysql_query(mysql, "create view v1 as select a from t1 where a>=1");
11449   myquery(rc);
11450 
11451   insert_stmt= mysql_stmt_init(mysql);
11452   rc= mysql_stmt_prepare(insert_stmt, query, strlen(query));
11453   check_execute(insert_stmt, rc);
11454   query= "select * from t1";
11455   select_stmt= mysql_stmt_init(mysql);
11456   rc= mysql_stmt_prepare(select_stmt, query, strlen(query));
11457   check_execute(select_stmt, rc);
11458 
11459   bzero((char*) my_bind, sizeof(my_bind));
11460   my_bind[0].buffer_type = MYSQL_TYPE_LONG;
11461   my_bind[0].buffer = (char *)&my_val;
11462   my_bind[0].length = &my_length;
11463   my_bind[0].is_null = (char*)&my_null;
11464   rc= mysql_stmt_bind_param(insert_stmt, my_bind);
11465   check_execute(insert_stmt, rc);
11466 
11467   for (i= 0; i < 3; i++)
11468   {
11469     int rowcount= 0;
11470     my_val= i;
11471 
11472     rc= mysql_stmt_execute(insert_stmt);
11473     check_execute(insert_stmt, rc);
11474 
11475     rc= mysql_stmt_execute(select_stmt);
11476     check_execute(select_stmt, rc);
11477     rowcount= (int)my_process_stmt_result(select_stmt);
11478     DIE_UNLESS((i+1) == rowcount);
11479   }
11480   mysql_stmt_close(insert_stmt);
11481   mysql_stmt_close(select_stmt);
11482 
11483   rc= mysql_query(mysql, "DROP VIEW v1");
11484   myquery(rc);
11485   rc= mysql_query(mysql, "DROP TABLE t1");
11486   myquery(rc);
11487 }
11488 
11489 
test_left_join_view()11490 static void test_left_join_view()
11491 {
11492   MYSQL_STMT *stmt;
11493   int rc, i;
11494   const char *query=
11495     "select t1.a, v1.x from t1 left join v1 on (t1.a= v1.x);";
11496 
11497   myheader("test_left_join_view");
11498 
11499   rc = mysql_query(mysql, "DROP TABLE IF EXISTS t1,v1");
11500   myquery(rc);
11501 
11502   rc = mysql_query(mysql, "DROP VIEW IF EXISTS v1,t1");
11503   myquery(rc);
11504   rc= mysql_query(mysql,"CREATE TABLE t1 (a int)");
11505   myquery(rc);
11506   rc= mysql_query(mysql,"insert into t1 values (1), (2), (3)");
11507   myquery(rc);
11508   rc= mysql_query(mysql,"create view v1 (x) as select a from t1 where a > 1");
11509   myquery(rc);
11510   stmt= mysql_stmt_init(mysql);
11511   rc= mysql_stmt_prepare(stmt, query, strlen(query));
11512   check_execute(stmt, rc);
11513 
11514   for (i= 0; i < 3; i++)
11515   {
11516     rc= mysql_stmt_execute(stmt);
11517     check_execute(stmt, rc);
11518     rc= my_process_stmt_result(stmt);
11519     DIE_UNLESS(3 == rc);
11520   }
11521   mysql_stmt_close(stmt);
11522 
11523   rc= mysql_query(mysql, "DROP VIEW v1");
11524   myquery(rc);
11525   rc= mysql_query(mysql, "DROP TABLE t1");
11526   myquery(rc);
11527 }
11528 
11529 
test_view_insert_fields()11530 static void test_view_insert_fields()
11531 {
11532   MYSQL_STMT	*stmt;
11533   char		parm[11][1000];
11534   ulong         l[11];
11535   int		rc, i;
11536   MYSQL_BIND	my_bind[11];
11537   const char    *query= "INSERT INTO `v1` ( `K1C4` ,`K2C4` ,`K3C4` ,`K4N4` ,`F1C4` ,`F2I4` ,`F3N5` ,`F7F8` ,`F6N4` ,`F5C8` ,`F9D8` ) VALUES( ? , ? , ? , ? , ? , ? , ? , ? , ? , ? , ? )";
11538 
11539   myheader("test_view_insert_fields");
11540 
11541   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1, v1");
11542   myquery(rc);
11543   rc= mysql_query(mysql, "DROP VIEW IF EXISTS t1, v1");
11544   myquery(rc);
11545   rc= mysql_query(mysql,
11546                   "CREATE TABLE t1 (K1C4 varchar(4) NOT NULL,"
11547                   "K2C4 varchar(4) NOT NULL, K3C4 varchar(4) NOT NULL,"
11548                   "K4N4 varchar(4) NOT NULL default '0000',"
11549                   "F1C4 varchar(4) NOT NULL, F2I4 int(11) NOT NULL,"
11550                   "F3N5 varchar(5) NOT NULL default '00000',"
11551                   "F4I4 int(11) NOT NULL default '0', F5C8 varchar(8) NOT NULL,"
11552                   "F6N4 varchar(4) NOT NULL default '0000',"
11553                   "F7F8 double NOT NULL default '0',"
11554                   "F8F8 double NOT NULL default '0',"
11555                   "F9D8 decimal(8,2) NOT NULL default '0.00',"
11556                   "PRIMARY KEY (K1C4,K2C4,K3C4,K4N4)) "
11557                   "CHARSET=latin1 COLLATE latin1_bin");
11558   myquery(rc);
11559   rc= mysql_query(mysql,
11560                   "CREATE VIEW v1 AS select sql_no_cache "
11561                   " K1C4 AS K1C4, K2C4 AS K2C4, K3C4 AS K3C4, K4N4 AS K4N4, "
11562                   " F1C4 AS F1C4, F2I4 AS F2I4, F3N5 AS F3N5,"
11563                   " F7F8 AS F7F8, F6N4 AS F6N4, F5C8 AS F5C8, F9D8 AS F9D8"
11564                   " from t1 T0001");
11565 
11566   bzero((char*) my_bind, sizeof(my_bind));
11567   for (i= 0; i < 11; i++)
11568   {
11569     l[i]= 20;
11570     my_bind[i].buffer_type= MYSQL_TYPE_STRING;
11571     my_bind[i].is_null= 0;
11572     my_bind[i].buffer= (char *)&parm[i];
11573 
11574     strmov(parm[i], "1");
11575     my_bind[i].buffer_length= 2;
11576     my_bind[i].length= &l[i];
11577   }
11578   stmt= mysql_stmt_init(mysql);
11579   rc= mysql_stmt_prepare(stmt, query, strlen(query));
11580   check_execute(stmt, rc);
11581   rc= mysql_stmt_bind_param(stmt, my_bind);
11582   check_execute(stmt, rc);
11583 
11584   rc= mysql_stmt_execute(stmt);
11585   check_execute(stmt, rc);
11586   mysql_stmt_close(stmt);
11587 
11588   query= "select * from t1";
11589   stmt= mysql_stmt_init(mysql);
11590   rc= mysql_stmt_prepare(stmt, query, strlen(query));
11591   check_execute(stmt, rc);
11592   rc= mysql_stmt_execute(stmt);
11593   check_execute(stmt, rc);
11594   rc= my_process_stmt_result(stmt);
11595   DIE_UNLESS(1 == rc);
11596 
11597   mysql_stmt_close(stmt);
11598   rc= mysql_query(mysql, "DROP VIEW v1");
11599   myquery(rc);
11600   rc= mysql_query(mysql, "DROP TABLE t1");
11601   myquery(rc);
11602 
11603 }
11604 
test_bug5126()11605 static void test_bug5126()
11606 {
11607   MYSQL_STMT *stmt;
11608   MYSQL_BIND my_bind[2];
11609   int32 c1, c2;
11610   const char *stmt_text;
11611   int rc;
11612 
11613   myheader("test_bug5126");
11614 
11615   stmt_text= "DROP TABLE IF EXISTS t1";
11616   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11617   myquery(rc);
11618 
11619   stmt_text= "CREATE TABLE t1 (a mediumint, b int)";
11620   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11621   myquery(rc);
11622 
11623   stmt_text= "INSERT INTO t1 VALUES (8386608, 1)";
11624   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11625   myquery(rc);
11626 
11627   stmt= mysql_stmt_init(mysql);
11628   stmt_text= "SELECT a, b FROM t1";
11629   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11630   check_execute(stmt, rc);
11631   rc= mysql_stmt_execute(stmt);
11632   check_execute(stmt, rc);
11633 
11634   /* Bind output buffers */
11635   bzero((char*) my_bind, sizeof(my_bind));
11636 
11637   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
11638   my_bind[0].buffer= &c1;
11639   my_bind[1].buffer_type= MYSQL_TYPE_LONG;
11640   my_bind[1].buffer= &c2;
11641 
11642   mysql_stmt_bind_result(stmt, my_bind);
11643 
11644   rc= mysql_stmt_fetch(stmt);
11645   DIE_UNLESS(rc == 0);
11646   DIE_UNLESS(c1 == 8386608 && c2 == 1);
11647   if (!opt_silent)
11648     printf("%ld, %ld\n", (long) c1, (long) c2);
11649   mysql_stmt_close(stmt);
11650 }
11651 
11652 
test_bug4231()11653 static void test_bug4231()
11654 {
11655   MYSQL_STMT *stmt;
11656   MYSQL_BIND my_bind[2];
11657   MYSQL_TIME tm[2];
11658   const char *stmt_text;
11659   int rc;
11660 
11661   myheader("test_bug4231");
11662 
11663   stmt_text= "DROP TABLE IF EXISTS t1";
11664   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11665   myquery(rc);
11666 
11667   stmt_text= "CREATE TABLE t1 (a int)";
11668   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11669   myquery(rc);
11670 
11671   stmt_text= "INSERT INTO t1 VALUES (1)";
11672   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11673   myquery(rc);
11674 
11675   stmt= mysql_stmt_init(mysql);
11676   stmt_text= "SELECT a FROM t1 WHERE ? = ?";
11677   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11678   check_execute(stmt, rc);
11679 
11680   /* Bind input buffers */
11681   bzero((char*) my_bind, sizeof(my_bind));
11682   bzero((char*) tm, sizeof(tm));
11683 
11684   my_bind[0].buffer_type= MYSQL_TYPE_DATE;
11685   my_bind[0].buffer= &tm[0];
11686   my_bind[1].buffer_type= MYSQL_TYPE_DATE;
11687   my_bind[1].buffer= &tm[1];
11688 
11689   mysql_stmt_bind_param(stmt, my_bind);
11690   check_execute(stmt, rc);
11691 
11692   /*
11693     First set server-side params to some non-zero non-equal values:
11694     then we will check that they are not used when client sends
11695     new (zero) times.
11696   */
11697   tm[0].time_type = MYSQL_TIMESTAMP_DATE;
11698   tm[0].year = 2000;
11699   tm[0].month = 1;
11700   tm[0].day = 1;
11701   tm[1]= tm[0];
11702   --tm[1].year;                                 /* tm[0] != tm[1] */
11703 
11704   rc= mysql_stmt_execute(stmt);
11705   check_execute(stmt, rc);
11706 
11707   rc= mysql_stmt_fetch(stmt);
11708 
11709   /* binds are unequal, no rows should be returned */
11710   DIE_UNLESS(rc == MYSQL_NO_DATA);
11711 
11712   /* Set one of the dates to zero */
11713   tm[0].year= tm[0].month= tm[0].day= 0;
11714   tm[1]= tm[0];
11715   mysql_stmt_execute(stmt);
11716   rc= mysql_stmt_fetch(stmt);
11717   DIE_UNLESS(rc == 0);
11718 
11719   mysql_stmt_close(stmt);
11720   stmt_text= "DROP TABLE t1";
11721   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11722   myquery(rc);
11723 }
11724 
11725 
test_bug5399()11726 static void test_bug5399()
11727 {
11728   /*
11729     Ascii 97 is 'a', which gets mapped to Ascii 65 'A' unless internal
11730     statement id hash in the server uses binary collation.
11731   */
11732 #define NUM_OF_USED_STMT 97
11733   MYSQL_STMT *stmt_list[NUM_OF_USED_STMT];
11734   MYSQL_STMT **stmt;
11735   MYSQL_BIND my_bind[1];
11736   char buff[600];
11737   int rc;
11738   int32 no;
11739 
11740   myheader("test_bug5399");
11741 
11742   bzero((char*) my_bind, sizeof(my_bind));
11743   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
11744   my_bind[0].buffer= &no;
11745 
11746   for (stmt= stmt_list; stmt != stmt_list + NUM_OF_USED_STMT; ++stmt)
11747   {
11748     sprintf(buff, "select %d", (int) (stmt - stmt_list));
11749     *stmt= mysql_stmt_init(mysql);
11750     rc= mysql_stmt_prepare(*stmt, buff, strlen(buff));
11751     check_execute(*stmt, rc);
11752     mysql_stmt_bind_result(*stmt, my_bind);
11753   }
11754   if (!opt_silent)
11755     printf("%d statements prepared.\n", NUM_OF_USED_STMT);
11756 
11757   for (stmt= stmt_list; stmt != stmt_list + NUM_OF_USED_STMT; ++stmt)
11758   {
11759     rc= mysql_stmt_execute(*stmt);
11760     check_execute(*stmt, rc);
11761     rc= mysql_stmt_store_result(*stmt);
11762     check_execute(*stmt, rc);
11763     rc= mysql_stmt_fetch(*stmt);
11764     DIE_UNLESS(rc == 0);
11765     DIE_UNLESS((int32) (stmt - stmt_list) == no);
11766   }
11767 
11768   for (stmt= stmt_list; stmt != stmt_list + NUM_OF_USED_STMT; ++stmt)
11769     mysql_stmt_close(*stmt);
11770 #undef NUM_OF_USED_STMT
11771 }
11772 
11773 
test_bug5194()11774 static void test_bug5194()
11775 {
11776   MYSQL_STMT *stmt;
11777   MYSQL_BIND *my_bind;
11778   char *query;
11779   char *param_str;
11780   int param_str_length;
11781   const char *stmt_text;
11782   int rc;
11783   float float_array[250] =
11784   {
11785     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11786     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11787     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11788     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11789     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11790     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11791     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11792     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11793     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11794     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11795     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11796     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11797     0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,  0.5,
11798     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11799     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11800     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11801     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11802     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11803     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11804     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11805     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11806     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11807     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11808     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,
11809     0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25
11810   };
11811   float *fa_ptr= float_array;
11812   /* Number of columns per row */
11813   const int COLUMN_COUNT= sizeof(float_array)/sizeof(*float_array);
11814   /* Number of rows per bulk insert to start with */
11815   const int MIN_ROWS_PER_INSERT= 262;
11816   /* Max number of rows per bulk insert to end with */
11817   const int MAX_ROWS_PER_INSERT= 300;
11818   const int MAX_PARAM_COUNT= COLUMN_COUNT*MAX_ROWS_PER_INSERT;
11819   const char *query_template= "insert into t1 values %s";
11820   const int CHARS_PER_PARAM= 5; /* space needed to place ", ?" in the query */
11821   const int uint16_max= 65535;
11822   int nrows, i;
11823 
11824   myheader("test_bug5194");
11825 
11826   stmt_text= "drop table if exists t1";
11827   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11828 
11829   stmt_text= "create table if not exists t1"
11830    "(c1 float, c2 float, c3 float, c4 float, c5 float, c6 float, "
11831    "c7 float, c8 float, c9 float, c10 float, c11 float, c12 float, "
11832    "c13 float, c14 float, c15 float, c16 float, c17 float, c18 float, "
11833    "c19 float, c20 float, c21 float, c22 float, c23 float, c24 float, "
11834    "c25 float, c26 float, c27 float, c28 float, c29 float, c30 float, "
11835    "c31 float, c32 float, c33 float, c34 float, c35 float, c36 float, "
11836    "c37 float, c38 float, c39 float, c40 float, c41 float, c42 float, "
11837    "c43 float, c44 float, c45 float, c46 float, c47 float, c48 float, "
11838    "c49 float, c50 float, c51 float, c52 float, c53 float, c54 float, "
11839    "c55 float, c56 float, c57 float, c58 float, c59 float, c60 float, "
11840    "c61 float, c62 float, c63 float, c64 float, c65 float, c66 float, "
11841    "c67 float, c68 float, c69 float, c70 float, c71 float, c72 float, "
11842    "c73 float, c74 float, c75 float, c76 float, c77 float, c78 float, "
11843    "c79 float, c80 float, c81 float, c82 float, c83 float, c84 float, "
11844    "c85 float, c86 float, c87 float, c88 float, c89 float, c90 float, "
11845    "c91 float, c92 float, c93 float, c94 float, c95 float, c96 float, "
11846    "c97 float, c98 float, c99 float, c100 float, c101 float, c102 float, "
11847    "c103 float, c104 float, c105 float, c106 float, c107 float, c108 float, "
11848    "c109 float, c110 float, c111 float, c112 float, c113 float, c114 float, "
11849    "c115 float, c116 float, c117 float, c118 float, c119 float, c120 float, "
11850    "c121 float, c122 float, c123 float, c124 float, c125 float, c126 float, "
11851    "c127 float, c128 float, c129 float, c130 float, c131 float, c132 float, "
11852    "c133 float, c134 float, c135 float, c136 float, c137 float, c138 float, "
11853    "c139 float, c140 float, c141 float, c142 float, c143 float, c144 float, "
11854    "c145 float, c146 float, c147 float, c148 float, c149 float, c150 float, "
11855    "c151 float, c152 float, c153 float, c154 float, c155 float, c156 float, "
11856    "c157 float, c158 float, c159 float, c160 float, c161 float, c162 float, "
11857    "c163 float, c164 float, c165 float, c166 float, c167 float, c168 float, "
11858    "c169 float, c170 float, c171 float, c172 float, c173 float, c174 float, "
11859    "c175 float, c176 float, c177 float, c178 float, c179 float, c180 float, "
11860    "c181 float, c182 float, c183 float, c184 float, c185 float, c186 float, "
11861    "c187 float, c188 float, c189 float, c190 float, c191 float, c192 float, "
11862    "c193 float, c194 float, c195 float, c196 float, c197 float, c198 float, "
11863    "c199 float, c200 float, c201 float, c202 float, c203 float, c204 float, "
11864    "c205 float, c206 float, c207 float, c208 float, c209 float, c210 float, "
11865    "c211 float, c212 float, c213 float, c214 float, c215 float, c216 float, "
11866    "c217 float, c218 float, c219 float, c220 float, c221 float, c222 float, "
11867    "c223 float, c224 float, c225 float, c226 float, c227 float, c228 float, "
11868    "c229 float, c230 float, c231 float, c232 float, c233 float, c234 float, "
11869    "c235 float, c236 float, c237 float, c238 float, c239 float, c240 float, "
11870    "c241 float, c242 float, c243 float, c244 float, c245 float, c246 float, "
11871    "c247 float, c248 float, c249 float, c250 float)";
11872   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11873   myquery(rc);
11874 
11875   my_bind= (MYSQL_BIND*) malloc(MAX_PARAM_COUNT * sizeof(MYSQL_BIND));
11876   query= (char*) malloc(strlen(query_template) +
11877                         MAX_PARAM_COUNT * CHARS_PER_PARAM + 1);
11878   param_str= (char*) malloc(COLUMN_COUNT * CHARS_PER_PARAM);
11879 
11880   if (my_bind == 0 || query == 0 || param_str == 0)
11881   {
11882     fprintf(stderr, "Can't allocate enough memory for query structs\n");
11883     if (my_bind)
11884       free(my_bind);
11885     if (query)
11886       free(query);
11887     if (param_str)
11888       free(param_str);
11889     return;
11890   }
11891 
11892   stmt= mysql_stmt_init(mysql);
11893 
11894   /* setup a template for one row of parameters */
11895   sprintf(param_str, "(");
11896   for (i= 1; i < COLUMN_COUNT; ++i)
11897     strcat(param_str, "?, ");
11898   strcat(param_str, "?)");
11899   param_str_length= strlen(param_str);
11900 
11901   /* setup bind array */
11902   bzero((char*) my_bind, MAX_PARAM_COUNT * sizeof(MYSQL_BIND));
11903   for (i= 0; i < MAX_PARAM_COUNT; ++i)
11904   {
11905     my_bind[i].buffer_type= MYSQL_TYPE_FLOAT;
11906     my_bind[i].buffer= fa_ptr;
11907     if (++fa_ptr == float_array + COLUMN_COUNT)
11908       fa_ptr= float_array;
11909   }
11910 
11911   /*
11912     Test each number of rows per bulk insert, so that we can see where
11913     MySQL fails.
11914   */
11915   for (nrows= MIN_ROWS_PER_INSERT; nrows <= MAX_ROWS_PER_INSERT; ++nrows)
11916   {
11917     char *query_ptr;
11918     /* Create statement text for current number of rows */
11919     sprintf(query, query_template, param_str);
11920     query_ptr= query + strlen(query);
11921     for (i= 1; i < nrows; ++i)
11922     {
11923       memcpy(query_ptr, ", ", 2);
11924       query_ptr+= 2;
11925       memcpy(query_ptr, param_str, param_str_length);
11926       query_ptr+= param_str_length;
11927     }
11928     *query_ptr= '\0';
11929 
11930     rc= mysql_stmt_prepare(stmt, query, (ulong)(query_ptr - query));
11931     if (rc && nrows * COLUMN_COUNT > uint16_max)
11932     {
11933       if (!opt_silent)
11934         printf("Failed to prepare a statement with %d placeholders "
11935                "(as expected).\n", nrows * COLUMN_COUNT);
11936       break;
11937     }
11938     else
11939       check_execute(stmt, rc);
11940 
11941     if (!opt_silent)
11942       printf("Insert: query length= %d, row count= %d, param count= %lu\n",
11943              (int) strlen(query), nrows, mysql_stmt_param_count(stmt));
11944 
11945     /* bind the parameter array and execute the query */
11946     rc= mysql_stmt_bind_param(stmt, my_bind);
11947     check_execute(stmt, rc);
11948 
11949     rc= mysql_stmt_execute(stmt);
11950     check_execute(stmt, rc);
11951     mysql_stmt_reset(stmt);
11952   }
11953 
11954   mysql_stmt_close(stmt);
11955   free(my_bind);
11956   free(query);
11957   free(param_str);
11958   stmt_text= "drop table t1";
11959   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
11960   myquery(rc);
11961 }
11962 
11963 
test_bug5315()11964 static void test_bug5315()
11965 {
11966   MYSQL_STMT *stmt;
11967   const char *stmt_text;
11968   int rc;
11969 
11970   myheader("test_bug5315");
11971 
11972   stmt_text= "SELECT 1";
11973   stmt= mysql_stmt_init(mysql);
11974   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11975   DIE_UNLESS(rc == 0);
11976   if (!opt_silent)
11977     printf("Executing mysql_change_user\n");
11978   mysql_change_user(mysql, opt_user, opt_password, current_db);
11979   if (!opt_silent)
11980     printf("Executing mysql_stmt_execute\n");
11981   rc= mysql_stmt_execute(stmt);
11982   DIE_UNLESS(rc != 0);
11983   if (rc)
11984   {
11985     if (!opt_silent)
11986       printf("Got error (as expected): '%s'\n", mysql_stmt_error(stmt));
11987   }
11988   /* check that connection is OK */
11989   if (!opt_silent)
11990     printf("Executing mysql_stmt_close\n");
11991   mysql_stmt_close(stmt);
11992   if (!opt_silent)
11993     printf("Executing mysql_stmt_init\n");
11994   stmt= mysql_stmt_init(mysql);
11995   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
11996   DIE_UNLESS(rc == 0);
11997   rc= mysql_stmt_execute(stmt);
11998   DIE_UNLESS(rc == 0);
11999   mysql_stmt_close(stmt);
12000 }
12001 
12002 
test_bug6049()12003 static void test_bug6049()
12004 {
12005   MYSQL_STMT *stmt;
12006   MYSQL_BIND my_bind[1];
12007   MYSQL_RES *res;
12008   MYSQL_ROW row;
12009   const char *stmt_text;
12010   char buffer[30];
12011   ulong length;
12012   int rc;
12013 
12014   myheader("test_bug6049");
12015 
12016   stmt_text= "SELECT MAKETIME(-25, 12, 12)";
12017 
12018   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12019   myquery(rc);
12020   res= mysql_store_result(mysql);
12021   row= mysql_fetch_row(res);
12022 
12023   stmt= mysql_stmt_init(mysql);
12024   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12025   check_execute(stmt, rc);
12026   rc= mysql_stmt_execute(stmt);
12027   check_execute(stmt, rc);
12028 
12029   bzero((char*) my_bind, sizeof(my_bind));
12030   my_bind[0].buffer_type    = MYSQL_TYPE_STRING;
12031   my_bind[0].buffer         = &buffer;
12032   my_bind[0].buffer_length  = sizeof(buffer);
12033   my_bind[0].length         = &length;
12034 
12035   mysql_stmt_bind_result(stmt, my_bind);
12036   rc= mysql_stmt_fetch(stmt);
12037   DIE_UNLESS(rc == 0);
12038 
12039   if (!opt_silent)
12040   {
12041     printf("Result from query: %s\n", row[0]);
12042     printf("Result from prepared statement: %s\n", (char*) buffer);
12043   }
12044 
12045   DIE_UNLESS(strcmp(row[0], (char*) buffer) == 0);
12046 
12047   mysql_free_result(res);
12048   mysql_stmt_close(stmt);
12049 }
12050 
12051 
test_bug6058()12052 static void test_bug6058()
12053 {
12054   MYSQL_STMT *stmt;
12055   MYSQL_BIND my_bind[1];
12056   MYSQL_RES *res;
12057   MYSQL_ROW row;
12058   const char *stmt_text;
12059   char buffer[30];
12060   ulong length;
12061   int rc;
12062 
12063   myheader("test_bug6058");
12064 
12065   rc= mysql_query(mysql, "SET SQL_MODE=''");
12066   myquery(rc);
12067 
12068   stmt_text= "SELECT CAST('0000-00-00' AS DATE)";
12069 
12070   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12071   myquery(rc);
12072   res= mysql_store_result(mysql);
12073   row= mysql_fetch_row(res);
12074 
12075   stmt= mysql_stmt_init(mysql);
12076   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12077   check_execute(stmt, rc);
12078   rc= mysql_stmt_execute(stmt);
12079   check_execute(stmt, rc);
12080 
12081   bzero((char*) my_bind, sizeof(my_bind));
12082   my_bind[0].buffer_type    = MYSQL_TYPE_STRING;
12083   my_bind[0].buffer         = &buffer;
12084   my_bind[0].buffer_length  = sizeof(buffer);
12085   my_bind[0].length         = &length;
12086 
12087   mysql_stmt_bind_result(stmt, my_bind);
12088   rc= mysql_stmt_fetch(stmt);
12089   DIE_UNLESS(rc == 0);
12090 
12091   if (!opt_silent)
12092   {
12093     printf("Result from query: %s\n", row[0]);
12094     printf("Result from prepared statement: %s\n", buffer);
12095   }
12096 
12097   DIE_UNLESS(strcmp(row[0], buffer) == 0);
12098 
12099   mysql_free_result(res);
12100   mysql_stmt_close(stmt);
12101 }
12102 
12103 
test_bug6059()12104 static void test_bug6059()
12105 {
12106   MYSQL_STMT *stmt;
12107   const char *stmt_text;
12108 
12109   myheader("test_bug6059");
12110 
12111   stmt_text= "SELECT 'foo' INTO OUTFILE 'x.3'";
12112 
12113   stmt= mysql_stmt_init(mysql);
12114   (void) mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12115   DIE_UNLESS(mysql_stmt_field_count(stmt) == 0);
12116   mysql_stmt_close(stmt);
12117 }
12118 
12119 
test_bug6046()12120 static void test_bug6046()
12121 {
12122   MYSQL_STMT *stmt;
12123   const char *stmt_text;
12124   int rc;
12125   short b= 1;
12126   MYSQL_BIND my_bind[1];
12127 
12128   myheader("test_bug6046");
12129 
12130   stmt_text= "DROP TABLE IF EXISTS t1";
12131   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12132   myquery(rc);
12133   stmt_text= "CREATE TABLE t1 (a int, b int)";
12134   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12135   myquery(rc);
12136   stmt_text= "INSERT INTO t1 VALUES (1,1),(2,2),(3,1),(4,2)";
12137   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12138   myquery(rc);
12139 
12140   stmt= mysql_stmt_init(mysql);
12141 
12142   stmt_text= "SELECT t1.a FROM t1 NATURAL JOIN t1 as X1 "
12143              "WHERE t1.b > ? ORDER BY t1.a";
12144 
12145   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12146   check_execute(stmt, rc);
12147 
12148   b= 1;
12149   bzero((char*) my_bind, sizeof(my_bind));
12150   my_bind[0].buffer= &b;
12151   my_bind[0].buffer_type= MYSQL_TYPE_SHORT;
12152 
12153   mysql_stmt_bind_param(stmt, my_bind);
12154 
12155   rc= mysql_stmt_execute(stmt);
12156   check_execute(stmt, rc);
12157   mysql_stmt_store_result(stmt);
12158 
12159   rc= mysql_stmt_execute(stmt);
12160   check_execute(stmt, rc);
12161 
12162   mysql_stmt_close(stmt);
12163 }
12164 
12165 
12166 
test_basic_cursors()12167 static void test_basic_cursors()
12168 {
12169   const char *basic_tables[]=
12170   {
12171     "DROP TABLE IF EXISTS t1, t2",
12172 
12173     "CREATE TABLE t1 "
12174     "(id INTEGER NOT NULL PRIMARY KEY, "
12175     " name VARCHAR(20) NOT NULL)",
12176 
12177     "INSERT INTO t1 (id, name) VALUES "
12178     "  (2, 'Ja'), (3, 'Ede'), "
12179     "  (4, 'Haag'), (5, 'Kabul'), "
12180     "  (6, 'Almere'), (7, 'Utrecht'), "
12181     "  (8, 'Qandahar'), (9, 'Amsterdam'), "
12182     "  (10, 'Amersfoort'), (11, 'Constantine')",
12183 
12184     "CREATE TABLE t2 "
12185     "(id INTEGER NOT NULL PRIMARY KEY, "
12186     " name VARCHAR(20) NOT NULL)",
12187 
12188     "INSERT INTO t2 (id, name) VALUES "
12189     "  (4, 'Guam'), (5, 'Aruba'), "
12190     "  (6, 'Angola'), (7, 'Albania'), "
12191     "  (8, 'Anguilla'), (9, 'Argentina'), "
12192     "  (10, 'Azerbaijan'), (11, 'Afghanistan'), "
12193     "  (12, 'Burkina Faso'), (13, 'Faroe Islands')"
12194   };
12195   const char *queries[]=
12196   {
12197     "SELECT * FROM t1",
12198     "SELECT * FROM t2"
12199   };
12200 
12201   DBUG_ENTER("test_basic_cursors");
12202   myheader("test_basic_cursors");
12203 
12204   fill_tables(basic_tables, sizeof(basic_tables)/sizeof(*basic_tables));
12205 
12206   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH);
12207   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT);
12208   DBUG_VOID_RETURN;
12209 }
12210 
12211 
test_cursors_with_union()12212 static void test_cursors_with_union()
12213 {
12214   const char *queries[]=
12215   {
12216     "SELECT t1.name FROM t1 UNION SELECT t2.name FROM t2",
12217     "SELECT t1.id FROM t1 WHERE t1.id < 5"
12218   };
12219   myheader("test_cursors_with_union");
12220   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH);
12221   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT);
12222 }
12223 
12224 
test_cursors_with_procedure()12225 static void test_cursors_with_procedure()
12226 {
12227   const char *queries[]=
12228   {
12229     "SELECT * FROM t1 procedure analyse()"
12230   };
12231   myheader("test_cursors_with_procedure");
12232   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH);
12233   fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT);
12234 }
12235 
12236 
12237 /*
12238   Altough mysql_create_db(), mysql_rm_db() are deprecated since 4.0 they
12239   should not crash server and should not hang in case of errors.
12240 
12241   Since those functions can't be seen in modern API (unless client library
12242   was compiled with USE_OLD_FUNCTIONS define) we use simple_command() macro.
12243 */
test_bug6081()12244 static void test_bug6081()
12245 {
12246   int rc;
12247   myheader("test_bug6081");
12248 
12249   rc= simple_command(mysql, COM_DROP_DB, (uchar*) current_db,
12250                      (ulong)strlen(current_db), 0);
12251   if (rc == 0 && mysql_errno(mysql) != ER_UNKNOWN_COM_ERROR)
12252   {
12253     myerror(NULL);                                   /* purecov: inspected */
12254     die(__FILE__, __LINE__, "COM_DROP_DB failed");   /* purecov: inspected */
12255   }
12256   rc= simple_command(mysql, COM_DROP_DB, (uchar*) current_db,
12257                      (ulong)strlen(current_db), 0);
12258   myquery_r(rc);
12259   rc= simple_command(mysql, COM_CREATE_DB, (uchar*) current_db,
12260                      (ulong)strlen(current_db), 0);
12261   if (rc == 0 && mysql_errno(mysql) != ER_UNKNOWN_COM_ERROR)
12262   {
12263     myerror(NULL);                                   /* purecov: inspected */
12264     die(__FILE__, __LINE__, "COM_CREATE_DB failed"); /* purecov: inspected */
12265   }
12266   rc= simple_command(mysql, COM_CREATE_DB, (uchar*) current_db,
12267                      (ulong)strlen(current_db), 0);
12268   myquery_r(rc);
12269   rc= mysql_select_db(mysql, current_db);
12270   myquery(rc);
12271 }
12272 
12273 
test_bug6096()12274 static void test_bug6096()
12275 {
12276   MYSQL_STMT *stmt;
12277   MYSQL_RES *query_result, *stmt_metadata;
12278   const char *stmt_text;
12279   MYSQL_BIND my_bind[12];
12280   MYSQL_FIELD *query_field_list, *stmt_field_list;
12281   ulong query_field_count, stmt_field_count;
12282   int rc;
12283   my_bool update_max_length= TRUE;
12284   uint i;
12285 
12286   myheader("test_bug6096");
12287 
12288   stmt_text= "drop table if exists t1";
12289   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12290   myquery(rc);
12291 
12292   mysql_query(mysql, "set sql_mode=''");
12293   stmt_text= "create table t1 (c_tinyint tinyint, c_smallint smallint, "
12294                              " c_mediumint mediumint, c_int int, "
12295                              " c_bigint bigint, c_float float, "
12296                              " c_double double, c_varchar varchar(20), "
12297                              " c_char char(20), c_time time, c_date date, "
12298                              " c_datetime datetime)";
12299   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12300   myquery(rc);
12301   stmt_text= "insert into t1  values (-100, -20000, 30000000, 4, 8, 1.0, "
12302                                      "2.0, 'abc', 'def', now(), now(), now())";
12303   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12304   myquery(rc);
12305 
12306   stmt_text= "select * from t1";
12307 
12308   /* Run select in prepared and non-prepared mode and compare metadata */
12309   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12310   myquery(rc);
12311   query_result= mysql_store_result(mysql);
12312   query_field_list= mysql_fetch_fields(query_result);
12313   query_field_count= mysql_num_fields(query_result);
12314 
12315   stmt= mysql_stmt_init(mysql);
12316   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12317   check_execute(stmt, rc);
12318   rc= mysql_stmt_execute(stmt);
12319   check_execute(stmt, rc);
12320   mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH,
12321                       (void*) &update_max_length);
12322   mysql_stmt_store_result(stmt);
12323   stmt_metadata= mysql_stmt_result_metadata(stmt);
12324   stmt_field_list= mysql_fetch_fields(stmt_metadata);
12325   stmt_field_count= mysql_num_fields(stmt_metadata);
12326   DIE_UNLESS(stmt_field_count == query_field_count);
12327 
12328   /* Print out and check the metadata */
12329 
12330   if (!opt_silent)
12331   {
12332     printf(" ------------------------------------------------------------\n");
12333     printf("             |                     Metadata \n");
12334     printf(" ------------------------------------------------------------\n");
12335     printf("             |         Query          |   Prepared statement \n");
12336     printf(" ------------------------------------------------------------\n");
12337     printf(" field name  |  length   | max_length |  length   |  max_length\n");
12338     printf(" ------------------------------------------------------------\n");
12339 
12340     for (i= 0; i < query_field_count; ++i)
12341     {
12342       MYSQL_FIELD *f1= &query_field_list[i], *f2= &stmt_field_list[i];
12343       printf(" %-11s | %9lu | %10lu | %9lu | %10lu \n",
12344              f1->name, f1->length, f1->max_length, f2->length, f2->max_length);
12345       DIE_UNLESS(f1->length == f2->length);
12346     }
12347     printf(" ---------------------------------------------------------------\n");
12348   }
12349 
12350   /* Bind and fetch the data */
12351 
12352   bzero((char*) my_bind, sizeof(my_bind));
12353   for (i= 0; i < stmt_field_count; ++i)
12354   {
12355     my_bind[i].buffer_type= MYSQL_TYPE_STRING;
12356     my_bind[i].buffer_length= stmt_field_list[i].max_length + 1;
12357     my_bind[i].buffer= malloc(my_bind[i].buffer_length);
12358   }
12359   mysql_stmt_bind_result(stmt, my_bind);
12360   rc= mysql_stmt_fetch(stmt);
12361   check_execute(stmt, rc);
12362   rc= mysql_stmt_fetch(stmt);
12363   DIE_UNLESS(rc == MYSQL_NO_DATA);
12364 
12365   /* Clean up */
12366 
12367   for (i= 0; i < stmt_field_count; ++i)
12368     free(my_bind[i].buffer);
12369   mysql_stmt_close(stmt);
12370   mysql_free_result(query_result);
12371   mysql_free_result(stmt_metadata);
12372   stmt_text= "drop table t1";
12373   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12374   myquery(rc);
12375 }
12376 
12377 
12378 /*
12379   Test of basic checks that are performed in server for components
12380   of MYSQL_TIME parameters.
12381 */
12382 
test_datetime_ranges()12383 static void test_datetime_ranges()
12384 {
12385   const char *stmt_text;
12386   int rc, i;
12387   MYSQL_STMT *stmt;
12388   MYSQL_BIND my_bind[6];
12389   MYSQL_TIME tm[6];
12390 
12391   myheader("test_datetime_ranges");
12392 
12393   stmt_text= "drop table if exists t1";
12394   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12395   myquery(rc);
12396 
12397   stmt_text= "create table t1 (year datetime, month datetime, day datetime, "
12398                               "hour datetime, min datetime, sec datetime)";
12399   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12400   myquery(rc);
12401 
12402   stmt= mysql_simple_prepare(mysql,
12403                              "INSERT INTO t1 VALUES (?, ?, ?, ?, ?, ?)");
12404   check_stmt(stmt);
12405   verify_param_count(stmt, 6);
12406 
12407   bzero((char*) my_bind, sizeof(my_bind));
12408   for (i= 0; i < 6; i++)
12409   {
12410     my_bind[i].buffer_type= MYSQL_TYPE_DATETIME;
12411     my_bind[i].buffer= &tm[i];
12412   }
12413   rc= mysql_stmt_bind_param(stmt, my_bind);
12414   check_execute(stmt, rc);
12415 
12416   tm[0].year= 2004; tm[0].month= 11; tm[0].day= 10;
12417   tm[0].hour= 12; tm[0].minute= 30; tm[0].second= 30;
12418   tm[0].second_part= 0; tm[0].neg= 0;
12419 
12420   tm[5]= tm[4]= tm[3]= tm[2]= tm[1]= tm[0];
12421   tm[0].year= 10000;  tm[1].month= 13; tm[2].day= 32;
12422   tm[3].hour= 24; tm[4].minute= 60; tm[5].second= 60;
12423 
12424   rc= mysql_stmt_execute(stmt);
12425   check_execute(stmt, rc);
12426   my_process_warnings(mysql, 6);
12427 
12428   verify_col_data("t1", "year", "0000-00-00 00:00:00");
12429   verify_col_data("t1", "month", "0000-00-00 00:00:00");
12430   verify_col_data("t1", "day", "0000-00-00 00:00:00");
12431   verify_col_data("t1", "hour", "0000-00-00 00:00:00");
12432   verify_col_data("t1", "min", "0000-00-00 00:00:00");
12433   verify_col_data("t1", "sec", "0000-00-00 00:00:00");
12434 
12435   mysql_stmt_close(stmt);
12436 
12437   stmt_text= "delete from t1";
12438   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12439   myquery(rc);
12440 
12441   stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 (year, month, day) "
12442                                     "VALUES (?, ?, ?)");
12443   check_stmt(stmt);
12444   verify_param_count(stmt, 3);
12445 
12446   /*
12447     We reuse contents of bind and tm arrays left from previous part of test.
12448   */
12449   for (i= 0; i < 3; i++)
12450     my_bind[i].buffer_type= MYSQL_TYPE_DATE;
12451 
12452   rc= mysql_stmt_bind_param(stmt, my_bind);
12453   check_execute(stmt, rc);
12454 
12455   rc= mysql_stmt_execute(stmt);
12456   check_execute(stmt, rc);
12457   my_process_warnings(mysql, 3);
12458 
12459   verify_col_data("t1", "year", "0000-00-00 00:00:00");
12460   verify_col_data("t1", "month", "0000-00-00 00:00:00");
12461   verify_col_data("t1", "day", "0000-00-00 00:00:00");
12462 
12463   mysql_stmt_close(stmt);
12464 
12465   stmt_text= "drop table t1";
12466   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12467   myquery(rc);
12468 
12469   stmt_text= "create table t1 (day_ovfl time, day time, hour time, min time, sec time)";
12470   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12471   myquery(rc);
12472 
12473   stmt= mysql_simple_prepare(mysql,
12474                              "INSERT INTO t1 VALUES (?, ?, ?, ?, ?)");
12475   check_stmt(stmt);
12476   verify_param_count(stmt, 5);
12477 
12478   /*
12479     Again we reuse what we can from previous part of test.
12480   */
12481   for (i= 0; i < 5; i++)
12482     my_bind[i].buffer_type= MYSQL_TYPE_TIME;
12483 
12484   rc= mysql_stmt_bind_param(stmt, my_bind);
12485   check_execute(stmt, rc);
12486 
12487   tm[0].year= 0; tm[0].month= 0; tm[0].day= 10;
12488   tm[0].hour= 12; tm[0].minute= 30; tm[0].second= 30;
12489   tm[0].second_part= 0; tm[0].neg= 0;
12490 
12491   tm[4]= tm[3]= tm[2]= tm[1]= tm[0];
12492   tm[0].day= 35; tm[1].day= 34; tm[2].hour= 30; tm[3].minute= 60; tm[4].second= 60;
12493 
12494   rc= mysql_stmt_execute(stmt);
12495   check_execute(stmt, rc);
12496   my_process_warnings(mysql, 2);
12497 
12498   verify_col_data("t1", "day_ovfl", "838:59:59");
12499   verify_col_data("t1", "day", "828:30:30");
12500   verify_col_data("t1", "hour", "270:30:30");
12501   verify_col_data("t1", "min", "00:00:00");
12502   verify_col_data("t1", "sec", "00:00:00");
12503 
12504   mysql_stmt_close(stmt);
12505 
12506   stmt_text= "drop table t1";
12507   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12508   myquery(rc);
12509 }
12510 
12511 
12512 /*
12513   This test is used in:
12514   mysql-test/suite/binlog/binlog_stm_datetime_ranges_mdev15289.test
12515 */
test_datetime_ranges_mdev15289()12516 static void test_datetime_ranges_mdev15289()
12517 {
12518   const char *stmt_text;
12519   int rc, i;
12520   MYSQL_STMT *stmt;
12521   MYSQL_BIND my_bind[4];
12522   MYSQL_TIME tm[4];
12523 
12524   myheader("test_datetime_ranges_mdev15289");
12525 
12526   stmt_text= "SET sql_mode=''";
12527   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12528   myquery(rc);
12529 
12530   stmt_text= "create or replace table t1 "
12531              "(t time, d date, dt datetime,ts timestamp)";
12532   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12533   myquery(rc);
12534 
12535   stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 VALUES (?, ?, ?, ?)");
12536   check_stmt(stmt);
12537   verify_param_count(stmt, 4);
12538 
12539   /*** Testing DATETIME ***/
12540   bzero((char*) my_bind, sizeof(my_bind));
12541   for (i= 0; i < 4; i++)
12542   {
12543     my_bind[i].buffer_type= MYSQL_TYPE_DATETIME;
12544     my_bind[i].buffer= &tm[i];
12545   }
12546   rc= mysql_stmt_bind_param(stmt, my_bind);
12547   check_execute(stmt, rc);
12548 
12549   /* Notice bad year */
12550   tm[0].year= 20010; tm[0].month= 1; tm[0].day= 2;
12551   tm[0].hour= 03; tm[0].minute= 04; tm[0].second= 05;
12552   tm[0].second_part= 0; tm[0].neg= 0;
12553   tm[0].time_type= MYSQL_TIMESTAMP_DATETIME;
12554   tm[3]= tm[2]= tm[1]= tm[0];
12555 
12556   rc= mysql_stmt_execute(stmt);
12557   check_execute(stmt, rc);
12558   my_process_warnings(mysql, 4);
12559 
12560   verify_col_data("t1", "t", "00:00:00");
12561   verify_col_data("t1", "d", "0000-00-00");
12562   verify_col_data("t1", "dt", "0000-00-00 00:00:00");
12563   verify_col_data("t1", "ts", "0000-00-00 00:00:00");
12564 
12565   /*** Testing DATE ***/
12566   bzero((char*) my_bind, sizeof(my_bind));
12567   for (i= 0; i < 4; i++)
12568   {
12569     my_bind[i].buffer_type= MYSQL_TYPE_DATE;
12570     my_bind[i].buffer= &tm[i];
12571   }
12572   rc= mysql_stmt_bind_param(stmt, my_bind);
12573   check_execute(stmt, rc);
12574 
12575   /* Notice bad year */
12576   tm[0].year= 20010; tm[0].month= 1; tm[0].day= 2;
12577   tm[0].hour= 00; tm[0].minute= 00; tm[0].second= 00;
12578   tm[0].second_part= 0; tm[0].neg= 0;
12579   tm[0].time_type= MYSQL_TIMESTAMP_DATE;
12580   tm[3]= tm[2]= tm[1]= tm[0];
12581 
12582   rc= mysql_stmt_execute(stmt);
12583   check_execute(stmt, rc);
12584   my_process_warnings(mysql, 4);
12585 
12586   verify_col_data("t1", "t", "00:00:00");
12587   verify_col_data("t1", "d", "0000-00-00");
12588   verify_col_data("t1", "dt", "0000-00-00 00:00:00");
12589   verify_col_data("t1", "ts", "0000-00-00 00:00:00");
12590 
12591   /*** Testing TIME ***/
12592   bzero((char*) my_bind, sizeof(my_bind));
12593   for (i= 0; i < 4; i++)
12594   {
12595     my_bind[i].buffer_type= MYSQL_TYPE_TIME;
12596     my_bind[i].buffer= &tm[i];
12597   }
12598   rc= mysql_stmt_bind_param(stmt, my_bind);
12599   check_execute(stmt, rc);
12600 
12601   /* Notice bad hour */
12602   tm[0].year= 0; tm[0].month= 0; tm[0].day= 0;
12603   tm[0].hour= 100; tm[0].minute= 64; tm[0].second= 05;
12604   tm[0].second_part= 0; tm[0].neg= 0;
12605   tm[0].time_type= MYSQL_TIMESTAMP_TIME;
12606   tm[3]= tm[2]= tm[1]= tm[0];
12607 
12608   rc= mysql_stmt_execute(stmt);
12609   check_execute(stmt, rc);
12610   my_process_warnings(mysql, 4);
12611 
12612   verify_col_data("t1", "t", "00:00:00");
12613   verify_col_data("t1", "d", "0000-00-00");
12614   verify_col_data("t1", "dt", "0000-00-00 00:00:00");
12615   verify_col_data("t1", "ts", "0000-00-00 00:00:00");
12616 
12617   mysql_stmt_close(stmt);
12618 
12619   stmt_text= "drop table t1";
12620   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12621   myquery(rc);
12622 }
12623 
12624 
test_bug4172()12625 static void test_bug4172()
12626 {
12627   MYSQL_STMT *stmt;
12628   MYSQL_BIND my_bind[3];
12629   const char *stmt_text;
12630   MYSQL_RES *res;
12631   MYSQL_ROW row;
12632   int rc;
12633   char f[100], d[100], e[100];
12634   ulong f_len, d_len, e_len;
12635 
12636   myheader("test_bug4172");
12637 
12638   mysql_query(mysql, "DROP TABLE IF EXISTS t1");
12639   mysql_query(mysql, "CREATE TABLE t1 (f float, d double, e decimal(10,4))");
12640   mysql_query(mysql, "INSERT INTO t1 VALUES (12345.1234, 123456.123456, "
12641                                             "123456.1234)");
12642 
12643   stmt= mysql_stmt_init(mysql);
12644   stmt_text= "SELECT f, d, e FROM t1";
12645 
12646   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12647   check_execute(stmt, rc);
12648   rc= mysql_stmt_execute(stmt);
12649   check_execute(stmt, rc);
12650 
12651   bzero((char*) my_bind, sizeof(my_bind));
12652   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
12653   my_bind[0].buffer= f;
12654   my_bind[0].buffer_length= sizeof(f);
12655   my_bind[0].length= &f_len;
12656   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
12657   my_bind[1].buffer= d;
12658   my_bind[1].buffer_length= sizeof(d);
12659   my_bind[1].length= &d_len;
12660   my_bind[2].buffer_type= MYSQL_TYPE_STRING;
12661   my_bind[2].buffer= e;
12662   my_bind[2].buffer_length= sizeof(e);
12663   my_bind[2].length= &e_len;
12664 
12665   mysql_stmt_bind_result(stmt, my_bind);
12666 
12667   mysql_stmt_store_result(stmt);
12668   rc= mysql_stmt_fetch(stmt);
12669   check_execute(stmt, rc);
12670 
12671   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12672   myquery(rc);
12673   res= mysql_store_result(mysql);
12674   row= mysql_fetch_row(res);
12675 
12676   if (!opt_silent)
12677   {
12678     printf("Binary protocol: float=%s, double=%s, decimal(10,4)=%s\n",
12679            f, d, e);
12680     printf("Text protocol:   float=%s, double=%s, decimal(10,4)=%s\n",
12681            row[0], row[1], row[2]);
12682   }
12683   DIE_UNLESS(!strcmp(f, row[0]) && !strcmp(d, row[1]) && !strcmp(e, row[2]));
12684 
12685   mysql_free_result(res);
12686   mysql_stmt_close(stmt);
12687 }
12688 
12689 
test_conversion()12690 static void test_conversion()
12691 {
12692   MYSQL_STMT *stmt;
12693   const char *stmt_text;
12694   int rc;
12695   MYSQL_BIND my_bind[1];
12696   uchar buff[4];
12697   ulong length;
12698 
12699   myheader("test_conversion");
12700 
12701   stmt_text= "DROP TABLE IF EXISTS t1";
12702   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12703   myquery(rc);
12704   stmt_text= "CREATE TABLE t1 (a TEXT) DEFAULT CHARSET latin1";
12705   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12706   myquery(rc);
12707   stmt_text= "SET character_set_connection=utf8, character_set_client=utf8, "
12708              " character_set_results=latin1";
12709   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12710   myquery(rc);
12711 
12712   stmt= mysql_stmt_init(mysql);
12713 
12714   stmt_text= "INSERT INTO t1 (a) VALUES (?)";
12715   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12716   check_execute(stmt, rc);
12717 
12718   bzero((char*) my_bind, sizeof(my_bind));
12719   my_bind[0].buffer= (char*) buff;
12720   my_bind[0].length= &length;
12721   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
12722 
12723   mysql_stmt_bind_param(stmt, my_bind);
12724 
12725   buff[0]= (uchar) 0xC3;
12726   buff[1]= (uchar) 0xA0;
12727   length= 2;
12728 
12729   rc= mysql_stmt_execute(stmt);
12730   check_execute(stmt, rc);
12731 
12732   stmt_text= "SELECT a FROM t1";
12733   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12734   check_execute(stmt, rc);
12735   rc= mysql_stmt_execute(stmt);
12736   check_execute(stmt, rc);
12737 
12738   my_bind[0].buffer_length= sizeof(buff);
12739   mysql_stmt_bind_result(stmt, my_bind);
12740 
12741   rc= mysql_stmt_fetch(stmt);
12742   DIE_UNLESS(rc == 0);
12743   DIE_UNLESS(length == 1);
12744   DIE_UNLESS(buff[0] == 0xE0);
12745   rc= mysql_stmt_fetch(stmt);
12746   DIE_UNLESS(rc == MYSQL_NO_DATA);
12747 
12748   mysql_stmt_close(stmt);
12749   stmt_text= "DROP TABLE t1";
12750   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12751   myquery(rc);
12752   stmt_text= "SET NAMES DEFAULT";
12753   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12754   myquery(rc);
12755 }
12756 
test_rewind(void)12757 static void test_rewind(void)
12758 {
12759   MYSQL_STMT *stmt;
12760   MYSQL_BIND my_bind;
12761   int rc = 0;
12762   const char *stmt_text;
12763   long unsigned int length=4, Data=0;
12764   my_bool isnull=0;
12765 
12766   myheader("test_rewind");
12767 
12768   stmt_text= "CREATE TABLE t1 (a int)";
12769   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12770   myquery(rc);
12771   stmt_text= "INSERT INTO t1 VALUES(2),(3),(4)";
12772   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12773   myquery(rc);
12774 
12775   stmt= mysql_stmt_init(mysql);
12776 
12777   stmt_text= "SELECT * FROM t1";
12778   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12779   check_execute(stmt, rc);
12780 
12781   bzero((char*) &my_bind, sizeof(MYSQL_BIND));
12782   my_bind.buffer_type= MYSQL_TYPE_LONG;
12783   my_bind.buffer= (void *)&Data; /* this buffer won't be altered */
12784   my_bind.length= &length;
12785   my_bind.is_null= &isnull;
12786 
12787   rc= mysql_stmt_execute(stmt);
12788   check_execute(stmt, rc);
12789 
12790   rc= mysql_stmt_store_result(stmt);
12791   DIE_UNLESS(rc == 0);
12792 
12793   rc= mysql_stmt_bind_result(stmt, &my_bind);
12794   DIE_UNLESS(rc == 0);
12795 
12796   /* retreive all result sets till we are at the end */
12797   while(!mysql_stmt_fetch(stmt))
12798     if (!opt_silent)
12799       printf("fetched result:%ld\n", Data);
12800 
12801   DIE_UNLESS(rc != MYSQL_NO_DATA);
12802 
12803   /* seek to the first row */
12804   mysql_stmt_data_seek(stmt, 0);
12805 
12806   /* now we should be able to fetch the results again */
12807   /* but mysql_stmt_fetch returns MYSQL_NO_DATA */
12808   while(!(rc= mysql_stmt_fetch(stmt)))
12809     if (!opt_silent)
12810       printf("fetched result after seek:%ld\n", Data);
12811 
12812   DIE_UNLESS(rc == MYSQL_NO_DATA);
12813 
12814   stmt_text= "DROP TABLE t1";
12815   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12816   myquery(rc);
12817   rc= mysql_stmt_free_result(stmt);
12818   rc= mysql_stmt_close(stmt);
12819 }
12820 
12821 
test_truncation()12822 static void test_truncation()
12823 {
12824   MYSQL_STMT *stmt;
12825   const char *stmt_text;
12826   int rc;
12827   uint bind_count;
12828   MYSQL_BIND *bind_array, *my_bind;
12829 
12830   myheader("test_truncation");
12831 
12832   /* Prepare the test table */
12833   rc= mysql_query(mysql, "drop table if exists t1");
12834   myquery(rc);
12835 
12836   stmt_text= "create table t1 ("
12837              "i8 tinyint, ui8 tinyint unsigned, "
12838              "i16 smallint, i16_1 smallint, "
12839              "ui16 smallint unsigned, i32 int, i32_1 int, "
12840              "d double, d_1 double, ch char(30), ch_1 char(30), "
12841              "tx text, tx_1 text, ch_2 char(30) "
12842              ")";
12843   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
12844   myquery(rc);
12845 
12846   {
12847     const char insert_text[]=
12848              "insert into t1 VALUES ("
12849              "-10, "                            /* i8 */
12850              "200, "                            /* ui8 */
12851              "32000, "                          /* i16 */
12852              "-32767, "                         /* i16_1 */
12853              "64000, "                          /* ui16 */
12854              "1073741824, "                     /* i32 */
12855              "1073741825, "                     /* i32_1 */
12856              "123.456, "                        /* d */
12857              "-12345678910, "                   /* d_1 */
12858              "'111111111111111111111111111111',"/* ch */
12859              "'abcdef', "                       /* ch_1 */
12860              "'12345 	      ', "              /* tx */
12861              "'12345.67 	      ', "      /* tx_1 */
12862              "'12345.67abc'"                    /* ch_2 */
12863              ")";
12864     rc= mysql_real_query(mysql, insert_text, strlen(insert_text));
12865     myquery(rc);
12866   }
12867 
12868   stmt_text= "select i8 c1, i8 c2, ui8 c3, i16_1 c4, ui16 c5, "
12869              "       i16 c6, ui16 c7, i32 c8, i32_1 c9, i32_1 c10, "
12870              "       d c11, d_1 c12, d_1 c13, ch c14, ch_1 c15, tx c16, "
12871              "       tx_1 c17, ch_2 c18 "
12872              "from t1";
12873 
12874   stmt= mysql_stmt_init(mysql);
12875   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
12876   check_execute(stmt, rc);
12877   rc= mysql_stmt_execute(stmt);
12878   check_execute(stmt, rc);
12879   bind_count= (uint) mysql_stmt_field_count(stmt);
12880 
12881   /*************** Fill in the bind structure and bind it **************/
12882   bind_array= malloc(sizeof(MYSQL_BIND) * bind_count);
12883   bzero((char*) bind_array, sizeof(MYSQL_BIND) * bind_count);
12884   for (my_bind= bind_array; my_bind < bind_array + bind_count; my_bind++)
12885     my_bind->error= &my_bind->error_value;
12886   my_bind= bind_array;
12887 
12888   my_bind->buffer= malloc(sizeof(uint8));
12889   my_bind->buffer_type= MYSQL_TYPE_TINY;
12890   my_bind->is_unsigned= TRUE;
12891 
12892   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12893   my_bind->buffer= malloc(sizeof(uint32));
12894   my_bind->buffer_type= MYSQL_TYPE_LONG;
12895   my_bind->is_unsigned= TRUE;
12896 
12897   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12898   my_bind->buffer= malloc(sizeof(int8));
12899   my_bind->buffer_type= MYSQL_TYPE_TINY;
12900 
12901   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12902   my_bind->buffer= malloc(sizeof(uint16));
12903   my_bind->buffer_type= MYSQL_TYPE_SHORT;
12904   my_bind->is_unsigned= TRUE;
12905 
12906   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12907   my_bind->buffer= malloc(sizeof(int16));
12908   my_bind->buffer_type= MYSQL_TYPE_SHORT;
12909 
12910   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12911   my_bind->buffer= malloc(sizeof(uint16));
12912   my_bind->buffer_type= MYSQL_TYPE_SHORT;
12913   my_bind->is_unsigned= TRUE;
12914 
12915   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12916   my_bind->buffer= malloc(sizeof(int8));
12917   my_bind->buffer_type= MYSQL_TYPE_TINY;
12918   my_bind->is_unsigned= TRUE;
12919 
12920   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12921   my_bind->buffer= malloc(sizeof(float));
12922   my_bind->buffer_type= MYSQL_TYPE_FLOAT;
12923 
12924   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12925   my_bind->buffer= malloc(sizeof(float));
12926   my_bind->buffer_type= MYSQL_TYPE_FLOAT;
12927 
12928   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12929   my_bind->buffer= malloc(sizeof(double));
12930   my_bind->buffer_type= MYSQL_TYPE_DOUBLE;
12931 
12932   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12933   my_bind->buffer= malloc(sizeof(longlong));
12934   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12935 
12936   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12937   my_bind->buffer= malloc(sizeof(ulonglong));
12938   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12939   my_bind->is_unsigned= TRUE;
12940 
12941   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12942   my_bind->buffer= malloc(sizeof(longlong));
12943   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12944 
12945   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12946   my_bind->buffer= malloc(sizeof(longlong));
12947   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12948 
12949   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12950   my_bind->buffer= malloc(sizeof(longlong));
12951   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12952 
12953   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12954   my_bind->buffer= malloc(sizeof(longlong));
12955   my_bind->buffer_type= MYSQL_TYPE_LONGLONG;
12956 
12957   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12958   my_bind->buffer= malloc(sizeof(double));
12959   my_bind->buffer_type= MYSQL_TYPE_DOUBLE;
12960 
12961   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12962   my_bind->buffer= malloc(sizeof(double));
12963   my_bind->buffer_type= MYSQL_TYPE_DOUBLE;
12964 
12965   rc= mysql_stmt_bind_result(stmt, bind_array);
12966   check_execute(stmt, rc);
12967   rc= mysql_stmt_fetch(stmt);
12968   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
12969 
12970   /*************** Verify truncation results ***************************/
12971   my_bind= bind_array;
12972 
12973   /* signed tiny -> tiny */
12974   DIE_UNLESS(*my_bind->error && * (int8*) my_bind->buffer == -10);
12975 
12976   /* signed tiny -> uint32 */
12977   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12978   DIE_UNLESS(*my_bind->error && * (int32*) my_bind->buffer == -10);
12979 
12980   /* unsigned tiny -> tiny */
12981   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12982   DIE_UNLESS(*my_bind->error && * (uint8*) my_bind->buffer == 200);
12983 
12984   /* short -> ushort */
12985   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12986   DIE_UNLESS(*my_bind->error && * (int16*) my_bind->buffer == -32767);
12987 
12988   /* ushort -> short */
12989   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12990   DIE_UNLESS(*my_bind->error && * (uint16*) my_bind->buffer == 64000);
12991 
12992   /* short -> ushort (no truncation, data is in the range of target type) */
12993   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12994   DIE_UNLESS(! *my_bind->error && * (uint16*) my_bind->buffer == 32000);
12995 
12996   /* ushort -> utiny */
12997   DIE_UNLESS(my_bind++ < bind_array + bind_count);
12998   DIE_UNLESS(*my_bind->error && * (int8*) my_bind->buffer == 0);
12999 
13000   /* int -> float: no truncation, the number is a power of two */
13001   DIE_UNLESS(my_bind++ < bind_array + bind_count);
13002   DIE_UNLESS(! *my_bind->error && * (float*) my_bind->buffer == 1073741824);
13003 
13004   /* int -> float: truncation, not enough bits in float */
13005   DIE_UNLESS(my_bind++ < bind_array + bind_count);
13006   DIE_UNLESS(*my_bind->error);
13007 
13008   /* int -> double: no truncation */
13009   DIE_UNLESS(my_bind++ < bind_array + bind_count);
13010   DIE_UNLESS(! *my_bind->error && * (double*) my_bind->buffer == 1073741825);
13011 
13012   /* double -> longlong: fractional part is lost */
13013   DIE_UNLESS(my_bind++ < bind_array + bind_count);
13014 
13015   /* double -> ulonglong, negative fp number to unsigned integer */
13016   DIE_UNLESS(my_bind++ < bind_array + bind_count);
13017   /* Value in the buffer is not defined: don't test it */
13018   DIE_UNLESS(*my_bind->error);
13019 
13020   /* double -> longlong, negative fp number to signed integer: no loss */
13021   DIE_UNLESS(my_bind++ < bind_array + bind_count);
13022   DIE_UNLESS(! *my_bind->error && * (longlong*) my_bind->buffer == -12345678910LL);
13023 
13024   /* big numeric string -> number */
13025   DIE_UNLESS(my_bind++ < bind_array + bind_count);
13026   DIE_UNLESS(*my_bind->error);
13027 
13028   /* junk string -> number */
13029   DIE_UNLESS(my_bind++ < bind_array + bind_count);
13030   DIE_UNLESS(*my_bind->error && *(longlong*) my_bind->buffer == 0);
13031 
13032   /* string with trailing spaces -> number */
13033   DIE_UNLESS(my_bind++ < bind_array + bind_count);
13034   DIE_UNLESS(! *my_bind->error && *(longlong*) my_bind->buffer == 12345);
13035 
13036   /* string with trailing spaces -> double */
13037   DIE_UNLESS(my_bind++ < bind_array + bind_count);
13038   DIE_UNLESS(! *my_bind->error && *(double*) my_bind->buffer == 12345.67);
13039 
13040   /* string with trailing junk -> double */
13041   DIE_UNLESS(my_bind++ < bind_array + bind_count);
13042   /*
13043     XXX: There must be a truncation error: but it's not the way the server
13044     behaves, so let's leave it for now.
13045   */
13046   DIE_UNLESS(*(double*) my_bind->buffer == 12345.67);
13047   /*
13048     TODO: string -> double,  double -> time, double -> string (truncation
13049           errors are not supported here yet)
13050           longlong -> time/date/datetime
13051           date -> time, date -> timestamp, date -> number
13052           time -> string, time -> date, time -> timestamp,
13053           number -> date string -> date
13054   */
13055   /*************** Cleanup *********************************************/
13056 
13057   mysql_stmt_close(stmt);
13058 
13059   for (my_bind= bind_array; my_bind < bind_array + bind_count; my_bind++)
13060     free(my_bind->buffer);
13061   free(bind_array);
13062 
13063   rc= mysql_query(mysql, "drop table t1");
13064   myquery(rc);
13065 }
13066 
test_truncation_option()13067 static void test_truncation_option()
13068 {
13069   MYSQL_STMT *stmt;
13070   const char *stmt_text;
13071   int rc;
13072   uint8 buf;
13073   my_bool option= 0;
13074   my_bool error;
13075   MYSQL_BIND my_bind;
13076 
13077   myheader("test_truncation_option");
13078 
13079   /* Prepare the test table */
13080   stmt_text= "select -1";
13081 
13082   stmt= mysql_stmt_init(mysql);
13083   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13084   check_execute(stmt, rc);
13085   rc= mysql_stmt_execute(stmt);
13086   check_execute(stmt, rc);
13087 
13088   bzero((char*) &my_bind, sizeof(my_bind));
13089 
13090   my_bind.buffer= (void*) &buf;
13091   my_bind.buffer_type= MYSQL_TYPE_TINY;
13092   my_bind.is_unsigned= TRUE;
13093   my_bind.error= &error;
13094 
13095   rc= mysql_stmt_bind_result(stmt, &my_bind);
13096   check_execute(stmt, rc);
13097   rc= mysql_stmt_fetch(stmt);
13098   DIE_UNLESS(rc == MYSQL_DATA_TRUNCATED);
13099   DIE_UNLESS(error);
13100   rc= mysql_options(mysql, MYSQL_REPORT_DATA_TRUNCATION, (char*) &option);
13101   myquery(rc);
13102   /* need to rebind for the new setting to take effect */
13103   rc= mysql_stmt_bind_result(stmt, &my_bind);
13104   check_execute(stmt, rc);
13105   rc= mysql_stmt_execute(stmt);
13106   check_execute(stmt, rc);
13107   rc= mysql_stmt_fetch(stmt);
13108   check_execute(stmt, rc);
13109   /* The only change is rc - error pointers are still filled in */
13110   DIE_UNLESS(error == 1);
13111   /* restore back the defaults */
13112   option= 1;
13113   mysql_options(mysql, MYSQL_REPORT_DATA_TRUNCATION, (char*) &option);
13114 
13115   mysql_stmt_close(stmt);
13116 }
13117 
13118 
13119 /* Bug#6761 - mysql_list_fields doesn't work */
13120 
test_bug6761(void)13121 static void test_bug6761(void)
13122 {
13123   const char *stmt_text;
13124   MYSQL_RES *res;
13125   int rc;
13126   myheader("test_bug6761");
13127 
13128   stmt_text= "CREATE TABLE t1 (a int, b char(255), c decimal)";
13129   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13130   myquery(rc);
13131 
13132   res= mysql_list_fields(mysql, "t1", "%");
13133   DIE_UNLESS(res && mysql_num_fields(res) == 3);
13134   mysql_free_result(res);
13135 
13136   stmt_text= "DROP TABLE t1";
13137   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13138   myquery(rc);
13139 }
13140 
13141 
13142 /* Bug#8330 - mysql_stmt_execute crashes (libmysql) */
13143 
test_bug8330()13144 static void test_bug8330()
13145 {
13146   const char *stmt_text;
13147   MYSQL_STMT *stmt[2];
13148   int i, rc;
13149   const char *query= "select a,b from t1 where a=?";
13150   MYSQL_BIND my_bind[2];
13151   long lval[2];
13152 
13153   myheader("test_bug8330");
13154 
13155   stmt_text= "drop table if exists t1";
13156   /* in case some previos test failed */
13157   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13158   myquery(rc);
13159   stmt_text= "create table t1 (a int, b int)";
13160   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13161   myquery(rc);
13162 
13163   bzero((char*) my_bind, sizeof(my_bind));
13164   for (i=0; i < 2; i++)
13165   {
13166     stmt[i]= mysql_stmt_init(mysql);
13167     rc= mysql_stmt_prepare(stmt[i], query, strlen(query));
13168     check_execute(stmt[i], rc);
13169 
13170     my_bind[i].buffer_type= MYSQL_TYPE_LONG;
13171     my_bind[i].buffer= (void*) &lval[i];
13172     my_bind[i].is_null= 0;
13173     mysql_stmt_bind_param(stmt[i], &my_bind[i]);
13174   }
13175 
13176   rc= mysql_stmt_execute(stmt[0]);
13177   check_execute(stmt[0], rc);
13178 
13179   rc= mysql_stmt_execute(stmt[1]);
13180   DIE_UNLESS(rc && mysql_stmt_errno(stmt[1]) == CR_COMMANDS_OUT_OF_SYNC);
13181   rc= mysql_stmt_execute(stmt[0]);
13182   check_execute(stmt[0], rc);
13183 
13184   mysql_stmt_close(stmt[0]);
13185   mysql_stmt_close(stmt[1]);
13186 
13187   stmt_text= "drop table t1";
13188   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13189   myquery(rc);
13190 }
13191 
13192 
13193 /* Bug#7990 - mysql_stmt_close doesn't reset mysql->net.last_error */
13194 
test_bug7990()13195 static void test_bug7990()
13196 {
13197   MYSQL_STMT *stmt;
13198   int rc;
13199   myheader("test_bug7990");
13200 
13201   stmt= mysql_stmt_init(mysql);
13202   rc= mysql_stmt_prepare(stmt, "foo", 3);
13203   /*
13204     XXX: the fact that we store errno both in STMT and in
13205     MYSQL is not documented and is subject to change in 5.0
13206   */
13207   DIE_UNLESS(rc && mysql_stmt_errno(stmt) && mysql_errno(mysql));
13208   mysql_stmt_close(stmt);
13209   DIE_UNLESS(!mysql_errno(mysql));
13210 }
13211 
13212 /*
13213   Bug #15518 - Reusing a stmt that has failed during prepare
13214   does not clear error
13215 */
13216 
test_bug15518()13217 static void test_bug15518()
13218 {
13219   MYSQL_STMT *stmt;
13220   MYSQL* mysql1;
13221   int rc;
13222   myheader("test_bug15518");
13223 
13224   mysql1= mysql_client_init(NULL);
13225 
13226   if (!mysql_real_connect(mysql1, opt_host, opt_user, opt_password,
13227                           opt_db ? opt_db : "test", opt_port, opt_unix_socket,
13228                           CLIENT_MULTI_STATEMENTS))
13229   {
13230     fprintf(stderr, "Failed to connect to the database\n");
13231     DIE_UNLESS(0);
13232   }
13233 
13234   stmt= mysql_stmt_init(mysql1);
13235 
13236   /*
13237     The prepare of foo should fail with errno 1064 since
13238     it's not a valid query
13239   */
13240   rc= mysql_stmt_prepare(stmt, "foo", 3);
13241   if (!opt_silent)
13242     fprintf(stdout, "rc: %d, mysql_stmt_errno: %d, mysql_errno: %d\n",
13243             rc, mysql_stmt_errno(stmt), mysql_errno(mysql1));
13244   DIE_UNLESS(rc && mysql_stmt_errno(stmt) && mysql_errno(mysql1));
13245 
13246   /*
13247     Use the same stmt and reprepare with another query that
13248     suceeds
13249   */
13250   rc= mysql_stmt_prepare(stmt, "SHOW STATUS", 12);
13251   if (!opt_silent)
13252     fprintf(stdout, "rc: %d, mysql_stmt_errno: %d, mysql_errno: %d\n",
13253             rc, mysql_stmt_errno(stmt), mysql_errno(mysql1));
13254   DIE_UNLESS(!rc || mysql_stmt_errno(stmt) || mysql_errno(mysql1));
13255 
13256   mysql_stmt_close(stmt);
13257   DIE_UNLESS(!mysql_errno(mysql1));
13258 
13259   /*
13260     part2, when connection to server has been closed
13261     after first prepare
13262   */
13263   stmt= mysql_stmt_init(mysql1);
13264   rc= mysql_stmt_prepare(stmt, "foo", 3);
13265   if (!opt_silent)
13266     fprintf(stdout, "rc: %d, mysql_stmt_errno: %d, mysql_errno: %d\n",
13267             rc, mysql_stmt_errno(stmt), mysql_errno(mysql1));
13268   DIE_UNLESS(rc && mysql_stmt_errno(stmt) && mysql_errno(mysql1));
13269 
13270   /* Close connection to server */
13271   mysql_close(mysql1);
13272 
13273   /*
13274     Use the same stmt and reprepare with another query that
13275     suceeds. The prepare should fail with error 2013 since
13276     connection to server has been closed.
13277   */
13278   rc= mysql_stmt_prepare(stmt, "SHOW STATUS", 12);
13279   if (!opt_silent)
13280     fprintf(stdout, "rc: %d, mysql_stmt_errno: %d\n",
13281             rc, mysql_stmt_errno(stmt));
13282   DIE_UNLESS(rc && mysql_stmt_errno(stmt));
13283 
13284   mysql_stmt_close(stmt);
13285 }
13286 
13287 
disable_query_logs()13288 static void disable_query_logs()
13289 {
13290   int rc;
13291   rc= mysql_query(mysql, "set @@global.general_log=off");
13292   myquery(rc);
13293   rc= mysql_query(mysql, "set @@global.slow_query_log=off");
13294   myquery(rc);
13295 }
13296 
13297 
enable_query_logs(int truncate)13298 static void enable_query_logs(int truncate)
13299 {
13300   int rc;
13301 
13302   rc= mysql_query(mysql, "set @save_global_general_log=@@global.general_log");
13303   myquery(rc);
13304 
13305   rc= mysql_query(mysql, "set @save_global_slow_query_log=@@global.slow_query_log");
13306   myquery(rc);
13307 
13308   rc= mysql_query(mysql, "set @@global.general_log=on");
13309   myquery(rc);
13310 
13311   rc= mysql_query(mysql, "set @@global.slow_query_log=on");
13312   myquery(rc);
13313 
13314 
13315   if (truncate)
13316   {
13317     rc= mysql_query(mysql, "truncate mysql.general_log");
13318     myquery(rc);
13319 
13320     rc= mysql_query(mysql, "truncate mysql.slow_log");
13321     myquery(rc);
13322   }
13323 }
13324 
13325 
restore_query_logs()13326 static void restore_query_logs()
13327 {
13328   int rc;
13329   rc= mysql_query(mysql, "set @@global.general_log=@save_global_general_log");
13330   myquery(rc);
13331 
13332   rc= mysql_query(mysql, "set @@global.slow_query_log=@save_global_slow_query_log");
13333   myquery(rc);
13334 }
13335 
13336 
test_view_sp_list_fields()13337 static void test_view_sp_list_fields()
13338 {
13339   int		rc;
13340   MYSQL_RES     *res;
13341 
13342   myheader("test_view_sp_list_fields");
13343 
13344   rc= mysql_query(mysql, "DROP FUNCTION IF EXISTS f1");
13345   myquery(rc);
13346   rc= mysql_query(mysql, "DROP TABLE IF EXISTS v1, t1, t2");
13347   myquery(rc);
13348   rc= mysql_query(mysql, "DROP VIEW IF EXISTS v1, t1, t2");
13349   myquery(rc);
13350   rc= mysql_query(mysql, "create function f1 () returns int return 5");
13351   myquery(rc);
13352   rc= mysql_query(mysql, "create table t1 (s1 char,s2 char)");
13353   myquery(rc);
13354   rc= mysql_query(mysql, "create table t2 (s1 int);");
13355   myquery(rc);
13356   rc= mysql_query(mysql, "create view v1 as select s2,sum(s1) - \
13357 count(s2) as vx from t1 group by s2 having sum(s1) - count(s2) < (select f1() \
13358 from t2);");
13359   myquery(rc);
13360   res= mysql_list_fields(mysql, "v1", NullS);
13361   DIE_UNLESS(res != 0 && mysql_num_fields(res) != 0);
13362   rc= mysql_query(mysql, "DROP FUNCTION f1");
13363   myquery(rc);
13364   rc= mysql_query(mysql, "DROP VIEW v1");
13365   myquery(rc);
13366   rc= mysql_query(mysql, "DROP TABLE t1, t2");
13367   mysql_free_result(res);
13368   myquery(rc);
13369 
13370 }
13371 
13372 
13373 /*
13374  Test mysql_real_escape_string() with gbk charset
13375 
13376  The important part is that 0x27 (') is the second-byte in a invalid
13377  two-byte GBK character here. But 0xbf5c is a valid GBK character, so
13378  it needs to be escaped as 0x5cbf27
13379 */
13380 #define TEST_BUG8378_IN  "\xef\xbb\xbf\x27\xbf\x10"
13381 #define TEST_BUG8378_OUT "\xef\xbb\x5c\xbf\x5c\x27\x5c\xbf\x10"
13382 
test_bug8378()13383 static void test_bug8378()
13384 {
13385 #if defined(HAVE_CHARSET_gbk) && !defined(EMBEDDED_LIBRARY)
13386   MYSQL *lmysql;
13387   char out[9]; /* strlen(TEST_BUG8378)*2+1 */
13388   char buf[256];
13389   int len, rc;
13390 
13391   myheader("test_bug8378");
13392 
13393   if (!opt_silent)
13394     fprintf(stdout, "\n Establishing a test connection ...");
13395   if (!(lmysql= mysql_client_init(NULL)))
13396   {
13397     myerror("mysql_client_init() failed");
13398     exit(1);
13399   }
13400   if (mysql_options(lmysql, MYSQL_SET_CHARSET_NAME, "gbk"))
13401   {
13402     myerror("mysql_options() failed");
13403     exit(1);
13404   }
13405   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
13406                            opt_password, current_db, opt_port,
13407                            opt_unix_socket, 0)))
13408   {
13409     myerror("connection failed");
13410     exit(1);
13411   }
13412   if (!opt_silent)
13413     fprintf(stdout, "OK");
13414 
13415   rc= mysql_query(lmysql, "SET SQL_MODE=''");
13416   myquery(rc);
13417 
13418   len= mysql_real_escape_string(lmysql, out, TEST_BUG8378_IN, 4);
13419 
13420   /* No escaping should have actually happened. */
13421   DIE_UNLESS(memcmp(out, TEST_BUG8378_OUT, len) == 0);
13422 
13423   sprintf(buf, "SELECT '%s'", out);
13424 
13425   rc=mysql_real_query(lmysql, buf, strlen(buf));
13426   myquery(rc);
13427 
13428   mysql_close(lmysql);
13429 #endif
13430 }
13431 
13432 
test_bug8722()13433 static void test_bug8722()
13434 {
13435   MYSQL_STMT *stmt;
13436   int rc;
13437   const char *stmt_text;
13438 
13439   myheader("test_bug8722");
13440   /* Prepare test data */
13441   stmt_text= "drop table if exists t1, v1";
13442   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13443   myquery(rc);
13444   stmt_text= "CREATE TABLE t1 (c1 varchar(10), c2 varchar(10), c3 varchar(10),"
13445                              " c4 varchar(10), c5 varchar(10), c6 varchar(10),"
13446                              " c7 varchar(10), c8 varchar(10), c9 varchar(10),"
13447                              "c10 varchar(10))";
13448   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13449   myquery(rc);
13450   stmt_text= "INSERT INTO t1 VALUES (1,2,3,4,5,6,7,8,9,10)";
13451   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13452   myquery(rc);
13453   stmt_text= "CREATE VIEW v1 AS SELECT * FROM t1";
13454   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13455   myquery(rc);
13456   /* Note: if you uncomment following block everything works fine */
13457 /*
13458   rc= mysql_query(mysql, "sellect * from v1");
13459   myquery(rc);
13460   mysql_free_result(mysql_store_result(mysql));
13461 */
13462 
13463   stmt= mysql_stmt_init(mysql);
13464   stmt_text= "select * from v1";
13465   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13466   check_execute(stmt, rc);
13467   mysql_stmt_close(stmt);
13468   stmt_text= "drop table if exists t1, v1";
13469   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
13470   myquery(rc);
13471 }
13472 
13473 
open_cursor(const char * query)13474 MYSQL_STMT *open_cursor(const char *query)
13475 {
13476   int rc;
13477   const ulong type= (ulong)CURSOR_TYPE_READ_ONLY;
13478 
13479   MYSQL_STMT *stmt= mysql_stmt_init(mysql);
13480   rc= mysql_stmt_prepare(stmt, query, strlen(query));
13481   check_execute(stmt, rc);
13482 
13483   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13484   return stmt;
13485 }
13486 
13487 
test_bug8880()13488 static void test_bug8880()
13489 {
13490   MYSQL_STMT *stmt_list[2], **stmt;
13491   MYSQL_STMT **stmt_list_end= (MYSQL_STMT**) stmt_list + 2;
13492   int rc;
13493 
13494   myheader("test_bug8880");
13495 
13496   mysql_query(mysql, "drop table if exists t1");
13497   mysql_query(mysql, "create table t1 (a int not null primary key, b int)");
13498   rc= mysql_query(mysql, "insert into t1 values (1,1)");
13499   myquery(rc);                                  /* one check is enough */
13500   /*
13501     when inserting 2 rows everything works well
13502     mysql_query(mysql, "INSERT INTO t1 VALUES (1,1),(2,2)");
13503   */
13504   for (stmt= stmt_list; stmt < stmt_list_end; stmt++)
13505     *stmt= open_cursor("select a from t1");
13506   for (stmt= stmt_list; stmt < stmt_list_end; stmt++)
13507   {
13508     rc= mysql_stmt_execute(*stmt);
13509     check_execute(*stmt, rc);
13510   }
13511   for (stmt= stmt_list; stmt < stmt_list_end; stmt++)
13512     mysql_stmt_close(*stmt);
13513 }
13514 
13515 /*
13516   Test executing a query with prepared statements while query cache is active
13517 */
13518 
test_open_cursor_prepared_statement_query_cache()13519 static void test_open_cursor_prepared_statement_query_cache()
13520 {
13521   MYSQL_STMT *stmt;
13522   int rc;
13523   MYSQL_RES *result;
13524 
13525   myheader("test_open_cursor_prepared_statement_query_cache");
13526   if (! is_query_cache_available())
13527   {
13528     fprintf(stdout, "Skipping test_open_cursor_prepared_statement_query_cache: Query cache not available.\n");
13529     return;
13530   }
13531 
13532   rc= mysql_query(mysql,
13533                   "set @save_query_cache_type="
13534                   "@@global.query_cache_type,"
13535                   "@save_query_cache_size="
13536                   "@@global.query_cache_size");
13537   myquery(rc);
13538   rc= mysql_query(mysql, "set global query_cache_type=ON");
13539   myquery(rc);
13540   rc= mysql_query(mysql, "set local query_cache_type=ON");
13541   myquery(rc);
13542   rc= mysql_query(mysql, "set global query_cache_size=1000000");
13543   myquery(rc);
13544 
13545   mysql_query(mysql, "drop table if exists t1");
13546   mysql_query(mysql, "create table t1 (a int not null primary key, b int)");
13547   rc= mysql_query(mysql, "insert into t1 values (1,1)");
13548   myquery(rc);                                  /* one check is enough */
13549 
13550   /* Store query in query cache */
13551   rc= mysql_query(mysql, "SELECT * FROM t1");
13552   myquery(rc);
13553   result= mysql_store_result(mysql);
13554   mytest(result);
13555   (void) my_process_result_set(result);
13556   mysql_free_result(result);
13557 
13558   /* Test using a cursor */
13559   stmt= open_cursor("select a from t1");
13560   rc= mysql_stmt_execute(stmt);
13561   check_execute(stmt, rc);
13562   mysql_stmt_close(stmt);
13563 
13564   rc= mysql_query(mysql, "set global query_cache_type=@save_query_cache_type");
13565   myquery(rc);
13566   rc= mysql_query(mysql, "set global query_cache_size=@save_query_cache_size");
13567   myquery(rc);
13568 }
13569 
13570 
test_bug9159()13571 static void test_bug9159()
13572 {
13573   MYSQL_STMT *stmt;
13574   int rc;
13575   const char *stmt_text= "select a, b from t1";
13576   const unsigned long type= CURSOR_TYPE_READ_ONLY;
13577 
13578   myheader("test_bug9159");
13579 
13580   mysql_query(mysql, "drop table if exists t1");
13581   mysql_query(mysql, "create table t1 (a int not null primary key, b int)");
13582   rc= mysql_query(mysql, "insert into t1 values (1,1)");
13583   myquery(rc);
13584 
13585   stmt= mysql_stmt_init(mysql);
13586   mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13587   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void *)&type);
13588 
13589   mysql_stmt_execute(stmt);
13590   mysql_stmt_close(stmt);
13591   rc= mysql_query(mysql, "drop table if exists t1");
13592   myquery(rc);
13593 }
13594 
13595 
13596 /* Crash when opening a cursor to a query with DISTICNT and no key */
13597 
test_bug9520()13598 static void test_bug9520()
13599 {
13600   MYSQL_STMT *stmt;
13601   MYSQL_BIND my_bind[1];
13602   char a[6];
13603   ulong a_len;
13604   int rc, row_count= 0;
13605 
13606   myheader("test_bug9520");
13607 
13608   mysql_query(mysql, "drop table if exists t1");
13609   mysql_query(mysql, "create table t1 (a char(5), b char(5), c char(5),"
13610                      " primary key (a, b, c))");
13611   rc= mysql_query(mysql, "insert into t1 values ('x', 'y', 'z'), "
13612                   " ('a', 'b', 'c'), ('k', 'l', 'm')");
13613   myquery(rc);
13614 
13615   stmt= open_cursor("select distinct b from t1");
13616 
13617   /*
13618     Not crashes with:
13619     stmt= open_cursor("select distinct a from t1");
13620   */
13621 
13622   rc= mysql_stmt_execute(stmt);
13623   check_execute(stmt, rc);
13624 
13625   bzero((char*) my_bind, sizeof(my_bind));
13626   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
13627   my_bind[0].buffer= (char*) a;
13628   my_bind[0].buffer_length= sizeof(a);
13629   my_bind[0].length= &a_len;
13630 
13631   mysql_stmt_bind_result(stmt, my_bind);
13632 
13633   while (!(rc= mysql_stmt_fetch(stmt)))
13634     row_count++;
13635 
13636   DIE_UNLESS(rc == MYSQL_NO_DATA);
13637 
13638   if (!opt_silent)
13639     printf("Fetched %d rows\n", row_count);
13640   DBUG_ASSERT(row_count == 3);
13641 
13642   mysql_stmt_close(stmt);
13643 
13644   rc= mysql_query(mysql, "drop table t1");
13645   myquery(rc);
13646 }
13647 
13648 
13649 /*
13650   We can't have more than one cursor open for a prepared statement.
13651   Test re-executions of a PS with cursor; mysql_stmt_reset must close
13652   the cursor attached to the statement, if there is one.
13653 */
13654 
test_bug9478()13655 static void test_bug9478()
13656 {
13657   MYSQL_STMT *stmt;
13658   MYSQL_BIND my_bind[1];
13659   char a[6];
13660   ulong a_len;
13661   int rc, i;
13662   DBUG_ENTER("test_bug9478");
13663 
13664   myheader("test_bug9478");
13665 
13666   mysql_query(mysql, "drop table if exists t1");
13667   mysql_query(mysql, "create table t1 (id integer not null primary key, "
13668                      " name varchar(20) not null)");
13669   rc= mysql_query(mysql, "insert into t1 (id, name) values "
13670                          " (1, 'aaa'), (2, 'bbb'), (3, 'ccc')");
13671   myquery(rc);
13672 
13673   stmt= open_cursor("select name from t1 where id=2");
13674 
13675   bzero((char*) my_bind, sizeof(my_bind));
13676   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
13677   my_bind[0].buffer= (char*) a;
13678   my_bind[0].buffer_length= sizeof(a);
13679   my_bind[0].length= &a_len;
13680   mysql_stmt_bind_result(stmt, my_bind);
13681 
13682   for (i= 0; i < 5; i++)
13683   {
13684     rc= mysql_stmt_execute(stmt);
13685     check_execute(stmt, rc);
13686     rc= mysql_stmt_fetch(stmt);
13687     check_execute(stmt, rc);
13688     if (!opt_silent && i == 0)
13689       printf("Fetched row: %s\n", a);
13690 
13691     /*
13692       The query above is a one-row result set. Therefore, there is no
13693       cursor associated with it, as the server won't bother with opening
13694       a cursor for a one-row result set. The first row was read from the
13695       server in the fetch above. But there is eof packet pending in the
13696       network. mysql_stmt_execute will flush the packet and successfully
13697       execute the statement.
13698     */
13699 
13700     rc= mysql_stmt_execute(stmt);
13701     check_execute(stmt, rc);
13702 
13703     rc= mysql_stmt_fetch(stmt);
13704     check_execute(stmt, rc);
13705     if (!opt_silent && i == 0)
13706       printf("Fetched row: %s\n", a);
13707     rc= mysql_stmt_fetch(stmt);
13708     DIE_UNLESS(rc == MYSQL_NO_DATA);
13709 
13710     {
13711       char buff[8];
13712       /* Fill in the fetch packet */
13713       int4store(buff, stmt->stmt_id);
13714       buff[4]= 1;                               /* prefetch rows */
13715       rc= mysql_stmt_fetch(stmt);
13716       DIE_UNLESS(rc);
13717       if (!opt_silent && i == 0)
13718         printf("Got error (as expected): %s\n", mysql_error(mysql));
13719     }
13720 
13721     rc= mysql_stmt_execute(stmt);
13722     check_execute(stmt, rc);
13723 
13724     rc= mysql_stmt_fetch(stmt);
13725     check_execute(stmt, rc);
13726     if (!opt_silent && i == 0)
13727       printf("Fetched row: %s\n", a);
13728 
13729     rc= mysql_stmt_reset(stmt);
13730     check_execute(stmt, rc);
13731     rc= mysql_stmt_fetch(stmt);
13732     DIE_UNLESS(rc && mysql_stmt_errno(stmt));
13733     if (!opt_silent && i == 0)
13734       printf("Got error (as expected): %s\n", mysql_stmt_error(stmt));
13735   }
13736   rc= mysql_stmt_close(stmt);
13737   DIE_UNLESS(rc == 0);
13738 
13739   /* Test the case with a server side cursor */
13740   stmt= open_cursor("select name from t1");
13741 
13742   mysql_stmt_bind_result(stmt, my_bind);
13743 
13744   for (i= 0; i < 5; i++)
13745   {
13746     DBUG_PRINT("loop",("i: %d", i));
13747     rc= mysql_stmt_execute(stmt);
13748     check_execute(stmt, rc);
13749     rc= mysql_stmt_fetch(stmt);
13750     check_execute(stmt, rc);
13751     if (!opt_silent && i == 0)
13752       printf("Fetched row: %s\n", a);
13753     rc= mysql_stmt_execute(stmt);
13754     check_execute(stmt, rc);
13755 
13756     while (! (rc= mysql_stmt_fetch(stmt)))
13757     {
13758       if (!opt_silent && i == 0)
13759         printf("Fetched row: %s\n", a);
13760     }
13761     DIE_UNLESS(rc == MYSQL_NO_DATA);
13762 
13763     rc= mysql_stmt_execute(stmt);
13764     check_execute(stmt, rc);
13765 
13766     rc= mysql_stmt_fetch(stmt);
13767     check_execute(stmt, rc);
13768     if (!opt_silent && i == 0)
13769       printf("Fetched row: %s\n", a);
13770 
13771     rc= mysql_stmt_reset(stmt);
13772     check_execute(stmt, rc);
13773     rc= mysql_stmt_fetch(stmt);
13774     DIE_UNLESS(rc && mysql_stmt_errno(stmt));
13775     if (!opt_silent && i == 0)
13776       printf("Got error (as expected): %s\n", mysql_stmt_error(stmt));
13777   }
13778 
13779   rc= mysql_stmt_close(stmt);
13780   DIE_UNLESS(rc == 0);
13781 
13782   rc= mysql_query(mysql, "drop table t1");
13783   myquery(rc);
13784   DBUG_VOID_RETURN;
13785 }
13786 
13787 
13788 /*
13789   Error message is returned for unsupported features.
13790   Test also cursors with non-default PREFETCH_ROWS
13791 */
13792 
test_bug9643()13793 static void test_bug9643()
13794 {
13795   MYSQL_STMT *stmt;
13796   MYSQL_BIND my_bind[1];
13797   int32 a;
13798   int rc;
13799   const char *stmt_text;
13800   int num_rows= 0;
13801   ulong type;
13802   ulong prefetch_rows= 5;
13803 
13804   myheader("test_bug9643");
13805 
13806   mysql_query(mysql, "drop table if exists t1");
13807   mysql_query(mysql, "create table t1 (id integer not null primary key)");
13808   rc= mysql_query(mysql, "insert into t1 (id) values "
13809                          " (1), (2), (3), (4), (5), (6), (7), (8), (9)");
13810   myquery(rc);
13811 
13812   stmt= mysql_stmt_init(mysql);
13813   /* Not implemented in 5.0 */
13814   type= (ulong) CURSOR_TYPE_SCROLLABLE;
13815   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13816   DIE_UNLESS(rc);
13817   if (! opt_silent)
13818     printf("Got error (as expected): %s\n", mysql_stmt_error(stmt));
13819 
13820   type= (ulong) CURSOR_TYPE_READ_ONLY;
13821   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13822   check_execute(stmt, rc);
13823   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_PREFETCH_ROWS,
13824                           (void*) &prefetch_rows);
13825   check_execute(stmt, rc);
13826   stmt_text= "select * 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_LONG;
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   rc= mysql_stmt_execute(stmt);
13837   check_execute(stmt, rc);
13838 
13839   while ((rc= mysql_stmt_fetch(stmt)) == 0)
13840     ++num_rows;
13841   DIE_UNLESS(num_rows == 9);
13842 
13843   rc= mysql_stmt_close(stmt);
13844   DIE_UNLESS(rc == 0);
13845 
13846   rc= mysql_query(mysql, "drop table t1");
13847   myquery(rc);
13848 }
13849 
13850 /*
13851   Bug#11111: fetch from view returns wrong data
13852 */
13853 
test_bug11111()13854 static void test_bug11111()
13855 {
13856   MYSQL_STMT    *stmt;
13857   MYSQL_BIND    my_bind[2];
13858   char          buf[2][20];
13859   ulong         len[2];
13860   int i;
13861   int rc;
13862   const char *query= "SELECT DISTINCT f1,ff2 FROM v1";
13863 
13864   myheader("test_bug11111");
13865 
13866   rc= mysql_query(mysql, "drop table if exists t1, t2, v1");
13867   myquery(rc);
13868   rc= mysql_query(mysql, "drop view if exists t1, t2, v1");
13869   myquery(rc);
13870   rc= mysql_query(mysql, "create table t1 (f1 int, f2 int)");
13871   myquery(rc);
13872   rc= mysql_query(mysql, "create table t2 (ff1 int, ff2 int)");
13873   myquery(rc);
13874   rc= mysql_query(mysql, "create view v1 as select * from t1, t2 where f1=ff1");
13875   myquery(rc);
13876   rc= mysql_query(mysql, "insert into t1 values (1,1), (2,2), (3,3)");
13877   myquery(rc);
13878   rc= mysql_query(mysql, "insert into t2 values (1,1), (2,2), (3,3)");
13879   myquery(rc);
13880 
13881   stmt= mysql_stmt_init(mysql);
13882 
13883   mysql_stmt_prepare(stmt, query, strlen(query));
13884   mysql_stmt_execute(stmt);
13885 
13886   bzero((char*) my_bind, sizeof(my_bind));
13887   for (i=0; i < 2; i++)
13888   {
13889     my_bind[i].buffer_type= MYSQL_TYPE_STRING;
13890     my_bind[i].buffer= (uchar* *)&buf[i];
13891     my_bind[i].buffer_length= 20;
13892     my_bind[i].length= &len[i];
13893   }
13894 
13895   rc= mysql_stmt_bind_result(stmt, my_bind);
13896   check_execute(stmt, rc);
13897 
13898   rc= mysql_stmt_fetch(stmt);
13899   check_execute(stmt, rc);
13900   if (!opt_silent)
13901     printf("return: %s", buf[1]);
13902   DIE_UNLESS(!strcmp(buf[1],"1"));
13903   mysql_stmt_close(stmt);
13904   rc= mysql_query(mysql, "drop view v1");
13905   myquery(rc);
13906   rc= mysql_query(mysql, "drop table t1, t2");
13907   myquery(rc);
13908 }
13909 
13910 /*
13911   Check that proper cleanups are done for prepared statement when
13912   fetching thorugh a cursor.
13913 */
13914 
test_bug10729()13915 static void test_bug10729()
13916 {
13917   MYSQL_STMT *stmt;
13918   MYSQL_BIND my_bind[1];
13919   char a[21];
13920   int rc;
13921   const char *stmt_text;
13922   int i= 0;
13923   const char *name_array[3]= { "aaa", "bbb", "ccc" };
13924   ulong type;
13925 
13926   myheader("test_bug10729");
13927 
13928   mysql_query(mysql, "drop table if exists t1");
13929   mysql_query(mysql, "create table t1 (id integer not null primary key,"
13930                                       "name VARCHAR(20) NOT NULL)");
13931   rc= mysql_query(mysql, "insert into t1 (id, name) values "
13932                          "(1, 'aaa'), (2, 'bbb'), (3, 'ccc')");
13933   myquery(rc);
13934 
13935   stmt= mysql_stmt_init(mysql);
13936 
13937   type= (ulong) CURSOR_TYPE_READ_ONLY;
13938   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
13939   check_execute(stmt, rc);
13940   stmt_text= "select name from t1";
13941   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
13942   check_execute(stmt, rc);
13943 
13944   bzero((char*) my_bind, sizeof(my_bind));
13945   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
13946   my_bind[0].buffer= (void*) a;
13947   my_bind[0].buffer_length= sizeof(a);
13948   mysql_stmt_bind_result(stmt, my_bind);
13949 
13950   for (i= 0; i < 3; i++)
13951   {
13952     int row_no= 0;
13953     rc= mysql_stmt_execute(stmt);
13954     check_execute(stmt, rc);
13955     while ((rc= mysql_stmt_fetch(stmt)) == 0)
13956     {
13957       DIE_UNLESS(strcmp(a, name_array[row_no]) == 0);
13958       if (!opt_silent)
13959         printf("%d: %s\n", row_no, a);
13960       ++row_no;
13961     }
13962     DIE_UNLESS(rc == MYSQL_NO_DATA);
13963   }
13964   rc= mysql_stmt_close(stmt);
13965   DIE_UNLESS(rc == 0);
13966 
13967   rc= mysql_query(mysql, "drop table t1");
13968   myquery(rc);
13969 }
13970 
13971 
13972 /*
13973   Check that mysql_next_result works properly in case when one of
13974   the statements used in a multi-statement query is erroneous
13975 */
13976 
test_bug9992()13977 static void test_bug9992()
13978 {
13979   MYSQL *mysql1;
13980   MYSQL_RES* res ;
13981   int   rc;
13982 
13983   myheader("test_bug9992");
13984 
13985   if (!opt_silent)
13986     printf("Establishing a connection with option CLIENT_MULTI_STATEMENTS..\n");
13987 
13988   mysql1= mysql_client_init(NULL);
13989 
13990   if (!mysql_real_connect(mysql1, opt_host, opt_user, opt_password,
13991                           opt_db ? opt_db : "test", opt_port, opt_unix_socket,
13992                           CLIENT_MULTI_STATEMENTS))
13993   {
13994     fprintf(stderr, "Failed to connect to the database\n");
13995     DIE_UNLESS(0);
13996   }
13997 
13998 
13999   /* Sic: SHOW DATABASE is incorrect syntax. */
14000   rc= mysql_query(mysql1, "SHOW TABLES; SHOW DATABASE; SELECT 1;");
14001 
14002   if (rc)
14003   {
14004     fprintf(stderr, "[%d] %s\n", mysql_errno(mysql1), mysql_error(mysql1));
14005     DIE_UNLESS(0);
14006   }
14007 
14008   if (!opt_silent)
14009     printf("Testing mysql_store_result/mysql_next_result..\n");
14010 
14011   res= mysql_store_result(mysql1);
14012   DIE_UNLESS(res);
14013   mysql_free_result(res);
14014   rc= mysql_next_result(mysql1);
14015   DIE_UNLESS(rc == 1);                         /* Got errors, as expected */
14016 
14017   if (!opt_silent)
14018     fprintf(stdout, "Got error, as expected:\n [%d] %s\n",
14019             mysql_errno(mysql1), mysql_error(mysql1));
14020 
14021   mysql_close(mysql1);
14022 }
14023 
14024 /* Bug#10736: cursors and subqueries, memroot management */
14025 
test_bug10736()14026 static void test_bug10736()
14027 {
14028   MYSQL_STMT *stmt;
14029   MYSQL_BIND my_bind[1];
14030   char a[21];
14031   int rc;
14032   const char *stmt_text;
14033   int i= 0;
14034   ulong type;
14035 
14036   myheader("test_bug10736");
14037 
14038   mysql_query(mysql, "drop table if exists t1");
14039   mysql_query(mysql, "create table t1 (id integer not null primary key,"
14040                                       "name VARCHAR(20) NOT NULL)");
14041   rc= mysql_query(mysql, "insert into t1 (id, name) values "
14042                          "(1, 'aaa'), (2, 'bbb'), (3, 'ccc')");
14043   myquery(rc);
14044 
14045   stmt= mysql_stmt_init(mysql);
14046 
14047   type= (ulong) CURSOR_TYPE_READ_ONLY;
14048   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
14049   check_execute(stmt, rc);
14050   stmt_text= "select name from t1 where name=(select name from t1 where id=2)";
14051   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
14052   check_execute(stmt, rc);
14053 
14054   bzero((char*) my_bind, sizeof(my_bind));
14055   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
14056   my_bind[0].buffer= (void*) a;
14057   my_bind[0].buffer_length= sizeof(a);
14058   mysql_stmt_bind_result(stmt, my_bind);
14059 
14060   for (i= 0; i < 3; i++)
14061   {
14062     int row_no= 0;
14063     rc= mysql_stmt_execute(stmt);
14064     check_execute(stmt, rc);
14065     while ((rc= mysql_stmt_fetch(stmt)) == 0)
14066     {
14067       if (!opt_silent)
14068         printf("%d: %s\n", row_no, a);
14069       ++row_no;
14070     }
14071     DIE_UNLESS(rc == MYSQL_NO_DATA);
14072   }
14073   rc= mysql_stmt_close(stmt);
14074   DIE_UNLESS(rc == 0);
14075 
14076   rc= mysql_query(mysql, "drop table t1");
14077   myquery(rc);
14078 }
14079 
14080 /* Bug#10794: cursors, packets out of order */
14081 
test_bug10794()14082 static void test_bug10794()
14083 {
14084   MYSQL_STMT *stmt, *stmt1;
14085   MYSQL_BIND my_bind[2];
14086   char a[21];
14087   int id_val;
14088   ulong a_len;
14089   int rc;
14090   const char *stmt_text;
14091   int i= 0;
14092   ulong type;
14093 
14094   myheader("test_bug10794");
14095 
14096   mysql_query(mysql, "drop table if exists t1");
14097   mysql_query(mysql, "create table t1 (id integer not null primary key,"
14098                                       "name varchar(20) not null)");
14099   stmt= mysql_stmt_init(mysql);
14100   stmt_text= "insert into t1 (id, name) values (?, ?)";
14101   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
14102   check_execute(stmt, rc);
14103   bzero((char*) my_bind, sizeof(my_bind));
14104   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
14105   my_bind[0].buffer= (void*) &id_val;
14106   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
14107   my_bind[1].buffer= (void*) a;
14108   my_bind[1].length= &a_len;
14109   rc= mysql_stmt_bind_param(stmt, my_bind);
14110   check_execute(stmt, rc);
14111   for (i= 0; i < 42; i++)
14112   {
14113     id_val= (i+1)*10;
14114     sprintf(a, "a%d", i);
14115     a_len= strlen(a); /* safety against broken sprintf */
14116     rc= mysql_stmt_execute(stmt);
14117     check_execute(stmt, rc);
14118   }
14119   stmt_text= "select name from t1";
14120   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
14121   type= (ulong) CURSOR_TYPE_READ_ONLY;
14122   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14123   stmt1= mysql_stmt_init(mysql);
14124   mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14125   bzero((char*) my_bind, sizeof(my_bind));
14126   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
14127   my_bind[0].buffer= (void*) a;
14128   my_bind[0].buffer_length= sizeof(a);
14129   my_bind[0].length= &a_len;
14130   rc= mysql_stmt_bind_result(stmt, my_bind);
14131   check_execute(stmt, rc);
14132   rc= mysql_stmt_execute(stmt);
14133   check_execute(stmt, rc);
14134   rc= mysql_stmt_fetch(stmt);
14135   check_execute(stmt, rc);
14136   if (!opt_silent)
14137     printf("Fetched row from stmt: %s\n", a);
14138   /* Don't optimize: an attribute of the original test case */
14139   mysql_stmt_free_result(stmt);
14140   mysql_stmt_reset(stmt);
14141   stmt_text= "select name from t1 where id=10";
14142   rc= mysql_stmt_prepare(stmt1, stmt_text, strlen(stmt_text));
14143   check_execute(stmt1, rc);
14144   rc= mysql_stmt_bind_result(stmt1, my_bind);
14145   check_execute(stmt1, rc);
14146   rc= mysql_stmt_execute(stmt1);
14147   while (1)
14148   {
14149     rc= mysql_stmt_fetch(stmt1);
14150     if (rc == MYSQL_NO_DATA)
14151     {
14152       if (!opt_silent)
14153         printf("End of data in stmt1\n");
14154       break;
14155     }
14156     check_execute(stmt1, rc);
14157     if (!opt_silent)
14158       printf("Fetched row from stmt1: %s\n", a);
14159   }
14160   mysql_stmt_close(stmt);
14161   mysql_stmt_close(stmt1);
14162 
14163   rc= mysql_query(mysql, "drop table t1");
14164   myquery(rc);
14165 }
14166 
14167 
14168 /* Bug#11172: cursors, crash on a fetch from a datetime column */
14169 
test_bug11172()14170 static void test_bug11172()
14171 {
14172   MYSQL_STMT *stmt;
14173   MYSQL_BIND bind_in[1], bind_out[2];
14174   MYSQL_TIME hired;
14175   int rc;
14176   const char *stmt_text;
14177   int i= 0, id;
14178   ulong type;
14179 
14180   myheader("test_bug11172");
14181 
14182   mysql_query(mysql, "drop table if exists t1");
14183   mysql_query(mysql, "create table t1 (id integer not null primary key,"
14184                                       "hired date not null)");
14185   rc= mysql_query(mysql,
14186                   "insert into t1 (id, hired) values (1, '1933-08-24'), "
14187                   "(2, '1965-01-01'), (3, '1949-08-17'), (4, '1945-07-07'), "
14188                   "(5, '1941-05-15'), (6, '1978-09-15'), (7, '1936-03-28')");
14189   myquery(rc);
14190   stmt= mysql_stmt_init(mysql);
14191   stmt_text= "SELECT id, hired FROM t1 WHERE hired=?";
14192   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
14193   check_execute(stmt, rc);
14194 
14195   type= (ulong) CURSOR_TYPE_READ_ONLY;
14196   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14197 
14198   bzero((char*) bind_in, sizeof(bind_in));
14199   bzero((char*) bind_out, sizeof(bind_out));
14200   bzero((char*) &hired, sizeof(hired));
14201   hired.year= 1965;
14202   hired.month= 1;
14203   hired.day= 1;
14204   bind_in[0].buffer_type= MYSQL_TYPE_DATE;
14205   bind_in[0].buffer= (void*) &hired;
14206   bind_in[0].buffer_length= sizeof(hired);
14207   bind_out[0].buffer_type= MYSQL_TYPE_LONG;
14208   bind_out[0].buffer= (void*) &id;
14209   bind_out[1]= bind_in[0];
14210 
14211   for (i= 0; i < 3; i++)
14212   {
14213     rc= mysql_stmt_bind_param(stmt, bind_in);
14214     check_execute(stmt, rc);
14215     rc= mysql_stmt_bind_result(stmt, bind_out);
14216     check_execute(stmt, rc);
14217     rc= mysql_stmt_execute(stmt);
14218     check_execute(stmt, rc);
14219     while ((rc= mysql_stmt_fetch(stmt)) == 0)
14220     {
14221       if (!opt_silent)
14222         printf("fetched data %d:%d-%d-%d\n", id,
14223                hired.year, hired.month, hired.day);
14224     }
14225     DIE_UNLESS(rc == MYSQL_NO_DATA);
14226     if (!mysql_stmt_free_result(stmt))
14227       mysql_stmt_reset(stmt);
14228   }
14229   mysql_stmt_close(stmt);
14230   mysql_rollback(mysql);
14231   mysql_rollback(mysql);
14232 
14233   rc= mysql_query(mysql, "drop table t1");
14234   myquery(rc);
14235 }
14236 
14237 
14238 /* Bug#11656: cursors, crash on a fetch from a query with distinct. */
14239 
test_bug11656()14240 static void test_bug11656()
14241 {
14242   MYSQL_STMT *stmt;
14243   MYSQL_BIND my_bind[2];
14244   int rc;
14245   const char *stmt_text;
14246   char buf[2][20];
14247   int i= 0;
14248   ulong type;
14249 
14250   myheader("test_bug11656");
14251 
14252   mysql_query(mysql, "drop table if exists t1");
14253 
14254   rc= mysql_query(mysql, "create table t1 ("
14255                   "server varchar(40) not null, "
14256                   "test_kind varchar(1) not null, "
14257                   "test_id varchar(30) not null , "
14258                   "primary key (server,test_kind,test_id))");
14259   myquery(rc);
14260 
14261   stmt_text= "select distinct test_kind, test_id from t1 "
14262              "where server in (?, ?)";
14263   stmt= mysql_stmt_init(mysql);
14264   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
14265   check_execute(stmt, rc);
14266   type= (ulong) CURSOR_TYPE_READ_ONLY;
14267   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14268 
14269   bzero((char*) my_bind, sizeof(my_bind));
14270   strmov(buf[0], "pcint502_MY2");
14271   strmov(buf[1], "*");
14272   for (i=0; i < 2; i++)
14273   {
14274     my_bind[i].buffer_type= MYSQL_TYPE_STRING;
14275     my_bind[i].buffer= (uchar* *)&buf[i];
14276     my_bind[i].buffer_length= strlen(buf[i]);
14277   }
14278   mysql_stmt_bind_param(stmt, my_bind);
14279 
14280   rc= mysql_stmt_execute(stmt);
14281   check_execute(stmt, rc);
14282 
14283   rc= mysql_stmt_fetch(stmt);
14284   DIE_UNLESS(rc == MYSQL_NO_DATA);
14285 
14286   mysql_stmt_close(stmt);
14287   rc= mysql_query(mysql, "drop table t1");
14288   myquery(rc);
14289 }
14290 
14291 
14292 /*
14293   Check that the server signals when NO_BACKSLASH_ESCAPES mode is in effect,
14294   and mysql_real_escape_string() does the right thing as a result.
14295 */
14296 
test_bug10214()14297 static void test_bug10214()
14298 {
14299   int   len;
14300   char  out[8];
14301 
14302   myheader("test_bug10214");
14303 
14304   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES));
14305 
14306   len= mysql_real_escape_string(mysql, out, "a'b\\c", 5);
14307   DIE_UNLESS(memcmp(out, "a\\'b\\\\c", len) == 0);
14308 
14309   mysql_query(mysql, "set sql_mode='NO_BACKSLASH_ESCAPES'");
14310   DIE_UNLESS(mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES);
14311 
14312   len= mysql_real_escape_string(mysql, out, "a'b\\c", 5);
14313   DIE_UNLESS(memcmp(out, "a''b\\c", len) == 0);
14314 
14315   mysql_query(mysql, "set sql_mode=''");
14316 }
14317 
test_client_character_set()14318 static void test_client_character_set()
14319 {
14320   MY_CHARSET_INFO cs;
14321   char *csname= (char*) "utf8";
14322   char *csdefault= (char*)mysql_character_set_name(mysql);
14323   int rc;
14324 
14325   myheader("test_client_character_set");
14326 
14327   rc= mysql_set_character_set(mysql, csname);
14328   DIE_UNLESS(rc == 0);
14329 
14330   mysql_get_character_set_info(mysql, &cs);
14331   DIE_UNLESS(!strcmp(cs.csname, "utf8"));
14332   DIE_UNLESS(!strcmp(cs.name, "utf8_general_ci"));
14333   /* Restore the default character set */
14334   rc= mysql_set_character_set(mysql, csdefault);
14335   myquery(rc);
14336 }
14337 
14338 /* Test correct max length for MEDIUMTEXT and LONGTEXT columns */
14339 
test_bug9735()14340 static void test_bug9735()
14341 {
14342   MYSQL_RES *res;
14343   int rc;
14344 
14345   myheader("test_bug9735");
14346 
14347   rc= mysql_query(mysql, "drop table if exists t1");
14348   myquery(rc);
14349   rc= mysql_query(mysql, "create table t1 (a mediumtext, b longtext) "
14350                          "character set latin1");
14351   myquery(rc);
14352   rc= mysql_query(mysql, "select * from t1");
14353   myquery(rc);
14354   res= mysql_store_result(mysql);
14355   verify_prepare_field(res, 0, "a", "a", MYSQL_TYPE_BLOB,
14356                        "t1", "t1", current_db, (1U << 24)-1, 0);
14357   verify_prepare_field(res, 1, "b", "b", MYSQL_TYPE_BLOB,
14358                        "t1", "t1", current_db, ~0U, 0);
14359   mysql_free_result(res);
14360   rc= mysql_query(mysql, "drop table t1");
14361   myquery(rc);
14362 }
14363 
14364 
14365 /* Bug#11183 "mysql_stmt_reset() doesn't reset information about error" */
14366 
test_bug11183()14367 static void test_bug11183()
14368 {
14369   int rc;
14370   MYSQL_STMT *stmt;
14371   char bug_statement[]= "insert into t1 values (1)";
14372 
14373   myheader("test_bug11183");
14374 
14375   mysql_query(mysql, "drop table t1 if exists");
14376   mysql_query(mysql, "create table t1 (a int)");
14377 
14378   stmt= mysql_stmt_init(mysql);
14379   DIE_UNLESS(stmt != 0);
14380 
14381   rc= mysql_stmt_prepare(stmt, bug_statement, strlen(bug_statement));
14382   check_execute(stmt, rc);
14383 
14384   rc= mysql_query(mysql, "drop table t1");
14385   myquery(rc);
14386 
14387   /* Trying to execute statement that should fail on execute stage */
14388   rc= mysql_stmt_execute(stmt);
14389   DIE_UNLESS(rc);
14390 
14391   mysql_stmt_reset(stmt);
14392   DIE_UNLESS(mysql_stmt_errno(stmt) == 0);
14393 
14394   mysql_query(mysql, "create table t1 (a int)");
14395 
14396   /* Trying to execute statement that should pass ok */
14397   if (mysql_stmt_execute(stmt))
14398   {
14399     mysql_stmt_reset(stmt);
14400     DIE_UNLESS(mysql_stmt_errno(stmt) == 0);
14401   }
14402 
14403   mysql_stmt_close(stmt);
14404 
14405   rc= mysql_query(mysql, "drop table t1");
14406   myquery(rc);
14407 }
14408 
test_bug11037()14409 static void test_bug11037()
14410 {
14411   MYSQL_STMT *stmt;
14412   int rc;
14413   const char *stmt_text;
14414 
14415   myheader("test_bug11037");
14416 
14417   mysql_query(mysql, "drop table if exists t1");
14418 
14419   rc= mysql_query(mysql, "create table t1 (id int not null)");
14420   myquery(rc);
14421 
14422   rc= mysql_query(mysql, "insert into t1 values (1)");
14423   myquery(rc);
14424 
14425   stmt_text= "select id FROM t1";
14426   stmt= mysql_stmt_init(mysql);
14427   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
14428 
14429   /* expected error */
14430   rc = mysql_stmt_fetch(stmt);
14431   DIE_UNLESS(rc==1);
14432   if (!opt_silent)
14433     fprintf(stdout, "Got error, as expected:\n [%d] %s\n",
14434             mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
14435 
14436   rc= mysql_stmt_execute(stmt);
14437   check_execute(stmt, rc);
14438 
14439   rc= mysql_stmt_fetch(stmt);
14440   DIE_UNLESS(rc==0);
14441 
14442   rc= mysql_stmt_fetch(stmt);
14443   DIE_UNLESS(rc==MYSQL_NO_DATA);
14444 
14445   rc= mysql_stmt_fetch(stmt);
14446   DIE_UNLESS(rc==MYSQL_NO_DATA);
14447 
14448   mysql_stmt_close(stmt);
14449   rc= mysql_query(mysql, "drop table t1");
14450   myquery(rc);
14451 }
14452 
14453 /* Bug#10760: cursors, crash in a fetch after rollback. */
14454 
test_bug10760()14455 static void test_bug10760()
14456 {
14457   MYSQL_STMT *stmt;
14458   MYSQL_BIND my_bind[1];
14459   int rc;
14460   const char *stmt_text;
14461   char id_buf[20];
14462   ulong id_len;
14463   int i= 0;
14464   ulong type;
14465 
14466   myheader("test_bug10760");
14467 
14468   mysql_query(mysql, "drop table if exists t1, t2");
14469 
14470   /* create tables */
14471   rc= mysql_query(mysql, "create table t1 (id integer not null primary key)"
14472                          " engine=MyISAM");
14473   myquery(rc);
14474   for (; i < 42; ++i)
14475   {
14476     char buf[100];
14477     sprintf(buf, "insert into t1 (id) values (%d)", i+1);
14478     rc= mysql_query(mysql, buf);
14479     myquery(rc);
14480   }
14481   mysql_autocommit(mysql, FALSE);
14482   /* create statement */
14483   stmt= mysql_stmt_init(mysql);
14484   type= (ulong) CURSOR_TYPE_READ_ONLY;
14485   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14486 
14487   /*
14488     1: check that a deadlock within the same connection
14489     is resolved and an error is returned. The deadlock is modelled
14490     as follows:
14491     con1: open cursor for select * from t1;
14492     con1: insert into t1 (id) values (1)
14493   */
14494   stmt_text= "select id from t1 order by 1";
14495   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
14496   check_execute(stmt, rc);
14497   rc= mysql_stmt_execute(stmt);
14498   check_execute(stmt, rc);
14499   rc= mysql_query(mysql, "update t1 set id=id+100");
14500   /*
14501     If cursors are not materialized, the update will return an error;
14502     we mainly test that it won't deadlock.
14503   */
14504   if (rc && !opt_silent)
14505     printf("Got error (as expected): %s\n", mysql_error(mysql));
14506   /*
14507     2: check that MyISAM tables used in cursors survive
14508     COMMIT/ROLLBACK.
14509   */
14510   rc= mysql_rollback(mysql);                  /* should not close the cursor */
14511   myquery(rc);
14512   rc= mysql_stmt_fetch(stmt);
14513   check_execute(stmt, rc);
14514 
14515   /*
14516     3: check that cursors to InnoDB tables are closed (for now) by
14517     COMMIT/ROLLBACK.
14518   */
14519   if (! have_innodb)
14520   {
14521     if (!opt_silent)
14522       printf("Testing that cursors are closed at COMMIT/ROLLBACK requires "
14523              "InnoDB.\n");
14524   }
14525   else
14526   {
14527     stmt_text= "select id from t1 order by 1";
14528     rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
14529     check_execute(stmt, rc);
14530 
14531     rc= mysql_query(mysql, "alter table t1 engine=InnoDB");
14532     myquery(rc);
14533 
14534     bzero(my_bind, sizeof(my_bind));
14535     my_bind[0].buffer_type= MYSQL_TYPE_STRING;
14536     my_bind[0].buffer= (void*) id_buf;
14537     my_bind[0].buffer_length= sizeof(id_buf);
14538     my_bind[0].length= &id_len;
14539     check_execute(stmt, rc);
14540     mysql_stmt_bind_result(stmt, my_bind);
14541 
14542     rc= mysql_stmt_execute(stmt);
14543     rc= mysql_stmt_fetch(stmt);
14544     DIE_UNLESS(rc == 0);
14545     if (!opt_silent)
14546       printf("Fetched row %s\n", id_buf);
14547     rc= mysql_rollback(mysql);                  /* should close the cursor */
14548     myquery(rc);
14549 #if 0
14550     rc= mysql_stmt_fetch(stmt);
14551     DIE_UNLESS(rc);
14552     if (!opt_silent)
14553       printf("Got error (as expected): %s\n", mysql_error(mysql));
14554 #endif
14555   }
14556 
14557   mysql_stmt_close(stmt);
14558   rc= mysql_query(mysql, "drop table t1");
14559   myquery(rc);
14560   mysql_autocommit(mysql, TRUE);                /* restore default */
14561 }
14562 
test_bug12001()14563 static void test_bug12001()
14564 {
14565   MYSQL *mysql_local;
14566   MYSQL_RES *result;
14567   const char *query= "DROP TABLE IF EXISTS test_table;"
14568                      "CREATE TABLE test_table(id INT);"
14569                      "INSERT INTO test_table VALUES(10);"
14570                      "UPDATE test_table SET id=20 WHERE id=10;"
14571                      "SELECT * FROM test_table;"
14572                      "INSERT INTO non_existent_table VALUES(11);";
14573   int rc, res;
14574 
14575   myheader("test_bug12001");
14576 
14577   if (!(mysql_local= mysql_client_init(NULL)))
14578   {
14579     fprintf(stdout, "\n mysql_client_init() failed");
14580     exit(1);
14581   }
14582 
14583   /* Create connection that supports multi statements */
14584   if (!mysql_real_connect(mysql_local, opt_host, opt_user,
14585                           opt_password, current_db, opt_port,
14586                           opt_unix_socket, CLIENT_MULTI_STATEMENTS))
14587   {
14588     fprintf(stdout, "\n mysql_real_connect() failed");
14589     exit(1);
14590   }
14591 
14592   rc= mysql_query(mysql_local, query);
14593   myquery(rc);
14594 
14595   do
14596   {
14597     if (mysql_field_count(mysql_local) &&
14598         (result= mysql_use_result(mysql_local)))
14599     {
14600       mysql_free_result(result);
14601     }
14602   }
14603   while (!(res= mysql_next_result(mysql_local)));
14604 
14605   rc= mysql_query(mysql_local, "DROP TABLE IF EXISTS test_table");
14606   myquery(rc);
14607 
14608   mysql_close(mysql_local);
14609   DIE_UNLESS(res==1);
14610 }
14611 
14612 
14613 /* Bug#11909: wrong metadata if fetching from two cursors */
14614 
test_bug11909()14615 static void test_bug11909()
14616 {
14617   MYSQL_STMT *stmt1, *stmt2;
14618   MYSQL_BIND my_bind[7];
14619   int rc;
14620   char firstname[20], midinit[20], lastname[20], workdept[20];
14621   ulong firstname_len, midinit_len, lastname_len, workdept_len;
14622   uint32 empno;
14623   double salary;
14624   float bonus;
14625   const char *stmt_text;
14626 
14627   myheader("test_bug11909");
14628 
14629   stmt_text= "drop table if exists t1";
14630   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14631   myquery(rc);
14632 
14633   stmt_text= "create table t1 ("
14634     "  empno int(11) not null, firstname varchar(20) not null,"
14635     "  midinit varchar(20) not null, lastname varchar(20) not null,"
14636     "  workdept varchar(6) not null, salary double not null,"
14637     "  bonus float not null, primary key (empno)"
14638     ") default charset=latin1 collate=latin1_bin";
14639   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14640   myquery(rc);
14641 
14642   stmt_text= "insert into t1 values "
14643     "(10, 'CHRISTINE', 'I', 'HAAS',     'A00', 52750, 1000), "
14644     "(20, 'MICHAEL',   'L', 'THOMPSON', 'B01', 41250, 800),"
14645     "(30, 'SALLY',     'A', 'KWAN',     'C01', 38250, 800),"
14646     "(50, 'JOHN',      'B', 'GEYER',    'E01', 40175, 800), "
14647     "(60, 'IRVING',    'F', 'STERN',    'D11', 32250, 500)";
14648   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14649   myquery(rc);
14650 
14651   /* ****** Begin of trace ****** */
14652 
14653   stmt1= open_cursor("SELECT empno, firstname, midinit, lastname,"
14654                      "workdept, salary, bonus FROM t1");
14655 
14656   bzero(my_bind, sizeof(my_bind));
14657   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
14658   my_bind[0].buffer= (void*) &empno;
14659 
14660   my_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
14661   my_bind[1].buffer= (void*) firstname;
14662   my_bind[1].buffer_length= sizeof(firstname);
14663   my_bind[1].length= &firstname_len;
14664 
14665   my_bind[2].buffer_type= MYSQL_TYPE_VAR_STRING;
14666   my_bind[2].buffer= (void*) midinit;
14667   my_bind[2].buffer_length= sizeof(midinit);
14668   my_bind[2].length= &midinit_len;
14669 
14670   my_bind[3].buffer_type= MYSQL_TYPE_VAR_STRING;
14671   my_bind[3].buffer= (void*) lastname;
14672   my_bind[3].buffer_length= sizeof(lastname);
14673   my_bind[3].length= &lastname_len;
14674 
14675   my_bind[4].buffer_type= MYSQL_TYPE_VAR_STRING;
14676   my_bind[4].buffer= (void*) workdept;
14677   my_bind[4].buffer_length= sizeof(workdept);
14678   my_bind[4].length= &workdept_len;
14679 
14680   my_bind[5].buffer_type= MYSQL_TYPE_DOUBLE;
14681   my_bind[5].buffer= (void*) &salary;
14682 
14683   my_bind[6].buffer_type= MYSQL_TYPE_FLOAT;
14684   my_bind[6].buffer= (void*) &bonus;
14685   rc= mysql_stmt_bind_result(stmt1, my_bind);
14686   check_execute(stmt1, rc);
14687 
14688   rc= mysql_stmt_execute(stmt1);
14689   check_execute(stmt1, rc);
14690 
14691   rc= mysql_stmt_fetch(stmt1);
14692   DIE_UNLESS(rc == 0);
14693   DIE_UNLESS(empno == 10);
14694   DIE_UNLESS(strcmp(firstname, "CHRISTINE") == 0);
14695   DIE_UNLESS(strcmp(midinit, "I") == 0);
14696   DIE_UNLESS(strcmp(lastname, "HAAS") == 0);
14697   DIE_UNLESS(strcmp(workdept, "A00") == 0);
14698   DIE_UNLESS(salary == (double) 52750.0);
14699   DIE_UNLESS(bonus == (float) 1000.0);
14700 
14701   stmt2= open_cursor("SELECT empno, firstname FROM t1");
14702   rc= mysql_stmt_bind_result(stmt2, my_bind);
14703   check_execute(stmt2, rc);
14704 
14705   rc= mysql_stmt_execute(stmt2);
14706   check_execute(stmt2, rc);
14707 
14708   rc= mysql_stmt_fetch(stmt2);
14709   DIE_UNLESS(rc == 0);
14710 
14711   DIE_UNLESS(empno == 10);
14712   DIE_UNLESS(strcmp(firstname, "CHRISTINE") == 0);
14713 
14714   rc= mysql_stmt_reset(stmt2);
14715   check_execute(stmt2, rc);
14716 
14717   /* ERROR: next statement should return 0 */
14718 
14719   rc= mysql_stmt_fetch(stmt1);
14720   DIE_UNLESS(rc == 0);
14721 
14722   mysql_stmt_close(stmt1);
14723   mysql_stmt_close(stmt2);
14724   rc= mysql_rollback(mysql);
14725   myquery(rc);
14726 
14727   rc= mysql_query(mysql, "drop table t1");
14728   myquery(rc);
14729 }
14730 
14731 /* Cursors: opening a cursor to a compilicated query with ORDER BY */
14732 
test_bug11901()14733 static void test_bug11901()
14734 {
14735   MYSQL_STMT *stmt;
14736   MYSQL_BIND my_bind[2];
14737   int rc;
14738   char workdept[20];
14739   ulong workdept_len;
14740   uint32 empno;
14741   const char *stmt_text;
14742 
14743   myheader("test_bug11901");
14744 
14745   stmt_text= "drop table if exists t1, t2";
14746   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14747   myquery(rc);
14748 
14749   stmt_text= "create table t1 ("
14750     "  empno int(11) not null, firstname varchar(20) not null,"
14751     "  midinit varchar(20) not null, lastname varchar(20) not null,"
14752     "  workdept varchar(6) not null, salary double not null,"
14753     "  bonus float not null, primary key (empno), "
14754     " unique key (workdept, empno) "
14755     ") default charset=latin1 collate=latin1_bin";
14756   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14757   myquery(rc);
14758 
14759   stmt_text= "insert into t1 values "
14760      "(10,  'CHRISTINE', 'I', 'HAAS',      'A00', 52750, 1000),"
14761      "(20,  'MICHAEL',   'L', 'THOMPSON',  'B01', 41250, 800), "
14762      "(30,  'SALLY',     'A', 'KWAN',      'C01', 38250, 800), "
14763      "(50,  'JOHN',      'B', 'GEYER',     'E01', 40175, 800), "
14764      "(60,  'IRVING',    'F', 'STERN',     'D11', 32250, 500), "
14765      "(70,  'EVA',       'D', 'PULASKI',   'D21', 36170, 700), "
14766      "(90,  'EILEEN',    'W', 'HENDERSON', 'E11', 29750, 600), "
14767      "(100, 'THEODORE',  'Q', 'SPENSER',   'E21', 26150, 500), "
14768      "(110, 'VINCENZO',  'G', 'LUCCHESSI', 'A00', 46500, 900), "
14769      "(120, 'SEAN',      '',  'O\\'CONNELL', 'A00', 29250, 600), "
14770      "(130, 'DOLORES',   'M', 'QUINTANA',  'C01', 23800, 500), "
14771      "(140, 'HEATHER',   'A', 'NICHOLLS',  'C01', 28420, 600), "
14772      "(150, 'BRUCE',     '',  'ADAMSON',   'D11', 25280, 500), "
14773      "(160, 'ELIZABETH', 'R', 'PIANKA',    'D11', 22250, 400), "
14774      "(170, 'MASATOSHI', 'J', 'YOSHIMURA', 'D11', 24680, 500), "
14775      "(180, 'MARILYN',   'S', 'SCOUTTEN',  'D11', 21340, 500), "
14776      "(190, 'JAMES',     'H', 'WALKER',    'D11', 20450, 400), "
14777      "(200, 'DAVID',     '',  'BROWN',     'D11', 27740, 600), "
14778      "(210, 'WILLIAM',   'T', 'JONES',     'D11', 18270, 400), "
14779      "(220, 'JENNIFER',  'K', 'LUTZ',      'D11', 29840, 600), "
14780      "(230, 'JAMES',     'J', 'JEFFERSON', 'D21', 22180, 400), "
14781      "(240, 'SALVATORE', 'M', 'MARINO',    'D21', 28760, 600), "
14782      "(250, 'DANIEL',    'S', 'SMITH',     'D21', 19180, 400), "
14783      "(260, 'SYBIL',     'P', 'JOHNSON',   'D21', 17250, 300), "
14784      "(270, 'MARIA',     'L', 'PEREZ',     'D21', 27380, 500), "
14785      "(280, 'ETHEL',     'R', 'SCHNEIDER', 'E11', 26250, 500), "
14786      "(290, 'JOHN',      'R', 'PARKER',    'E11', 15340, 300), "
14787      "(300, 'PHILIP',    'X', 'SMITH',     'E11', 17750, 400), "
14788      "(310, 'MAUDE',     'F', 'SETRIGHT',  'E11', 15900, 300), "
14789      "(320, 'RAMLAL',    'V', 'MEHTA',     'E21', 19950, 400), "
14790      "(330, 'WING',      '',  'LEE',       'E21', 25370, 500), "
14791      "(340, 'JASON',     'R', 'GOUNOT',    'E21', 23840, 500)";
14792 
14793   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14794   myquery(rc);
14795 
14796   stmt_text= "create table t2 ("
14797     " deptno varchar(6) not null, deptname varchar(20) not null,"
14798     " mgrno int(11) not null, location varchar(20) not null,"
14799     " admrdept varchar(6) not null, refcntd int(11) not null,"
14800     " refcntu int(11) not null, primary key (deptno)"
14801     ") default charset=latin1 collate=latin1_bin";
14802   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14803   myquery(rc);
14804 
14805   stmt_text= "insert into t2 values "
14806     "('A00', 'SPIFFY COMPUTER SERV', 10, '', 'A00', 0, 0), "
14807     "('B01', 'PLANNING',             20, '', 'A00', 0, 0), "
14808     "('C01', 'INFORMATION CENTER',   30, '', 'A00', 0, 0), "
14809     "('D01', 'DEVELOPMENT CENTER',   0,  '', 'A00', 0, 0),"
14810     "('D11', 'MANUFACTURING SYSTEM', 60, '', 'D01', 0, 0), "
14811     "('D21', 'ADMINISTRATION SYSTE', 70, '', 'D01', 0, 0), "
14812     "('E01', 'SUPPORT SERVICES',     50, '', 'A00', 0, 0), "
14813     "('E11', 'OPERATIONS',           90, '', 'E01', 0, 0), "
14814     "('E21', 'SOFTWARE SUPPORT',     100,'', 'E01', 0, 0)";
14815   rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text));
14816   myquery(rc);
14817 
14818   /* ****** Begin of trace ****** */
14819 
14820   stmt= open_cursor("select t1.empno, t1.workdept "
14821                     "from (t1 left join t2 on t2.deptno = t1.workdept) "
14822                     "where t2.deptno in "
14823                     "   (select t2.deptno "
14824                     "    from (t1 left join t2 on t2.deptno = t1.workdept) "
14825                     "    where t1.empno = ?) "
14826                     "order by 1");
14827   bzero(my_bind, sizeof(my_bind));
14828 
14829   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
14830   my_bind[0].buffer= &empno;
14831   rc= mysql_stmt_bind_param(stmt, my_bind);
14832   check_execute(stmt, rc);
14833 
14834   my_bind[1].buffer_type= MYSQL_TYPE_VAR_STRING;
14835   my_bind[1].buffer= (void*) workdept;
14836   my_bind[1].buffer_length= sizeof(workdept);
14837   my_bind[1].length= &workdept_len;
14838 
14839   rc= mysql_stmt_bind_result(stmt, my_bind);
14840   check_execute(stmt, rc);
14841 
14842   empno= 10;
14843   /* ERROR: next statement causes a server crash */
14844   rc= mysql_stmt_execute(stmt);
14845   check_execute(stmt, rc);
14846 
14847   mysql_stmt_close(stmt);
14848 
14849   rc= mysql_query(mysql, "drop table t1, t2");
14850   myquery(rc);
14851 }
14852 
14853 /* Bug#11904: mysql_stmt_attr_set CURSOR_TYPE_READ_ONLY grouping wrong result */
14854 
test_bug11904()14855 static void test_bug11904()
14856 {
14857   MYSQL_STMT *stmt1;
14858   int rc;
14859   const char *stmt_text;
14860   const ulong type= (ulong)CURSOR_TYPE_READ_ONLY;
14861   MYSQL_BIND my_bind[2];
14862   int country_id=0;
14863   char row_data[11]= {0};
14864 
14865   myheader("test_bug11904");
14866 
14867   /* create tables */
14868   rc= mysql_query(mysql, "DROP TABLE IF EXISTS bug11904b");
14869   myquery(rc);
14870   rc= mysql_query(mysql, "CREATE TABLE bug11904b (id int, name char(10), primary key(id, name))");
14871   myquery(rc);
14872 
14873   rc= mysql_query(mysql, "INSERT INTO bug11904b VALUES (1, 'sofia'), (1,'plovdiv'),"
14874                           " (1,'varna'), (2,'LA'), (2,'new york'), (3,'heidelberg'),"
14875                           " (3,'berlin'), (3, 'frankfurt')");
14876 
14877   myquery(rc);
14878   mysql_commit(mysql);
14879   /* create statement */
14880   stmt1= mysql_stmt_init(mysql);
14881   mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14882 
14883   stmt_text= "SELECT id, MIN(name) FROM bug11904b GROUP BY id";
14884 
14885   rc= mysql_stmt_prepare(stmt1, stmt_text, strlen(stmt_text));
14886   check_execute(stmt1, rc);
14887 
14888   memset(my_bind, 0, sizeof(my_bind));
14889   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
14890   my_bind[0].buffer=& country_id;
14891   my_bind[0].buffer_length= 0;
14892   my_bind[0].length= 0;
14893 
14894   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
14895   my_bind[1].buffer=& row_data;
14896   my_bind[1].buffer_length= sizeof(row_data) - 1;
14897   my_bind[1].length= 0;
14898 
14899   rc= mysql_stmt_bind_result(stmt1, my_bind);
14900   check_execute(stmt1, rc);
14901 
14902   rc= mysql_stmt_execute(stmt1);
14903   check_execute(stmt1, rc);
14904 
14905   rc= mysql_stmt_fetch(stmt1);
14906   check_execute(stmt1, rc);
14907   DIE_UNLESS(country_id == 1);
14908   DIE_UNLESS(memcmp(row_data, "plovdiv", 7) == 0);
14909 
14910   rc= mysql_stmt_fetch(stmt1);
14911   check_execute(stmt1, rc);
14912   DIE_UNLESS(country_id == 2);
14913   DIE_UNLESS(memcmp(row_data, "LA", 2) == 0);
14914 
14915   rc= mysql_stmt_fetch(stmt1);
14916   check_execute(stmt1, rc);
14917   DIE_UNLESS(country_id == 3);
14918   DIE_UNLESS(memcmp(row_data, "berlin", 6) == 0);
14919 
14920   rc= mysql_stmt_close(stmt1);
14921   check_execute(stmt1, rc);
14922 
14923   rc= mysql_query(mysql, "drop table bug11904b");
14924   myquery(rc);
14925 }
14926 
14927 
14928 /* Bug#12243: multiple cursors, crash in a fetch after commit. */
14929 
test_bug12243()14930 static void test_bug12243()
14931 {
14932   MYSQL_STMT *stmt1, *stmt2;
14933   int rc;
14934   const char *stmt_text;
14935   ulong type;
14936 
14937   myheader("test_bug12243");
14938 
14939   if (! have_innodb)
14940   {
14941     if (!opt_silent)
14942       printf("This test requires InnoDB.\n");
14943     return;
14944   }
14945 
14946   /* create tables */
14947   mysql_query(mysql, "drop table if exists t1");
14948   mysql_query(mysql, "create table t1 (a int) engine=InnoDB");
14949   rc= mysql_query(mysql, "insert into t1 (a) values (1), (2)");
14950   myquery(rc);
14951   mysql_autocommit(mysql, FALSE);
14952   /* create statement */
14953   stmt1= mysql_stmt_init(mysql);
14954   stmt2= mysql_stmt_init(mysql);
14955   type= (ulong) CURSOR_TYPE_READ_ONLY;
14956   mysql_stmt_attr_set(stmt1, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14957   mysql_stmt_attr_set(stmt2, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
14958 
14959   stmt_text= "select a from t1";
14960 
14961   rc= mysql_stmt_prepare(stmt1, stmt_text, strlen(stmt_text));
14962   check_execute(stmt1, rc);
14963   rc= mysql_stmt_execute(stmt1);
14964   check_execute(stmt1, rc);
14965   rc= mysql_stmt_fetch(stmt1);
14966   check_execute(stmt1, rc);
14967 
14968   rc= mysql_stmt_prepare(stmt2, stmt_text, strlen(stmt_text));
14969   check_execute(stmt2, rc);
14970   rc= mysql_stmt_execute(stmt2);
14971   check_execute(stmt2, rc);
14972   rc= mysql_stmt_fetch(stmt2);
14973   check_execute(stmt2, rc);
14974 
14975   rc= mysql_stmt_close(stmt1);
14976   check_execute(stmt1, rc);
14977   rc= mysql_commit(mysql);
14978   myquery(rc);
14979   rc= mysql_stmt_fetch(stmt2);
14980   check_execute(stmt2, rc);
14981 
14982   mysql_stmt_close(stmt2);
14983   rc= mysql_query(mysql, "drop table t1");
14984   myquery(rc);
14985   mysql_autocommit(mysql, TRUE);                /* restore default */
14986 }
14987 
14988 
14989 /*
14990   Bug#11718: query with function, join and order by returns wrong type
14991 */
14992 
test_bug11718()14993 static void test_bug11718()
14994 {
14995   MYSQL_RES	*res;
14996   int rc;
14997   const char *query= "select str_to_date(concat(f3),'%Y%m%d') from t1,t2 "
14998                      "where f1=f2 order by f1";
14999 
15000   myheader("test_bug11718");
15001 
15002   rc= mysql_query(mysql, "drop table if exists t1, t2");
15003   myquery(rc);
15004   rc= mysql_query(mysql, "create table t1 (f1 int)");
15005   myquery(rc);
15006   rc= mysql_query(mysql, "create table t2 (f2 int, f3 numeric(8))");
15007   myquery(rc);
15008   rc= mysql_query(mysql, "insert into t1 values (1), (2)");
15009   myquery(rc);
15010   rc= mysql_query(mysql, "insert into t2 values (1,20050101), (2,20050202)");
15011   myquery(rc);
15012   rc= mysql_query(mysql, query);
15013   myquery(rc);
15014   res = mysql_store_result(mysql);
15015 
15016   if (!opt_silent)
15017     printf("return type: %s", (res->fields[0].type == MYSQL_TYPE_DATE)?"DATE":
15018            "not DATE");
15019   DIE_UNLESS(res->fields[0].type == MYSQL_TYPE_DATE);
15020   mysql_free_result(res);
15021   rc= mysql_query(mysql, "drop table t1, t2");
15022   myquery(rc);
15023 }
15024 
15025 
15026 /*
15027   Bug #12925: Bad handling of maximum values in getopt
15028 */
test_bug12925()15029 static void test_bug12925()
15030 {
15031   myheader("test_bug12925");
15032   if (opt_getopt_ll_test)
15033     DIE_UNLESS(opt_getopt_ll_test == 25600LL*1024*1024);
15034 }
15035 
15036 
15037 /*
15038   Bug#14210 "Simple query with > operator on large table gives server
15039   crash"
15040 */
15041 
test_bug14210()15042 static void test_bug14210()
15043 {
15044   MYSQL_STMT *stmt;
15045   int rc, i;
15046   const char *stmt_text;
15047   ulong type;
15048 
15049   myheader("test_bug14210");
15050 
15051   mysql_query(mysql, "drop table if exists t1");
15052   /*
15053     To trigger the problem the table must be InnoDB, although the problem
15054     itself is not InnoDB related. In case the table is MyISAM this test
15055     is harmless.
15056   */
15057   mysql_query(mysql, "create table t1 (a varchar(255)) engine=InnoDB");
15058   rc= mysql_query(mysql, "insert into t1 (a) values (repeat('a', 256))");
15059   myquery(rc);
15060   rc= mysql_query(mysql, "set @@session.max_heap_table_size=16384");
15061   /* Create a big enough table (more than max_heap_table_size) */
15062   for (i= 0; i < 8; i++)
15063   {
15064     rc= mysql_query(mysql, "insert into t1 (a) select a from t1");
15065     myquery(rc);
15066   }
15067   /* create statement */
15068   stmt= mysql_stmt_init(mysql);
15069   type= (ulong) CURSOR_TYPE_READ_ONLY;
15070   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
15071 
15072   stmt_text= "select a from t1";
15073 
15074   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
15075   check_execute(stmt, rc);
15076   rc= mysql_stmt_execute(stmt);
15077   while ((rc= mysql_stmt_fetch(stmt)) == 0)
15078     ;
15079   DIE_UNLESS(rc == MYSQL_NO_DATA);
15080 
15081   rc= mysql_stmt_close(stmt);
15082 
15083   rc= mysql_query(mysql, "drop table t1");
15084   myquery(rc);
15085   rc= mysql_query(mysql, "set @@session.max_heap_table_size=default");
15086   myquery(rc);
15087 }
15088 
15089 /* Bug#13488: wrong column metadata when fetching from cursor */
15090 
test_bug13488()15091 static void test_bug13488()
15092 {
15093   MYSQL_BIND my_bind[3];
15094   MYSQL_STMT *stmt1;
15095   int rc, f1, f2, f3, i;
15096   const ulong type= CURSOR_TYPE_READ_ONLY;
15097   const char *query= "select * from t1 left join t2 on f1=f2 where f1=1";
15098 
15099   myheader("test_bug13488");
15100 
15101   rc= mysql_query(mysql, "drop table if exists t1, t2");
15102   myquery(rc);
15103   rc= mysql_query(mysql, "create table t1 (f1 int not null primary key)");
15104   myquery(rc);
15105   rc= mysql_query(mysql, "create table t2 (f2 int not null primary key, "
15106                   "f3 int not null)");
15107   myquery(rc);
15108   rc= mysql_query(mysql, "insert into t1 values (1), (2)");
15109   myquery(rc);
15110   rc= mysql_query(mysql, "insert into t2 values (1,2), (2,4)");
15111   myquery(rc);
15112 
15113   memset(my_bind, 0, sizeof(my_bind));
15114   for (i= 0; i < 3; i++)
15115   {
15116     my_bind[i].buffer_type= MYSQL_TYPE_LONG;
15117     my_bind[i].buffer_length= 4;
15118     my_bind[i].length= 0;
15119   }
15120   my_bind[0].buffer=&f1;
15121   my_bind[1].buffer=&f2;
15122   my_bind[2].buffer=&f3;
15123 
15124   stmt1= mysql_stmt_init(mysql);
15125   rc= mysql_stmt_attr_set(stmt1,STMT_ATTR_CURSOR_TYPE, (const void *)&type);
15126   check_execute(stmt1, rc);
15127 
15128   rc= mysql_stmt_prepare(stmt1, query, strlen(query));
15129   check_execute(stmt1, rc);
15130 
15131   rc= mysql_stmt_execute(stmt1);
15132   check_execute(stmt1, rc);
15133 
15134   rc= mysql_stmt_bind_result(stmt1, my_bind);
15135   check_execute(stmt1, rc);
15136 
15137   rc= mysql_stmt_fetch(stmt1);
15138   check_execute(stmt1, rc);
15139 
15140   rc= mysql_stmt_free_result(stmt1);
15141   check_execute(stmt1, rc);
15142 
15143   rc= mysql_stmt_reset(stmt1);
15144   check_execute(stmt1, rc);
15145 
15146   rc= mysql_stmt_close(stmt1);
15147   check_execute(stmt1, rc);
15148 
15149   if (!opt_silent)
15150   {
15151     printf("data: f1: %d; f2: %d; f3: %d\n", f1, f2, f3);
15152     printf("data is: %s\n",
15153            (f1 == 1 && f2 == 1 && f3 == 2) ? "OK" : "wrong");
15154   }
15155   DIE_UNLESS(f1 == 1 && f2 == 1 && f3 == 2);
15156   rc= mysql_query(mysql, "drop table t1, t2");
15157   myquery(rc);
15158 }
15159 
15160 /*
15161   Bug#13524: warnings of a previous command are not reset when fetching
15162   from a cursor.
15163 */
15164 
test_bug13524()15165 static void test_bug13524()
15166 {
15167   MYSQL_STMT *stmt;
15168   int rc;
15169   unsigned int warning_count;
15170   const ulong type= CURSOR_TYPE_READ_ONLY;
15171   const char *query= "select * from t1";
15172 
15173   myheader("test_bug13524");
15174 
15175   rc= mysql_query(mysql, "drop table if exists t1, t2");
15176   myquery(rc);
15177   rc= mysql_query(mysql, "create table t1 (a int not null primary key)");
15178   myquery(rc);
15179   rc= mysql_query(mysql, "insert into t1 values (1), (2), (3), (4)");
15180   myquery(rc);
15181 
15182   stmt= mysql_stmt_init(mysql);
15183   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
15184   check_execute(stmt, rc);
15185 
15186   rc= mysql_stmt_prepare(stmt, query, strlen(query));
15187   check_execute(stmt, rc);
15188 
15189   rc= mysql_stmt_execute(stmt);
15190   check_execute(stmt, rc);
15191 
15192   rc= mysql_stmt_fetch(stmt);
15193   check_execute(stmt, rc);
15194 
15195   warning_count= mysql_warning_count(mysql);
15196   DIE_UNLESS(warning_count == 0);
15197 
15198   /* Check that DROP TABLE produced a warning (no such table) */
15199   rc= mysql_query(mysql, "drop table if exists t2");
15200   myquery(rc);
15201   warning_count= mysql_warning_count(mysql);
15202   DIE_UNLESS(warning_count == 1);
15203 
15204   /*
15205     Check that fetch from a cursor cleared the warning from the previous
15206     command.
15207   */
15208   rc= mysql_stmt_fetch(stmt);
15209   check_execute(stmt, rc);
15210   warning_count= mysql_warning_count(mysql);
15211   DIE_UNLESS(warning_count == 0);
15212 
15213   /* Cleanup */
15214   mysql_stmt_close(stmt);
15215   rc= mysql_query(mysql, "drop table t1");
15216   myquery(rc);
15217 }
15218 
15219 /*
15220   Bug#14845 "mysql_stmt_fetch returns MYSQL_NO_DATA when COUNT(*) is 0"
15221 */
15222 
test_bug14845()15223 static void test_bug14845()
15224 {
15225   MYSQL_STMT *stmt;
15226   int rc;
15227   const ulong type= CURSOR_TYPE_READ_ONLY;
15228   const char *query= "select count(*) from t1 where 1 = 0";
15229 
15230   myheader("test_bug14845");
15231 
15232   rc= mysql_query(mysql, "drop table if exists t1");
15233   myquery(rc);
15234   rc= mysql_query(mysql, "create table t1 (id int(11) default null, "
15235                          "name varchar(20) default null)"
15236                          "engine=MyISAM DEFAULT CHARSET=utf8");
15237   myquery(rc);
15238   rc= mysql_query(mysql, "insert into t1 values (1,'abc'),(2,'def')");
15239   myquery(rc);
15240 
15241   stmt= mysql_stmt_init(mysql);
15242   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void*) &type);
15243   check_execute(stmt, rc);
15244 
15245   rc= mysql_stmt_prepare(stmt, query, strlen(query));
15246   check_execute(stmt, rc);
15247 
15248   rc= mysql_stmt_execute(stmt);
15249   check_execute(stmt, rc);
15250 
15251   rc= mysql_stmt_fetch(stmt);
15252   DIE_UNLESS(rc == 0);
15253 
15254   rc= mysql_stmt_fetch(stmt);
15255   DIE_UNLESS(rc == MYSQL_NO_DATA);
15256 
15257   /* Cleanup */
15258   mysql_stmt_close(stmt);
15259   rc= mysql_query(mysql, "drop table t1");
15260   myquery(rc);
15261 }
15262 
15263 
15264 /*
15265   Bug #15510: mysql_warning_count returns 0 after mysql_stmt_fetch which
15266   should warn
15267 */
test_bug15510()15268 static void test_bug15510()
15269 {
15270   MYSQL_STMT *stmt;
15271   int rc;
15272   const char *query= "select 1 from dual where 1/0";
15273 
15274   myheader("test_bug15510");
15275 
15276   rc= mysql_query(mysql, "set @@sql_mode='ERROR_FOR_DIVISION_BY_ZERO'");
15277   myquery(rc);
15278 
15279   stmt= mysql_stmt_init(mysql);
15280 
15281   rc= mysql_stmt_prepare(stmt, query, strlen(query));
15282   check_execute(stmt, rc);
15283 
15284   rc= mysql_stmt_execute(stmt);
15285   check_execute(stmt, rc);
15286 
15287   rc= mysql_stmt_fetch(stmt);
15288   DIE_UNLESS(mysql_warning_count(mysql));
15289 
15290   /* Cleanup */
15291   mysql_stmt_close(stmt);
15292   rc= mysql_query(mysql, "set @@sql_mode=''");
15293   myquery(rc);
15294 }
15295 
15296 
15297 /* Test MYSQL_OPT_RECONNECT, Bug#15719 */
15298 
test_opt_reconnect()15299 static void test_opt_reconnect()
15300 {
15301   MYSQL *lmysql;
15302 
15303 
15304   myheader("test_opt_reconnect");
15305 
15306   if (!(lmysql= mysql_client_init(NULL)))
15307   {
15308     myerror("mysql_client_init() failed");
15309     exit(1);
15310   }
15311 
15312   if (!opt_silent)
15313     fprintf(stdout, "reconnect before mysql_options: %d\n", get_reconnect(lmysql));
15314   DIE_UNLESS(get_reconnect(lmysql) == 0);
15315 
15316   if (mysql_options(lmysql, MYSQL_OPT_RECONNECT, &my_true))
15317   {
15318     myerror("mysql_options failed: unknown option MYSQL_OPT_RECONNECT\n");
15319     DIE_UNLESS(0);
15320   }
15321 
15322   /* reconnect should be 1 */
15323   if (!opt_silent)
15324     fprintf(stdout, "reconnect after mysql_options: %d\n", get_reconnect(lmysql));
15325   DIE_UNLESS(get_reconnect(lmysql) == 1);
15326 
15327   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
15328                            opt_password, current_db, opt_port,
15329                            opt_unix_socket, 0)))
15330   {
15331     myerror("connection failed");
15332     DIE_UNLESS(0);
15333   }
15334 
15335   /* reconnect should still be 1 */
15336   if (!opt_silent)
15337     fprintf(stdout, "reconnect after mysql_real_connect: %d\n",
15338 	    get_reconnect(lmysql));
15339   DIE_UNLESS(get_reconnect(lmysql) == 1);
15340 
15341   mysql_close(lmysql);
15342 
15343   if (!(lmysql= mysql_client_init(NULL)))
15344   {
15345     myerror("mysql_client_init() failed");
15346     DIE_UNLESS(0);
15347   }
15348 
15349   if (!opt_silent)
15350     fprintf(stdout, "reconnect before mysql_real_connect: %d\n", get_reconnect(lmysql));
15351   DIE_UNLESS(get_reconnect(lmysql) == 0);
15352 
15353   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
15354                            opt_password, current_db, opt_port,
15355                            opt_unix_socket, 0)))
15356   {
15357     myerror("connection failed");
15358     DIE_UNLESS(0);
15359   }
15360 
15361   /* reconnect should still be 0 */
15362   if (!opt_silent)
15363     fprintf(stdout, "reconnect after mysql_real_connect: %d\n",
15364 	    get_reconnect(lmysql));
15365   DIE_UNLESS(get_reconnect(lmysql) == 0);
15366 
15367   mysql_close(lmysql);
15368 }
15369 
15370 
15371 #ifndef EMBEDDED_LIBRARY
15372 
test_bug12744()15373 static void test_bug12744()
15374 {
15375   MYSQL_STMT *prep_stmt = NULL;
15376   MYSQL *lmysql;
15377   int rc;
15378   myheader("test_bug12744");
15379 
15380   lmysql= mysql_client_init(NULL);
15381   DIE_UNLESS(lmysql);
15382 
15383   if (!mysql_real_connect(lmysql, opt_host, opt_user, opt_password,
15384                           current_db, opt_port, opt_unix_socket, 0))
15385   {
15386     fprintf(stderr, "Failed to connect to the database\n");
15387     DIE_UNLESS(0);
15388   }
15389 
15390   prep_stmt= mysql_stmt_init(lmysql);
15391   rc= mysql_stmt_prepare(prep_stmt, "SELECT 1", 8);
15392   DIE_UNLESS(rc == 0);
15393 
15394   mysql_close(lmysql);
15395 
15396   rc= mysql_stmt_execute(prep_stmt);
15397   DIE_UNLESS(rc);
15398   rc= mysql_stmt_reset(prep_stmt);
15399   DIE_UNLESS(rc);
15400   rc= mysql_stmt_close(prep_stmt);
15401   DIE_UNLESS(rc == 0);
15402 }
15403 
15404 #endif /* EMBEDDED_LIBRARY */
15405 
15406 /* Bug #16143: mysql_stmt_sqlstate returns an empty string instead of '00000' */
15407 
test_bug16143()15408 static void test_bug16143()
15409 {
15410   MYSQL_STMT *stmt;
15411   myheader("test_bug16143");
15412 
15413   stmt= mysql_stmt_init(mysql);
15414   /* Check mysql_stmt_sqlstate return "no error" */
15415   DIE_UNLESS(strcmp(mysql_stmt_sqlstate(stmt), "00000") == 0);
15416 
15417   mysql_stmt_close(stmt);
15418 }
15419 
15420 
15421 /* Bug #16144: mysql_stmt_attr_get type error */
15422 
test_bug16144()15423 static void test_bug16144()
15424 {
15425   const my_bool flag_orig= (my_bool) 0xde;
15426   my_bool flag= flag_orig;
15427   MYSQL_STMT *stmt;
15428   myheader("test_bug16144");
15429 
15430   /* Check that attr_get returns correct data on little and big endian CPUs */
15431   stmt= mysql_stmt_init(mysql);
15432   mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (const void*) &flag);
15433   mysql_stmt_attr_get(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &flag);
15434   DIE_UNLESS(flag == flag_orig);
15435 
15436   mysql_stmt_close(stmt);
15437 }
15438 
15439 /*
15440   Bug #15613: "libmysqlclient API function mysql_stmt_prepare returns wrong
15441   field length"
15442 */
15443 
test_bug15613()15444 static void test_bug15613()
15445 {
15446   MYSQL_STMT *stmt;
15447   const char *stmt_text;
15448   MYSQL_RES *metadata;
15449   MYSQL_FIELD *field;
15450   int rc;
15451   myheader("test_bug15613");
15452 
15453   /* I. Prepare the table */
15454   rc= mysql_query(mysql, "set names latin1");
15455   myquery(rc);
15456   mysql_query(mysql, "drop table if exists t1");
15457   rc= mysql_query(mysql,
15458                   "create table t1 (t text character set utf8, "
15459                                    "tt tinytext character set utf8, "
15460                                    "mt mediumtext character set utf8, "
15461                                    "lt longtext character set utf8, "
15462                                    "vl varchar(255) character set latin1,"
15463                                    "vb varchar(255) character set binary,"
15464                                    "vu varchar(255) character set utf8)");
15465   myquery(rc);
15466 
15467   stmt= mysql_stmt_init(mysql);
15468 
15469   /* II. Check SELECT metadata */
15470   stmt_text= ("select t, tt, mt, lt, vl, vb, vu from t1");
15471   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
15472   metadata= mysql_stmt_result_metadata(stmt);
15473   field= mysql_fetch_fields(metadata);
15474   if (!opt_silent)
15475   {
15476     printf("Field lengths (client character set is latin1):\n"
15477            "text character set utf8:\t\t%lu\n"
15478            "tinytext character set utf8:\t\t%lu\n"
15479            "mediumtext character set utf8:\t\t%lu\n"
15480            "longtext character set utf8:\t\t%lu\n"
15481            "varchar(255) character set latin1:\t%lu\n"
15482            "varchar(255) character set binary:\t%lu\n"
15483            "varchar(255) character set utf8:\t%lu\n",
15484            field[0].length, field[1].length, field[2].length, field[3].length,
15485            field[4].length, field[5].length, field[6].length);
15486   }
15487   DIE_UNLESS(field[0].length == 65535);
15488   DIE_UNLESS(field[1].length == 255);
15489   DIE_UNLESS(field[2].length == 16777215);
15490   DIE_UNLESS(field[3].length == 4294967295UL);
15491   DIE_UNLESS(field[4].length == 255);
15492   DIE_UNLESS(field[5].length == 255);
15493   DIE_UNLESS(field[6].length == 255);
15494   mysql_free_result(metadata);
15495   mysql_stmt_free_result(stmt);
15496 
15497   /* III. Cleanup */
15498   rc= mysql_query(mysql, "drop table t1");
15499   myquery(rc);
15500   rc= mysql_query(mysql, "set names default");
15501   myquery(rc);
15502   mysql_stmt_close(stmt);
15503 }
15504 
15505 /*
15506   Bug#17667: An attacker has the opportunity to bypass query logging.
15507 
15508   Note! Also tests Bug#21813, where prepared statements are used to
15509   run queries
15510 */
test_bug17667()15511 static void test_bug17667()
15512 {
15513   int rc;
15514   MYSQL_STMT *stmt;
15515   enum query_type { QT_NORMAL, QT_PREPARED};
15516   struct buffer_and_length {
15517     enum query_type qt;
15518     const char *buffer;
15519     const uint length;
15520   } statements[]= {
15521     { QT_NORMAL, "drop table if exists bug17667", 29 },
15522     { QT_NORMAL, "create table bug17667 (c varchar(20))", 37 },
15523     { QT_NORMAL, "insert into bug17667 (c) values ('regular') /* NUL=\0 with comment */", 68 },
15524     { QT_PREPARED,
15525       "insert into bug17667 (c) values ('prepared') /* NUL=\0 with comment */", 69, },
15526     { QT_NORMAL, "insert into bug17667 (c) values ('NUL=\0 in value')", 50 },
15527     { QT_NORMAL, "insert into bug17667 (c) values ('5 NULs=\0\0\0\0\0')", 48 },
15528     { QT_PREPARED, "insert into bug17667 (c) values ('6 NULs=\0\0\0\0\0\0')", 50 },
15529     { QT_NORMAL, "/* NUL=\0 with comment */ insert into bug17667 (c) values ('encore')", 67 },
15530     { QT_NORMAL, "drop table bug17667", 19 },
15531     { QT_NORMAL, NULL, 0 } };
15532 
15533   struct buffer_and_length *statement_cursor;
15534   FILE *log_file;
15535   char *master_log_filename;
15536 
15537   myheader("test_bug17667");
15538 
15539   master_log_filename = (char *) malloc(strlen(opt_vardir) + strlen("/log/master.log") + 1);
15540   strxmov(master_log_filename, opt_vardir, "/log/master.log", NullS);
15541   if (!opt_silent)
15542     printf("Opening '%s'\n", master_log_filename);
15543   log_file= my_fopen(master_log_filename, (int) (O_RDONLY | O_BINARY), MYF(0));
15544   free(master_log_filename);
15545 
15546   if (log_file == NULL)
15547   {
15548     if (!opt_silent)
15549     {
15550       printf("Could not find the log file, VARDIR/log/master.log, so "
15551              "test_bug17667 is not run.\n"
15552              "Run test from the mysql-test/mysql-test-run* program to set up "
15553              "correct environment for this test.\n\n");
15554     }
15555     return;
15556   }
15557 
15558   enable_query_logs(1);
15559 
15560   for (statement_cursor= statements; statement_cursor->buffer != NULL;
15561        statement_cursor++)
15562   {
15563     if (statement_cursor->qt == QT_NORMAL)
15564     {
15565       /* Run statement as normal query */
15566       rc= mysql_real_query(mysql, statement_cursor->buffer,
15567                            statement_cursor->length);
15568       myquery(rc);
15569     }
15570     else if (statement_cursor->qt == QT_PREPARED)
15571     {
15572       /*
15573         Run as prepared statement
15574 
15575         NOTE! All these queries should be in the log twice,
15576         one time for prepare and one time for execute
15577       */
15578       stmt= mysql_stmt_init(mysql);
15579 
15580       rc= mysql_stmt_prepare(stmt, statement_cursor->buffer,
15581                              statement_cursor->length);
15582       check_execute(stmt, rc);
15583 
15584       rc= mysql_stmt_execute(stmt);
15585       check_execute(stmt, rc);
15586 
15587       mysql_stmt_close(stmt);
15588     }
15589     else
15590     {
15591       DIE_UNLESS(0==1);
15592     }
15593   }
15594 
15595   /* Make sure the server has written the logs to disk before reading it */
15596   rc= mysql_query(mysql, "flush logs");
15597   myquery(rc);
15598 
15599   for (statement_cursor= statements; statement_cursor->buffer != NULL;
15600        statement_cursor++)
15601   {
15602     int expected_hits= 1, hits= 0;
15603     char line_buffer[MAX_TEST_QUERY_LENGTH*2];
15604     /* more than enough room for the query and some marginalia. */
15605 
15606     /* Prepared statments always occurs twice in log */
15607     if (statement_cursor->qt == QT_PREPARED)
15608       expected_hits++;
15609 
15610     /* Loop until we found expected number of log entries */
15611     do {
15612       /* Loop until statement is found in log */
15613       do {
15614         memset(line_buffer, '/', MAX_TEST_QUERY_LENGTH*2);
15615 
15616         if(fgets(line_buffer, MAX_TEST_QUERY_LENGTH*2, log_file) == NULL)
15617         {
15618           /* If fgets returned NULL, it indicates either error or EOF */
15619           if (feof(log_file))
15620             DIE("Found EOF before all statements where found");
15621 
15622           fprintf(stderr, "Got error %d while reading from file\n",
15623                   ferror(log_file));
15624           DIE("Read error");
15625         }
15626 
15627       } while (my_memmem(line_buffer, MAX_TEST_QUERY_LENGTH*2,
15628                          statement_cursor->buffer,
15629                          statement_cursor->length) == NULL);
15630       hits++;
15631     } while (hits < expected_hits);
15632 
15633     if (!opt_silent)
15634       printf("Found statement starting with \"%s\"\n",
15635              statement_cursor->buffer);
15636   }
15637 
15638   restore_query_logs();
15639 
15640   if (!opt_silent)
15641     printf("success.  All queries found intact in the log.\n");
15642 
15643   my_fclose(log_file, MYF(0));
15644 }
15645 
15646 
15647 /*
15648   Bug#14169: type of group_concat() result changed to blob if tmp_table was
15649   used
15650 */
test_bug14169()15651 static void test_bug14169()
15652 {
15653   MYSQL_STMT *stmt;
15654   const char *stmt_text;
15655   MYSQL_RES *res;
15656   MYSQL_FIELD *field;
15657   int rc;
15658 
15659   myheader("test_bug14169");
15660 
15661   rc= mysql_query(mysql, "drop table if exists t1");
15662   myquery(rc);
15663   rc= mysql_query(mysql, "set session group_concat_max_len=1024");
15664   myquery(rc);
15665   rc= mysql_query(mysql, "create table t1 (f1 int unsigned, f2 varchar(255))");
15666   myquery(rc);
15667   rc= mysql_query(mysql, "insert into t1 values (1,repeat('a',255)),"
15668                          "(2,repeat('b',255))");
15669   myquery(rc);
15670   stmt= mysql_stmt_init(mysql);
15671   stmt_text= "select f2,group_concat(f1) from t1 group by f2";
15672   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
15673   myquery(rc);
15674   res= mysql_stmt_result_metadata(stmt);
15675   field= mysql_fetch_fields(res);
15676   if (!opt_silent)
15677     printf("GROUP_CONCAT() result type %i", field[1].type);
15678   DIE_UNLESS(field[1].type == MYSQL_TYPE_BLOB);
15679   mysql_free_result(res);
15680   mysql_stmt_free_result(stmt);
15681   mysql_stmt_close(stmt);
15682 
15683   rc= mysql_query(mysql, "drop table t1");
15684   myquery(rc);
15685 
15686   rc= mysql_query(mysql, "set session group_concat_max_len=@@global.group_concat_max_len");
15687   myquery(rc);
15688 }
15689 
15690 /*
15691    Test that mysql_insert_id() behaves as documented in our manual
15692 */
test_mysql_insert_id()15693 static void test_mysql_insert_id()
15694 {
15695   my_ulonglong res;
15696   int rc;
15697 
15698   myheader("test_mysql_insert_id");
15699 
15700   rc= mysql_query(mysql, "drop table if exists t1,t2");
15701   myquery(rc);
15702   /* table without auto_increment column */
15703   rc= mysql_query(mysql, "create table t1 (f1 int, f2 varchar(255), key(f1))");
15704   myquery(rc);
15705   rc= mysql_query(mysql, "insert into t1 values (1,'a')");
15706   myquery(rc);
15707   res= mysql_insert_id(mysql);
15708   DIE_UNLESS(res == 0);
15709   rc= mysql_query(mysql, "insert into t1 values (null,'b')");
15710   myquery(rc);
15711   res= mysql_insert_id(mysql);
15712   DIE_UNLESS(res == 0);
15713   rc= mysql_query(mysql, "insert into t1 select 5,'c'");
15714   myquery(rc);
15715   res= mysql_insert_id(mysql);
15716   DIE_UNLESS(res == 0);
15717 
15718   /*
15719     Test for bug #34889: mysql_client_test::test_mysql_insert_id test fails
15720     sporadically
15721   */
15722   rc= mysql_query(mysql, "create table t2 (f1 int not null primary key auto_increment, f2 varchar(255))");
15723   myquery(rc);
15724   rc= mysql_query(mysql, "insert into t2 values (null,'b')");
15725   myquery(rc);
15726   rc= mysql_query(mysql, "insert into t1 select 5,'c'");
15727   myquery(rc);
15728   res= mysql_insert_id(mysql);
15729   DIE_UNLESS(res == 0);
15730   rc= mysql_query(mysql, "drop table t2");
15731   myquery(rc);
15732 
15733   rc= mysql_query(mysql, "insert into t1 select null,'d'");
15734   myquery(rc);
15735   res= mysql_insert_id(mysql);
15736   DIE_UNLESS(res == 0);
15737   rc= mysql_query(mysql, "insert into t1 values (null,last_insert_id(300))");
15738   myquery(rc);
15739   res= mysql_insert_id(mysql);
15740   DIE_UNLESS(res == 300);
15741   rc= mysql_query(mysql, "insert into t1 select null,last_insert_id(400)");
15742   myquery(rc);
15743   res= mysql_insert_id(mysql);
15744   /*
15745     Behaviour change: old code used to return 0; but 400 is consistent
15746     with INSERT VALUES, and the manual's section of mysql_insert_id() does not
15747     say INSERT SELECT should be different.
15748   */
15749   DIE_UNLESS(res == 400);
15750 
15751   /* table with auto_increment column */
15752   rc= mysql_query(mysql, "create table t2 (f1 int not null primary key auto_increment, f2 varchar(255))");
15753   myquery(rc);
15754   rc= mysql_query(mysql, "insert into t2 values (1,'a')");
15755   myquery(rc);
15756   res= mysql_insert_id(mysql);
15757   DIE_UNLESS(res == 1);
15758   /* this should not influence next INSERT if it doesn't have auto_inc */
15759   rc= mysql_query(mysql, "insert into t1 values (10,'e')");
15760   myquery(rc);
15761   res= mysql_insert_id(mysql);
15762   DIE_UNLESS(res == 0);
15763 
15764   rc= mysql_query(mysql, "insert into t2 values (null,'b')");
15765   myquery(rc);
15766   res= mysql_insert_id(mysql);
15767   DIE_UNLESS(res == 2);
15768   rc= mysql_query(mysql, "insert into t2 select 5,'c'");
15769   myquery(rc);
15770   res= mysql_insert_id(mysql);
15771   /*
15772     Manual says that for multirow insert this should have been 5, but does not
15773     say for INSERT SELECT. This is a behaviour change: old code used to return
15774     0. We try to be consistent with INSERT VALUES.
15775   */
15776   DIE_UNLESS(res == 5);
15777   rc= mysql_query(mysql, "insert into t2 select null,'d'");
15778   myquery(rc);
15779   res= mysql_insert_id(mysql);
15780   DIE_UNLESS(res == 6);
15781   /* with more than one row */
15782   rc= mysql_query(mysql, "insert into t2 values (10,'a'),(11,'b')");
15783   myquery(rc);
15784   res= mysql_insert_id(mysql);
15785   DIE_UNLESS(res == 11);
15786   rc= mysql_query(mysql, "insert into t2 select 12,'a' union select 13,'b'");
15787   myquery(rc);
15788   res= mysql_insert_id(mysql);
15789   /*
15790     Manual says that for multirow insert this should have been 13, but does
15791     not say for INSERT SELECT. This is a behaviour change: old code used to
15792     return 0. We try to be consistent with INSERT VALUES.
15793   */
15794   DIE_UNLESS(res == 13);
15795   rc= mysql_query(mysql, "insert into t2 values (null,'a'),(null,'b')");
15796   myquery(rc);
15797   res= mysql_insert_id(mysql);
15798   DIE_UNLESS(res == 14);
15799   rc= mysql_query(mysql, "insert into t2 select null,'a' union select null,'b'");
15800   myquery(rc);
15801   res= mysql_insert_id(mysql);
15802   DIE_UNLESS(res == 16);
15803   rc= mysql_query(mysql, "insert into t2 select 12,'a' union select 13,'b'");
15804   myquery_r(rc);
15805   rc= mysql_query(mysql, "insert ignore into t2 select 12,'a' union select 13,'b'");
15806   myquery(rc);
15807   res= mysql_insert_id(mysql);
15808   DIE_UNLESS(res == 0);
15809   rc= mysql_query(mysql, "insert into t2 values (12,'a'),(13,'b')");
15810   myquery_r(rc);
15811   res= mysql_insert_id(mysql);
15812   DIE_UNLESS(res == 0);
15813   rc= mysql_query(mysql, "insert ignore into t2 values (12,'a'),(13,'b')");
15814   myquery(rc);
15815   res= mysql_insert_id(mysql);
15816   DIE_UNLESS(res == 0);
15817   /* mixing autogenerated and explicit values */
15818   rc= mysql_query(mysql, "insert into t2 values (null,'e'),(12,'a'),(13,'b')");
15819   myquery_r(rc);
15820   rc= mysql_query(mysql, "insert into t2 values (null,'e'),(12,'a'),(13,'b'),(25,'g')");
15821   myquery_r(rc);
15822   rc= mysql_query(mysql, "insert into t2 values (null,last_insert_id(300))");
15823   myquery(rc);
15824   res= mysql_insert_id(mysql);
15825   /*
15826     according to the manual, this might be 20 or 300, but it looks like
15827     auto_increment column takes priority over last_insert_id().
15828   */
15829   DIE_UNLESS(res == 20);
15830   /* If first autogenerated number fails and 2nd works: */
15831   rc= mysql_query(mysql, "drop table t2");
15832   myquery(rc);
15833   rc= mysql_query(mysql, "create table t2 (f1 int not null primary key "
15834                   "auto_increment, f2 varchar(255), unique (f2))");
15835   myquery(rc);
15836   rc= mysql_query(mysql, "insert into t2 values (null,'e')");
15837   res= mysql_insert_id(mysql);
15838   DIE_UNLESS(res == 1);
15839   rc= mysql_query(mysql, "insert ignore into t2 values (null,'e'),(null,'a'),(null,'e')");
15840   myquery(rc);
15841   res= mysql_insert_id(mysql);
15842   DIE_UNLESS(res == 2);
15843   /* If autogenerated fails and explicit works: */
15844   rc= mysql_query(mysql, "insert ignore into t2 values (null,'e'),(12,'c'),(null,'d')");
15845   myquery(rc);
15846   res= mysql_insert_id(mysql);
15847   /*
15848     Behaviour change: old code returned 3 (first autogenerated, even if it
15849     fails); we now return first successful autogenerated.
15850   */
15851   DIE_UNLESS(res == 13);
15852   /* UPDATE may update mysql_insert_id() if it uses LAST_INSERT_ID(#) */
15853   rc= mysql_query(mysql, "update t2 set f1=14 where f1=12");
15854   myquery(rc);
15855   res= mysql_insert_id(mysql);
15856   DIE_UNLESS(res == 0);
15857   rc= mysql_query(mysql, "update t2 set f1=0 where f1=14");
15858   myquery(rc);
15859   res= mysql_insert_id(mysql);
15860   DIE_UNLESS(res == 0);
15861   rc= mysql_query(mysql, "update t2 set f2=last_insert_id(372) where f1=0");
15862   myquery(rc);
15863   res= mysql_insert_id(mysql);
15864   DIE_UNLESS(res == 372);
15865   /* check that LAST_INSERT_ID() does not update mysql_insert_id(): */
15866   rc= mysql_query(mysql, "insert into t2 values (null,'g')");
15867   myquery(rc);
15868   res= mysql_insert_id(mysql);
15869   DIE_UNLESS(res == 15);
15870   rc= mysql_query(mysql, "update t2 set f2=(@li:=last_insert_id()) where f1=15");
15871   myquery(rc);
15872   res= mysql_insert_id(mysql);
15873   DIE_UNLESS(res == 0);
15874   /*
15875     Behaviour change: now if ON DUPLICATE KEY UPDATE updates a row,
15876     mysql_insert_id() returns the id of the row, instead of not being
15877     affected.
15878   */
15879   rc= mysql_query(mysql, "insert into t2 values (null,@li) on duplicate key "
15880                   "update f2=concat('we updated ',f2)");
15881   myquery(rc);
15882   res= mysql_insert_id(mysql);
15883   DIE_UNLESS(res == 15);
15884 
15885   rc= mysql_query(mysql, "drop table t1,t2");
15886   myquery(rc);
15887 }
15888 
15889 /*
15890   Bug#20152: mysql_stmt_execute() writes to MYSQL_TYPE_DATE buffer
15891 */
15892 
test_bug20152()15893 static void test_bug20152()
15894 {
15895   MYSQL_BIND my_bind[1];
15896   MYSQL_STMT *stmt;
15897   MYSQL_TIME tm;
15898   int rc;
15899   const char *query= "INSERT INTO t1 (f1) VALUES (?)";
15900 
15901   myheader("test_bug20152");
15902 
15903   memset(my_bind, 0, sizeof(my_bind));
15904   my_bind[0].buffer_type= MYSQL_TYPE_DATE;
15905   my_bind[0].buffer= (void*)&tm;
15906 
15907   tm.year = 2006;
15908   tm.month = 6;
15909   tm.day = 18;
15910   tm.hour = 14;
15911   tm.minute = 9;
15912   tm.second = 42;
15913 
15914   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
15915   myquery(rc);
15916   rc= mysql_query(mysql, "CREATE TABLE t1 (f1 DATE)");
15917   myquery(rc);
15918 
15919   stmt= mysql_stmt_init(mysql);
15920   rc= mysql_stmt_prepare(stmt, query, strlen(query));
15921   check_execute(stmt, rc);
15922   rc= mysql_stmt_bind_param(stmt, my_bind);
15923   check_execute(stmt, rc);
15924   rc= mysql_stmt_execute(stmt);
15925   check_execute(stmt, rc);
15926   rc= mysql_stmt_close(stmt);
15927   check_execute(stmt, rc);
15928   rc= mysql_query(mysql, "DROP TABLE t1");
15929   myquery(rc);
15930 
15931   if (tm.hour == 14 && tm.minute == 9 && tm.second == 42) {
15932     if (!opt_silent)
15933       printf("OK!");
15934   } else {
15935     printf("[14:09:42] != [%02d:%02d:%02d]\n", tm.hour, tm.minute, tm.second);
15936     DIE_UNLESS(0==1);
15937   }
15938 }
15939 
15940 /* Bug#15752 "Lost connection to MySQL server when calling a SP from C API" */
15941 
test_bug15752()15942 static void test_bug15752()
15943 {
15944   MYSQL mysql_local;
15945   int rc, i;
15946   const int ITERATION_COUNT= 100;
15947   const char *query= "CALL p1()";
15948 
15949   myheader("test_bug15752");
15950 
15951   rc= mysql_query(mysql, "drop procedure if exists p1");
15952   myquery(rc);
15953   rc= mysql_query(mysql, "create procedure p1() select 1");
15954   myquery(rc);
15955 
15956   mysql_client_init(&mysql_local);
15957   if (! mysql_real_connect(&mysql_local, opt_host, opt_user,
15958                            opt_password, current_db, opt_port,
15959                            opt_unix_socket,
15960                            CLIENT_MULTI_STATEMENTS))
15961   {
15962     printf("Unable connect to MySQL server: %s\n", mysql_error(&mysql_local));
15963     DIE_UNLESS(0);
15964   }
15965   rc= mysql_real_query(&mysql_local, query, strlen(query));
15966   myquery(rc);
15967   mysql_free_result(mysql_store_result(&mysql_local));
15968 
15969   rc= mysql_real_query(&mysql_local, query, strlen(query));
15970   DIE_UNLESS(rc && mysql_errno(&mysql_local) == CR_COMMANDS_OUT_OF_SYNC);
15971 
15972   if (! opt_silent)
15973     printf("Got error (as expected): %s\n", mysql_error(&mysql_local));
15974 
15975   /* Check some other commands too */
15976 
15977   DIE_UNLESS(mysql_next_result(&mysql_local) == 0);
15978   mysql_free_result(mysql_store_result(&mysql_local));
15979   DIE_UNLESS(mysql_next_result(&mysql_local) == -1);
15980 
15981   /* The second problem is not reproducible: add the test case */
15982   for (i = 0; i < ITERATION_COUNT; i++)
15983   {
15984     if (mysql_real_query(&mysql_local, query, strlen(query)))
15985     {
15986       printf("\ni=%d %s failed: %s\n", i, query, mysql_error(&mysql_local));
15987       break;
15988     }
15989     mysql_free_result(mysql_store_result(&mysql_local));
15990     DIE_UNLESS(mysql_next_result(&mysql_local) == 0);
15991     mysql_free_result(mysql_store_result(&mysql_local));
15992     DIE_UNLESS(mysql_next_result(&mysql_local) == -1);
15993 
15994   }
15995   mysql_close(&mysql_local);
15996   rc= mysql_query(mysql, "drop procedure p1");
15997   myquery(rc);
15998 }
15999 
16000 /*
16001   Bug#21206: memory corruption when too many cursors are opened at once
16002 
16003   Memory corruption happens when more than 1024 cursors are open
16004   simultaneously.
16005 */
test_bug21206()16006 static void test_bug21206()
16007 {
16008   const size_t cursor_count= 1025;
16009 
16010   const char *create_table[]=
16011   {
16012     "DROP TABLE IF EXISTS t1",
16013     "CREATE TABLE t1 (i INT)",
16014     "INSERT INTO t1 VALUES (1), (2), (3)"
16015   };
16016   const char *query= "SELECT * FROM t1";
16017 
16018   Stmt_fetch *fetch_array=
16019     (Stmt_fetch*) calloc(cursor_count, sizeof(Stmt_fetch));
16020 
16021   Stmt_fetch *fetch;
16022 
16023   DBUG_ENTER("test_bug21206");
16024   myheader("test_bug21206");
16025 
16026   fill_tables(create_table, sizeof(create_table) / sizeof(*create_table));
16027 
16028   for (fetch= fetch_array; fetch < fetch_array + cursor_count; ++fetch)
16029   {
16030     /* Init will exit(1) in case of error */
16031     stmt_fetch_init(fetch, (uint)(fetch - fetch_array), query);
16032   }
16033 
16034   for (fetch= fetch_array; fetch < fetch_array + cursor_count; ++fetch)
16035     stmt_fetch_close(fetch);
16036 
16037   free(fetch_array);
16038 
16039   DBUG_VOID_RETURN;
16040 }
16041 
16042 /*
16043   Ensure we execute the status code while testing
16044 */
16045 
test_status()16046 static void test_status()
16047 {
16048   DBUG_ENTER("test_status");
16049   myheader("test_status");
16050 
16051   if (!mysql_stat(mysql))
16052   {
16053     myerror("mysql_stat failed");                 /* purecov: inspected */
16054     die(__FILE__, __LINE__, "mysql_stat failed"); /* purecov: inspected */
16055   }
16056   DBUG_VOID_RETURN;
16057 }
16058 
16059 /*
16060   Bug#21726: Incorrect result with multiple invocations of
16061   LAST_INSERT_ID
16062 
16063   Test that client gets updated value of insert_id on UPDATE that uses
16064   LAST_INSERT_ID(expr).
16065   select_query added to test for bug
16066     #26921 Problem in mysql_insert_id() Embedded C API function
16067 */
test_bug21726()16068 static void test_bug21726()
16069 {
16070   const char *create_table[]=
16071   {
16072     "DROP TABLE IF EXISTS t1",
16073     "CREATE TABLE t1 (i INT)",
16074     "INSERT INTO t1 VALUES (1)",
16075   };
16076   const char *update_query= "UPDATE t1 SET i= LAST_INSERT_ID(i + 1)";
16077   int rc;
16078   my_ulonglong insert_id;
16079   const char *select_query= "SELECT * FROM t1";
16080   MYSQL_RES  *result;
16081 
16082   DBUG_ENTER("test_bug21726");
16083   myheader("test_bug21726");
16084 
16085   fill_tables(create_table, sizeof(create_table) / sizeof(*create_table));
16086 
16087   rc= mysql_query(mysql, update_query);
16088   myquery(rc);
16089   insert_id= mysql_insert_id(mysql);
16090   DIE_UNLESS(insert_id == 2);
16091 
16092   rc= mysql_query(mysql, update_query);
16093   myquery(rc);
16094   insert_id= mysql_insert_id(mysql);
16095   DIE_UNLESS(insert_id == 3);
16096 
16097   rc= mysql_query(mysql, select_query);
16098   myquery(rc);
16099   insert_id= mysql_insert_id(mysql);
16100   DIE_UNLESS(insert_id == 3);
16101   result= mysql_store_result(mysql);
16102   mysql_free_result(result);
16103 
16104   DBUG_VOID_RETURN;
16105 }
16106 
16107 
16108 /*
16109   BUG#23383: mysql_affected_rows() returns different values than
16110   mysql_stmt_affected_rows()
16111 
16112   Test that both mysql_affected_rows() and mysql_stmt_affected_rows()
16113   return -1 on error, 0 when no rows were affected, and (positive) row
16114   count when some rows were affected.
16115 */
test_bug23383()16116 static void test_bug23383()
16117 {
16118   const char *insert_query= "INSERT INTO t1 VALUES (1), (2)";
16119   const char *update_query= "UPDATE t1 SET i= 4 WHERE i = 3";
16120   MYSQL_STMT *stmt;
16121   my_ulonglong row_count;
16122   int rc;
16123 
16124   DBUG_ENTER("test_bug23383");
16125   myheader("test_bug23383");
16126 
16127   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
16128   myquery(rc);
16129 
16130   rc= mysql_query(mysql, "CREATE TABLE t1 (i INT UNIQUE)");
16131   myquery(rc);
16132 
16133   rc= mysql_query(mysql, insert_query);
16134   myquery(rc);
16135   row_count= mysql_affected_rows(mysql);
16136   DIE_UNLESS(row_count == 2);
16137 
16138   rc= mysql_query(mysql, insert_query);
16139   DIE_UNLESS(rc != 0);
16140   row_count= mysql_affected_rows(mysql);
16141   DIE_UNLESS(row_count == (my_ulonglong)-1);
16142 
16143   rc= mysql_query(mysql, update_query);
16144   myquery(rc);
16145   row_count= mysql_affected_rows(mysql);
16146   DIE_UNLESS(row_count == 0);
16147 
16148   rc= mysql_query(mysql, "DELETE FROM t1");
16149   myquery(rc);
16150 
16151   stmt= mysql_stmt_init(mysql);
16152   DIE_UNLESS(stmt != 0);
16153 
16154   rc= mysql_stmt_prepare(stmt, insert_query, strlen(insert_query));
16155   check_execute(stmt, rc);
16156 
16157   rc= mysql_stmt_execute(stmt);
16158   check_execute(stmt, rc);
16159   row_count= mysql_stmt_affected_rows(stmt);
16160   DIE_UNLESS(row_count == 2);
16161 
16162   rc= mysql_stmt_execute(stmt);
16163   DIE_UNLESS(rc != 0);
16164   row_count= mysql_stmt_affected_rows(stmt);
16165   DIE_UNLESS(row_count == (my_ulonglong)-1);
16166 
16167   rc= mysql_stmt_prepare(stmt, update_query, strlen(update_query));
16168   check_execute(stmt, rc);
16169 
16170   rc= mysql_stmt_execute(stmt);
16171   check_execute(stmt, rc);
16172   row_count= mysql_stmt_affected_rows(stmt);
16173   DIE_UNLESS(row_count == 0);
16174 
16175   rc= mysql_stmt_close(stmt);
16176   check_execute(stmt, rc);
16177 
16178   rc= mysql_query(mysql, "DROP TABLE t1");
16179   myquery(rc);
16180 
16181   DBUG_VOID_RETURN;
16182 }
16183 
16184 
16185 /*
16186   BUG#21635: MYSQL_FIELD struct's member strings seem to misbehave for
16187   expression cols
16188 
16189   Check that for MIN(), MAX(), COUNT() only MYSQL_FIELD::name is set
16190   to either expression or its alias, and db, org_table, table,
16191   org_name fields are empty strings.
16192 */
test_bug21635()16193 static void test_bug21635()
16194 {
16195   const char *expr[]=
16196   {
16197     "MIN(i)", "MIN(i)",
16198     "MIN(i) AS A1", "A1",
16199     "MAX(i)", "MAX(i)",
16200     "MAX(i) AS A2", "A2",
16201     "COUNT(i)", "COUNT(i)",
16202     "COUNT(i) AS A3", "A3",
16203   };
16204   char query[MAX_TEST_QUERY_LENGTH];
16205   char *query_end;
16206   MYSQL_RES *result;
16207   MYSQL_FIELD *field;
16208   unsigned int field_count, i, j;
16209   int rc;
16210 
16211   DBUG_ENTER("test_bug21635");
16212   myheader("test_bug21635");
16213 
16214   query_end= strxmov(query, "SELECT ", NullS);
16215   for (i= 0; i < sizeof(expr) / sizeof(*expr) / 2; ++i)
16216     query_end= strxmov(query_end, expr[i * 2], ", ", NullS);
16217   query_end= strxmov(query_end - 2, " FROM t1 GROUP BY i", NullS);
16218   DIE_UNLESS(query_end - query < MAX_TEST_QUERY_LENGTH);
16219 
16220   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
16221   myquery(rc);
16222   rc= mysql_query(mysql, "CREATE TABLE t1 (i INT)");
16223   myquery(rc);
16224   /*
16225     We need this loop to ensure correct behavior with both constant and
16226     non-constant tables.
16227   */
16228   for (j= 0; j < 2 ; j++)
16229   {
16230     rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)");
16231     myquery(rc);
16232 
16233     rc= mysql_real_query(mysql, query, (ulong)(query_end - query));
16234     myquery(rc);
16235 
16236     result= mysql_use_result(mysql);
16237     DIE_UNLESS(result);
16238 
16239   field_count= mysql_field_count(mysql);
16240   for (i= 0; i < field_count; ++i)
16241   {
16242     field= mysql_fetch_field_direct(result, i);
16243     if (!opt_silent)
16244       if (!opt_silent)
16245         printf("%s -> %s ... ", expr[i * 2], field->name);
16246     fflush(stdout);
16247     DIE_UNLESS(field->db[0] == 0 && field->org_table[0] == 0 &&
16248                field->table[0] == 0 && field->org_name[0] == 0);
16249     DIE_UNLESS(strcmp(field->name, expr[i * 2 + 1]) == 0);
16250     if (!opt_silent)
16251       if (!opt_silent)
16252         puts("OK");
16253   }
16254 
16255     mysql_free_result(result);
16256   }
16257   rc= mysql_query(mysql, "DROP TABLE t1");
16258   myquery(rc);
16259 
16260   DBUG_VOID_RETURN;
16261 }
16262 
16263 /*
16264   Bug#24179 "select b into $var" fails with --cursor_protocol"
16265   The failure is correct, check that the returned message is meaningful.
16266 */
16267 
test_bug24179()16268 static void test_bug24179()
16269 {
16270   int rc;
16271   MYSQL_STMT *stmt;
16272 
16273   DBUG_ENTER("test_bug24179");
16274   myheader("test_bug24179");
16275 
16276   stmt= open_cursor("select 1 into @a");
16277   rc= mysql_stmt_execute(stmt);
16278   DIE_UNLESS(rc);
16279   if (!opt_silent)
16280   {
16281     printf("Got error (as expected): %d %s\n",
16282            mysql_stmt_errno(stmt),
16283            mysql_stmt_error(stmt));
16284   }
16285   DIE_UNLESS(mysql_stmt_errno(stmt) == 1323);
16286   mysql_stmt_close(stmt);
16287 
16288   DBUG_VOID_RETURN;
16289 }
16290 
16291 
16292 /**
16293   Bug#32265 Server returns different metadata if prepared statement is used
16294 */
16295 
test_bug32265()16296 static void test_bug32265()
16297 {
16298   int rc;
16299   MYSQL_STMT *stmt;
16300   MYSQL_FIELD *field;
16301   MYSQL_RES *metadata;
16302 
16303   DBUG_ENTER("test_bug32265");
16304   myheader("test_bug32265");
16305 
16306   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
16307   myquery(rc);
16308   rc= mysql_query(mysql, "CREATE  TABLE t1 (a INTEGER)");
16309   myquery(rc);
16310   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)");
16311   myquery(rc);
16312   rc= mysql_query(mysql, "CREATE VIEW v1 AS SELECT * FROM t1");
16313   myquery(rc);
16314 
16315   stmt= open_cursor("SELECT * FROM t1");
16316   rc= mysql_stmt_execute(stmt);
16317   check_execute(stmt, rc);
16318 
16319   metadata= mysql_stmt_result_metadata(stmt);
16320   field= mysql_fetch_field(metadata);
16321   DIE_UNLESS(field);
16322   DIE_UNLESS(strcmp(field->table, "t1") == 0);
16323   DIE_UNLESS(strcmp(field->org_table, "t1") == 0);
16324   DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
16325   mysql_free_result(metadata);
16326   mysql_stmt_close(stmt);
16327 
16328   stmt= open_cursor("SELECT a '' FROM t1 ``");
16329   rc= mysql_stmt_execute(stmt);
16330   check_execute(stmt, rc);
16331 
16332   metadata= mysql_stmt_result_metadata(stmt);
16333   field= mysql_fetch_field(metadata);
16334   DIE_UNLESS(strcmp(field->table, "") == 0);
16335   DIE_UNLESS(strcmp(field->org_table, "t1") == 0);
16336   DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
16337   mysql_free_result(metadata);
16338   mysql_stmt_close(stmt);
16339 
16340   stmt= open_cursor("SELECT a '' FROM t1 ``");
16341   rc= mysql_stmt_execute(stmt);
16342   check_execute(stmt, rc);
16343 
16344   metadata= mysql_stmt_result_metadata(stmt);
16345   field= mysql_fetch_field(metadata);
16346   DIE_UNLESS(strcmp(field->table, "") == 0);
16347   DIE_UNLESS(strcmp(field->org_table, "t1") == 0);
16348   DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
16349   mysql_free_result(metadata);
16350   mysql_stmt_close(stmt);
16351 
16352   stmt= open_cursor("SELECT * FROM v1");
16353   rc= mysql_stmt_execute(stmt);
16354   check_execute(stmt, rc);
16355 
16356   metadata= mysql_stmt_result_metadata(stmt);
16357   field= mysql_fetch_field(metadata);
16358   DIE_UNLESS(strcmp(field->table, "v1") == 0);
16359   DIE_UNLESS(strcmp(field->org_table, "v1") == 0);
16360   DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
16361   mysql_free_result(metadata);
16362   mysql_stmt_close(stmt);
16363 
16364   stmt= open_cursor("SELECT * FROM v1 /* SIC */ GROUP BY 1");
16365   rc= mysql_stmt_execute(stmt);
16366   check_execute(stmt, rc);
16367 
16368   metadata= mysql_stmt_result_metadata(stmt);
16369   field= mysql_fetch_field(metadata);
16370   DIE_UNLESS(strcmp(field->table, "v1") == 0);
16371   DIE_UNLESS(strcmp(field->org_table, "v1") == 0);
16372   DIE_UNLESS(strcmp(field->db, "client_test_db") == 0);
16373   mysql_free_result(metadata);
16374   mysql_stmt_close(stmt);
16375 
16376   rc= mysql_query(mysql, "DROP VIEW v1");
16377   myquery(rc);
16378   rc= mysql_query(mysql, "DROP TABLE t1");
16379   myquery(rc);
16380 
16381   DBUG_VOID_RETURN;
16382 }
16383 
16384 /*
16385   Bug#28075 "COM_DEBUG crashes mysqld"
16386 */
16387 
test_bug28075()16388 static void test_bug28075()
16389 {
16390   int rc;
16391 
16392   DBUG_ENTER("test_bug28075");
16393   myheader("test_bug28075");
16394 
16395   rc= mysql_dump_debug_info(mysql);
16396   DIE_UNLESS(rc == 0);
16397 
16398   rc= mysql_ping(mysql);
16399   DIE_UNLESS(rc == 0);
16400 
16401   DBUG_VOID_RETURN;
16402 }
16403 
16404 
16405 /*
16406   Bug#27876 (SF with cyrillic variable name fails during execution (regression))
16407 */
16408 
test_bug27876()16409 static void test_bug27876()
16410 {
16411   int rc;
16412   MYSQL_RES *result;
16413 
16414   uchar utf8_func[] =
16415   {
16416     0xd1, 0x84, 0xd1, 0x83, 0xd0, 0xbd, 0xd0, 0xba,
16417     0xd1, 0x86, 0xd0, 0xb8, 0xd0, 0xb9, 0xd0, 0xba,
16418     0xd0, 0xb0,
16419     0x00
16420   };
16421 
16422   uchar utf8_param[] =
16423   {
16424     0xd0, 0xbf, 0xd0, 0xb0, 0xd1, 0x80, 0xd0, 0xb0,
16425     0xd0, 0xbc, 0xd0, 0xb5, 0xd1, 0x82, 0xd1, 0x8a,
16426     0xd1, 0x80, 0x5f, 0xd0, 0xb2, 0xd0, 0xb5, 0xd1,
16427     0x80, 0xd1, 0x81, 0xd0, 0xb8, 0xd1, 0x8f,
16428     0x00
16429   };
16430 
16431   char query[500];
16432 
16433   DBUG_ENTER("test_bug27876");
16434   myheader("test_bug27876");
16435 
16436   rc= mysql_query(mysql, "set names utf8");
16437   myquery(rc);
16438 
16439   rc= mysql_query(mysql, "select version()");
16440   myquery(rc);
16441   result= mysql_store_result(mysql);
16442   mytest(result);
16443   mysql_free_result(result);
16444 
16445   sprintf(query, "DROP FUNCTION IF EXISTS %s", (char*) utf8_func);
16446   rc= mysql_query(mysql, query);
16447   myquery(rc);
16448 
16449   sprintf(query,
16450           "CREATE FUNCTION %s( %s VARCHAR(25))"
16451           " RETURNS VARCHAR(25) DETERMINISTIC RETURN %s",
16452           (char*) utf8_func, (char*) utf8_param, (char*) utf8_param);
16453   rc= mysql_query(mysql, query);
16454   myquery(rc);
16455   sprintf(query, "SELECT %s(VERSION())", (char*) utf8_func);
16456   rc= mysql_query(mysql, query);
16457   myquery(rc);
16458   result= mysql_store_result(mysql);
16459   mytest(result);
16460   mysql_free_result(result);
16461 
16462   sprintf(query, "DROP FUNCTION %s", (char*) utf8_func);
16463   rc= mysql_query(mysql, query);
16464   myquery(rc);
16465 
16466   rc= mysql_query(mysql, "set names default");
16467   myquery(rc);
16468 
16469   DBUG_VOID_RETURN;
16470 }
16471 
16472 
16473 /*
16474   Bug#28505: mysql_affected_rows() returns wrong value if CLIENT_FOUND_ROWS
16475   flag is set.
16476 */
16477 
test_bug28505()16478 static void test_bug28505()
16479 {
16480   my_ulonglong res;
16481 
16482   myquery(mysql_query(mysql, "drop table if exists t1"));
16483   myquery(mysql_query(mysql, "create table t1(f1 int primary key)"));
16484   myquery(mysql_query(mysql, "insert into t1 values(1)"));
16485   myquery(mysql_query(mysql,
16486                   "insert into t1 values(1) on duplicate key update f1=1"));
16487   res= mysql_affected_rows(mysql);
16488   DIE_UNLESS(!res);
16489   myquery(mysql_query(mysql, "drop table t1"));
16490 }
16491 
16492 
16493 /*
16494   Bug#28934: server crash when receiving malformed com_execute packets
16495 */
16496 
test_bug28934()16497 static void test_bug28934()
16498 {
16499   my_bool error= 0;
16500   MYSQL_BIND bind[5];
16501   MYSQL_STMT *stmt;
16502   int cnt;
16503 
16504   myquery(mysql_query(mysql, "drop table if exists t1"));
16505   myquery(mysql_query(mysql, "create table t1(id int)"));
16506 
16507   myquery(mysql_query(mysql, "insert into t1 values(1),(2),(3),(4),(5)"));
16508   stmt= mysql_simple_prepare(mysql,"select * from t1 where id in(?,?,?,?,?)");
16509   check_stmt(stmt);
16510 
16511   memset (&bind, 0, sizeof (bind));
16512   for (cnt= 0; cnt < 5; cnt++)
16513   {
16514     bind[cnt].buffer_type= MYSQL_TYPE_LONG;
16515     bind[cnt].buffer= (char*)&cnt;
16516     bind[cnt].buffer_length= 0;
16517   }
16518   myquery(mysql_stmt_bind_param(stmt, bind));
16519 
16520   stmt->param_count=2;
16521   error= mysql_stmt_execute(stmt);
16522   DIE_UNLESS(error != 0);
16523   myerror(NULL);
16524   mysql_stmt_close(stmt);
16525 
16526   myquery(mysql_query(mysql, "drop table t1"));
16527 }
16528 
16529 /*
16530   Test mysql_change_user() C API and COM_CHANGE_USER
16531 */
16532 
test_change_user()16533 static void test_change_user()
16534 {
16535   char buff[256];
16536   const char *user_pw= "mysqltest_pw";
16537   const char *user_no_pw= "mysqltest_no_pw";
16538   const char *pw= "password";
16539   const char *db= "mysqltest_user_test_database";
16540   int rc;
16541   MYSQL*       conn;
16542   MYSQL_RES* res;
16543   DBUG_ENTER("test_change_user");
16544   myheader("test_change_user");
16545 
16546   /* Prepare environment */
16547   sprintf(buff, "drop database if exists %s", db);
16548   rc= mysql_query(mysql, buff);
16549   myquery(rc);
16550 
16551   sprintf(buff, "create database %s", db);
16552   rc= mysql_query(mysql, buff);
16553   myquery(rc);
16554 
16555   rc= mysql_query(mysql, "SET SQL_MODE=''");
16556   myquery(rc);
16557 
16558   sprintf(buff,
16559           "grant select on %s.* to %s@'%%' identified by '%s'",
16560           db,
16561           user_pw,
16562           pw);
16563   rc= mysql_query(mysql, buff);
16564   myquery(rc);
16565 
16566   sprintf(buff,
16567           "grant select on %s.* to %s@'localhost' identified by '%s'",
16568           db,
16569           user_pw,
16570           pw);
16571   rc= mysql_query(mysql, buff);
16572   myquery(rc);
16573 
16574   sprintf(buff,
16575           "grant select on %s.* to %s@'%%'",
16576           db,
16577           user_no_pw);
16578   rc= mysql_query(mysql, buff);
16579   myquery(rc);
16580 
16581   sprintf(buff,
16582           "grant select on %s.* to %s@'localhost'",
16583           db,
16584           user_no_pw);
16585   rc= mysql_query(mysql, buff);
16586   myquery(rc);
16587 
16588   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
16589 
16590   /* Try some combinations */
16591   rc= mysql_change_user(conn, NULL, NULL, NULL);
16592   DIE_UNLESS(rc);
16593   if (! opt_silent)
16594     printf("Got error (as expected): %s\n", mysql_error(conn));
16595 
16596 
16597   rc= mysql_change_user(conn, "", NULL, NULL);
16598   DIE_UNLESS(rc);
16599   if (! opt_silent)
16600     printf("Got error (as expected): %s\n", mysql_error(conn));
16601 
16602   rc= mysql_change_user(conn, "", "", NULL);
16603   DIE_UNLESS(rc);
16604   if (! opt_silent)
16605     printf("Got error (as expected): %s\n", mysql_error(conn));
16606 
16607   mysql_close(conn);
16608   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
16609 
16610   rc= mysql_change_user(conn, "", "", "");
16611   DIE_UNLESS(rc);
16612   if (! opt_silent)
16613     printf("Got error (as expected): %s\n", mysql_error(conn));
16614 
16615   rc= mysql_change_user(conn, NULL, "", "");
16616   DIE_UNLESS(rc);
16617   if (! opt_silent)
16618     printf("Got error (as expected): %s\n", mysql_error(conn));
16619 
16620 
16621   rc= mysql_change_user(conn, NULL, NULL, "");
16622   DIE_UNLESS(rc);
16623   if (! opt_silent)
16624     printf("Got error (as expected): %s\n", mysql_error(conn));
16625 
16626   mysql_close(conn);
16627   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
16628 
16629   rc= mysql_change_user(conn, "", NULL, "");
16630   DIE_UNLESS(rc);
16631   if (! opt_silent)
16632     printf("Got error (as expected): %s\n", mysql_error(conn));
16633 
16634   rc= mysql_change_user(conn, user_pw, NULL, "");
16635   DIE_UNLESS(rc);
16636   if (! opt_silent)
16637     printf("Got error (as expected): %s\n", mysql_error(conn));
16638 
16639   rc= mysql_change_user(conn, user_pw, "", "");
16640   DIE_UNLESS(rc);
16641   if (! opt_silent)
16642     printf("Got error (as expected): %s\n", mysql_error(conn));
16643 
16644   mysql_close(conn);
16645   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
16646 
16647   rc= mysql_change_user(conn, user_pw, "", NULL);
16648   DIE_UNLESS(rc);
16649   if (! opt_silent)
16650     printf("Got error (as expected): %s\n", mysql_error(conn));
16651 
16652   rc= mysql_change_user(conn, user_pw, NULL, NULL);
16653   DIE_UNLESS(rc);
16654   if (! opt_silent)
16655     printf("Got error (as expected): %s\n", mysql_error(conn));
16656 
16657   rc= mysql_change_user(conn, user_pw, "", db);
16658   DIE_UNLESS(rc);
16659   if (! opt_silent)
16660     printf("Got error (as expected): %s\n", mysql_error(conn));
16661 
16662   mysql_close(conn);
16663   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
16664 
16665   rc= mysql_change_user(conn, user_pw, NULL, db);
16666   DIE_UNLESS(rc);
16667   if (! opt_silent)
16668     printf("Got error (as expected): %s\n", mysql_error(conn));
16669 
16670   rc= mysql_change_user(conn, user_pw, pw, db);
16671   myquery(rc);
16672 
16673   rc= mysql_change_user(conn, user_pw, pw, NULL);
16674   myquery(rc);
16675 
16676   rc= mysql_change_user(conn, user_pw, pw, "");
16677   myquery(rc);
16678 
16679   /* MDEV-14581 : Check that there are no warnings after change user.*/
16680   rc = mysql_query(conn,"SIGNAL SQLSTATE '01000'");
16681   myquery(rc);
16682 
16683   rc = mysql_change_user(conn, user_pw, pw, "");
16684   myquery(rc);
16685 
16686   rc = mysql_query(conn, "SHOW WARNINGS");
16687   myquery(rc);
16688   res = mysql_store_result(conn);
16689   rc = my_process_result_set(res);
16690   DIE_UNLESS(rc == 0);
16691   mysql_free_result(res);
16692 
16693   rc= mysql_change_user(conn, user_no_pw, pw, db);
16694   DIE_UNLESS(rc);
16695   if (! opt_silent)
16696     printf("Got error (as expected): %s\n", mysql_error(conn));
16697 
16698   rc= mysql_change_user(conn, user_no_pw, pw, "");
16699   DIE_UNLESS(rc);
16700   if (! opt_silent)
16701     printf("Got error (as expected): %s\n", mysql_error(conn));
16702 
16703   mysql_close(conn);
16704   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
16705 
16706   rc= mysql_change_user(conn, user_no_pw, pw, NULL);
16707   DIE_UNLESS(rc);
16708   if (! opt_silent)
16709     printf("Got error (as expected): %s\n", mysql_error(conn));
16710 
16711   rc= mysql_change_user(conn, user_no_pw, "", NULL);
16712   myquery(rc);
16713 
16714   rc= mysql_change_user(conn, user_no_pw, "", "");
16715   myquery(rc);
16716 
16717   rc= mysql_change_user(conn, user_no_pw, "", db);
16718   myquery(rc);
16719 
16720   rc= mysql_change_user(conn, user_no_pw, NULL, db);
16721   myquery(rc);
16722 
16723   rc= mysql_change_user(conn, "", pw, db);
16724   DIE_UNLESS(rc);
16725   if (! opt_silent)
16726     printf("Got error (as expected): %s\n", mysql_error(conn));
16727 
16728   rc= mysql_change_user(conn, "", pw, "");
16729   DIE_UNLESS(rc);
16730   if (! opt_silent)
16731     printf("Got error (as expected): %s\n", mysql_error(conn));
16732 
16733   mysql_close(conn);
16734   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
16735 
16736   rc= mysql_change_user(conn, "", pw, NULL);
16737   DIE_UNLESS(rc);
16738   if (! opt_silent)
16739     printf("Got error (as expected): %s\n", mysql_error(conn));
16740 
16741   rc= mysql_change_user(conn, NULL, pw, NULL);
16742   DIE_UNLESS(rc);
16743   if (! opt_silent)
16744     printf("Got error (as expected): %s\n", mysql_error(conn));
16745 
16746   rc= mysql_change_user(conn, NULL, NULL, db);
16747   DIE_UNLESS(rc);
16748   if (! opt_silent)
16749     printf("Got error (as expected): %s\n", mysql_error(conn));
16750 
16751   mysql_close(conn);
16752   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
16753 
16754   rc= mysql_change_user(conn, NULL, "", db);
16755   DIE_UNLESS(rc);
16756   if (! opt_silent)
16757     printf("Got error (as expected): %s\n", mysql_error(conn));
16758 
16759   rc= mysql_change_user(conn, "", "", db);
16760   DIE_UNLESS(rc);
16761   if (! opt_silent)
16762     printf("Got error (as expected): %s\n", mysql_error(conn));
16763 
16764   /* Cleanup the environment */
16765 
16766   mysql_change_user(conn, opt_user, opt_password, current_db);
16767 
16768   mysql_close(conn);
16769 
16770   sprintf(buff, "drop database %s", db);
16771   rc= mysql_query(mysql, buff);
16772   myquery(rc);
16773 
16774   sprintf(buff, "drop user %s@'%%'", user_pw);
16775   rc= mysql_query(mysql, buff);
16776   myquery(rc);
16777 
16778   sprintf(buff, "drop user %s@'%%'", user_no_pw);
16779   rc= mysql_query(mysql, buff);
16780   myquery(rc);
16781 
16782   sprintf(buff, "drop user %s@'localhost'", user_pw);
16783   rc= mysql_query(mysql, buff);
16784   myquery(rc);
16785 
16786   sprintf(buff, "drop user %s@'localhost'", user_no_pw);
16787   rc= mysql_query(mysql, buff);
16788   myquery(rc);
16789 
16790   DBUG_VOID_RETURN;
16791 }
16792 
16793 /*
16794   Bug#27592 (stack overrun when storing datetime value using prepared statements)
16795 */
16796 
test_bug27592()16797 static void test_bug27592()
16798 {
16799   const int NUM_ITERATIONS= 40;
16800   int i;
16801   int rc;
16802   MYSQL_STMT *stmt= NULL;
16803   MYSQL_BIND bind[1];
16804   MYSQL_TIME time_val;
16805 
16806   DBUG_ENTER("test_bug27592");
16807   myheader("test_bug27592");
16808 
16809   mysql_query(mysql, "DROP TABLE IF EXISTS t1");
16810   mysql_query(mysql, "CREATE TABLE t1(c2 DATETIME)");
16811 
16812   stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 VALUES (?)");
16813   DIE_UNLESS(stmt);
16814 
16815   memset(bind, 0, sizeof(bind));
16816 
16817   bind[0].buffer_type= MYSQL_TYPE_DATETIME;
16818   bind[0].buffer= (char *) &time_val;
16819   bind[0].length= NULL;
16820 
16821   for (i= 0; i < NUM_ITERATIONS; i++)
16822   {
16823     time_val.year= 2007;
16824     time_val.month= 6;
16825     time_val.day= 7;
16826     time_val.hour= 18;
16827     time_val.minute= 41;
16828     time_val.second= 3;
16829 
16830     time_val.second_part=0;
16831     time_val.neg=0;
16832 
16833     rc= mysql_stmt_bind_param(stmt, bind);
16834     check_execute(stmt, rc);
16835 
16836     rc= mysql_stmt_execute(stmt);
16837     check_execute(stmt, rc);
16838   }
16839 
16840   mysql_stmt_close(stmt);
16841 
16842   DBUG_VOID_RETURN;
16843 }
16844 
16845 /*
16846   Bug#29687 mysql_stmt_store_result memory leak in libmysqld
16847 */
16848 
test_bug29687()16849 static void test_bug29687()
16850 {
16851   const int NUM_ITERATIONS= 40;
16852   int i;
16853   int rc;
16854   MYSQL_STMT *stmt= NULL;
16855 
16856   DBUG_ENTER("test_bug29687");
16857   myheader("test_bug29687");
16858 
16859   stmt= mysql_simple_prepare(mysql, "SELECT 1 FROM dual WHERE 0=2");
16860   DIE_UNLESS(stmt);
16861 
16862   for (i= 0; i < NUM_ITERATIONS; i++)
16863   {
16864     rc= mysql_stmt_execute(stmt);
16865     check_execute(stmt, rc);
16866     mysql_stmt_store_result(stmt);
16867     while (mysql_stmt_fetch(stmt)==0);
16868     mysql_stmt_free_result(stmt);
16869   }
16870 
16871   mysql_stmt_close(stmt);
16872   DBUG_VOID_RETURN;
16873 }
16874 
16875 
16876 /*
16877   Bug #29692  	Single row inserts can incorrectly report a huge number of
16878   row insertions
16879 */
16880 
test_bug29692()16881 static void test_bug29692()
16882 {
16883   MYSQL* conn;
16884 
16885   if (!(conn= mysql_client_init(NULL)))
16886   {
16887     myerror("test_bug29692 init failed");
16888     exit(1);
16889   }
16890 
16891   if (!(mysql_real_connect(conn, opt_host, opt_user,
16892                            opt_password, opt_db ? opt_db:"test", opt_port,
16893                            opt_unix_socket,  CLIENT_FOUND_ROWS)))
16894   {
16895     myerror("test_bug29692 connection failed");
16896     mysql_close(mysql);
16897     exit(1);
16898   }
16899   myquery(mysql_query(conn, "drop table if exists t1"));
16900   myquery(mysql_query(conn, "create table t1(f1 int)"));
16901   myquery(mysql_query(conn, "insert into t1 values(1)"));
16902   DIE_UNLESS(1 == mysql_affected_rows(conn));
16903   myquery(mysql_query(conn, "drop table t1"));
16904   mysql_close(conn);
16905 }
16906 
16907 /**
16908   Bug#29306 Truncated data in MS Access with decimal (3,1) columns in a VIEW
16909 */
16910 
test_bug29306()16911 static void test_bug29306()
16912 {
16913   MYSQL_FIELD *field;
16914   int rc;
16915   MYSQL_RES *res;
16916 
16917   DBUG_ENTER("test_bug29306");
16918   myheader("test_bug29306");
16919 
16920   rc= mysql_query(mysql, "DROP TABLE IF EXISTS tab17557");
16921   myquery(rc);
16922   rc= mysql_query(mysql, "DROP VIEW IF EXISTS view17557");
16923   myquery(rc);
16924   rc= mysql_query(mysql, "CREATE TABLE tab17557 (dd decimal (3,1))");
16925   myquery(rc);
16926   rc= mysql_query(mysql, "CREATE VIEW view17557 as SELECT dd FROM tab17557");
16927   myquery(rc);
16928   rc= mysql_query(mysql, "INSERT INTO tab17557 VALUES (7.6)");
16929   myquery(rc);
16930 
16931   /* Checking the view */
16932   res= mysql_list_fields(mysql, "view17557", NULL);
16933   while ((field= mysql_fetch_field(res)))
16934   {
16935     if (! opt_silent)
16936     {
16937       printf("field name %s\n", field->name);
16938       printf("field table %s\n", field->table);
16939       printf("field decimals %d\n", field->decimals);
16940       if (field->decimals < 1)
16941         printf("Error! No decimals! \n");
16942       printf("\n\n");
16943     }
16944     DIE_UNLESS(field->decimals == 1);
16945   }
16946   mysql_free_result(res);
16947 
16948   rc= mysql_query(mysql, "DROP TABLE tab17557");
16949   myquery(rc);
16950   rc= mysql_query(mysql, "DROP VIEW view17557");
16951   myquery(rc);
16952 
16953   DBUG_VOID_RETURN;
16954 }
16955 /*
16956   Bug#30472: libmysql doesn't reset charset, insert_id after succ.
16957   mysql_change_user() call row insertions.
16958 */
16959 
bug30472_retrieve_charset_info(MYSQL * con,char * character_set_name,char * character_set_client,char * character_set_results,char * collation_connection)16960 static void bug30472_retrieve_charset_info(MYSQL *con,
16961                                            char *character_set_name,
16962                                            char *character_set_client,
16963                                            char *character_set_results,
16964                                            char *collation_connection)
16965 {
16966   MYSQL_RES *rs;
16967   MYSQL_ROW row;
16968 
16969   /* Get the cached client character set name. */
16970 
16971   strcpy(character_set_name, mysql_character_set_name(con));
16972 
16973   /* Retrieve server character set information. */
16974 
16975   DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'character_set_client'"));
16976   DIE_UNLESS(rs= mysql_store_result(con));
16977   DIE_UNLESS(row= mysql_fetch_row(rs));
16978   strcpy(character_set_client, row[1]);
16979   mysql_free_result(rs);
16980 
16981   DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'character_set_results'"));
16982   DIE_UNLESS(rs= mysql_store_result(con));
16983   DIE_UNLESS(row= mysql_fetch_row(rs));
16984   strcpy(character_set_results, row[1]);
16985   mysql_free_result(rs);
16986 
16987   DIE_IF(mysql_query(con, "SHOW VARIABLES LIKE 'collation_connection'"));
16988   DIE_UNLESS(rs= mysql_store_result(con));
16989   DIE_UNLESS(row= mysql_fetch_row(rs));
16990   strcpy(collation_connection, row[1]);
16991   mysql_free_result(rs);
16992 }
16993 
test_bug30472()16994 static void test_bug30472()
16995 {
16996   MYSQL con;
16997 
16998   char character_set_name_1[MY_CS_NAME_SIZE];
16999   char character_set_client_1[MY_CS_NAME_SIZE];
17000   char character_set_results_1[MY_CS_NAME_SIZE];
17001   char collation_connnection_1[MY_CS_NAME_SIZE];
17002 
17003   char character_set_name_2[MY_CS_NAME_SIZE];
17004   char character_set_client_2[MY_CS_NAME_SIZE];
17005   char character_set_results_2[MY_CS_NAME_SIZE];
17006   char collation_connnection_2[MY_CS_NAME_SIZE];
17007 
17008   char character_set_name_3[MY_CS_NAME_SIZE];
17009   char character_set_client_3[MY_CS_NAME_SIZE];
17010   char character_set_results_3[MY_CS_NAME_SIZE];
17011   char collation_connnection_3[MY_CS_NAME_SIZE];
17012 
17013   char character_set_name_4[MY_CS_NAME_SIZE];
17014   char character_set_client_4[MY_CS_NAME_SIZE];
17015   char character_set_results_4[MY_CS_NAME_SIZE];
17016   char collation_connnection_4[MY_CS_NAME_SIZE];
17017 
17018   /* Create a new connection. */
17019 
17020   DIE_UNLESS(mysql_client_init(&con));
17021 
17022   DIE_UNLESS(mysql_real_connect(&con,
17023                                 opt_host,
17024                                 opt_user,
17025                                 opt_password,
17026                                 opt_db ? opt_db : "test",
17027                                 opt_port,
17028                                 opt_unix_socket,
17029                                 CLIENT_FOUND_ROWS));
17030 
17031   /* Retrieve character set information. */
17032 
17033   bug30472_retrieve_charset_info(&con,
17034                                  character_set_name_1,
17035                                  character_set_client_1,
17036                                  character_set_results_1,
17037                                  collation_connnection_1);
17038 
17039   /* Switch client character set. */
17040 
17041   DIE_IF(mysql_set_character_set(&con, "latin2"));
17042 
17043   /* Retrieve character set information. */
17044 
17045   bug30472_retrieve_charset_info(&con,
17046                                  character_set_name_2,
17047                                  character_set_client_2,
17048                                  character_set_results_2,
17049                                  collation_connnection_2);
17050 
17051   /*
17052     Check that
17053       1) character set has been switched and
17054       2) new character set is different from the original one.
17055   */
17056 
17057   DIE_UNLESS(strcmp(character_set_name_2, "latin2") == 0);
17058   DIE_UNLESS(strcmp(character_set_client_2, "latin2") == 0);
17059   DIE_UNLESS(strcmp(character_set_results_2, "latin2") == 0);
17060   DIE_UNLESS(strcmp(collation_connnection_2, "latin2_general_ci") == 0);
17061 
17062   DIE_UNLESS(strcmp(character_set_name_1, character_set_name_2) != 0);
17063   DIE_UNLESS(strcmp(character_set_client_1, character_set_client_2) != 0);
17064   DIE_UNLESS(strcmp(character_set_results_1, character_set_results_2) != 0);
17065   DIE_UNLESS(strcmp(collation_connnection_1, collation_connnection_2) != 0);
17066 
17067   /* Call mysql_change_user() with the same username, password, database. */
17068 
17069   DIE_IF(mysql_change_user(&con,
17070                            opt_user,
17071                            opt_password,
17072                            opt_db ? opt_db : "test"));
17073 
17074   /* Retrieve character set information. */
17075 
17076   bug30472_retrieve_charset_info(&con,
17077                                  character_set_name_3,
17078                                  character_set_client_3,
17079                                  character_set_results_3,
17080                                  collation_connnection_3);
17081 
17082   /* Check that character set information has been reset. */
17083 
17084   DIE_UNLESS(strcmp(character_set_name_1, character_set_name_3) == 0);
17085   DIE_UNLESS(strcmp(character_set_client_1, character_set_client_3) == 0);
17086   DIE_UNLESS(strcmp(character_set_results_1, character_set_results_3) == 0);
17087   DIE_UNLESS(strcmp(collation_connnection_1, collation_connnection_3) == 0);
17088 
17089   /* Change connection-default character set in the client. */
17090 
17091   mysql_options(&con, MYSQL_SET_CHARSET_NAME, "utf8");
17092 
17093   /*
17094     Call mysql_change_user() in order to check that new connection will
17095     have UTF8 character set on the client and on the server.
17096   */
17097 
17098   DIE_IF(mysql_change_user(&con,
17099                            opt_user,
17100                            opt_password,
17101                            opt_db ? opt_db : "test"));
17102 
17103   /* Retrieve character set information. */
17104 
17105   bug30472_retrieve_charset_info(&con,
17106                                  character_set_name_4,
17107                                  character_set_client_4,
17108                                  character_set_results_4,
17109                                  collation_connnection_4);
17110 
17111   /* Check that we have UTF8 on the server and on the client. */
17112 
17113   DIE_UNLESS(strcmp(character_set_name_4, "utf8") == 0);
17114   DIE_UNLESS(strcmp(character_set_client_4, "utf8") == 0);
17115   DIE_UNLESS(strcmp(character_set_results_4, "utf8") == 0);
17116   DIE_UNLESS(strcmp(collation_connnection_4, "utf8_general_ci") == 0);
17117 
17118   /* That's it. Cleanup. */
17119 
17120   mysql_close(&con);
17121 }
17122 
bug20023_change_user(MYSQL * con)17123 static void bug20023_change_user(MYSQL *con)
17124 {
17125   DIE_IF(mysql_change_user(con,
17126                            opt_user,
17127                            opt_password,
17128                            opt_db ? opt_db : "test"));
17129 }
17130 
query_str_variable(MYSQL * con,const char * var_name,char * str,size_t len)17131 static my_bool query_str_variable(MYSQL *con,
17132                                   const char *var_name,
17133                                   char *str,
17134                                   size_t len)
17135 {
17136   MYSQL_RES *rs;
17137   MYSQL_ROW row;
17138 
17139   char query_buffer[MAX_TEST_QUERY_LENGTH];
17140 
17141   my_bool is_null;
17142 
17143   my_snprintf(query_buffer, sizeof (query_buffer),
17144               "SELECT %s", var_name);
17145 
17146   DIE_IF(mysql_query(con, query_buffer));
17147   DIE_UNLESS(rs= mysql_store_result(con));
17148   DIE_UNLESS(row= mysql_fetch_row(rs));
17149 
17150   is_null= row[0] == NULL;
17151 
17152   if (!is_null)
17153     my_snprintf(str, len, "%s", row[0]);
17154 
17155   mysql_free_result(rs);
17156 
17157   return is_null;
17158 }
17159 
query_int_variable(MYSQL * con,const char * var_name,int * var_value)17160 static my_bool query_int_variable(MYSQL *con,
17161                                   const char *var_name,
17162                                   int *var_value)
17163 {
17164   char str[32];
17165   my_bool is_null= query_str_variable(con, var_name, str, sizeof(str));
17166 
17167   if (!is_null)
17168     *var_value= atoi(str);
17169 
17170   return is_null;
17171 }
17172 
test_bug20023()17173 static void test_bug20023()
17174 {
17175   MYSQL con;
17176 
17177   int sql_big_selects_orig= 0;
17178   /*
17179     Type of max_join_size is ha_rows, which might be ulong or off_t
17180     depending on the platform or configure options. Preserve the string
17181     to avoid type overflow pitfalls.
17182   */
17183   char max_join_size_orig[32];
17184 
17185   int sql_big_selects_2= 0;
17186   int sql_big_selects_3= 0;
17187   int sql_big_selects_4= 0;
17188   int sql_big_selects_5= 0;
17189 
17190   char query_buffer[MAX_TEST_QUERY_LENGTH];
17191 
17192   /* Create a new connection. */
17193 
17194   DIE_UNLESS(mysql_client_init(&con));
17195 
17196   DIE_UNLESS(mysql_real_connect(&con,
17197                                 opt_host,
17198                                 opt_user,
17199                                 opt_password,
17200                                 opt_db ? opt_db : "test",
17201                                 opt_port,
17202                                 opt_unix_socket,
17203                                 CLIENT_FOUND_ROWS));
17204 
17205   /***********************************************************************
17206     Remember original SQL_BIG_SELECTS, MAX_JOIN_SIZE values.
17207   ***********************************************************************/
17208 
17209   query_int_variable(&con,
17210                      "@@session.sql_big_selects",
17211                      &sql_big_selects_orig);
17212 
17213   query_str_variable(&con,
17214                      "@@global.max_join_size",
17215                      max_join_size_orig,
17216                      sizeof(max_join_size_orig));
17217 
17218   /***********************************************************************
17219     Test that COM_CHANGE_USER resets the SQL_BIG_SELECTS to the initial value.
17220   ***********************************************************************/
17221 
17222   /* Issue COM_CHANGE_USER. */
17223 
17224   bug20023_change_user(&con);
17225 
17226   /* Query SQL_BIG_SELECTS. */
17227 
17228   query_int_variable(&con,
17229                      "@@session.sql_big_selects",
17230                      &sql_big_selects_2);
17231 
17232   /* Check that SQL_BIG_SELECTS is reset properly. */
17233 
17234   DIE_UNLESS(sql_big_selects_orig == sql_big_selects_2);
17235 
17236   /***********************************************************************
17237     Test that if MAX_JOIN_SIZE set to non-default value,
17238     SQL_BIG_SELECTS will be 0.
17239   ***********************************************************************/
17240 
17241   /* Set MAX_JOIN_SIZE to some non-default value. */
17242 
17243   DIE_IF(mysql_query(&con, "SET @@global.max_join_size = 10000"));
17244   DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default"));
17245 
17246   /* Issue COM_CHANGE_USER. */
17247 
17248   bug20023_change_user(&con);
17249 
17250   /* Query SQL_BIG_SELECTS. */
17251 
17252   query_int_variable(&con,
17253                      "@@session.sql_big_selects",
17254                      &sql_big_selects_3);
17255 
17256   /* Check that SQL_BIG_SELECTS is 0. */
17257 
17258   DIE_UNLESS(sql_big_selects_3 == 0);
17259 
17260   /***********************************************************************
17261     Test that if MAX_JOIN_SIZE set to default value,
17262     SQL_BIG_SELECTS will be 1.
17263   ***********************************************************************/
17264 
17265   /* Set MAX_JOIN_SIZE to the default value (2^64-1). */
17266 
17267   DIE_IF(mysql_query(&con, "SET @@global.max_join_size = cast(-1 as unsigned int)"));
17268   DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default"));
17269 
17270   /* Issue COM_CHANGE_USER. */
17271 
17272   bug20023_change_user(&con);
17273 
17274   /* Query SQL_BIG_SELECTS. */
17275 
17276   query_int_variable(&con,
17277                      "@@session.sql_big_selects",
17278                      &sql_big_selects_4);
17279 
17280   /* Check that SQL_BIG_SELECTS is 1. */
17281 
17282   DIE_UNLESS(sql_big_selects_4 == 1);
17283 
17284   /***********************************************************************
17285     Restore MAX_JOIN_SIZE.
17286     Check that SQL_BIG_SELECTS will be the original one.
17287   ***********************************************************************/
17288 
17289   /* Restore MAX_JOIN_SIZE. */
17290 
17291   my_snprintf(query_buffer,
17292            sizeof (query_buffer),
17293            "SET @@global.max_join_size = %s",
17294            max_join_size_orig);
17295 
17296   DIE_IF(mysql_query(&con, query_buffer));
17297 
17298   DIE_IF(mysql_query(&con, "SET @@global.max_join_size = cast(-1 as unsigned int)"));
17299   DIE_IF(mysql_query(&con, "SET @@session.max_join_size = default"));
17300 
17301   /* Issue COM_CHANGE_USER. */
17302 
17303   bug20023_change_user(&con);
17304 
17305   /* Query SQL_BIG_SELECTS. */
17306 
17307   query_int_variable(&con,
17308                      "@@session.sql_big_selects",
17309                      &sql_big_selects_5);
17310 
17311   /* Check that SQL_BIG_SELECTS is 1. */
17312 
17313   DIE_UNLESS(sql_big_selects_5 == sql_big_selects_orig);
17314 
17315   /***********************************************************************
17316     That's it. Cleanup.
17317   ***********************************************************************/
17318 
17319   mysql_close(&con);
17320 }
17321 
bug31418_impl()17322 static void bug31418_impl()
17323 {
17324   MYSQL con;
17325 
17326   my_bool is_null;
17327   int rc= 0;
17328 
17329   /* Create a new connection. */
17330 
17331   DIE_UNLESS(mysql_client_init(&con));
17332 
17333   DIE_UNLESS(mysql_real_connect(&con,
17334                                 opt_host,
17335                                 opt_user,
17336                                 opt_password,
17337                                 opt_db ? opt_db : "test",
17338                                 opt_port,
17339                                 opt_unix_socket,
17340                                 CLIENT_FOUND_ROWS));
17341 
17342   /***********************************************************************
17343     Check that lock is free:
17344       - IS_FREE_LOCK() should return 1;
17345       - IS_USED_LOCK() should return NULL;
17346   ***********************************************************************/
17347 
17348   is_null= query_int_variable(&con,
17349                               "IS_FREE_LOCK('bug31418')",
17350                               &rc);
17351   DIE_UNLESS(!is_null && rc);
17352 
17353   is_null= query_int_variable(&con,
17354                               "IS_USED_LOCK('bug31418')",
17355                               &rc);
17356   DIE_UNLESS(is_null);
17357 
17358   /***********************************************************************
17359     Acquire lock and check the lock status (the lock must be in use):
17360       - IS_FREE_LOCK() should return 0;
17361       - IS_USED_LOCK() should return non-zero thread id;
17362   ***********************************************************************/
17363 
17364   query_int_variable(&con, "GET_LOCK('bug31418', 1)", &rc);
17365   DIE_UNLESS(rc);
17366 
17367   is_null= query_int_variable(&con,
17368                               "IS_FREE_LOCK('bug31418')",
17369                               &rc);
17370   DIE_UNLESS(!is_null && !rc);
17371 
17372   is_null= query_int_variable(&con,
17373                               "IS_USED_LOCK('bug31418')",
17374                               &rc);
17375   DIE_UNLESS(!is_null && rc);
17376 
17377   /***********************************************************************
17378     Issue COM_CHANGE_USER command and check the lock status
17379     (the lock must be free):
17380       - IS_FREE_LOCK() should return 1;
17381       - IS_USED_LOCK() should return NULL;
17382   **********************************************************************/
17383 
17384   bug20023_change_user(&con);
17385 
17386   is_null= query_int_variable(&con,
17387                               "IS_FREE_LOCK('bug31418')",
17388                               &rc);
17389   DIE_UNLESS(!is_null && rc);
17390 
17391   is_null= query_int_variable(&con,
17392                               "IS_USED_LOCK('bug31418')",
17393                               &rc);
17394   DIE_UNLESS(is_null);
17395 
17396   /***********************************************************************
17397    That's it. Cleanup.
17398   ***********************************************************************/
17399 
17400   mysql_close(&con);
17401 }
17402 
test_bug31418()17403 static void test_bug31418()
17404 {
17405   /* Run test case for BUG#31418 for three different connections. */
17406 
17407   bug31418_impl();
17408 
17409   bug31418_impl();
17410 
17411   bug31418_impl();
17412 }
17413 
17414 
17415 
17416 /**
17417   Bug#31669 Buffer overflow in mysql_change_user()
17418 */
17419 
17420 #define LARGE_BUFFER_SIZE 2048
17421 #define OLD_USERNAME_CHAR_LENGTH 16
17422 
test_bug31669()17423 static void test_bug31669()
17424 {
17425   int rc;
17426   static char buff[LARGE_BUFFER_SIZE+1];
17427 #ifndef EMBEDDED_LIBRARY
17428   static char user[OLD_USERNAME_CHAR_LENGTH+1];
17429   static char db[NAME_CHAR_LEN+1];
17430   static char query[LARGE_BUFFER_SIZE*2];
17431 #endif
17432   MYSQL* conn;
17433 
17434   DBUG_ENTER("test_bug31669");
17435   myheader("test_bug31669");
17436 
17437   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
17438 
17439   rc= mysql_change_user(conn, NULL, NULL, NULL);
17440   DIE_UNLESS(rc);
17441 
17442   rc= mysql_change_user(conn, "", "", "");
17443   DIE_UNLESS(rc);
17444 
17445   memset(buff, 'a', sizeof(buff) -  1);
17446   buff[sizeof(buff) -  1]= 0;
17447 
17448   mysql_close(conn);
17449   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
17450 
17451   rc= mysql_change_user(conn, buff, buff, buff);
17452   DIE_UNLESS(rc);
17453 
17454   rc = mysql_change_user(conn, opt_user, opt_password, current_db);
17455   DIE_UNLESS(!rc);
17456 
17457 #ifndef EMBEDDED_LIBRARY
17458   memset(db, 'a', sizeof(db));
17459   db[NAME_CHAR_LEN]= 0;
17460   strxmov(query, "CREATE DATABASE IF NOT EXISTS ", db, NullS);
17461   rc= mysql_query(conn, query);
17462   myquery(rc);
17463 
17464   memset(user, 'b', sizeof(user));
17465   user[OLD_USERNAME_CHAR_LENGTH]= 0;
17466   memset(buff, 'c', sizeof(buff));
17467   buff[LARGE_BUFFER_SIZE]= 0;
17468   strxmov(query, "GRANT ALL PRIVILEGES ON *.* TO '", user, "'@'%' IDENTIFIED BY "
17469                  "'", buff, "' WITH GRANT OPTION", NullS);
17470   rc= mysql_query(conn, query);
17471   myquery(rc);
17472 
17473   strxmov(query, "GRANT ALL PRIVILEGES ON *.* TO '", user, "'@'localhost' IDENTIFIED BY "
17474                  "'", buff, "' WITH GRANT OPTION", NullS);
17475   rc= mysql_query(conn, query);
17476   myquery(rc);
17477 
17478   rc= mysql_query(conn, "FLUSH PRIVILEGES");
17479   myquery(rc);
17480 
17481   rc= mysql_change_user(conn, user, buff, db);
17482   DIE_UNLESS(!rc);
17483 
17484   user[OLD_USERNAME_CHAR_LENGTH-1]= 'a';
17485   rc= mysql_change_user(conn, user, buff, db);
17486   DIE_UNLESS(rc);
17487 
17488   user[OLD_USERNAME_CHAR_LENGTH-1]= 'b';
17489   buff[LARGE_BUFFER_SIZE-1]= 'd';
17490   rc= mysql_change_user(conn, user, buff, db);
17491   DIE_UNLESS(rc);
17492 
17493   buff[LARGE_BUFFER_SIZE-1]= 'c';
17494   db[NAME_CHAR_LEN-1]= 'e';
17495   rc= mysql_change_user(conn, user, buff, db);
17496   DIE_UNLESS(rc);
17497 
17498   mysql_close(conn);
17499   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
17500 
17501   db[NAME_CHAR_LEN-1]= 'a';
17502   rc= mysql_change_user(conn, user, buff, db);
17503   DIE_UNLESS(!rc);
17504 
17505   rc= mysql_change_user(conn, user + 1, buff + 1, db + 1);
17506   DIE_UNLESS(rc);
17507 
17508   rc = mysql_change_user(conn, opt_user, opt_password, current_db);
17509   DIE_UNLESS(!rc);
17510 
17511   strxmov(query, "DROP DATABASE ", db, NullS);
17512   rc= mysql_query(conn, query);
17513   myquery(rc);
17514 
17515   strxmov(query, "DELETE FROM mysql.user WHERE User='", user, "'", NullS);
17516   rc= mysql_query(conn, query);
17517   myquery(rc);
17518   DIE_UNLESS(mysql_affected_rows(conn) == 2);
17519 #endif
17520 
17521   mysql_close(conn);
17522 
17523   DBUG_VOID_RETURN;
17524 }
17525 
17526 
17527 /**
17528   Bug#28386 the general log is incomplete
17529 */
17530 
test_bug28386()17531 static void test_bug28386()
17532 {
17533   int rc;
17534   MYSQL_STMT *stmt;
17535   MYSQL_RES *result;
17536   MYSQL_ROW row;
17537   MYSQL_BIND bind;
17538   const char hello[]= "hello world!";
17539 
17540   DBUG_ENTER("test_bug28386");
17541   myheader("test_bug28386");
17542 
17543   rc= mysql_query(mysql, "select @@global.log_output");
17544   myquery(rc);
17545 
17546   result= mysql_store_result(mysql);
17547   DIE_UNLESS(result);
17548 
17549   row= mysql_fetch_row(result);
17550   if (! strstr(row[0], "TABLE"))
17551   {
17552     mysql_free_result(result);
17553     if (! opt_silent)
17554       printf("Skipping the test since logging to tables is not enabled\n");
17555     /* Log output is not to tables */
17556     DBUG_VOID_RETURN;
17557   }
17558   mysql_free_result(result);
17559 
17560   enable_query_logs(1);
17561 
17562   stmt= mysql_simple_prepare(mysql, "SELECT ?");
17563   check_stmt(stmt);
17564 
17565   memset(&bind, 0, sizeof(bind));
17566 
17567   bind.buffer_type= MYSQL_TYPE_STRING;
17568   bind.buffer= (void *) hello;
17569   bind.buffer_length= sizeof(hello);
17570 
17571   mysql_stmt_bind_param(stmt, &bind);
17572   mysql_stmt_send_long_data(stmt, 0, hello, sizeof(hello));
17573 
17574   rc= mysql_stmt_execute(stmt);
17575   check_execute(stmt, rc);
17576 
17577   rc= my_process_stmt_result(stmt);
17578   DIE_UNLESS(rc == 1);
17579 
17580   rc= mysql_stmt_reset(stmt);
17581   check_execute(stmt, rc);
17582 
17583   rc= mysql_stmt_close(stmt);
17584   DIE_UNLESS(!rc);
17585 
17586   rc= mysql_query(mysql, "select * from mysql.general_log where "
17587                          "command_type='Close stmt' or "
17588                          "command_type='Reset stmt' or "
17589                          "command_type='Long Data'");
17590   myquery(rc);
17591 
17592   result= mysql_store_result(mysql);
17593   mytest(result);
17594 
17595   DIE_UNLESS(mysql_num_rows(result) == 3);
17596 
17597   mysql_free_result(result);
17598 
17599   restore_query_logs();
17600 
17601   DBUG_VOID_RETURN;
17602 }
17603 
17604 
test_wl4166_1()17605 static void test_wl4166_1()
17606 {
17607   MYSQL_STMT *stmt;
17608   int        int_data;
17609   char       str_data[50];
17610   char       tiny_data;
17611   short      small_data;
17612   longlong   big_data;
17613   float      real_data;
17614   double     double_data;
17615   ulong      length[7];
17616   my_bool    is_null[7];
17617   MYSQL_BIND my_bind[7];
17618   int rc;
17619   int i;
17620 
17621   myheader("test_wl4166_1");
17622 
17623   rc= mysql_query(mysql, "DROP TABLE IF EXISTS table_4166");
17624   myquery(rc);
17625 
17626   rc= mysql_query(mysql, "CREATE TABLE table_4166(col1 tinyint NOT NULL, "
17627                          "col2 varchar(15), col3 int, "
17628                          "col4 smallint, col5 bigint, "
17629                          "col6 float, col7 double, "
17630                          "colX varchar(10) default NULL)");
17631   myquery(rc);
17632 
17633   stmt= mysql_simple_prepare(mysql,
17634     "INSERT INTO table_4166(col1, col2, col3, col4, col5, col6, col7) "
17635     "VALUES(?, ?, ?, ?, ?, ?, ?)");
17636   check_stmt(stmt);
17637 
17638   verify_param_count(stmt, 7);
17639 
17640   bzero(my_bind, sizeof(my_bind));
17641   /* tinyint */
17642   my_bind[0].buffer_type= MYSQL_TYPE_TINY;
17643   my_bind[0].buffer= (void *)&tiny_data;
17644   /* string */
17645   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
17646   my_bind[1].buffer= (void *)str_data;
17647   my_bind[1].buffer_length= 1000;                  /* Max string length */
17648   /* integer */
17649   my_bind[2].buffer_type= MYSQL_TYPE_LONG;
17650   my_bind[2].buffer= (void *)&int_data;
17651   /* short */
17652   my_bind[3].buffer_type= MYSQL_TYPE_SHORT;
17653   my_bind[3].buffer= (void *)&small_data;
17654   /* bigint */
17655   my_bind[4].buffer_type= MYSQL_TYPE_LONGLONG;
17656   my_bind[4].buffer= (void *)&big_data;
17657   /* float */
17658   my_bind[5].buffer_type= MYSQL_TYPE_FLOAT;
17659   my_bind[5].buffer= (void *)&real_data;
17660   /* double */
17661   my_bind[6].buffer_type= MYSQL_TYPE_DOUBLE;
17662   my_bind[6].buffer= (void *)&double_data;
17663 
17664   for (i= 0; i < (int) array_elements(my_bind); i++)
17665   {
17666     my_bind[i].length= &length[i];
17667     my_bind[i].is_null= &is_null[i];
17668     is_null[i]= 0;
17669   }
17670 
17671   rc= mysql_stmt_bind_param(stmt, my_bind);
17672   check_execute(stmt, rc);
17673 
17674   int_data= 320;
17675   small_data= 1867;
17676   big_data= 1000;
17677   real_data= 2;
17678   double_data= 6578.001;
17679 
17680   /* now, execute the prepared statement to insert 10 records.. */
17681   for (tiny_data= 0; tiny_data < 10; tiny_data++)
17682   {
17683     length[1]= sprintf(str_data, "MySQL%d", int_data);
17684     rc= mysql_stmt_execute(stmt);
17685     check_execute(stmt, rc);
17686     int_data += 25;
17687     small_data += 10;
17688     big_data += 100;
17689     real_data += 1;
17690     double_data += 10.09;
17691   }
17692 
17693   /* force a re-prepare with some DDL */
17694 
17695   rc= mysql_query(mysql,
17696     "ALTER TABLE table_4166 change colX colX varchar(20) default NULL");
17697   myquery(rc);
17698 
17699   /*
17700     execute the prepared statement again,
17701     without changing the types of parameters already bound.
17702   */
17703 
17704   for (tiny_data= 50; tiny_data < 60; tiny_data++)
17705   {
17706     length[1]= sprintf(str_data, "MySQL%d", int_data);
17707     rc= mysql_stmt_execute(stmt);
17708     check_execute(stmt, rc);
17709     int_data += 25;
17710     small_data += 10;
17711     big_data += 100;
17712     real_data += 1;
17713     double_data += 10.09;
17714   }
17715 
17716   mysql_stmt_close(stmt);
17717 
17718   rc= mysql_query(mysql, "DROP TABLE table_4166");
17719   myquery(rc);
17720 }
17721 
17722 
test_wl4166_2()17723 static void test_wl4166_2()
17724 {
17725   MYSQL_STMT *stmt;
17726   int        c_int;
17727   MYSQL_TIME d_date;
17728   MYSQL_BIND bind_out[2];
17729   int rc;
17730 
17731   myheader("test_wl4166_2");
17732 
17733   rc= mysql_query(mysql, "SET SQL_MODE=''");
17734   myquery(rc);
17735 
17736   rc= mysql_query(mysql, "drop table if exists t1");
17737   myquery(rc);
17738   rc= mysql_query(mysql, "create table t1 (c_int int, d_date date)");
17739   myquery(rc);
17740   rc= mysql_query(mysql,
17741                   "insert into t1 (c_int, d_date) values (42, '1948-05-15')");
17742   myquery(rc);
17743 
17744   stmt= mysql_simple_prepare(mysql, "select * from t1");
17745   check_stmt(stmt);
17746 
17747   bzero(bind_out, sizeof(bind_out));
17748   bind_out[0].buffer_type= MYSQL_TYPE_LONG;
17749   bind_out[0].buffer= (void*) &c_int;
17750 
17751   bind_out[1].buffer_type= MYSQL_TYPE_DATE;
17752   bind_out[1].buffer= (void*) &d_date;
17753 
17754   rc= mysql_stmt_bind_result(stmt, bind_out);
17755   check_execute(stmt, rc);
17756 
17757   /* int -> varchar transition */
17758 
17759   rc= mysql_query(mysql,
17760                   "alter table t1 change column c_int c_int varchar(11)");
17761   myquery(rc);
17762 
17763   rc= mysql_stmt_execute(stmt);
17764   check_execute(stmt, rc);
17765 
17766   rc= mysql_stmt_fetch(stmt);
17767   check_execute(stmt, rc);
17768 
17769   DIE_UNLESS(c_int == 42);
17770   DIE_UNLESS(d_date.year == 1948);
17771   DIE_UNLESS(d_date.month == 5);
17772   DIE_UNLESS(d_date.day == 15);
17773 
17774   rc= mysql_stmt_fetch(stmt);
17775   DIE_UNLESS(rc == MYSQL_NO_DATA);
17776 
17777   /* varchar to int retrieval with truncation */
17778 
17779   rc= mysql_query(mysql, "update t1 set c_int='abcde'");
17780   myquery(rc);
17781 
17782   rc= mysql_stmt_execute(stmt);
17783   check_execute(stmt, rc);
17784 
17785   rc= mysql_stmt_fetch(stmt);
17786   check_execute_r(stmt, rc);
17787 
17788   DIE_UNLESS(c_int == 0);
17789 
17790   rc= mysql_stmt_fetch(stmt);
17791   DIE_UNLESS(rc == MYSQL_NO_DATA);
17792 
17793   /* alter table and increase the number of columns */
17794   rc= mysql_query(mysql, "alter table t1 add column d_int int");
17795   myquery(rc);
17796 
17797   rc= mysql_stmt_execute(stmt);
17798   check_execute_r(stmt, rc);
17799 
17800   rc= mysql_stmt_reset(stmt);
17801   check_execute(stmt, rc);
17802 
17803   /* decrease the number of columns */
17804   rc= mysql_query(mysql, "alter table t1 drop d_date, drop d_int");
17805   myquery(rc);
17806 
17807   rc= mysql_stmt_execute(stmt);
17808   check_execute_r(stmt, rc);
17809 
17810   mysql_stmt_close(stmt);
17811   rc= mysql_query(mysql, "drop table t1");
17812   myquery(rc);
17813 }
17814 
17815 
17816 /**
17817   Test how warnings generated during assignment of parameters
17818   are (currently not) preserve in case of reprepare.
17819 */
17820 
test_wl4166_3()17821 static void test_wl4166_3()
17822 {
17823   int rc;
17824   MYSQL_STMT *stmt;
17825   MYSQL_BIND my_bind[1];
17826   MYSQL_TIME tm[1];
17827 
17828   myheader("test_wl4166_3");
17829 
17830   rc= mysql_query(mysql, "drop table if exists t1");
17831   myquery(rc);
17832 
17833   rc= mysql_query(mysql, "create table t1 (year datetime)");
17834   myquery(rc);
17835 
17836   stmt= mysql_simple_prepare(mysql, "insert into t1 (year) values (?)");
17837   check_stmt(stmt);
17838   verify_param_count(stmt, 1);
17839 
17840   bzero((char*) my_bind, sizeof(my_bind));
17841   my_bind[0].buffer_type= MYSQL_TYPE_DATETIME;
17842   my_bind[0].buffer= &tm[0];
17843 
17844   rc= mysql_stmt_bind_param(stmt, my_bind);
17845   check_execute(stmt, rc);
17846 
17847   tm[0].year= 10000;
17848   tm[0].month= 1; tm[0].day= 1;
17849   tm[0].hour= 1; tm[0].minute= 1; tm[0].second= 1;
17850   tm[0].second_part= 0; tm[0].neg= 0;
17851 
17852   /* Cause a statement reprepare */
17853   rc= mysql_query(mysql, "alter table t1 add column c int");
17854   myquery(rc);
17855 
17856   rc= mysql_stmt_execute(stmt);
17857   check_execute(stmt, rc);
17858   /*
17859     The warning about data truncation when assigning a parameter is lost.
17860     This is a bug.
17861   */
17862   my_process_warnings(mysql, 0);
17863 
17864   verify_col_data("t1", "year", "0000-00-00 00:00:00");
17865 
17866   mysql_stmt_close(stmt);
17867 
17868   rc= mysql_query(mysql, "drop table t1");
17869   myquery(rc);
17870 }
17871 
17872 
17873 /**
17874   Test that long data parameters, as well as parameters
17875   that were originally in a different character set, are
17876   preserved in case of reprepare.
17877 */
17878 
test_wl4166_4()17879 static void test_wl4166_4()
17880 {
17881   MYSQL_STMT *stmt;
17882   int rc;
17883   const char *stmt_text;
17884   MYSQL_BIND bind_array[2];
17885 
17886   /* Represented as numbers to keep UTF8 tools from clobbering them. */
17887   const char *koi8= "\xee\xd5\x2c\x20\xda\xc1\x20\xd2\xd9\xc2\xc1\xcc\xcb\xd5";
17888   const char *cp1251= "\xcd\xf3\x2c\x20\xe7\xe0\x20\xf0\xfb\xe1\xe0\xeb\xea\xf3";
17889   char buf1[16], buf2[16];
17890   ulong buf1_len, buf2_len;
17891 
17892   myheader("test_wl4166_4");
17893 
17894   rc= mysql_query(mysql, "drop table if exists t1");
17895   myquery(rc);
17896 
17897   /*
17898     Create table with binary columns, set session character set to cp1251,
17899     client character set to koi8, and make sure that there is conversion
17900     on insert and no conversion on select
17901   */
17902   rc= mysql_query(mysql,
17903                   "create table t1 (c1 varbinary(255), c2 varbinary(255))");
17904   myquery(rc);
17905   rc= mysql_query(mysql, "set character_set_client=koi8r, "
17906                          "character_set_connection=cp1251, "
17907                          "character_set_results=koi8r");
17908   myquery(rc);
17909 
17910   bzero((char*) bind_array, sizeof(bind_array));
17911 
17912   bind_array[0].buffer_type= MYSQL_TYPE_STRING;
17913 
17914   bind_array[1].buffer_type= MYSQL_TYPE_STRING;
17915   bind_array[1].buffer= (void *) koi8;
17916   bind_array[1].buffer_length= strlen(koi8);
17917 
17918   stmt= mysql_stmt_init(mysql);
17919   check_stmt(stmt);
17920 
17921   stmt_text= "insert into t1 (c1, c2) values (?, ?)";
17922 
17923   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
17924   check_execute(stmt, rc);
17925 
17926   mysql_stmt_bind_param(stmt, bind_array);
17927 
17928   mysql_stmt_send_long_data(stmt, 0, koi8, strlen(koi8));
17929 
17930   /* Cause a reprepare at statement execute */
17931   rc= mysql_query(mysql, "alter table t1 add column d int");
17932   myquery(rc);
17933 
17934   rc= mysql_stmt_execute(stmt);
17935   check_execute(stmt, rc);
17936 
17937   stmt_text= "select c1, c2 from t1";
17938 
17939   /* c1 and c2 are binary so no conversion will be done on select */
17940   rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
17941   check_execute(stmt, rc);
17942 
17943   rc= mysql_stmt_execute(stmt);
17944   check_execute(stmt, rc);
17945 
17946   bind_array[0].buffer= buf1;
17947   bind_array[0].buffer_length= sizeof(buf1);
17948   bind_array[0].length= &buf1_len;
17949 
17950   bind_array[1].buffer= buf2;
17951   bind_array[1].buffer_length= sizeof(buf2);
17952   bind_array[1].length= &buf2_len;
17953 
17954   mysql_stmt_bind_result(stmt, bind_array);
17955 
17956   rc= mysql_stmt_fetch(stmt);
17957   check_execute(stmt, rc);
17958 
17959   DIE_UNLESS(buf1_len == strlen(cp1251));
17960   DIE_UNLESS(buf2_len == strlen(cp1251));
17961   DIE_UNLESS(!memcmp(buf1, cp1251, buf1_len));
17962   DIE_UNLESS(!memcmp(buf2, cp1251, buf1_len));
17963 
17964   rc= mysql_stmt_fetch(stmt);
17965   DIE_UNLESS(rc == MYSQL_NO_DATA);
17966 
17967   mysql_stmt_close(stmt);
17968 
17969   rc= mysql_query(mysql, "drop table t1");
17970   myquery(rc);
17971   rc= mysql_query(mysql, "set names default");
17972   myquery(rc);
17973 }
17974 
17975 /**
17976   Bug#36004 mysql_stmt_prepare resets the list of warnings
17977 */
17978 
test_bug36004()17979 static void test_bug36004()
17980 {
17981   int rc, warning_count= 0;
17982   MYSQL_STMT *stmt;
17983 
17984   DBUG_ENTER("test_bug36004");
17985   myheader("test_bug36004");
17986 
17987   rc= mysql_query(mysql, "drop table if exists inexistant");
17988   myquery(rc);
17989 
17990   DIE_UNLESS(mysql_warning_count(mysql) == 1);
17991   query_int_variable(mysql, "@@warning_count", &warning_count);
17992   DIE_UNLESS(warning_count);
17993 
17994   stmt= mysql_simple_prepare(mysql, "select 1");
17995   check_stmt(stmt);
17996 
17997   DIE_UNLESS(mysql_warning_count(mysql) == 0);
17998   query_int_variable(mysql, "@@warning_count", &warning_count);
17999   DIE_UNLESS(warning_count);
18000 
18001   rc= mysql_stmt_execute(stmt);
18002   check_execute(stmt, rc);
18003 
18004   DIE_UNLESS(mysql_warning_count(mysql) == 0);
18005   mysql_stmt_close(stmt);
18006 
18007   query_int_variable(mysql, "@@warning_count", &warning_count);
18008   DIE_UNLESS(warning_count);
18009 
18010   stmt= mysql_simple_prepare(mysql, "drop table if exists inexistant");
18011   check_stmt(stmt);
18012 
18013   query_int_variable(mysql, "@@warning_count", &warning_count);
18014   DIE_UNLESS(warning_count == 0);
18015   mysql_stmt_close(stmt);
18016 
18017   DBUG_VOID_RETURN;
18018 }
18019 
18020 /**
18021   Test that COM_REFRESH issues a implicit commit.
18022 */
18023 
test_wl4284_1()18024 static void test_wl4284_1()
18025 {
18026   int rc;
18027   MYSQL_ROW row;
18028   MYSQL_RES *result;
18029 
18030   DBUG_ENTER("test_wl4284_1");
18031   myheader("test_wl4284_1");
18032 
18033   /* set AUTOCOMMIT to OFF */
18034   rc= mysql_autocommit(mysql, FALSE);
18035   myquery(rc);
18036 
18037   rc= mysql_query(mysql, "DROP TABLE IF EXISTS trans");
18038   myquery(rc);
18039 
18040   rc= mysql_query(mysql, "CREATE TABLE trans (a INT) ENGINE= InnoDB");
18041   myquery(rc);
18042 
18043   rc= mysql_query(mysql, "INSERT INTO trans VALUES(1)");
18044   myquery(rc);
18045 
18046   rc= mysql_refresh(mysql, REFRESH_GRANT | REFRESH_TABLES);
18047   myquery(rc);
18048 
18049   rc= mysql_rollback(mysql);
18050   myquery(rc);
18051 
18052   rc= mysql_query(mysql, "SELECT * FROM trans");
18053   myquery(rc);
18054 
18055   result= mysql_use_result(mysql);
18056   mytest(result);
18057 
18058   row= mysql_fetch_row(result);
18059   mytest(row);
18060 
18061   mysql_free_result(result);
18062 
18063   /* set AUTOCOMMIT to ON */
18064   rc= mysql_autocommit(mysql, TRUE);
18065   myquery(rc);
18066 
18067   rc= mysql_query(mysql, "DROP TABLE trans");
18068   myquery(rc);
18069 
18070   DBUG_VOID_RETURN;
18071 }
18072 
18073 
test_bug38486(void)18074 static void test_bug38486(void)
18075 {
18076   MYSQL_STMT *stmt;
18077   const char *stmt_text;
18078   unsigned long type= CURSOR_TYPE_READ_ONLY;
18079 
18080   DBUG_ENTER("test_bug38486");
18081   myheader("test_bug38486");
18082 
18083   stmt= mysql_stmt_init(mysql);
18084   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*)&type);
18085   stmt_text= "CREATE TABLE t1 (a INT)";
18086   mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
18087   mysql_stmt_execute(stmt);
18088   mysql_stmt_close(stmt);
18089 
18090   stmt= mysql_stmt_init(mysql);
18091   mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*)&type);
18092   stmt_text= "INSERT INTO t1 VALUES (1)";
18093   mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
18094   mysql_stmt_execute(stmt);
18095   mysql_stmt_close(stmt);
18096 
18097   DBUG_VOID_RETURN;
18098 }
18099 
18100 
18101 /**
18102      Bug# 33831 mysql_real_connect() should fail if
18103      given an already connected MYSQL handle.
18104 */
18105 
test_bug33831(void)18106 static void test_bug33831(void)
18107 {
18108   MYSQL *l_mysql;
18109 
18110   DBUG_ENTER("test_bug33831");
18111 
18112   if (!(l_mysql= mysql_client_init(NULL)))
18113   {
18114     myerror("mysql_client_init() failed");
18115     DIE_UNLESS(0);
18116   }
18117   if (!(mysql_real_connect(l_mysql, opt_host, opt_user,
18118                            opt_password, current_db, opt_port,
18119                            opt_unix_socket, 0)))
18120   {
18121     myerror("connection failed");
18122     DIE_UNLESS(0);
18123   }
18124 
18125   if (mysql_real_connect(l_mysql, opt_host, opt_user,
18126                          opt_password, current_db, opt_port,
18127                          opt_unix_socket, 0))
18128   {
18129     myerror("connection should have failed");
18130     DIE_UNLESS(0);
18131   }
18132 
18133   mysql_close(l_mysql);
18134 
18135   DBUG_VOID_RETURN;
18136 }
18137 
18138 
test_bug40365(void)18139 static void test_bug40365(void)
18140 {
18141   uint         rc, i;
18142   MYSQL_STMT   *stmt= 0;
18143   MYSQL_BIND   my_bind[2];
18144   my_bool      is_null[2]= {0};
18145   MYSQL_TIME   tm[2];
18146 
18147   DBUG_ENTER("test_bug40365");
18148 
18149   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18150   myquery(rc);
18151   rc= mysql_query(mysql, "CREATE TABLE t1(c1 DATETIME, \
18152                                           c2 DATE)");
18153   myquery(rc);
18154 
18155   stmt= mysql_simple_prepare(mysql, "INSERT INTO t1 VALUES(?, ?)");
18156   check_stmt(stmt);
18157   verify_param_count(stmt, 2);
18158 
18159   bzero((char*) my_bind, sizeof(my_bind));
18160   my_bind[0].buffer_type= MYSQL_TYPE_DATETIME;
18161   my_bind[1].buffer_type= MYSQL_TYPE_DATE;
18162   for (i= 0; i < (int) array_elements(my_bind); i++)
18163   {
18164     my_bind[i].buffer= (void *) &tm[i];
18165     my_bind[i].is_null= &is_null[i];
18166   }
18167 
18168   rc= mysql_stmt_bind_param(stmt, my_bind);
18169   check_execute(stmt, rc);
18170 
18171   for (i= 0; i < (int) array_elements(my_bind); i++)
18172   {
18173     tm[i].neg= 0;
18174     tm[i].second_part= 0;
18175     tm[i].year= 2009;
18176     tm[i].month= 2;
18177     tm[i].day= 29;
18178     tm[i].hour= 0;
18179     tm[i].minute= 0;
18180     tm[i].second= 0;
18181   }
18182   rc= mysql_stmt_execute(stmt);
18183   check_execute(stmt, rc);
18184 
18185   rc= mysql_commit(mysql);
18186   myquery(rc);
18187   mysql_stmt_close(stmt);
18188 
18189   stmt= mysql_simple_prepare(mysql, "SELECT * FROM t1");
18190   check_stmt(stmt);
18191 
18192   rc= mysql_stmt_bind_result(stmt, my_bind);
18193   check_execute(stmt, rc);
18194 
18195   rc= mysql_stmt_execute(stmt);
18196   check_execute(stmt, rc);
18197 
18198   rc= mysql_stmt_store_result(stmt);
18199   check_execute(stmt, rc);
18200 
18201   rc= mysql_stmt_fetch(stmt);
18202   check_execute(stmt, rc);
18203 
18204   if (!opt_silent)
18205     fprintf(stdout, "\n");
18206 
18207   for (i= 0; i < array_elements(my_bind); i++)
18208   {
18209     if (!opt_silent)
18210       fprintf(stdout, "\ntime[%d]: %02d-%02d-%02d ",
18211               i, tm[i].year, tm[i].month, tm[i].day);
18212     DIE_UNLESS(tm[i].year == 0);
18213     DIE_UNLESS(tm[i].month == 0);
18214     DIE_UNLESS(tm[i].day == 0);
18215   }
18216   mysql_stmt_close(stmt);
18217   rc= mysql_commit(mysql);
18218   myquery(rc);
18219 
18220   DBUG_VOID_RETURN;
18221 }
18222 
18223 
18224 /**
18225   Subtest for Bug#43560. Verifies that a loss of connection on the server side
18226   is handled well by the mysql_stmt_execute() call, i.e., no SIGSEGV due to
18227   a vio socket that is cleared upon closed connection.
18228 
18229   Assumes the presence of the close_conn_after_stmt_execute debug feature in
18230   the server. Verifies that it is connected to a debug server before proceeding
18231   with the test.
18232  */
test_bug43560(void)18233 static void test_bug43560(void)
18234 {
18235   MYSQL*       conn;
18236   uint         rc;
18237   MYSQL_STMT   *stmt= 0;
18238   MYSQL_BIND   bind;
18239   my_bool      is_null= 0;
18240   char         buffer[256];
18241   const uint   BUFSIZE= sizeof(buffer);
18242   const char*  values[] = {"eins", "zwei", "drei", "viele", NULL};
18243   const char   insert_str[] = "INSERT INTO t1 (c2) VALUES (?)";
18244   unsigned long length;
18245   const unsigned int drop_db= opt_drop_db;
18246 
18247   DBUG_ENTER("test_bug43560");
18248   myheader("test_bug43560");
18249 
18250   /* Make sure we only run against a debug server. */
18251   if (!strstr(mysql->server_version, "debug"))
18252   {
18253     fprintf(stdout, "Skipping test_bug43560: server not DEBUG version\n");
18254     DBUG_VOID_RETURN;
18255   }
18256   if (opt_unix_socket)
18257   {
18258     fprintf(stdout, "Skipping test_bug43560: connected via UNIX socket\n");
18259     DBUG_VOID_RETURN;
18260   }
18261   /*
18262     Set up a separate connection for this test to avoid messing up the
18263     general MYSQL object used in other subtests. Use TCP protocol to avoid
18264     problems with the buffer semantics of AF_UNIX, and turn off auto reconnect.
18265   */
18266   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
18267 
18268   rc= mysql_query(conn, "DROP TABLE IF EXISTS t1");
18269   myquery(rc);
18270   rc= mysql_query(conn,
18271     "CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT, c2 CHAR(10))");
18272   myquery(rc);
18273 
18274   stmt= mysql_stmt_init(conn);
18275   check_stmt(stmt);
18276   rc= mysql_stmt_prepare(stmt, insert_str, strlen(insert_str));
18277   check_execute(stmt, rc);
18278 
18279   bind.buffer_type= MYSQL_TYPE_STRING;
18280   bind.buffer_length= BUFSIZE;
18281   bind.buffer= buffer;
18282   bind.is_null= &is_null;
18283   bind.length= &length;
18284   rc= mysql_stmt_bind_param(stmt, &bind);
18285   check_execute(stmt, rc);
18286 
18287   /* First execute; should succeed. */
18288   strncpy(buffer, values[0], BUFSIZE);
18289   length= strlen(buffer);
18290   rc= mysql_stmt_execute(stmt);
18291   check_execute(stmt, rc);
18292 
18293   /*
18294     Set up the server to close this session's server-side socket after
18295     next execution of prep statement.
18296   */
18297   rc= mysql_query(conn,"SET SESSION debug='+d,close_conn_after_stmt_execute'");
18298   myquery(rc);
18299 
18300   /* Second execute; should fail due to socket closed during execution. */
18301   strncpy(buffer, values[1], BUFSIZE);
18302   length= strlen(buffer);
18303   rc= mysql_stmt_execute(stmt);
18304   DIE_UNLESS(rc && mysql_stmt_errno(stmt) == CR_SERVER_LOST);
18305 
18306   /*
18307     Third execute; should fail (connection already closed), or SIGSEGV in
18308     case of a Bug#43560 type regression in which case the whole test fails.
18309   */
18310   strncpy(buffer, values[2], BUFSIZE);
18311   length= strlen(buffer);
18312   rc= mysql_stmt_execute(stmt);
18313   DIE_UNLESS(rc && (mysql_stmt_errno(stmt) == CR_SERVER_LOST ||
18314                     mysql_stmt_errno(stmt) == CR_SERVER_GONE_ERROR));
18315 
18316   opt_drop_db= 0;
18317   client_disconnect(conn);
18318   rc= mysql_query(mysql, "DROP TABLE t1");
18319   myquery(rc);
18320   opt_drop_db= drop_db;
18321 
18322   DBUG_VOID_RETURN;
18323 }
18324 
18325 
18326 /**
18327   Bug#36326: nested transaction and select
18328 */
18329 
test_bug36326()18330 static void test_bug36326()
18331 {
18332   int rc;
18333 
18334   DBUG_ENTER("test_bug36326");
18335   myheader("test_bug36326");
18336 
18337   if (! is_query_cache_available())
18338   {
18339     fprintf(stdout, "Skipping test_bug36326: Query cache not available.\n");
18340     DBUG_VOID_RETURN;
18341   }
18342 
18343   rc= mysql_autocommit(mysql, TRUE);
18344   myquery(rc);
18345   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18346   myquery(rc);
18347   rc= mysql_query(mysql, "CREATE  TABLE t1 (a INTEGER)");
18348   myquery(rc);
18349   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)");
18350   myquery(rc);
18351   rc= mysql_query(mysql,
18352                   "set @save_query_cache_type="
18353                   "@@global.query_cache_type,"
18354                   "@save_query_cache_size="
18355                   "@@global.query_cache_size");
18356   myquery(rc);
18357   rc= mysql_query(mysql, "SET GLOBAL query_cache_type = 1");
18358   myquery(rc);
18359   rc= mysql_query(mysql, "SET LOCAL query_cache_type = 1");
18360   myquery(rc);
18361   rc= mysql_query(mysql, "SET GLOBAL query_cache_size = 1048576");
18362   myquery(rc);
18363   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS));
18364   DIE_UNLESS(mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
18365   rc= mysql_query(mysql, "BEGIN");
18366   myquery(rc);
18367   DIE_UNLESS(mysql->server_status & SERVER_STATUS_IN_TRANS);
18368   rc= mysql_query(mysql, "SELECT * FROM t1");
18369   myquery(rc);
18370   rc= my_process_result(mysql);
18371   DIE_UNLESS(rc == 1);
18372   rc= mysql_rollback(mysql);
18373   myquery(rc);
18374   rc= mysql_query(mysql, "ROLLBACK");
18375   myquery(rc);
18376   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS));
18377   rc= mysql_query(mysql, "SELECT * FROM t1");
18378   myquery(rc);
18379   DIE_UNLESS(!(mysql->server_status & SERVER_STATUS_IN_TRANS));
18380   rc= my_process_result(mysql);
18381   DIE_UNLESS(rc == 1);
18382   rc= mysql_query(mysql, "DROP TABLE t1");
18383   myquery(rc);
18384   rc= mysql_query(mysql, "SET GLOBAL query_cache_size = @save_query_cache_size");
18385   rc= mysql_query(mysql, "SET GLOBAL query_cache_type = @save_query_cache_type");
18386   myquery(rc);
18387 
18388   DBUG_VOID_RETURN;
18389 }
18390 
18391 /**
18392   Bug#41078: With CURSOR_TYPE_READ_ONLY mysql_stmt_fetch() returns short
18393              string value.
18394 */
18395 
test_bug41078(void)18396 static void test_bug41078(void)
18397 {
18398   uint         rc;
18399   MYSQL_STMT   *stmt= 0;
18400   MYSQL_BIND   param, result;
18401   ulong        cursor_type= CURSOR_TYPE_READ_ONLY;
18402   ulong        len;
18403   char         str[64];
18404   const char   param_str[]= "abcdefghijklmn";
18405   my_bool      is_null, error;
18406 
18407   DBUG_ENTER("test_bug41078");
18408 
18409   rc= mysql_query(mysql, "SET NAMES UTF8");
18410   myquery(rc);
18411 
18412   stmt= mysql_simple_prepare(mysql, "SELECT ?");
18413   check_stmt(stmt);
18414   verify_param_count(stmt, 1);
18415 
18416   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, &cursor_type);
18417   check_execute(stmt, rc);
18418 
18419   bzero(&param, sizeof(param));
18420   param.buffer_type= MYSQL_TYPE_STRING;
18421   param.buffer= (void *) param_str;
18422   len= sizeof(param_str) - 1;
18423   param.length= &len;
18424 
18425   rc= mysql_stmt_bind_param(stmt, &param);
18426   check_execute(stmt, rc);
18427 
18428   rc= mysql_stmt_execute(stmt);
18429   check_execute(stmt, rc);
18430 
18431   bzero(&result, sizeof(result));
18432   result.buffer_type= MYSQL_TYPE_STRING;
18433   result.buffer= str;
18434   result.buffer_length= sizeof(str);
18435   result.is_null= &is_null;
18436   result.length= &len;
18437   result.error=  &error;
18438 
18439   rc= mysql_stmt_bind_result(stmt, &result);
18440   check_execute(stmt, rc);
18441 
18442   rc= mysql_stmt_store_result(stmt);
18443   check_execute(stmt, rc);
18444 
18445   rc= mysql_stmt_fetch(stmt);
18446   check_execute(stmt, rc);
18447 
18448   DIE_UNLESS(len == sizeof(param_str) - 1 && !strcmp(str, param_str));
18449 
18450   mysql_stmt_close(stmt);
18451 
18452   DBUG_VOID_RETURN;
18453 }
18454 
18455 /**
18456   Bug#45010: invalid memory reads during parsing some strange statements
18457 */
test_bug45010()18458 static void test_bug45010()
18459 {
18460   int rc;
18461   const char query1[]= "select a.\x80",
18462              query2[]= "describe `table\xef";
18463 
18464   DBUG_ENTER("test_bug45010");
18465   myheader("test_bug45010");
18466 
18467   rc= mysql_query(mysql, "set names utf8");
18468   myquery(rc);
18469 
18470   /* \x80 (-128) could be used as a index of ident_map. */
18471   rc= mysql_real_query(mysql, query1, sizeof(query1) - 1);
18472   DIE_UNLESS(rc);
18473 
18474   /* \xef (-17) could be used to skip 3 bytes past the buffer end. */
18475   rc= mysql_real_query(mysql, query2, sizeof(query2) - 1);
18476   DIE_UNLESS(rc);
18477 
18478   rc= mysql_query(mysql, "set names default");
18479   myquery(rc);
18480 
18481   DBUG_VOID_RETURN;
18482 }
18483 
18484 /**
18485   Bug#44495: Prepared Statement:
18486              CALL p(<x>) - `thd->protocol == &thd->protocol_text' failed
18487 */
18488 
test_bug44495()18489 static void test_bug44495()
18490 {
18491   int rc;
18492   MYSQL con;
18493   MYSQL_STMT *stmt;
18494 
18495   DBUG_ENTER("test_bug44495");
18496   myheader("test_44495");
18497 
18498   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
18499   myquery(rc);
18500 
18501   rc= mysql_query(mysql, "CREATE PROCEDURE p1(IN arg VARCHAR(25))"
18502                          "  BEGIN SET @stmt = CONCAT('SELECT \"', arg, '\"');"
18503                          "  PREPARE ps1 FROM @stmt;"
18504                          "  EXECUTE ps1;"
18505                          "  DROP PREPARE ps1;"
18506                          "END;");
18507   myquery(rc);
18508 
18509   DIE_UNLESS(mysql_client_init(&con));
18510 
18511   DIE_UNLESS(mysql_real_connect(&con, opt_host, opt_user, opt_password,
18512                                 current_db, opt_port, opt_unix_socket,
18513                                 CLIENT_MULTI_RESULTS));
18514 
18515   stmt= mysql_simple_prepare(&con, "CALL p1('abc')");
18516   check_stmt(stmt);
18517 
18518   rc= mysql_stmt_execute(stmt);
18519   check_execute(stmt, rc);
18520 
18521   rc= my_process_stmt_result(stmt);
18522   DIE_UNLESS(rc == 1);
18523 
18524   mysql_stmt_close(stmt);
18525 
18526   mysql_close(&con);
18527 
18528   rc= mysql_query(mysql, "DROP PROCEDURE p1");
18529   myquery(rc);
18530 
18531   DBUG_VOID_RETURN;
18532 }
18533 
test_bug53371()18534 static void test_bug53371()
18535 {
18536   int rc;
18537   MYSQL_RES *result;
18538 
18539   myheader("test_bug53371");
18540 
18541   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18542   myquery(rc);
18543   rc= mysql_query(mysql, "DROP DATABASE IF EXISTS bug53371");
18544   myquery(rc);
18545   rc= mysql_query(mysql, "DROP USER 'testbug'@localhost");
18546 
18547   rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
18548   myquery(rc);
18549   rc= mysql_query(mysql, "CREATE DATABASE bug53371");
18550   myquery(rc);
18551   rc= mysql_query(mysql, "GRANT SELECT ON bug53371.* to 'testbug'@localhost");
18552   myquery(rc);
18553 
18554   rc= mysql_change_user(mysql, "testbug", NULL, "bug53371");
18555   myquery(rc);
18556 
18557   rc= mysql_query(mysql, "SHOW COLUMNS FROM client_test_db.t1");
18558   DIE_UNLESS(rc);
18559   DIE_UNLESS(mysql_errno(mysql) == 1142);
18560 
18561   result= mysql_list_fields(mysql, "../client_test_db/t1", NULL);
18562   DIE_IF(result);
18563 
18564   result= mysql_list_fields(mysql, "#mysql50#/../client_test_db/t1", NULL);
18565   DIE_IF(result);
18566 
18567   rc= mysql_change_user(mysql, opt_user, opt_password, current_db);
18568   myquery(rc);
18569   rc= mysql_query(mysql, "DROP TABLE t1");
18570   myquery(rc);
18571   rc= mysql_query(mysql, "DROP DATABASE bug53371");
18572   myquery(rc);
18573   rc= mysql_query(mysql, "DROP USER 'testbug'@localhost");
18574   myquery(rc);
18575 }
18576 
18577 
18578 
18579 /**
18580   Bug#42373: libmysql can mess a connection at connect
18581 */
test_bug42373()18582 static void test_bug42373()
18583 {
18584   int rc;
18585   MYSQL con;
18586   MYSQL_STMT *stmt;
18587 
18588   DBUG_ENTER("test_bug42373");
18589   myheader("test_42373");
18590 
18591   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
18592   myquery(rc);
18593 
18594   rc= mysql_query(mysql, "CREATE PROCEDURE p1()"
18595                          "  BEGIN"
18596                          "  SELECT 1;"
18597                          "  INSERT INTO t1 VALUES (2);"
18598                          "END;");
18599   myquery(rc);
18600 
18601   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18602   myquery(rc);
18603 
18604   rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
18605   myquery(rc);
18606 
18607   /* Try with a stored procedure. */
18608   DIE_UNLESS(mysql_client_init(&con));
18609 
18610   mysql_options(&con, MYSQL_INIT_COMMAND, "CALL p1()");
18611 
18612   DIE_UNLESS(mysql_real_connect(&con, opt_host, opt_user, opt_password,
18613                                 current_db, opt_port, opt_unix_socket,
18614                                 CLIENT_MULTI_STATEMENTS|CLIENT_MULTI_RESULTS));
18615 
18616   stmt= mysql_simple_prepare(&con, "SELECT a FROM t1");
18617   check_stmt(stmt);
18618 
18619   rc= mysql_stmt_execute(stmt);
18620   check_execute(stmt, rc);
18621 
18622   rc= my_process_stmt_result(stmt);
18623   DIE_UNLESS(rc == 1);
18624 
18625   mysql_stmt_close(stmt);
18626   mysql_close(&con);
18627 
18628   /* Now try with a multi-statement. */
18629   DIE_UNLESS(mysql_client_init(&con));
18630 
18631   mysql_options(&con, MYSQL_INIT_COMMAND,
18632                 "SELECT 3; INSERT INTO t1 VALUES (4)");
18633 
18634   DIE_UNLESS(mysql_real_connect(&con, opt_host, opt_user, opt_password,
18635                                 current_db, opt_port, opt_unix_socket,
18636                                 CLIENT_MULTI_STATEMENTS|CLIENT_MULTI_RESULTS));
18637 
18638   stmt= mysql_simple_prepare(&con, "SELECT a FROM t1");
18639   check_stmt(stmt);
18640 
18641   rc= mysql_stmt_execute(stmt);
18642   check_execute(stmt, rc);
18643 
18644   rc= my_process_stmt_result(stmt);
18645   DIE_UNLESS(rc == 2);
18646 
18647   mysql_stmt_close(stmt);
18648   mysql_close(&con);
18649 
18650   rc= mysql_query(mysql, "DROP TABLE t1");
18651   myquery(rc);
18652 
18653   rc= mysql_query(mysql, "DROP PROCEDURE p1");
18654   myquery(rc);
18655 
18656   DBUG_VOID_RETURN;
18657 }
18658 
18659 
18660 /**
18661   Bug#54041: MySQL 5.0.92 fails when tests from Connector/C suite run
18662 */
18663 
test_bug54041_impl()18664 static void test_bug54041_impl()
18665 {
18666   int rc;
18667   MYSQL_STMT *stmt;
18668   MYSQL_BIND bind;
18669 
18670   DBUG_ENTER("test_bug54041");
18671   myheader("test_bug54041");
18672 
18673   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18674   myquery(rc);
18675 
18676   rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
18677   myquery(rc);
18678 
18679   stmt= mysql_simple_prepare(mysql, "SELECT a FROM t1 WHERE a > ?");
18680   check_stmt(stmt);
18681   verify_param_count(stmt, 1);
18682 
18683   memset(&bind, 0, sizeof(bind));
18684 
18685   /* Any type that does not support long data handling. */
18686   bind.buffer_type= MYSQL_TYPE_LONG;
18687 
18688   rc= mysql_stmt_bind_param(stmt, &bind);
18689   check_execute(stmt, rc);
18690 
18691   /*
18692     Trick the client API into sending a long data packet for
18693     the parameter. Long data is only supported for string and
18694     binary types.
18695   */
18696   stmt->params[0].buffer_type= MYSQL_TYPE_STRING;
18697 
18698   rc= mysql_stmt_send_long_data(stmt, 0, "data", 5);
18699   check_execute(stmt, rc);
18700 
18701   /* Undo API violation. */
18702   stmt->params[0].buffer_type= MYSQL_TYPE_LONG;
18703 
18704   rc= mysql_stmt_execute(stmt);
18705   /* Incorrect arguments. */
18706   check_execute_r(stmt, rc);
18707 
18708   mysql_stmt_close(stmt);
18709 
18710   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
18711   myquery(rc);
18712 
18713   DBUG_VOID_RETURN;
18714 }
18715 
18716 
18717 /**
18718   Bug#54041: MySQL 5.0.92 fails when tests from Connector/C suite run
18719 */
18720 
test_bug54041()18721 static void test_bug54041()
18722 {
18723   enable_query_logs(0);
18724   test_bug54041_impl();
18725   disable_query_logs();
18726   test_bug54041_impl();
18727   restore_query_logs();
18728 }
18729 
18730 
18731 /**
18732   Bug#47485: mysql_store_result returns a result set for a prepared statement
18733 */
test_bug47485()18734 static void test_bug47485()
18735 {
18736   MYSQL_STMT   *stmt;
18737   MYSQL_RES    *res;
18738   MYSQL_BIND    bind[2];
18739   int           rc;
18740   const char*   sql_select = "SELECT 1, 'a'";
18741   int           int_data;
18742   char          str_data[16];
18743   my_bool       is_null[2];
18744   my_bool       error[2];
18745   unsigned long length[2];
18746 
18747   DBUG_ENTER("test_bug47485");
18748   myheader("test_bug47485");
18749 
18750   stmt= mysql_stmt_init(mysql);
18751   check_stmt(stmt);
18752   rc= mysql_stmt_prepare(stmt, sql_select, strlen(sql_select));
18753   check_execute(stmt, rc);
18754 
18755   rc= mysql_stmt_execute(stmt);
18756   check_execute(stmt, rc);
18757 
18758   res = mysql_store_result(mysql);
18759   DIE_UNLESS(res == NULL);
18760 
18761   mysql_stmt_reset(stmt);
18762 
18763   rc= mysql_stmt_execute(stmt);
18764   check_execute(stmt, rc);
18765 
18766   res = mysql_use_result(mysql);
18767   DIE_UNLESS(res == NULL);
18768 
18769   mysql_stmt_reset(stmt);
18770 
18771   memset(bind, 0, sizeof(bind));
18772   bind[0].buffer_type= MYSQL_TYPE_LONG;
18773   bind[0].buffer= (char *)&int_data;
18774   bind[0].is_null= &is_null[0];
18775   bind[0].length= &length[0];
18776   bind[0].error= &error[0];
18777 
18778   bind[1].buffer_type= MYSQL_TYPE_STRING;
18779   bind[1].buffer= (char *)str_data;
18780   bind[1].buffer_length= sizeof(str_data);
18781   bind[1].is_null= &is_null[1];
18782   bind[1].length= &length[1];
18783   bind[1].error= &error[1];
18784 
18785   rc= mysql_stmt_bind_result(stmt, bind);
18786   check_execute(stmt, rc);
18787 
18788   rc= mysql_stmt_execute(stmt);
18789   check_execute(stmt, rc);
18790 
18791   rc= mysql_stmt_store_result(stmt);
18792   check_execute(stmt, rc);
18793 
18794   while (!(rc= mysql_stmt_fetch(stmt)))
18795     ;
18796 
18797   DIE_UNLESS(rc == MYSQL_NO_DATA);
18798 
18799   mysql_stmt_reset(stmt);
18800 
18801   memset(bind, 0, sizeof(bind));
18802   bind[0].buffer_type= MYSQL_TYPE_LONG;
18803   bind[0].buffer= (char *)&int_data;
18804   bind[0].is_null= &is_null[0];
18805   bind[0].length= &length[0];
18806   bind[0].error= &error[0];
18807 
18808   bind[1].buffer_type= MYSQL_TYPE_STRING;
18809   bind[1].buffer= (char *)str_data;
18810   bind[1].buffer_length= sizeof(str_data);
18811   bind[1].is_null= &is_null[1];
18812   bind[1].length= &length[1];
18813   bind[1].error= &error[1];
18814 
18815   rc= mysql_stmt_bind_result(stmt, bind);
18816   check_execute(stmt, rc);
18817 
18818   rc= mysql_stmt_execute(stmt);
18819   check_execute(stmt, rc);
18820 
18821   while (!(rc= mysql_stmt_fetch(stmt)))
18822     ;
18823 
18824   DIE_UNLESS(rc == MYSQL_NO_DATA);
18825 
18826   mysql_stmt_close(stmt);
18827 
18828   DBUG_VOID_RETURN;
18829 }
18830 
18831 
18832 /*
18833   Bug#58036 client utf32, utf16, ucs2 should be disallowed, they crash server
18834 */
test_bug58036()18835 static void test_bug58036()
18836 {
18837   MYSQL *conn;
18838   DBUG_ENTER("test_bug58036");
18839   myheader("test_bug58036");
18840 
18841   /* Part1: try to connect with ucs2 client character set */
18842   conn= mysql_client_init(NULL);
18843   mysql_options(conn, MYSQL_SET_CHARSET_NAME, "ucs2");
18844 
18845   if (mysql_real_connect(conn, opt_host, opt_user,
18846                          opt_password,  opt_db ? opt_db : "test",
18847                          opt_port, opt_unix_socket, 0))
18848   {
18849     if (!opt_silent)
18850       printf("mysql_real_connect() succeeded (failure expected)\n");
18851     mysql_close(conn);
18852     DIE("");
18853   }
18854 
18855   if (!opt_silent)
18856     printf("Got mysql_real_connect() error (expected): %s (%d)\n",
18857            mysql_error(conn), mysql_errno(conn));
18858   DIE_UNLESS(mysql_errno(conn) == ER_WRONG_VALUE_FOR_VAR ||
18859              mysql_errno(conn)== CR_CANT_READ_CHARSET);
18860   mysql_close(conn);
18861 
18862 
18863   /*
18864     Part2:
18865     - connect with latin1
18866     - then change client character set to ucs2
18867     - then try mysql_change_user()
18868   */
18869   conn= mysql_client_init(NULL);
18870   mysql_options(conn, MYSQL_SET_CHARSET_NAME, "latin1");
18871   if (!mysql_real_connect(conn, opt_host, opt_user,
18872                          opt_password, opt_db ? opt_db : "test",
18873                          opt_port, opt_unix_socket, 0))
18874   {
18875     if (!opt_silent)
18876       printf("mysql_real_connect() failed: %s (%d)\n",
18877              mysql_error(conn), mysql_errno(conn));
18878     mysql_close(conn);
18879     DIE("");
18880   }
18881 
18882   mysql_options(conn, MYSQL_SET_CHARSET_NAME, "ucs2");
18883   if (!mysql_change_user(conn, opt_user, opt_password, NULL))
18884   {
18885     if (!opt_silent)
18886       printf("mysql_change_user() succedded, error expected!");
18887     mysql_close(conn);
18888     DIE("");
18889   }
18890 
18891   if (!opt_silent)
18892     printf("Got mysql_change_user() error (expected): %s (%d)\n",
18893            mysql_error(conn), mysql_errno(conn));
18894   mysql_close(conn);
18895   DBUG_VOID_RETURN;
18896 }
18897 
18898 
18899 /*
18900   Bug#49972: Crash in prepared statements.
18901 
18902   The following case lead to a server crash:
18903     - Use binary protocol;
18904     - Prepare a statement with OUT-parameter;
18905     - Execute the statement;
18906     - Cause re-prepare of the statement (change dependencies);
18907     - Execute the statement again -- crash here.
18908 */
18909 
test_bug49972()18910 static void test_bug49972()
18911 {
18912   int rc;
18913   MYSQL_STMT *stmt;
18914 
18915   MYSQL_BIND in_param_bind;
18916   MYSQL_BIND out_param_bind;
18917   int int_data;
18918   my_bool is_null;
18919 
18920   DBUG_ENTER("test_bug49972");
18921   myheader("test_bug49972");
18922 
18923   rc= mysql_query(mysql, "DROP FUNCTION IF EXISTS f1");
18924   myquery(rc);
18925 
18926   rc= mysql_query(mysql, "DROP PROCEDURE IF EXISTS p1");
18927   myquery(rc);
18928 
18929   rc= mysql_query(mysql, "CREATE FUNCTION f1() RETURNS INT RETURN 1");
18930   myquery(rc);
18931 
18932   rc= mysql_query(mysql, "CREATE PROCEDURE p1(IN a INT, OUT b INT) SET b = a");
18933   myquery(rc);
18934 
18935   stmt= mysql_simple_prepare(mysql, "CALL p1((SELECT f1()), ?)");
18936   check_stmt(stmt);
18937 
18938   bzero((char *) &in_param_bind, sizeof (in_param_bind));
18939 
18940   in_param_bind.buffer_type= MYSQL_TYPE_LONG;
18941   in_param_bind.buffer= (char *) &int_data;
18942   in_param_bind.length= 0;
18943   in_param_bind.is_null= 0;
18944 
18945   rc= mysql_stmt_bind_param(stmt, &in_param_bind);
18946 
18947   rc= mysql_stmt_execute(stmt);
18948   check_execute(stmt, rc);
18949 
18950   {
18951     bzero(&out_param_bind, sizeof (out_param_bind));
18952 
18953     out_param_bind.buffer_type= MYSQL_TYPE_LONG;
18954     out_param_bind.is_null= &is_null;
18955     out_param_bind.buffer= &int_data;
18956     out_param_bind.buffer_length= sizeof (int_data);
18957 
18958     rc= mysql_stmt_bind_result(stmt, &out_param_bind);
18959     check_execute(stmt, rc);
18960 
18961     rc= mysql_stmt_fetch(stmt);
18962     rc= mysql_stmt_fetch(stmt);
18963     DBUG_ASSERT(rc == MYSQL_NO_DATA);
18964 
18965     mysql_stmt_next_result(stmt);
18966     mysql_stmt_fetch(stmt);
18967   }
18968 
18969   rc= mysql_query(mysql, "DROP FUNCTION f1");
18970   myquery(rc);
18971 
18972   rc= mysql_query(mysql, "CREATE FUNCTION f1() RETURNS INT RETURN 1");
18973   myquery(rc);
18974 
18975   rc= mysql_stmt_execute(stmt);
18976   check_execute(stmt, rc);
18977 
18978   {
18979     bzero(&out_param_bind, sizeof (out_param_bind));
18980 
18981     out_param_bind.buffer_type= MYSQL_TYPE_LONG;
18982     out_param_bind.is_null= &is_null;
18983     out_param_bind.buffer= &int_data;
18984     out_param_bind.buffer_length= sizeof (int_data);
18985 
18986     rc= mysql_stmt_bind_result(stmt, &out_param_bind);
18987     check_execute(stmt, rc);
18988 
18989     rc= mysql_stmt_fetch(stmt);
18990     rc= mysql_stmt_fetch(stmt);
18991     DBUG_ASSERT(rc == MYSQL_NO_DATA);
18992 
18993     mysql_stmt_next_result(stmt);
18994     mysql_stmt_fetch(stmt);
18995   }
18996 
18997   mysql_stmt_close(stmt);
18998 
18999   rc= mysql_query(mysql, "DROP PROCEDURE p1");
19000   myquery(rc);
19001 
19002   rc= mysql_query(mysql, "DROP FUNCTION f1");
19003   myquery(rc);
19004 
19005   DBUG_VOID_RETURN;
19006 }
19007 
19008 
19009 /*
19010   Bug #56976:   Severe Denial Of Service in prepared statements
19011 */
test_bug56976()19012 static void test_bug56976()
19013 {
19014   MYSQL_STMT   *stmt;
19015   MYSQL_BIND    bind[1];
19016   int           rc;
19017   const char*   query = "SELECT LENGTH(?)";
19018   char *long_buffer;
19019   unsigned long i, packet_len = 256 * 1024L;
19020   unsigned long dos_len    = 35000000;
19021 
19022   DBUG_ENTER("test_bug56976");
19023   myheader("test_bug56976");
19024 
19025   stmt= mysql_stmt_init(mysql);
19026   check_stmt(stmt);
19027 
19028   rc= mysql_stmt_prepare(stmt, query, strlen(query));
19029   check_execute(stmt, rc);
19030 
19031   memset(bind, 0, sizeof(bind));
19032   bind[0].buffer_type = MYSQL_TYPE_TINY_BLOB;
19033 
19034   rc= mysql_stmt_bind_param(stmt, bind);
19035   check_execute(stmt, rc);
19036 
19037   long_buffer= (char*) my_malloc(packet_len, MYF(0));
19038   DIE_UNLESS(long_buffer);
19039 
19040   memset(long_buffer, 'a', packet_len);
19041 
19042   for (i= 0; i < dos_len / packet_len; i++)
19043   {
19044     rc= mysql_stmt_send_long_data(stmt, 0, long_buffer, packet_len);
19045     check_execute(stmt, rc);
19046   }
19047 
19048   my_free(long_buffer);
19049   rc= mysql_stmt_execute(stmt);
19050 
19051   DIE_UNLESS(rc && mysql_stmt_errno(stmt) == ER_UNKNOWN_ERROR);
19052 
19053   mysql_stmt_close(stmt);
19054 
19055   DBUG_VOID_RETURN;
19056 }
19057 
19058 /*
19059   Test that CLIENT_PROGRESS works.
19060 */
19061 
19062 uint progress_stage, progress_max_stage, progress_count;
19063 
report_progress(const MYSQL * mysql,uint stage,uint max_stage,double progress,const char * proc_info,uint proc_info_length)19064 static void report_progress(const MYSQL *mysql __attribute__((unused)),
19065                             uint stage, uint max_stage,
19066                             double progress __attribute__((unused)),
19067                             const char *proc_info __attribute__((unused)),
19068                             uint proc_info_length __attribute__((unused)))
19069 {
19070   progress_stage= stage;
19071   progress_max_stage= max_stage;
19072   progress_count++;
19073 }
19074 
19075 
test_progress_reporting()19076 static void test_progress_reporting()
19077 {
19078   int rc, i;
19079   MYSQL*       conn;
19080 
19081   /* Progress reporting doesn't work yet with embedded server */
19082   if (embedded_server_arg_count)
19083     return;
19084 
19085   myheader("test_progress_reporting");
19086 
19087 
19088   conn= client_connect(CLIENT_PROGRESS_OBSOLETE, MYSQL_PROTOCOL_TCP, 0);
19089   DIE_UNLESS(conn->client_flag & CLIENT_PROGRESS_OBSOLETE);
19090 
19091   mysql_options(conn, MYSQL_PROGRESS_CALLBACK, (void*) report_progress);
19092   rc= mysql_query(conn, "set @save=@@global.progress_report_time");
19093   myquery(rc);
19094   rc= mysql_query(conn, "set @@global.progress_report_time=1");
19095   myquery(rc);
19096 
19097   rc= mysql_query(conn, "drop table if exists t1,t2");
19098   myquery(rc);
19099   rc= mysql_query(conn, "create table t1 (f2 varchar(255)) engine=aria");
19100   myquery(rc);
19101   rc= mysql_query(conn, "create table t2 like t1");
19102   myquery(rc);
19103   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))");
19104   myquery(rc);
19105   for (i= 0 ; i < 5 ; i++)
19106   {
19107     rc= mysql_query(conn, "insert into t2 (f2) select f2 from t1");
19108     myquery(rc);
19109     rc= mysql_query(conn, "insert into t1 (f2) select f2 from t2");
19110     myquery(rc);
19111   }
19112 
19113   progress_stage= progress_max_stage= progress_count= 0;
19114   rc= mysql_query(conn, "alter table t1 add f1 int primary key auto_increment, order by f2");
19115   myquery(rc);
19116   if (!opt_silent)
19117     printf("Got progress_count: %u  stage: %u  max_stage: %u\n",
19118            progress_count, progress_stage, progress_max_stage);
19119   DIE_UNLESS(progress_count > 0 && progress_stage >=2 && progress_max_stage == 3);
19120 
19121   progress_stage= progress_max_stage= progress_count= 0;
19122   rc= mysql_query(conn, "create index f2 on t1 (f2)");
19123   myquery(rc);
19124   if (!opt_silent)
19125     printf("Got progress_count: %u  stage: %u  max_stage: %u\n",
19126            progress_count, progress_stage, progress_max_stage);
19127   DIE_UNLESS(progress_count > 0 && progress_stage >=2 && progress_max_stage == 2);
19128 
19129   progress_stage= progress_max_stage= progress_count= 0;
19130   rc= mysql_query(conn, "drop index f2 on t1");
19131   myquery(rc);
19132   if (!opt_silent)
19133     printf("Got progress_count: %u  stage: %u  max_stage: %u\n",
19134            progress_count, progress_stage, progress_max_stage);
19135   DIE_UNLESS(progress_count > 0 && progress_stage >=2 && progress_max_stage == 2);
19136 
19137   rc= mysql_query(conn, "set @@global.progress_report_time=@save");
19138   myquery(rc);
19139   mysql_close(conn);
19140 }
19141 
19142 /**
19143   MDEV-3885 - connection suicide via mysql_kill() causes assertion in server
19144 */
19145 
test_mdev3885()19146 static void test_mdev3885()
19147 {
19148   int rc;
19149   MYSQL *conn;
19150 
19151   myheader("test_mdev3885");
19152   conn= client_connect(0, MYSQL_PROTOCOL_TCP, 0);
19153   rc= mysql_kill(conn, mysql_thread_id(conn));
19154   DIE_UNLESS(rc);
19155   mysql_close(conn);
19156 }
19157 
19158 
19159 /**
19160   Bug#57058 SERVER_QUERY_WAS_SLOW not wired up.
19161 */
19162 
test_bug57058()19163 static void test_bug57058()
19164 {
19165   MYSQL_RES *res;
19166   int rc;
19167 
19168   DBUG_ENTER("test_bug57058");
19169   myheader("test_bug57058");
19170 
19171   rc= mysql_query(mysql, "set @@session.long_query_time=0.1");
19172   myquery(rc);
19173 
19174   DIE_UNLESS(!(mysql->server_status & SERVER_QUERY_WAS_SLOW));
19175 
19176   rc= mysql_query(mysql, "select sleep(1)");
19177   myquery(rc);
19178 
19179   /*
19180     Important: the flag is sent in the last EOF packet of
19181     the query, the one which ends the result. Read the
19182     result to see the "slow" status.
19183   */
19184   res= mysql_store_result(mysql);
19185 
19186   DIE_UNLESS(mysql->server_status & SERVER_QUERY_WAS_SLOW);
19187 
19188   mysql_free_result(res);
19189 
19190   rc= mysql_query(mysql, "set @@session.long_query_time=default");
19191   myquery(rc);
19192 
19193   DBUG_VOID_RETURN;
19194 }
19195 
19196 
19197 /**
19198   Bug#11766854: 60075: MYSQL_LOAD_CLIENT_PLUGIN DOESN'T CLEAR ERROR
19199 */
19200 
test_bug11766854()19201 static void test_bug11766854()
19202 {
19203   struct st_mysql_client_plugin *plugin;
19204 
19205   DBUG_ENTER("test_bug11766854");
19206   myheader("test_bug11766854");
19207 
19208   plugin= mysql_load_plugin(mysql, "foo", -1, 0);
19209   DIE_UNLESS(plugin == 0);
19210 
19211   plugin= mysql_load_plugin(mysql, "qa_auth_client", -1, 0);
19212   DIE_UNLESS(plugin != 0);
19213   DIE_IF(mysql_errno(mysql));
19214 
19215   DBUG_VOID_RETURN;
19216 }
19217 
19218 /**
19219   Bug#12337762: 60075: MYSQL_LIST_FIELDS() RETURNS WRONG CHARSET FOR
19220                        CHAR/VARCHAR/TEXT COLUMNS IN VIEWS
19221 */
test_bug12337762()19222 static void test_bug12337762()
19223 {
19224   int rc,i=0;
19225   MYSQL_RES *result;
19226   MYSQL_FIELD *field;
19227   unsigned int tab_charsetnr[3]= {0};
19228 
19229   DBUG_ENTER("test_bug12337762");
19230   myheader("test_bug12337762");
19231 
19232   /*
19233     Creating table with specific charset.
19234   */
19235   rc= mysql_query(mysql, "drop table if exists charset_tab");
19236   rc= mysql_query(mysql, "create table charset_tab("\
19237                          "txt1 varchar(32) character set Latin1,"\
19238                          "txt2 varchar(32) character set Latin1 collate latin1_bin,"\
19239                          "txt3 varchar(32) character set utf8 collate utf8_bin"\
19240 						 ")");
19241 
19242   DIE_UNLESS(rc == 0);
19243   DIE_IF(mysql_errno(mysql));
19244 
19245   /*
19246     Creating view from table created earlier.
19247   */
19248   rc= mysql_query(mysql, "drop view if exists charset_view");
19249   rc= mysql_query(mysql, "create view charset_view as "\
19250                          "select * from charset_tab;");
19251   DIE_UNLESS(rc == 0);
19252   DIE_IF(mysql_errno(mysql));
19253 
19254   /*
19255     Checking field information for table.
19256   */
19257   result= mysql_list_fields(mysql, "charset_tab", NULL);
19258   DIE_IF(mysql_errno(mysql));
19259   i=0;
19260   while((field= mysql_fetch_field(result)))
19261   {
19262     printf("field name %s\n", field->name);
19263     printf("field table %s\n", field->table);
19264     printf("field type %d\n", field->type);
19265     printf("field charset %d\n", field->charsetnr);
19266     tab_charsetnr[i++]= field->charsetnr;
19267     printf("\n");
19268   }
19269   mysql_free_result(result);
19270 
19271   /*
19272     Checking field information for view.
19273   */
19274   result= mysql_list_fields(mysql, "charset_view", NULL);
19275   DIE_IF(mysql_errno(mysql));
19276   i=0;
19277   while((field= mysql_fetch_field(result)))
19278   {
19279     printf("field name %s\n", field->name);
19280     printf("field table %s\n", field->table);
19281     printf("field type %d\n", field->type);
19282     printf("field charset %d\n", field->charsetnr);
19283     printf("\n");
19284     /*
19285       charset value for field must be same for both, view and table.
19286     */
19287     DIE_UNLESS(field->charsetnr == tab_charsetnr[i++]);
19288   }
19289   mysql_free_result(result);
19290 
19291   DBUG_VOID_RETURN;
19292 }
19293 
19294 /*
19295    MDEV-4603: mysql_stmt_reset doesn't clear
19296               all result sets (from stored procedures).
19297    This test requires also fix for MDEV-4604
19298 */
test_mdev4603()19299 static void test_mdev4603()
19300 {
19301   MYSQL *my;
19302   MYSQL_STMT *stmt;
19303   int i, rc;
19304   int a[] = {10,20,30};
19305   MYSQL_BIND bind[3];
19306 
19307   myheader("test_mdev4603");
19308   my= mysql_client_init(NULL);
19309 
19310   if (!mysql_real_connect(my, opt_host, opt_user,
19311                                opt_password, current_db, opt_port,
19312                                opt_unix_socket, CLIENT_MULTI_RESULTS))
19313     DIE("mysql_real_connect failed");
19314 
19315   /* 1st test:
19316      use a procedure with out param
19317   */
19318   rc= mysql_query(my, "DROP PROCEDURE IF EXISTS p1");
19319   myquery(rc);
19320 
19321   rc= mysql_query(mysql, "CREATE PROCEDURE p1(OUT p_out VARCHAR(19), IN p_in INT, INOUT p_inout INT)"
19322                          "BEGIN "
19323                           "  SET p_in = 300, p_out := 'This is OUT param', p_inout = 200; "
19324                           "  SELECT p_inout, p_in, substring(p_out, 9);"
19325                          "END");
19326   myquery(rc);
19327 
19328   stmt= mysql_stmt_init(mysql);
19329   DIE_UNLESS(stmt != NULL);
19330 
19331   rc= mysql_stmt_prepare(stmt, "CALL P1(?,?,?)", 14);
19332   DIE_UNLESS(rc == 0);
19333 
19334   DIE_UNLESS(mysql_stmt_param_count(stmt) == 3);
19335 
19336   memset(bind, 0, sizeof(MYSQL_BIND) * 3);
19337   for (i=0; i < 3; i++)
19338   {
19339     bind[i].buffer= &a[i];
19340     bind[i].buffer_type= MYSQL_TYPE_LONG;
19341   }
19342   bind[0].buffer_type= MYSQL_TYPE_NULL;
19343   rc= mysql_stmt_bind_param(stmt, bind);
19344   DIE_UNLESS(rc == 0);
19345 
19346   rc= mysql_stmt_execute(stmt);
19347   DIE_UNLESS(rc == 0);
19348 
19349   rc= mysql_stmt_fetch(stmt);
19350   DIE_UNLESS(rc == 0);
19351 
19352   rc= mysql_stmt_reset(stmt);
19353   DIE_UNLESS(rc == 0);
19354 
19355   /*connection shouldn't be blocked now */
19356 
19357   rc= mysql_query(mysql, "DROP PROCEDURE p1");
19358   myquery(rc);
19359 
19360   /* 2nd test:
19361      reset all result sets */
19362   rc= mysql_query(my, "CREATE PROCEDURE p1() "
19363                       "BEGIN"
19364                       "  SELECT 1,2,3 FROM DUAL;"
19365                       "  SELECT 'foo' FROM DUAL;"
19366                       "END");
19367   myquery(rc);
19368 
19369   rc= mysql_stmt_prepare(stmt, "CALL P1()", 9);
19370   DIE_UNLESS(rc == 0);
19371 
19372   rc= mysql_stmt_execute(stmt);
19373   DIE_UNLESS(rc == 0);
19374 
19375   rc= mysql_stmt_reset(stmt);
19376   DIE_UNLESS(rc == 0);
19377 
19378   /* 3rd test:
19379      mysql_stmt_close should also flush all pending
19380      result sets
19381   */
19382 
19383   rc= mysql_stmt_prepare(stmt, "CALL P1()", 9);
19384   DIE_UNLESS(rc == 0);
19385 
19386   rc= mysql_stmt_execute(stmt);
19387   DIE_UNLESS(rc == 0);
19388 
19389   rc= mysql_stmt_close(stmt);
19390   DIE_UNLESS(rc == 0);
19391 
19392   rc= mysql_query(my, "DROP PROCEDURE p1");
19393   myquery(rc);
19394 
19395   mysql_close(my);
19396 }
19397 
19398 /*
19399   BUG 11754979 - 46675: ON DUPLICATE KEY UPDATE AND UPDATECOUNT() POSSIBLY WRONG
19400 */
19401 
test_bug11754979()19402 static void test_bug11754979()
19403 {
19404   MYSQL* conn;
19405   DBUG_ENTER("test_bug11754979");
19406 
19407   myheader("test_bug11754979");
19408   DIE_UNLESS((conn= mysql_client_init(NULL)));
19409   DIE_UNLESS(mysql_real_connect(conn, opt_host, opt_user,
19410              opt_password, opt_db ? opt_db:"test", opt_port,
19411              opt_unix_socket,  CLIENT_FOUND_ROWS));
19412   myquery(mysql_query(conn, "DROP TABLE IF EXISTS t1"));
19413   myquery(mysql_query(conn, "CREATE TABLE t1(id INT, label CHAR(1), PRIMARY KEY(id))"));
19414   myquery(mysql_query(conn, "INSERT INTO t1(id, label) VALUES (1, 'a')"));
19415   myquery(mysql_query(conn, "INSERT INTO t1(id, label) VALUES (1, 'a') "
19416                             "ON DUPLICATE KEY UPDATE id = 4"));
19417   DIE_UNLESS(mysql_affected_rows(conn) == 2);
19418   myquery(mysql_query(conn, "DROP TABLE t1"));
19419   mysql_close(conn);
19420 
19421   DBUG_VOID_RETURN;
19422 }
19423 
test_ps_sp_out_params()19424 static void test_ps_sp_out_params()
19425 {
19426   MYSQL *my;
19427   MYSQL_STMT *stmt;
19428   MYSQL_BIND bind[1];
19429   char buffer[20];
19430   int status, rc;
19431 
19432   myheader("test_ps_sp_out_params");
19433   my= mysql_client_init(NULL);
19434 
19435   if (!mysql_real_connect(my, opt_host, opt_user,
19436                                opt_password, current_db, opt_port,
19437                                opt_unix_socket, CLIENT_MULTI_RESULTS))
19438     DIE("mysql_real_connect failed");
19439 
19440   rc= mysql_query(my, "DROP PROCEDURE IF EXISTS p1");
19441   myquery(rc);
19442 
19443   rc= mysql_query(my,
19444     "CREATE PROCEDURE p1(OUT out_param VARCHAR(19)) "
19445     "BEGIN"
19446     " SELECT 'foo' FROM DUAL;"
19447     " SET out_param='foo';"
19448     " SELECT 'foo' FROM DUAL;"
19449     "END");
19450   myquery(rc);
19451 
19452   stmt= mysql_stmt_init(my);
19453 
19454   rc= mysql_stmt_prepare(stmt, "CALL P1(?)", 10);
19455   DIE_UNLESS(rc==0);
19456 
19457   DIE_UNLESS(mysql_stmt_param_count(stmt) == 1);
19458 
19459   memset(bind, 0, sizeof(MYSQL_BIND));
19460   bind[0].buffer= buffer;
19461   bind[0].buffer_length= sizeof(buffer);
19462   bind[0].buffer_type= MYSQL_TYPE_STRING;
19463 
19464   mysql_stmt_bind_param(stmt, bind);
19465 
19466   rc= mysql_stmt_execute(stmt);
19467   check_execute(stmt, rc);
19468 
19469   do {
19470     if (mysql_stmt_field_count(stmt))
19471     {
19472       /* since server sends a status packet at the end,
19473          there must follow at least one additional packet */
19474       DIE_UNLESS(mysql_more_results(stmt->mysql));
19475 
19476       mysql_stmt_bind_result(stmt, bind);
19477 
19478       rc= mysql_stmt_fetch(stmt);
19479       DIE_UNLESS(rc== 0);
19480 
19481       DIE_UNLESS(strcmp(buffer, "foo") == 0);
19482     }
19483     status= mysql_stmt_next_result(stmt);
19484   } while (status == 0);
19485 
19486   rc= mysql_stmt_reset(stmt);
19487   DIE_UNLESS(rc== 0);
19488 
19489   mysql_stmt_close(stmt);
19490   mysql_close(my);
19491 
19492   printf("end\n");
19493 }
19494 
19495 /*
19496   Bug#13001491: MYSQL_REFRESH CRASHES WHEN STORED ROUTINES ARE RUN CONCURRENTLY.
19497 */
test_bug13001491()19498 static void test_bug13001491()
19499 {
19500   int rc;
19501   char query[MAX_TEST_QUERY_LENGTH];
19502   MYSQL *c;
19503 
19504   myheader("test_bug13001491");
19505 
19506   my_snprintf(query, MAX_TEST_QUERY_LENGTH,
19507            "GRANT ALL PRIVILEGES ON *.* TO mysqltest_u1@%s",
19508            opt_host ? opt_host : "'localhost'");
19509 
19510   rc= mysql_query(mysql, query);
19511   myquery(rc);
19512 
19513   my_snprintf(query, MAX_TEST_QUERY_LENGTH,
19514            "GRANT RELOAD ON *.* TO mysqltest_u1@%s",
19515            opt_host ? opt_host : "'localhost'");
19516 
19517   rc= mysql_query(mysql, query);
19518   myquery(rc);
19519 
19520   c= mysql_client_init(NULL);
19521 
19522   DIE_UNLESS(mysql_real_connect(c, opt_host, "mysqltest_u1", NULL,
19523                                 current_db, opt_port, opt_unix_socket,
19524                                 CLIENT_MULTI_STATEMENTS |
19525                                 CLIENT_MULTI_RESULTS));
19526 
19527   rc= mysql_query(c, "DROP PROCEDURE IF EXISTS p1");
19528   myquery(rc);
19529 
19530   rc= mysql_query(c,
19531     "CREATE PROCEDURE p1() "
19532     "BEGIN "
19533     " DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; "
19534     " SELECT COUNT(*) "
19535     " FROM INFORMATION_SCHEMA.PROCESSLIST "
19536     " GROUP BY user "
19537     " ORDER BY NULL "
19538     " INTO @a; "
19539     "END");
19540   myquery(rc);
19541 
19542   rc= mysql_query(c, "CALL p1()");
19543   myquery(rc);
19544 
19545   mysql_free_result(mysql_store_result(c));
19546 
19547   /* Check that mysql_refresh() succeeds without REFRESH_LOG. */
19548   rc= mysql_refresh(c, REFRESH_GRANT |
19549                        REFRESH_TABLES | REFRESH_HOSTS |
19550                        REFRESH_STATUS | REFRESH_THREADS);
19551   myquery(rc);
19552 
19553   /*
19554     Check that mysql_refresh(REFRESH_LOG) does not crash the server even if it
19555     fails. mysql_refresh(REFRESH_LOG) fails when error log points to unavailable
19556     location.
19557   */
19558   mysql_refresh(c, REFRESH_LOG);
19559 
19560   rc= mysql_query(c, "DROP PROCEDURE p1");
19561   myquery(rc);
19562 
19563   mysql_close(c);
19564   c= NULL;
19565 
19566   my_snprintf(query, MAX_TEST_QUERY_LENGTH,
19567            "DROP USER mysqltest_u1@%s",
19568            opt_host ? opt_host : "'localhost'");
19569 
19570   rc= mysql_query(mysql, query);
19571   myquery(rc);
19572 }
19573 
test_mdev4326()19574 static void test_mdev4326()
19575 {
19576   MYSQL_STMT   *stmt;
19577   MYSQL_BIND    bind;
19578   char query[]= "SELECT * FROM mysql.user LIMIT ?";
19579   char str_data[]= "1";
19580   unsigned long length= 0;
19581   int int_data= 1;
19582   int rc, count;
19583   my_bool is_null= 0;
19584   my_bool error= 0;
19585   myheader("test_mdev4326");
19586 
19587   rc= mysql_change_user(mysql, opt_user, opt_password, "mysql");
19588   myquery(rc);
19589 
19590   rc= mysql_query(mysql, "SET GLOBAL general_log = 1");
19591   myquery(rc);
19592 
19593   stmt= mysql_stmt_init(mysql);
19594   check_stmt(stmt);
19595 
19596   /* Numeric parameter test */
19597 
19598   rc= mysql_stmt_prepare(stmt, query, strlen(query));
19599   check_execute(stmt, rc);
19600   check_stmt(stmt);
19601   verify_param_count(stmt, 1);
19602 
19603   memset((char *)&bind, 0, sizeof(bind));
19604   bind.buffer_type= MYSQL_TYPE_LONG;
19605   bind.buffer= (char *)&int_data;
19606   bind.is_null= &is_null;
19607   bind.length= &length;
19608   bind.error= &error;
19609 
19610   rc= mysql_stmt_bind_param(stmt, &bind);
19611   check_execute(stmt, rc);
19612   rc= mysql_stmt_execute(stmt);
19613   check_execute(stmt, rc);
19614   count= 0;
19615   while (!(rc= mysql_stmt_fetch(stmt)))
19616     count++;
19617   DIE_UNLESS(count == 1);
19618   rc= mysql_stmt_execute(stmt);
19619   check_execute(stmt, rc);
19620   count= 0;
19621   while (!(rc= mysql_stmt_fetch(stmt)))
19622     count++;
19623   DIE_UNLESS(count == 1);
19624   int_data= 0;
19625   rc= mysql_stmt_execute(stmt);
19626   check_execute(stmt, rc);
19627   count= 0;
19628   while (!(rc= mysql_stmt_fetch(stmt)))
19629     count++;
19630   DIE_UNLESS(count == 0);
19631   rc= mysql_stmt_close(stmt);
19632   check_execute(stmt, rc);
19633 
19634   /* String parameter test */
19635 
19636   stmt= mysql_stmt_init(mysql);
19637   rc= mysql_stmt_prepare(stmt, query, strlen(query));
19638   check_execute(stmt, rc);
19639   check_stmt(stmt);
19640   verify_param_count(stmt, 1);
19641 
19642   memset((char *)&bind, 0, sizeof(bind));
19643   bind.buffer_type= MYSQL_TYPE_STRING;
19644   bind.buffer= (char *)str_data;
19645   length= bind.buffer_length= sizeof(str_data);
19646   bind.is_null= &is_null;
19647   bind.length= &length;
19648   bind.error= &error;
19649 
19650   rc= mysql_stmt_bind_param(stmt, &bind);
19651   check_execute(stmt, rc);
19652   rc= mysql_stmt_execute(stmt);
19653   check_execute(stmt, rc);
19654   count= 0;
19655   while (!(rc= mysql_stmt_fetch(stmt)))
19656     count++;
19657   DIE_UNLESS(count == 1);
19658   rc= mysql_stmt_execute(stmt);
19659   check_execute(stmt, rc);
19660   count= 0;
19661   while (!(rc= mysql_stmt_fetch(stmt)))
19662     count++;
19663   DIE_UNLESS(count == 1);
19664   str_data[0]= '0';
19665   rc= mysql_stmt_execute(stmt);
19666   check_execute(stmt, rc);
19667   count= 0;
19668   while (!(rc= mysql_stmt_fetch(stmt)))
19669     count++;
19670   DIE_UNLESS(count == 0);
19671   rc= mysql_stmt_close(stmt);
19672   check_execute(stmt, rc);
19673 
19674   rc= mysql_change_user(mysql, opt_user, opt_password, current_db);
19675   myquery(rc);
19676 }
19677 
19678 /* Test uses MYSQL_PROTOCOL_SOCKET, not on Windows */
19679 
19680 #ifndef _WIN32
19681 /**
19682    BUG#17512527: LIST HANDLING INCORRECT IN MYSQL_PRUNE_STMT_LIST()
19683 */
test_bug17512527()19684 static void test_bug17512527()
19685 {
19686   MYSQL *conn;
19687   MYSQL_STMT *stmt1, *stmt2;
19688   unsigned long thread_id;
19689   char query[MAX_TEST_QUERY_LENGTH];
19690   int rc;
19691 
19692   conn= client_connect(0, MYSQL_PROTOCOL_SOCKET, 1);
19693 
19694   stmt1 = mysql_stmt_init(conn);
19695   check_stmt(stmt1);
19696   rc= mysql_stmt_prepare(stmt1, STRING_WITH_LEN("SELECT 1"));
19697   check_execute(stmt1, rc);
19698 
19699   stmt2 = mysql_stmt_init(conn);
19700   check_stmt(stmt2);
19701 
19702   thread_id= mysql_thread_id(conn);
19703   sprintf(query, "KILL %lu", thread_id);
19704   if (thread_query(query))
19705     exit(1);
19706 
19707   rc= mysql_stmt_prepare(stmt2, STRING_WITH_LEN("SELECT 2"));
19708   check_execute(stmt2, rc);
19709 
19710   rc= mysql_stmt_execute(stmt1);
19711   check_execute_r(stmt1, rc);
19712 
19713   rc= mysql_stmt_execute(stmt2);
19714   check_execute(stmt2, rc);
19715 
19716   mysql_close(conn);
19717 
19718   mysql_stmt_close(stmt2);
19719   mysql_stmt_close(stmt1);
19720 }
19721 #endif
19722 
19723 
19724 /*
19725   Check compressed protocol
19726 */
19727 
test_compressed_protocol()19728 static void test_compressed_protocol()
19729 {
19730   MYSQL *mysql_local;
19731   char query[4096], *end;
19732   int i;
19733   myheader("test_compressed_protocol");
19734 
19735   if (!(mysql_local= mysql_client_init(NULL)))
19736   {
19737     fprintf(stderr, "\n mysql_client_init() failed");
19738     exit(1);
19739   }
19740 
19741   if (!(mysql_real_connect(mysql_local, opt_host, opt_user,
19742                            opt_password, current_db, opt_port,
19743                            opt_unix_socket, CLIENT_COMPRESS)))
19744   {
19745     fprintf(stderr, "\n connection failed(%s)", mysql_error(mysql_local));
19746     exit(1);
19747   }
19748   mysql_options(mysql_local,MYSQL_OPT_COMPRESS,NullS);
19749 
19750   end= strmov(strfill(strmov(query, "select length(\""),1000,'a'),"\")");
19751 
19752   for (i=0 ; i < 2 ; i++)
19753   {
19754     MYSQL_RES *res;
19755 
19756     int rc= mysql_real_query(mysql, query, (int) (end-query));
19757     myquery(rc);
19758     res= mysql_store_result(mysql);
19759     DBUG_ASSERT(res != 0);
19760     mysql_free_result(res);
19761   }
19762 
19763   mysql_close(mysql_local);
19764 }
19765 
19766 /*
19767   Check big packets
19768 */
19769 
test_big_packet()19770 static void test_big_packet()
19771 {
19772   MYSQL *mysql_local;
19773   char *query, *end;
19774   /* We run the tests with a server with max packet size of 3200000 */
19775   size_t big_packet= 31000000L;
19776   int i;
19777   MYSQL_PARAMETERS *mysql_params= mysql_get_parameters();
19778   long org_max_allowed_packet= *mysql_params->p_max_allowed_packet;
19779   long opt_net_buffer_length= *mysql_params->p_net_buffer_length;
19780 
19781   myheader("test_big_packet");
19782 
19783   query= (char*) my_malloc(big_packet+1024, MYF(MY_WME));
19784   DIE_UNLESS(query);
19785 
19786   if (!(mysql_local= mysql_client_init(NULL)))
19787   {
19788     fprintf(stderr, "\n mysql_client_init() failed");
19789     exit(1);
19790   }
19791 
19792   if (!(mysql_real_connect(mysql_local, opt_host, opt_user,
19793                            opt_password, current_db, opt_port,
19794                            opt_unix_socket, 0)))
19795   {
19796     fprintf(stderr, "\n connection failed(%s)", mysql_error(mysql_local));
19797     mysql_close(mysql_local);
19798     exit(1);
19799   }
19800 
19801   *mysql_params->p_max_allowed_packet= big_packet+1000;
19802   *mysql_params->p_net_buffer_length=  8L*256L*256L;
19803 
19804   end= strmov(strfill(strmov(query, "select length(\""), big_packet,'a'),"\")");
19805 
19806   for (i=0 ; i < 2 ; i++)
19807   {
19808     MYSQL_RES *res;
19809     int rc= mysql_real_query(mysql, query, (int) (end-query));
19810     myquery(rc);
19811     res= mysql_store_result(mysql);
19812     DBUG_ASSERT(res != 0);
19813     mysql_free_result(res);
19814   }
19815 
19816   mysql_close(mysql_local);
19817   my_free(query);
19818 
19819   *mysql_params->p_max_allowed_packet= org_max_allowed_packet;
19820   *mysql_params->p_net_buffer_length = opt_net_buffer_length;
19821 }
19822 
19823 
test_prepare_analyze()19824 static void test_prepare_analyze()
19825 {
19826   MYSQL_STMT *stmt;
19827   const char *query= "ANALYZE SELECT 1";
19828   int rc;
19829   myheader("test_prepare_analyze");
19830 
19831   stmt= mysql_stmt_init(mysql);
19832   check_stmt(stmt);
19833   rc= mysql_stmt_prepare(stmt, query, strlen(query));
19834   check_execute(stmt, rc);
19835 
19836   rc= mysql_stmt_execute(stmt);
19837   check_execute(stmt, rc);
19838 
19839   rc= mysql_stmt_store_result(stmt);
19840   check_execute(stmt, rc);
19841 
19842   while (!(rc= mysql_stmt_fetch(stmt)))
19843     ;
19844 
19845   DIE_UNLESS(rc == MYSQL_NO_DATA);
19846 
19847   rc= mysql_stmt_close(stmt);
19848   check_execute(stmt, rc);
19849 }
19850 
test_mdev12579()19851 static void test_mdev12579()
19852 {
19853   MYSQL_STMT *stmt= mysql_stmt_init(mysql);
19854   MYSQL_BIND bind[2];
19855   int rc;
19856   long l=3;
19857   const char *data = "123456";
19858 
19859   rc= mysql_query(mysql, "CREATE TABLE mdev12579 (k integer,t LONGTEXT,b LONGBLOB,x integer)");
19860   myquery(rc);
19861 
19862   rc= mysql_stmt_prepare(stmt, "INSERT INTO mdev12579 VALUES (1,?,NULL,?)", -1);
19863   myquery(rc);
19864 
19865   rc= mysql_stmt_send_long_data(stmt, 0, data, 6);
19866   rc= mysql_stmt_send_long_data(stmt, 0, data, 6);
19867   rc= mysql_stmt_send_long_data(stmt, 0, data, 6);
19868 
19869   memset(bind, 0, sizeof(MYSQL_BIND) * 2);
19870   bind[0].buffer_type= MYSQL_TYPE_VAR_STRING;
19871   bind[1].buffer_type= MYSQL_TYPE_LONG;
19872   bind[1].buffer= &l;
19873   mysql_stmt_bind_param(stmt, bind);
19874 
19875   rc= mysql_stmt_execute(stmt);
19876   check_execute(stmt, rc);
19877 
19878   mysql_stmt_close(stmt);
19879 
19880   rc= mysql_query(mysql, "DROP TABLE mdev12579");
19881   myquery(rc);
19882 }
19883 
19884 /* Test test_mdev14013 sql_mode=EMPTY_STRING_IS_NULL */
19885 
test_mdev14013()19886 static void test_mdev14013()
19887 {
19888   MYSQL *lmysql;
19889   MYSQL_STMT *stmt1;
19890   MYSQL_BIND  my_bind[2];
19891   MYSQL_RES   *result;
19892   char       str_data[20];
19893   unsigned int  count;
19894   int   rc;
19895   char query[MAX_TEST_QUERY_LENGTH];
19896 
19897   myheader("test_mdev14013");
19898 
19899   if (!opt_silent)
19900     fprintf(stdout, "\n Establishing a test connection ...");
19901   if (!(lmysql= mysql_client_init(NULL)))
19902   {
19903     myerror("mysql_client_init() failed");
19904     exit(1);
19905   }
19906   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
19907                            opt_password, current_db, opt_port,
19908                            opt_unix_socket, 0)))
19909   {
19910     myerror("connection failed");
19911     exit(1);
19912   }
19913   mysql_options(lmysql, MYSQL_OPT_RECONNECT, &my_true);
19914   if (!opt_silent)
19915     fprintf(stdout, "OK");
19916 
19917   /* set AUTOCOMMIT to ON*/
19918   mysql_autocommit(lmysql, TRUE);
19919 
19920   strmov(query, "SET SQL_MODE= \"EMPTY_STRING_IS_NULL\"");
19921   if (!opt_silent)
19922     fprintf(stdout, "\n With %s", query);
19923   rc= mysql_query(mysql, query);
19924   myquery(rc);
19925 
19926   rc= mysql_query(lmysql, "DROP TABLE IF EXISTS test_mdev14013");
19927   myquery(rc);
19928 
19929   rc= mysql_query(lmysql, "CREATE TABLE test_mdev14013(id int, val varchar(10))");
19930   myquery(rc);
19931 
19932   strmov(query, "INSERT INTO test_mdev14013(id,val) VALUES(?,?)");
19933   stmt1= mysql_simple_prepare(mysql, query);
19934   check_stmt(stmt1);
19935 
19936   verify_param_count(stmt1, 2);
19937 
19938   /*
19939     We need to bzero bind structure because mysql_stmt_bind_param checks all
19940     its members.
19941   */
19942   bzero((char*) my_bind, sizeof(my_bind));
19943 
19944   my_bind[0].buffer= (void *)&count;
19945   my_bind[0].buffer_type= MYSQL_TYPE_LONG;
19946   count= 100;
19947 
19948   strcpy(str_data,"");
19949   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
19950   my_bind[1].buffer= (char *) str_data;
19951   my_bind[1].buffer_length= strlen(str_data);
19952 
19953   rc= mysql_stmt_bind_param(stmt1, my_bind);
19954 
19955   rc= mysql_stmt_execute(stmt1);
19956   check_execute(stmt1, rc);
19957 
19958   verify_st_affected_rows(stmt1, 1);
19959 
19960   rc= mysql_stmt_close(stmt1);
19961 
19962   strmov(query, "SET SQL_MODE= default");
19963   if (!opt_silent)
19964     fprintf(stdout, "\n With %s\n", query);
19965   rc= mysql_query(mysql, query);
19966   myquery(rc);
19967 
19968   strmov(query, "INSERT INTO test_mdev14013(id,val) VALUES(?,?)");
19969   stmt1= mysql_simple_prepare(mysql, query);
19970   check_stmt(stmt1);
19971 
19972   count= 200;
19973   rc= mysql_stmt_bind_param(stmt1, my_bind);
19974 
19975   rc= mysql_stmt_execute(stmt1);
19976   check_execute(stmt1, rc);
19977 
19978   verify_st_affected_rows(stmt1, 1);
19979 
19980   rc= mysql_stmt_close(stmt1);
19981   if (!opt_silent)
19982     fprintf(stdout, "\n test_mdev14013(x) returned: %d", rc);
19983   DIE_UNLESS( rc == 0);
19984 
19985   rc= mysql_query(mysql, "SELECT id, val FROM test_mdev14013 order by id");
19986   myquery(rc);
19987 
19988   result= mysql_store_result(mysql);
19989   mytest(result);
19990 
19991   rc= my_process_result_set(result);
19992   DIE_UNLESS(rc == 2);
19993   mysql_free_result(result);
19994 
19995   rc= mysql_query(mysql, "SELECT id, val FROM test_mdev14013 where val is null");
19996   myquery(rc);
19997 
19998   result= mysql_store_result(mysql);
19999   mytest(result);
20000 
20001   rc= my_process_result_set(result);
20002   DIE_UNLESS(rc == 1);
20003   mysql_free_result(result);
20004 
20005   myquery(mysql_query(mysql, "drop table test_mdev14013"));
20006   mysql_close(lmysql);
20007 }
20008 
test_mdev14013_1()20009 static void test_mdev14013_1()
20010 {
20011   MYSQL *lmysql;
20012   MYSQL_STMT *stmt1;
20013   MYSQL_BIND  my_bind[3];
20014   char       str_data[3][255];
20015   int  rc;
20016   char query[MAX_TEST_QUERY_LENGTH];
20017 
20018   myheader("test_mdev14013_1");
20019 
20020   if (!opt_silent)
20021     fprintf(stdout, "\n Establishing a test connection ...");
20022   if (!(lmysql= mysql_client_init(NULL)))
20023   {
20024     myerror("mysql_client_init() failed");
20025     exit(1);
20026   }
20027   if (!(mysql_real_connect(lmysql, opt_host, opt_user,
20028                            opt_password, current_db, opt_port,
20029                            opt_unix_socket, 0)))
20030   {
20031     myerror("connection failed");
20032     exit(1);
20033   }
20034   mysql_options(lmysql, MYSQL_OPT_RECONNECT, &my_true);
20035   if (!opt_silent)
20036     fprintf(stdout, "OK");
20037 
20038   /* set AUTOCOMMIT to ON*/
20039   mysql_autocommit(lmysql, TRUE);
20040 
20041   strmov(query, "SET SQL_MODE= \"EMPTY_STRING_IS_NULL\"");
20042   if (!opt_silent)
20043     fprintf(stdout, "\n With %s", query);
20044   rc= mysql_query(mysql, query);
20045   myquery(rc);
20046 
20047   rc= mysql_query(mysql,
20048     "CREATE OR REPLACE PROCEDURE test_mdev14013_p1("
20049     "   IN i1 VARCHAR(255) , "
20050     "   INOUT io1 VARCHAR(255), "
20051     "   OUT o2 VARBINARY(255)) "
20052     "BEGIN "
20053     "   SET o2 = concat(concat(coalesce(i1,'i1 is null'),' - '),coalesce(i1,'io1 is null')); "
20054     "END");
20055   myquery(rc);
20056 
20057   strmov(query, "CALL test_mdev14013_p1(?, ?, ?)");
20058   stmt1= mysql_simple_prepare(mysql, query);
20059   check_stmt(stmt1);
20060 
20061   /* Init PS-parameters. */
20062 
20063   bzero((char *) my_bind, sizeof (my_bind));
20064 
20065   strcpy(str_data[0],"");
20066   my_bind[0].buffer_type= MYSQL_TYPE_STRING;
20067   my_bind[0].buffer= (char *) str_data[0];
20068   my_bind[0].buffer_length= strlen(str_data[0]);
20069 
20070   strcpy(str_data[1],"");
20071   my_bind[1].buffer_type= MYSQL_TYPE_STRING;
20072   my_bind[1].buffer= (char *) str_data[1];
20073   my_bind[1].buffer_length= strlen(str_data[1]);
20074 
20075   strcpy(str_data[2],"");
20076   my_bind[2].buffer_type= MYSQL_TYPE_STRING;
20077   my_bind[2].buffer= (char *) str_data[2];
20078   my_bind[2].buffer_length= strlen(str_data[2]);
20079 
20080   /* Bind parameters. */
20081 
20082   rc= mysql_stmt_bind_param(stmt1, my_bind);
20083   check_execute(stmt1, rc);
20084   /* Execute */
20085 
20086   rc= mysql_stmt_execute(stmt1);
20087   check_execute(stmt1, rc);
20088 
20089   my_bind[0].buffer_length= sizeof(str_data[0]);
20090   my_bind[1].buffer_length= sizeof(str_data[1]);
20091 
20092   mysql_stmt_bind_result(stmt1, my_bind);
20093   rc= mysql_stmt_fetch(stmt1);
20094 
20095   if (!opt_silent)
20096     fprintf(stdout,"\nstr_data[1]=%s\n",str_data[1]);
20097 
20098   DIE_UNLESS(strcmp(str_data[1], "i1 is null - io1 is null") == 0);
20099 
20100   rc= mysql_stmt_close(stmt1);
20101   DIE_UNLESS( rc == 0);
20102 
20103   myquery(mysql_query(mysql, "drop procedure test_mdev14013_p1"));
20104   mysql_close(lmysql);
20105 }
20106 
20107 
test_mdev14454_internal(const char * init,unsigned int csid,const char * value)20108 static void test_mdev14454_internal(const char *init,
20109                                     unsigned int csid,
20110                                     const char *value)
20111 {
20112   MYSQL_STMT *stmt;
20113   MYSQL_BIND bind;
20114   const char *stmtstr= "CALL P1(?)";
20115   char res[20];
20116   int rc;
20117 
20118   if ((rc= mysql_query_or_error(mysql, init)) ||
20119       (rc= mysql_query_or_error(mysql, "DROP PROCEDURE IF EXISTS p1")) ||
20120       (rc= mysql_query_or_error(mysql,
20121                                "CREATE PROCEDURE p1"
20122                                "("
20123                                "  OUT param1 TEXT CHARACTER SET utf8"
20124                                ")"
20125                                "BEGIN "
20126                                "  SET param1 = _latin1'test\xFF'; "
20127                                "END")))
20128     DIE("Initiation failed");
20129 
20130   stmt= mysql_stmt_init(mysql);
20131   rc= mysql_stmt_prepare(stmt, stmtstr, strlen(stmtstr));
20132   DIE_UNLESS(rc == 0);
20133   DIE_UNLESS(mysql_stmt_param_count(stmt) == 1);
20134 
20135   bind.buffer_type= MYSQL_TYPE_NULL;
20136   rc= mysql_stmt_bind_param(stmt, &bind);
20137   DIE_UNLESS(rc == 0);
20138 
20139   rc= mysql_stmt_execute(stmt);
20140   DIE_UNLESS(rc == 0);
20141 
20142   memset(res, 0, sizeof(res));
20143   memset(&bind, 0, sizeof(bind));
20144   bind.buffer_type= MYSQL_TYPE_STRING;
20145   bind.buffer_length= sizeof(res);
20146   bind.buffer= res;
20147 
20148   do {
20149     if (mysql->server_status & SERVER_PS_OUT_PARAMS)
20150     {
20151       MYSQL_FIELD *field;
20152       printf("\nOUT param result set:\n");
20153       DIE_UNLESS(mysql_stmt_field_count(stmt) == 1);
20154       field= &stmt->fields[0];
20155       printf("Field: %s\n", field->name);
20156       printf("Type: %d\n", field->type);
20157       printf("Collation: %d\n", field->charsetnr);
20158       printf("Length: %lu\n", field->length);
20159       DIE_UNLESS(stmt->fields[0].charsetnr == csid);
20160 
20161       rc= mysql_stmt_bind_result(stmt, &bind);
20162       DIE_UNLESS(rc == 0);
20163       rc= mysql_stmt_fetch(stmt);
20164       DIE_UNLESS(rc == 0);
20165       printf("Value: %s\n", res);
20166       DIE_UNLESS(strcmp(res, value) == 0);
20167     }
20168     else if (mysql_stmt_field_count(stmt))
20169     {
20170       printf("sp result set\n");
20171     }
20172   } while (mysql_stmt_next_result(stmt) == 0);
20173 
20174   mysql_stmt_close(stmt);
20175   DIE_UNLESS(mysql_query_or_error(mysql, "DROP PROCEDURE p1") == 0);
20176 }
20177 
20178 
test_mdev14454()20179 static void test_mdev14454()
20180 {
20181   myheader("test_mdev14454");
20182   test_mdev14454_internal("SET NAMES latin1", 8, "test\xFF");
20183   test_mdev14454_internal("SET NAMES utf8", 33, "test\xC3\xBF");
20184 }
20185 
20186 
20187 typedef struct {
20188   char sig[12];
20189   char ver_cmd;
20190   char fam;
20191   short len;
20192   union {
20193     struct {  /* for TCP/UDP over IPv4, len = 12 */
20194       int src_addr;
20195       int dst_addr;
20196       short src_port;
20197       short dst_port;
20198     } ip4;
20199     struct {  /* for TCP/UDP over IPv6, len = 36 */
20200       char  src_addr[16];
20201       char  dst_addr[16];
20202       short src_port;
20203       short dst_port;
20204     } ip6;
20205     struct {  /* for AF_UNIX sockets, len = 216 */
20206       char src_addr[108];
20207       char dst_addr[108];
20208     } unx;
20209   } addr;
20210 } v2_proxy_header;
20211 
20212 #ifndef EMBEDDED_LIBRARY
test_proxy_header_tcp(const char * ipaddr,int port)20213 static void test_proxy_header_tcp(const char *ipaddr, int port)
20214 {
20215 
20216   int rc;
20217   MYSQL_RES *result;
20218   int family = (strchr(ipaddr,':') == NULL)?AF_INET:AF_INET6;
20219   char query[256];
20220   char text_header[256];
20221   char addr_bin[16];
20222   v2_proxy_header v2_header;
20223   void *header_data[2];
20224   size_t header_lengths[2];
20225   int i;
20226 
20227   // normalize IPv4-mapped IPv6 addresses, e.g ::ffff:127.0.0.2 to 127.0.0.2
20228   const char *normalized_addr= strncmp(ipaddr, "::ffff:", 7)?ipaddr : ipaddr + 7;
20229 
20230   memset(&v2_header, 0, sizeof(v2_header));
20231   sprintf(text_header,"PROXY %s %s %s %d 3306\r\n",family == AF_INET?"TCP4":"TCP6", ipaddr, ipaddr, port);
20232 
20233   inet_pton(family,ipaddr,addr_bin);
20234 
20235   memcpy(v2_header.sig, "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A", 12);
20236   v2_header.ver_cmd = (0x2 << 4) | 0x1; /* Version (0x2) , Command = PROXY (0x1) */
20237   if(family == AF_INET)
20238   {
20239     v2_header.fam= 0x11;
20240     v2_header.len= htons(12);
20241     v2_header.addr.ip4.src_port= htons(port);
20242     v2_header.addr.ip4.dst_port= htons(3306);
20243     memcpy(&v2_header.addr.ip4.src_addr,addr_bin, sizeof (v2_header.addr.ip4.src_addr));
20244     memcpy(&v2_header.addr.ip4.dst_addr,addr_bin, sizeof (v2_header.addr.ip4.dst_addr));
20245   }
20246   else
20247   {
20248     v2_header.fam= 0x21;
20249     v2_header.len= htons(36);
20250     v2_header.addr.ip6.src_port= htons(port);
20251     v2_header.addr.ip6.dst_port= htons(3306);
20252     memcpy(v2_header.addr.ip6.src_addr,addr_bin, sizeof (v2_header.addr.ip6.src_addr));
20253     memcpy(v2_header.addr.ip6.dst_addr,addr_bin, sizeof (v2_header.addr.ip6.dst_addr));
20254   }
20255 
20256   sprintf(query,"CREATE USER 'u'@'%s' IDENTIFIED BY 'password'",normalized_addr);
20257   rc= mysql_query(mysql, query);
20258   myquery(rc);
20259 
20260   header_data[0]= text_header;
20261   header_data[1]= &v2_header;
20262 
20263   header_lengths[0]= strlen(text_header);
20264   header_lengths[1]= family == AF_INET ? 28 : 52;
20265 
20266   for (i = 0; i < 2; i++)
20267   {
20268     MYSQL *m;
20269     size_t addrlen;
20270     MYSQL_ROW row;
20271     m = mysql_client_init(NULL);
20272     DIE_UNLESS(m);
20273     mysql_optionsv(m, MARIADB_OPT_PROXY_HEADER, header_data[i], header_lengths[i]);
20274     if (!mysql_real_connect(m, opt_host, "u", "password", NULL, opt_port, opt_unix_socket, 0))
20275     {
20276        DIE_UNLESS(0);
20277     }
20278     rc= mysql_query(m, "select host from information_schema.processlist WHERE ID = connection_id()");
20279     myquery(rc);
20280     /* get the result */
20281     result= mysql_store_result(m);
20282     mytest(result);
20283     row = mysql_fetch_row(result);
20284     addrlen = strlen(normalized_addr);
20285     printf("%.*s %.*s\n", (int)addrlen, row[0], (int)addrlen, normalized_addr);
20286     DIE_UNLESS(strncmp(row[0], normalized_addr, addrlen) == 0);
20287     DIE_UNLESS(atoi(row[0] + addrlen+1) == port);
20288     mysql_free_result(result);
20289     mysql_close(m);
20290   }
20291   sprintf(query,"DROP USER 'u'@'%s'",normalized_addr);
20292   rc = mysql_query(mysql, query);
20293   myquery(rc);
20294 }
20295 
20296 
20297 /* Test proxy protocol with AF_UNIX (localhost) */
test_proxy_header_localhost()20298 static void test_proxy_header_localhost()
20299 {
20300   v2_proxy_header v2_header;
20301   void *header_data = &v2_header;
20302   size_t header_length= 216 + 16;
20303   MYSQL *m;
20304   MYSQL_RES *result;
20305   MYSQL_ROW row;
20306   int rc;
20307 
20308   memset(&v2_header, 0, sizeof(v2_header));
20309   memcpy(v2_header.sig, "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A", 12);
20310   v2_header.ver_cmd = (0x2 << 4) | 0x1; /* Version (0x2) , Command = PROXY (0x1) */
20311   v2_header.fam= 0x31;
20312   v2_header.len= htons(216);
20313   strcpy(v2_header.addr.unx.src_addr,"/tmp/mysql.sock");
20314   strcpy(v2_header.addr.unx.dst_addr,"/tmp/mysql.sock");
20315   rc = mysql_query(mysql, "CREATE USER 'u'@'localhost' IDENTIFIED BY 'password'");
20316   myquery(rc);
20317   m = mysql_client_init(NULL);
20318   DIE_UNLESS(m != NULL);
20319   mysql_optionsv(m, MARIADB_OPT_PROXY_HEADER, header_data, header_length);
20320   DIE_UNLESS(mysql_real_connect(m, opt_host, "u", "password", NULL, opt_port, opt_unix_socket, 0) == m);
20321   DIE_UNLESS(mysql_query(m, "select host from information_schema.processlist WHERE ID = connection_id()") == 0);
20322   /* get the result */
20323   result= mysql_store_result(m);
20324   mytest(result);
20325   row = mysql_fetch_row(result);
20326   DIE_UNLESS(strcmp(row[0], "localhost") == 0);
20327   mysql_free_result(result);
20328   mysql_close(m);
20329   rc = mysql_query(mysql,  "DROP USER 'u'@'localhost'");
20330   myquery(rc);
20331 }
20332 
20333 /* Proxy header ignoring */
test_proxy_header_ignore()20334 static void test_proxy_header_ignore()
20335 {
20336   int rc;
20337   MYSQL *m = mysql_client_init(NULL);
20338   v2_proxy_header v2_header;
20339   DIE_UNLESS(m != NULL);
20340   mysql_optionsv(m, MARIADB_OPT_PROXY_HEADER, "PROXY UNKNOWN\r\n",15);
20341   DIE_UNLESS(mysql_real_connect(m, opt_host, "root", "", NULL, opt_port, opt_unix_socket, 0) == m);
20342   mysql_close(m);
20343 
20344   memcpy(v2_header.sig, "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A", 12);
20345   v2_header.ver_cmd = (0x2 << 4) | 0x0; /* Version (0x2) , Command = LOCAL (0x0) */
20346   v2_header.fam= 0x0; /* AF_UNSPEC*/
20347   v2_header.len= htons(0);
20348   m = mysql_client_init(NULL);
20349   mysql_optionsv(m, MARIADB_OPT_PROXY_HEADER, &v2_header,16);
20350   DIE_UNLESS(mysql_real_connect(m, opt_host, "root", "", NULL, opt_port, opt_unix_socket, 0) == m);
20351   mysql_close(m);
20352 
20353   /* test for connection denied with empty proxy_protocol_networks */
20354   rc = mysql_query(mysql, "select @@proxy_protocol_networks into @sv_proxy_protocol_networks");
20355   myquery(rc);
20356   mysql_query(mysql, "set global proxy_protocol_networks=default");
20357   myquery(rc);
20358   m = mysql_client_init(NULL);
20359   mysql_optionsv(m, MARIADB_OPT_PROXY_HEADER, &v2_header,16);
20360   DIE_UNLESS(mysql_real_connect(m, opt_host, "root", "", NULL, opt_port, opt_unix_socket, 0) == 0);
20361   mysql_close(m);
20362   mysql_query(mysql, "set global proxy_protocol_networks= @sv_proxy_protocol_networks");
20363   myquery(rc);
20364 }
20365 
20366 
test_proxy_header()20367 static void test_proxy_header()
20368 {
20369   test_proxy_header_tcp("192.0.2.1",3333);
20370   test_proxy_header_tcp("2001:db8:85a3::8a2e:370:7334",2222);
20371   test_proxy_header_tcp("::ffff:192.0.2.1",2222);
20372   test_proxy_header_localhost();
20373   test_proxy_header_ignore();
20374 }
20375 
20376 
test_bulk_autoinc()20377 static void test_bulk_autoinc()
20378 {
20379   int rc;
20380   MYSQL_STMT *stmt;
20381   MYSQL_BIND bind[1];
20382   MYSQL_ROW  row;
20383   char       indicator[]= {0, STMT_INDICATOR_NULL, 0/*STMT_INDICATOR_IGNORE*/};
20384   my_bool   error[1];
20385   int        i, id[]= {2, 3, 777}, count= sizeof(id)/sizeof(id[0]);
20386   MYSQL_RES *result;
20387 
20388   rc= mysql_query(mysql, "DROP TABLE IF EXISTS ai_field_value");
20389   myquery(rc);
20390   rc= mysql_query(mysql, "CREATE TABLE ai_field_value (id int not null primary key auto_increment)");
20391   myquery(rc);
20392   stmt= mysql_stmt_init(mysql);
20393   rc= mysql_stmt_prepare(stmt, "INSERT INTO ai_field_value(id) values(?)", -1);
20394   check_execute(stmt, rc);
20395 
20396   memset(bind, 0, sizeof(bind));
20397   bind[0].buffer_type = MYSQL_TYPE_LONG;
20398   bind[0].buffer = (void *)id;
20399   bind[0].buffer_length = 0;
20400   bind[0].is_null = NULL;
20401   bind[0].length = NULL;
20402   bind[0].error = error;
20403   bind[0].u.indicator= indicator;
20404 
20405   mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, (void*)&count);
20406   rc= mysql_stmt_bind_param(stmt, bind);
20407   check_execute(stmt, rc);
20408 
20409   rc= mysql_stmt_execute(stmt);
20410   check_execute(stmt, rc);
20411 
20412   mysql_stmt_close(stmt);
20413 
20414   rc= mysql_query(mysql, "SELECT id FROM ai_field_value");
20415   myquery(rc);
20416 
20417   result= mysql_store_result(mysql);
20418   mytest(result);
20419 
20420   i= 0;
20421   while ((row= mysql_fetch_row(result)))
20422   {
20423     DIE_IF(atoi(row[0]) != id[i++]);
20424   }
20425   mysql_free_result(result);
20426   rc= mysql_query(mysql, "DROP TABLE ai_field_value");
20427   myquery(rc);
20428 }
20429 
test_bulk_delete()20430 static void test_bulk_delete()
20431 {
20432   int rc;
20433   MYSQL_STMT *stmt;
20434   MYSQL_BIND bind[1];
20435   MYSQL_ROW  row;
20436   char       indicator[]= {0, 0, 0};
20437   my_bool   error[1];
20438   int        i, id[]= {1, 2, 4}, count= sizeof(id)/sizeof(id[0]);
20439   MYSQL_RES *result;
20440 
20441   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
20442   myquery(rc);
20443   rc= mysql_query(mysql, "CREATE TABLE t1 (id int not null primary key)");
20444   myquery(rc);
20445   rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1),(2),(3),(4)");
20446   myquery(rc);
20447   verify_affected_rows(4);
20448 
20449   stmt= mysql_stmt_init(mysql);
20450   rc= mysql_stmt_prepare(stmt, "DELETE FROM t1 where id=?", -1);
20451   check_execute(stmt, rc);
20452 
20453   memset(bind, 0, sizeof(bind));
20454   bind[0].buffer_type = MYSQL_TYPE_LONG;
20455   bind[0].buffer = (void *)id;
20456   bind[0].buffer_length = 0;
20457   bind[0].is_null = NULL;
20458   bind[0].length = NULL;
20459   bind[0].error = error;
20460   bind[0].u.indicator= indicator;
20461 
20462   mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, (void*)&count);
20463   rc= mysql_stmt_bind_param(stmt, bind);
20464   check_execute(stmt, rc);
20465 
20466   rc= mysql_stmt_execute(stmt);
20467   check_execute(stmt, rc);
20468   verify_affected_rows(3);
20469 
20470   mysql_stmt_close(stmt);
20471 
20472   rc= mysql_query(mysql, "SELECT id FROM t1");
20473   myquery(rc);
20474 
20475   result= mysql_store_result(mysql);
20476   mytest(result);
20477 
20478   i= 0;
20479   while ((row= mysql_fetch_row(result)))
20480   {
20481     i++;
20482     DIE_IF(atoi(row[0]) != 3);
20483   }
20484   DIE_IF(i != 1);
20485   mysql_free_result(result);
20486 
20487   rc= mysql_query(mysql, "DROP TABLE t1");
20488   myquery(rc);
20489 }
20490 
test_bulk_replace()20491 static void test_bulk_replace()
20492 {
20493   int rc;
20494   MYSQL_STMT *stmt;
20495   MYSQL_BIND bind[2];
20496   MYSQL_ROW  row;
20497   int        i,
20498              id[]= {1, 2, 3, 4},
20499              val[]= {1, 1, 1, 1},
20500              count= sizeof(id)/sizeof(id[0]);
20501   MYSQL_RES *result;
20502 
20503   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
20504   myquery(rc);
20505   rc= mysql_query(mysql, "CREATE TABLE t1 (id int not null primary key, active int)");
20506   myquery(rc);
20507   rc= mysql_query(mysql, "insert into t1 values (1, 0), (2, 0), (3, 0)");
20508   myquery(rc);
20509   verify_affected_rows(3);
20510 
20511   stmt= mysql_stmt_init(mysql);
20512   rc= mysql_stmt_prepare(stmt, "replace into t1 (id, active) values (?, ?)", -1);
20513   check_execute(stmt, rc);
20514 
20515   memset(bind, 0, sizeof(bind));
20516   bind[0].buffer_type = MYSQL_TYPE_LONG;
20517   bind[0].buffer = (void *)id;
20518   bind[0].buffer_length = 0;
20519   bind[1].buffer_type = MYSQL_TYPE_LONG;
20520   bind[1].buffer = (void *)val;
20521   bind[1].buffer_length = 0;
20522 
20523   mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, (void*)&count);
20524   rc= mysql_stmt_bind_param(stmt, bind);
20525   check_execute(stmt, rc);
20526 
20527   rc= mysql_stmt_execute(stmt);
20528   check_execute(stmt, rc);
20529 
20530   mysql_stmt_close(stmt);
20531 
20532   rc= mysql_query(mysql, "SELECT active FROM t1");
20533   myquery(rc);
20534 
20535   result= mysql_store_result(mysql);
20536   mytest(result);
20537 
20538   i= 0;
20539   while ((row= mysql_fetch_row(result)))
20540   {
20541     i++;
20542     DIE_IF(atoi(row[0]) != 1);
20543   }
20544   DIE_IF(i != 4);
20545   mysql_free_result(result);
20546 
20547   rc= mysql_query(mysql, "DROP TABLE t1");
20548   myquery(rc);
20549 }
20550 #endif
20551 
20552 
test_ps_params_in_ctes()20553 static void test_ps_params_in_ctes()
20554 {
20555   int rc;
20556   const char *query;
20557   MYSQL_BIND ps_params[1];
20558   int int_data[1];
20559   MYSQL_STMT *stmt;
20560 
20561   rc= mysql_query(mysql, "create table t1(a int, b int, key(a))");
20562   myquery(rc);
20563 
20564   rc= mysql_query(mysql, "insert into t1 (a) values "
20565                          "(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)");
20566   myquery(rc);
20567 
20568   query=
20569     "explain "
20570     "with T as "
20571     "( "
20572     "  select * from t1 where t1.a=? limit 2 "
20573     ") "
20574     "select * from T as TA, T as TB;";
20575 
20576   stmt= mysql_stmt_init(mysql);
20577   check_stmt(stmt);
20578 
20579   rc= mysql_stmt_prepare(stmt, query, (uint) strlen(query));
20580   check_execute(stmt, rc);
20581 
20582   int_data[0]=2;
20583 
20584   ps_params[0].buffer_type= MYSQL_TYPE_LONG;
20585   ps_params[0].buffer= (char *) &int_data[0];
20586   ps_params[0].length= 0;
20587   ps_params[0].is_null= 0;
20588 
20589   rc= mysql_stmt_bind_param(stmt, ps_params);
20590   check_execute(stmt, rc);
20591 
20592   rc= mysql_stmt_execute(stmt);
20593   check_execute(stmt, rc);
20594 
20595   rc= mysql_stmt_store_result(stmt);
20596   check_execute(stmt, rc);
20597 
20598   mysql_stmt_close(stmt);
20599 
20600   rc= mysql_query(mysql, "drop table t1");
20601   myquery(rc);
20602 }
20603 
display_result_metadata(MYSQL_FIELD * field,uint num_fields)20604 void display_result_metadata(MYSQL_FIELD *field,
20605                              uint num_fields)
20606 {
20607   MYSQL_FIELD* field_end;
20608 
20609   mct_log("Catalog\tDatabase\tTable\tTable_alias\tColumn\t"
20610           "Column_alias\tType\tLength\tMax length\tIs_null\t"
20611           "Flags\tDecimals\tCharsetnr\n");
20612   for (field_end= field+num_fields; field < field_end; field++)
20613   {
20614     mct_log("%s\t", field->catalog);
20615     mct_log("%s\t", field->db);
20616     mct_log("%s\t", field->org_table);
20617     mct_log("%s\t", field->table);
20618     mct_log("%s\t", field->org_name);
20619     mct_log("%s\t", field->name);
20620     mct_log("%u\t", field->type);
20621     mct_log("%lu\t", field->length);
20622     mct_log("%lu\t", field->max_length);
20623     mct_log("%s\t", (IS_NOT_NULL(field->flags) ?  "N" : "Y"));
20624     mct_log("%u\t", field->flags);
20625     mct_log("%u\t", field->decimals);
20626     mct_log("%u\n", field->charsetnr);
20627   }
20628 }
20629 
test_mdev_26145()20630 static void test_mdev_26145()
20631 {
20632   MYSQL_STMT *stmt;
20633   MYSQL_RES *result;
20634   MYSQL_FIELD *fields;
20635   int        rc, num_fields;
20636 
20637   myheader("test_mdev_26145");
20638 
20639   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
20640   myquery(rc);
20641 
20642   rc= mysql_query(mysql, "CREATE TABLE t1(a INT)");
20643   myquery(rc);
20644 
20645   stmt= mysql_simple_prepare(
20646     mysql, "(SELECT MAX(a) FROM t1) UNION (SELECT MAX(a) FROM t1)");
20647   check_stmt(stmt);
20648 
20649   rc= mysql_stmt_execute(stmt);
20650   check_execute(stmt, rc);
20651 
20652   result= mysql_stmt_result_metadata(stmt);
20653   DIE_UNLESS(result);
20654 
20655   num_fields= mysql_stmt_field_count(stmt);
20656   fields= mysql_fetch_fields(result);
20657 
20658   mct_start_logging("test_mdev26145");
20659   display_result_metadata(fields, num_fields);
20660   mct_close_log();
20661 
20662   mysql_free_result(result);
20663   mysql_stmt_close(stmt);
20664 
20665   rc= mysql_query(mysql, "DROP TABLE t1");
20666 
20667   myquery(rc);
20668 }
20669 
test_mdev24827()20670 static void test_mdev24827()
20671 {
20672   int rc;
20673   MYSQL_STMT *stmt;
20674   unsigned long cursor = CURSOR_TYPE_READ_ONLY;
20675   const char* query=
20676     "SELECT t2.c1 AS c1 FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1 "
20677     "WHERE EXISTS (SELECT 1 FROM t1 WHERE c2 = -1) ORDER BY c1";
20678 
20679   myheader("test_mdev24827");
20680 
20681   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
20682   myquery(rc);
20683 
20684   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t2");
20685   myquery(rc);
20686 
20687   rc= mysql_query(mysql, "CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 INT)");
20688   myquery(rc);
20689 
20690   rc= mysql_query(mysql, "CREATE TABLE t2 (c1 INT PRIMARY KEY, c2 INT, "
20691                   "KEY idx_c2(c2))");
20692   myquery(rc);
20693 
20694   rc= mysql_query(mysql, "INSERT INTO t1 (c1, c2) "
20695                   "SELECT seq, seq FROM seq_1_to_10000");
20696   myquery(rc);
20697 
20698   rc= mysql_query(mysql, "INSERT INTO t2 (c1, c2) "
20699                   "SELECT seq, seq FROM seq_1_to_20000");
20700   myquery(rc);
20701 
20702   stmt= mysql_stmt_init(mysql);
20703   check_stmt(stmt);
20704 
20705   rc= mysql_stmt_prepare(stmt, query, strlen(query));
20706   check_execute(stmt, rc);
20707 
20708   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, &cursor);
20709   check_execute(stmt, rc);
20710 
20711   rc= mysql_stmt_execute(stmt);
20712   check_execute(stmt, rc);
20713   mysql_stmt_close(stmt);
20714 
20715   rc= mysql_query(mysql, "DROP TABLE t1");
20716   myquery(rc);
20717 
20718   rc= mysql_query(mysql, "DROP TABLE t2");
20719   myquery(rc);
20720 }
20721 
test_mdev_20516()20722 static void test_mdev_20516()
20723 {
20724   MYSQL_STMT *stmt;
20725   int        rc;
20726   unsigned long cursor= CURSOR_TYPE_READ_ONLY;
20727   const char* query=
20728     "CREATE VIEW v1 AS SELECT * FROM t1";
20729 
20730   myheader("test_mdev_20516");
20731 
20732   rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
20733   myquery(rc);
20734 
20735   rc= mysql_query(mysql, "CREATE TABLE t1(a INT)");
20736   myquery(rc);
20737 
20738   stmt= mysql_stmt_init(mysql);
20739   check_stmt(stmt);
20740 
20741   rc= mysql_stmt_prepare(stmt, query, strlen(query));
20742   check_execute(stmt, rc);
20743 
20744   rc= mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, &cursor);
20745   check_execute(stmt, rc);
20746 
20747   rc= mysql_stmt_execute(stmt);
20748   check_execute(stmt, rc);
20749   mysql_stmt_close(stmt);
20750 
20751   rc= mysql_query(mysql, "DROP TABLE t1");
20752   myquery(rc);
20753 }
20754 
print_metadata(MYSQL_RES * rs_metadata,int num_fields)20755 static void print_metadata(MYSQL_RES *rs_metadata, int num_fields)
20756 {
20757   int i;
20758   MYSQL_FIELD *fields= mysql_fetch_fields(rs_metadata);
20759 
20760   for (i = 0; i < num_fields; ++i)
20761   {
20762     mct_log("  - %d: name: '%s'/'%s'; table: '%s'/'%s'; "
20763         "db: '%s'; catalog: '%s'; length: %d; max_length: %d; "
20764         "type: %d; decimals: %d\n",
20765         (int) i,
20766         (const char *) fields[i].name,
20767         (const char *) fields[i].org_name,
20768         (const char *) fields[i].table,
20769         (const char *) fields[i].org_table,
20770         (const char *) fields[i].db,
20771         (const char *) fields[i].catalog,
20772         (int) fields[i].length,
20773         (int) fields[i].max_length,
20774         (int) fields[i].type,
20775         (int) fields[i].decimals);
20776 
20777   }
20778 }
20779 
test_explain_meta()20780 static void test_explain_meta()
20781 {
20782   MYSQL_STMT *stmt;
20783   int num_fields;
20784   char query[MAX_TEST_QUERY_LENGTH];
20785   MYSQL_RES *rs_metadata;
20786   int rc;
20787 
20788   myheader("test_explain_meta");
20789   mct_start_logging("test_explain_meta");
20790 
20791   strmov(query, "SELECT 1");
20792   stmt= mysql_simple_prepare(mysql, query);
20793   check_stmt(stmt);
20794 
20795   rs_metadata= mysql_stmt_result_metadata(stmt);
20796 
20797   num_fields= mysql_stmt_field_count(stmt);
20798   mct_log("SELECT number of fields: %d\n", (int) num_fields);
20799   if (num_fields != 1)
20800   {
20801     mct_close_log();
20802     DIE("num_fields != 1");
20803   }
20804   mysql_free_result(rs_metadata);
20805   mysql_stmt_close(stmt);
20806 
20807   strmov(query, "EXPLAIN SELECT 1");
20808   stmt= mysql_simple_prepare(mysql, query);
20809   check_stmt(stmt);
20810 
20811   rs_metadata= mysql_stmt_result_metadata(stmt);
20812 
20813   num_fields= mysql_stmt_field_count(stmt);
20814   mct_log("EXPALIN number of fields: %d\n", (int) num_fields);
20815   if (num_fields != 10)
20816   {
20817     mct_close_log();
20818     DIE("num_fields != 10");
20819   }
20820   print_metadata(rs_metadata, num_fields);
20821   mysql_free_result(rs_metadata);
20822   mysql_stmt_close(stmt);
20823 
20824   strmov(query, "EXPLAIN format=json SELECT 1");
20825   stmt= mysql_simple_prepare(mysql, query);
20826   check_stmt(stmt);
20827 
20828   rs_metadata= mysql_stmt_result_metadata(stmt);
20829 
20830   num_fields= mysql_stmt_field_count(stmt);
20831   mct_log("EXPALIN JSON number of fields: %d\n", (int) num_fields);
20832   if (num_fields != 1)
20833   {
20834     mct_close_log();
20835     DIE("num_fields != 1");
20836   }
20837   print_metadata(rs_metadata, num_fields);
20838   mysql_free_result(rs_metadata);
20839   mysql_stmt_close(stmt);
20840 
20841 
20842   strmov(query, "ANALYZE SELECT 1");
20843   stmt= mysql_simple_prepare(mysql, query);
20844   check_stmt(stmt);
20845 
20846   rs_metadata= mysql_stmt_result_metadata(stmt);
20847 
20848   num_fields= mysql_stmt_field_count(stmt);
20849   mct_log("ANALYZE number of fields: %d\n", (int) num_fields);
20850   if (num_fields != 13)
20851   {
20852     mct_close_log();
20853     DIE("num_fields != 13");
20854   }
20855   print_metadata(rs_metadata, num_fields);
20856   mysql_free_result(rs_metadata);
20857   mysql_stmt_close(stmt);
20858 
20859   strmov(query, "ANALYZE format=json SELECT 1");
20860   stmt= mysql_simple_prepare(mysql, query);
20861   check_stmt(stmt);
20862 
20863   rs_metadata= mysql_stmt_result_metadata(stmt);
20864 
20865   num_fields= mysql_stmt_field_count(stmt);
20866   mct_log("ANALYZE JSON number of fields: %d\n", (int) num_fields);
20867   if (num_fields != 1)
20868   {
20869     mct_close_log();
20870     DIE("num_fields != 1");
20871   }
20872   print_metadata(rs_metadata, num_fields);
20873   mysql_free_result(rs_metadata);
20874   mysql_stmt_close(stmt);
20875 
20876   rc= mysql_query(mysql, "CREATE TABLE t1 (a int)");
20877   myquery(rc);
20878 
20879   strmov(query, "EXPLAIN INSERT INTO t1 values (1)");
20880   stmt= mysql_simple_prepare(mysql, query);
20881   check_stmt(stmt);
20882 
20883   rs_metadata= mysql_stmt_result_metadata(stmt);
20884 
20885   num_fields= mysql_stmt_field_count(stmt);
20886   mct_log("EXPALIN INSERT number of fields: %d\n", (int) num_fields);
20887   if (num_fields != 10)
20888   {
20889     mct_close_log();
20890     DIE("num_fields != 10");
20891   }
20892   print_metadata(rs_metadata, num_fields);
20893   mysql_free_result(rs_metadata);
20894   mysql_stmt_close(stmt);
20895 
20896   strmov(query, "EXPLAIN format=json INSERT INTO t1 values(1)");
20897   stmt= mysql_simple_prepare(mysql, query);
20898   check_stmt(stmt);
20899 
20900   rs_metadata= mysql_stmt_result_metadata(stmt);
20901 
20902   num_fields= mysql_stmt_field_count(stmt);
20903   mct_log("EXPALIN JSON INSERT number of fields: %d\n", (int) num_fields);
20904   if (num_fields != 1)
20905   {
20906     mct_close_log();
20907     DIE("num_fields != 1");
20908   }
20909   print_metadata(rs_metadata, num_fields);
20910   mysql_free_result(rs_metadata);
20911   mysql_stmt_close(stmt);
20912 
20913 
20914   strmov(query, "ANALYZE INSERT INTO t1 values(1)");
20915   stmt= mysql_simple_prepare(mysql, query);
20916   check_stmt(stmt);
20917 
20918   rs_metadata= mysql_stmt_result_metadata(stmt);
20919 
20920   num_fields= mysql_stmt_field_count(stmt);
20921   mct_log("ANALYZE INSERT number of fields: %d\n", (int) num_fields);
20922   if (num_fields != 13)
20923   {
20924     mct_close_log();
20925     DIE("num_fields != 13");
20926   }
20927   print_metadata(rs_metadata, num_fields);
20928   mysql_free_result(rs_metadata);
20929   mysql_stmt_close(stmt);
20930 
20931   strmov(query, "ANALYZE format=json INSERT INTO t1 values(1)");
20932   stmt= mysql_simple_prepare(mysql, query);
20933   check_stmt(stmt);
20934 
20935   rs_metadata= mysql_stmt_result_metadata(stmt);
20936 
20937   num_fields= mysql_stmt_field_count(stmt);
20938   mct_log("ANALYZE JSON INSERT number of fields: %d\n", (int) num_fields);
20939   if (num_fields != 1)
20940   {
20941     mct_close_log();
20942     DIE("num_fields != 1");
20943   }
20944   print_metadata(rs_metadata, num_fields);
20945   mysql_free_result(rs_metadata);
20946   mysql_stmt_close(stmt);
20947 
20948 
20949   strmov(query, "EXPLAIN UPDATE t1 set a=2");
20950   stmt= mysql_simple_prepare(mysql, query);
20951   check_stmt(stmt);
20952 
20953   rs_metadata= mysql_stmt_result_metadata(stmt);
20954 
20955   num_fields= mysql_stmt_field_count(stmt);
20956   mct_log("EXPALIN UPDATE number of fields: %d\n", (int) num_fields);
20957   if (num_fields != 10)
20958   {
20959     mct_close_log();
20960     DIE("num_fields != 10");
20961   }
20962   print_metadata(rs_metadata, num_fields);
20963   mysql_free_result(rs_metadata);
20964   mysql_stmt_close(stmt);
20965 
20966   strmov(query, "EXPLAIN format=json  UPDATE t1 set a=2");
20967   stmt= mysql_simple_prepare(mysql, query);
20968   check_stmt(stmt);
20969 
20970   rs_metadata= mysql_stmt_result_metadata(stmt);
20971 
20972   num_fields= mysql_stmt_field_count(stmt);
20973   mct_log("EXPALIN JSON UPDATE number of fields: %d\n", (int) num_fields);
20974   if (num_fields != 1)
20975   {
20976     mct_close_log();
20977     DIE("num_fields != 1");
20978   }
20979   print_metadata(rs_metadata, num_fields);
20980   mysql_free_result(rs_metadata);
20981   mysql_stmt_close(stmt);
20982 
20983 
20984   strmov(query, "ANALYZE UPDATE t1 set a=2");
20985   stmt= mysql_simple_prepare(mysql, query);
20986   check_stmt(stmt);
20987 
20988   rs_metadata= mysql_stmt_result_metadata(stmt);
20989 
20990   num_fields= mysql_stmt_field_count(stmt);
20991   mct_log("ANALYZE UPDATE number of fields: %d\n", (int) num_fields);
20992   if (num_fields != 13)
20993   {
20994     mct_close_log();
20995     DIE("num_fields != 13");
20996   }
20997   print_metadata(rs_metadata, num_fields);
20998   mysql_free_result(rs_metadata);
20999   mysql_stmt_close(stmt);
21000 
21001   strmov(query, "ANALYZE format=json UPDATE t1 set a=2");
21002   stmt= mysql_simple_prepare(mysql, query);
21003   check_stmt(stmt);
21004 
21005   rs_metadata= mysql_stmt_result_metadata(stmt);
21006 
21007   num_fields= mysql_stmt_field_count(stmt);
21008   mct_log("ANALYZE JSON UPDATE number of fields: %d\n", (int) num_fields);
21009   if (num_fields != 1)
21010   {
21011     mct_close_log();
21012     DIE("num_fields != 1");
21013   }
21014   print_metadata(rs_metadata, num_fields);
21015   mysql_free_result(rs_metadata);
21016   mysql_stmt_close(stmt);
21017 
21018 
21019   strmov(query, "EXPLAIN DELETE FROM t1");
21020   stmt= mysql_simple_prepare(mysql, query);
21021   check_stmt(stmt);
21022 
21023   rs_metadata= mysql_stmt_result_metadata(stmt);
21024 
21025   num_fields= mysql_stmt_field_count(stmt);
21026   mct_log("EXPALIN DELETE number of fields: %d\n", (int) num_fields);
21027   if (num_fields != 10)
21028   {
21029     mct_close_log();
21030     DIE("num_fields != 10");
21031   }
21032   print_metadata(rs_metadata, num_fields);
21033   mysql_free_result(rs_metadata);
21034   mysql_stmt_close(stmt);
21035 
21036   strmov(query, "EXPLAIN format=json DELETE FROM t1");
21037   stmt= mysql_simple_prepare(mysql, query);
21038   check_stmt(stmt);
21039 
21040   rs_metadata= mysql_stmt_result_metadata(stmt);
21041 
21042   num_fields= mysql_stmt_field_count(stmt);
21043   mct_log("EXPALIN JSON DELETE number of fields: %d\n", (int) num_fields);
21044   if (num_fields != 1)
21045   {
21046     mct_close_log();
21047     DIE("num_fields != 1");
21048   }
21049   print_metadata(rs_metadata, num_fields);
21050   mysql_free_result(rs_metadata);
21051   mysql_stmt_close(stmt);
21052 
21053 
21054   strmov(query, "ANALYZE DELETE FROM t1");
21055   stmt= mysql_simple_prepare(mysql, query);
21056   check_stmt(stmt);
21057 
21058   rs_metadata= mysql_stmt_result_metadata(stmt);
21059 
21060   num_fields= mysql_stmt_field_count(stmt);
21061   mct_log("ANALYZE DELETE number of fields: %d\n", (int) num_fields);
21062   if (num_fields != 13)
21063   {
21064     mct_close_log();
21065     DIE("num_fields != 13");
21066   }
21067   print_metadata(rs_metadata, num_fields);
21068   mysql_free_result(rs_metadata);
21069   mysql_stmt_close(stmt);
21070 
21071   strmov(query, "ANALYZE format=json DELETE FROM t1");
21072   stmt= mysql_simple_prepare(mysql, query);
21073   check_stmt(stmt);
21074 
21075   rs_metadata= mysql_stmt_result_metadata(stmt);
21076 
21077   num_fields= mysql_stmt_field_count(stmt);
21078   mct_log("ANALYZE JSON DELETE number of fields: %d\n", (int) num_fields);
21079   if (num_fields != 1)
21080   {
21081     mct_close_log();
21082     DIE("num_fields != 1");
21083   }
21084   print_metadata(rs_metadata, num_fields);
21085   mysql_free_result(rs_metadata);
21086   mysql_stmt_close(stmt);
21087 
21088   rc= mysql_query(mysql, "DROP TABLE t1");
21089   myquery(rc);
21090   mct_close_log();
21091 }
21092 
21093 
21094 #ifndef EMBEDDED_LIBRARY
21095 #define MDEV19838_MAX_PARAM_COUNT 32
21096 #define MDEV19838_FIELDS_COUNT 17
test_mdev19838()21097 static void test_mdev19838()
21098 {
21099   int rc;
21100   MYSQL_BIND bind[MDEV19838_MAX_PARAM_COUNT];
21101   unsigned int i, paramCount = 1;
21102   char charvalue[] = "012345678901234567890123456789012345";
21103   MYSQL_STMT *stmt;
21104 
21105   myheader("test_mdev19838");
21106 
21107   rc = mysql_query(mysql, "CREATE TABLE mdev19838("
21108           "f1  char(36),"
21109           "f2  char(36),"
21110           "f3  char(36),"
21111           "f4  char(36),"
21112           "f5  char(36),"
21113           "f6  char(36),"
21114           "f7  char(36),"
21115           "f8  char(36),"
21116           "f9  char(36),"
21117           "f10 char(36),"
21118           "f11 char(36),"
21119           "f12 char(36),"
21120           "f13 char(36),"
21121           "f14 char(36),"
21122           "f15 char(36),"
21123           "f16 char(36),"
21124           "f17 char(36)"
21125     ")");
21126   myquery(rc);
21127 
21128   stmt = mysql_stmt_init(mysql);
21129   check_stmt(stmt);
21130 
21131   memset(bind, 0, sizeof(bind));
21132 
21133   for (i = 0; i < MDEV19838_MAX_PARAM_COUNT; ++i)
21134   {
21135     bind[i].buffer = charvalue;
21136     bind[i].buffer_type = MYSQL_TYPE_STRING;
21137     bind[i].buffer_length = strlen(charvalue) + 1;
21138     bind[i].length = &bind[i].length_value;
21139     bind[i].length_value = bind[i].buffer_length - 1;
21140   }
21141 
21142   for (paramCount = 1; paramCount < MDEV19838_FIELDS_COUNT; ++paramCount)
21143   {
21144     mysql_stmt_attr_set(stmt, STMT_ATTR_PREBIND_PARAMS, &paramCount);
21145 
21146     rc = mysql_stmt_bind_param(stmt, bind);
21147     check_execute(stmt, rc);
21148 
21149     rc = mariadb_stmt_execute_direct(stmt, "INSERT INTO mdev19838"
21150       "(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17)"
21151       " VALUES "
21152       "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", -1);
21153 
21154     /* Expecting an error */
21155     DIE_UNLESS(rc != 0);
21156 
21157     mysql_stmt_close(stmt);
21158     stmt = mysql_stmt_init(mysql);
21159     check_stmt(stmt);
21160   }
21161 
21162   paramCount = 0;
21163   mysql_stmt_attr_set(stmt, STMT_ATTR_PREBIND_PARAMS, &paramCount);
21164   rc = mariadb_stmt_execute_direct(stmt, "INSERT INTO mdev19838(f1)"
21165     " VALUES (?)", -1);
21166   /* Expecting an error */
21167   DIE_UNLESS(rc != 0);
21168   mysql_stmt_close(stmt);
21169 
21170   stmt = mysql_stmt_init(mysql);
21171   check_stmt(stmt);
21172   /* Correct number of parameters */
21173   paramCount = MDEV19838_FIELDS_COUNT;
21174   mysql_stmt_attr_set(stmt, STMT_ATTR_PREBIND_PARAMS, &paramCount);
21175   mysql_stmt_bind_param(stmt, bind);
21176 
21177   rc = mariadb_stmt_execute_direct(stmt, "INSERT INTO mdev19838"
21178     "(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17)"
21179     " VALUES "
21180     "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", -1);
21181   check_execute(stmt, rc);
21182 
21183   /* MYSQL_TYPE_TINY = 1. This parameter byte can be read as "parameters send" flag byte.
21184      Checking that wrong packet is still detected */
21185   bind[0].buffer_type = MYSQL_TYPE_TINY;
21186   bind[0].length_value = 1;
21187   bind[0].buffer_length = 1;
21188 
21189   for (paramCount = 8; paramCount > 0; --paramCount)
21190   {
21191     mysql_stmt_close(stmt);
21192     stmt = mysql_stmt_init(mysql);
21193     check_stmt(stmt);
21194 
21195     mysql_stmt_attr_set(stmt, STMT_ATTR_PREBIND_PARAMS, &paramCount);
21196 
21197     rc = mysql_stmt_bind_param(stmt, bind);
21198     check_execute(stmt, rc);
21199 
21200     rc = mariadb_stmt_execute_direct(stmt, "INSERT INTO mdev19838"
21201       "(f1, f2, f3, f4, f5, f6, f7, f8, f9)"
21202       " VALUES "
21203       "(?, ?, ?, ?, ?, ?, ?, ?, ?)", -1);
21204 
21205     /* Expecting an error */
21206     DIE_UNLESS(rc != 0);
21207   }
21208 
21209   /* Test of query w/out parameters, with parameter sent and not sent */
21210   for (paramCount = MDEV19838_MAX_PARAM_COUNT; paramCount != (unsigned int)-1; --paramCount)
21211   {
21212     mysql_stmt_close(stmt);
21213     stmt = mysql_stmt_init(mysql);
21214     check_stmt(stmt);
21215 
21216     mysql_stmt_attr_set(stmt, STMT_ATTR_PREBIND_PARAMS, &paramCount);
21217 
21218     if (paramCount > 0)
21219     {
21220       rc = mysql_stmt_bind_param(stmt, bind);
21221       check_execute(stmt, rc);
21222     }
21223 
21224     rc = mariadb_stmt_execute_direct(stmt, "INSERT INTO mdev19838"
21225       "(f1)"
21226       " VALUES "
21227       "(0x1111111111111111)", -1);
21228 
21229     /*
21230       We allow junk at the end of the packet in case of
21231       no parameters. So it will succeed.
21232     */
21233     DIE_UNLESS(rc == 0);
21234   }
21235 
21236   mysql_stmt_close(stmt);
21237 
21238   rc = mysql_query(mysql, "drop table mdev19838");
21239   myquery(rc);
21240 }
21241 #endif // EMBEDDED_LIBRARY
21242 
21243 
21244 /*
21245   MDEV-20261 NULL passed to String::eq, SEGV, server crash, regression in 10.4
21246 */
test_mdev20261()21247 static void test_mdev20261()
21248 {
21249   int rc;
21250   MYSQL_STMT *stmt;
21251   MYSQL_BIND param[1];
21252   const char *query= "SELECT * FROM t1 WHERE f = ? OR f = 'foo'";
21253   char val[]= "";
21254   my_bool is_null= TRUE;
21255 
21256   myheader("test_mdev20261");
21257 
21258   rc= mysql_query(mysql, "CREATE OR REPLACE TABLE t1 (f varchar(64)) ENGINE=MyISAM");
21259   myquery(rc);
21260 
21261   stmt= mysql_stmt_init(mysql);
21262   check_stmt(stmt);
21263   rc= mysql_stmt_prepare(stmt, query, strlen(query));
21264   check_execute(stmt, rc);
21265 
21266   verify_param_count(stmt, 1);
21267 
21268   bzero((char*) param, sizeof(param));
21269 
21270   param[0].buffer= &val;
21271   param[0].buffer_type= MYSQL_TYPE_STRING;
21272   param[0].is_null= &is_null;
21273 
21274   rc= mysql_stmt_bind_param(stmt, param);
21275   check_execute(stmt, rc);
21276 
21277   rc= mysql_stmt_execute(stmt);
21278   check_execute(stmt, rc);
21279 
21280   rc= mysql_stmt_store_result(stmt);
21281   check_execute(stmt, rc);
21282 
21283   mysql_stmt_close(stmt);
21284 
21285   rc= mysql_query(mysql, "DROP TABLE t1");
21286   myquery(rc);
21287 }
21288 
21289 
21290 static struct my_tests_st my_tests[]= {
21291   { "test_mdev_20516", test_mdev_20516 },
21292   { "test_mdev24827", test_mdev24827 },
21293   { "test_mdev_26145", test_mdev_26145 },
21294   { "disable_query_logs", disable_query_logs },
21295   { "test_view_sp_list_fields", test_view_sp_list_fields },
21296   { "client_query", client_query },
21297   { "test_prepare_insert_update", test_prepare_insert_update},
21298 #ifdef EMBEDDED_LIBRARY
21299   { "test_embedded_start_stop", test_embedded_start_stop },
21300 #endif
21301 #ifdef NOT_YET_WORKING
21302   { "test_drop_temp", test_drop_temp },
21303 #endif
21304   { "test_fetch_seek", test_fetch_seek },
21305   { "test_fetch_nobuffs", test_fetch_nobuffs },
21306   { "test_open_direct", test_open_direct },
21307   { "test_fetch_null", test_fetch_null },
21308   { "test_ps_null_param", test_ps_null_param },
21309   { "test_fetch_date", test_fetch_date },
21310   { "test_fetch_str", test_fetch_str },
21311   { "test_fetch_long", test_fetch_long },
21312   { "test_fetch_short", test_fetch_short },
21313   { "test_fetch_tiny", test_fetch_tiny },
21314   { "test_fetch_bigint", test_fetch_bigint },
21315   { "test_fetch_float", test_fetch_float },
21316   { "test_fetch_double", test_fetch_double },
21317   { "test_bind_result_ext", test_bind_result_ext },
21318   { "test_bind_result_ext1", test_bind_result_ext1 },
21319   { "test_select_direct", test_select_direct },
21320   { "test_select_prepare", test_select_prepare },
21321   { "test_select", test_select },
21322   { "test_select_version", test_select_version },
21323   { "test_ps_conj_select", test_ps_conj_select },
21324   { "test_select_show_table", test_select_show_table },
21325   { "test_func_fields", test_func_fields },
21326   { "test_long_data", test_long_data },
21327   { "test_insert", test_insert },
21328   { "test_set_variable", test_set_variable },
21329   { "test_select_show", test_select_show },
21330   { "test_prepare_noparam", test_prepare_noparam },
21331   { "test_bind_result", test_bind_result },
21332   { "test_prepare_simple", test_prepare_simple },
21333   { "test_prepare", test_prepare },
21334   { "test_null", test_null },
21335   { "test_debug_example", test_debug_example },
21336   { "test_update", test_update },
21337   { "test_simple_update", test_simple_update },
21338   { "test_simple_delete", test_simple_delete },
21339   { "test_double_compare", test_double_compare },
21340   { "client_store_result", client_store_result },
21341   { "client_use_result", client_use_result },
21342   { "test_tran_bdb", test_tran_bdb },
21343   { "test_tran_innodb", test_tran_innodb },
21344   { "test_prepare_ext", test_prepare_ext },
21345   { "test_prepare_syntax", test_prepare_syntax },
21346   { "test_field_names", test_field_names },
21347   { "test_field_flags", test_field_flags },
21348   { "test_long_data_str", test_long_data_str },
21349   { "test_long_data_str1", test_long_data_str1 },
21350   { "test_long_data_bin", test_long_data_bin },
21351   { "test_warnings", test_warnings },
21352   { "test_errors", test_errors },
21353   { "test_prepare_resultset", test_prepare_resultset },
21354   { "test_stmt_close", test_stmt_close },
21355   { "test_prepare_field_result", test_prepare_field_result },
21356   { "test_multi_stmt", test_multi_stmt },
21357   { "test_multi_statements", test_multi_statements },
21358   { "test_prepare_multi_statements", test_prepare_multi_statements },
21359   { "test_store_result", test_store_result },
21360   { "test_store_result1", test_store_result1 },
21361   { "test_store_result2", test_store_result2 },
21362   { "test_subselect", test_subselect },
21363   { "test_date", test_date },
21364   { "test_date_date", test_date_date },
21365   { "test_date_time", test_date_time },
21366   { "test_date_ts", test_date_ts },
21367   { "test_date_dt", test_date_dt },
21368   { "test_prepare_alter", test_prepare_alter },
21369   { "test_manual_sample", test_manual_sample },
21370   { "test_pure_coverage", test_pure_coverage },
21371   { "test_buffers", test_buffers },
21372   { "test_ushort_bug", test_ushort_bug },
21373   { "test_sshort_bug", test_sshort_bug },
21374   { "test_stiny_bug", test_stiny_bug },
21375   { "test_field_misc", test_field_misc },
21376   { "test_set_option", test_set_option },
21377 #ifndef EMBEDDED_LIBRARY
21378   { "test_prepare_grant", test_prepare_grant },
21379 
21380 #endif
21381   { "test_frm_bug", test_frm_bug },
21382   { "test_explain_bug", test_explain_bug },
21383   { "test_decimal_bug", test_decimal_bug },
21384   { "test_nstmts", test_nstmts },
21385   { "test_logs;", test_logs },
21386   { "test_cuted_rows", test_cuted_rows },
21387   { "test_fetch_offset", test_fetch_offset },
21388   { "test_fetch_column", test_fetch_column },
21389   { "test_mem_overun", test_mem_overun },
21390   { "test_list_fields", test_list_fields },
21391   { "test_list_information_schema_fields", test_list_information_schema_fields },
21392   { "test_list_fields_blob", test_list_fields_blob },
21393   { "test_list_fields_default", test_list_fields_default },
21394   { "test_free_result", test_free_result },
21395   { "test_free_store_result", test_free_store_result },
21396   { "test_sqlmode", test_sqlmode },
21397   { "test_ts", test_ts },
21398   { "test_bug1115", test_bug1115 },
21399   { "test_bug1180", test_bug1180 },
21400   { "test_bug1500", test_bug1500 },
21401   { "test_bug1644", test_bug1644 },
21402   { "test_bug1946", test_bug1946 },
21403   { "test_bug2248", test_bug2248 },
21404   { "test_parse_error_and_bad_length", test_parse_error_and_bad_length },
21405   { "test_bug2247", test_bug2247 },
21406   { "test_subqueries", test_subqueries },
21407   { "test_bad_union", test_bad_union },
21408   { "test_distinct", test_distinct },
21409   { "test_subqueries_ref", test_subqueries_ref },
21410   { "test_union", test_union },
21411   { "test_bug3117", test_bug3117 },
21412   { "test_join", test_join },
21413   { "test_selecttmp", test_selecttmp },
21414   { "test_create_drop", test_create_drop },
21415   { "test_rename", test_rename },
21416   { "test_do_set", test_do_set },
21417   { "test_multi", test_multi },
21418   { "test_insert_select", test_insert_select },
21419   { "test_bind_nagative", test_bind_nagative },
21420   { "test_derived", test_derived },
21421   { "test_xjoin", test_xjoin },
21422   { "test_bug3035", test_bug3035 },
21423   { "test_union2", test_union2 },
21424   { "test_bug1664", test_bug1664 },
21425   { "test_union_param", test_union_param },
21426   { "test_order_param", test_order_param },
21427   { "test_ps_i18n", test_ps_i18n },
21428   { "test_bug3796", test_bug3796 },
21429   { "test_bug4026", test_bug4026 },
21430   { "test_bug4079", test_bug4079 },
21431   { "test_bug4236", test_bug4236 },
21432   { "test_bug4030", test_bug4030 },
21433   { "test_bug5126", test_bug5126 },
21434   { "test_bug4231", test_bug4231 },
21435   { "test_bug5399", test_bug5399 },
21436   { "test_bug5194", test_bug5194 },
21437   { "test_bug5315", test_bug5315 },
21438   { "test_bug6049", test_bug6049 },
21439   { "test_bug6058", test_bug6058 },
21440   { "test_bug6059", test_bug6059 },
21441   { "test_bug6046", test_bug6046 },
21442   { "test_bug6081", test_bug6081 },
21443   { "test_bug6096", test_bug6096 },
21444   { "test_datetime_ranges", test_datetime_ranges },
21445   { "test_datetime_ranges_mdev15289", test_datetime_ranges_mdev15289 },
21446   { "test_bug4172", test_bug4172 },
21447   { "test_conversion", test_conversion },
21448   { "test_rewind", test_rewind },
21449   { "test_bug6761", test_bug6761 },
21450   { "test_view", test_view },
21451   { "test_view_where", test_view_where },
21452   { "test_view_2where", test_view_2where },
21453   { "test_view_star", test_view_star },
21454   { "test_view_insert", test_view_insert },
21455   { "test_left_join_view", test_left_join_view },
21456   { "test_view_insert_fields", test_view_insert_fields },
21457   { "test_basic_cursors", test_basic_cursors },
21458   { "test_cursors_with_union", test_cursors_with_union },
21459   { "test_cursors_with_procedure", test_cursors_with_procedure },
21460   { "test_truncation", test_truncation },
21461   { "test_truncation_option", test_truncation_option },
21462   { "test_client_character_set", test_client_character_set },
21463   { "test_bug8330", test_bug8330 },
21464   { "test_bug7990", test_bug7990 },
21465   { "test_bug8378", test_bug8378 },
21466   { "test_bug8722", test_bug8722 },
21467   { "test_bug8880", test_bug8880 },
21468   { "test_open_cursor_prepared_statement_query_cache",
21469     test_open_cursor_prepared_statement_query_cache },
21470   { "test_bug9159", test_bug9159 },
21471   { "test_bug9520", test_bug9520 },
21472   { "test_bug9478", test_bug9478 },
21473   { "test_bug9643", test_bug9643 },
21474   { "test_bug10729", test_bug10729 },
21475   { "test_bug11111", test_bug11111 },
21476   { "test_bug9992", test_bug9992 },
21477   { "test_bug10736", test_bug10736 },
21478   { "test_bug10794", test_bug10794 },
21479   { "test_bug11172", test_bug11172 },
21480   { "test_bug11656", test_bug11656 },
21481   { "test_bug10214", test_bug10214 },
21482   { "test_bug9735", test_bug9735 },
21483   { "test_bug11183", test_bug11183 },
21484   { "test_bug11037", test_bug11037 },
21485   { "test_bug10760", test_bug10760 },
21486   { "test_bug12001", test_bug12001 },
21487   { "test_bug11718", test_bug11718 },
21488   { "test_bug12925", test_bug12925 },
21489   { "test_bug11909", test_bug11909 },
21490   { "test_bug11901", test_bug11901 },
21491   { "test_bug11904", test_bug11904 },
21492   { "test_bug12243", test_bug12243 },
21493   { "test_bug14210", test_bug14210 },
21494   { "test_bug13488", test_bug13488 },
21495   { "test_bug13524", test_bug13524 },
21496   { "test_bug14845", test_bug14845 },
21497   { "test_opt_reconnect", test_opt_reconnect },
21498   { "test_bug15510", test_bug15510},
21499 #ifndef EMBEDDED_LIBRARY
21500   { "test_bug12744", test_bug12744 },
21501 #endif
21502   { "test_bug16143", test_bug16143 },
21503   { "test_bug16144", test_bug16144 },
21504   { "test_bug15613", test_bug15613 },
21505   { "test_bug20152", test_bug20152 },
21506   { "test_bug14169", test_bug14169 },
21507   { "test_bug17667", test_bug17667 },
21508   { "test_bug15752", test_bug15752 },
21509   { "test_mysql_insert_id", test_mysql_insert_id },
21510   { "test_bug19671", test_bug19671 },
21511   { "test_bug21206", test_bug21206 },
21512   { "test_bug21726", test_bug21726 },
21513   { "test_bug15518", test_bug15518 },
21514   { "test_bug23383", test_bug23383 },
21515   { "test_bug32265", test_bug32265 },
21516   { "test_bug21635", test_bug21635 },
21517   { "test_status",   test_status   },
21518   { "test_bug24179", test_bug24179 },
21519   { "test_ps_query_cache", test_ps_query_cache },
21520   { "test_bug28075", test_bug28075 },
21521   { "test_bug27876", test_bug27876 },
21522   { "test_bug28505", test_bug28505 },
21523   { "test_bug28934", test_bug28934 },
21524   { "test_bug27592", test_bug27592 },
21525   { "test_bug29687", test_bug29687 },
21526   { "test_bug29692", test_bug29692 },
21527   { "test_bug29306", test_bug29306 },
21528   { "test_change_user", test_change_user },
21529   { "test_bug30472", test_bug30472 },
21530   { "test_bug20023", test_bug20023 },
21531   { "test_bug45010", test_bug45010 },
21532   { "test_bug53371", test_bug53371 },
21533   { "test_bug31418", test_bug31418 },
21534   { "test_bug31669", test_bug31669 },
21535   { "test_bug28386", test_bug28386 },
21536   { "test_wl4166_1", test_wl4166_1 },
21537   { "test_wl4166_2", test_wl4166_2 },
21538   { "test_wl4166_3", test_wl4166_3 },
21539   { "test_wl4166_4", test_wl4166_4 },
21540   { "test_bug36004", test_bug36004 },
21541   { "test_wl4284_1", test_wl4284_1 },
21542   { "test_wl4435",   test_wl4435 },
21543   { "test_wl4435_2", test_wl4435_2 },
21544   { "test_wl4435_3", test_wl4435_3 },
21545   { "test_bug38486", test_bug38486 },
21546   { "test_bug33831", test_bug33831 },
21547   { "test_bug40365", test_bug40365 },
21548   { "test_bug43560", test_bug43560 },
21549   { "test_bug36326", test_bug36326 },
21550   { "test_bug41078", test_bug41078 },
21551   { "test_bug44495", test_bug44495 },
21552   { "test_bug49972", test_bug49972 },
21553   { "test_bug42373", test_bug42373 },
21554   { "test_bug54041", test_bug54041 },
21555   { "test_bug47485", test_bug47485 },
21556   { "test_bug58036", test_bug58036 },
21557   { "test_bug57058", test_bug57058 },
21558   { "test_bug56976", test_bug56976 },
21559   { "test_mdev3885", test_mdev3885 },
21560   { "test_mdev4603", test_mdev4603 },
21561   { "test_bug11766854", test_bug11766854 },
21562   { "test_bug12337762", test_bug12337762 },
21563   { "test_progress_reporting", test_progress_reporting },
21564   { "test_bug11754979", test_bug11754979 },
21565   { "test_bug13001491", test_bug13001491 },
21566   { "test_mdev4326", test_mdev4326 },
21567   { "test_ps_sp_out_params", test_ps_sp_out_params },
21568 #ifndef _WIN32
21569   { "test_bug17512527", test_bug17512527},
21570 #endif
21571   { "test_compressed_protocol", test_compressed_protocol },
21572   { "test_big_packet", test_big_packet },
21573   { "test_prepare_analyze", test_prepare_analyze },
21574   { "test_mdev12579", test_mdev12579 },
21575   { "test_mdev14013", test_mdev14013 },
21576   { "test_mdev14013_1", test_mdev14013_1 },
21577   { "test_mdev14454", test_mdev14454 },
21578 #ifndef EMBEDDED_LIBRARY
21579   { "test_proxy_header", test_proxy_header},
21580   { "test_bulk_autoinc", test_bulk_autoinc},
21581   { "test_bulk_delete", test_bulk_delete },
21582   { "test_bulk_replace", test_bulk_replace },
21583 #endif
21584   { "test_ps_params_in_ctes", test_ps_params_in_ctes },
21585   { "test_explain_meta", test_explain_meta },
21586 #ifndef EMBEDDED_LIBRARY
21587   { "test_mdev19838", test_mdev19838 },
21588 #endif
21589   { "test_mdev18408", test_mdev18408 },
21590   { "test_mdev20261", test_mdev20261 },
21591   { 0, 0 }
21592 };
21593 
21594 
get_my_tests()21595 static struct my_tests_st *get_my_tests() { return my_tests; }
21596